summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 19:17:32 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 19:17:32 +0000
commite38d2351b83fa65c66ccde443777647ef5cb6cff (patch)
tree1897fc20e9f73a81c520a5b9f76f8ed042124883
downloadtellico-e38d2351.tar.gz
tellico-e38d2351.zip
Added KDE3 version of Tellico
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/tellico@1097620 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
-rw-r--r--AUTHORS1
-rw-r--r--COPYING353
-rw-r--r--ChangeLog2416
-rw-r--r--INSTALL167
-rw-r--r--Makefile.am128
-rw-r--r--NEWS0
-rw-r--r--README1
-rw-r--r--TODO1
-rw-r--r--acinclude.m411720
-rw-r--r--aclocal.m41033
-rw-r--r--config.h.in326
-rw-r--r--configure.in723
-rw-r--r--configure.in.in552
-rw-r--r--doc/CMakeLists.txt4
-rw-r--r--doc/Makefile.am5
-rw-r--r--doc/en/CMakeLists.txt62
-rw-r--r--doc/en/Makefile.am50
-rw-r--r--doc/en/advanced.docbook151
-rw-r--r--doc/en/amazon-options.pngbin0 -> 36487 bytes
-rw-r--r--doc/en/configuration.docbook376
-rw-r--r--doc/en/csv-dialog.pngbin0 -> 41376 bytes
-rw-r--r--doc/en/details.docbook547
-rw-r--r--doc/en/entry-editor1.pngbin0 -> 26001 bytes
-rw-r--r--doc/en/entry-editor3.pngbin0 -> 23827 bytes
-rw-r--r--doc/en/entry-editor4.pngbin0 -> 20807 bytes
-rw-r--r--doc/en/entry-editor5.pngbin0 -> 25436 bytes
-rw-r--r--doc/en/export-bibtex.pngbin0 -> 9404 bytes
-rw-r--r--doc/en/export-csv.pngbin0 -> 6259 bytes
-rw-r--r--doc/en/export-html.pngbin0 -> 4973 bytes
-rw-r--r--doc/en/export-options.pngbin0 -> 7411 bytes
-rw-r--r--doc/en/export-pdb.pngbin0 -> 3742 bytes
-rw-r--r--doc/en/externalexec-options.pngbin0 -> 47693 bytes
-rw-r--r--doc/en/faqs.docbook257
-rw-r--r--doc/en/fetch-dialog.pngbin0 -> 110344 bytes
-rw-r--r--doc/en/fields-dialog.pngbin0 -> 59595 bytes
-rw-r--r--doc/en/filter-dialog.pngbin0 -> 28523 bytes
-rw-r--r--doc/en/filter-view.pngbin0 -> 9865 bytes
-rw-r--r--doc/en/freebsd-doc-license.html57
-rw-r--r--doc/en/fundamentals.docbook595
-rw-r--r--doc/en/general-options.pngbin0 -> 43921 bytes
-rw-r--r--doc/en/hacking.docbook362
-rw-r--r--doc/en/imdb-options.pngbin0 -> 37132 bytes
-rw-r--r--doc/en/importing-exporting.docbook452
-rw-r--r--doc/en/index.docbook423
-rw-r--r--doc/en/loan-dialog.pngbin0 -> 32261 bytes
-rw-r--r--doc/en/loan-view.pngbin0 -> 8383 bytes
-rw-r--r--doc/en/main-window.pngbin0 -> 296455 bytes
-rw-r--r--doc/en/menus.docbook768
-rw-r--r--doc/en/openoffice-dialog.pngbin0 -> 29340 bytes
-rw-r--r--doc/en/print-options.pngbin0 -> 41140 bytes
-rw-r--r--doc/en/report-dialog.pngbin0 -> 125817 bytes
-rw-r--r--doc/en/source-options.pngbin0 -> 64944 bytes
-rw-r--r--doc/en/sru-options.pngbin0 -> 33399 bytes
-rw-r--r--doc/en/template-options.pngbin0 -> 52477 bytes
-rw-r--r--doc/en/z3950-options.pngbin0 -> 46578 bytes
-rw-r--r--doc/fr/CMakeLists.txt60
-rw-r--r--doc/fr/Makefile.am50
-rw-r--r--doc/fr/advanced.docbook120
-rw-r--r--doc/fr/amazon-options.pngbin0 -> 25139 bytes
-rw-r--r--doc/fr/configuration.docbook445
-rw-r--r--doc/fr/csv-dialog.pngbin0 -> 44655 bytes
-rw-r--r--doc/fr/details.docbook613
-rw-r--r--doc/fr/entry-editor1.pngbin0 -> 18682 bytes
-rw-r--r--doc/fr/entry-editor3.pngbin0 -> 17142 bytes
-rw-r--r--doc/fr/entry-editor4.pngbin0 -> 13710 bytes
-rw-r--r--doc/fr/entry-editor5.pngbin0 -> 21396 bytes
-rw-r--r--doc/fr/export-bibtex.pngbin0 -> 9322 bytes
-rw-r--r--doc/fr/export-csv.pngbin0 -> 6859 bytes
-rw-r--r--doc/fr/export-html.pngbin0 -> 5455 bytes
-rw-r--r--doc/fr/export-options.pngbin0 -> 9052 bytes
-rw-r--r--doc/fr/export-pdb.pngbin0 -> 3809 bytes
-rw-r--r--doc/fr/externalexec-options.pngbin0 -> 32785 bytes
-rw-r--r--doc/fr/faqs.docbook279
-rw-r--r--doc/fr/fetch-dialog.pngbin0 -> 58858 bytes
-rw-r--r--doc/fr/fields-dialog.pngbin0 -> 51344 bytes
-rw-r--r--doc/fr/filter-dialog.pngbin0 -> 18958 bytes
-rw-r--r--doc/fr/filter-view.pngbin0 -> 6325 bytes
-rw-r--r--doc/fr/freebsd-doc-license.html57
-rw-r--r--doc/fr/fundamentals.docbook841
-rw-r--r--doc/fr/general-options.pngbin0 -> 37318 bytes
-rw-r--r--doc/fr/hacking.docbook448
-rw-r--r--doc/fr/imdb-options.pngbin0 -> 28569 bytes
-rw-r--r--doc/fr/importing-exporting.docbook594
-rw-r--r--doc/fr/index.docbook452
-rw-r--r--doc/fr/loan-dialog.pngbin0 -> 25629 bytes
-rw-r--r--doc/fr/loan-view.pngbin0 -> 6034 bytes
-rw-r--r--doc/fr/main-window.pngbin0 -> 110844 bytes
-rw-r--r--doc/fr/menus.docbook821
-rw-r--r--doc/fr/openoffice-dialog.pngbin0 -> 20695 bytes
-rw-r--r--doc/fr/print-options.pngbin0 -> 32049 bytes
-rw-r--r--doc/fr/report-dialog.pngbin0 -> 55663 bytes
-rw-r--r--doc/fr/source-options.pngbin0 -> 32748 bytes
-rw-r--r--doc/fr/sru-options.pngbin0 -> 23757 bytes
-rw-r--r--doc/fr/template-options.pngbin0 -> 46891 bytes
-rw-r--r--doc/fr/z3950-options.pngbin0 -> 30819 bytes
-rw-r--r--icons/Makefile.am81
-rw-r--r--icons/README.icons18
-rw-r--r--icons/README.quesnay62
-rw-r--r--icons/album.pngbin0 -> 456 bytes
-rw-r--r--icons/bibtex.pngbin0 -> 513 bytes
-rw-r--r--icons/boardgame.pngbin0 -> 823 bytes
-rw-r--r--icons/book.pngbin0 -> 380 bytes
-rw-r--r--icons/card.pngbin0 -> 647 bytes
-rw-r--r--icons/checkmark.pngbin0 -> 594 bytes
-rw-r--r--icons/coin.pngbin0 -> 917 bytes
-rw-r--r--icons/comic.pngbin0 -> 332 bytes
-rw-r--r--icons/file.pngbin0 -> 544 bytes
-rw-r--r--icons/game.pngbin0 -> 868 bytes
-rw-r--r--icons/hi128-app-tellico.pngbin0 -> 12895 bytes
-rw-r--r--icons/hi128-mime-application-x-tellico.pngbin0 -> 10540 bytes
-rw-r--r--icons/hi16-app-tellico.pngbin0 -> 851 bytes
-rw-r--r--icons/hi16-mime-application-x-tellico.pngbin0 -> 747 bytes
-rw-r--r--icons/hi22-app-tellico.pngbin0 -> 1299 bytes
-rw-r--r--icons/hi22-mime-application-x-tellico.pngbin0 -> 1063 bytes
-rw-r--r--icons/hi32-app-tellico.pngbin0 -> 2193 bytes
-rw-r--r--icons/hi32-mime-application-x-tellico.pngbin0 -> 1717 bytes
-rw-r--r--icons/hi48-app-tellico.pngbin0 -> 3785 bytes
-rw-r--r--icons/hi48-mime-application-x-tellico.pngbin0 -> 2860 bytes
-rw-r--r--icons/hi64-app-tellico.pngbin0 -> 5454 bytes
-rw-r--r--icons/hi64-mime-application-x-tellico.pngbin0 -> 4238 bytes
-rw-r--r--icons/nocover_album.pngbin0 -> 10778 bytes
-rw-r--r--icons/nocover_bibtex.pngbin0 -> 3531 bytes
-rw-r--r--icons/nocover_boardgame.pngbin0 -> 7996 bytes
-rw-r--r--icons/nocover_book.pngbin0 -> 7996 bytes
-rw-r--r--icons/nocover_comic.pngbin0 -> 7996 bytes
-rw-r--r--icons/nocover_game.pngbin0 -> 7996 bytes
-rw-r--r--icons/nocover_video.pngbin0 -> 7996 bytes
-rw-r--r--icons/person-open.pngbin0 -> 655 bytes
-rw-r--r--icons/person.pngbin0 -> 655 bytes
-rw-r--r--icons/script.pngbin0 -> 3703 bytes
-rw-r--r--icons/script.svg1499
-rw-r--r--icons/stamp.pngbin0 -> 1010 bytes
-rw-r--r--icons/star_off.pngbin0 -> 263 bytes
-rw-r--r--icons/star_on.pngbin0 -> 318 bytes
-rw-r--r--icons/stars1.pngbin0 -> 322 bytes
-rw-r--r--icons/stars10.pngbin0 -> 345 bytes
-rw-r--r--icons/stars2.pngbin0 -> 341 bytes
-rw-r--r--icons/stars3.pngbin0 -> 344 bytes
-rw-r--r--icons/stars4.pngbin0 -> 344 bytes
-rw-r--r--icons/stars5.pngbin0 -> 345 bytes
-rw-r--r--icons/stars6.pngbin0 -> 344 bytes
-rw-r--r--icons/stars7.pngbin0 -> 346 bytes
-rw-r--r--icons/stars8.pngbin0 -> 345 bytes
-rw-r--r--icons/stars9.pngbin0 -> 348 bytes
-rw-r--r--icons/tellico.pngbin0 -> 2193 bytes
-rw-r--r--icons/tellico.svg2024
-rw-r--r--icons/tellico_mime.svg1560
-rw-r--r--icons/video.pngbin0 -> 312 bytes
-rw-r--r--icons/wine.pngbin0 -> 413 bytes
-rwxr-xr-xinstall-sh251
-rw-r--r--po/CMakeLists.txt5
-rw-r--r--po/Makefile.am9
-rw-r--r--po/README5
-rw-r--r--po/bg.po5968
-rw-r--r--po/ca.po5375
-rw-r--r--po/cs.po5344
-rw-r--r--po/de.po5450
-rw-r--r--po/ee.po6000
-rw-r--r--po/en_GB.po5243
-rw-r--r--po/es.po5294
-rw-r--r--po/fi.po5143
-rw-r--r--po/fr.po5283
-rw-r--r--po/hu.po5246
-rw-r--r--po/it.po6027
-rw-r--r--po/nb.po6012
-rw-r--r--po/nl.po5505
-rw-r--r--po/nn.po5147
-rw-r--r--po/pl.po5441
-rw-r--r--po/pt.po5227
-rw-r--r--po/pt_BR.po5364
-rw-r--r--po/ro.po5951
-rw-r--r--po/ru.po5178
-rw-r--r--po/sv.po5236
-rw-r--r--po/tellico.pot4942
-rw-r--r--po/tr.po5376
-rw-r--r--po/uk.po5624
-rw-r--r--src/Makefile.am140
-rw-r--r--src/barcode/Makefile.am14
-rw-r--r--src/barcode/barcode.cpp877
-rw-r--r--src/barcode/barcode.h135
-rw-r--r--src/barcode/barcode_v4l.cpp538
-rw-r--r--src/barcode/barcode_v4l.h184
-rw-r--r--src/borrower.cpp75
-rw-r--r--src/borrower.h95
-rw-r--r--src/borrowerdialog.cpp136
-rw-r--r--src/borrowerdialog.h74
-rw-r--r--src/borroweritem.cpp40
-rw-r--r--src/borroweritem.h41
-rw-r--r--src/calendarhandler.cpp251
-rw-r--r--src/calendarhandler.h57
-rw-r--r--src/cite/Makefile.am20
-rw-r--r--src/cite/actionmanager.cpp85
-rw-r--r--src/cite/actionmanager.h64
-rw-r--r--src/cite/clipboard.cpp51
-rw-r--r--src/cite/clipboard.h36
-rw-r--r--src/cite/handler.h61
-rw-r--r--src/cite/lyxpipe.cpp92
-rw-r--r--src/cite/lyxpipe.h36
-rw-r--r--src/cite/ooo/Makefile.am88
-rw-r--r--src/cite/ooo/interface.cpp430
-rw-r--r--src/cite/ooo/interface.h62
-rw-r--r--src/cite/ooo/ooohandler.cpp159
-rw-r--r--src/cite/ooo/ooohandler.h54
-rw-r--r--src/cite/openoffice.cpp267
-rw-r--r--src/cite/openoffice.h47
-rw-r--r--src/collection.cpp915
-rw-r--r--src/collection.h394
-rw-r--r--src/collectionfactory.cpp210
-rw-r--r--src/collectionfactory.h40
-rw-r--r--src/collectionfieldsdialog.cpp1036
-rw-r--r--src/collectionfieldsdialog.h127
-rw-r--r--src/collections/Makefile.am32
-rw-r--r--src/collections/bibtexcollection.cpp400
-rw-r--r--src/collections/bibtexcollection.h70
-rw-r--r--src/collections/boardgamecollection.cpp112
-rw-r--r--src/collections/boardgamecollection.h44
-rw-r--r--src/collections/bookcollection.cpp202
-rw-r--r--src/collections/bookcollection.h74
-rw-r--r--src/collections/cardcollection.cpp121
-rw-r--r--src/collections/cardcollection.h49
-rw-r--r--src/collections/coincollection.cpp135
-rw-r--r--src/collections/coincollection.h49
-rw-r--r--src/collections/comicbookcollection.cpp157
-rw-r--r--src/collections/comicbookcollection.h48
-rw-r--r--src/collections/filecatalog.cpp105
-rw-r--r--src/collections/filecatalog.h38
-rw-r--r--src/collections/gamecollection.cpp126
-rw-r--r--src/collections/gamecollection.h44
-rw-r--r--src/collections/musiccollection.cpp132
-rw-r--r--src/collections/musiccollection.h55
-rw-r--r--src/collections/stampcollection.cpp133
-rw-r--r--src/collections/stampcollection.h66
-rw-r--r--src/collections/videocollection.cpp236
-rw-r--r--src/collections/videocollection.h54
-rw-r--r--src/collections/winecollection.cpp120
-rw-r--r--src/collections/winecollection.h54
-rw-r--r--src/commands/Makefile.am29
-rw-r--r--src/commands/addentries.cpp64
-rw-r--r--src/commands/addentries.h44
-rw-r--r--src/commands/addloans.cpp110
-rw-r--r--src/commands/addloans.h47
-rw-r--r--src/commands/collectioncommand.cpp126
-rw-r--r--src/commands/collectioncommand.h63
-rw-r--r--src/commands/fieldcommand.cpp112
-rw-r--r--src/commands/fieldcommand.h52
-rw-r--r--src/commands/filtercommand.cpp106
-rw-r--r--src/commands/filtercommand.h51
-rw-r--r--src/commands/group.cpp23
-rw-r--r--src/commands/group.h38
-rw-r--r--src/commands/modifyentries.cpp88
-rw-r--r--src/commands/modifyentries.h48
-rw-r--r--src/commands/modifyloans.cpp76
-rw-r--r--src/commands/modifyloans.h45
-rw-r--r--src/commands/removeentries.cpp50
-rw-r--r--src/commands/removeentries.h44
-rw-r--r--src/commands/removeloans.cpp81
-rw-r--r--src/commands/removeloans.h43
-rw-r--r--src/commands/renamecollection.cpp46
-rw-r--r--src/commands/renamecollection.h43
-rw-r--r--src/commands/reorderfields.cpp55
-rw-r--r--src/commands/reorderfields.h45
-rw-r--r--src/commands/updateentries.cpp94
-rw-r--r--src/commands/updateentries.h43
-rw-r--r--src/configdialog.cpp1060
-rw-r--r--src/configdialog.h226
-rw-r--r--src/controller.cpp762
-rw-r--r--src/controller.h175
-rw-r--r--src/core/Makefile.am27
-rw-r--r--src/core/dcopinterface.cpp171
-rw-r--r--src/core/dcopinterface.h85
-rw-r--r--src/core/dcopinterface_skel.cpp374
-rw-r--r--src/core/drophandler.cpp101
-rw-r--r--src/core/drophandler.h39
-rw-r--r--src/core/netaccess.cpp100
-rw-r--r--src/core/netaccess.h47
-rw-r--r--src/core/tellico-1-3-update.pl24
-rw-r--r--src/core/tellico-rename.upd4
-rw-r--r--src/core/tellico.upd26
-rw-r--r--src/core/tellico_config.cpp455
-rw-r--r--src/core/tellico_config.kcfg477
-rw-r--r--src/core/tellico_config.kcfgc9
-rw-r--r--src/core/tellico_config_addons.cpp171
-rw-r--r--src/core/tellico_config_addons.h36
-rw-r--r--src/datavectors.h63
-rw-r--r--src/detailedentryitem.cpp127
-rw-r--r--src/detailedentryitem.h55
-rw-r--r--src/detailedlistview.cpp894
-rw-r--r--src/detailedlistview.h214
-rw-r--r--src/document.cpp679
-rw-r--r--src/document.h237
-rw-r--r--src/entry.cpp466
-rw-r--r--src/entry.h256
-rw-r--r--src/entryeditdialog.cpp757
-rw-r--r--src/entryeditdialog.h149
-rw-r--r--src/entrygroupitem.cpp140
-rw-r--r--src/entrygroupitem.h71
-rw-r--r--src/entryiconfactory.cpp43
-rw-r--r--src/entryiconfactory.h36
-rw-r--r--src/entryiconview.cpp444
-rw-r--r--src/entryiconview.h133
-rw-r--r--src/entryitem.cpp55
-rw-r--r--src/entryitem.h83
-rw-r--r--src/entrymerger.cpp107
-rw-r--r--src/entrymerger.h52
-rw-r--r--src/entryupdater.cpp273
-rw-r--r--src/entryupdater.h66
-rw-r--r--src/entryview.cpp364
-rw-r--r--src/entryview.h106
-rw-r--r--src/exportdialog.cpp262
-rw-r--r--src/exportdialog.h65
-rw-r--r--src/fetch/Makefile.am46
-rw-r--r--src/fetch/amazonfetcher.cpp937
-rw-r--r--src/fetch/amazonfetcher.h158
-rw-r--r--src/fetch/animenfofetcher.cpp378
-rw-r--r--src/fetch/animenfofetcher.h86
-rw-r--r--src/fetch/arxivfetcher.cpp366
-rw-r--r--src/fetch/arxivfetcher.h93
-rw-r--r--src/fetch/bibsonomyfetcher.cpp209
-rw-r--r--src/fetch/bibsonomyfetcher.h82
-rw-r--r--src/fetch/citebasefetcher.cpp248
-rw-r--r--src/fetch/citebasefetcher.h83
-rw-r--r--src/fetch/configwidget.cpp66
-rw-r--r--src/fetch/configwidget.h78
-rw-r--r--src/fetch/crossreffetcher.cpp392
-rw-r--r--src/fetch/crossreffetcher.h97
-rw-r--r--src/fetch/discogsfetcher.cpp413
-rw-r--r--src/fetch/discogsfetcher.h117
-rw-r--r--src/fetch/entrezfetcher.cpp498
-rw-r--r--src/fetch/entrezfetcher.h113
-rw-r--r--src/fetch/execexternalfetcher.cpp561
-rw-r--r--src/fetch/execexternalfetcher.h118
-rw-r--r--src/fetch/fetch.h64
-rw-r--r--src/fetch/fetcher.cpp61
-rw-r--r--src/fetch/fetcher.h151
-rw-r--r--src/fetch/fetchmanager.cpp707
-rw-r--r--src/fetch/fetchmanager.h108
-rw-r--r--src/fetch/gcstarpluginfetcher.cpp486
-rw-r--r--src/fetch/gcstarpluginfetcher.h121
-rw-r--r--src/fetch/googlescholarfetcher.cpp233
-rw-r--r--src/fetch/googlescholarfetcher.h103
-rw-r--r--src/fetch/ibsfetcher.cpp415
-rw-r--r--src/fetch/ibsfetcher.h87
-rw-r--r--src/fetch/imdbfetcher.cpp1208
-rw-r--r--src/fetch/imdbfetcher.h141
-rw-r--r--src/fetch/isbndbfetcher.cpp350
-rw-r--r--src/fetch/isbndbfetcher.h94
-rw-r--r--src/fetch/messagehandler.cpp35
-rw-r--r--src/fetch/messagehandler.h49
-rw-r--r--src/fetch/scripts/Makefile.am30
-rw-r--r--src/fetch/scripts/boardgamegeek.rb235
-rw-r--r--src/fetch/scripts/boardgamegeek.rb.spec7
-rw-r--r--src/fetch/scripts/dark_horse_comics.py399
-rw-r--r--src/fetch/scripts/dark_horse_comics.py.spec7
-rwxr-xr-xsrc/fetch/scripts/fr.allocine.py335
-rw-r--r--src/fetch/scripts/fr.allocine.py.spec7
-rw-r--r--src/fetch/scripts/ministerio_de_cultura.py595
-rw-r--r--src/fetch/scripts/ministerio_de_cultura.py.spec7
-rw-r--r--src/fetch/srufetcher.cpp541
-rw-r--r--src/fetch/srufetcher.h131
-rw-r--r--src/fetch/yahoofetcher.cpp400
-rw-r--r--src/fetch/yahoofetcher.h105
-rw-r--r--src/fetch/z3950-servers.cfg106
-rw-r--r--src/fetch/z3950connection.cpp503
-rw-r--r--src/fetch/z3950connection.h126
-rw-r--r--src/fetch/z3950fetcher.cpp782
-rw-r--r--src/fetch/z3950fetcher.h153
-rw-r--r--src/fetchdialog.cpp753
-rw-r--r--src/fetchdialog.h133
-rw-r--r--src/fetcherconfigdialog.cpp225
-rw-r--r--src/fetcherconfigdialog.h69
-rw-r--r--src/field.cpp594
-rw-r--r--src/field.h395
-rw-r--r--src/fieldcompletion.cpp73
-rw-r--r--src/fieldcompletion.h45
-rw-r--r--src/filehandler.cpp418
-rw-r--r--src/filehandler.h171
-rw-r--r--src/filter.cpp137
-rw-r--r--src/filter.h130
-rw-r--r--src/filterdialog.cpp428
-rw-r--r--src/filterdialog.h170
-rw-r--r--src/filteritem.cpp36
-rw-r--r--src/filteritem.h41
-rw-r--r--src/filterview.cpp266
-rw-r--r--src/filterview.h83
-rw-r--r--src/groupiterator.cpp34
-rw-r--r--src/groupiterator.h43
-rw-r--r--src/groupview.cpp495
-rw-r--r--src/groupview.h198
-rw-r--r--src/gui/Makefile.am43
-rw-r--r--src/gui/boolfieldwidget.cpp61
-rw-r--r--src/gui/boolfieldwidget.h51
-rw-r--r--src/gui/choicefieldwidget.cpp69
-rw-r--r--src/gui/choicefieldwidget.h51
-rw-r--r--src/gui/collectiontypecombo.cpp53
-rw-r--r--src/gui/collectiontypecombo.h33
-rw-r--r--src/gui/combobox.cpp71
-rw-r--r--src/gui/combobox.h52
-rw-r--r--src/gui/counteditem.cpp113
-rw-r--r--src/gui/counteditem.h49
-rw-r--r--src/gui/datefieldwidget.cpp52
-rw-r--r--src/gui/datefieldwidget.h51
-rw-r--r--src/gui/datewidget.cpp279
-rw-r--r--src/gui/datewidget.h74
-rw-r--r--src/gui/fieldwidget.cpp201
-rw-r--r--src/gui/fieldwidget.h91
-rw-r--r--src/gui/imagefieldwidget.cpp54
-rw-r--r--src/gui/imagefieldwidget.h51
-rw-r--r--src/gui/imagewidget.cpp257
-rw-r--r--src/gui/imagewidget.h78
-rw-r--r--src/gui/kwidgetlister.cpp178
-rw-r--r--src/gui/kwidgetlister.h150
-rw-r--r--src/gui/lineedit.cpp150
-rw-r--r--src/gui/lineedit.h72
-rw-r--r--src/gui/linefieldwidget.cpp90
-rw-r--r--src/gui/linefieldwidget.h51
-rw-r--r--src/gui/listboxtext.cpp74
-rw-r--r--src/gui/listboxtext.h50
-rw-r--r--src/gui/listview.cpp347
-rw-r--r--src/gui/listview.h180
-rw-r--r--src/gui/numberfieldwidget.cpp143
-rw-r--r--src/gui/numberfieldwidget.h57
-rw-r--r--src/gui/overlaywidget.cpp104
-rw-r--r--src/gui/overlaywidget.h54
-rw-r--r--src/gui/parafieldwidget.cpp63
-rw-r--r--src/gui/parafieldwidget.h50
-rw-r--r--src/gui/previewdialog.cpp56
-rw-r--r--src/gui/previewdialog.h47
-rw-r--r--src/gui/progress.cpp33
-rw-r--r--src/gui/progress.h39
-rw-r--r--src/gui/ratingfieldwidget.cpp59
-rw-r--r--src/gui/ratingfieldwidget.h50
-rw-r--r--src/gui/ratingwidget.cpp170
-rw-r--r--src/gui/ratingwidget.h75
-rw-r--r--src/gui/richtextlabel.cpp47
-rw-r--r--src/gui/richtextlabel.h46
-rw-r--r--src/gui/stringmapdialog.cpp125
-rw-r--r--src/gui/stringmapdialog.h71
-rw-r--r--src/gui/tabcontrol.cpp77
-rw-r--r--src/gui/tabcontrol.h48
-rw-r--r--src/gui/tablefieldwidget.cpp330
-rw-r--r--src/gui/tablefieldwidget.h74
-rw-r--r--src/gui/urlfieldwidget.cpp98
-rw-r--r--src/gui/urlfieldwidget.h66
-rw-r--r--src/image.cpp162
-rw-r--r--src/image.h99
-rw-r--r--src/imagefactory.cpp611
-rw-r--r--src/imagefactory.h195
-rw-r--r--src/importdialog.cpp382
-rw-r--r--src/importdialog.h71
-rw-r--r--src/isbnvalidator.cpp478
-rw-r--r--src/isbnvalidator.h148
-rw-r--r--src/iso5426converter.cpp883
-rw-r--r--src/iso5426converter.h43
-rw-r--r--src/iso6937converter.cpp597
-rw-r--r--src/iso6937converter.h41
-rw-r--r--src/latin1literal.h90
-rw-r--r--src/lccnvalidator.cpp74
-rw-r--r--src/lccnvalidator.h44
-rw-r--r--src/listviewcomparison.cpp279
-rw-r--r--src/listviewcomparison.h116
-rw-r--r--src/loandialog.cpp268
-rw-r--r--src/loandialog.h82
-rw-r--r--src/loanitem.cpp26
-rw-r--r--src/loanitem.h40
-rw-r--r--src/loanview.cpp234
-rw-r--r--src/loanview.h72
-rw-r--r--src/main.cpp88
-rw-r--r--src/mainwindow.cpp2391
-rw-r--r--src/mainwindow.h534
-rw-r--r--src/newstuff/Makefile.am18
-rw-r--r--src/newstuff/dialog.cpp477
-rw-r--r--src/newstuff/dialog.h101
-rw-r--r--src/newstuff/manager.cpp446
-rw-r--r--src/newstuff/manager.h101
-rw-r--r--src/newstuff/newscript.cpp48
-rw-r--r--src/newstuff/newscript.h60
-rw-r--r--src/newstuff/providerloader.cpp102
-rw-r--r--src/newstuff/providerloader.h84
-rw-r--r--src/observer.h50
-rw-r--r--src/progressmanager.cpp183
-rw-r--r--src/progressmanager.h127
-rw-r--r--src/ptrvector.h322
-rw-r--r--src/reportdialog.cpp220
-rw-r--r--src/reportdialog.h64
-rw-r--r--src/rtf2html/Makefile.am15
-rw-r--r--src/rtf2html/common.h38
-rw-r--r--src/rtf2html/dbg_iter.h67
-rw-r--r--src/rtf2html/fmt_opts.cpp221
-rw-r--r--src/rtf2html/fmt_opts.h154
-rw-r--r--src/rtf2html/rtf2html.cpp531
-rw-r--r--src/rtf2html/rtf2html.h28
-rw-r--r--src/rtf2html/rtf_keyword.cpp107
-rw-r--r--src/rtf2html/rtf_keyword.h1
-rw-r--r--src/rtf2html/rtf_table.cpp235
-rw-r--r--src/rtf2html/rtf_table.h90
-rw-r--r--src/rtf2html/rtf_tools.h65
-rw-r--r--src/statusbar.cpp122
-rw-r--r--src/statusbar.h63
-rw-r--r--src/stringset.h58
-rw-r--r--src/tellico_debug.h156
-rw-r--r--src/tellico_kernel.cpp407
-rw-r--r--src/tellico_kernel.h145
-rw-r--r--src/tellico_map.h41
-rw-r--r--src/tellico_strings.cpp27
-rw-r--r--src/tellico_strings.h26
-rw-r--r--src/tellico_utils.cpp218
-rw-r--r--src/tellico_utils.h80
-rw-r--r--src/tellicorc3
-rw-r--r--src/tellicoui.rc187
-rw-r--r--src/tests/Makefile.am28
-rw-r--r--src/tests/entitytest.cpp19
-rw-r--r--src/tests/isbntest.cpp73
-rw-r--r--src/tests/latin1test.cpp25
-rw-r--r--src/translators/Makefile.am70
-rw-r--r--src/translators/alexandriaexporter.cpp183
-rw-r--r--src/translators/alexandriaexporter.h51
-rw-r--r--src/translators/alexandriaimporter.cpp255
-rw-r--r--src/translators/alexandriaimporter.h72
-rw-r--r--src/translators/amcimporter.cpp294
-rw-r--r--src/translators/amcimporter.h55
-rw-r--r--src/translators/audiofileimporter.cpp424
-rw-r--r--src/translators/audiofileimporter.h69
-rw-r--r--src/translators/bibtex-translation.xml298
-rw-r--r--src/translators/bibtexexporter.cpp326
-rw-r--r--src/translators/bibtexexporter.h63
-rw-r--r--src/translators/bibtexhandler.cpp319
-rw-r--r--src/translators/bibtexhandler.h60
-rw-r--r--src/translators/bibteximporter.cpp312
-rw-r--r--src/translators/bibteximporter.h90
-rw-r--r--src/translators/bibtexmlexporter.cpp182
-rw-r--r--src/translators/bibtexmlexporter.h41
-rw-r--r--src/translators/bibtexmlimporter.cpp163
-rw-r--r--src/translators/bibtexmlimporter.h54
-rw-r--r--src/translators/btparse/Makefile.am18
-rw-r--r--src/translators/btparse/antlr.h561
-rw-r--r--src/translators/btparse/ast.c227
-rw-r--r--src/translators/btparse/ast.h99
-rw-r--r--src/translators/btparse/attrib.h35
-rw-r--r--src/translators/btparse/bibtex.c312
-rw-r--r--src/translators/btparse/bibtex_ast.c63
-rw-r--r--src/translators/btparse/bt_debug.h38
-rw-r--r--src/translators/btparse/btconfig.h220
-rw-r--r--src/translators/btparse/btparse.h378
-rw-r--r--src/translators/btparse/dlgauto.h408
-rw-r--r--src/translators/btparse/dlgdef.h97
-rw-r--r--src/translators/btparse/err.c75
-rw-r--r--src/translators/btparse/err.h700
-rw-r--r--src/translators/btparse/error.c348
-rw-r--r--src/translators/btparse/error.h65
-rw-r--r--src/translators/btparse/format_name.c841
-rw-r--r--src/translators/btparse/init.c42
-rw-r--r--src/translators/btparse/input.c499
-rw-r--r--src/translators/btparse/lex_auxiliary.c939
-rw-r--r--src/translators/btparse/lex_auxiliary.h71
-rw-r--r--src/translators/btparse/macros.c367
-rw-r--r--src/translators/btparse/mode.h3
-rw-r--r--src/translators/btparse/modify.c75
-rw-r--r--src/translators/btparse/my_alloca.h35
-rw-r--r--src/translators/btparse/names.c915
-rw-r--r--src/translators/btparse/parse_auxiliary.c336
-rw-r--r--src/translators/btparse/parse_auxiliary.h32
-rw-r--r--src/translators/btparse/postprocess.c498
-rw-r--r--src/translators/btparse/prototypes.h47
-rw-r--r--src/translators/btparse/scan.c615
-rw-r--r--src/translators/btparse/stdpccts.h31
-rw-r--r--src/translators/btparse/string_util.c695
-rw-r--r--src/translators/btparse/sym.c372
-rw-r--r--src/translators/btparse/sym.h33
-rw-r--r--src/translators/btparse/tex_tree.c414
-rw-r--r--src/translators/btparse/tokens.h41
-rw-r--r--src/translators/btparse/traversal.c187
-rw-r--r--src/translators/btparse/util.c79
-rw-r--r--src/translators/csvexporter.cpp190
-rw-r--r--src/translators/csvexporter.h63
-rw-r--r--src/translators/csvimporter.cpp552
-rw-r--r--src/translators/csvimporter.h107
-rw-r--r--src/translators/dataimporter.h71
-rw-r--r--src/translators/dcimporter.cpp128
-rw-r--r--src/translators/dcimporter.h34
-rw-r--r--src/translators/deliciousimporter.cpp87
-rw-r--r--src/translators/deliciousimporter.h49
-rw-r--r--src/translators/exporter.cpp36
-rw-r--r--src/translators/exporter.h89
-rw-r--r--src/translators/filelistingimporter.cpp274
-rw-r--r--src/translators/filelistingimporter.h72
-rw-r--r--src/translators/freedb_util.cpp376
-rw-r--r--src/translators/freedbimporter.cpp556
-rw-r--r--src/translators/freedbimporter.h85
-rw-r--r--src/translators/gcfilmsexporter.cpp235
-rw-r--r--src/translators/gcfilmsexporter.h46
-rw-r--r--src/translators/gcfilmsimporter.cpp273
-rw-r--r--src/translators/gcfilmsimporter.h60
-rwxr-xr-xsrc/translators/griffith2tellico.py319
-rw-r--r--src/translators/griffithimporter.cpp107
-rw-r--r--src/translators/griffithimporter.h63
-rw-r--r--src/translators/grs1importer.cpp130
-rw-r--r--src/translators/grs1importer.h65
-rw-r--r--src/translators/htmlexporter.cpp815
-rw-r--r--src/translators/htmlexporter.h124
-rw-r--r--src/translators/importer.h137
-rw-r--r--src/translators/libcsv.c490
-rw-r--r--src/translators/libcsv.h84
-rw-r--r--src/translators/onixexporter.cpp199
-rw-r--r--src/translators/onixexporter.h60
-rw-r--r--src/translators/pdfimporter.cpp281
-rw-r--r--src/translators/pdfimporter.h41
-rw-r--r--src/translators/pilotdb/Makefile.am16
-rw-r--r--src/translators/pilotdb/libflatfile/DB.cpp1437
-rw-r--r--src/translators/pilotdb/libflatfile/DB.h166
-rw-r--r--src/translators/pilotdb/libflatfile/Database.cpp331
-rw-r--r--src/translators/pilotdb/libflatfile/Database.h320
-rw-r--r--src/translators/pilotdb/libflatfile/FType.h48
-rw-r--r--src/translators/pilotdb/libflatfile/Field.h119
-rw-r--r--src/translators/pilotdb/libflatfile/ListView.h77
-rw-r--r--src/translators/pilotdb/libflatfile/ListViewColumn.h19
-rw-r--r--src/translators/pilotdb/libflatfile/Makefile.am20
-rw-r--r--src/translators/pilotdb/libflatfile/Record.h45
-rw-r--r--src/translators/pilotdb/libpalm/Block.cpp85
-rw-r--r--src/translators/pilotdb/libpalm/Block.h186
-rw-r--r--src/translators/pilotdb/libpalm/Database.cpp43
-rw-r--r--src/translators/pilotdb/libpalm/Database.h181
-rw-r--r--src/translators/pilotdb/libpalm/Makefile.am15
-rw-r--r--src/translators/pilotdb/libpalm/Record.h168
-rw-r--r--src/translators/pilotdb/libpalm/Resource.h85
-rw-r--r--src/translators/pilotdb/libpalm/palmtypes.h117
-rw-r--r--src/translators/pilotdb/pilotdb.cpp277
-rw-r--r--src/translators/pilotdb/pilotdb.h127
-rw-r--r--src/translators/pilotdb/portability.h72
-rw-r--r--src/translators/pilotdb/strop.cpp589
-rw-r--r--src/translators/pilotdb/strop.h153
-rw-r--r--src/translators/pilotdbexporter.cpp232
-rw-r--r--src/translators/pilotdbexporter.h55
-rw-r--r--src/translators/referencerimporter.cpp71
-rw-r--r--src/translators/referencerimporter.h49
-rw-r--r--src/translators/risimporter.cpp315
-rw-r--r--src/translators/risimporter.h71
-rw-r--r--src/translators/tellico_xml.cpp98
-rw-r--r--src/translators/tellico_xml.h41
-rw-r--r--src/translators/tellicoimporter.cpp1021
-rw-r--r--src/translators/tellicoimporter.h100
-rw-r--r--src/translators/tellicoxmlexporter.cpp505
-rw-r--r--src/translators/tellicoxmlexporter.h80
-rw-r--r--src/translators/tellicozipexporter.cpp133
-rw-r--r--src/translators/tellicozipexporter.h50
-rw-r--r--src/translators/textimporter.cpp29
-rw-r--r--src/translators/textimporter.h42
-rw-r--r--src/translators/translators.h77
-rw-r--r--src/translators/xmlimporter.cpp72
-rw-r--r--src/translators/xmlimporter.h74
-rw-r--r--src/translators/xsltexporter.cpp80
-rw-r--r--src/translators/xsltexporter.h44
-rw-r--r--src/translators/xslthandler.cpp267
-rw-r--r--src/translators/xslthandler.h112
-rw-r--r--src/translators/xsltimporter.cpp112
-rw-r--r--src/translators/xsltimporter.h56
-rw-r--r--src/upcvalidator.cpp133
-rw-r--r--src/upcvalidator.h46
-rw-r--r--src/viewstack.cpp55
-rw-r--r--src/viewstack.h48
-rw-r--r--src/xmphandler.cpp90
-rw-r--r--src/xmphandler.h37
-rw-r--r--subdirs5
-rw-r--r--tellico.desktop27
-rw-r--r--tellico.dtd264
-rw-r--r--tellico.lsm16
-rw-r--r--tellico.tips107
-rw-r--r--tellico.xml12
-rw-r--r--x-tellico.desktop11
-rw-r--r--xslt/MARC21slim2MODS3.xsl2517
-rw-r--r--xslt/MARC21slimUtils.xsl82
-rw-r--r--xslt/Makefile.am29
-rw-r--r--xslt/UNIMARC2MODS3.xsl2920
-rw-r--r--xslt/amazon2tellico.xsl590
-rw-r--r--xslt/arxiv2tellico.xsl277
-rw-r--r--xslt/bluray-logo.pngbin0 -> 1359 bytes
-rw-r--r--xslt/cassette-logo.pngbin0 -> 1042 bytes
-rw-r--r--xslt/cd-logo.pngbin0 -> 2153 bytes
-rw-r--r--xslt/crossref2tellico.xsl121
-rw-r--r--xslt/delicious2tellico.xsl164
-rw-r--r--xslt/discogs2tellico.xsl206
-rw-r--r--xslt/dvd-logo.pngbin0 -> 4387 bytes
-rw-r--r--xslt/entry-templates/Album.xsl497
-rw-r--r--xslt/entry-templates/Compact.xsl294
-rw-r--r--xslt/entry-templates/Default.xsl346
-rw-r--r--xslt/entry-templates/Fancy.xsl444
-rw-r--r--xslt/entry-templates/Makefile.am17
-rw-r--r--xslt/entry-templates/Video.xsl512
-rw-r--r--xslt/gcstar2tellico.xsl503
-rw-r--r--xslt/hddvd-logo.pngbin0 -> 2390 bytes
-rw-r--r--xslt/isbndb2tellico.xsl205
-rw-r--r--xslt/mods2tellico.xsl521
-rw-r--r--xslt/pubmed2tellico.xsl190
-rw-r--r--xslt/record-logo.pngbin0 -> 9306 bytes
-rw-r--r--xslt/referencer2tellico.xsl120
-rw-r--r--xslt/report-templates/Column_View.xsl310
-rw-r--r--xslt/report-templates/Group_Summary.xsl323
-rw-r--r--xslt/report-templates/Group_View.xsl284
-rw-r--r--xslt/report-templates/Image_List.xsl250
-rw-r--r--xslt/report-templates/Loan_View.xsl201
-rw-r--r--xslt/report-templates/Makefile.am21
-rw-r--r--xslt/report-templates/Title_Listing_(Horizontal).xsl146
-rw-r--r--xslt/report-templates/Title_Listing_(Vertical).xsl156
-rw-r--r--xslt/report-templates/Tri-Column.xsl234
-rw-r--r--xslt/shadowAlpha.pngbin0 -> 1670 bytes
-rw-r--r--xslt/tellico-by-author.xsl159
-rw-r--r--xslt/tellico-by-title.xsl120
-rw-r--r--xslt/tellico-common.xsl307
-rw-r--r--xslt/tellico-printing.xsl381
-rw-r--r--xslt/tellico2gcstar.xsl286
-rw-r--r--xslt/tellico2html.js620
-rw-r--r--xslt/tellico2html.xsl625
-rw-r--r--xslt/tellico2onix.xsl149
-rw-r--r--xslt/unixref2tellico.xsl174
-rw-r--r--xslt/vhs-logo.pngbin0 -> 2081 bytes
-rw-r--r--xslt/welcome.html60
-rw-r--r--xslt/xmp2tellico.xsl176
-rw-r--r--xslt/yahoo2tellico.xsl86
717 files changed, 262262 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..4f68927
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Robby Stephenson <robby@periapsis.org>
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..ff1f4b1
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,353 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+----------------------------------------------------------------------------
+
+In addition, as a special exception, the author gives permission to
+link the code of this program with the OpenSSL library released by
+the OpenSSL Project (or with modified versions of OpenSSL that use
+the same license as OpenSSL), and distribute linked combinations
+including the two. You must obey the GNU General Public License in
+all respects for all of the code used other than OpenSSL. If you
+modify this software, you may extend this exception to your version of,
+but you are not obligated to do so. If you do not wish to do so,
+delete this exception statement from your version.
+
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..24344f6
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,2416 @@
+2008-05-24 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.3.2.1.
+ * Fixed en_GB translation to remove context strings.
+
+2008-05-23 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.3.2.
+ * Include Canadian LCC values, patch from Peter Stevenson.
+
+2008-05-19 Robby Stephenson <robby@periapsis.org>
+
+ * Updated entry creation to always add default values. Fixes Debian bug 481639.
+
+2008-04-29 Robby Stephenson <robby@periapsis.org>
+
+ * Improved IMDb search results.
+
+2008-04-15 Robby Stephenson <robby@periapsis.org>
+
+ * When adding a book to a bibliography, set the type to 'book'.
+
+2008-04-11 Robby Stephenson <robby@periapsis.org>
+
+ * Updated LCCN search to validate format.
+ * Updated entry match to compare validated LCCN.
+ * Updated z39.50 search to allow multiple LCCN values.
+
+2008-04-09 Robby Stephenson <robby@periapsis.org>
+
+ * Changed loader to eliminate possible duplicates for fields allowing multiple values (like keywords).
+ * Updated PubMed search to add all keywords.
+ * Fixed PubMed search to use utf8 encoding.
+
+2008-04-08 Robby Stephenson <robby@periapsis.org>
+
+ * Changed XML loader to strip whitespace from non-paragraph values.
+
+2008-04-06 Robby Stephenson <robby@periapsis.org>
+
+ * Added languages and editors to Amazon book import.
+
+2008-03-15 Robby Stephenson <robby@periapsis.org>
+
+ * Updated mods2tellico.xsl to try to capture more of mods info converted from refbase.
+
+2008-03-13 Robby Stephenson <robby@periapsis.org>
+
+ * Updated mods2tellico.xsl to try to capture more of bibtex info converted from wikindx.
+
+2008-03-10 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.3.1.
+ * Added Discogs.com fetcher.
+
+2008-03-06 Robby Stephenson <robby@periapsis.org>
+
+ * Added Google Scholar search.
+
+2008-03-05 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug that prevented using bibtex format for external scripts.
+
+2008-03-03 Robby Stephenson <robby@periapsis.org>
+
+ * Changed "ISBN not found" dialog to only appear if multiple ISBN values are being searched.
+
+2008-03-01 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with SRU format not getting remembered in config dialog.
+ * Fixed bug with entries with multiple titles not getting linked in the HTML export.
+
+2008-02-29 Robby Stephenson <robby@periapsis.org>
+
+ * Added LCCN lookup to z39.50 source.
+ * Added LCCN lookup to SRU source.
+ * Updated CrossRef fetcher to use new unixref format with more data.
+
+2008-02-26 Robby Stephenson <robby@periapsis.org>
+
+ * Added DOI search to Entrez/Pubmed interface.
+ * Fixed bug with some free-form date fields not getting formatted correctly, resulting in a blank string in column view and reports.
+
+2008-02-12 Robby Stephenson <robby@periapsis.org>
+
+ * Improved loader to delay loading linked images as long as possible.
+
+2008-02-11 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed Bibtex import for keywords field.
+
+2008-02-07 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Delicious Library importer to look for cover images.
+ * Updated BoardGameGeek script to grab cover image, patch from
+Sven Werlen.
+
+2008-01-29 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.3.
+ * Fixed bug with stepping through selected entries after editing one.
+
+2008-01-20 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with matching ISBN values for updating entries.
+
+2008-01-11 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.3pre1.
+
+2008-01-09 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Spanish Ministry of Culture script.
+
+2008-01-05 Robby Stephenson <robby@periapsis.org>
+
+ * Updated IMDB search to fix director and TV cast.
+
+2007-12-11 Robby Stephenson <robby@periapsis.org>
+
+ * Added DCOP calls to set the view filter and to show entries.
+ * Improved filter to allow specifying field name with '='.
+
+2007-12-10 Robby Stephenson <robby@periapsis.org>
+
+ * Added importer for Delicious Library files.
+
+2007-12-06 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Dependant field parsing to allow %{id} to grab entry id.
+ * Added context menu option in icon view to change sorting.
+ * Extended the DCOP interface to allow adding and removing entries, reading field values, and setting field values.
+
+2007-11-30 Robby Stephenson <robby@periapsis.org>
+
+ * Added capability to save a link to an image only, instead of saving it to the users image directory. Setting an image field property link=true will make that the default.
+
+2007-11-26 Robby Stephenson <robby@periapsis.org>
+
+ * Updated to allow a "required" property to be included to indicate that a on-empty value should always be present when saving.
+ * Updated to use libcsv from Robert Gamble, allowing newlines
+
+2007-11-25 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with creating filter from group item.
+ * Added Ukrainian translation from Serhij Dubyk Сергій Дубик.
+
+2007-11-15 Robby Stephenson <robby@periapsis.org>
+
+ * Added a sharedmimeinfo file.
+
+2007-11-13 Robby Stephenson <robby@periapsis.org>
+
+ * Added Bibsonomy fetcher.
+ * Added citebase.org fetcher.
+
+2007-11-06 Robby Stephenson <robby@periapsis.org>
+
+ * Added option for importing bibtex in Unicode (UTF-8).
+ * Added importing from Referencer.
+
+2007-11-05 Robby Stephenson <robby@periapsis.org>
+
+ * Added arxiv.org API fetcher.
+
+2007-11-04 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bugs related to compilation with gcc 4.3.
+
+2007-10-27 Robby Stephenson <robby@periapsis.org>
+
+ * Added option for saving images in local relative directory to data file.
+
+2007-10-26 Robby Stephenson <robby@periapsis.org>
+
+ * Added menu command for merging entries, based on patch from Cyril Dangerville.
+
+2007-10-24 Robby Stephenson <robby@periapsis.org>
+
+ * Added CrossRef search for DOI.
+
+2007-10-21 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed list view sorting to take into account automatic formatting.
+ * Fixed date sorting to put empty dates first.
+
+2007-10-19 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed sorting bug for images.
+ * Fixed sorting bug for empty dates in HTML export, patch from Jake Maciejewski.
+
+2007-10-15 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed crashing bug in bibtex importer.
+
+2007-10-14 Robby Stephenson <robby@periapsis.org>
+
+ * Added PDF importer, using exempi XMP library.
+ * Added drag & drop support for PDF importer.
+
+2007-10-13 Robby Stephenson <robby@periapsis.org>
+
+ * Added DOI and URL to default bibtex collection fields.
+
+2007-09-23 Robby Stephenson <robby@periapsis.org>
+
+ * Added data source for using GCstar plugins.
+ * Fixed bug with escaping the image id for file names.
+
+2007-09-22 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2.14.
+
+2007-09-20 Robby Stephenson <robby@periapsis.org>
+
+ * Added importer for Griffith database.
+
+2007-09-10 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Spanish Ministry of Culture script to search out of prints book and add notes field.
+ * Updated tellico2html.js file for searching in HTML export.
+ * Updated GCstar import to parse new XML format in GCstar version 1.2.
+
+2007-08-27 Robby Stephenson <robby@periapsis.org>
+
+ * Updated allocine.fr source script to version 0.4, thanks to Mathias Monnerville.
+ * Updated the Amazon.com search to allow searching for comic books.
+ * Updated the isbndb.com search to allow searching for comic books.
+ * Fixed ISBNdb search.
+
+2007-08-25 Robby Stephenson <robby@periapsis.org>
+
+ * Changed default SRU port from 7090 to 80.
+
+2007-08-23 Robby Stephenson <robby@periapsis.org>
+
+ * Update CSS in HTML export.
+
+2007-08-10 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with yaz_iconv not flushing complete string for z39.50 search.
+
+2007-08-09 Robby Stephenson <robby@periapsis.org>
+
+ * Added MARCXML to possible SRU format.
+ * Fixed bug with MARC stylesheets to work with better with embedded records.
+
+2007-08-03 Robby Stephenson <robby@periapsis.org>
+
+ * Updated entry updating to work with all collection types.
+
+2007-07-28 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2.13.
+
+2007-07-24 Robby Stephenson <robby@periapsis.org>
+
+ * Added spell-check for text and paragraph fields.
+
+2007-07-22 Robby Stephenson <robby@periapsis.org>
+
+ * Added compatibility with yaz3.
+
+2007-07-19 Robby Stephenson <robby@periapsis.org>
+
+ * Added importer for GCstar files.
+ * Fixed bug with namespace handling in Tellico XML loading.
+
+2007-07-14 Robby Stephenson <robby@periapsis.org>
+
+ * Added Copac and National Library of Lithuania to z39.50 list.
+
+2007-07-08 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed crashing bug when adding items to a collection with loans.
+
+2007-07-04 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2.12.
+ * Changed z39.60 search event loop in an attemp to fix some intermittent freezes.
+
+2007-06-26 Robby Stephenson <robby@periapsis.org>
+
+ * Changed Quick Filter to split text on white space and do an AND search.
+ * Bumped automake requirement to version 1.8 or later for macro to work.
+ * Fixed HTML export to not rewrite file location for files referenced in the XSL file which don't exist.
+ * Fixed Column View report to sort numerically when needed.
+ * Fixed Date fields to suppress empty date values.
+ * Fixed Date comparisons to work for single digits, patch from
+Jake Maciejewski.
+ * Fixed Fields Dialog to show warnings when clicking Ok.
+
+2007-06-22 Robby Stephenson <robby@periapsis.org>
+
+ * Added '\%' to bibtex translation table for comment escaping.
+
+2007-05-30 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed potential recursion bug for dependent fields.
+
+2007-05-26 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug that didn't write image size options when printing.
+
+2007-05-09 Robby Stephenson <robby@periapsis.org>
+
+ * Added Turkish translation, thanks to Ali Isingor.
+
+2007-05-08 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2.11.
+
+2007-05-06 Robby Stephenson <robby@periapsis.org>
+
+ * Improved file saving performance by caching image info on load.
+
+2007-05-04 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug that lost some images when loading directly from XML.
+
+2007-04-13 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed sorting for Dependent fields to match on subfields.
+
+2007-04-12 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed BibteXML export to include author.
+ * Fixed book collection conversion to bibliography to set entry type.
+
+2007-04-10 Robby Stephenson <robby@periapsis.org>
+
+ * Updated IMDb search for director and writer.
+ * Fixed CDDB lookup on OpenBSD, patch from Marc Espie.
+
+2007-04-07 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2.10.
+
+2007-04-03 Robby Stephenson <robby@periapsis.org>
+
+ * Improved accuracy and comprehensiveness of merging collections.
+ * Changed collection merge to concatenate paragraph fields.
+ * Fixed bug that hid some field groups after undoing append collection.
+
+2007-04-01 Robby Stephenson <robby@periapsis.org>
+
+ * Added Blu-ray and HD DVD to video formats.
+
+2007-03-31 Robby Stephenson <robby@periapsis.org>
+
+ * Updated ibs.it searching.
+ * Fixed searching to replace all HTML entities.
+ * Fixed character encoding for Alexandria import.
+
+2007-03-29 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Amazon API to 2007-02-22.
+ * Fixed error handling for ISBN-13 searches.
+ * Fixed bug that showed "ISBN Not Found" dialog in error.
+
+2007-03-27 Robby Stephenson <robby@periapsis.org>
+
+ * Cleaned-up up ONIX export a bit.
+ * Fixed Alexandria export.
+ * Fixed importing covers from Alexandria.
+
+2007-03-24 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug that caused some amazon results to be hidden when repeating a search.
+
+2007-03-20 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed hanging bug when stopping a z39.50 search.
+
+2007-03-14 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed crashing bug when undoing a collection import or replacement.
+
+2007-03-01 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2.9.
+
+2007-02-25 Robby Stephenson <robby@periapsis.org>
+
+ * Relaxed MODS processing to allow any result with typeOfResource="text"
+ * Fixed bug with adding space after commas in edit widget.
+ * Fixed bug with formatting of dependent fields always being capitalized.
+
+2007-02-20 Robby Stephenson <robby@periapsis.org>
+
+ * Updated IMDb parsing for alternative titles and certifications.
+
+2007-02-06 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed sorting for rating groups with rating = 10.
+
+2007-02-03 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2.8.
+
+2007-01-22 Robby Stephenson <robby@periapsis.org>
+
+ * Updated CDDB import to grab extd data as comments, and category as keyword.
+
+2007-01-21 Robby Stephenson <robby@periapsis.org>
+
+ * Updated audio file importer to take disc number into account for mp3, ogg, and flac files.
+
+2007-01-13 Robby Stephenson <robby@periapsis.org>
+
+ * Changed IMDB rating to allow float values.
+ * Fixed compile error for z3950 connection, patch from Markus Brueffer.
+
+2007-01-04 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed cleanup for deleting scripts installed from newstuff.
+
+2007-01-03 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed busy cursor hanging in newstuff download dialog.
+
+2006-12-21 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed "ISBN Not Found" dialog to have selectable text.
+
+2006-12-19 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with comparing relative URLs for merging file catalogs.
+
+2006-12-17 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with some results in z39.50 search not showing up,
+ due to search events getting processed out of order.
+
+2006-12-07 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with secondary and tertiary sorting.
+
+2006-12-06 Robby Stephenson <robby@periapsis.org>
+
+ * Bumped the Amazon ECS version to 2006-11-30.
+ * Updated Amazon search to allow ISBN-13 values.
+ * Fixed bug with saving URLs without the protocol.
+ * Changed entry comparison for files to match only on URL value.
+ * Released Tellico 1.2.7.
+
+2006-12-04 Robby Stephenson <robby@periapsis.org>
+
+ * Improved performance for copying and deleting multiple entries.
+
+2006-11-30 Robby Stephenson <robby@periapsis.org>
+
+ * Updated sorting to take title articles into account.
+
+2006-11-29 Robby Stephenson <robby@periapsis.org>
+
+ * Added ISBN hyphenation rules for German, Czech, and Dutch.
+ * Fixed bug that caused image loss when loading from data file.
+
+2006-11-10 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2.6.
+
+2006-11-09 Robby Stephenson <robby@periapsis.org>
+
+ * Improved TV show matching for IMDB.
+
+2006-11-05 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed crashing bug in ProgressItem, reported by Izaak Branderhorst.
+
+2006-11-03 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2.5.
+
+2006-11-01 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed another bug with over-writing images on entry update.
+
+2006-10-24 Robby Stephenson <robby@periapsis.org>
+
+ * Updated yahoo audio search webservice url.
+
+2006-10-18 Robby Stephenson <robby@periapsis.org>
+
+ * Added warning when importing CSV without assigning any fields.
+ * Updated allocine script (v 0.3), from Mathias Monnerville.
+
+2006-10-16 Robby Stephenson <robby@periapsis.org>
+
+ * Added board game collection, patch from Steve Beattie.
+ * Added script for searching boardgamegeek.com, patch from Steve Beattie.
+
+2006-10-15 Robby Stephenson <robby@periapsis.org>
+
+ * Branched 1.2.x series.
+ * Fixed encoding bug with allocine.fr script.
+
+2006-10-14 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2.4.
+
+2006-10-12 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with overwriting images when updating entries.
+
+2006-10-11 Robby Stephenson <robby@periapsis.org>
+
+ * Improved performance on loading and unloading.
+ * Changed Nintendo 'Revolution' to 'Wii'.
+
+2006-10-05 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed off-by-one error in file listing volume name reader.
+ * Update allocine fetcher.
+
+2006-09-25 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with fetch dialog showing all sources, instead of just relevant ones.
+
+2006-09-24 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2.3.
+
+2006-09-20 Robby Stephenson <robby@periapsis.org>
+
+ * Added button to search dialog to get additional results.
+
+2006-09-14 Robby Stephenson <robby@periapsis.org>
+
+ * Updated to work with KDE 3.3.1 or later.
+
+2006-09-09 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with HTML export not including tellico2html.js.
+
+2006-09-07 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug that could cause loss of images.
+ * Fixed URL output in Image List report.
+ * Released Tellico 1.2.2.
+
+2006-09-06 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2.1.
+
+2006-09-05 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed CDDB cache importer to always assume utf-8, as in libkcddb.
+ * Changed bibtex exporter to add braces or quotes around url fields.
+
+2006-09-04 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed infinite loop in file listing importer.
+ * Increased default image cache size to 10 meg.
+ * Reworked image loading to avoid reloading large images as much as possible.
+
+2006-09-02 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with CDDB not working (always using debug for Pink Floyd!)
+
+2006-09-01 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with completion not working in filter dialog.
+ * Fixed bug with template image gradients not getting updated properly.
+
+2006-08-31 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2.
+
+2006-08-30 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed crashing bug when using right-click in list view.
+
+2006-08-16 Robby Stephenson <robby@periapsis.org>
+
+ * Added Abstract and Keywords to default fields for bibliographies.
+
+2006-08-15 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2-pre3.
+
+2006-08-09 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2-pre2.
+
+2006-08-07 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with merging fields in CSV importer.
+
+2006-08-06 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.2-pre1.
+
+2006-08-06 Robby Stephenson <robby@periapsis.org>
+
+ * Added "next" and "prev" buttons to entry editor.
+
+2006-08-04 Robby Stephenson <robby@periapsis.org>
+
+ * Changed HTML export to use libxml2 instead of KHTML for parsing. That should fix the "all text on one line" problem.
+ * Bumped minimum libxml2 verstion to 2.6.0 or greater.
+
+2006-07-30 Robby Stephenson <robby@periapsis.org>
+
+ * Added bundled scripts for allocine.fr, Spanish Minstry of Culture, and Dark Horse Comics, all from Mathias Monnerville.
+
+2005-11-13 Robby Stephenson <robby@periapsis.org>
+
+ * Bumped minimum KDE version to 3.3.
+
+2006-07-18 Robby Stephenson <robby@periapsis.org>
+
+ * Added illustrator field to MODS translator.
+
+2006-07-13 Robby Stephenson <robby@periapsis.org>
+
+ * Changed document saving to remember what format (Zip or XML) was opened, and save the file in the same format.
+
+2006-07-04 Robby Stephenson <robby@periapsis.org>
+
+ * Updated sorting in HTML export to be locale-aware.
+ * Added auto-completion to filter dialog.
+
+2006-06-30 Robby Stephenson <robby@periapsis.org>
+
+ * Improved ISBN-13 compliance.
+
+2006-06-24 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with relative url links in template.
+
+2006-06-22 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed memory leak in image handling.
+
+2006-06-16 Robby Stephenson <robby@periapsis.org>
+
+ * Changed IMDb and Amazon to always use iso-8859-1 encoding for URL.
+
+2006-06-12 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with HTML export and MSIE.
+
+2006-06-11 Robby Stephenson <robby@periapsis.org>
+
+ * Added date stamp to all report templates.
+
+2006-06-07 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed IMDb bug that hid partial name matches for duplicate names.
+ * Implemented workaround for NetAccess::download() that doesn't show download progress info.
+
+2006-06-03 Robby Stephenson <robby@periapsis.org>
+
+ * Added validator for unmodified CueCat bar code reader.
+
+2006-05-07 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.1.6.
+
+2006-05-04 Regis Boudin
+
+ * Added French documentation.
+
+2006-05-04 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug that prevented some images from being written to data directory.
+
+2006-04-22 Robby Stephenson <robby@periapsis.org>
+
+ * Add font and color config to templates.
+
+2006-04-19 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with multiple ISBN search for z29.50.
+ * Fixed "disappearing paragraph" bug in Fancy template.
+ * Fixed name order for IBS searches.
+ * Released Tellico 1.1.5.
+
+2006-04-12 Robby Stephenson <robby@periapsis.org>
+
+ * Added Xbox 360, Revolution and Playstation3 to game collection.
+
+2006-04-11 Robby Stephenson <robby@periapsis.org>
+
+ * Added view config saving for custom collections based on URL.
+ * Fixed crashing bug when deleting and re-adding fields by same name.
+ * Fixed bug with HTML decoding in IMDb plot summary.
+
+2006-04-10 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug that re-added default fields when adding search results.
+
+2006-04-07 Robby Stephenson <robby@periapsis.org>
+
+ * Added OS check (linux only) for enabling cd-text support.
+
+2006-04-06 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Spanish, thanks to Alejandro Hamann and Quique.
+ * Fixed bug with writing temporary files, even when using app data dir.
+
+2006-04-03 Robby Stephenson <robby@periapsis.org>
+
+ * Improved PubMed fetcher to grab URL links.
+
+2006-04-02 Robby Stephenson <robby@periapsis.org>
+
+ * Changed grouping list to be sorted alphabetically.
+ * Fixed OpenOffice.org plugin build for OOo SDK 2.0.2.
+ * Released Tellico 1.1.4.
+
+2006-03-29 Robby Stephenson <robby@periapsis.org>
+
+ * Added referrer to IBS fetcher so images get downloaded.
+
+2006-03-27 Robby Stephenson <robby@periapsis.org>
+
+ * Changed XSL templates to output valid HTML 4.01 Strict, patch from Karl Ove Hufthammer.
+
+2006-03-25 Robby Stephenson <robby@periapsis.org>
+
+ * Added button for installing new templates.
+
+2006-03-24 Robby Stephenson <robby@periapsis.org>
+
+ * Added context menu item in table widget for clearing table.
+
+2006-03-23 Robby Stephenson <robby@periapsis.org>
+
+ * Added template preview button in configuration dialog.
+ * Added field for relative folder path to file catalog listing.
+ * Fixed bug with incorrectly setting document modified when loading images.
+ * Fixed bug with loading loans for entries with non-consecutive ids.
+ * Fixed bug that prevented XSLT files with spaces or other non-encoded characters from being opened.
+ * Fixed bug that caused crashes when changing grouping options
+ for some fields.
+
+2006-03-15 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug that prevented files saved with versions < 0.8 from
+ being opened.
+
+2006-03-12 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.1.3.
+
+2006-03-10 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with comic book template not showing up in a couple of
+ places in the GUI.
+ * Updated MARC2MODS3 stylesheet to MODS 3.1 from LoC.
+ * Added preset z39.50 server list.
+
+2006-03-09 Robby Stephenson <robby@periapsis.org>
+
+ * Added isbndb.com fetcher.
+ * Fixed z39.50 search to use proper encoding for search terms.
+
+2006-03-07 Robby Stephenson <robby@periapsis.org>
+
+ * Changed ISO 5426 converter to grab diaeresis instead of umlaut.
+
+2006-03-05 Robby Stephenson <robby@periapsis.org>
+
+ * Added patch from Karl Ove Hufthammer, for lang-specific sorting.
+ * Released Tellico 1.1.2.
+
+2006-03-04 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed file save permissions to remember group.
+ * Fixed backup file permissions.
+
+2006-03-02 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed mess with shared pointers holding shared pointers holding
+ shared pointers...
+ * Fixed button size in HTML export.
+
+2006-02-28 Robby Stephenson <robby@periapsis.org>
+
+ * Updated fr.po, thanks to Mathias Monnerville.
+ * Fixed GCfilms importer to read running time correctly.
+ * Use IMDb url for updating if available.
+
+2006-02-27 Robby Stephenson <robby@periapsis.org>
+
+ * Added pt_BR, thanks to Claudio Felix.
+
+2006-02-23 Robby Stephenson <robby@periapsis.org>
+
+ * Added dialog for importing new data sources.
+
+ 2006-02-22 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed HTML export to always use relative links.
+ * Fixed Fancy template column widths, patch from Karl Ove Hufthammer.
+
+2006-02-20 Robby Stephenson <robby@periapsis.org>
+
+ * Add Ant Movie Catalog file importer.
+
+2006-02-19 Robby Stephenson <robby@periapsis.org>
+
+ * Allow data sources to overwrite current data when updating.
+
+2006-02-18 Robby Stephenson <robby@periapsis.org>
+
+ * Added dialog to choose from multiple CDDB lookup responses.
+ * Fields can have default values.
+ * Changed default IMDB server to akas.imdb.com.
+
+2006-02-18 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed cleanup when oowriter is closed.
+ * Fixed character encoding for IMDB searches.
+ * Released Tellico 1.1.1.
+ * Branched Tellico 1.1.x.
+
+2006-02-17 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed image linking in HTML export.
+ * Updated admin/ and Makefile.am for recent KDE updates.
+ * Changed installation directory of .desktop file to use xdg_appsdir.
+
+2006-02-14 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed templates to scale images down to max of 150x200.
+
+2006-02-08 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with Video template not showing nationality.
+ * Added ISO 5426 and ISO 6937 character set converters, adapted from MARC4J;
+
+2006-02-07 Robby Stephenson <robby@periapsis.org>
+
+ * Dual-licensed the documentation under the GFDL and the FreeBSD
+ Documentation License.
+ * Released Tellico 1.1.
+
+2006-02-04 Robby Stephenson <robby@periapsis.org>
+
+ * Added track length to CDDB lookup result.
+
+2006-02-01 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with not deleting some temporary files.
+
+2006-01-29 Robby Stephenson <robby@periapsis.org>
+
+ * Updated bibtex-translation.xml, thanks to Norbert Nemec.
+ * Updated es.po, thanks to Alejandro Hamann.
+
+2006-01-25 Robby Stephenson <robby@periapsis.org>
+
+ * Relaxed MODS importer to look for publisher, isbn, or lccn to
+ determine the entry is a book. Previously, a typeOfResource="text"
+ was required.
+ * Allowed z39.50 source to ask for MODS directly.
+ * Added message box for stderr output from scripts.
+ * Added simple GRS-1 importer for z39.50 fetcher.
+
+2006-01-24 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with potential data los for saving image files after
+ changing config option.
+ * Released Tellico 1.1pre3.
+
+2006-01-22 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.1pre2.
+ * Improved entry views with some graphics, a la amaroK.
+
+2006-01-21 Robby Stephenson <robby@periapsis.org>
+
+ * Added drag-n-drop from Mozilla Firefox to image widget.
+ * Changed default behavior to include images in data file, and
+ added a config option.
+ * Added a message box warning about performance when the user
+ first opens a file with more than 100 images.
+
+2006-01-20 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with parsing arguments to external data source scripts.
+
+2006-01-19 Robby Stephenson <robby@periapsis.org>
+
+ * AnimneNfo.com source added by default, and IBS.it added if
+ Italian is in the user's language list.
+ * Alexandria exporter includes publishing year now.
+
+2006-01-17 Robby Stephenson <robby@periapsis.org>
+
+ * Alexandria importer includes publishing year now.
+
+2006-01-15 Robby Stephenson <robby@periapsis.org>
+
+ * Changed file saving to be smart about which images need written
+ to cache. Should improve save-time.
+ * Fixed bug with undo/redo not correctly reverting to old values.
+
+2006-01-14 Robby Stephenson <robby@periapsis.org>
+
+ * Added Russian translation, from Artur Kalimullin.
+
+2006-01-12 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.1pre1.
+ * Added/updated SRU fetcher.
+
+2006-01-11 Robby Stephenson <robby@periapsis.org>
+
+ * Added Internet Bookshop (ibs.it) book source.
+
+2006-01-10 Robby Stephenson <robby@periapsis.org>
+
+ * Added AnimeNfo.com search source.
+
+2006-01-09 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed Debian bug #346414 in hu.po.
+
+2006-01-08 Robby Stephenson <robby@periapsis.org>
+
+ * Changed image loader to read and write images inside the Tellico
+ shared directory to speed up loading, etc.
+
+2005-12-06 Robby Stephenson <robby@periapsis.org>
+
+ * Merged OpenOffice.org interop. Requires SDK for compilation.
+
+2006-01-05 Robby Stephenson <robby@periapsis.org>
+
+ * Added Yahoo! Album Search source.
+ * Added Tri-Column video report template.
+
+2005-12-15 Robby Stephenson <robby@periapsis.org>
+
+ * Expand external app fetcher to include any of the fetch keys.
+
+2005-12-08 Robby Stephenson <robby@periapsis.org>
+
+ * Increased max table columns to 10.
+
+2005-12-07 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Amazon fetcher to allow selecting keywords or not.
+
+2005-12-05 Robby Stephenson <robby@periapsis.org>
+
+ * Changed bibtex behavior to not add braces around capital letters.
+
+2005-11-29 Robby Stephenson <robby@periapsis.org>
+
+ * Moved no-capitalization list to config dialog.
+
+2005-11-28 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Hungarian, from Csaba Zakarias.
+
+2005-11-17 Robby Stephenson <robby@periapsis.org>
+
+ * Added separate UPC searching for Amazon.
+
+2005-11-16 Robby Stephenson <robby@periapsis.org>
+
+ * Added CD-Text reading to FreeDBImporter, plus option to disable
+ compilation in case of platform issues.
+ * Move to Amazon ECS version 4.
+
+2005-11-15 Robby Stephenson <robby@periapsis.org>
+
+ * Added IMDB rating field to fetcher.
+
+2005-11-13 Robby Stephenson <robby@periapsis.org>
+
+ * Bumped minimum KDE version to 3.2 and minimum QT version to 3.2.
+
+2005-11-10 Robby Stephenson <robby@periapsis.org>
+
+ * Custom data source fields are now configurable.
+
+2005-11-07 Robby Stephenson <robby@periapsis.org>
+
+ * Made size of IMDb cast list configurable.
+ * Broke out cite actions into submenu, and added copying bibtex to clipboard.
+
+2005-11-03 Robby Stephenson <robby@periapsis.org>
+
+ * Bumped XML syntax version to 9 to include file catalog and
+ changing default music collection track field to 3 columns.
+
+2005-11-01 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed compilation on GNU/kFreeBSD, Debian bug #336949, patch
+ from Aurelien Jarno.
+
+2005-10-29 Robby Stephenson <robby@periapsis.org>
+
+ * Improved table fields to show column titles.
+ * Changed buttons to a right-click popup.
+
+2005-10-27 Robby Stephenson <robby@periapsis.org>
+
+ * Improved audio file metadata importer to include track length as
+ an additional column in the track field.
+
+2005-10-26 Robby Stephenson <robby@periapsis.org>
+
+ * The audio file importer now checks for track numbers in the file
+ name, patch from Andras Mantia.
+
+2005-10-19 Robby Stephenson <robby@periapsis.org>
+
+ * Added a string store to reduce memory consumption.
+
+2005-10-17 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.0.3.
+
+2005-10-15 Robby Stephenson <robby@periapsis.org>
+
+ * Added buttons for inserting and removing rows from a table.
+
+2005-10-13 Robby Stephenson <robby@periapsis.org>
+
+ * Enabled auto-updating for certain entries and data sources.
+
+2005-10-12 Robby Stephenson <robby@periapsis.org>
+
+ * Updated it.po, from Lorenzo Novaro.
+
+2005-10-11 Robby Stephenson <robby@periapsis.org>
+
+ * New and modified entries now show labels indicating so.
+
+2005-10-08 Robby Stephenson <robby@periapsis.org>
+
+ * Improved status bar.
+
+2005-10-07 Robby Stephenson <robby@periapsis.org>
+
+ * Updated CalendarHandler to compile with KDEPIM 3.5.
+
+2005-10-06 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with bibtex macro names always being imported in lowercase.
+
+2005-10-03 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with initialization, patch from Marco Clemencic.
+
+2005-10-02 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.0.2.
+ * Updated IMDB fetcher.
+
+2005-09-25 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with auto-detecting MARC encoding for z39.50 import.
+
+2005-09-22 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with CSV importer not properly parsing some non-CSV files.
+ * Fixed bug with entry selection in icon view.
+ * Added GCfilms exporter;
+
+2005-09-21 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with showing invalid loan due date.
+ * Added GCfilms importer.
+ * Added IMDB link when fetching info from IMDB.
+ * limited number of cast results form IMDB to 20;
+
+2005-09-20 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.0.1.
+
+2005-09-19 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with loading utf-8 encoded bibtex files.
+
+2005-09-18 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with variable icon sizes in config dialog.
+
+2005-09-16 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug for merging field properties, which mostly showed up
+ as double-colons in music collection tracks.
+ * Fixed crashing bug with modifying filters and cancelling.
+
+2005-09-11 Robby Stephenson <robby@periapsis.org>
+
+ * Added Norwegian Nynorsk translation from Karl Ove Hufthammer.
+
+2005-09-10 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug in audio file metadata import that was overwriting
+ track listings incorrectly.
+ * Fixed crashing bug for selecting groups and entries in group view.
+
+2005-09-09 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.0.
+
+2005-09-05 Robby Stephenson <robby@periapsis.org>
+
+ * Added Polish translaion from Marek Janukowicz.
+
+2005-08-22 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with external application fetcher not reading path
+ entries correctly.
+ * Updated Spanish translation, thanks to Brian Hughes.
+
+2005-08-21 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Swedish, thanks to Peter Landgren.
+ * Added patch from Nix to dynamically resize table columns.
+
+2005-08-20 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.0pre2.
+
+2005-08-14 Robby Stephenson <robby@periapsis.org>
+
+ * Changed audio file metadata to ignore case when doing album
+ comparisons.
+ * Changed collection loader to better compensate for old rating
+ fields.
+ * Changed AddEntry command to act on multiple entries.
+
+2005-08-11 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Dutch translation, thanks to Fred Marchee.
+ * Updated Fininsh translation, thanks to Teuvo Eloranta.
+
+2005-08-06 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 1.0pre1.
+
+2005-08-04 Robby Stephenson <robby@periapsis.org>
+
+ * When exporting HTML, copy any relative images, etc.
+
+2005-08-01 Robby Stephenson <robby@periapsis.org>
+
+ * Strip HTML tags from paragraph export to PilotDB.
+
+2005-07-30 Robby Stephenson <robby@periapsis.org>
+
+ * Make the amazon importer default to medium images instead of none.
+
+2005-07-28 Robby Stephenson <robby@periapsis.org>
+
+ * Make the 'Fancy' template default.
+
+2005-07-01 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 0.13.8.
+
+2005-06-30 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with CSV import parsing.
+
+2005-06-28 Robby Stephenson <robby@periapsis.org>
+
+ * Added license exception for linking to OpenSSL.
+
+2005-06-25 Robby Stephenson <robby@periapsis.org>
+
+ * Added a status message timeout for main window and fetch dialog.
+
+2005-06-23 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed crashing bug for fields with empty categories.
+
+2005-06-22 Robby Stephenson <robby@periapsis.org>
+
+ * Added initial Catalan translation from David Majà Martínez.
+
+2005-06-20 Robby Stephenson <robby@periapsis.org>
+
+ * Added fetcher for reading output from an external application.
+ * Fixed bug with wrong icon size for entry action.
+
+2005-06-17 Robby Stephenson <robby@periapsis.org>
+
+ * Added video game collection type.
+
+2005-06-12 Robby Stephenson <robby@periapsis.org>
+
+ * Added capability for recursively reading all CDDB cache files,
+ based on patch from Marco Hofmann.
+
+2005-06-08 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with file extension defaulting to .bc.
+
+2005-06-02 Robby Stephenson <robby@periapsis.org>
+
+ * Changed Table field to allow up to 5 columns. Deprecated Table2 type.
+
+2005-06-01 Robby Stephenson <robby@periapsis.org>
+
+ * Added Rating field type.
+
+2005-05-31 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with grouping by checkbox fields.
+
+2005-05-30 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Norwegian translation.
+ * Added Unimarc support to z39.50 importer.
+
+2005-05-25 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 0.13.7.
+
+2005-05-25 Robby Stephenson <robby@periapsis.org>
+
+ * Changed bibtex exporter to put crossref'd entries at the
+ end. Only one level of crossref is allowed.
+
+2005-05-19 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with changing between rating and normal choice field.
+
+2005-05-18 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Dutch translation, thanks to Fred Marchee.
+
+2005-05-13 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with clearing table fields.
+ * Added ONIX export, borrowing format from Alexandria.
+
+2005-05-10 Robby Stephenson <robby@periapsis.org>
+
+ * Changed contact email to tellico-users mailing list.
+
+2005-04-27 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed corner case xml element naming for new fields.
+ * Fixed typo on allowed and description in fields editor.
+
+2005-04-10 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with having fields named after xml elements, like
+ entry or field.
+
+2005-04-09 Robby Stephenson <robby@periapsis.org>
+
+ * Added a PubMed search source, thanks to an XSL stylesheet from
+ Michaël Zugaro.
+
+2005-04-08 Robby Stephenson <robby@periapsis.org>
+
+ * Added some accelerators, thanks to patch from Felix Berger.
+
+2005-04-07 Robby Stephenson <robby@periapsis.org>
+
+ * Added Undo/Redo framework.
+
+2005-04-03 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 0.13.6.
+
+2005-03-29 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with adding multiple entries from fetch dialog not
+ added additional images.
+ * Added Portuguese translation, thanks to Ligia Moreira.
+
+2005-03-23 Robby Stephenson <robby@periapsis.org>
+
+ * Changed internet search dialog to clear results when running a
+ new search.
+ * Changed selection so that hidden items are not selected.
+
+2005-03-16 Robby Stephenson <robby@periapsis.org>
+
+ * Added shortcuts for entry grouping and filter.
+
+2005-03-08 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 0.13.5.
+
+2005-03-02 Robby Stephenson <robby@periapsis.org>
+
+ * Updated German translation, thanks to Gerrit Albrecht.
+
+2005-03-01 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed crash for some amazon searches.
+ * Fixed character encoding for Japanese amazon searches.
+
+2005-02-27 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 0.13.4
+
+2005-02-25 Robby Stephenson <robby@periapsis.org>
+
+ * Added a configure param to disable cddb even if kcddb headers found.
+
+2005-02-24 Robby Stephenson <robby@periapsis.org>
+
+ * Updated bibtex translation map, fixing some bugs.
+ * Fixed bug with Amazon search character encoding.
+ * Changed Bibtex handler to convert {MIT} to MIT, importing and exporting.
+
+2005-02-23 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with grouping being enabled for paragraphs.
+
+2005-02-17 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with exporting empty groups in HTML.
+ * Added capability for adding loan due notice to KOrganizer calendar.
+
+2005-02-14 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with RIS importer messing up entry types.
+
+2005-02-10 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 0.13.3.
+
+2005-02-08 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug in configure script for disabling amazon, thanks to
+ Markus Brueffer.
+ * Fixed bug with spin boxes not enabling Apply button in Config Dialog.
+ * Fixed bug with audio file metadata import for compilations.
+
+2005-02-05 Robby Stephenson <robby@periapsis.org>
+
+ * Update some bibtex character translations.
+ * Released Tellico 0.13.2.
+
+2005-02-03 Robby Stephenson <robby@periapsis.org>
+
+ * Updated IMDb fetcher.
+ * Updated bibtex import and export to recognize {X} constructions.
+ * Fixed bug with locale encoding for HTML export.
+ * Changed statusbar to show tooltips for menu items.
+
+2005-02-02 Robby Stephenson <robby@periapsis.org>
+
+ * Added France and Canada locales to Amazon.com sources.
+
+2005-02-01 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with importing RIS with no final space.
+ * Fixed Debian bug #290467 for gcc 4.0 compilation, thanks to Regis Boudin.
+
+2005-01-28 Robby Stephenson <robby@periapsis.org>
+
+ * Removed find dialog since the filter works so much better.
+
+2005-01-27 Robby Stephenson <robby@periapsis.org>
+
+ * Removed option for toggling entry count show in group view.
+ * Added check-out for lending items with view.
+
+2005-01-25 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed Debian bug #292165 with bibtex export of umlauts.
+
+2005-01-21 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Swedish translation, thanks to Peter Landgren.
+
+2005-01-20 Robby Stephenson <robby@periapsis.org>
+
+ * Added saved filters with view.
+ * Changed IMDb cast page to decode HTML entities, thanks to Rafa Kortes.
+
+2005-01-12 Robby Stephenson <robby@periapsis.org>
+
+ * Changed double click in the Internet Search dialog to add the entry.
+
+2005-01-11 Robby Stephenson <robby@periapsis.org>
+
+ * Added collection report dialog.
+
+2005-01-06 Robby Stephenson <robby@periapsis.org>
+
+ * Improved file loading efficiency somewhat.
+
+2005-01-05 Robby Stephenson <robby@periapsis.org>
+
+ * Changed image loading to be on-demand for local zip files.
+
+2004-12-19 Robby Stephenson <robby@periapsis.org>
+
+ * Added DCOP interface for exporting files.
+ * Added vertical line between columns in list view.
+ * Translated xsl entry template names.
+
+2004-12-18 Robby Stephenson <robby@periapsis.org>
+
+ * Added DCOP interface for importing files.
+
+2004-12-17 Robby Stephenson <robby@periapsis.org>
+
+ * Branched to 0.13.x.
+ * Updated audio file importer to use "(Various)" for multi-artist albums.
+
+2004-12-11 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed a bug in PilotDB exporting, I think.
+ * Added PilotDB export support for Date fields.
+ * Released Tellico 0.13.1.
+
+2004-12-10 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed some date formatting.
+
+2004-12-09 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed auto bibtex key generation for empty keys.
+
+2004-12-08 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed Entry View to react to changes in the color palette.
+
+2004-12-06 Robby Stephenson <robby@periapsis.org>
+
+ * Increased maz z39.50 port to 999999.
+ * Fixed some KMAX, KMIN template issues with casts.
+ * Added column shading for detailed view, per KDE bug 59791.
+
+2004-12-03 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Finnish translation, thanks to Tuevo Eloranta.
+ * Updated Norwegian translation, thanks to Leif Mathis Gaup.
+ * Fixed *BSD compile, with patch from Markus Brüffer.
+
+2004-12-01 Robby Stephenson <robby@periapsis.org>
+
+ * Enabled relative URLs in URL fields.
+ * Disabled running executables in URL fields.
+ * Released Tellico 0.13.
+
+2004-11-30 Robby Stephenson <robby@periapsis.org>
+
+ * Removed all the KStaticDeleter references. Don't get fancy.
+ * Updated title sorts to work for articles ending with an
+ apostrophe.
+ * Updated audio file metadata importer to recognize albums with
+ multiple artists and change track list accordingly.
+ * Fixed CSV importer to properly find pre-existing, non-default fields.
+
+2004-11-25 Robby Stephenson <robby@periapsis.org>
+
+ * Added stars for up to a 10 rating.
+ * Added checkmark in entry templates for bool fields.
+
+2004-11-20 Robby Stephenson <robby@periapsis.org>
+
+ * Added Spanish tips translation from ventolera.
+
+2004-11-19 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 0.13pre3.
+
+2004-11-18 Robby Stephenson <robby@periapsis.org>
+
+ * Added command-line options for loading bibtex, MODS, and RIS files.
+
+2004-11-17 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Amazon fetcher to work with more than 10 ISBN.
+ * Updated z39.50 fetcher to work with more than 10 ISBN.
+ * Added language lookup table to mods2tellico.xsl.
+ * Updated lyxpipe cite to auto-generate bibtex key if necessary.
+ * Added "load ISBN list from file" to search dialog.
+
+2004-11-14 Robby Stephenson <robby@periapsis.org>
+
+ * Released Tellico 0.13pre2.
+
+2004-11-12 Robby Stephenson <robby@periapsis.org>
+
+ * Improved printing speed.
+ * Added user and password config for z39.50.
+ * Added address field to default bibliography.
+
+2004-11-10 Robby Stephenson <robby@periapsis.org>
+
+ * Updated French translation, thanks to Regis Boudin.
+ * Fixed layout bug in config dialog.
+
+2004-11-09 Robby Stephenson <robby@periapsis.org>
+
+ * Added fix similar to kde bug 86188 for including linux/cdrom.h.
+ * Changed latex cite to separate multiple cites with ", " instead
+ of "," to better match pybliographer.
+
+2004-11-08 Robby Stephenson <robby@periapsis.org>
+
+ * Added host config to IMDB.
+ * Added image download option to Amazon and IMDB.
+ * Updated kde-common/admin/cvs.sh to allow other automake versions.
+ * Released Tellico 0.13pre1.
+
+2004-11-07 Robby Stephenson <robby@periapsis.org>
+
+ * Added character set config to z39.50.
+ * Changed main document to tellico.xml.
+
+2004-10-31 Robby Stephenson <robby@periapsis.org>
+
+ * Updated initial minimum width to 600 pixels.
+ * Added group selection entry to collection menu.
+ * Updated Find Dialog to remove FromBeginning (didn't make sense)
+
+2004-10-23 Robby Stephenson <robby@periapsis.org>
+
+ * Updated HTML export and printing stylesheets a bit.
+
+2004-10-18 Robby Stephenson <robby@periapsis.org>
+
+ * Added patch to compile on g++ 2.95 from Markus Brueffer.
+
+2004-10-11 Robby Stephenson <robby@periapsis.org>
+
+ * Added patch from wwp to fix saving file on quit.
+
+2004-10-02 Robby Stephenson <robby@periapsis.org>
+
+ * Added confirm message box when deleting an entry.
+
+2004-09-23 Robby Stephenson <robby@periapsis.org>
+
+ * Changed default file textension to .tc.
+
+2004-09-15 Robby Stephenson <robby@periapsis.org>
+
+ * Added Unrated certification to default video collection.
+
+2004-09-14 Robby Stephenson <robby@periapsis.org>
+
+ * Renamed Bookcase to Tellico
+ * Added IMDB fetcher.
+ * Incremented DTD version to 7, changed root element to tellico.
+ * Changed zip file to use maindoc.xml as do the KOffice files.
+
+2004-09-10 Robby Stephenson <robby@periapsis.org>
+
+ * Added new icons from Virginie Quesnay.
+
+2004-09-09 Robby Stephenson <robby@periapsis.org>
+
+ * Updated French translation, thanks to Regis Boudin.
+ * Removed libcdda (cdparanoia) dependency, using cd-discid code
+ instead.
+ * Added rating widget in entry editor, using stars.
+
+2004-09-07 Robby Stephenson <robby@periapsis.org>
+
+ * Really fixed gcc 2.95 compilation.
+ * Added RIS importer.
+
+2004-09-02 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase 0.11.
+
+2004-09-01 Robby Stephenson <robby@periapsis.org>
+
+ * Added FreeDB importer.
+
+2004-08-27 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed compile on gcc 2.95.
+
+2004-08-26 Robby Stephenson <robby@periapsis.org>
+
+ * Added Alexandria importer.
+ * Added Alexandria exporter.
+
+2004-08-25 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Norwegian translation, thanks to Leif Mathis Gaup.
+ * Read album covers from .directory files in audio file importer.
+
+2004-08-24 Robby Stephenson <robby@periapsis.org>
+
+ * Added support for reading audio file meta-data.
+
+2004-08-22 Robby Stephenson <robby@periapsis.org>
+
+ * Updated paragraph fields to remember line-breaks.
+ * Released Bookcase 0.10.
+
+2004-08-20 Robby Stephenson <robby@periapsis.org>
+
+ * Added HTML formatting to paragraphs in entry templates.
+ * Updated German translation, thanks to Gerrit M. Albrecht.
+
+2004-08-18 Robby Stephenson <robby@periapsis.org>
+
+ * Added Latin1Literal class to speed up string comparisons.
+ * Added MODS import menu item.
+
+2004-08-10 Robby Stephenson <robby@periapsis.org>
+
+ * Added "export selected entries only" option.
+
+2004-08-09 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed UI file location.
+ * Released Bookcase 0.10pre2.
+
+2004-08-08 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase 0.10pre1.
+ * Added entry icon to fetch dialog button.
+
+2004-08-03 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug for exporting HTML for entries with multiple titles.
+ * Changed HTML export to put entry files in separate directory.
+ * Added link to parent collection file for entry templates.
+
+2004-08-01 Robby Stephenson <robby@periapsis.org>
+
+ * Updated French translation, thanks to Rui Nibau.
+ * Changed to show a spinbox for single number values;
+
+2004-07-30 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with capitalization of words split by dash or comma,
+ and ending with apostrophes.
+
+2004-07-13 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bugs with enabling apply/ok buttons in fields dialog for
+ extended properties, and disappearing groups when renaming fields.
+
+2004-07-02 Robby Stephenson <robby@periapsis.org>
+
+ * Added collection and group view in stack.
+
+2004-06-26 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with copying selected entries.
+
+2004-06-21 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed gcc 3.4 compilation bug in src/translators/btparse/err.h
+
+2004-06-07 Robby Stephenson <robby@periapsis.org>
+
+ * Update Norwegian translation, thanks to Leif Mathis Gaup.
+
+2004-05-27 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase 0.9.3.
+ * Updated italian translation, thanks to FaUsT.
+
+2004-05-25 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed crashing bug for exporting when no fields can be grouped.
+
+2004-05-24 Robby Stephenson <robby@periapsis.org>
+
+ * Restructured ISBN code to get rid of some old cruft.
+ * Added patch from Regis Boudin to add French ISBN formatting and
+ remove old copyright restricted ISBN code.
+
+2004-05-22 Robby Stephenson <robby@periapsis.org>
+
+ * Added entry group templates.
+
+2004-05-19 Robby Stephenson <robby@periapsis.org>
+
+ * Changed focus to move to next entry when one is deleted.
+ * Changed document loader to allow i18n attribute indicate translation.
+ * Fixed bug with empty group names.
+
+2004-05-17 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase 0.9.2.
+
+2004-05-15 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with xslt import with libxml < 2.6.
+ * Fixed bug with losing extended properties when cloning fields/
+
+2004-05-10 Robby Stephenson <robby@periapsis.org>
+
+ * Added Amazon fetcher.
+ * Added SRU Fetcher.
+
+2004-05-07 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with XSLT importer.
+ * Added MODS XSLT importer file.
+
+2004-05-06 Robby Stephenson <robby@periapsis.org>
+
+ * Branched 0.9.x
+
+2004-05-02 Robby Stephenson <robby@periapsis.org>
+
+ * Changed Fields Dialog to close when creating a new collection or opening one.
+ * Removed GCJ/java checks from configure.
+ * Released Bookcase 0.9.1
+
+2004-04-30 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed i18n extraction for UI and gettext extensions.
+ * Removed Japanese translation because of encoding errors.
+ * Updated CSV import to know about current fields when appending or merging
+
+2004-04-29 Robby Stephenson <robby@periapsis.org>
+
+ * Updated German translation from Gerrit Albrecht.
+
+2004-04-27 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with lyxpipe using LYXSRV insted of LYXCMD.
+ * Changed quick filter to wait 200 ms before updating the filter.
+
+2004-04-21 Robby Stephenson <robby@periapsis.org>
+
+ * Added wait cursor for file saving.
+ * Fixed bug with created a double collection when failing to load the initial file.
+ * Make sure column view updates when an image is cleared.
+
+2004-04-18 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase 0.9.
+
+2004-04-16 Robby Stephenson <robby@periapsis.org>
+
+ * Improved visibilty of image size in Fancy.xsl.
+ * Updated Italian translation, thanks to FaUsT.
+ * Updated Finnish translation, thanks to Teuvo.
+ * Added hidden pref for pixmap size in detailed view.
+ * Changed HTML exporter to use titles as filenames.
+
+2004-04-13 Robby Stephenson <robby@periapsis.org>
+
+ * Added hidden preference for pilotdb export charset encoding.
+
+2004-04-09 Robby Stephenson <robby@periapsis.org>
+
+ * Improved bibtex export to detect duplicates keys and add 'a'b,
+ 'b', etc.
+ * Released Bookcase 0.9pre1
+
+2004-03-26 Robby Stephenson <robby@periapsis.org>
+
+ * Updated printing and HTML export to include images.
+ * Updated Detailed View to show images, too.
+
+2004-03-25 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Italian translation, thanks to FaUsT.
+ * Changed toolbar icon for New Entry to collection icon on top of
+ empty mime type.
+
+2004-03-24 Robby Stephenson <robby@periapsis.org>
+
+ * Added menu item in group view for filtering on groups.
+ * Added config options for image sizes in printout.
+
+2004-03-22 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed another bug with HTML export character encoding.
+ * Added config panel for bibtex quotation style and lyxpipe location
+
+2004-03-20 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed Paragraph fields to properly signal modified in the Entry Editor.
+ * Fixed crashing bug for fields with nothing but whitespace in the datafile.
+ * Updated printing stylesheet so that images can be included.
+
+2004-03-19 Robby Stephenson <robby@periapsis.org>
+
+ * Changed document opening so that if the first field has the name
+ of "_default", all the default fields will be added.
+
+2004-03-17 Robby Stephenson <robby@periapsis.org>
+
+ * Changed Dependent fields to allow grouping.
+ * Changed Fields Dialog to allow changing the field types, in some
+ limited cases.
+
+2004-03-15 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed crashing bug in PilotDB export with images.
+ * Fixed bug with "other" delimiter freezing the app.
+
+2004-03-13 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with trying to reopen Untitled after converting to a bibliography.
+ * Added support for lyxpipe and citing entries in bibliography.
+
+2004-03-12 Robby Stephenson <robby@periapsis.org>
+
+ * Changed to be more aggressive in creating URL fields on Bibtex import.
+
+2004-03-10 Robby Stephenson <robby@periapsis.org>
+
+ * Added Compact and Fancy entry templates.
+ * Released Bookcase 0.8.5.
+
+2004-03-07 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug in Video template for when there's no Cast template.
+ * Fixed bug with detecting old versions of gcc and vector::at.
+
+2004-03-05 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with filter dialog layout and KDE 3.2.
+
+2004-03-04 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with corrupt zip files when more than one entry
+ references the same image.
+
+2004-02-28 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed the gcc 2.95 compile bug for sure.
+
+2004-02-25 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed crashing bug in Data::Entry::field().
+ * Fixed XSLTHandler to work for URLs, so XSLT files can reference
+ other files.
+
+2004-02-22 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with HTML entities in XSLT stylesheet params.
+
+2004-02-20 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with duplicate menu items in KDE 3.2.x.
+ * Fixed bug to properly reorder categories when reordering fields.
+ * Released Bookcase 0.8.4.
+
+2004-02-19 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed auto-capitalize and auto-format to take affect immediately.
+
+2004-02-18 Robby Stephenson <robby@periapsis.org>
+
+ * Added Czech translation, thanks to Robert Kratky.
+
+2004-02-17 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed compilation issues for gcc 2.95 and FreeBSD.
+ * Changed the Config Dialog to use a semi-colon to separated the articles, prefixes, and suffixes instead of a comma, for consistency. They're still saved in the config file with a comma, though, so old options should be fine.
+
+2004-02-14 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed problem when trying to reopen last file and getting error.
+ * Added drag & drop support for the image widget.
+
+2004-02-13 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Estonian translation, from Toomas Nigola.
+ * Changed to remember sorting config in group view.
+
+2004-02-12 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed crashing bug when renaming a single-category field.
+
+2004-02-11 Robby Stephenson <robby@periapsis.org>
+
+ * Changed Entry Editor to redo page layout when deleting fields.
+ * Added merge functionality when importing collections.
+ * Fixed bug with exporting HTML in non-utf8.
+
+2004-02-09 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Spanish translation, thanks to Quique.
+ * Added sorting by group count.
+
+2004-02-07 Robby Stephenson <robby@periapsis.org>
+
+ * Added workaround for layout bug in Keramik style.
+
+2004-02-04 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed saving visible columns yet again.
+ * Changed XSLT parser to prevent all network calls.
+ * Fixed crashing bug when deleting a field.
+ * Fixed compilation bug when using libxml > 2.6.0 but libxslt < 1.1.
+ * Released Bookcase 0.8.3.
+
+2004-02-04 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed file truncation for file with some Unicode characters.
+ * Released Bookcase 0.8.2.
+
+2004-02-03 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase 0.8.1.
+
+2004-02-02 Robby Stephenson <robby@periapsis.org>
+
+ * Added Album entry template.
+ * Added Finnish translation, thanks to Teuvo Eloranta.
+ * Added --with-xml-catalog configure option.
+
+2004-01-30 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed compile bug with src/Makefile.am and libxslt.
+ * Fixed bug with $datadir param in Default entry template.
+ * Added Video entry template.
+ * Added EAN to ISBN conversion for 978 and 979 codes. Patch from Martijn Pieters.
+
+2004-01-27 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with Select All not working.
+ * Fixed some compilation issues.
+ * Updated French translation from Rui Nibau.
+
+2004-01-25 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed DTD for new collections.
+ * Updated some accel keys.
+ * Changed Requires to KDE 3.1 or higher since KZip is used.
+ * Released Bookcase 0.8.
+
+2004-01-23 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase 0.8pre1
+
+2004-01-22 Robby Stephenson <robby@periapsis.org>
+
+ * Added Finnish translation from Teuvo Eloranta.
+ * Added "Export to XML" option since file format is Zip now.
+ * Switched to new XML parser in libxml2 > 2.6.0
+
+2004-01-13 Robby Stephenson <robby@periapsis.org>
+
+ * Added new Collection menu.
+
+2004-01-09 Robby Stephenson <robby@periapsis.org>
+
+ * Changed entry method for bibtex string macros. Triple-clicking on list view items is stupid.
+
+2004-01-08 Robby Stephenson <robby@periapsis.org>
+
+ * Added zip file format for collections with images.
+
+2004-01-01 Robby Stephenson <robby@periapsis.org>
+
+ * Added cut, copy, and paste functions.
+ * Added new entry and copy entry functions.
+ * Added find previous, select all, and deselection functions.
+
+2003-12-31 Robby Stephenson <robby@periapsis.org>
+
+ * Changed double clicking an entry to show the editor.
+ * Moved entry edit widget to dialog box.
+
+2003-12-13 Robby Stephenson <robby@periapsis.org>
+
+ * Updated French translation, thanks to RNB.
+
+2003-12-11 Robby Stephenson <robby@periapsis.org>
+
+ * Added image fields.
+ * Changed auto-completion to account for fields with multiple values.
+
+2003-12-07 Robby Stephenson <robby@periapsis.org>
+
+ * Updated Norwegian translation, thanks to Leif Mathis Gaup.
+
+
+2003-11-25 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug in remembering visible columns for custom fields.
+ * Added some speed-ups in loading time.
+ * Released Bookcase 0.7.2
+
+2003-11-24 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed another ISBN format bug for non-english publishers.
+
+2003-11-23 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with auto-capitalization when global setting was turned off.
+ * Fixed bug with not saving options for empty collections.
+ * Fixed bug with reordering visible fields.
+
+2003-11-21 Robby Stephenson <robby@periapsis.org>
+
+ * Added Pilot-DB export option.
+ * Fixed bug to update status line after deleting entries.
+
+2003-11-12 Robby Stephenson <robby@periapsis.org>
+
+ * Added Derived field type for concatenating values from other fields.
+ * Added default collections for trading cards, coins, stamps, comic books, and wines.
+
+2003-11-11 Robby Stephenson <robby@periapsis.org>
+
+ * Updated German tranlation, thanks to Gerrit Albrecht.
+ * Added Swedish translation, thanks to Karolina Lindqvist.
+ * Fixed bug with adding 2-column table.
+ * Cut the 0.7.x branch.
+ * Added Derived field type.
+
+2003-11-09 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed charset encoding bug.
+ * Fixed compile for GCC 2.96.
+ * Changed bibtex and CSV export to default to locale encoding.
+ * Fixed bug with field editor not updating title.
+ * Released Bookcase 0.7.1.
+
+2003-11-08 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase 0.7.
+
+2003-11-05 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed the tips file translation issue.
+ * Released Bookcase 0.7pre2.
+
+2003-11-03 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed ISBN formatting bug for non-english language publishers.
+ * Released Bookcase 0.7pre1.
+
+2003-10-25 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed documentation compile error for KDE 3.2.
+ * Added CSV importer.
+ * Changed Bibtexml importer and exporter to use internal classes rather than XSL stylesheets.
+
+2003-10-24 Robby Stephenson <robby@periapsis.org>
+
+ * Added string macro editor for Bibtex collections.
+ * Printing now only prints visible entries by default.
+
+2003-10-21 Robby Stephenson <robby@periapsis.org>
+
+ * Added new group for all attributes formatted as names, so Editors and Authors can be grouped together.
+
+2003-10-10 Robby Stephenson <robby@periapsis.org>
+
+ * Changed printing to print columns as shown in the view, and group by the current grouping.
+ * Removed old options for printing fields selection.
+
+2003-10-04 Robby Stephenson <robby@periapsis.org>
+
+ * Added capability to reorder fields in field editor.
+
+2003-10-03 Robby Stephenson <robby@periapsis.org>
+
+ * Imported btparse library code to use for importing Bibtex files. It has a lot of warnings, but none should be fatal.
+
+2003-09-23 Robby Stephenson <robby@periapsis.org>
+
+ * Added "Bibtex Field" to default Bibtex collections fields to aid in exporting to Bibtex and Bibtexml.
+ * Bumped document syntax to 4.
+ * Changed "attribute" elements in document file to "field".
+ * Changed all unit elements to "entry" rather than the unit name.
+ * Changed Boolean values to save as "true" instead of an implicit value.
+ * Added CSV exporter.
+
+2003-09-12 Robby Stephenson <robby@periapsis.org>
+
+ * Added 2-column Table field type.
+
+2003-09-09 Robby Stephenson <robby@periapsis.org>
+
+ * Changed boolean values to show title in group view.
+
+2003-09-03 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug when deleting multiple books from detailed listview.
+
+2003-08-31 Robby Stephenson <robby@periapsis.org>
+
+ * Changed field completion to be case-insensitive.
+ * Fixed bug with saving listview columns.
+
+2003-08-16 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with reopening last saved file.
+
+2003-08-12 Robby Stephenson <robby@periapsis.org>
+
+ * Added French translation from RNB.
+
+2003-08-08 Robby Stephenson <robby@periapsis.org>
+
+ * Added menu item for configuring toolbars.
+ * Added menu item for configuring shortcut keys.
+
+2003-07-31 Robby Stephenson <robby@periapsis.org>
+
+ * Added Table field type.
+
+2003-07-30 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug in saving visible columns.
+ * Improved loading time.
+
+2003-07-29 Robby Stephenson <robby@periapsis.org>
+
+ * Implemented adding file extension (.bc) when using File->Save As and an extension filter is shown.
+ * Added status bar text showing number of selected books when more than 1 is selected.
+
+2003-07-24 Robby Stephenson <robby@periapsis.org>
+
+ * Added menu comands for showing/hiding the group view and editor.
+
+2003-07-23 Robby Stephenson <robby@periapsis.org>
+
+ * Added "--nofile" command line option for bypassing the "Open last file" config setting.
+ * Added "Tip of the Day" dialog.
+ * Changed default for showing unit count to true.
+ * Changed Year field type to generic Number.
+ * Improved sorting to sort numerically for Number fields.
+ * Added Default button to Field Editor dialog.
+ * Added additional format option to never capitalize or format.
+ * Fixed last open file option to no longer be over-written when Bookcase is exited with an empty document.
+ * Cut the 0.6.x branch.
+
+2003-07-22 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed crashing bug in "Edit Fields" dialog.
+
+2003-07-21 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase 0.6.5
+
+2003-07-09 Robby Stephenson <robby@periapsis.org>
+
+ * Added Estonian translation from Toomas Nigola.
+
+2003-07-07 Robby Stephenson <robby@periapsis.org>
+
+ * Updated German translation from Ulf-Diether Ehlert.
+
+2003-07-01 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed translation bug with category names.
+ * Added Bulgarian translation from Boyan Ivanov.
+
+2003-06-25 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed sorting bug for empty fields.
+ * Released Bookcase 0.6.4
+
+2003-06-19 Robby Stephenson <robby@periapsis.org>
+
+ * Changed focus to first tab when adding new book.
+ * Disabled multiple value option for title field in field editor.
+ * Fixed bug with completion object not being updated when a field is changed to all auto-completion.
+ * Fixed drawing bug with toolbar label background.
+
+2003-06-17 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with surname matching too much with periods in regexp.
+ * Added Japanese translation from Linux Magazine.
+ * Added Dutch translation from Liese De Vos.
+
+2003-05-30 Robby Stephenson <robby@periapsis.org>
+
+ * Fix crashing bug when opening the filter dialog on KDE 3.0.
+
+2003-05-27 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase 0.6.3
+
+2003-05-26 Robby Stephenson <robby@periapsis.org>
+
+ * Added feature where the column view remembers the previous sorted column, so that items with the same sort key are subsequently sorted by previous column.
+
+2003-05-25 Robby Stephenson <robby@periapsis.org>
+
+ * Add Spanish translation, thanks to Quique.
+ * Updated Norwegian translation, thanks to Leif Mathis.
+ * Fix bug with collapse/expand all not working in group view.
+ * Fix bug with "Find" not properly traversing the collection.
+ * Fix bug with sorted column not being saved between document loads.
+ * Fix bug with changed category not being reflected in edit widget.
+ * Fix bug with name prefixes not being limited to word boundaries.
+
+2003-05-11 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase 0.6.2
+
+2003-05-10 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with custom fields not showing up in column popup menu.
+ * Fixed crashing when selecting a different book after modifying the current one and not saving it.
+ * Fixed icon bug for column view.
+ * Prettied-up some of layout code.
+
+2003-05-09 Robby Stephenson <robby@periapsis.org>
+
+ * Added Norwegian translation from Leif Mathis Gaup.
+ * Fixed printing bug for books with multiple groups.
+
+2003-05-06 Robby Stephenson <robby@periapsis.org>
+
+ * Changed initial file opening so that if a new empty file was the last viewed, then no recent file is opened at next startup.
+ * Fixed bug with initial collection not updating edit widgets.
+
+2003-05-05 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase version 0.6.1
+ * Fixed automake 1.7 error with configure.in.in
+ * Fixed UIC variable usage, primarily for *BSD platforms
+ * Fixed double encoding bug on bibtexml inport
+ * Fixed wrong namespace on bibtexml export
+ * Changed to use KAcceleratorManager for keyboard accels on tabs
+ * Fixed bug with the group view icon not getting changed back to the folder
+
+2003-05-03 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with editing multiple books and getting asked every time if I'm sure.
+ * Changed modified field names in the "Edit Fields" dialog to be colored, an din italic font instead of having an asterisk in front.
+
+2003-05-02 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase version 0.6
+ * Changed Bibtex export to use the Locale character encoding instead of UTF-8
+
+2003-04-22 Robby Stephenson <robby@periapsis.org>
+
+ * Added a URL attribute type
+ * Changed articles, surname prefixes, and suffixes to be case-insensitive so the config value no longer has to include both capitalized and lower-case values
+ * Broke out the attribute format flag for cleaner code
+
+2003-04-13 Robby Stephenson <robby@periapsis.org>
+
+ * Added multiple selection, batch editing
+
+2003-04-12 Robby Stephenson <robby@periapsis.org>
+
+ * Added RegExp Editor button to find dialog
+ * Added Quick and Advanced filtering in the detailed list view
+
+2003-04-10 Robby Stephenson <robby@periapsis.org>
+
+ * Added new "person" icon for grouping when the group is a name
+
+2003-04-09 Robby Stephenson <robby@periapsis.org>
+
+ * Convert from KTabCtrl to QTabWidget, which has more documentation and is actively developed
+
+2003-04-08 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with column order not retained on save
+
+2003-04-05 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed bug with validating multiple copyright years
+
+2003-03-25 Robby Stephenson <robby@periapsis.org>
+
+ * Added surname prefixes like 'de' and 'von'
+
+2003-03-23 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed debug mistake.
+ * Released Bookcase version 0.5.2a
+
+2003-03-22 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase version 0.5.2
+
+2003-03-21 Robby Stephenson <robby@periapsis.org>
+
+ * Added German translation from Gerrit M. Albrecht
+ * Fixed bugs with empty suffix and article list
+ * Fixed some i18n issues
+
+2003-03-18 Robby Stephenson <robby@periapsis.org>
+
+ * Added Hungarian translation from Marcel Hilzinger
+
+2003-03-15 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed types and compile problems. Thanks, Dre!
+ * Released Bookcase version 0.5.1
+
+2003-03-14 Robby Stephenson <robby@periapsis.org>
+
+ * Put the book count in color.
+ * Took out general export function for now.
+ * Released Bookcase version 0.5
+
+2003-03-07 Robby Stephenson <robby@periapsis.org>
+
+ * Added a new printing page in the configuration dialog
+ * Added a checkmark pixmap for the boolean fields
+ * Added a header menu to be able to select which fields to show in
+ the detailed list view
+
+2003-03-02 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed character encoding bug for latin2
+
+2003-01-25 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed focus bug
+
+2003-01-19 Robby Stephenson <robby@periapsis.org>
+
+ * Changed FORMAT_VERSION to 2
+ * Changed document format so that attributes which allow multiple
+ entries are saved in multiple XML elements
+ * Changed "keywords" attribute to "keyword"
+ * Added check for document format version so that incompatible versions
+ are not loaded. Older versions will be properly loaded, but once saved,
+ previous versions of Bookcase will not load the new files properly.
+ * Changed "Language" and "Copyright Year" to allow multiple entries.
+
+2002-12-12 Robby Stephenson <robby@periapsis.org>
+
+ * Added namespaces to document file
+
+2002-12-11 Robby Stephenson <robby@periapsis.org>
+
+ * Added import from Bibtexml using XSLT
+
+2002-12-08 Robby Stephenson <robby@periapsis.org>
+
+ * Added export to Bibtex using XSLT
+ * Added export to Bibtexml using XSLT
+
+2002-12-03 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase version 0.4.1
+ * Added a Romanian translation from Iulian Ursache <iulianu@cs.tuiasi.ro>
+
+2002-11-29 Robby Stephenson <robby@periapsis.org>
+
+ * Fixed compile problems with gcc 2.95
+
+2002-11-24 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase version 0.4
+ * Printing improvements in XSLT layout
+
+2002-11-10 Robby Stephenson <robby@periapsis.org>
+
+ * Added an Italian translation from FaUsT <faust@inventati.org>
+
+2002-11-05 Robby Stephenson <robby@periapsis.org>
+
+ * Added a new toolbar for changing the grouping of the units
+ * Changed the bookcase.spec file to add proper files
+
+2002-10-20 Robby Stephenson <robby@periapsis.org>
+
+ * Released Bookcase version 0.3
+
+2002-08-27 Robby Stephenson <robby@periapsis.org>
+
+ * Added two new XSLT files
+ * Added printing support using KHTML
+ * Added RPM spec file to automake
+
+2002-02-21 Robby Stephenson <robby@radiojodi.com>
+
+ * Released Bookcase version 0.2
+
+2002-02-20 Robby Stephenson <robby@radiojodi.com>
+
+ * Added BCColumnView::slotShowUnit() so to ensure that the proper listview in the stack is shown.
+ * Added BCAttribute::capitalize for auto capitalization of names and titles.
+
+2002-02-08 Robby Stephenson <robby@radiojodi.com>
+
+ * Changed selection behavior so the two listviews do not sync now. Clicking in one clears the other.
+
+2002-02-03 Robby Stephenson <robby@radiojodi.com>
+
+ * Added article and suffix list to options in config dialog.
+
+2002-01-11 Robby Stephenson <robby@radiojodi.com>
+
+ * BCListView is now BCColumnView and can flip between different collections. Woo-hoo! Now multiple collections behave properly. Also started adding configuration options.
+
+2002-01-10 Robby Stephenson <robby@radiojodi.com>
+
+ * bctabcontrol.{h,cpp} Need KTabCtl::showTab to be public, so subclassed it.
+
+2002-01-10 Robby Stephenson <robby@radiojodi.com>
+
+ * configdialog.{h,cpp} Added beginnings of configuration dialog.
+
+2001-12-06 Robby Stephenson <robby@radiojodi.com>
+
+ * bcgroupview.cpp, bcattribute.cpp Fixed the bug for formatting names with suffixes like Jr.
+
+2001-11-05 Robby Stephenson <robby@radiojodi.com>
+
+ * bookcase.h Removed the File->Close() action item.
+
+2001-11-05 Robby Stephenson <robby@radiojodi.com>
+
+ * bcgroupview.cpp Fixed the bug where clicking the collapse or expand menu item on a BCUnitItem caused the pixmap to change to a folder.
+
+2001-11-04 Robby Stephenson <robby@radiojodi.com>
+
+ * Released Bookcase version 0.1
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..02a4a07
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,167 @@
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes a while. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 4. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment. Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory. After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Use and save the results of the tests in FILE instead of
+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for
+ debugging `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..016817a
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,128 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+SUBDIRS = src po doc icons xslt
+
+ADMIN_DIST = \
+admin/acinclude.m4.in \
+admin/am_edit \
+admin/am_edit.py \
+admin/conf.change.pl \
+admin/config.pl \
+admin/libtool.m4.in \
+admin/Makefile.common
+
+EXTRA_DIST = \
+COPYING ChangeLog INSTALL README TODO \
+tellico.lsm tellico.dtd x-tellico.desktop \
+configure.in.in AUTHORS NEWS tellico.tips \
+tellico.desktop tellico.xml $(ADMIN_DIST)
+
+####### kdevelop will overwrite this part!!! (end)############
+# not a GNU package. You can remove this line, if
+# have all needed files, that a GNU package needs
+AUTOMAKE_OPTIONS = foreign
+
+KDE_OPTIONS = noautodist
+
+#$(top_srcdir)/configure.in: configure.in.in $(top_srcdir)/subdirs
+$(top_srcdir)/configure.in: configure.in.in
+ cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common subdirs
+ cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common configure.in
+
+$(top_srcdir)/subdirs:
+ cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common subdirs
+
+$(top_srcdir)/acinclude.m4: $(top_srcdir)/admin/acinclude.m4.in $(top_srcdir)/admin/libtool.m4.in
+ @cd $(top_srcdir) && cat admin/acinclude.m4.in admin/libtool.m4.in > acinclude.m4
+
+xdg_apps_DATA = tellico.desktop
+xdg_mime_DATA = tellico.xml
+
+mimedir = $(kde_mimedir)/application
+mime_DATA = x-tellico.desktop
+
+localdir = $(kde_datadir)/tellico
+local_DATA = tellico.dtd tellico.tips
+
+CLEANFILES = *~ *.loT
+
+DISTCLEANFILES = stamp-h1 stamp-h.in stamp-h2 $(distdir).tar.gz $(CLEANFILES)
+
+MAINTAINERCLEANFILES = \
+subdirs configure configure.in \
+aclocal.m4 acinclude.m4 configure.files \
+Makefile.in $(DISTCLEANFILES)
+
+
+package-messages:
+ $(MAKE) -f admin/Makefile.common package-messages
+ $(MAKE) -C po merge
+
+messages:
+ @ rm -f tips.cpp xslt.cpp z3950.cpp scripts.cpp
+ @ touch $(podir)/tellico.pot;
+ ./preparetips tellico.tips > tips.cpp; \
+ $(XGETTEXT) --join-existing tips.cpp -o $(podir)/tellico.pot; \
+ ./prepare_i18n_xslt > xslt.cpp; \
+ $(XGETTEXT) --join-existing xslt.cpp -o $(podir)/tellico.pot; \
+ ./prepare_desktop src/fetch/z3950-servers.cfg > z3950.cpp; \
+ $(XGETTEXT) --join-existing z3950.cpp -o $(podir)/tellico.pot; \
+ ./prepare_desktop src/fetch/scripts/*.spec > scripts.cpp; \
+ $(XGETTEXT) --join-existing scripts.cpp -o $(podir)/tellico.pot;
+ @ rm -f tips.cpp xslt.cpp z3950.cpp scripts.cpp
+
+
+dist-hook:
+# am_edit needs to modify the Makefile.in files, so they must be writeable
+ -find $(distdir) -exec chmod a+w {} \;
+ cd $(distdir) && perl admin/am_edit -padmin
+ cd $(distdir) && $(MAKE) -f admin/Makefile.common subdirs
+# don't include dist file inside the dist file
+# cd $(srcdir) && rm -f $(distdir).tar.gz
+# remove any executable
+ rm -rf $(distdir)/src/tellico
+
+PUBLIC_ID=-//Robby Stephenson/DTD Tellico V9.0//EN
+SYSTEM_ID=http://www.periapsis.org/tellico/dtd/v9/tellico.dtd
+
+install-data-local:
+ @if test x"@XML_CATALOG_FILE@" != x; then \
+ echo @XMLCATALOG@ --noout --add "delegatePublic" \
+ "$(PUBLIC_ID)" \
+ "file://$(localdir)/tellico.dtd" "@XML_CATALOG_FILE@" ; \
+ @XMLCATALOG@ --noout --add "delegatePublic" \
+ "$(PUBLIC_ID)" \
+ "file://$(localdir)/tellico.dtd" "@XML_CATALOG_FILE@" ; \
+ echo @XMLCATALOG@ --noout --add "delegateSystem" \
+ "$(SYSTEM_ID)" \
+ "file://$(localdir)/tellico.dtd" "@XML_CATALOG_FILE@" ; \
+ @XMLCATALOG@ --noout --add "delegateSystem" \
+ "$(SYSTEM_ID)" \
+ "file://$(localdir)/tellico.dtd" "@XML_CATALOG_FILE@" ; \
+ echo @XMLCATALOG@ --noout --add "delegateURI" \
+ "$(SYSTEM_ID)" \
+ "file://$(localdir)/tellico.dtd" "@XML_CATALOG_FILE@" ; \
+ @XMLCATALOG@ --noout --add "delegateURI" \
+ "$(SYSTEM_ID)" \
+ "file://$(localdir)/tellico.dtd" "@XML_CATALOG_FILE@" ; \
+ fi
+
+uninstall-local:
+ @if test x"@XML_CATALOG_FILE@" != x; then \
+ echo @XMLCATALOG@ --noout --del \
+ "$(PUBLIC_ID)" "@XML_CATALOG_FILE@" ; \
+ @XMLCATALOG@ --noout --del \
+ "$(PUBLIC_ID)" "@XML_CATALOG_FILE@" ; \
+ echo @XMLCATALOG@ --noout --del \
+ "$(SYSTEM_ID)" "@XML_CATALOG_FILE@" ; \
+ @XMLCATALOG@ --noout --del \
+ "$(SYSTEM_ID)" "@XML_CATALOG_FILE@" ; \
+ echo @XMLCATALOG@ --noout --del \
+ "$(SYSTEM_ID)" "@XML_CATALOG_FILE@" ; \
+ @XMLCATALOG@ --noout --del \
+ "$(SYSTEM_ID)" "@XML_CATALOG_FILE@" ; \
+ fi
+
+# probably a better way to do this
+uninstall-hook:
+ -if [ -d $(localdir) ]; then rmdir $(localdir); fi
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/NEWS
diff --git a/README b/README
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..a6b105b
--- /dev/null
+++ b/TODO
@@ -0,0 +1 @@
+See http://www.periapsis.org/tellico/
diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644
index 0000000..a0a28f1
--- /dev/null
+++ b/acinclude.m4
@@ -0,0 +1,11720 @@
+## -*- autoconf -*-
+
+dnl This file is part of the KDE libraries/packages
+dnl Copyright (C) 1997 Janos Farkas (chexum@shadow.banki.hu)
+dnl (C) 1997,98,99 Stephan Kulow (coolo@kde.org)
+
+dnl This file is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Library General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2 of the License, or (at your option) any later version.
+
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl Library General Public License for more details.
+
+dnl You should have received a copy of the GNU Library General Public License
+dnl along with this library; see the file COPYING.LIB. If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+dnl Boston, MA 02110-1301, USA.
+
+dnl IMPORTANT NOTE:
+dnl Please do not modify this file unless you expect your modifications to be
+dnl carried into every other module in the repository.
+dnl
+dnl Single-module modifications are best placed in configure.in for kdelibs
+dnl and kdebase or configure.in.in if present.
+
+dnl ------------------------------------------------------------------------
+dnl Forward compatibility macros (make autoconf 2.13 look like 2.50),
+dnl thanks to Raja R Harinath.
+dnl ------------------------------------------------------------------------
+dnl
+ifdef([_AC_PATH_X_XMKMF],[],
+ [AC_DEFUN([_AC_PATH_X_XMKMF],[AC_PATH_X_XMKMF])])
+ifdef([AC_OUTPUT_SUBDIRS],[],
+ [AC_DEFUN([AC_OUTPUT_SUBDIRS],[subdirs=$1; _AC_OUTPUT_SUBDIRS])])
+
+# KDE_PATH_X_DIRECT
+dnl Internal subroutine of AC_PATH_X.
+dnl Set ac_x_includes and/or ac_x_libraries.
+AC_DEFUN([KDE_PATH_X_DIRECT],
+[
+AC_REQUIRE([KDE_CHECK_LIB64])
+
+if test "$ac_x_includes" = NO; then
+ # Guess where to find include files, by looking for this one X11 .h file.
+ test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
+
+ # First, try using that file with no special directory specified.
+AC_TRY_CPP([#include <$x_direct_test_include>],
+[# We can compile using X headers with no special include directory.
+ac_x_includes=],
+[# Look for the header file in a standard set of common directories.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ for ac_dir in \
+ /usr/X11/include \
+ /usr/X11R6/include \
+ /usr/X11R5/include \
+ /usr/X11R4/include \
+ \
+ /usr/include/X11 \
+ /usr/include/X11R6 \
+ /usr/include/X11R5 \
+ /usr/include/X11R4 \
+ \
+ /usr/local/X11/include \
+ /usr/local/X11R6/include \
+ /usr/local/X11R5/include \
+ /usr/local/X11R4/include \
+ \
+ /usr/local/include/X11 \
+ /usr/local/include/X11R6 \
+ /usr/local/include/X11R5 \
+ /usr/local/include/X11R4 \
+ \
+ /usr/X386/include \
+ /usr/x386/include \
+ /usr/XFree86/include/X11 \
+ \
+ /usr/include \
+ /usr/local/include \
+ /usr/unsupported/include \
+ /usr/athena/include \
+ /usr/local/x11r5/include \
+ /usr/lpp/Xamples/include \
+ \
+ /usr/openwin/include \
+ /usr/openwin/share/include \
+ ; \
+ do
+ if test -r "$ac_dir/$x_direct_test_include"; then
+ ac_x_includes=$ac_dir
+ break
+ fi
+ done])
+fi # $ac_x_includes = NO
+
+if test "$ac_x_libraries" = NO; then
+ # Check for the libraries.
+
+ test -z "$x_direct_test_library" && x_direct_test_library=Xt
+ test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
+
+ # See if we find them without any special options.
+ # Don't add to $LIBS permanently.
+ ac_save_LIBS="$LIBS"
+ LIBS="-l$x_direct_test_library $LIBS"
+AC_TRY_LINK([#include <X11/Intrinsic.h>], [${x_direct_test_function}(1)],
+[LIBS="$ac_save_LIBS"
+# We can link X programs with no special library path.
+ac_x_libraries=],
+[LIBS="$ac_save_LIBS"
+# First see if replacing the include by lib works.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+for ac_dir in `echo "$ac_x_includes" | sed s/include/lib${kdelibsuff}/` \
+ /usr/X11/lib${kdelibsuff} \
+ /usr/X11R6/lib${kdelibsuff} \
+ /usr/X11R5/lib${kdelibsuff} \
+ /usr/X11R4/lib${kdelibsuff} \
+ \
+ /usr/lib${kdelibsuff}/X11 \
+ /usr/lib${kdelibsuff}/X11R6 \
+ /usr/lib${kdelibsuff}/X11R5 \
+ /usr/lib${kdelibsuff}/X11R4 \
+ \
+ /usr/local/X11/lib${kdelibsuff} \
+ /usr/local/X11R6/lib${kdelibsuff} \
+ /usr/local/X11R5/lib${kdelibsuff} \
+ /usr/local/X11R4/lib${kdelibsuff} \
+ \
+ /usr/local/lib${kdelibsuff}/X11 \
+ /usr/local/lib${kdelibsuff}/X11R6 \
+ /usr/local/lib${kdelibsuff}/X11R5 \
+ /usr/local/lib${kdelibsuff}/X11R4 \
+ \
+ /usr/X386/lib${kdelibsuff} \
+ /usr/x386/lib${kdelibsuff} \
+ /usr/XFree86/lib${kdelibsuff}/X11 \
+ \
+ /usr/lib${kdelibsuff} \
+ /usr/local/lib${kdelibsuff} \
+ /usr/unsupported/lib${kdelibsuff} \
+ /usr/athena/lib${kdelibsuff} \
+ /usr/local/x11r5/lib${kdelibsuff} \
+ /usr/lpp/Xamples/lib${kdelibsuff} \
+ /lib/usr/lib${kdelibsuff}/X11 \
+ \
+ /usr/openwin/lib${kdelibsuff} \
+ /usr/openwin/share/lib${kdelibsuff} \
+ ; \
+do
+dnl Don't even attempt the hair of trying to link an X program!
+ for ac_extension in a so sl; do
+ if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then
+ ac_x_libraries=$ac_dir
+ break 2
+ fi
+ done
+done])
+fi # $ac_x_libraries = NO
+])
+
+
+dnl ------------------------------------------------------------------------
+dnl Find a file (or one of more files in a list of dirs)
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_FIND_FILE],
+[
+$3=NO
+for i in $2;
+do
+ for j in $1;
+ do
+ echo "configure: __oline__: $i/$j" >&AC_FD_CC
+ if test -r "$i/$j"; then
+ echo "taking that" >&AC_FD_CC
+ $3=$i
+ break 2
+ fi
+ done
+done
+])
+
+dnl KDE_FIND_PATH(program-name, variable-name, list-of-dirs,
+dnl if-not-found, test-parameter, prepend-path)
+dnl
+dnl Look for program-name in list-of-dirs+$PATH.
+dnl If prepend-path is set, look in $PATH+list-of-dirs instead.
+dnl If found, $variable-name is set. If not, if-not-found is evaluated.
+dnl test-parameter: if set, the program is executed with this arg,
+dnl and only a successful exit code is required.
+AC_DEFUN([KDE_FIND_PATH],
+[
+ AC_MSG_CHECKING([for $1])
+ if test -n "$$2"; then
+ kde_cv_path="$$2";
+ else
+ kde_cache=`echo $1 | sed 'y%./+-%__p_%'`
+
+ AC_CACHE_VAL(kde_cv_path_$kde_cache,
+ [
+ kde_cv_path="NONE"
+ kde_save_IFS=$IFS
+ IFS=':'
+ dirs=""
+ for dir in $PATH; do
+ dirs="$dirs $dir"
+ done
+ if test -z "$6"; then dnl Append dirs in PATH (default)
+ dirs="$3 $dirs"
+ else dnl Prepend dirs in PATH (if 6th arg is set)
+ dirs="$dirs $3"
+ fi
+ IFS=$kde_save_IFS
+
+ for dir in $dirs; do
+ if test -x "$dir/$1"; then
+ if test -n "$5"
+ then
+ evalstr="$dir/$1 $5 2>&1 "
+ if eval $evalstr; then
+ kde_cv_path="$dir/$1"
+ break
+ fi
+ else
+ kde_cv_path="$dir/$1"
+ break
+ fi
+ fi
+ done
+
+ eval "kde_cv_path_$kde_cache=$kde_cv_path"
+
+ ])
+
+ eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\""
+
+ fi
+
+ if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then
+ AC_MSG_RESULT(not found)
+ $4
+ else
+ AC_MSG_RESULT($kde_cv_path)
+ $2=$kde_cv_path
+
+ fi
+])
+
+AC_DEFUN([KDE_MOC_ERROR_MESSAGE],
+[
+ AC_MSG_ERROR([No Qt meta object compiler (moc) found!
+Please check whether you installed Qt correctly.
+You need to have a running moc binary.
+configure tried to run $ac_cv_path_moc and the test didn't
+succeed. If configure shouldn't have tried this one, set
+the environment variable MOC to the right one before running
+configure.
+])
+])
+
+AC_DEFUN([KDE_UIC_ERROR_MESSAGE],
+[
+ AC_MSG_WARN([No Qt ui compiler (uic) found!
+Please check whether you installed Qt correctly.
+You need to have a running uic binary.
+configure tried to run $ac_cv_path_uic and the test didn't
+succeed. If configure shouldn't have tried this one, set
+the environment variable UIC to the right one before running
+configure.
+])
+])
+
+
+AC_DEFUN([KDE_CHECK_UIC_FLAG],
+[
+ AC_MSG_CHECKING([whether uic supports -$1 ])
+ kde_cache=`echo $1 | sed 'y% .=/+-%____p_%'`
+ AC_CACHE_VAL(kde_cv_prog_uic_$kde_cache,
+ [
+ cat >conftest.ui <<EOT
+ <!DOCTYPE UI><UI version="3" stdsetdef="1"></UI>
+EOT
+ ac_uic_testrun="$UIC -$1 $2 conftest.ui >/dev/null"
+ if AC_TRY_EVAL(ac_uic_testrun); then
+ eval "kde_cv_prog_uic_$kde_cache=yes"
+ else
+ eval "kde_cv_prog_uic_$kde_cache=no"
+ fi
+ rm -f conftest*
+ ])
+
+ if eval "test \"`echo '$kde_cv_prog_uic_'$kde_cache`\" = yes"; then
+ AC_MSG_RESULT([yes])
+ :
+ $3
+ else
+ AC_MSG_RESULT([no])
+ :
+ $4
+ fi
+])
+
+
+dnl ------------------------------------------------------------------------
+dnl Find the meta object compiler and the ui compiler in the PATH,
+dnl in $QTDIR/bin, and some more usual places
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_PATH_QT_MOC_UIC],
+[
+ AC_REQUIRE([KDE_CHECK_PERL])
+ qt_bindirs=""
+ for dir in $kde_qt_dirs; do
+ qt_bindirs="$qt_bindirs $dir/bin $dir/src/moc"
+ done
+ qt_bindirs="$qt_bindirs /usr/bin /usr/X11R6/bin /usr/local/qt/bin"
+ if test ! "$ac_qt_bindir" = "NO"; then
+ qt_bindirs="$ac_qt_bindir $qt_bindirs"
+ fi
+
+ KDE_FIND_PATH(moc, MOC, [$qt_bindirs], [KDE_MOC_ERROR_MESSAGE])
+ if test -z "$UIC_NOT_NEEDED"; then
+ KDE_FIND_PATH(uic, UIC, [$qt_bindirs], [UIC=""])
+ if test -z "$UIC" ; then
+ KDE_UIC_ERROR_MESSAGE
+ exit 1
+ elif test $kde_qtver = 3; then
+ KDE_CHECK_UIC_FLAG(L,[/nonexistant],ac_uic_supports_libpath=yes,ac_uic_supports_libpath=no)
+ KDE_CHECK_UIC_FLAG(nounload,,ac_uic_supports_nounload=yes,ac_uic_supports_nounload=no)
+
+ if test x$ac_uic_supports_libpath = xyes; then
+ UIC="$UIC -L $kde_widgetdir"
+ fi
+ if test x$ac_uic_supports_nounload = xyes; then
+ UIC="$UIC -nounload"
+ fi
+ fi
+ else
+ UIC="echo uic not available: "
+ fi
+
+ AC_SUBST(MOC)
+ AC_SUBST(UIC)
+
+ UIC_TR="i18n"
+ if test $kde_qtver = 3; then
+ UIC_TR="tr2i18n"
+ fi
+
+ AC_SUBST(UIC_TR)
+])
+
+AC_DEFUN([KDE_1_CHECK_PATHS],
+[
+ KDE_1_CHECK_PATH_HEADERS
+
+ KDE_TEST_RPATH=
+
+ if test -n "$USE_RPATH"; then
+
+ if test -n "$kde_libraries"; then
+ KDE_TEST_RPATH="-R $kde_libraries"
+ fi
+
+ if test -n "$qt_libraries"; then
+ KDE_TEST_RPATH="$KDE_TEST_RPATH -R $qt_libraries"
+ fi
+
+ if test -n "$x_libraries"; then
+ KDE_TEST_RPATH="$KDE_TEST_RPATH -R $x_libraries"
+ fi
+
+ KDE_TEST_RPATH="$KDE_TEST_RPATH $KDE_EXTRA_RPATH"
+ fi
+
+AC_MSG_CHECKING([for KDE libraries installed])
+ac_link='$LIBTOOL_SHELL --silent --mode=link ${CXX-g++} -o conftest $CXXFLAGS $all_includes $CPPFLAGS $LDFLAGS $all_libraries conftest.$ac_ext $LIBS -lkdecore $LIBQT $KDE_TEST_RPATH 1>&5'
+
+if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_ERROR([your system fails at linking a small KDE application!
+Check, if your compiler is installed correctly and if you have used the
+same compiler to compile Qt and kdelibs as you did use now.
+For more details about this problem, look at the end of config.log.])
+fi
+
+if eval `KDEDIR= ./conftest 2>&5`; then
+ kde_result=done
+else
+ kde_result=problems
+fi
+
+KDEDIR= ./conftest 2> /dev/null >&5 # make an echo for config.log
+kde_have_all_paths=yes
+
+KDE_SET_PATHS($kde_result)
+
+])
+
+AC_DEFUN([KDE_SET_PATHS],
+[
+ kde_cv_all_paths="kde_have_all_paths=\"yes\" \
+ kde_htmldir=\"$kde_htmldir\" \
+ kde_appsdir=\"$kde_appsdir\" \
+ kde_icondir=\"$kde_icondir\" \
+ kde_sounddir=\"$kde_sounddir\" \
+ kde_datadir=\"$kde_datadir\" \
+ kde_locale=\"$kde_locale\" \
+ kde_cgidir=\"$kde_cgidir\" \
+ kde_confdir=\"$kde_confdir\" \
+ kde_kcfgdir=\"$kde_kcfgdir\" \
+ kde_mimedir=\"$kde_mimedir\" \
+ kde_toolbardir=\"$kde_toolbardir\" \
+ kde_wallpaperdir=\"$kde_wallpaperdir\" \
+ kde_templatesdir=\"$kde_templatesdir\" \
+ kde_bindir=\"$kde_bindir\" \
+ kde_servicesdir=\"$kde_servicesdir\" \
+ kde_servicetypesdir=\"$kde_servicetypesdir\" \
+ kde_moduledir=\"$kde_moduledir\" \
+ kde_styledir=\"$kde_styledir\" \
+ kde_widgetdir=\"$kde_widgetdir\" \
+ xdg_appsdir=\"$xdg_appsdir\" \
+ xdg_menudir=\"$xdg_menudir\" \
+ xdg_mimedir=\"$xdg_mimedir\" \
+ xdg_directorydir=\"$xdg_directorydir\" \
+ kde_result=$1"
+])
+
+AC_DEFUN([KDE_SET_DEFAULT_PATHS],
+[
+if test "$1" = "default"; then
+
+ if test -z "$kde_htmldir"; then
+ kde_htmldir='\${datadir}/doc/HTML'
+ fi
+ if test -z "$kde_appsdir"; then
+ kde_appsdir='\${datadir}/applnk'
+ fi
+ if test -z "$kde_icondir"; then
+ kde_icondir='\${datadir}/icons'
+ fi
+ if test -z "$kde_sounddir"; then
+ kde_sounddir='\${datadir}/sounds'
+ fi
+ if test -z "$kde_datadir"; then
+ kde_datadir='\${datadir}/apps'
+ fi
+ if test -z "$kde_locale"; then
+ kde_locale='\${datadir}/locale'
+ fi
+ if test -z "$kde_cgidir"; then
+ kde_cgidir='\${exec_prefix}/cgi-bin'
+ fi
+ if test -z "$kde_confdir"; then
+ kde_confdir='\${datadir}/config'
+ fi
+ if test -z "$kde_kcfgdir"; then
+ kde_kcfgdir='\${datadir}/config.kcfg'
+ fi
+ if test -z "$kde_mimedir"; then
+ kde_mimedir='\${datadir}/mimelnk'
+ fi
+ if test -z "$kde_toolbardir"; then
+ kde_toolbardir='\${datadir}/toolbar'
+ fi
+ if test -z "$kde_wallpaperdir"; then
+ kde_wallpaperdir='\${datadir}/wallpapers'
+ fi
+ if test -z "$kde_templatesdir"; then
+ kde_templatesdir='\${datadir}/templates'
+ fi
+ if test -z "$kde_bindir"; then
+ kde_bindir='\${exec_prefix}/bin'
+ fi
+ if test -z "$kde_servicesdir"; then
+ kde_servicesdir='\${datadir}/services'
+ fi
+ if test -z "$kde_servicetypesdir"; then
+ kde_servicetypesdir='\${datadir}/servicetypes'
+ fi
+ if test -z "$kde_moduledir"; then
+ if test "$kde_qtver" = "2"; then
+ kde_moduledir='\${libdir}/kde2'
+ else
+ kde_moduledir='\${libdir}/kde3'
+ fi
+ fi
+ if test -z "$kde_styledir"; then
+ kde_styledir='\${libdir}/kde3/plugins/styles'
+ fi
+ if test -z "$kde_widgetdir"; then
+ kde_widgetdir='\${libdir}/kde3/plugins/designer'
+ fi
+ if test -z "$xdg_appsdir"; then
+ xdg_appsdir='\${datadir}/applications/kde'
+ fi
+ if test -z "$xdg_menudir"; then
+ xdg_menudir='\${sysconfdir}/xdg/menus'
+ fi
+ if test -z "$xdg_mimedir"; then
+ xdg_mimedir='\${datadir}/mime/packages'
+ fi
+ if test -z "$xdg_directorydir"; then
+ xdg_directorydir='\${datadir}/desktop-directories'
+ fi
+
+ KDE_SET_PATHS(defaults)
+
+else
+
+ if test $kde_qtver = 1; then
+ AC_MSG_RESULT([compiling])
+ KDE_1_CHECK_PATHS
+ else
+ AC_MSG_ERROR([path checking not yet supported for KDE 2])
+ fi
+
+fi
+])
+
+AC_DEFUN([KDE_CHECK_PATHS_FOR_COMPLETENESS],
+[ if test -z "$kde_htmldir" || test -z "$kde_appsdir" ||
+ test -z "$kde_icondir" || test -z "$kde_sounddir" ||
+ test -z "$kde_datadir" || test -z "$kde_locale" ||
+ test -z "$kde_cgidir" || test -z "$kde_confdir" ||
+ test -z "$kde_kcfgdir" ||
+ test -z "$kde_mimedir" || test -z "$kde_toolbardir" ||
+ test -z "$kde_wallpaperdir" || test -z "$kde_templatesdir" ||
+ test -z "$kde_bindir" || test -z "$kde_servicesdir" ||
+ test -z "$kde_servicetypesdir" || test -z "$kde_moduledir" ||
+ test -z "$kde_styledir" || test -z "$kde_widgetdir" ||
+ test -z "$xdg_appsdir" || test -z "$xdg_menudir" || test -z "$xdg_mimedir" || test -z "$xdg_directorydir" ||
+ test "x$kde_have_all_paths" != "xyes"; then
+ kde_have_all_paths=no
+ fi
+])
+
+AC_DEFUN([KDE_MISSING_PROG_ERROR],
+[
+ AC_MSG_ERROR([The important program $1 was not found!
+Please check whether you installed KDE correctly.
+])
+])
+
+AC_DEFUN([KDE_MISSING_ARTS_ERROR],
+[
+ AC_MSG_ERROR([The important program $1 was not found!
+Please check whether you installed aRts correctly or use
+--without-arts to compile without aRts support (this will remove functionality).
+])
+])
+
+AC_DEFUN([KDE_SET_DEFAULT_BINDIRS],
+[
+ kde_default_bindirs="/usr/bin /usr/local/bin /opt/local/bin /usr/X11R6/bin /opt/kde/bin /opt/kde3/bin /usr/kde/bin /usr/local/kde/bin"
+ test -n "$KDEDIR" && kde_default_bindirs="$KDEDIR/bin $kde_default_bindirs"
+ if test -n "$KDEDIRS"; then
+ kde_save_IFS=$IFS
+ IFS=:
+ for dir in $KDEDIRS; do
+ kde_default_bindirs="$dir/bin $kde_default_bindirs "
+ done
+ IFS=$kde_save_IFS
+ fi
+])
+
+AC_DEFUN([KDE_SUBST_PROGRAMS],
+[
+ AC_ARG_WITH(arts,
+ AC_HELP_STRING([--without-arts],[build without aRts [default=no]]),
+ [build_arts=$withval],
+ [build_arts=yes]
+ )
+ AM_CONDITIONAL(include_ARTS, test "$build_arts" '!=' "no")
+ if test "$build_arts" = "no"; then
+ AC_DEFINE(WITHOUT_ARTS, 1, [Defined if compiling without arts])
+ fi
+
+ KDE_SET_DEFAULT_BINDIRS
+ kde_default_bindirs="$exec_prefix/bin $prefix/bin $kde_libs_prefix/bin $kde_default_bindirs"
+ KDE_FIND_PATH(dcopidl, DCOPIDL, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidl)])
+ KDE_FIND_PATH(dcopidl2cpp, DCOPIDL2CPP, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidl2cpp)])
+ if test "$build_arts" '!=' "no"; then
+ KDE_FIND_PATH(mcopidl, MCOPIDL, [$kde_default_bindirs], [KDE_MISSING_ARTS_ERROR(mcopidl)])
+ KDE_FIND_PATH(artsc-config, ARTSCCONFIG, [$kde_default_bindirs], [KDE_MISSING_ARTS_ERROR(artsc-config)])
+ fi
+ KDE_FIND_PATH(meinproc, MEINPROC, [$kde_default_bindirs])
+
+ kde32ornewer=1
+ kde33ornewer=1
+ if test -n "$kde_qtver" && test "$kde_qtver" -lt 3; then
+ kde32ornewer=
+ kde33ornewer=
+ else
+ if test "$kde_qtver" = "3"; then
+ if test "$kde_qtsubver" -le 1; then
+ kde32ornewer=
+ fi
+ if test "$kde_qtsubver" -le 2; then
+ kde33ornewer=
+ fi
+ if test "$KDECONFIG" != "compiled"; then
+ if test `$KDECONFIG --version | grep KDE | sed 's/KDE: \(...\).*/\1/'` = 3.2; then
+ kde33ornewer=
+ fi
+ fi
+ fi
+ fi
+
+ if test -n "$kde32ornewer"; then
+ KDE_FIND_PATH(kconfig_compiler, KCONFIG_COMPILER, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(kconfig_compiler)])
+ KDE_FIND_PATH(dcopidlng, DCOPIDLNG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidlng)])
+ fi
+ if test -n "$kde33ornewer"; then
+ KDE_FIND_PATH(makekdewidgets, MAKEKDEWIDGETS, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(makekdewidgets)])
+ AC_SUBST(MAKEKDEWIDGETS)
+ fi
+ KDE_FIND_PATH(xmllint, XMLLINT, [${prefix}/bin ${exec_prefix}/bin], [XMLLINT=""])
+
+ if test -n "$MEINPROC" -a "$MEINPROC" != "compiled"; then
+ kde_sharedirs="/usr/share/kde /usr/local/share /usr/share /opt/kde3/share /opt/kde/share $prefix/share"
+ test -n "$KDEDIR" && kde_sharedirs="$KDEDIR/share $kde_sharedirs"
+ AC_FIND_FILE(apps/ksgmltools2/customization/kde-chunk.xsl, $kde_sharedirs, KDE_XSL_STYLESHEET)
+ if test "$KDE_XSL_STYLESHEET" = "NO"; then
+ KDE_XSL_STYLESHEET=""
+ else
+ KDE_XSL_STYLESHEET="$KDE_XSL_STYLESHEET/apps/ksgmltools2/customization/kde-chunk.xsl"
+ fi
+ fi
+
+ DCOP_DEPENDENCIES='$(DCOPIDL)'
+ if test -n "$kde32ornewer"; then
+ KCFG_DEPENDENCIES='$(KCONFIG_COMPILER)'
+ DCOP_DEPENDENCIES='$(DCOPIDL) $(DCOPIDLNG)'
+ AC_SUBST(KCONFIG_COMPILER)
+ AC_SUBST(KCFG_DEPENDENCIES)
+ AC_SUBST(DCOPIDLNG)
+ fi
+ AC_SUBST(DCOPIDL)
+ AC_SUBST(DCOPIDL2CPP)
+ AC_SUBST(DCOP_DEPENDENCIES)
+ AC_SUBST(MCOPIDL)
+ AC_SUBST(ARTSCCONFIG)
+ AC_SUBST(MEINPROC)
+ AC_SUBST(KDE_XSL_STYLESHEET)
+ AC_SUBST(XMLLINT)
+])dnl
+
+AC_DEFUN([AC_CREATE_KFSSTND],
+[
+AC_REQUIRE([AC_CHECK_RPATH])
+
+AC_MSG_CHECKING([for KDE paths])
+kde_result=""
+kde_cached_paths=yes
+AC_CACHE_VAL(kde_cv_all_paths,
+[
+ KDE_SET_DEFAULT_PATHS($1)
+ kde_cached_paths=no
+])
+eval "$kde_cv_all_paths"
+KDE_CHECK_PATHS_FOR_COMPLETENESS
+if test "$kde_have_all_paths" = "no" && test "$kde_cached_paths" = "yes"; then
+ # wrong values were cached, may be, we can set better ones
+ kde_result=
+ kde_htmldir= kde_appsdir= kde_icondir= kde_sounddir=
+ kde_datadir= kde_locale= kde_cgidir= kde_confdir= kde_kcfgdir=
+ kde_mimedir= kde_toolbardir= kde_wallpaperdir= kde_templatesdir=
+ kde_bindir= kde_servicesdir= kde_servicetypesdir= kde_moduledir=
+ kde_have_all_paths=
+ kde_styledir=
+ kde_widgetdir=
+ xdg_appsdir = xdg_menudir= xdg_mimedir= xdg_directorydir=
+ KDE_SET_DEFAULT_PATHS($1)
+ eval "$kde_cv_all_paths"
+ KDE_CHECK_PATHS_FOR_COMPLETENESS
+ kde_result="$kde_result (cache overridden)"
+fi
+if test "$kde_have_all_paths" = "no"; then
+ AC_MSG_ERROR([configure could not run a little KDE program to test the environment.
+Since it had compiled and linked before, it must be a strange problem on your system.
+Look at config.log for details. If you are not able to fix this, look at
+http://www.kde.org/faq/installation.html or any www.kde.org mirror.
+(If you're using an egcs version on Linux, you may update binutils!)
+])
+else
+ rm -f conftest*
+ AC_MSG_RESULT($kde_result)
+fi
+
+bindir=$kde_bindir
+
+KDE_SUBST_PROGRAMS
+
+])
+
+AC_DEFUN([AC_SUBST_KFSSTND],
+[
+AC_SUBST(kde_htmldir)
+AC_SUBST(kde_appsdir)
+AC_SUBST(kde_icondir)
+AC_SUBST(kde_sounddir)
+AC_SUBST(kde_datadir)
+AC_SUBST(kde_locale)
+AC_SUBST(kde_confdir)
+AC_SUBST(kde_kcfgdir)
+AC_SUBST(kde_mimedir)
+AC_SUBST(kde_wallpaperdir)
+AC_SUBST(kde_bindir)
+dnl X Desktop Group standards
+AC_SUBST(xdg_appsdir)
+AC_SUBST(xdg_menudir)
+AC_SUBST(xdg_mimedir)
+AC_SUBST(xdg_directorydir)
+dnl for KDE 2
+AC_SUBST(kde_templatesdir)
+AC_SUBST(kde_servicesdir)
+AC_SUBST(kde_servicetypesdir)
+AC_SUBST(kde_moduledir)
+AC_SUBST(kdeinitdir, '$(kde_moduledir)')
+AC_SUBST(kde_styledir)
+AC_SUBST(kde_widgetdir)
+if test "$kde_qtver" = 1; then
+ kde_minidir="$kde_icondir/mini"
+else
+# for KDE 1 - this breaks KDE2 apps using minidir, but
+# that's the plan ;-/
+ kde_minidir="/dev/null"
+fi
+dnl AC_SUBST(kde_minidir)
+dnl AC_SUBST(kde_cgidir)
+dnl AC_SUBST(kde_toolbardir)
+])
+
+AC_DEFUN([KDE_MISC_TESTS],
+[
+ dnl Checks for libraries.
+ AC_CHECK_LIB(util, main, [LIBUTIL="-lutil"]) dnl for *BSD
+ AC_SUBST(LIBUTIL)
+ AC_CHECK_LIB(compat, main, [LIBCOMPAT="-lcompat"]) dnl for *BSD
+ AC_SUBST(LIBCOMPAT)
+ kde_have_crypt=
+ AC_CHECK_LIB(crypt, crypt, [LIBCRYPT="-lcrypt"; kde_have_crypt=yes],
+ AC_CHECK_LIB(c, crypt, [kde_have_crypt=yes], [
+ AC_MSG_WARN([you have no crypt in either libcrypt or libc.
+You should install libcrypt from another source or configure with PAM
+support])
+ kde_have_crypt=no
+ ]))
+ AC_SUBST(LIBCRYPT)
+ if test $kde_have_crypt = yes; then
+ AC_DEFINE_UNQUOTED(HAVE_CRYPT, 1, [Defines if your system has the crypt function])
+ fi
+ AC_CHECK_SOCKLEN_T
+ AC_CHECK_LIB(dnet, dnet_ntoa, [X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"])
+ if test $ac_cv_lib_dnet_dnet_ntoa = no; then
+ AC_CHECK_LIB(dnet_stub, dnet_ntoa,
+ [X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"])
+ fi
+ AC_CHECK_FUNC(inet_ntoa)
+ if test $ac_cv_func_inet_ntoa = no; then
+ AC_CHECK_LIB(nsl, inet_ntoa, X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl")
+ fi
+ AC_CHECK_FUNC(connect)
+ if test $ac_cv_func_connect = no; then
+ AC_CHECK_LIB(socket, connect, X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS", ,
+ $X_EXTRA_LIBS)
+ fi
+
+ AC_CHECK_FUNC(remove)
+ if test $ac_cv_func_remove = no; then
+ AC_CHECK_LIB(posix, remove, X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix")
+ fi
+
+ # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
+ AC_CHECK_FUNC(shmat, ,
+ AC_CHECK_LIB(ipc, shmat, X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"))
+
+ # more headers that need to be explicitly included on darwin
+ AC_CHECK_HEADERS(sys/types.h stdint.h)
+
+ # sys/bitypes.h is needed for uint32_t and friends on Tru64
+ AC_CHECK_HEADERS(sys/bitypes.h)
+
+ # darwin requires a poll emulation library
+ AC_CHECK_LIB(poll, poll, LIB_POLL="-lpoll")
+
+ # CoreAudio framework
+ AC_CHECK_HEADER(CoreAudio/CoreAudio.h, [
+ AC_DEFINE(HAVE_COREAUDIO, 1, [Define if you have the CoreAudio API])
+ FRAMEWORK_COREAUDIO="-Xlinker -framework -Xlinker CoreAudio"
+ ])
+
+ AC_CHECK_RES_INIT
+ AC_SUBST(LIB_POLL)
+ AC_SUBST(FRAMEWORK_COREAUDIO)
+ LIBSOCKET="$X_EXTRA_LIBS"
+ AC_SUBST(LIBSOCKET)
+ AC_SUBST(X_EXTRA_LIBS)
+ AC_CHECK_LIB(ucb, killpg, [LIBUCB="-lucb"]) dnl for Solaris2.4
+ AC_SUBST(LIBUCB)
+
+ case $host in dnl this *is* LynxOS specific
+ *-*-lynxos* )
+ AC_MSG_CHECKING([LynxOS header file wrappers])
+ [CFLAGS="$CFLAGS -D__NO_INCLUDE_WARN__"]
+ AC_MSG_RESULT(disabled)
+ AC_CHECK_LIB(bsd, gethostbyname, [LIBSOCKET="-lbsd"]) dnl for LynxOS
+ ;;
+ esac
+
+ KDE_CHECK_TYPES
+ KDE_CHECK_LIBDL
+ KDE_CHECK_STRLCPY
+
+# darwin needs this to initialize the environment
+AC_CHECK_HEADERS(crt_externs.h)
+AC_CHECK_FUNC(_NSGetEnviron, [AC_DEFINE(HAVE_NSGETENVIRON, 1, [Define if your system needs _NSGetEnviron to set up the environment])])
+
+AH_VERBATIM(_DARWIN_ENVIRON,
+[
+#if defined(HAVE_NSGETENVIRON) && defined(HAVE_CRT_EXTERNS_H)
+# include <sys/time.h>
+# include <crt_externs.h>
+# define environ (*_NSGetEnviron())
+#endif
+])
+
+AH_VERBATIM(_AIX_STRINGS_H_BZERO,
+[
+/*
+ * AIX defines FD_SET in terms of bzero, but fails to include <strings.h>
+ * that defines bzero.
+ */
+
+#if defined(_AIX)
+#include <strings.h>
+#endif
+])
+
+AC_CHECK_FUNCS([vsnprintf snprintf])
+
+AH_VERBATIM(_TRU64,[
+/*
+ * On HP-UX, the declaration of vsnprintf() is needed every time !
+ */
+
+#if !defined(HAVE_VSNPRINTF) || defined(hpux)
+#if __STDC__
+#include <stdarg.h>
+#include <stdlib.h>
+#else
+#include <varargs.h>
+#endif
+#ifdef __cplusplus
+extern "C"
+#endif
+int vsnprintf(char *str, size_t n, char const *fmt, va_list ap);
+#ifdef __cplusplus
+extern "C"
+#endif
+int snprintf(char *str, size_t n, char const *fmt, ...);
+#endif
+])
+
+])
+
+dnl ------------------------------------------------------------------------
+dnl Find the header files and libraries for X-Windows. Extended the
+dnl macro AC_PATH_X
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([K_PATH_X],
+[
+AC_REQUIRE([KDE_MISC_TESTS])dnl
+AC_REQUIRE([KDE_CHECK_LIB64])
+
+AC_ARG_ENABLE(
+ embedded,
+ AC_HELP_STRING([--enable-embedded],[link to Qt-embedded, don't use X]),
+ kde_use_qt_emb=$enableval,
+ kde_use_qt_emb=no
+)
+
+AC_ARG_ENABLE(
+ qtopia,
+ AC_HELP_STRING([--enable-qtopia],[link to Qt-embedded, link to the Qtopia Environment]),
+ kde_use_qt_emb_palm=$enableval,
+ kde_use_qt_emb_palm=no
+)
+
+AC_ARG_ENABLE(
+ mac,
+ AC_HELP_STRING([--enable-mac],[link to Qt/Mac (don't use X)]),
+ kde_use_qt_mac=$enableval,
+ kde_use_qt_mac=no
+)
+
+if test "$kde_use_qt_emb" = "no" && test "$kde_use_qt_mac" = "no"; then
+
+AC_MSG_CHECKING(for X)
+
+AC_CACHE_VAL(kde_cv_have_x,
+[# One or both of the vars are not set, and there is no cached value.
+if test "{$x_includes+set}" = set || test "$x_includes" = NONE; then
+ kde_x_includes=NO
+else
+ kde_x_includes=$x_includes
+fi
+if test "{$x_libraries+set}" = set || test "$x_libraries" = NONE; then
+ kde_x_libraries=NO
+else
+ kde_x_libraries=$x_libraries
+fi
+
+# below we use the standard autoconf calls
+ac_x_libraries=$kde_x_libraries
+ac_x_includes=$kde_x_includes
+
+KDE_PATH_X_DIRECT
+dnl AC_PATH_X_XMKMF picks /usr/lib as the path for the X libraries.
+dnl Unfortunately, if compiling with the N32 ABI, this is not the correct
+dnl location. The correct location is /usr/lib32 or an undefined value
+dnl (the linker is smart enough to pick the correct default library).
+dnl Things work just fine if you use just AC_PATH_X_DIRECT.
+dnl Solaris has a similar problem. AC_PATH_X_XMKMF forces x_includes to
+dnl /usr/openwin/include, which doesn't work. /usr/include does work, so
+dnl x_includes should be left alone.
+case "$host" in
+mips-sgi-irix6*)
+ ;;
+*-*-solaris*)
+ ;;
+*)
+ _AC_PATH_X_XMKMF
+ if test -z "$ac_x_includes"; then
+ ac_x_includes="."
+ fi
+ if test -z "$ac_x_libraries"; then
+ ac_x_libraries="/usr/lib${kdelibsuff}"
+ fi
+esac
+#from now on we use our own again
+
+# when the user already gave --x-includes, we ignore
+# what the standard autoconf macros told us.
+if test "$kde_x_includes" = NO; then
+ kde_x_includes=$ac_x_includes
+fi
+
+# for --x-libraries too
+if test "$kde_x_libraries" = NO; then
+ kde_x_libraries=$ac_x_libraries
+fi
+
+if test "$kde_x_includes" = NO; then
+ AC_MSG_ERROR([Can't find X includes. Please check your installation and add the correct paths!])
+fi
+
+if test "$kde_x_libraries" = NO; then
+ AC_MSG_ERROR([Can't find X libraries. Please check your installation and add the correct paths!])
+fi
+
+# Record where we found X for the cache.
+kde_cv_have_x="have_x=yes \
+ kde_x_includes=$kde_x_includes kde_x_libraries=$kde_x_libraries"
+])dnl
+
+eval "$kde_cv_have_x"
+
+if test "$have_x" != yes; then
+ AC_MSG_RESULT($have_x)
+ no_x=yes
+else
+ AC_MSG_RESULT([libraries $kde_x_libraries, headers $kde_x_includes])
+fi
+
+if test -z "$kde_x_includes" || test "x$kde_x_includes" = xNONE; then
+ X_INCLUDES=""
+ x_includes="."; dnl better than nothing :-
+ else
+ x_includes=$kde_x_includes
+ X_INCLUDES="-I$x_includes"
+fi
+
+if test -z "$kde_x_libraries" || test "x$kde_x_libraries" = xNONE; then
+ X_LDFLAGS=""
+ x_libraries="/usr/lib"; dnl better than nothing :-
+ else
+ x_libraries=$kde_x_libraries
+ X_LDFLAGS="-L$x_libraries"
+fi
+all_includes="$X_INCLUDES"
+all_libraries="$X_LDFLAGS $LDFLAGS_AS_NEEDED $LDFLAGS_NEW_DTAGS"
+
+# Check for libraries that X11R6 Xt/Xaw programs need.
+ac_save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $X_LDFLAGS"
+# SM needs ICE to (dynamically) link under SunOS 4.x (so we have to
+# check for ICE first), but we must link in the order -lSM -lICE or
+# we get undefined symbols. So assume we have SM if we have ICE.
+# These have to be linked with before -lX11, unlike the other
+# libraries we check for below, so use a different variable.
+# --interran@uluru.Stanford.EDU, kb@cs.umb.edu.
+AC_CHECK_LIB(ICE, IceConnectionNumber,
+ [LIBSM="-lSM -lICE"], , $X_EXTRA_LIBS)
+LDFLAGS="$ac_save_LDFLAGS"
+
+LIB_X11='-lX11 $(LIBSOCKET)'
+
+AC_MSG_CHECKING(for libXext)
+AC_CACHE_VAL(kde_cv_have_libXext,
+[
+kde_ldflags_safe="$LDFLAGS"
+kde_libs_safe="$LIBS"
+
+LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS"
+LIBS="-lXext -lX11 $LIBSOCKET"
+
+AC_TRY_LINK([
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+#endif
+],
+[
+printf("hello Xext\n");
+],
+kde_cv_have_libXext=yes,
+kde_cv_have_libXext=no
+)
+
+LDFLAGS=$kde_ldflags_safe
+LIBS=$kde_libs_safe
+])
+
+AC_MSG_RESULT($kde_cv_have_libXext)
+
+if test "$kde_cv_have_libXext" = "no"; then
+ AC_MSG_ERROR([We need a working libXext to proceed. Since configure
+can't find it itself, we stop here assuming that make wouldn't find
+them either.])
+fi
+
+LIB_XEXT="-lXext"
+QTE_NORTTI=""
+
+elif test "$kde_use_qt_emb" = "yes"; then
+ dnl We're using QT Embedded
+ CPPFLAGS=-DQWS
+ CXXFLAGS="$CXXFLAGS -fno-rtti"
+ QTE_NORTTI="-fno-rtti -DQWS"
+ X_PRE_LIBS=""
+ LIB_X11=""
+ LIB_XEXT=""
+ LIB_XRENDER=""
+ LIBSM=""
+ X_INCLUDES=""
+ X_LDFLAGS=""
+ x_includes=""
+ x_libraries=""
+elif test "$kde_use_qt_mac" = "yes"; then
+ dnl We're using QT/Mac (I use QT_MAC so that qglobal.h doesn't *have* to
+ dnl be included to get the information) --Sam
+ CXXFLAGS="$CXXFLAGS -DQT_MAC -no-cpp-precomp"
+ CFLAGS="$CFLAGS -DQT_MAC -no-cpp-precomp"
+ X_PRE_LIBS=""
+ LIB_X11=""
+ LIB_XEXT=""
+ LIB_XRENDER=""
+ LIBSM=""
+ X_INCLUDES=""
+ X_LDFLAGS=""
+ x_includes=""
+ x_libraries=""
+fi
+AC_SUBST(X_PRE_LIBS)
+AC_SUBST(LIB_X11)
+AC_SUBST(LIB_XRENDER)
+AC_SUBST(LIBSM)
+AC_SUBST(X_INCLUDES)
+AC_SUBST(X_LDFLAGS)
+AC_SUBST(x_includes)
+AC_SUBST(x_libraries)
+AC_SUBST(QTE_NORTTI)
+AC_SUBST(LIB_XEXT)
+
+])
+
+AC_DEFUN([KDE_PRINT_QT_PROGRAM],
+[
+AC_REQUIRE([KDE_USE_QT])
+cat > conftest.$ac_ext <<EOF
+#include "confdefs.h"
+#include <qglobal.h>
+#include <qapplication.h>
+EOF
+if test "$kde_qtver" = "2"; then
+cat >> conftest.$ac_ext <<EOF
+#include <qevent.h>
+#include <qstring.h>
+#include <qstyle.h>
+EOF
+
+if test $kde_qtsubver -gt 0; then
+cat >> conftest.$ac_ext <<EOF
+#if QT_VERSION < 210
+#error 1
+#endif
+EOF
+fi
+fi
+
+if test "$kde_qtver" = "3"; then
+cat >> conftest.$ac_ext <<EOF
+#include <qcursor.h>
+#include <qstylefactory.h>
+#include <private/qucomextra_p.h>
+EOF
+fi
+
+echo "#if ! ($kde_qt_verstring)" >> conftest.$ac_ext
+cat >> conftest.$ac_ext <<EOF
+#error 1
+#endif
+
+int main() {
+EOF
+if test "$kde_qtver" = "2"; then
+cat >> conftest.$ac_ext <<EOF
+ QStringList *t = new QStringList();
+ Q_UNUSED(t);
+EOF
+if test $kde_qtsubver -gt 0; then
+cat >> conftest.$ac_ext <<EOF
+ QString s;
+ s.setLatin1("Elvis is alive", 14);
+EOF
+fi
+fi
+if test "$kde_qtver" = "3"; then
+cat >> conftest.$ac_ext <<EOF
+ (void)QStyleFactory::create(QString::null);
+ QCursor c(Qt::WhatsThisCursor);
+EOF
+fi
+cat >> conftest.$ac_ext <<EOF
+ return 0;
+}
+EOF
+])
+
+AC_DEFUN([KDE_USE_QT],
+[
+if test -z "$1"; then
+ # Current default Qt version: 3.2
+ kde_qtver=3
+ kde_qtsubver=2
+else
+ kde_qtsubver=`echo "$1" | sed -e 's#[0-9][0-9]*\.\([0-9][0-9]*\).*#\1#'`
+ # following is the check if subversion isnt found in passed argument
+ if test "$kde_qtsubver" = "$1"; then
+ kde_qtsubver=1
+ fi
+ kde_qtver=`echo "$1" | sed -e 's#^\([0-9][0-9]*\)\..*#\1#'`
+ if test "$kde_qtver" = "1"; then
+ kde_qtsubver=42
+ fi
+fi
+
+if test -z "$2"; then
+ if test "$kde_qtver" = "2"; then
+ if test $kde_qtsubver -gt 0; then
+ kde_qt_minversion=">= Qt 2.2.2"
+ else
+ kde_qt_minversion=">= Qt 2.0.2"
+ fi
+ fi
+ if test "$kde_qtver" = "3"; then
+ if test $kde_qtsubver -gt 0; then
+ if test $kde_qtsubver -gt 1; then
+ if test $kde_qtsubver -gt 2; then
+ kde_qt_minversion=">= Qt 3.3 and < 4.0"
+ else
+ kde_qt_minversion=">= Qt 3.2 and < 4.0"
+ fi
+ else
+ kde_qt_minversion=">= Qt 3.1 (20021021) and < 4.0"
+ fi
+ else
+ kde_qt_minversion=">= Qt 3.0 and < 4.0"
+ fi
+ fi
+ if test "$kde_qtver" = "1"; then
+ kde_qt_minversion=">= 1.42 and < 2.0"
+ fi
+else
+ kde_qt_minversion="$2"
+fi
+
+if test -z "$3"; then
+ if test $kde_qtver = 3; then
+ if test $kde_qtsubver -gt 0; then
+ kde_qt_verstring="QT_VERSION >= 0x03@VER@00 && QT_VERSION < 0x040000"
+ qtsubver=`echo "00$kde_qtsubver" | sed -e 's,.*\(..\)$,\1,'`
+ kde_qt_verstring=`echo $kde_qt_verstring | sed -e "s,@VER@,$qtsubver,"`
+ else
+ kde_qt_verstring="QT_VERSION >= 300 && QT_VERSION < 0x040000"
+ fi
+ fi
+ if test $kde_qtver = 2; then
+ if test $kde_qtsubver -gt 0; then
+ kde_qt_verstring="QT_VERSION >= 222"
+ else
+ kde_qt_verstring="QT_VERSION >= 200"
+ fi
+ fi
+ if test $kde_qtver = 1; then
+ kde_qt_verstring="QT_VERSION >= 142 && QT_VERSION < 200"
+ fi
+else
+ kde_qt_verstring="$3"
+fi
+
+if test $kde_qtver = 4; then
+ kde_qt_dirs="$QTDIR /usr/lib/qt4 /usr/lib/qt /usr/share/qt4"
+fi
+if test $kde_qtver = 3; then
+ kde_qt_dirs="$QTDIR /usr/lib/qt3 /usr/lib/qt /usr/share/qt3"
+fi
+if test $kde_qtver = 2; then
+ kde_qt_dirs="$QTDIR /usr/lib/qt2 /usr/lib/qt"
+fi
+if test $kde_qtver = 1; then
+ kde_qt_dirs="$QTDIR /usr/lib/qt"
+fi
+])
+
+AC_DEFUN([KDE_CHECK_QT_DIRECT],
+[
+AC_REQUIRE([KDE_USE_QT])
+AC_MSG_CHECKING([if Qt compiles without flags])
+AC_CACHE_VAL(kde_cv_qt_direct,
+[
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+ac_LD_LIBRARY_PATH_safe=$LD_LIBRARY_PATH
+ac_LIBRARY_PATH="$LIBRARY_PATH"
+ac_cxxflags_safe="$CXXFLAGS"
+ac_ldflags_safe="$LDFLAGS"
+ac_libs_safe="$LIBS"
+
+CXXFLAGS="$CXXFLAGS -I$qt_includes"
+LDFLAGS="$LDFLAGS $X_LDFLAGS"
+if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then
+LIBS="$LIBQT -lXext -lX11 $LIBSOCKET"
+else
+LIBS="$LIBQT $LIBSOCKET"
+fi
+LD_LIBRARY_PATH=
+export LD_LIBRARY_PATH
+LIBRARY_PATH=
+export LIBRARY_PATH
+
+KDE_PRINT_QT_PROGRAM
+
+if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ kde_cv_qt_direct="yes"
+else
+ kde_cv_qt_direct="no"
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.$ac_ext >&AC_FD_CC
+fi
+
+rm -f conftest*
+CXXFLAGS="$ac_cxxflags_safe"
+LDFLAGS="$ac_ldflags_safe"
+LIBS="$ac_libs_safe"
+
+LD_LIBRARY_PATH="$ac_LD_LIBRARY_PATH_safe"
+export LD_LIBRARY_PATH
+LIBRARY_PATH="$ac_LIBRARY_PATH"
+export LIBRARY_PATH
+AC_LANG_RESTORE
+])
+
+if test "$kde_cv_qt_direct" = "yes"; then
+ AC_MSG_RESULT(yes)
+ $1
+else
+ AC_MSG_RESULT(no)
+ $2
+fi
+])
+
+dnl ------------------------------------------------------------------------
+dnl Try to find the Qt headers and libraries.
+dnl $(QT_LDFLAGS) will be -Lqtliblocation (if needed)
+dnl and $(QT_INCLUDES) will be -Iqthdrlocation (if needed)
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_PATH_QT_1_3],
+[
+AC_REQUIRE([K_PATH_X])
+AC_REQUIRE([KDE_USE_QT])
+AC_REQUIRE([KDE_CHECK_LIB64])
+
+dnl ------------------------------------------------------------------------
+dnl Add configure flag to enable linking to MT version of Qt library.
+dnl ------------------------------------------------------------------------
+
+AC_ARG_ENABLE(
+ mt,
+ AC_HELP_STRING([--disable-mt],[link to non-threaded Qt (deprecated)]),
+ kde_use_qt_mt=$enableval,
+ [
+ if test $kde_qtver = 3; then
+ kde_use_qt_mt=yes
+ else
+ kde_use_qt_mt=no
+ fi
+ ]
+)
+
+USING_QT_MT=""
+
+dnl ------------------------------------------------------------------------
+dnl If we not get --disable-qt-mt then adjust some vars for the host.
+dnl ------------------------------------------------------------------------
+
+KDE_MT_LDFLAGS=
+KDE_MT_LIBS=
+if test "x$kde_use_qt_mt" = "xyes"; then
+ KDE_CHECK_THREADING
+ if test "x$kde_use_threading" = "xyes"; then
+ CPPFLAGS="$USE_THREADS -DQT_THREAD_SUPPORT $CPPFLAGS"
+ KDE_MT_LDFLAGS="$USE_THREADS"
+ KDE_MT_LIBS="$LIBPTHREAD"
+ else
+ kde_use_qt_mt=no
+ fi
+fi
+AC_SUBST(KDE_MT_LDFLAGS)
+AC_SUBST(KDE_MT_LIBS)
+
+kde_qt_was_given=yes
+
+dnl ------------------------------------------------------------------------
+dnl If we haven't been told how to link to Qt, we work it out for ourselves.
+dnl ------------------------------------------------------------------------
+if test -z "$LIBQT_GLOB"; then
+ if test "x$kde_use_qt_emb" = "xyes"; then
+ LIBQT_GLOB="libqte.*"
+ else
+ LIBQT_GLOB="libqt.*"
+ fi
+fi
+
+dnl ------------------------------------------------------------
+dnl If we got --enable-embedded then adjust the Qt library name.
+dnl ------------------------------------------------------------
+if test "x$kde_use_qt_emb" = "xyes"; then
+ qtlib="qte"
+else
+ qtlib="qt"
+fi
+
+kde_int_qt="-l$qtlib"
+
+if test -z "$LIBQPE"; then
+dnl ------------------------------------------------------------
+dnl If we got --enable-palmtop then add -lqpe to the link line
+dnl ------------------------------------------------------------
+ if test "x$kde_use_qt_emb" = "xyes"; then
+ if test "x$kde_use_qt_emb_palm" = "xyes"; then
+ LIB_QPE="-lqpe"
+ else
+ LIB_QPE=""
+ fi
+ else
+ LIB_QPE=""
+ fi
+fi
+
+dnl ------------------------------------------------------------------------
+dnl If we got --enable-qt-mt then adjust the Qt library name for the host.
+dnl ------------------------------------------------------------------------
+
+if test "x$kde_use_qt_mt" = "xyes"; then
+ LIBQT="-l$qtlib-mt"
+ kde_int_qt="-l$qtlib-mt"
+ LIBQT_GLOB="lib$qtlib-mt.*"
+ USING_QT_MT="using -mt"
+else
+ LIBQT="-l$qtlib"
+fi
+
+if test $kde_qtver != 1; then
+
+ AC_REQUIRE([AC_FIND_PNG])
+ AC_REQUIRE([AC_FIND_JPEG])
+ LIBQT="$LIBQT $LIBPNG $LIBJPEG"
+fi
+
+if test $kde_qtver = 3; then
+ AC_REQUIRE([KDE_CHECK_LIBDL])
+ LIBQT="$LIBQT $LIBDL"
+fi
+
+AC_MSG_CHECKING([for Qt])
+
+if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then
+LIBQT="$LIBQT $X_PRE_LIBS -lXext -lX11 $LIBSM $LIBSOCKET"
+fi
+ac_qt_includes=NO ac_qt_libraries=NO ac_qt_bindir=NO
+qt_libraries=""
+qt_includes=""
+AC_ARG_WITH(qt-dir,
+ AC_HELP_STRING([--with-qt-dir=DIR],[where the root of Qt is installed ]),
+ [ ac_qt_includes="$withval"/include
+ ac_qt_libraries="$withval"/lib${kdelibsuff}
+ ac_qt_bindir="$withval"/bin
+ ])
+
+AC_ARG_WITH(qt-includes,
+ AC_HELP_STRING([--with-qt-includes=DIR],[where the Qt includes are. ]),
+ [
+ ac_qt_includes="$withval"
+ ])
+
+kde_qt_libs_given=no
+
+AC_ARG_WITH(qt-libraries,
+ AC_HELP_STRING([--with-qt-libraries=DIR],[where the Qt library is installed.]),
+ [ ac_qt_libraries="$withval"
+ kde_qt_libs_given=yes
+ ])
+
+AC_CACHE_VAL(ac_cv_have_qt,
+[#try to guess Qt locations
+
+qt_incdirs=""
+for dir in $kde_qt_dirs; do
+ qt_incdirs="$qt_incdirs $dir/include $dir"
+done
+qt_incdirs="$QTINC $qt_incdirs /usr/local/qt/include /usr/include/qt /usr/include /usr/X11R6/include/X11/qt /usr/X11R6/include/qt /usr/X11R6/include/qt2 /usr/include/qt3 $x_includes"
+if test ! "$ac_qt_includes" = "NO"; then
+ qt_incdirs="$ac_qt_includes $qt_incdirs"
+fi
+
+if test "$kde_qtver" != "1"; then
+ kde_qt_header=qstyle.h
+else
+ kde_qt_header=qglobal.h
+fi
+
+AC_FIND_FILE($kde_qt_header, $qt_incdirs, qt_incdir)
+ac_qt_includes="$qt_incdir"
+
+qt_libdirs=""
+for dir in $kde_qt_dirs; do
+ qt_libdirs="$qt_libdirs $dir/lib${kdelibsuff} $dir"
+done
+qt_libdirs="$QTLIB $qt_libdirs /usr/X11R6/lib /usr/lib /usr/local/qt/lib $x_libraries"
+if test ! "$ac_qt_libraries" = "NO"; then
+ qt_libdir=$ac_qt_libraries
+else
+ qt_libdirs="$ac_qt_libraries $qt_libdirs"
+ # if the Qt was given, the chance is too big that libqt.* doesn't exist
+ qt_libdir=NONE
+ for dir in $qt_libdirs; do
+ try="ls -1 $dir/${LIBQT_GLOB}"
+ if test -n "`$try 2> /dev/null`"; then qt_libdir=$dir; break; else echo "tried $dir" >&AC_FD_CC ; fi
+ done
+fi
+for a in $qt_libdir/lib`echo ${kde_int_qt} | sed 's,^-l,,'`_incremental.*; do
+ if test -e "$a"; then
+ LIBQT="$LIBQT ${kde_int_qt}_incremental"
+ break
+ fi
+done
+
+ac_qt_libraries="$qt_libdir"
+
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+
+ac_cxxflags_safe="$CXXFLAGS"
+ac_ldflags_safe="$LDFLAGS"
+ac_libs_safe="$LIBS"
+
+CXXFLAGS="$CXXFLAGS -I$qt_incdir $all_includes"
+LDFLAGS="$LDFLAGS -L$qt_libdir $all_libraries $USER_LDFLAGS $KDE_MT_LDFLAGS"
+LIBS="$LIBS $LIBQT $KDE_MT_LIBS"
+
+KDE_PRINT_QT_PROGRAM
+
+if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ rm -f conftest*
+else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.$ac_ext >&AC_FD_CC
+ ac_qt_libraries="NO"
+fi
+rm -f conftest*
+CXXFLAGS="$ac_cxxflags_safe"
+LDFLAGS="$ac_ldflags_safe"
+LIBS="$ac_libs_safe"
+
+AC_LANG_RESTORE
+if test "$ac_qt_includes" = NO || test "$ac_qt_libraries" = NO; then
+ ac_cv_have_qt="have_qt=no"
+ ac_qt_notfound=""
+ missing_qt_mt=""
+ if test "$ac_qt_includes" = NO; then
+ if test "$ac_qt_libraries" = NO; then
+ ac_qt_notfound="(headers and libraries)";
+ else
+ ac_qt_notfound="(headers)";
+ fi
+ else
+ if test "x$kde_use_qt_mt" = "xyes"; then
+ missing_qt_mt="
+Make sure that you have compiled Qt with thread support!"
+ ac_qt_notfound="(library $qtlib-mt)";
+ else
+ ac_qt_notfound="(library $qtlib)";
+ fi
+ fi
+
+ AC_MSG_ERROR([Qt ($kde_qt_minversion) $ac_qt_notfound not found. Please check your installation!
+For more details about this problem, look at the end of config.log.$missing_qt_mt])
+else
+ have_qt="yes"
+fi
+])
+
+eval "$ac_cv_have_qt"
+
+if test "$have_qt" != yes; then
+ AC_MSG_RESULT([$have_qt]);
+else
+ ac_cv_have_qt="have_qt=yes \
+ ac_qt_includes=$ac_qt_includes ac_qt_libraries=$ac_qt_libraries"
+ AC_MSG_RESULT([libraries $ac_qt_libraries, headers $ac_qt_includes $USING_QT_MT])
+
+ qt_libraries="$ac_qt_libraries"
+ qt_includes="$ac_qt_includes"
+fi
+
+if test ! "$kde_qt_libs_given" = "yes" && test ! "$kde_qtver" = 3; then
+ KDE_CHECK_QT_DIRECT(qt_libraries= ,[])
+fi
+
+AC_SUBST(qt_libraries)
+AC_SUBST(qt_includes)
+
+if test "$qt_includes" = "$x_includes" || test -z "$qt_includes"; then
+ QT_INCLUDES=""
+else
+ QT_INCLUDES="-I$qt_includes"
+ all_includes="$QT_INCLUDES $all_includes"
+fi
+
+if test "$qt_libraries" = "$x_libraries" || test -z "$qt_libraries"; then
+ QT_LDFLAGS=""
+else
+ QT_LDFLAGS="-L$qt_libraries"
+ all_libraries="$QT_LDFLAGS $all_libraries"
+fi
+test -z "$KDE_MT_LDFLAGS" || all_libraries="$all_libraries $KDE_MT_LDFLAGS"
+
+AC_SUBST(QT_INCLUDES)
+AC_SUBST(QT_LDFLAGS)
+AC_PATH_QT_MOC_UIC
+
+KDE_CHECK_QT_JPEG
+
+if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then
+LIB_QT="$kde_int_qt $LIBJPEG_QT "'$(LIBZ) $(LIBPNG) -lXext $(LIB_X11) $(LIBSM)'
+else
+LIB_QT="$kde_int_qt $LIBJPEG_QT "'$(LIBZ) $(LIBPNG)'
+fi
+test -z "$KDE_MT_LIBS" || LIB_QT="$LIB_QT $KDE_MT_LIBS"
+for a in $qt_libdir/lib`echo ${kde_int_qt} | sed 's,^-l,,'`_incremental.*; do
+ if test -e "$a"; then
+ LIB_QT="$LIB_QT ${kde_int_qt}_incremental"
+ break
+ fi
+done
+
+AC_SUBST(LIB_QT)
+AC_SUBST(LIB_QPE)
+
+AC_SUBST(kde_qtver)
+])
+
+AC_DEFUN([AC_PATH_QT],
+[
+AC_PATH_QT_1_3
+])
+
+AC_DEFUN([KDE_CHECK_UIC_PLUGINS],
+[
+AC_REQUIRE([AC_PATH_QT_MOC_UIC])
+
+if test x$ac_uic_supports_libpath = xyes; then
+
+AC_MSG_CHECKING([if UIC has KDE plugins available])
+AC_CACHE_VAL(kde_cv_uic_plugins,
+[
+cat > actest.ui << EOF
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>NewConnectionDialog</class>
+<widget class="QDialog">
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>testInput</cstring>
+ </property>
+ </widget>
+</widget>
+</UI>
+EOF
+
+
+
+kde_cv_uic_plugins=no
+kde_line="$UIC -L $kde_widgetdir"
+if test x$ac_uic_supports_nounload = xyes; then
+ kde_line="$kde_line -nounload"
+fi
+kde_line="$kde_line -impl actest.h actest.ui > actest.cpp"
+if AC_TRY_EVAL(kde_line); then
+ # if you're trying to debug this check and think it's incorrect,
+ # better check your installation. The check _is_ correct - your
+ # installation is not.
+ if test -f actest.cpp && grep klineedit actest.cpp > /dev/null; then
+ kde_cv_uic_plugins=yes
+ fi
+fi
+rm -f actest.ui actest.cpp
+])
+
+AC_MSG_RESULT([$kde_cv_uic_plugins])
+if test "$kde_cv_uic_plugins" != yes; then
+ AC_MSG_ERROR([
+you need to install kdelibs first.
+
+If you did install kdelibs, then the Qt version that is picked up by
+this configure is not the same version you used to compile kdelibs.
+The Qt Plugin installed by kdelibs is *ONLY* loadable if it is the
+_same Qt version_, compiled with the _same compiler_ and the same Qt
+configuration settings.
+])
+fi
+fi
+])
+
+AC_DEFUN([KDE_CHECK_FINAL],
+[
+ AC_ARG_ENABLE(final,
+ AC_HELP_STRING([--enable-final],
+ [build size optimized apps (experimental - needs lots of memory)]),
+ kde_use_final=$enableval, kde_use_final=no)
+
+ if test "x$kde_use_final" = "xyes"; then
+ KDE_USE_FINAL_TRUE=""
+ KDE_USE_FINAL_FALSE="#"
+ else
+ KDE_USE_FINAL_TRUE="#"
+ KDE_USE_FINAL_FALSE=""
+ fi
+ AC_SUBST(KDE_USE_FINAL_TRUE)
+ AC_SUBST(KDE_USE_FINAL_FALSE)
+])
+
+AC_DEFUN([KDE_CHECK_CLOSURE],
+[
+ AC_ARG_ENABLE(closure,
+ AC_HELP_STRING([--enable-closure],[delay template instantiation]),
+ kde_use_closure=$enableval, kde_use_closure=no)
+
+ KDE_NO_UNDEFINED=""
+ if test "x$kde_use_closure" = "xyes"; then
+ KDE_USE_CLOSURE_TRUE=""
+ KDE_USE_CLOSURE_FALSE="#"
+# CXXFLAGS="$CXXFLAGS $REPO"
+ else
+ KDE_USE_CLOSURE_TRUE="#"
+ KDE_USE_CLOSURE_FALSE=""
+ KDE_NO_UNDEFINED=""
+ case $host in
+ *-*-linux-gnu)
+ KDE_CHECK_COMPILER_FLAG([Wl,--no-undefined],
+ [KDE_CHECK_COMPILER_FLAG([Wl,--allow-shlib-undefined],
+ [KDE_NO_UNDEFINED="-Wl,--no-undefined -Wl,--allow-shlib-undefined"],
+ [KDE_NO_UNDEFINED=""])],
+ [KDE_NO_UNDEFINED=""])
+ ;;
+ esac
+ fi
+ AC_SUBST(KDE_USE_CLOSURE_TRUE)
+ AC_SUBST(KDE_USE_CLOSURE_FALSE)
+ AC_SUBST(KDE_NO_UNDEFINED)
+])
+
+dnl Check if the linker supports --enable-new-dtags and --as-needed
+AC_DEFUN([KDE_CHECK_NEW_LDFLAGS],
+[
+ AC_ARG_ENABLE(new_ldflags,
+ AC_HELP_STRING([--enable-new-ldflags],
+ [enable the new linker flags]),
+ kde_use_new_ldflags=$enableval,
+ kde_use_new_ldflags=no)
+
+ LDFLAGS_AS_NEEDED=""
+ LDFLAGS_NEW_DTAGS=""
+ if test "x$kde_use_new_ldflags" = "xyes"; then
+ LDFLAGS_NEW_DTAGS=""
+ KDE_CHECK_COMPILER_FLAG([Wl,--enable-new-dtags],
+ [LDFLAGS_NEW_DTAGS="-Wl,--enable-new-dtags"],)
+
+ KDE_CHECK_COMPILER_FLAG([Wl,--as-needed],
+ [LDFLAGS_AS_NEEDED="-Wl,--as-needed"],)
+ fi
+ AC_SUBST(LDFLAGS_AS_NEEDED)
+ AC_SUBST(LDFLAGS_NEW_DTAGS)
+])
+
+AC_DEFUN([KDE_CHECK_NMCHECK],
+[
+ AC_ARG_ENABLE(nmcheck,AC_HELP_STRING([--enable-nmcheck],[enable automatic namespace cleanness check]),
+ kde_use_nmcheck=$enableval, kde_use_nmcheck=no)
+
+ if test "$kde_use_nmcheck" = "yes"; then
+ KDE_USE_NMCHECK_TRUE=""
+ KDE_USE_NMCHECK_FALSE="#"
+ else
+ KDE_USE_NMCHECK_TRUE="#"
+ KDE_USE_NMCHECK_FALSE=""
+ fi
+ AC_SUBST(KDE_USE_NMCHECK_TRUE)
+ AC_SUBST(KDE_USE_NMCHECK_FALSE)
+])
+
+AC_DEFUN([KDE_EXPAND_MAKEVAR], [
+savex=$exec_prefix
+test "x$exec_prefix" = xNONE && exec_prefix=$prefix
+tmp=$$2
+while $1=`eval echo "$tmp"`; test "x$$1" != "x$tmp"; do tmp=$$1; done
+exec_prefix=$savex
+])
+
+dnl ------------------------------------------------------------------------
+dnl Now, the same with KDE
+dnl $(KDE_LDFLAGS) will be the kdeliblocation (if needed)
+dnl and $(kde_includes) will be the kdehdrlocation (if needed)
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_BASE_PATH_KDE],
+[
+AC_PREREQ([2.13])
+AC_REQUIRE([AC_PATH_QT])dnl
+AC_REQUIRE([KDE_CHECK_LIB64])
+
+AC_CHECK_RPATH
+AC_MSG_CHECKING([for KDE])
+
+if test "${prefix}" != NONE; then
+ kde_includes=${includedir}
+ KDE_EXPAND_MAKEVAR(ac_kde_includes, includedir)
+
+ kde_libraries=${libdir}
+ KDE_EXPAND_MAKEVAR(ac_kde_libraries, libdir)
+
+else
+ ac_kde_includes=
+ ac_kde_libraries=
+ kde_libraries=""
+ kde_includes=""
+fi
+
+AC_CACHE_VAL(ac_cv_have_kde,
+[#try to guess kde locations
+
+if test "$kde_qtver" = 1; then
+ kde_check_header="ksock.h"
+ kde_check_lib="libkdecore.la"
+else
+ kde_check_header="ksharedptr.h"
+ kde_check_lib="libkio.la"
+fi
+
+if test -z "$1"; then
+
+kde_incdirs="$kde_libs_prefix/include /usr/lib/kde/include /usr/local/kde/include /usr/local/include /usr/kde/include /usr/include/kde /usr/include /opt/kde3/include /opt/kde/include $x_includes $qt_includes"
+test -n "$KDEDIR" && kde_incdirs="$KDEDIR/include $KDEDIR/include/kde $KDEDIR $kde_incdirs"
+kde_incdirs="$ac_kde_includes $kde_incdirs"
+AC_FIND_FILE($kde_check_header, $kde_incdirs, kde_incdir)
+ac_kde_includes="$kde_incdir"
+
+if test -n "$ac_kde_includes" && test ! -r "$ac_kde_includes/$kde_check_header"; then
+ AC_MSG_ERROR([
+in the prefix, you've chosen, are no KDE headers installed. This will fail.
+So, check this please and use another prefix!])
+fi
+
+kde_libdirs="$kde_libs_prefix/lib${kdelibsuff} /usr/lib/kde/lib${kdelibsuff} /usr/local/kde/lib${kdelibsuff} /usr/kde/lib${kdelibsuff} /usr/lib${kdelibsuff}/kde /usr/lib${kdelibsuff}/kde3 /usr/lib${kdelibsuff} /usr/X11R6/lib${kdelibsuff} /usr/local/lib${kdelibsuff} /opt/kde3/lib${kdelibsuff} /opt/kde/lib${kdelibsuff} /usr/X11R6/kde/lib${kdelibsuff}"
+test -n "$KDEDIR" && kde_libdirs="$KDEDIR/lib${kdelibsuff} $KDEDIR $kde_libdirs"
+kde_libdirs="$ac_kde_libraries $libdir $kde_libdirs"
+AC_FIND_FILE($kde_check_lib, $kde_libdirs, kde_libdir)
+ac_kde_libraries="$kde_libdir"
+
+kde_widgetdir=NO
+dnl this might be somewhere else
+AC_FIND_FILE("kde3/plugins/designer/kdewidgets.la", $kde_libdirs, kde_widgetdir)
+
+if test -n "$ac_kde_libraries" && test ! -r "$ac_kde_libraries/$kde_check_lib"; then
+AC_MSG_ERROR([
+in the prefix, you've chosen, are no KDE libraries installed. This will fail.
+So, check this please and use another prefix!])
+fi
+
+if test -n "$kde_widgetdir" && test ! -r "$kde_widgetdir/kde3/plugins/designer/kdewidgets.la"; then
+AC_MSG_ERROR([
+I can't find the designer plugins. These are required and should have been installed
+by kdelibs])
+fi
+
+if test -n "$kde_widgetdir"; then
+ kde_widgetdir="$kde_widgetdir/kde3/plugins/designer"
+fi
+
+
+if test "$ac_kde_includes" = NO || test "$ac_kde_libraries" = NO || test "$kde_widgetdir" = NO; then
+ ac_cv_have_kde="have_kde=no"
+else
+ ac_cv_have_kde="have_kde=yes \
+ ac_kde_includes=$ac_kde_includes ac_kde_libraries=$ac_kde_libraries"
+fi
+
+else dnl test -z $1, e.g. from kdelibs
+
+ ac_cv_have_kde="have_kde=no"
+
+fi
+])dnl
+
+eval "$ac_cv_have_kde"
+
+if test "$have_kde" != "yes"; then
+ if test "${prefix}" = NONE; then
+ ac_kde_prefix="$ac_default_prefix"
+ else
+ ac_kde_prefix="$prefix"
+ fi
+ if test "$exec_prefix" = NONE; then
+ ac_kde_exec_prefix="$ac_kde_prefix"
+ AC_MSG_RESULT([will be installed in $ac_kde_prefix])
+ else
+ ac_kde_exec_prefix="$exec_prefix"
+ AC_MSG_RESULT([will be installed in $ac_kde_prefix and $ac_kde_exec_prefix])
+ fi
+
+ kde_libraries="${libdir}"
+ kde_includes="${includedir}"
+
+else
+ ac_cv_have_kde="have_kde=yes \
+ ac_kde_includes=$ac_kde_includes ac_kde_libraries=$ac_kde_libraries"
+ AC_MSG_RESULT([libraries $ac_kde_libraries, headers $ac_kde_includes])
+
+ kde_libraries="$ac_kde_libraries"
+ kde_includes="$ac_kde_includes"
+fi
+AC_SUBST(kde_libraries)
+AC_SUBST(kde_includes)
+
+if test "$kde_includes" = "$x_includes" || test "$kde_includes" = "$qt_includes" || test "$kde_includes" = "/usr/include"; then
+ KDE_INCLUDES=""
+else
+ KDE_INCLUDES="-I$kde_includes"
+ all_includes="$KDE_INCLUDES $all_includes"
+fi
+
+KDE_DEFAULT_CXXFLAGS="-DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION"
+
+KDE_LDFLAGS="-L$kde_libraries"
+if test ! "$kde_libraries" = "$x_libraries" && test ! "$kde_libraries" = "$qt_libraries" ; then
+ all_libraries="$KDE_LDFLAGS $all_libraries"
+fi
+
+AC_SUBST(KDE_LDFLAGS)
+AC_SUBST(KDE_INCLUDES)
+
+AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+
+all_libraries="$all_libraries $USER_LDFLAGS"
+all_includes="$all_includes $USER_INCLUDES"
+AC_SUBST(all_includes)
+AC_SUBST(all_libraries)
+
+if test -z "$1"; then
+KDE_CHECK_UIC_PLUGINS
+fi
+
+ac_kde_libraries="$kde_libdir"
+
+AC_SUBST(AUTODIRS)
+
+
+])
+
+AC_DEFUN([KDE_CHECK_EXTRA_LIBS],
+[
+AC_MSG_CHECKING(for extra includes)
+AC_ARG_WITH(extra-includes,AC_HELP_STRING([--with-extra-includes=DIR],[adds non standard include paths]),
+ kde_use_extra_includes="$withval",
+ kde_use_extra_includes=NONE
+)
+kde_extra_includes=
+if test -n "$kde_use_extra_includes" && \
+ test "$kde_use_extra_includes" != "NONE"; then
+
+ ac_save_ifs=$IFS
+ IFS=':'
+ for dir in $kde_use_extra_includes; do
+ kde_extra_includes="$kde_extra_includes $dir"
+ USER_INCLUDES="$USER_INCLUDES -I$dir"
+ done
+ IFS=$ac_save_ifs
+ kde_use_extra_includes="added"
+else
+ kde_use_extra_includes="no"
+fi
+AC_SUBST(USER_INCLUDES)
+
+AC_MSG_RESULT($kde_use_extra_includes)
+
+kde_extra_libs=
+AC_MSG_CHECKING(for extra libs)
+AC_ARG_WITH(extra-libs,AC_HELP_STRING([--with-extra-libs=DIR],[adds non standard library paths]),
+ kde_use_extra_libs=$withval,
+ kde_use_extra_libs=NONE
+)
+if test -n "$kde_use_extra_libs" && \
+ test "$kde_use_extra_libs" != "NONE"; then
+
+ ac_save_ifs=$IFS
+ IFS=':'
+ for dir in $kde_use_extra_libs; do
+ kde_extra_libs="$kde_extra_libs $dir"
+ KDE_EXTRA_RPATH="$KDE_EXTRA_RPATH -R $dir"
+ USER_LDFLAGS="$USER_LDFLAGS -L$dir"
+ done
+ IFS=$ac_save_ifs
+ kde_use_extra_libs="added"
+else
+ kde_use_extra_libs="no"
+fi
+
+AC_SUBST(USER_LDFLAGS)
+
+AC_MSG_RESULT($kde_use_extra_libs)
+
+])
+
+AC_DEFUN([KDE_1_CHECK_PATH_HEADERS],
+[
+ AC_MSG_CHECKING([for KDE headers installed])
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+cat > conftest.$ac_ext <<EOF
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+#endif
+#include <stdio.h>
+#include "confdefs.h"
+#include <kapp.h>
+
+int main() {
+ printf("kde_htmldir=\\"%s\\"\n", KApplication::kde_htmldir().data());
+ printf("kde_appsdir=\\"%s\\"\n", KApplication::kde_appsdir().data());
+ printf("kde_icondir=\\"%s\\"\n", KApplication::kde_icondir().data());
+ printf("kde_sounddir=\\"%s\\"\n", KApplication::kde_sounddir().data());
+ printf("kde_datadir=\\"%s\\"\n", KApplication::kde_datadir().data());
+ printf("kde_locale=\\"%s\\"\n", KApplication::kde_localedir().data());
+ printf("kde_cgidir=\\"%s\\"\n", KApplication::kde_cgidir().data());
+ printf("kde_confdir=\\"%s\\"\n", KApplication::kde_configdir().data());
+ printf("kde_mimedir=\\"%s\\"\n", KApplication::kde_mimedir().data());
+ printf("kde_toolbardir=\\"%s\\"\n", KApplication::kde_toolbardir().data());
+ printf("kde_wallpaperdir=\\"%s\\"\n",
+ KApplication::kde_wallpaperdir().data());
+ printf("kde_bindir=\\"%s\\"\n", KApplication::kde_bindir().data());
+ printf("kde_partsdir=\\"%s\\"\n", KApplication::kde_partsdir().data());
+ printf("kde_servicesdir=\\"/tmp/dummy\\"\n");
+ printf("kde_servicetypesdir=\\"/tmp/dummy\\"\n");
+ printf("kde_moduledir=\\"/tmp/dummy\\"\n");
+ printf("kde_styledir=\\"/tmp/dummy\\"\n");
+ printf("kde_widgetdir=\\"/tmp/dummy\\"\n");
+ printf("xdg_appsdir=\\"/tmp/dummy\\"\n");
+ printf("xdg_menudir=\\"/tmp/dummy\\"\n");
+ printf("xdg_mimedir=\\"/tmp/dummy\\"\n");
+ printf("xdg_directorydir=\\"/tmp/dummy\\"\n");
+ printf("kde_kcfgdir=\\"/tmp/dummy\\"\n");
+ return 0;
+ }
+EOF
+
+ ac_save_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$all_includes $CPPFLAGS"
+ if AC_TRY_EVAL(ac_compile); then
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_ERROR([your system is not able to compile a small KDE application!
+Check, if you installed the KDE header files correctly.
+For more details about this problem, look at the end of config.log.])
+ fi
+ CPPFLAGS=$ac_save_CPPFLAGS
+
+ AC_LANG_RESTORE
+])
+
+AC_DEFUN([KDE_CHECK_KDEQTADDON],
+[
+AC_MSG_CHECKING(for kde-qt-addon)
+AC_CACHE_VAL(kde_cv_have_kdeqtaddon,
+[
+ kde_ldflags_safe="$LDFLAGS"
+ kde_libs_safe="$LIBS"
+ kde_cxxflags_safe="$CXXFLAGS"
+
+ LIBS="-lkde-qt-addon $LIBQT $LIBS"
+ CXXFLAGS="$CXXFLAGS -I$prefix/include -I$prefix/include/kde $all_includes"
+ LDFLAGS="$LDFLAGS $all_libraries $USER_LDFLAGS"
+
+ AC_TRY_LINK([
+ #include <qdom.h>
+ ],
+ [
+ QDomDocument doc;
+ ],
+ kde_cv_have_kdeqtaddon=yes,
+ kde_cv_have_kdeqtaddon=no
+ )
+
+ LDFLAGS=$kde_ldflags_safe
+ LIBS=$kde_libs_safe
+ CXXFLAGS=$kde_cxxflags_safe
+])
+
+AC_MSG_RESULT($kde_cv_have_kdeqtaddon)
+
+if test "$kde_cv_have_kdeqtaddon" = "no"; then
+ AC_MSG_ERROR([Can't find libkde-qt-addon. You need to install it first.
+It is a separate package (and CVS module) named kde-qt-addon.])
+fi
+])
+
+AC_DEFUN([KDE_CREATE_LIBS_ALIASES],
+[
+ AC_REQUIRE([KDE_MISC_TESTS])
+ AC_REQUIRE([KDE_CHECK_LIBDL])
+ AC_REQUIRE([K_PATH_X])
+
+if test $kde_qtver = 3; then
+ case $host in
+ *cygwin*) lib_kded="-lkdeinit_kded" ;;
+ *) lib_kded="" ;;
+ esac
+ AC_SUBST(LIB_KDED, $lib_kded)
+ AC_SUBST(LIB_KDECORE, "-lkdecore")
+ AC_SUBST(LIB_KDEUI, "-lkdeui")
+ AC_SUBST(LIB_KIO, "-lkio")
+ AC_SUBST(LIB_KJS, "-lkjs")
+ AC_SUBST(LIB_SMB, "-lsmb")
+ AC_SUBST(LIB_KAB, "-lkab")
+ AC_SUBST(LIB_KABC, "-lkabc")
+ AC_SUBST(LIB_KHTML, "-lkhtml")
+ AC_SUBST(LIB_KSPELL, "-lkspell")
+ AC_SUBST(LIB_KPARTS, "-lkparts")
+ AC_SUBST(LIB_KDEPRINT, "-lkdeprint")
+ AC_SUBST(LIB_KUTILS, "-lkutils")
+ AC_SUBST(LIB_KDEPIM, "-lkdepim")
+ AC_SUBST(LIB_KIMPROXY, "-lkimproxy")
+ AC_SUBST(LIB_KNEWSTUFF, "-lknewstuff")
+ AC_SUBST(LIB_KDNSSD, "-lkdnssd")
+ AC_SUBST(LIB_KUNITTEST, "-lkunittest")
+# these are for backward compatibility
+ AC_SUBST(LIB_KSYCOCA, "-lkio")
+ AC_SUBST(LIB_KFILE, "-lkio")
+elif test $kde_qtver = 2; then
+ AC_SUBST(LIB_KDECORE, "-lkdecore")
+ AC_SUBST(LIB_KDEUI, "-lkdeui")
+ AC_SUBST(LIB_KIO, "-lkio")
+ AC_SUBST(LIB_KSYCOCA, "-lksycoca")
+ AC_SUBST(LIB_SMB, "-lsmb")
+ AC_SUBST(LIB_KFILE, "-lkfile")
+ AC_SUBST(LIB_KAB, "-lkab")
+ AC_SUBST(LIB_KHTML, "-lkhtml")
+ AC_SUBST(LIB_KSPELL, "-lkspell")
+ AC_SUBST(LIB_KPARTS, "-lkparts")
+ AC_SUBST(LIB_KDEPRINT, "-lkdeprint")
+else
+ AC_SUBST(LIB_KDECORE, "-lkdecore -lXext $(LIB_QT)")
+ AC_SUBST(LIB_KDEUI, "-lkdeui $(LIB_KDECORE)")
+ AC_SUBST(LIB_KFM, "-lkfm $(LIB_KDECORE)")
+ AC_SUBST(LIB_KFILE, "-lkfile $(LIB_KFM) $(LIB_KDEUI)")
+ AC_SUBST(LIB_KAB, "-lkab $(LIB_KIMGIO) $(LIB_KDECORE)")
+fi
+])
+
+AC_DEFUN([AC_PATH_KDE],
+[
+ AC_BASE_PATH_KDE
+ AC_ARG_ENABLE(path-check,AC_HELP_STRING([--disable-path-check],[don't try to find out, where to install]),
+ [
+ if test "$enableval" = "no";
+ then ac_use_path_checking="default"
+ else ac_use_path_checking=""
+ fi
+ ],
+ [
+ if test "$kde_qtver" = 1;
+ then ac_use_path_checking=""
+ else ac_use_path_checking="default"
+ fi
+ ]
+ )
+
+ AC_CREATE_KFSSTND($ac_use_path_checking)
+
+ AC_SUBST_KFSSTND
+ KDE_CREATE_LIBS_ALIASES
+])
+
+dnl KDE_CHECK_FUNC_EXT(<func>, [headers], [sample-use], [C prototype], [autoheader define], [call if found])
+AC_DEFUN([KDE_CHECK_FUNC_EXT],
+[
+AC_MSG_CHECKING(for $1)
+AC_CACHE_VAL(kde_cv_func_$1,
+[
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+save_CXXFLAGS="$CXXFLAGS"
+kde_safe_LIBS="$LIBS"
+LIBS="$LIBS $X_EXTRA_LIBS"
+if test "$GXX" = "yes"; then
+CXXFLAGS="$CXXFLAGS -pedantic-errors"
+fi
+AC_TRY_COMPILE([
+$2
+],
+[
+$3
+],
+kde_cv_func_$1=yes,
+kde_cv_func_$1=no)
+CXXFLAGS="$save_CXXFLAGS"
+LIBS="$kde_safe_LIBS"
+AC_LANG_RESTORE
+])
+
+AC_MSG_RESULT($kde_cv_func_$1)
+
+AC_MSG_CHECKING([if $1 needs custom prototype])
+AC_CACHE_VAL(kde_cv_proto_$1,
+[
+if test "x$kde_cv_func_$1" = xyes; then
+ kde_cv_proto_$1=no
+else
+ case "$1" in
+ setenv|unsetenv|usleep|random|srandom|seteuid|mkstemps|mkstemp|revoke|vsnprintf|strlcpy|strlcat)
+ kde_cv_proto_$1="yes - in libkdefakes"
+ ;;
+ *)
+ kde_cv_proto_$1=unknown
+ ;;
+ esac
+fi
+
+if test "x$kde_cv_proto_$1" = xunknown; then
+
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+ kde_safe_libs=$LIBS
+ LIBS="$LIBS $X_EXTRA_LIBS"
+ AC_TRY_LINK([
+$2
+
+extern "C" $4;
+],
+[
+$3
+],
+[ kde_cv_func_$1=yes
+ kde_cv_proto_$1=yes ],
+ [kde_cv_proto_$1="$1 unavailable"]
+)
+LIBS=$kde_safe_libs
+AC_LANG_RESTORE
+fi
+])
+AC_MSG_RESULT($kde_cv_proto_$1)
+
+if test "x$kde_cv_func_$1" = xyes; then
+ AC_DEFINE(HAVE_$5, 1, [Define if you have $1])
+ $6
+fi
+if test "x$kde_cv_proto_$1" = xno; then
+ AC_DEFINE(HAVE_$5_PROTO, 1,
+ [Define if you have the $1 prototype])
+fi
+
+AH_VERBATIM([_HAVE_$5_PROTO],
+[
+#if !defined(HAVE_$5_PROTO)
+#ifdef __cplusplus
+extern "C" {
+#endif
+$4;
+#ifdef __cplusplus
+}
+#endif
+#endif
+])
+])
+
+AC_DEFUN([AC_CHECK_SETENV],
+[
+ KDE_CHECK_FUNC_EXT(setenv, [
+#include <stdlib.h>
+],
+ [setenv("VAR", "VALUE", 1);],
+ [int setenv (const char *, const char *, int)],
+ [SETENV])
+])
+
+AC_DEFUN([AC_CHECK_UNSETENV],
+[
+ KDE_CHECK_FUNC_EXT(unsetenv, [
+#include <stdlib.h>
+],
+ [unsetenv("VAR");],
+ [void unsetenv (const char *)],
+ [UNSETENV])
+])
+
+AC_DEFUN([AC_CHECK_GETDOMAINNAME],
+[
+ KDE_CHECK_FUNC_EXT(getdomainname, [
+#include <stdlib.h>
+#include <unistd.h>
+#include <netdb.h>
+],
+ [
+char buffer[200];
+getdomainname(buffer, 200);
+],
+ [#include <sys/types.h>
+ int getdomainname (char *, size_t)],
+ [GETDOMAINNAME])
+])
+
+AC_DEFUN([AC_CHECK_GETHOSTNAME],
+[
+ KDE_CHECK_FUNC_EXT(gethostname, [
+#include <stdlib.h>
+#include <unistd.h>
+],
+ [
+char buffer[200];
+gethostname(buffer, 200);
+],
+ [int gethostname (char *, unsigned int)],
+ [GETHOSTNAME])
+])
+
+AC_DEFUN([AC_CHECK_USLEEP],
+[
+ KDE_CHECK_FUNC_EXT(usleep, [
+#include <unistd.h>
+],
+ [
+usleep(200);
+],
+ [int usleep (unsigned int)],
+ [USLEEP])
+])
+
+
+AC_DEFUN([AC_CHECK_RANDOM],
+[
+ KDE_CHECK_FUNC_EXT(random, [
+#include <stdlib.h>
+],
+ [
+random();
+],
+ [long int random(void)],
+ [RANDOM])
+
+ KDE_CHECK_FUNC_EXT(srandom, [
+#include <stdlib.h>
+],
+ [
+srandom(27);
+],
+ [void srandom(unsigned int)],
+ [SRANDOM])
+
+])
+
+AC_DEFUN([AC_CHECK_INITGROUPS],
+[
+ KDE_CHECK_FUNC_EXT(initgroups, [
+#include <sys/types.h>
+#include <unistd.h>
+#include <grp.h>
+],
+ [
+char buffer[200];
+initgroups(buffer, 27);
+],
+ [int initgroups(const char *, gid_t)],
+ [INITGROUPS])
+])
+
+AC_DEFUN([AC_CHECK_MKSTEMPS],
+[
+ KDE_CHECK_FUNC_EXT(mkstemps, [
+#include <stdlib.h>
+#include <unistd.h>
+],
+ [
+mkstemps("/tmp/aaaXXXXXX", 6);
+],
+ [int mkstemps(char *, int)],
+ [MKSTEMPS])
+])
+
+AC_DEFUN([AC_CHECK_MKSTEMP],
+[
+ KDE_CHECK_FUNC_EXT(mkstemp, [
+#include <stdlib.h>
+#include <unistd.h>
+],
+ [
+mkstemp("/tmp/aaaXXXXXX");
+],
+ [int mkstemp(char *)],
+ [MKSTEMP])
+])
+
+AC_DEFUN([AC_CHECK_MKDTEMP],
+[
+ KDE_CHECK_FUNC_EXT(mkdtemp, [
+#include <stdlib.h>
+#include <unistd.h>
+],
+ [
+mkdtemp("/tmp/aaaXXXXXX");
+],
+ [char *mkdtemp(char *)],
+ [MKDTEMP])
+])
+
+
+AC_DEFUN([AC_CHECK_RES_INIT],
+[
+ AC_MSG_CHECKING([if res_init needs -lresolv])
+ kde_libs_safe="$LIBS"
+ LIBS="$LIBS $X_EXTRA_LIBS -lresolv"
+ AC_TRY_LINK(
+ [
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+ ],
+ [
+ res_init();
+ ],
+ [
+ LIBRESOLV="-lresolv"
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_RES_INIT, 1, [Define if you have the res_init function])
+ ],
+ [ AC_MSG_RESULT(no) ]
+ )
+ LIBS=$kde_libs_safe
+ AC_SUBST(LIBRESOLV)
+
+ KDE_CHECK_FUNC_EXT(res_init,
+ [
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+ ],
+ [res_init()],
+ [int res_init(void)],
+ [RES_INIT])
+])
+
+AC_DEFUN([AC_CHECK_STRLCPY],
+[
+ KDE_CHECK_FUNC_EXT(strlcpy, [
+#include <string.h>
+],
+[ char buf[20];
+ strlcpy(buf, "KDE function test", sizeof(buf));
+],
+ [unsigned long strlcpy(char*, const char*, unsigned long)],
+ [STRLCPY])
+])
+
+AC_DEFUN([AC_CHECK_STRLCAT],
+[
+ KDE_CHECK_FUNC_EXT(strlcat, [
+#include <string.h>
+],
+[ char buf[20];
+ buf[0]='\0';
+ strlcat(buf, "KDE function test", sizeof(buf));
+],
+ [unsigned long strlcat(char*, const char*, unsigned long)],
+ [STRLCAT])
+])
+
+AC_DEFUN([AC_CHECK_RES_QUERY],
+[
+ KDE_CHECK_FUNC_EXT(res_query, [
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <netdb.h>
+],
+[
+res_query(NULL, 0, 0, NULL, 0);
+],
+ [int res_query(const char *, int, int, unsigned char *, int)],
+ [RES_QUERY])
+])
+
+AC_DEFUN([AC_CHECK_DN_SKIPNAME],
+[
+ KDE_CHECK_FUNC_EXT(dn_skipname, [
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+],
+[
+dn_skipname (NULL, NULL);
+],
+ [int dn_skipname (unsigned char *, unsigned char *)],
+ [DN_SKIPNAME])
+])
+
+
+AC_DEFUN([AC_FIND_GIF],
+ [AC_MSG_CHECKING([for giflib])
+AC_CACHE_VAL(ac_cv_lib_gif,
+[ac_save_LIBS="$LIBS"
+if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then
+LIBS="$all_libraries -lgif -lX11 $LIBSOCKET"
+else
+LIBS="$all_libraries -lgif"
+fi
+AC_TRY_LINK(dnl
+[
+#ifdef __cplusplus
+extern "C" {
+#endif
+int GifLastError(void);
+#ifdef __cplusplus
+}
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+],
+ [return GifLastError();],
+ eval "ac_cv_lib_gif=yes",
+ eval "ac_cv_lib_gif=no")
+LIBS="$ac_save_LIBS"
+])dnl
+if eval "test \"`echo $ac_cv_lib_gif`\" = yes"; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE_UNQUOTED(HAVE_LIBGIF, 1, [Define if you have libgif])
+else
+ AC_MSG_ERROR(You need giflib30. Please install the kdesupport package)
+fi
+])
+
+AC_DEFUN([KDE_FIND_JPEG_HELPER],
+[
+AC_MSG_CHECKING([for libjpeg$2])
+AC_CACHE_VAL(ac_cv_lib_jpeg_$1,
+[
+ac_save_LIBS="$LIBS"
+LIBS="$all_libraries $USER_LDFLAGS -ljpeg$2 -lm"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $all_includes $USER_INCLUDES"
+AC_TRY_LINK(
+[
+#ifdef __cplusplus
+extern "C" {
+#endif
+void jpeg_CreateDecompress();
+#ifdef __cplusplus
+}
+#endif
+],
+[jpeg_CreateDecompress();],
+ eval "ac_cv_lib_jpeg_$1=-ljpeg$2",
+ eval "ac_cv_lib_jpeg_$1=no")
+LIBS="$ac_save_LIBS"
+CFLAGS="$ac_save_CFLAGS"
+])
+
+if eval "test ! \"`echo $ac_cv_lib_jpeg_$1`\" = no"; then
+ LIBJPEG="$ac_cv_lib_jpeg_$1"
+ AC_MSG_RESULT($ac_cv_lib_jpeg_$1)
+else
+ AC_MSG_RESULT(no)
+ $3
+fi
+
+])
+
+AC_DEFUN([AC_FIND_JPEG],
+[
+dnl first look for libraries
+KDE_FIND_JPEG_HELPER(6b, 6b,
+ KDE_FIND_JPEG_HELPER(normal, [],
+ [
+ LIBJPEG=
+ ]
+ )
+)
+
+dnl then search the headers (can't use simply AC_TRY_xxx, as jpeglib.h
+dnl requires system dependent includes loaded before it)
+jpeg_incdirs="$includedir /usr/include /usr/local/include $kde_extra_includes"
+AC_FIND_FILE(jpeglib.h, $jpeg_incdirs, jpeg_incdir)
+test "x$jpeg_incdir" = xNO && jpeg_incdir=
+
+dnl if headers _and_ libraries are missing, this is no error, and we
+dnl continue with a warning (the user will get no jpeg support in khtml)
+dnl if only one is missing, it means a configuration error, but we still
+dnl only warn
+if test -n "$jpeg_incdir" && test -n "$LIBJPEG" ; then
+ AC_DEFINE_UNQUOTED(HAVE_LIBJPEG, 1, [Define if you have libjpeg])
+else
+ if test -n "$jpeg_incdir" || test -n "$LIBJPEG" ; then
+ AC_MSG_WARN([
+There is an installation error in jpeg support. You seem to have only one
+of either the headers _or_ the libraries installed. You may need to either
+provide correct --with-extra-... options, or the development package of
+libjpeg6b. You can get a source package of libjpeg from http://www.ijg.org/
+Disabling JPEG support.
+])
+ else
+ AC_MSG_WARN([libjpeg not found. disable JPEG support.])
+ fi
+ jpeg_incdir=
+ LIBJPEG=
+fi
+
+AC_SUBST(LIBJPEG)
+AH_VERBATIM(_AC_CHECK_JPEG,
+[/*
+ * jpeg.h needs HAVE_BOOLEAN, when the system uses boolean in system
+ * headers and I'm too lazy to write a configure test as long as only
+ * unixware is related
+ */
+#ifdef _UNIXWARE
+#define HAVE_BOOLEAN
+#endif
+])
+])
+
+AC_DEFUN([KDE_CHECK_QT_JPEG],
+[
+if test -n "$LIBJPEG"; then
+AC_MSG_CHECKING([if Qt needs $LIBJPEG])
+AC_CACHE_VAL(kde_cv_qt_jpeg,
+[
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+ac_save_LIBS="$LIBS"
+LIBS="$all_libraries $USER_LDFLAGS $LIBQT"
+LIBS=`echo $LIBS | sed "s/$LIBJPEG//"`
+ac_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES"
+AC_TRY_LINK(
+[#include <qapplication.h>],
+ [
+ int argc;
+ char** argv;
+ QApplication app(argc, argv);],
+ eval "kde_cv_qt_jpeg=no",
+ eval "kde_cv_qt_jpeg=yes")
+LIBS="$ac_save_LIBS"
+CXXFLAGS="$ac_save_CXXFLAGS"
+AC_LANG_RESTORE
+fi
+])
+
+if eval "test ! \"`echo $kde_cv_qt_jpeg`\" = no"; then
+ AC_MSG_RESULT(yes)
+ LIBJPEG_QT='$(LIBJPEG)'
+else
+ AC_MSG_RESULT(no)
+ LIBJPEG_QT=
+fi
+
+])
+
+AC_DEFUN([AC_FIND_ZLIB],
+[
+AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+AC_MSG_CHECKING([for libz])
+AC_CACHE_VAL(ac_cv_lib_z,
+[
+kde_save_LIBS="$LIBS"
+LIBS="$all_libraries $USER_LDFLAGS -lz $LIBSOCKET"
+kde_save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $all_includes $USER_INCLUDES"
+AC_TRY_LINK(dnl
+[
+#include<zlib.h>
+],
+[
+ char buf[42];
+ gzFile f = (gzFile) 0;
+ /* this would segfault.. but we only link, don't run */
+ (void) gzgets(f, buf, sizeof(buf));
+
+ return (zlibVersion() == ZLIB_VERSION);
+],
+ eval "ac_cv_lib_z='-lz'",
+ eval "ac_cv_lib_z=no")
+LIBS="$kde_save_LIBS"
+CFLAGS="$kde_save_CFLAGS"
+])dnl
+if test ! "$ac_cv_lib_z" = no; then
+ AC_DEFINE_UNQUOTED(HAVE_LIBZ, 1, [Define if you have libz])
+ LIBZ="$ac_cv_lib_z"
+ AC_MSG_RESULT($ac_cv_lib_z)
+else
+ AC_MSG_ERROR(not found.
+ Possibly configure picks up an outdated version
+ installed by XFree86. Remove it from your system.
+
+ Check your installation and look into config.log)
+ LIBZ=""
+fi
+AC_SUBST(LIBZ)
+])
+
+AC_DEFUN([KDE_TRY_TIFFLIB],
+[
+AC_MSG_CHECKING([for libtiff $1])
+
+AC_CACHE_VAL(kde_cv_libtiff_$1,
+[
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+kde_save_LIBS="$LIBS"
+if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then
+LIBS="$all_libraries $USER_LDFLAGS -l$1 $LIBJPEG $LIBZ -lX11 $LIBSOCKET -lm"
+else
+LIBS="$all_libraries $USER_LDFLAGS -l$1 $LIBJPEG $LIBZ -lm"
+fi
+kde_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES"
+
+AC_TRY_LINK(dnl
+[
+#include<tiffio.h>
+],
+ [return (TIFFOpen( "", "r") == 0); ],
+[
+ kde_cv_libtiff_$1="-l$1 $LIBJPEG $LIBZ"
+], [
+ kde_cv_libtiff_$1=no
+])
+
+LIBS="$kde_save_LIBS"
+CXXFLAGS="$kde_save_CXXFLAGS"
+AC_LANG_RESTORE
+])
+
+if test "$kde_cv_libtiff_$1" = "no"; then
+ AC_MSG_RESULT(no)
+ LIBTIFF=""
+ $3
+else
+ LIBTIFF="$kde_cv_libtiff_$1"
+ AC_MSG_RESULT(yes)
+ AC_DEFINE_UNQUOTED(HAVE_LIBTIFF, 1, [Define if you have libtiff])
+ $2
+fi
+
+])
+
+AC_DEFUN([AC_FIND_TIFF],
+[
+AC_REQUIRE([K_PATH_X])
+AC_REQUIRE([AC_FIND_ZLIB])
+AC_REQUIRE([AC_FIND_JPEG])
+AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+
+KDE_TRY_TIFFLIB(tiff, [],
+ KDE_TRY_TIFFLIB(tiff34))
+
+AC_SUBST(LIBTIFF)
+])
+
+AC_DEFUN([KDE_FIND_LIBEXR],
+[
+AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+AC_REQUIRE([AC_FIND_ZLIB])
+AC_CACHE_VAL(ac_cv_libexr,
+[
+ if test -z "$PKG_CONFIG"; then
+ AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+ fi
+
+ AC_MSG_CHECKING([for OpenEXR libraries])
+
+ if test "$PKG_CONFIG" = "no" ; then
+ AC_MSG_RESULT(no)
+ echo "*** The pkg-config script could not be found. Make sure it is"
+ echo "*** in your path, or set the PKG_CONFIG environment variable"
+ echo "*** to the full path to pkg-config."
+ echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
+ else
+ if !(`$PKG_CONFIG --exists OpenEXR`) ; then
+ AC_MSG_RESULT(no)
+ EXRSTATUS=no
+ else
+ if !(`$PKG_CONFIG --atleast-version="1.1.1" OpenEXR`) ; then
+ AC_MSG_RESULT(no)
+ EXRSTATUS=old
+ else
+ kde_save_LIBS="$LIBS"
+ LIBS="$LIBS $all_libraries $USER_LDFLAGS $LIBZ `pkg-config --libs OpenEXR`"
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ kde_save_CXXFLAGS="$CXXFLAGS"
+ EXR_FLAGS=`$PKG_CONFIG --cflags OpenEXR`
+ CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES $EXR_FLAGS"
+
+ AC_TRY_LINK(dnl
+ [
+ #include <ImfRgbaFile.h>
+ ],
+ [
+ using namespace Imf;
+ RgbaInputFile file ("dummy");
+ return 0;
+ ],
+ eval "ac_cv_libexr='`pkg-config --libs OpenEXR`'",
+ eval "ac_cv_libexr=no"
+ )
+ LIBS="$kde_save_LIBS"
+ CXXFLAGS="$kde_save_CXXFLAGS"
+ AC_LANG_RESTORE
+ ])dnl
+ if eval "test ! \"`echo $ac_cv_libexr`\" = no"; then
+ AC_DEFINE_UNQUOTED(HAVE_EXR, 1, [Define if you have OpenEXR])
+ LIB_EXR="$ac_cv_libexr"
+ AC_MSG_RESULT($ac_cv_libexr)
+ else
+ AC_MSG_RESULT(no)
+ LIB_EXR=""
+ fi
+ fi
+ fi
+ fi
+ AC_SUBST(LIB_EXR)
+ AC_SUBST(EXR_FLAGS)
+])
+
+
+
+AC_DEFUN([AC_FIND_PNG],
+[
+AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+AC_REQUIRE([AC_FIND_ZLIB])
+AC_MSG_CHECKING([for libpng])
+AC_CACHE_VAL(ac_cv_lib_png,
+[
+kde_save_LIBS="$LIBS"
+if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then
+LIBS="$LIBS $all_libraries $USER_LDFLAGS -lpng $LIBZ -lm -lX11 $LIBSOCKET"
+else
+LIBS="$LIBS $all_libraries $USER_LDFLAGS -lpng $LIBZ -lm"
+fi
+kde_save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $all_includes $USER_INCLUDES"
+
+AC_TRY_LINK(dnl
+ [
+ #include<png.h>
+ ],
+ [
+ png_structp png_ptr = png_create_read_struct( /* image ptr */
+ PNG_LIBPNG_VER_STRING, 0, 0, 0 );
+ return( png_ptr != 0 );
+ ],
+ eval "ac_cv_lib_png='-lpng $LIBZ -lm'",
+ eval "ac_cv_lib_png=no"
+)
+LIBS="$kde_save_LIBS"
+CFLAGS="$kde_save_CFLAGS"
+])dnl
+if eval "test ! \"`echo $ac_cv_lib_png`\" = no"; then
+ AC_DEFINE_UNQUOTED(HAVE_LIBPNG, 1, [Define if you have libpng])
+ LIBPNG="$ac_cv_lib_png"
+ AC_SUBST(LIBPNG)
+ AC_MSG_RESULT($ac_cv_lib_png)
+else
+ AC_MSG_RESULT(no)
+ LIBPNG=""
+ AC_SUBST(LIBPNG)
+fi
+])
+
+
+AC_DEFUN([AC_FIND_JASPER],
+[
+AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+AC_REQUIRE([AC_FIND_JPEG])
+AC_MSG_CHECKING([for jasper])
+AC_CACHE_VAL(ac_cv_jasper,
+[
+kde_save_LIBS="$LIBS"
+LIBS="$LIBS $all_libraries $USER_LDFLAGS -ljasper $LIBJPEG -lm"
+kde_save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $all_includes $USER_INCLUDES"
+
+AC_TRY_LINK(dnl
+ [
+ #include<jasper/jasper.h>
+ ],
+ [
+ return( jas_init() );
+ ],
+ eval "ac_cv_jasper='-ljasper $LIBJPEG -lm'",
+ eval "ac_cv_jasper=no"
+)
+LIBS="$kde_save_LIBS"
+CFLAGS="$kde_save_CFLAGS"
+])dnl
+if eval "test ! \"`echo $ac_cv_jasper`\" = no"; then
+ AC_DEFINE_UNQUOTED(HAVE_JASPER, 1, [Define if you have jasper])
+ LIB_JASPER="$ac_cv_jasper"
+ AC_MSG_RESULT($ac_cv_jasper)
+else
+ AC_MSG_RESULT(no)
+ LIB_JASPER=""
+fi
+AC_SUBST(LIB_JASPER)
+])
+
+AC_DEFUN([AC_CHECK_BOOL],
+[
+ AC_DEFINE_UNQUOTED(HAVE_BOOL, 1, [You _must_ have bool])
+])
+
+AC_DEFUN([AC_CHECK_GNU_EXTENSIONS],
+[
+AC_MSG_CHECKING(if you need GNU extensions)
+AC_CACHE_VAL(ac_cv_gnu_extensions,
+[
+cat > conftest.c << EOF
+#include <features.h>
+
+#ifdef __GNU_LIBRARY__
+yes
+#endif
+EOF
+
+if (eval "$ac_cpp conftest.c") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_gnu_extensions=yes
+else
+ ac_cv_gnu_extensions=no
+fi
+])
+
+AC_MSG_RESULT($ac_cv_gnu_extensions)
+if test "$ac_cv_gnu_extensions" = "yes"; then
+ AC_DEFINE_UNQUOTED(_GNU_SOURCE, 1, [Define if you need to use the GNU extensions])
+fi
+])
+
+AC_DEFUN([KDE_CHECK_COMPILER_FLAG],
+[
+AC_MSG_CHECKING([whether $CXX supports -$1])
+kde_cache=`echo $1 | sed 'y% .=/+-,%____p__%'`
+AC_CACHE_VAL(kde_cv_prog_cxx_$kde_cache,
+[
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS -$1"
+ AC_TRY_LINK([],[ return 0; ], [eval "kde_cv_prog_cxx_$kde_cache=yes"], [])
+ CXXFLAGS="$save_CXXFLAGS"
+ AC_LANG_RESTORE
+])
+if eval "test \"`echo '$kde_cv_prog_cxx_'$kde_cache`\" = yes"; then
+ AC_MSG_RESULT(yes)
+ :
+ $2
+else
+ AC_MSG_RESULT(no)
+ :
+ $3
+fi
+])
+
+AC_DEFUN([KDE_CHECK_C_COMPILER_FLAG],
+[
+AC_MSG_CHECKING([whether $CC supports -$1])
+kde_cache=`echo $1 | sed 'y% .=/+-,%____p__%'`
+AC_CACHE_VAL(kde_cv_prog_cc_$kde_cache,
+[
+ AC_LANG_SAVE
+ AC_LANG_C
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -$1"
+ AC_TRY_LINK([],[ return 0; ], [eval "kde_cv_prog_cc_$kde_cache=yes"], [])
+ CFLAGS="$save_CFLAGS"
+ AC_LANG_RESTORE
+])
+if eval "test \"`echo '$kde_cv_prog_cc_'$kde_cache`\" = yes"; then
+ AC_MSG_RESULT(yes)
+ :
+ $2
+else
+ AC_MSG_RESULT(no)
+ :
+ $3
+fi
+])
+
+
+dnl AC_REMOVE_FORBIDDEN removes forbidden arguments from variables
+dnl use: AC_REMOVE_FORBIDDEN(CC, [-forbid -bad-option whatever])
+dnl it's all white-space separated
+AC_DEFUN([AC_REMOVE_FORBIDDEN],
+[ __val=$$1
+ __forbid=" $2 "
+ if test -n "$__val"; then
+ __new=""
+ ac_save_IFS=$IFS
+ IFS=" "
+ for i in $__val; do
+ case "$__forbid" in
+ *" $i "*) AC_MSG_WARN([found forbidden $i in $1, removing it]) ;;
+ *) # Careful to not add spaces, where there were none, because otherwise
+ # libtool gets confused, if we change e.g. CXX
+ if test -z "$__new" ; then __new=$i ; else __new="$__new $i" ; fi ;;
+ esac
+ done
+ IFS=$ac_save_IFS
+ $1=$__new
+ fi
+])
+
+
+AC_DEFUN([KDE_CHECK_FOR_BAD_COMPILER],
+[
+ AC_MSG_CHECKING([whether $CC is blacklisted])
+
+ dnl In theory we have tu run this test against $CC and $CXX
+ dnl in C and in C++ mode, because its perfectly legal for
+ dnl the user to mix compiler versions, since C has a defined
+ dnl ABI.
+ dnl
+ dnl For now, we assume the user is not on crack.
+
+ AC_TRY_COMPILE([
+#ifdef __GNUC__
+#if __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 0
+choke me
+#endif
+#endif
+], ,
+ kde_bad_compiler=no,
+ kde_bad_compiler=yes
+)
+
+ AC_MSG_RESULT($kde_bad_compiler)
+
+if test "$kde_bad_compiler" = "yes"; then
+ AC_MSG_ERROR([
+
+This particular compiler version is blacklisted because it
+is known to miscompile KDE. Please use a newer version, or
+if that is not yet available, choose an older version.
+
+Please do not report a bug or bother us reporting this
+configure error. We know about it, and we introduced
+it by intention to avoid untraceable bugs or crashes in KDE.
+
+])
+fi
+
+])
+
+
+AC_DEFUN([KDE_CHECK_FOR_OPT_NOINLINE_MATCH],
+[
+ AC_CACHE_CHECK([whether system headers can cope with -O2 -fno-inline],
+ kde_cv_opt_noinline_match,
+ [
+ kde_cv_opt_noinline_match=irrelevant
+ dnl if we don't use both -O2 and -fno-inline, this check is moot
+ if echo "$CFLAGS" | grep -qe -O2 \
+ && echo "$CFLAGS" | grep -qe -fno-inline ; then
+
+ ac_cflags_save="$CFLAGS"
+ CFLAGS="$CFLAGS -D_USE_GNU"
+
+ AC_TRY_LINK([
+ #include <string.h>
+], [ const char *pt, *et;
+ et = __extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p ( ";," ) && ((size_t)(const void *)(( ";," )+ 1) - (size_t)(const void *)( ";," ) == 1) ? ((__a0 =((__const char *) ( ";," ))[0], __a0 == '\0') ? ((void) ( pt ),((void *)0) ) : ((__a1 = ((__const char *) ( ";," ))[1], __a1== '\0') ? (__extension__ (__builtin_constant_p ( __a0 ) && ( __a0 ) == '\0' ? (char *) __rawmemchr ( pt , __a0) : strchr( pt , __a0 ))) : ((__a2 = ((__const char *) ( ";," ))[2], __a2 == '\0') ? __strpbrk_c2 ( pt , __a0, __a1) :(((__const char *) ( ";," ))[3] == '\0' ? __strpbrk_c3 ( pt ,__a0, __a1, __a2): strpbrk ( pt , ";," ))))) : strpbrk ( pt , ";," )); }) ;
+],
+ kde_cv_opt_noinline_match=yes,
+ kde_cv_opt_noinline_match=no
+ )
+
+ CFLAGS="$ac_cflags_save"
+ fi
+ ])
+])
+
+
+dnl AC_VALIDIFY_CXXFLAGS checks for forbidden flags the user may have given
+AC_DEFUN([AC_VALIDIFY_CXXFLAGS],
+[dnl
+if test "x$kde_use_qt_emb" != "xyes"; then
+ AC_REMOVE_FORBIDDEN(CXX, [-fno-rtti -rpath])
+ AC_REMOVE_FORBIDDEN(CXXFLAGS, [-fno-rtti -rpath])
+else
+ AC_REMOVE_FORBIDDEN(CXX, [-rpath])
+ AC_REMOVE_FORBIDDEN(CXXFLAGS, [-rpath])
+fi
+])
+
+AC_DEFUN([AC_CHECK_COMPILERS],
+[
+ AC_ARG_ENABLE(debug,
+ AC_HELP_STRING([--enable-debug=ARG],[enables debug symbols (yes|no|full) [default=no]]),
+ [
+ case $enableval in
+ yes)
+ kde_use_debug_code="yes"
+ kde_use_debug_define=no
+ ;;
+ full)
+ kde_use_debug_code="full"
+ kde_use_debug_define=no
+ ;;
+ *)
+ kde_use_debug_code="no"
+ kde_use_debug_define=yes
+ ;;
+ esac
+ ],
+ [kde_use_debug_code="no"
+ kde_use_debug_define=no
+ ])
+
+ dnl Just for configure --help
+ AC_ARG_ENABLE(dummyoption,
+ AC_HELP_STRING([--disable-debug],
+ [disables debug output and debug symbols [default=no]]),
+ [],[])
+
+ AC_ARG_ENABLE(strict,
+ AC_HELP_STRING([--enable-strict],
+ [compiles with strict compiler options (may not work!)]),
+ [
+ if test $enableval = "no"; then
+ kde_use_strict_options="no"
+ else
+ kde_use_strict_options="yes"
+ fi
+ ], [kde_use_strict_options="no"])
+
+ AC_ARG_ENABLE(warnings,AC_HELP_STRING([--disable-warnings],[disables compilation with -Wall and similar]),
+ [
+ if test $enableval = "no"; then
+ kde_use_warnings="no"
+ else
+ kde_use_warnings="yes"
+ fi
+ ], [kde_use_warnings="yes"])
+
+ dnl enable warnings for debug build
+ if test "$kde_use_debug_code" != "no"; then
+ kde_use_warnings=yes
+ fi
+
+ AC_ARG_ENABLE(profile,AC_HELP_STRING([--enable-profile],[creates profiling infos [default=no]]),
+ [kde_use_profiling=$enableval],
+ [kde_use_profiling="no"]
+ )
+
+ dnl this prevents stupid AC_PROG_CC to add "-g" to the default CFLAGS
+ CFLAGS=" $CFLAGS"
+
+ AC_PROG_CC
+
+ AC_PROG_CPP
+
+ if test "$GCC" = "yes"; then
+ if test "$kde_use_debug_code" != "no"; then
+ if test $kde_use_debug_code = "full"; then
+ CFLAGS="-g3 -fno-inline $CFLAGS"
+ else
+ CFLAGS="-g -O2 -fno-schedule-insns -fno-inline $CFLAGS"
+ fi
+ else
+ CFLAGS="-O2 $CFLAGS"
+ fi
+ fi
+
+ if test "$kde_use_debug_define" = "yes"; then
+ CFLAGS="-DNDEBUG $CFLAGS"
+ fi
+
+
+ case "$host" in
+ *-*-sysv4.2uw*) CFLAGS="-D_UNIXWARE $CFLAGS";;
+ *-*-sysv5uw7*) CFLAGS="-D_UNIXWARE7 $CFLAGS";;
+ esac
+
+ if test -z "$LDFLAGS" && test "$kde_use_debug_code" = "no" && test "$GCC" = "yes"; then
+ LDFLAGS=""
+ fi
+
+ CXXFLAGS=" $CXXFLAGS"
+
+ AC_PROG_CXX
+
+ KDE_CHECK_FOR_BAD_COMPILER
+
+ if test "$GXX" = "yes" || test "$CXX" = "KCC"; then
+ if test "$kde_use_debug_code" != "no"; then
+ if test "$CXX" = "KCC"; then
+ CXXFLAGS="+K0 -Wall -pedantic -W -Wpointer-arith -Wwrite-strings $CXXFLAGS"
+ else
+ if test "$kde_use_debug_code" = "full"; then
+ CXXFLAGS="-g3 -fno-inline $CXXFLAGS"
+ else
+ CXXFLAGS="-g -O2 -fno-schedule-insns -fno-inline $CXXFLAGS"
+ fi
+ fi
+ KDE_CHECK_COMPILER_FLAG(fno-builtin,[CXXFLAGS="-fno-builtin $CXXFLAGS"])
+
+ dnl convenience compiler flags
+ KDE_CHECK_COMPILER_FLAG(Woverloaded-virtual, [WOVERLOADED_VIRTUAL="-Woverloaded-virtual"], [WOVERLOADED_VRITUAL=""])
+ AC_SUBST(WOVERLOADED_VIRTUAL)
+ else
+ if test "$CXX" = "KCC"; then
+ CXXFLAGS="+K3 $CXXFLAGS"
+ else
+ CXXFLAGS="-O2 $CXXFLAGS"
+ fi
+ fi
+ fi
+
+ if test "$kde_use_debug_define" = "yes"; then
+ CXXFLAGS="-DNDEBUG -DNO_DEBUG $CXXFLAGS"
+ fi
+
+ if test "$kde_use_profiling" = "yes"; then
+ KDE_CHECK_COMPILER_FLAG(pg,
+ [
+ CFLAGS="-pg $CFLAGS"
+ CXXFLAGS="-pg $CXXFLAGS"
+ ])
+ fi
+
+ if test "$kde_use_warnings" = "yes"; then
+ if test "$GCC" = "yes"; then
+ CXXFLAGS="-Wall -W -Wpointer-arith $CXXFLAGS"
+ case $host in
+ *-*-linux-gnu)
+ CFLAGS="-std=iso9899:1990 -W -Wall -Wchar-subscripts -Wshadow -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -D_XOPEN_SOURCE=500 -D_BSD_SOURCE $CFLAGS"
+ CXXFLAGS="-ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -Wchar-subscripts $CXXFLAGS"
+ KDE_CHECK_COMPILER_FLAG(Wmissing-format-attribute, [CXXFLAGS="$CXXFLAGS -Wformat-security -Wmissing-format-attribute"])
+ KDE_CHECK_C_COMPILER_FLAG(Wmissing-format-attribute, [CFLAGS="$CFLAGS -Wformat-security -Wmissing-format-attribute"])
+ ;;
+ esac
+ KDE_CHECK_COMPILER_FLAG(Wundef,[CXXFLAGS="-Wundef $CXXFLAGS"])
+ KDE_CHECK_COMPILER_FLAG(Wno-long-long,[CXXFLAGS="-Wno-long-long $CXXFLAGS"])
+ dnl ### FIXME: revert for KDE 4
+ KDE_CHECK_COMPILER_FLAG(Wno-non-virtual-dtor,[CXXFLAGS="$CXXFLAGS -Wno-non-virtual-dtor"])
+ fi
+ fi
+
+ if test "$GXX" = "yes" && test "$kde_use_strict_options" = "yes"; then
+ CXXFLAGS="-Wcast-qual -Wshadow -Wcast-align $CXXFLAGS"
+ fi
+
+ AC_ARG_ENABLE(pch,
+ AC_HELP_STRING([--enable-pch],
+ [enables precompiled header support (currently only KCC or gcc >=3.4+unsermake) [default=no]]),
+ [ kde_use_pch=$enableval ],[ kde_use_pch=no ])
+
+ HAVE_GCC_VISIBILITY=0
+ AC_SUBST([HAVE_GCC_VISIBILITY])
+
+ if test "$GXX" = "yes"; then
+ gcc_no_reorder_blocks=NO
+ KDE_CHECK_COMPILER_FLAG(fno-reorder-blocks,[gcc_no_reorder_blocks=YES])
+ if test $kde_use_debug_code != "no" && \
+ test $kde_use_debug_code != "full" && \
+ test "YES" = "$gcc_no_reorder_blocks" ; then
+ CXXFLAGS="$CXXFLAGS -fno-reorder-blocks"
+ CFLAGS="$CFLAGS -fno-reorder-blocks"
+ fi
+ KDE_CHECK_COMPILER_FLAG(fno-exceptions,[CXXFLAGS="$CXXFLAGS -fno-exceptions"])
+ KDE_CHECK_COMPILER_FLAG(fno-check-new, [CXXFLAGS="$CXXFLAGS -fno-check-new"])
+ KDE_CHECK_COMPILER_FLAG(fno-common, [CXXFLAGS="$CXXFLAGS -fno-common"])
+ KDE_CHECK_COMPILER_FLAG(fexceptions, [USE_EXCEPTIONS="-fexceptions"], USE_EXCEPTIONS= )
+ ENABLE_PERMISSIVE_FLAG="-fpermissive"
+
+ if test "$kde_use_pch" = "yes"; then
+ AC_MSG_CHECKING(whether gcc supports precompiling c header files)
+ echo >conftest.h
+ if $CC -x c-header conftest.h >/dev/null 2>/dev/null; then
+ kde_gcc_supports_pch=yes
+ AC_MSG_RESULT(yes)
+ else
+ kde_gcc_supports_pch=no
+ AC_MSG_RESULT(no)
+ fi
+ if test "$kde_gcc_supports_pch" = "yes"; then
+ AC_MSG_CHECKING(whether gcc supports precompiling c++ header files)
+ if $CXX -x c++-header conftest.h >/dev/null 2>/dev/null; then
+ kde_gcc_supports_pch=yes
+ AC_MSG_RESULT(yes)
+ else
+ kde_gcc_supports_pch=no
+ AC_MSG_RESULT(no)
+ fi
+ fi
+ rm -f conftest.h conftest.h.gch
+ fi
+
+ KDE_CHECK_FOR_OPT_NOINLINE_MATCH
+ if test "x$kde_cv_opt_noinline_match" = "xno" ; then
+ CFLAGS="`echo "$CFLAGS" | sed "s/ -fno-inline//"`"
+ fi
+ fi
+ AM_CONDITIONAL(unsermake_enable_pch, test "$kde_use_pch" = "yes" && test "$kde_gcc_supports_pch" = "yes")
+ if test "$CXX" = "KCC"; then
+ dnl unfortunately we currently cannot disable exception support in KCC
+ dnl because doing so is binary incompatible and Qt by default links with exceptions :-(
+ dnl KDE_CHECK_COMPILER_FLAG(-no_exceptions,[CXXFLAGS="$CXXFLAGS --no_exceptions"])
+ dnl KDE_CHECK_COMPILER_FLAG(-exceptions, [USE_EXCEPTIONS="--exceptions"], USE_EXCEPTIONS= )
+
+ if test "$kde_use_pch" = "yes"; then
+ dnl TODO: support --pch-dir!
+ KDE_CHECK_COMPILER_FLAG(-pch,[CXXFLAGS="$CXXFLAGS --pch"])
+ dnl the below works (but the dir must exist), but it's
+ dnl useless for a whole package.
+ dnl The are precompiled headers for each source file, so when compiling
+ dnl from scratch, it doesn't make a difference, and they take up
+ dnl around ~5Mb _per_ sourcefile.
+ dnl KDE_CHECK_COMPILER_FLAG(-pch_dir /tmp,
+ dnl [CXXFLAGS="$CXXFLAGS --pch_dir `pwd`/pcheaders"])
+ fi
+ dnl this flag controls inlining. by default KCC inlines in optimisation mode
+ dnl all implementations that are defined inside the class {} declaration.
+ dnl because of templates-compatibility with broken gcc compilers, this
+ dnl can cause excessive inlining. This flag limits it to a sane level
+ KDE_CHECK_COMPILER_FLAG(-inline_keyword_space_time=6,[CXXFLAGS="$CXXFLAGS --inline_keyword_space_time=6"])
+ KDE_CHECK_COMPILER_FLAG(-inline_auto_space_time=2,[CXXFLAGS="$CXXFLAGS --inline_auto_space_time=2"])
+ KDE_CHECK_COMPILER_FLAG(-inline_implicit_space_time=2.0,[CXXFLAGS="$CXXFLAGS --inline_implicit_space_time=2.0"])
+ KDE_CHECK_COMPILER_FLAG(-inline_generated_space_time=2.0,[CXXFLAGS="$CXXFLAGS --inline_generated_space_time=2.0"])
+ dnl Some source files are shared between multiple executables
+ dnl (or libraries) and some of those need template instantiations.
+ dnl In that case KCC needs to compile those sources with
+ dnl --one_instantiation_per_object. To make it easy for us we compile
+ dnl _all_ objects with that flag (--one_per is a shorthand).
+ KDE_CHECK_COMPILER_FLAG(-one_per, [CXXFLAGS="$CXXFLAGS --one_per"])
+ fi
+ AC_SUBST(USE_EXCEPTIONS)
+ dnl obsolete macro - provided to keep things going
+ USE_RTTI=
+ AC_SUBST(USE_RTTI)
+
+ case "$host" in
+ *-*-irix*) test "$GXX" = yes && CXXFLAGS="-D_LANGUAGE_C_PLUS_PLUS -D__LANGUAGE_C_PLUS_PLUS $CXXFLAGS" ;;
+ *-*-sysv4.2uw*) CXXFLAGS="-D_UNIXWARE $CXXFLAGS";;
+ *-*-sysv5uw7*) CXXFLAGS="-D_UNIXWARE7 $CXXFLAGS";;
+ *-*-solaris*)
+ if test "$GXX" = yes; then
+ libstdcpp=`$CXX -print-file-name=libstdc++.so`
+ if test ! -f $libstdcpp; then
+ AC_MSG_ERROR([You've compiled gcc without --enable-shared. This doesn't work with KDE. Please recompile gcc with --enable-shared to receive a libstdc++.so])
+ fi
+ fi
+ ;;
+ esac
+
+ AC_VALIDIFY_CXXFLAGS
+
+ AC_PROG_CXXCPP
+
+ if test "$GCC" = yes; then
+ NOOPT_CFLAGS=-O0
+ fi
+ KDE_CHECK_COMPILER_FLAG(O0,[NOOPT_CXXFLAGS=-O0])
+
+ AC_ARG_ENABLE(coverage,
+ AC_HELP_STRING([--enable-coverage],[use gcc coverage testing]), [
+ if test "$am_cv_CC_dependencies_compiler_type" = "gcc3"; then
+ ac_coverage_compiler="-fprofile-arcs -ftest-coverage"
+ ac_coverage_linker="-lgcc"
+ elif test "$am_cv_CC_dependencies_compiler_type" = "gcc"; then
+ ac_coverage_compiler="-fprofile-arcs -ftest-coverage"
+ ac_coverage_linker=""
+ else
+ AC_MSG_ERROR([coverage with your compiler is not supported])
+ fi
+ CFLAGS="$CFLAGS $ac_coverage_compiler"
+ CXXFLAGS="$CXXFLAGS $ac_coverage_compiler"
+ LDFLAGS="$LDFLAGS $ac_coverage_linker"
+ ])
+
+ AC_SUBST(NOOPT_CXXFLAGS)
+ AC_SUBST(NOOPT_CFLAGS)
+ AC_SUBST(ENABLE_PERMISSIVE_FLAG)
+
+ KDE_CHECK_NEW_LDFLAGS
+ KDE_CHECK_FINAL
+ KDE_CHECK_CLOSURE
+ KDE_CHECK_NMCHECK
+
+ ifdef([AM_DEPENDENCIES], AC_REQUIRE([KDE_ADD_DEPENDENCIES]), [])
+])
+
+AC_DEFUN([KDE_CHECK_VISIBILITY_GCC_BUG],
+ [
+ AC_CACHE_CHECK([for gcc -fvisibility-inlines-hidden bug], kde_cv_val_gcc_visibility_bug,
+ [
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+
+ safe_CXXFLAGS=$CXXFLAGS
+ safe_LDFLAGS=$LDFLAGS
+ CXXFLAGS="$CXXFLAGS -fPIC -fvisibility-inlines-hidden -O0"
+ LDFLAGS="$LDFLAGS -shared -fPIC"
+
+ AC_TRY_LINK(
+ [
+ /* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19664 */
+ #include <string>
+ int some_function( void ) __attribute__ ((visibility("default")));
+ int some_function( void )
+ {
+ std::string s("blafasel");
+ return 0;
+ }
+ ], [/* elvis is alive */],
+ kde_cv_val_gcc_visibility_bug=no, kde_cv_val_gcc_visibility_bug=yes)
+
+ CXXFLAGS=$safe_CXXFLAGS
+ LDFLAGS=$safe_LDFLAGS
+ AC_LANG_RESTORE
+ ]
+ )
+
+ if test x$kde_cv_val_gcc_visibility_bug = xno; then
+ CXXFLAGS="$CXXFLAGS -fvisibility-inlines-hidden"
+ fi
+ ]
+)
+
+AC_DEFUN([KDE_ENABLE_HIDDEN_VISIBILITY],
+[
+ AC_BEFORE([AC_PATH_QT_1_3], [KDE_ENABLE_HIDDEN_VISIBILITY])
+
+ AC_MSG_CHECKING([grepping for visibility push/pop in headers])
+
+ if test "x$GXX" = "xyes"; then
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_EGREP_CPP(
+ [GCC visibility push],
+ [ #include <exception>
+ ],
+ [
+ AC_MSG_RESULT(yes)
+ kde_stdc_visibility_patched=yes ],
+ [
+ AC_MSG_RESULT(no)
+ AC_MSG_WARN([Your libstdc++ doesn't appear to be patched for
+ visibility support. Disabling -fvisibility=hidden])
+
+ kde_stdc_visibility_patched=no ])
+
+ AC_LANG_RESTORE
+
+ kde_have_gcc_visibility=no
+ KDE_CHECK_COMPILER_FLAG(fvisibility=hidden,
+ [
+ kde_have_gcc_visibility=yes
+ dnl the whole toolchain is just a mess, gcc is just too buggy
+ dnl to handle STL with visibility enabled. Lets reconsider
+ dnl when gcc 4.2 is out or when things get fixed in the compiler.
+ dnl Contact mueller@kde.org for details.
+ AC_ARG_ENABLE(gcc-hidden-visibility,
+ AC_HELP_STRING([--enable-gcc-hidden-visibility],[toolchain hidden visibility [default=no]]),
+ [kde_have_gcc_visibility=$enableval],
+ [kde_have_gcc_visibility=no])
+
+ AC_CACHE_CHECK([if Qt is patched for -fvisibility], kde_cv_val_qt_gcc_visibility_patched,
+ [
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+
+ safe_CXXFLAGS=$CXXFLAGS
+ CXXFLAGS="$CXXFLAGS $all_includes"
+
+ AC_TRY_COMPILE(
+ [
+#include <qglobal.h>
+#if Q_EXPORT - 0 != 0
+/* if this compiles, then Q_EXPORT is undefined */
+/* if Q_EXPORT is nonempty, this will break compilation */
+#endif
+ ], [/* elvis is alive */],
+ kde_cv_val_qt_gcc_visibility_patched=no, kde_cv_val_qt_gcc_visibility_patched=yes)
+
+ CXXFLAGS=$safe_CXXFLAGS
+ AC_LANG_RESTORE
+ ]
+ )
+
+ if test x$kde_have_gcc_visibility = "xyes" && test x$kde_stdc_visibility_patched = "xyes" && test x$kde_cv_val_qt_gcc_visibility_patched = "xyes"; then
+ CXXFLAGS="$CXXFLAGS -fvisibility=hidden"
+ KDE_CHECK_VISIBILITY_GCC_BUG
+ HAVE_GCC_VISIBILITY=1
+ AC_DEFINE_UNQUOTED(__KDE_HAVE_GCC_VISIBILITY, "$HAVE_GCC_VISIBILITY", [define to 1 if -fvisibility is supported])
+ fi
+ ])
+ fi
+])
+
+AC_DEFUN([KDE_ADD_DEPENDENCIES],
+[
+ [A]M_DEPENDENCIES(CC)
+ [A]M_DEPENDENCIES(CXX)
+])
+
+dnl just a wrapper to clean up configure.in
+AC_DEFUN([KDE_PROG_LIBTOOL],
+[
+AC_REQUIRE([AC_CHECK_COMPILERS])
+AC_REQUIRE([AC_ENABLE_SHARED])
+AC_REQUIRE([AC_ENABLE_STATIC])
+
+AC_REQUIRE([AC_LIBTOOL_DLOPEN])
+AC_REQUIRE([KDE_CHECK_LIB64])
+
+AC_OBJEXT
+AC_EXEEXT
+
+AM_PROG_LIBTOOL
+AC_LIBTOOL_CXX
+
+LIBTOOL_SHELL="/bin/sh ./libtool"
+# LIBTOOL="$LIBTOOL --silent"
+KDE_PLUGIN="-avoid-version -module -no-undefined \$(KDE_NO_UNDEFINED) \$(KDE_RPATH) \$(KDE_MT_LDFLAGS)"
+AC_SUBST(KDE_PLUGIN)
+
+# This hack ensures that libtool creates shared libs for kunittest plugins. By default check_LTLIBRARIES makes static libs.
+KDE_CHECK_PLUGIN="\$(KDE_PLUGIN) -rpath \$(libdir)"
+AC_SUBST(KDE_CHECK_PLUGIN)
+
+# we patch configure quite some so we better keep that consistent for incremental runs
+AC_SUBST(AUTOCONF,'$(SHELL) $(top_srcdir)/admin/cvs.sh configure || touch configure')
+])
+
+AC_DEFUN([KDE_CHECK_LIB64],
+[
+ kdelibsuff="$kde_libs_suffix"
+ if test -z "$kdelibsuff"; then
+ kdelibsuff="auto"
+ fi
+ AC_ARG_ENABLE(libsuffix,
+ AC_HELP_STRING([--enable-libsuffix],
+ [/lib directory suffix (64,32,none,auto[=default])]),
+ kdelibsuff=$enableval)
+
+ if test "$kdelibsuff" = "auto"; then
+
+cat > conftest.c << EOF
+#include <stdio.h>
+int main() {
+ return 0;
+}
+EOF
+ kdelibsuff=`$CC conftest.c -o conftest.out; ldd conftest.out | grep -E "libc.so"| grep -E -o "/lib[[^\/]]*/" | sed "s/lib//" | sed "s/\/*//g"`
+ rm -rf conftest.*
+ fi
+
+ if test "$kdelibsuff" = "no"; then
+ kdelibsuff=
+ fi
+ if test -z "$kdelibsuff"; then
+ AC_MSG_RESULT([not using lib directory suffix])
+ AC_DEFINE(KDELIBSUFF, [""], Suffix for lib directories)
+ else
+ if test "$libdir" = '${exec_prefix}/lib'; then
+ libdir="$libdir${kdelibsuff}"
+ AC_SUBST([libdir], ["$libdir"]) dnl ugly hack for lib64 platforms
+ fi
+ AC_DEFINE_UNQUOTED(KDELIBSUFF, ["${kdelibsuff}"], Suffix for lib directories)
+ AC_MSG_RESULT([using lib directory suffix $kdelibsuff])
+ fi
+])
+
+AC_DEFUN([KDE_CHECK_TYPES],
+[ AC_CHECK_SIZEOF(int, 4)dnl
+ AC_CHECK_SIZEOF(short)dnl
+ AC_CHECK_SIZEOF(long, 4)dnl
+ AC_CHECK_SIZEOF(char *, 4)dnl
+])dnl
+
+dnl Not used - kept for compat only?
+AC_DEFUN([KDE_DO_IT_ALL],
+[
+AC_CANONICAL_SYSTEM
+AC_ARG_PROGRAM
+AM_INIT_AUTOMAKE($1, $2)
+AM_DISABLE_LIBRARIES
+AC_PREFIX_DEFAULT(${KDEDIR:-/usr/local/kde})
+AC_CHECK_COMPILERS
+KDE_PROG_LIBTOOL
+AM_KDE_WITH_NLS
+AC_PATH_KDE
+])
+
+AC_DEFUN([AC_CHECK_RPATH],
+[
+AC_MSG_CHECKING(for rpath)
+AC_ARG_ENABLE(rpath,
+ AC_HELP_STRING([--disable-rpath],[do not use the rpath feature of ld]),
+ USE_RPATH=$enableval, USE_RPATH=yes)
+
+if test -z "$KDE_RPATH" && test "$USE_RPATH" = "yes"; then
+
+ KDE_RPATH="-R \$(libdir)"
+
+ if test "$kde_libraries" != "$libdir"; then
+ KDE_RPATH="$KDE_RPATH -R \$(kde_libraries)"
+ fi
+
+ if test -n "$qt_libraries"; then
+ KDE_RPATH="$KDE_RPATH -R \$(qt_libraries)"
+ fi
+ dnl $x_libraries is set to /usr/lib in case
+ if test -n "$X_LDFLAGS"; then
+ X_RPATH="-R \$(x_libraries)"
+ KDE_RPATH="$KDE_RPATH $X_RPATH"
+ fi
+ if test -n "$KDE_EXTRA_RPATH"; then
+ KDE_RPATH="$KDE_RPATH \$(KDE_EXTRA_RPATH)"
+ fi
+fi
+AC_SUBST(KDE_EXTRA_RPATH)
+AC_SUBST(KDE_RPATH)
+AC_SUBST(X_RPATH)
+AC_MSG_RESULT($USE_RPATH)
+])
+
+dnl Check for the type of the third argument of getsockname
+AC_DEFUN([AC_CHECK_SOCKLEN_T],
+[
+ AC_MSG_CHECKING(for socklen_t)
+ AC_CACHE_VAL(kde_cv_socklen_t,
+ [
+ AC_LANG_PUSH(C++)
+ kde_cv_socklen_t=no
+ AC_TRY_COMPILE([
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ ],
+ [
+ socklen_t len;
+ getpeername(0,0,&len);
+ ],
+ [
+ kde_cv_socklen_t=yes
+ kde_cv_socklen_t_equiv=socklen_t
+ ])
+ AC_LANG_POP(C++)
+ ])
+ AC_MSG_RESULT($kde_cv_socklen_t)
+ if test $kde_cv_socklen_t = no; then
+ AC_MSG_CHECKING([for socklen_t equivalent for socket functions])
+ AC_CACHE_VAL(kde_cv_socklen_t_equiv,
+ [
+ kde_cv_socklen_t_equiv=int
+ AC_LANG_PUSH(C++)
+ for t in int size_t unsigned long "unsigned long"; do
+ AC_TRY_COMPILE([
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ ],
+ [
+ $t len;
+ getpeername(0,0,&len);
+ ],
+ [
+ kde_cv_socklen_t_equiv="$t"
+ break
+ ])
+ done
+ AC_LANG_POP(C++)
+ ])
+ AC_MSG_RESULT($kde_cv_socklen_t_equiv)
+ fi
+ AC_DEFINE_UNQUOTED(kde_socklen_t, $kde_cv_socklen_t_equiv,
+ [type to use in place of socklen_t if not defined])
+ AC_DEFINE_UNQUOTED(ksize_t, $kde_cv_socklen_t_equiv,
+ [type to use in place of socklen_t if not defined (deprecated, use kde_socklen_t)])
+])
+
+dnl This is a merge of some macros out of the gettext aclocal.m4
+dnl since we don't need anything, I took the things we need
+dnl the copyright for them is:
+dnl >
+dnl Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+dnl This Makefile.in is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+dnl >
+dnl for this file it is relicensed under LGPL
+
+AC_DEFUN([AM_KDE_WITH_NLS],
+ [
+ dnl If we use NLS figure out what method
+
+ AM_PATH_PROG_WITH_TEST_KDE(MSGFMT, msgfmt,
+ [test -n "`$ac_dir/$ac_word --version 2>&1 | grep 'GNU gettext'`"], msgfmt)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+
+ if test -z "`$GMSGFMT --version 2>&1 | grep 'GNU gettext'`"; then
+ AC_MSG_RESULT([found msgfmt program is not GNU msgfmt; ignore it])
+ GMSGFMT=":"
+ fi
+ MSGFMT=$GMSGFMT
+ AC_SUBST(GMSGFMT)
+ AC_SUBST(MSGFMT)
+
+ AM_PATH_PROG_WITH_TEST_KDE(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext programs is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+ AC_SUBST(XGETTEXT)
+
+ ])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+# serial 1
+# Stephan Kulow: I appended a _KDE against name conflicts
+
+dnl AM_PATH_PROG_WITH_TEST_KDE(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN([AM_PATH_PROG_WITH_TEST_KDE],
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+
+# serial 1
+
+AC_DEFUN([AM_LC_MESSAGES],
+ [if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES, 1, [Define if your locale.h file contains LC_MESSAGES])
+ fi
+ fi])
+
+dnl From Jim Meyering.
+dnl FIXME: migrate into libit.
+
+AC_DEFUN([AM_FUNC_OBSTACK],
+[AC_CACHE_CHECK([for obstacks], am_cv_func_obstack,
+ [AC_TRY_LINK([#include "obstack.h"],
+ [struct obstack *mem;obstack_free(mem,(char *) 0)],
+ am_cv_func_obstack=yes,
+ am_cv_func_obstack=no)])
+ if test $am_cv_func_obstack = yes; then
+ AC_DEFINE(HAVE_OBSTACK)
+ else
+ LIBOBJS="$LIBOBJS obstack.o"
+ fi
+])
+
+dnl From Jim Meyering. Use this if you use the GNU error.[ch].
+dnl FIXME: Migrate into libit
+
+AC_DEFUN([AM_FUNC_ERROR_AT_LINE],
+[AC_CACHE_CHECK([for error_at_line], am_cv_lib_error_at_line,
+ [AC_TRY_LINK([],[error_at_line(0, 0, "", 0, "");],
+ am_cv_lib_error_at_line=yes,
+ am_cv_lib_error_at_line=no)])
+ if test $am_cv_lib_error_at_line = no; then
+ LIBOBJS="$LIBOBJS error.o"
+ fi
+ AC_SUBST(LIBOBJS)dnl
+])
+
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+
+# serial 1
+# Stephan Kulow: I put a KDE in it to avoid name conflicts
+
+AC_DEFUN([AM_KDE_GNU_GETTEXT],
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+ AC_REQUIRE([AM_KDE_WITH_NLS])dnl
+ AC_CHECK_HEADERS([limits.h locale.h nl_types.h string.h values.h alloca.h])
+ AC_CHECK_FUNCS([getcwd munmap putenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next])
+
+ AC_MSG_CHECKING(for stpcpy)
+ AC_CACHE_VAL(kde_cv_func_stpcpy,
+ [
+ kde_safe_cxxflags=$CXXFLAGS
+ CXXFLAGS="-Werror"
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([
+ #include <string.h>
+ ],
+ [
+ char buffer[200];
+ stpcpy(buffer, buffer);
+ ],
+ kde_cv_func_stpcpy=yes,
+ kde_cv_func_stpcpy=no)
+ AC_LANG_RESTORE
+ CXXFLAGS=$kde_safe_cxxflags
+ ])
+ AC_MSG_RESULT($kde_cv_func_stpcpy)
+ if eval "test \"`echo $kde_cv_func_stpcpy`\" = yes"; then
+ AC_DEFINE(HAVE_STPCPY, 1, [Define if you have stpcpy])
+ fi
+
+ AM_LC_MESSAGES
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ ])
+
+AC_DEFUN([AC_HAVE_XPM],
+ [AC_REQUIRE_CPP()dnl
+ AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+
+ test -z "$XPM_LDFLAGS" && XPM_LDFLAGS=
+ test -z "$XPM_INCLUDE" && XPM_INCLUDE=
+
+ AC_ARG_WITH(xpm,AC_HELP_STRING([--without-xpm],[disable color pixmap XPM tests]),
+ xpm_test=$withval, xpm_test="yes")
+ if test "x$xpm_test" = xno; then
+ ac_cv_have_xpm=no
+ else
+ AC_MSG_CHECKING(for XPM)
+ AC_CACHE_VAL(ac_cv_have_xpm,
+ [
+ ac_save_ldflags="$LDFLAGS"
+ ac_save_cflags="$CFLAGS"
+ if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then
+ LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS $LDFLAGS $XPM_LDFLAGS $all_libraries -lXpm -lX11 -lXext $LIBZ $LIBSOCKET"
+ else
+ LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS $LDFLAGS $XPM_LDFLAGS $all_libraries -lXpm $LIBZ $LIBSOCKET"
+ fi
+ CFLAGS="$CFLAGS $X_INCLUDES $USER_INCLUDES"
+ test -n "$XPM_INCLUDE" && CFLAGS="-I$XPM_INCLUDE $CFLAGS"
+ AC_TRY_LINK([#include <X11/xpm.h>],[],
+ ac_cv_have_xpm="yes",ac_cv_have_xpm="no")
+ LDFLAGS="$ac_save_ldflags"
+ CFLAGS="$ac_save_cflags"
+ ])dnl
+
+ if test "$ac_cv_have_xpm" = no; then
+ AC_MSG_RESULT(no)
+ XPM_LDFLAGS=""
+ XPMINC=""
+ $2
+ else
+ AC_DEFINE(HAVE_XPM, 1, [Define if you have XPM support])
+ if test "$XPM_LDFLAGS" = ""; then
+ XPMLIB='-lXpm $(LIB_X11)'
+ else
+ XPMLIB="-L$XPM_LDFLAGS -lXpm "'$(LIB_X11)'
+ fi
+ if test "$XPM_INCLUDE" = ""; then
+ XPMINC=""
+ else
+ XPMINC="-I$XPM_INCLUDE"
+ fi
+ AC_MSG_RESULT(yes)
+ $1
+ fi
+ fi
+ AC_SUBST(XPMINC)
+ AC_SUBST(XPMLIB)
+])
+
+AC_DEFUN([AC_HAVE_DPMS],
+ [AC_REQUIRE_CPP()dnl
+ AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+
+ test -z "$DPMS_LDFLAGS" && DPMS_LDFLAGS=
+ test -z "$DPMS_INCLUDE" && DPMS_INCLUDE=
+ DPMS_LIB=
+
+ AC_ARG_WITH(dpms,AC_HELP_STRING([--without-dpms],[disable DPMS power saving]),
+ dpms_test=$withval, dpms_test="yes")
+ if test "x$dpms_test" = xno; then
+ ac_cv_have_dpms=no
+ else
+ AC_MSG_CHECKING(for DPMS)
+ dnl Note: ac_cv_have_dpms can be no, yes, or -lXdpms.
+ dnl 'yes' means DPMS_LIB="", '-lXdpms' means DPMS_LIB="-lXdpms".
+ AC_CACHE_VAL(ac_cv_have_dpms,
+ [
+ if test "x$kde_use_qt_emb" = "xyes" || test "x$kde_use_qt_mac" = "xyes"; then
+ AC_MSG_RESULT(no)
+ ac_cv_have_dpms="no"
+ else
+ ac_save_ldflags="$LDFLAGS"
+ ac_save_cflags="$CFLAGS"
+ ac_save_libs="$LIBS"
+ LDFLAGS="$LDFLAGS $DPMS_LDFLAGS $all_libraries"
+ LIBS="-lX11 -lXext $LIBSOCKET"
+ CFLAGS="$CFLAGS $X_INCLUDES"
+ test -n "$DPMS_INCLUDE" && CFLAGS="-I$DPMS_INCLUDE $CFLAGS"
+ AC_TRY_LINK([
+ #include <X11/Xproto.h>
+ #include <X11/X.h>
+ #include <X11/Xlib.h>
+ #include <X11/extensions/dpms.h>
+ int foo_test_dpms()
+ { return DPMSSetTimeouts( 0, 0, 0, 0 ); }],[],
+ ac_cv_have_dpms="yes", [
+ LIBS="-lXdpms $LIBS"
+ AC_TRY_LINK([
+ #include <X11/Xproto.h>
+ #include <X11/X.h>
+ #include <X11/Xlib.h>
+ #include <X11/extensions/dpms.h>
+ int foo_test_dpms()
+ { return DPMSSetTimeouts( 0, 0, 0, 0 ); }],[],
+ [
+ ac_cv_have_dpms="-lXdpms"
+ ],ac_cv_have_dpms="no")
+ ])
+ LDFLAGS="$ac_save_ldflags"
+ CFLAGS="$ac_save_cflags"
+ LIBS="$ac_save_libs"
+ fi
+ ])dnl
+
+ if test "$ac_cv_have_dpms" = no; then
+ AC_MSG_RESULT(no)
+ DPMS_LDFLAGS=""
+ DPMSINC=""
+ $2
+ else
+ AC_DEFINE(HAVE_DPMS, 1, [Define if you have DPMS support])
+ if test "$ac_cv_have_dpms" = "-lXdpms"; then
+ DPMS_LIB="-lXdpms"
+ fi
+ if test "$DPMS_LDFLAGS" = ""; then
+ DPMSLIB="$DPMS_LIB "'$(LIB_X11)'
+ else
+ DPMSLIB="$DPMS_LDFLAGS $DPMS_LIB "'$(LIB_X11)'
+ fi
+ if test "$DPMS_INCLUDE" = ""; then
+ DPMSINC=""
+ else
+ DPMSINC="-I$DPMS_INCLUDE"
+ fi
+ AC_MSG_RESULT(yes)
+ $1
+ fi
+ fi
+ ac_save_cflags="$CFLAGS"
+ CFLAGS="$CFLAGS $X_INCLUDES"
+ test -n "$DPMS_INCLUDE" && CFLAGS="-I$DPMS_INCLUDE $CFLAGS"
+ AH_TEMPLATE(HAVE_DPMSCAPABLE_PROTO,
+ [Define if you have the DPMSCapable prototype in <X11/extensions/dpms.h>])
+ AC_CHECK_DECL(DPMSCapable,
+ AC_DEFINE(HAVE_DPMSCAPABLE_PROTO),,
+ [#include <X11/Xlib.h>
+ #include <X11/extensions/dpms.h>])
+ AH_TEMPLATE(HAVE_DPMSINFO_PROTO,
+ [Define if you have the DPMSInfo prototype in <X11/extensions/dpms.h>])
+ AC_CHECK_DECL(DPMSInfo,
+ AC_DEFINE(HAVE_DPMSINFO_PROTO),,
+ [#include <X11/Xlib.h>
+ #include <X11/extensions/dpms.h>])
+ CFLAGS="$ac_save_cflags"
+ AC_SUBST(DPMSINC)
+ AC_SUBST(DPMSLIB)
+])
+
+AC_DEFUN([AC_HAVE_GL],
+ [AC_REQUIRE_CPP()dnl
+ AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+
+ test -z "$GL_LDFLAGS" && GL_LDFLAGS=
+ test -z "$GL_INCLUDE" && GL_INCLUDE=
+
+ AC_ARG_WITH(gl,AC_HELP_STRING([--without-gl],[disable 3D GL modes]),
+ gl_test=$withval, gl_test="yes")
+ if test "x$kde_use_qt_emb" = "xyes"; then
+ # GL and Qt Embedded is a no-go for now.
+ ac_cv_have_gl=no
+ elif test "x$gl_test" = xno; then
+ ac_cv_have_gl=no
+ else
+ AC_MSG_CHECKING(for GL)
+ AC_CACHE_VAL(ac_cv_have_gl,
+ [
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ ac_save_ldflags=$LDFLAGS
+ ac_save_cxxflags=$CXXFLAGS
+ ac_save_libs=$LIBS
+ LDFLAGS="$LDFLAGS $GL_LDFLAGS $X_LDFLAGS $all_libraries"
+ LIBS="$LIBS -lGL -lGLU"
+ test "x$kde_use_qt_mac" != xyes && test "x$kde_use_qt_emb" != xyes && LIBS="$LIBS -lX11"
+ LIBS="$LIBS $LIB_XEXT -lm $LIBSOCKET"
+ CXXFLAGS="$CFLAGS $X_INCLUDES"
+ test -n "$GL_INCLUDE" && CFLAGS="-I$GL_INCLUDE $CFLAGS"
+ AC_TRY_LINK([#include <GL/gl.h>
+#include <GL/glu.h>
+], [],
+ ac_cv_have_gl="yes", ac_cv_have_gl="no")
+ AC_LANG_RESTORE
+ LDFLAGS=$ac_save_ldflags
+ CXXFLAGS=$ac_save_cxxflags
+ LIBS=$ac_save_libs
+ ])dnl
+
+ if test "$ac_cv_have_gl" = "no"; then
+ AC_MSG_RESULT(no)
+ GL_LDFLAGS=""
+ GLINC=""
+ $2
+ else
+ AC_DEFINE(HAVE_GL, 1, [Defines if you have GL (Mesa, OpenGL, ...)])
+ if test "$GL_LDFLAGS" = ""; then
+ GLLIB='-lGLU -lGL $(LIB_X11)'
+ else
+ GLLIB="$GL_LDFLAGS -lGLU -lGL "'$(LIB_X11)'
+ fi
+ if test "$GL_INCLUDE" = ""; then
+ GLINC=""
+ else
+ GLINC="-I$GL_INCLUDE"
+ fi
+ AC_MSG_RESULT($ac_cv_have_gl)
+ $1
+ fi
+ fi
+ AC_SUBST(GLINC)
+ AC_SUBST(GLLIB)
+])
+
+
+ dnl shadow password and PAM magic - maintained by ossi@kde.org
+
+AC_DEFUN([KDE_PAM], [
+ AC_REQUIRE([KDE_CHECK_LIBDL])
+
+ want_pam=
+ AC_ARG_WITH(pam,
+ AC_HELP_STRING([--with-pam[=ARG]],[enable support for PAM: ARG=[yes|no|service name]]),
+ [ if test "x$withval" = "xyes"; then
+ want_pam=yes
+ pam_service=kde
+ elif test "x$withval" = "xno"; then
+ want_pam=no
+ else
+ want_pam=yes
+ pam_service=$withval
+ fi
+ ], [ pam_service=kde ])
+
+ use_pam=
+ PAMLIBS=
+ if test "x$want_pam" != xno; then
+ AC_CHECK_LIB(pam, pam_start, [
+ AC_CHECK_HEADER(security/pam_appl.h,
+ [ pam_header=security/pam_appl.h ],
+ [ AC_CHECK_HEADER(pam/pam_appl.h,
+ [ pam_header=pam/pam_appl.h ],
+ [
+ AC_MSG_WARN([PAM detected, but no headers found!
+Make sure you have the necessary development packages installed.])
+ ]
+ )
+ ]
+ )
+ ], , $LIBDL)
+ if test -z "$pam_header"; then
+ if test "x$want_pam" = xyes; then
+ AC_MSG_ERROR([--with-pam was specified, but cannot compile with PAM!])
+ fi
+ else
+ AC_DEFINE(HAVE_PAM, 1, [Defines if you have PAM (Pluggable Authentication Modules)])
+ PAMLIBS="$PAM_MISC_LIB -lpam $LIBDL"
+ use_pam=yes
+
+ dnl darwin claims to be something special
+ if test "$pam_header" = "pam/pam_appl.h"; then
+ AC_DEFINE(HAVE_PAM_PAM_APPL_H, 1, [Define if your PAM headers are in pam/ instead of security/])
+ fi
+
+ dnl test whether struct pam_message is const (Linux) or not (Sun)
+ AC_MSG_CHECKING(for const pam_message)
+ AC_EGREP_HEADER([struct pam_message], $pam_header,
+ [ AC_EGREP_HEADER([const struct pam_message], $pam_header,
+ [AC_MSG_RESULT([const: Linux-type PAM])],
+ [AC_MSG_RESULT([nonconst: Sun-type PAM])
+ AC_DEFINE(PAM_MESSAGE_NONCONST, 1, [Define if your PAM support takes non-const arguments (Solaris)])]
+ )],
+ [AC_MSG_RESULT([not found - assume const, Linux-type PAM])])
+ fi
+ fi
+
+ AC_SUBST(PAMLIBS)
+])
+
+dnl DEF_PAM_SERVICE(arg name, full name, define name)
+AC_DEFUN([DEF_PAM_SERVICE], [
+ AC_ARG_WITH($1-pam,
+ AC_HELP_STRING([--with-$1-pam=[val]],[override PAM service from --with-pam for $2]),
+ [ if test "x$use_pam" = xyes; then
+ $3_PAM_SERVICE=$withval
+ else
+ AC_MSG_ERROR([Cannot use use --with-$1-pam, as no PAM was detected.
+You may want to enforce it by using --with-pam.])
+ fi
+ ],
+ [ if test "x$use_pam" = xyes; then
+ $3_PAM_SERVICE="$pam_service"
+ fi
+ ])
+ if test -n "$$3_PAM_SERVICE"; then
+ AC_MSG_RESULT([The PAM service used by $2 will be $$3_PAM_SERVICE])
+ AC_DEFINE_UNQUOTED($3_PAM_SERVICE, "$$3_PAM_SERVICE", [The PAM service to be used by $2])
+ fi
+ AC_SUBST($3_PAM_SERVICE)
+])
+
+AC_DEFUN([KDE_SHADOWPASSWD], [
+ AC_REQUIRE([KDE_PAM])
+
+ AC_CHECK_LIB(shadow, getspent,
+ [ LIBSHADOW="-lshadow"
+ ac_use_shadow=yes
+ ],
+ [ dnl for UnixWare
+ AC_CHECK_LIB(gen, getspent,
+ [ LIBGEN="-lgen"
+ ac_use_shadow=yes
+ ],
+ [ AC_CHECK_FUNC(getspent,
+ [ ac_use_shadow=yes ],
+ [ ac_use_shadow=no ])
+ ])
+ ])
+ AC_SUBST(LIBSHADOW)
+ AC_SUBST(LIBGEN)
+
+ AC_MSG_CHECKING([for shadow passwords])
+
+ AC_ARG_WITH(shadow,
+ AC_HELP_STRING([--with-shadow],[If you want shadow password support]),
+ [ if test "x$withval" != "xno"; then
+ use_shadow=yes
+ else
+ use_shadow=no
+ fi
+ ], [
+ use_shadow="$ac_use_shadow"
+ ])
+
+ if test "x$use_shadow" = xyes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SHADOW, 1, [Define if you use shadow passwords])
+ else
+ AC_MSG_RESULT(no)
+ LIBSHADOW=
+ LIBGEN=
+ fi
+
+ dnl finally make the relevant binaries setuid root, if we have shadow passwds.
+ dnl this still applies, if we could use it indirectly through pam.
+ if test "x$use_shadow" = xyes ||
+ ( test "x$use_pam" = xyes && test "x$ac_use_shadow" = xyes ); then
+ case $host in
+ *-*-freebsd* | *-*-netbsd* | *-*-openbsd*)
+ SETUIDFLAGS="-m 4755 -o root";;
+ *)
+ SETUIDFLAGS="-m 4755";;
+ esac
+ fi
+ AC_SUBST(SETUIDFLAGS)
+
+])
+
+AC_DEFUN([KDE_PASSWDLIBS], [
+ AC_REQUIRE([KDE_MISC_TESTS]) dnl for LIBCRYPT
+ AC_REQUIRE([KDE_PAM])
+ AC_REQUIRE([KDE_SHADOWPASSWD])
+
+ if test "x$use_pam" = "xyes"; then
+ PASSWDLIBS="$PAMLIBS"
+ else
+ PASSWDLIBS="$LIBCRYPT $LIBSHADOW $LIBGEN"
+ fi
+
+ dnl FreeBSD uses a shadow-like setup, where /etc/passwd holds the users, but
+ dnl /etc/master.passwd holds the actual passwords. /etc/master.passwd requires
+ dnl root to read, so kcheckpass needs to be root (even when using pam, since pam
+ dnl may need to read /etc/master.passwd).
+ case $host in
+ *-*-freebsd*)
+ SETUIDFLAGS="-m 4755 -o root"
+ ;;
+ *)
+ ;;
+ esac
+
+ AC_SUBST(PASSWDLIBS)
+])
+
+AC_DEFUN([KDE_CHECK_LIBDL],
+[
+AC_CHECK_LIB(dl, dlopen, [
+LIBDL="-ldl"
+ac_cv_have_dlfcn=yes
+])
+
+AC_CHECK_LIB(dld, shl_unload, [
+LIBDL="-ldld"
+ac_cv_have_shload=yes
+])
+
+AC_SUBST(LIBDL)
+])
+
+AC_DEFUN([KDE_CHECK_DLOPEN],
+[
+KDE_CHECK_LIBDL
+AC_CHECK_HEADERS(dlfcn.h dl.h)
+if test "$ac_cv_header_dlfcn_h" = "no"; then
+ ac_cv_have_dlfcn=no
+fi
+
+if test "$ac_cv_header_dl_h" = "no"; then
+ ac_cv_have_shload=no
+fi
+
+dnl XXX why change enable_dlopen? its already set by autoconf's AC_ARG_ENABLE
+dnl (MM)
+AC_ARG_ENABLE(dlopen,
+AC_HELP_STRING([--disable-dlopen],[link statically [default=no]]),
+enable_dlopen=$enableval,
+enable_dlopen=yes)
+
+# override the user's opinion, if we know it better ;)
+if test "$ac_cv_have_dlfcn" = "no" && test "$ac_cv_have_shload" = "no"; then
+ enable_dlopen=no
+fi
+
+if test "$ac_cv_have_dlfcn" = "yes"; then
+ AC_DEFINE_UNQUOTED(HAVE_DLFCN, 1, [Define if you have dlfcn])
+fi
+
+if test "$ac_cv_have_shload" = "yes"; then
+ AC_DEFINE_UNQUOTED(HAVE_SHLOAD, 1, [Define if you have shload])
+fi
+
+if test "$enable_dlopen" = no ; then
+ test -n "$1" && eval $1
+else
+ test -n "$2" && eval $2
+fi
+
+])
+
+AC_DEFUN([KDE_CHECK_DYNAMIC_LOADING],
+[
+KDE_CHECK_DLOPEN(libtool_enable_shared=yes, libtool_enable_static=no)
+KDE_PROG_LIBTOOL
+AC_MSG_CHECKING([dynamic loading])
+eval "`egrep '^build_libtool_libs=' libtool`"
+if test "$build_libtool_libs" = "yes" && test "$enable_dlopen" = "yes"; then
+ dynamic_loading=yes
+ AC_DEFINE_UNQUOTED(HAVE_DYNAMIC_LOADING)
+else
+ dynamic_loading=no
+fi
+AC_MSG_RESULT($dynamic_loading)
+if test "$dynamic_loading" = "yes"; then
+ $1
+else
+ $2
+fi
+])
+
+AC_DEFUN([KDE_ADD_INCLUDES],
+[
+if test -z "$1"; then
+ test_include="Pix.h"
+else
+ test_include="$1"
+fi
+
+AC_MSG_CHECKING([for libg++ ($test_include)])
+
+AC_CACHE_VAL(kde_cv_libgpp_includes,
+[
+kde_cv_libgpp_includes=no
+
+ for ac_dir in \
+ \
+ /usr/include/g++ \
+ /usr/include \
+ /usr/unsupported/include \
+ /opt/include \
+ $extra_include \
+ ; \
+ do
+ if test -r "$ac_dir/$test_include"; then
+ kde_cv_libgpp_includes=$ac_dir
+ break
+ fi
+ done
+])
+
+AC_MSG_RESULT($kde_cv_libgpp_includes)
+if test "$kde_cv_libgpp_includes" != "no"; then
+ all_includes="-I$kde_cv_libgpp_includes $all_includes $USER_INCLUDES"
+fi
+])
+])
+
+AC_DEFUN([KDE_CHECK_LIBPTHREAD],
+[
+ dnl This code is here specifically to handle the
+ dnl various flavors of threading library on FreeBSD
+ dnl 4-, 5-, and 6-, and the (weird) rules around it.
+ dnl There may be an environment PTHREAD_LIBS that
+ dnl specifies what to use; otherwise, search for it.
+ dnl -pthread is special cased and unsets LIBPTHREAD
+ dnl below if found.
+ LIBPTHREAD=""
+
+ if test -n "$PTHREAD_LIBS"; then
+ if test "x$PTHREAD_LIBS" = "x-pthread" ; then
+ LIBPTHREAD="PTHREAD"
+ else
+ PTHREAD_LIBS_save="$PTHREAD_LIBS"
+ PTHREAD_LIBS=`echo "$PTHREAD_LIBS_save" | sed -e 's,^-l,,g'`
+ AC_MSG_CHECKING([for pthread_create in $PTHREAD_LIBS])
+ KDE_CHECK_LIB($PTHREAD_LIBS, pthread_create, [
+ LIBPTHREAD="$PTHREAD_LIBS_save"])
+ PTHREAD_LIBS="$PTHREAD_LIBS_save"
+ fi
+ fi
+
+ dnl Is this test really needed, in the face of the Tru64 test below?
+ if test -z "$LIBPTHREAD"; then
+ AC_CHECK_LIB(pthread, pthread_create, [LIBPTHREAD="-lpthread"])
+ fi
+
+ dnl This is a special Tru64 check, see BR 76171 issue #18.
+ if test -z "$LIBPTHREAD" ; then
+ AC_MSG_CHECKING([for pthread_create in -lpthread])
+ kde_safe_libs=$LIBS
+ LIBS="$LIBS -lpthread"
+ AC_TRY_LINK([#include <pthread.h>],[(void)pthread_create(0,0,0,0);],[
+ AC_MSG_RESULT(yes)
+ LIBPTHREAD="-lpthread"],[
+ AC_MSG_RESULT(no)])
+ LIBS=$kde_safe_libs
+ fi
+
+ dnl Un-special-case for FreeBSD.
+ if test "x$LIBPTHREAD" = "xPTHREAD" ; then
+ LIBPTHREAD=""
+ fi
+
+ AC_SUBST(LIBPTHREAD)
+])
+
+AC_DEFUN([KDE_CHECK_PTHREAD_OPTION],
+[
+ USE_THREADS=""
+ if test -z "$LIBPTHREAD"; then
+ KDE_CHECK_COMPILER_FLAG(pthread, [USE_THREADS="-D_THREAD_SAFE -pthread"])
+ fi
+
+ AH_VERBATIM(__svr_define, [
+#if defined(__SVR4) && !defined(__svr4__)
+#define __svr4__ 1
+#endif
+])
+ case $host_os in
+ solaris*)
+ KDE_CHECK_COMPILER_FLAG(mt, [USE_THREADS="-mt"])
+ CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -DUSE_SOLARIS -DSVR4"
+ ;;
+ freebsd*)
+ CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE $PTHREAD_CFLAGS"
+ ;;
+ aix*)
+ CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE"
+ LIBPTHREAD="$LIBPTHREAD -lc_r"
+ ;;
+ linux*) CPPFLAGS="$CPPFLAGS -D_REENTRANT"
+ if test "$CXX" = "KCC"; then
+ CXXFLAGS="$CXXFLAGS --thread_safe"
+ NOOPT_CXXFLAGS="$NOOPT_CXXFLAGS --thread_safe"
+ fi
+ ;;
+ *)
+ ;;
+ esac
+ AC_SUBST(USE_THREADS)
+ AC_SUBST(LIBPTHREAD)
+])
+
+AC_DEFUN([KDE_CHECK_THREADING],
+[
+ AC_REQUIRE([KDE_CHECK_LIBPTHREAD])
+ AC_REQUIRE([KDE_CHECK_PTHREAD_OPTION])
+ dnl default is yes if libpthread is found and no if no libpthread is available
+ if test -z "$LIBPTHREAD"; then
+ if test -z "$USE_THREADS"; then
+ kde_check_threading_default=no
+ else
+ kde_check_threading_default=yes
+ fi
+ else
+ kde_check_threading_default=yes
+ fi
+ AC_ARG_ENABLE(threading,AC_HELP_STRING([--disable-threading],[disables threading even if libpthread found]),
+ kde_use_threading=$enableval, kde_use_threading=$kde_check_threading_default)
+ if test "x$kde_use_threading" = "xyes"; then
+ AC_DEFINE(HAVE_LIBPTHREAD, 1, [Define if you have a working libpthread (will enable threaded code)])
+ fi
+])
+
+AC_DEFUN([KDE_TRY_LINK_PYTHON],
+[
+if test "$kde_python_link_found" = no; then
+
+if test "$1" = normal; then
+ AC_MSG_CHECKING(if a Python application links)
+else
+ AC_MSG_CHECKING(if Python depends on $2)
+fi
+
+AC_CACHE_VAL(kde_cv_try_link_python_$1,
+[
+kde_save_cflags="$CFLAGS"
+CFLAGS="$CFLAGS $PYTHONINC"
+kde_save_libs="$LIBS"
+LIBS="$LIBS $LIBPYTHON $2 $LIBDL $LIBSOCKET"
+kde_save_ldflags="$LDFLAGS"
+LDFLAGS="$LDFLAGS $PYTHONLIB"
+
+AC_TRY_LINK(
+[
+#include <Python.h>
+],[
+ PySys_SetArgv(1, 0);
+],
+ [kde_cv_try_link_python_$1=yes],
+ [kde_cv_try_link_python_$1=no]
+)
+CFLAGS="$kde_save_cflags"
+LIBS="$kde_save_libs"
+LDFLAGS="$kde_save_ldflags"
+])
+
+if test "$kde_cv_try_link_python_$1" = "yes"; then
+ AC_MSG_RESULT(yes)
+ kde_python_link_found=yes
+ if test ! "$1" = normal; then
+ LIBPYTHON="$LIBPYTHON $2"
+ fi
+ $3
+else
+ AC_MSG_RESULT(no)
+ $4
+fi
+
+fi
+
+])
+
+AC_DEFUN([KDE_CHECK_PYTHON_DIR],
+[
+AC_MSG_CHECKING([for Python directory])
+
+AC_CACHE_VAL(kde_cv_pythondir,
+[
+ if test -z "$PYTHONDIR"; then
+ kde_cv_pythondir=/usr/local
+ else
+ kde_cv_pythondir="$PYTHONDIR"
+ fi
+])
+
+AC_ARG_WITH(pythondir,
+AC_HELP_STRING([--with-pythondir=pythondir],[use python installed in pythondir]),
+[
+ ac_python_dir=$withval
+], ac_python_dir=$kde_cv_pythondir
+)
+
+AC_MSG_RESULT($ac_python_dir)
+])
+
+AC_DEFUN([KDE_CHECK_PYTHON_INTERN],
+[
+AC_REQUIRE([KDE_CHECK_LIBDL])
+AC_REQUIRE([KDE_CHECK_LIBPTHREAD])
+AC_REQUIRE([KDE_CHECK_PYTHON_DIR])
+
+if test -z "$1"; then
+ version="1.5"
+else
+ version="$1"
+fi
+
+AC_MSG_CHECKING([for Python$version])
+
+python_incdirs="$ac_python_dir/include /usr/include /usr/local/include/ $kde_extra_includes"
+AC_FIND_FILE(Python.h, $python_incdirs, python_incdir)
+if test ! -r $python_incdir/Python.h; then
+ AC_FIND_FILE(python$version/Python.h, $python_incdirs, python_incdir)
+ python_incdir=$python_incdir/python$version
+ if test ! -r $python_incdir/Python.h; then
+ python_incdir=no
+ fi
+fi
+
+PYTHONINC=-I$python_incdir
+
+python_libdirs="$ac_python_dir/lib$kdelibsuff /usr/lib$kdelibsuff /usr/local /usr/lib$kdelibsuff $kde_extra_libs"
+AC_FIND_FILE(libpython$version.so, $python_libdirs, python_libdir)
+if test ! -r $python_libdir/libpython$version.so; then
+ AC_FIND_FILE(libpython$version.a, $python_libdirs, python_libdir)
+ if test ! -r $python_libdir/libpython$version.a; then
+ AC_FIND_FILE(python$version/config/libpython$version.a, $python_libdirs, python_libdir)
+ python_libdir=$python_libdir/python$version/config
+ if test ! -r $python_libdir/libpython$version.a; then
+ python_libdir=no
+ fi
+ fi
+fi
+
+PYTHONLIB=-L$python_libdir
+kde_orig_LIBPYTHON=$LIBPYTHON
+if test -z "$LIBPYTHON"; then
+ LIBPYTHON=-lpython$version
+fi
+
+AC_FIND_FILE(python$version/copy.py, $python_libdirs, python_moddir)
+python_moddir=$python_moddir/python$version
+if test ! -r $python_moddir/copy.py; then
+ python_moddir=no
+fi
+
+PYTHONMODDIR=$python_moddir
+
+AC_MSG_RESULT(header $python_incdir library $python_libdir modules $python_moddir)
+
+if test x$python_incdir = xno || test x$python_libdir = xno || test x$python_moddir = xno; then
+ LIBPYTHON=$kde_orig_LIBPYTHON
+ test "x$PYTHONLIB" = "x-Lno" && PYTHONLIB=""
+ test "x$PYTHONINC" = "x-Ino" && PYTHONINC=""
+ $2
+else
+ dnl Note: this test is very weak
+ kde_python_link_found=no
+ KDE_TRY_LINK_PYTHON(normal)
+ KDE_TRY_LINK_PYTHON(m, -lm)
+ KDE_TRY_LINK_PYTHON(pthread, $LIBPTHREAD)
+ KDE_TRY_LINK_PYTHON(tcl, -ltcl)
+ KDE_TRY_LINK_PYTHON(db2, -ldb2)
+ KDE_TRY_LINK_PYTHON(m_and_thread, [$LIBPTHREAD -lm])
+ KDE_TRY_LINK_PYTHON(m_and_thread_and_util, [$LIBPTHREAD -lm -lutil])
+ KDE_TRY_LINK_PYTHON(m_and_thread_and_db3, [$LIBPTHREAD -lm -ldb-3 -lutil])
+ KDE_TRY_LINK_PYTHON(pthread_and_db3, [$LIBPTHREAD -ldb-3])
+ KDE_TRY_LINK_PYTHON(m_and_thread_and_db, [$LIBPTHREAD -lm -ldb -ltermcap -lutil])
+ KDE_TRY_LINK_PYTHON(pthread_and_dl, [$LIBPTHREAD $LIBDL -lutil -lreadline -lncurses -lm])
+ KDE_TRY_LINK_PYTHON(pthread_and_panel_curses, [$LIBPTHREAD $LIBDL -lm -lpanel -lcurses])
+ KDE_TRY_LINK_PYTHON(m_and_thread_and_db_special, [$LIBPTHREAD -lm -ldb -lutil], [],
+ [AC_MSG_WARN([it seems, Python depends on another library.
+ Please set LIBPYTHON to '-lpython$version -lotherlib' before calling configure to fix this
+ and contact the authors to let them know about this problem])
+ ])
+
+ LIBPYTHON="$LIBPYTHON $LIBDL $LIBSOCKET"
+ AC_SUBST(PYTHONINC)
+ AC_SUBST(PYTHONLIB)
+ AC_SUBST(LIBPYTHON)
+ AC_SUBST(PYTHONMODDIR)
+ AC_DEFINE(HAVE_PYTHON, 1, [Define if you have the development files for python])
+fi
+
+])
+
+
+AC_DEFUN([KDE_CHECK_PYTHON],
+[
+ KDE_CHECK_PYTHON_INTERN("2.4",
+ [KDE_CHECK_PYTHON_INTERN("2.3",
+ [KDE_CHECK_PYTHON_INTERN("2.2",
+ [KDE_CHECK_PYTHON_INTERN("2.1",
+ [KDE_CHECK_PYTHON_INTERN("2.0",
+ [KDE_CHECK_PYTHON_INTERN($1, $2) ])
+ ])
+ ])
+ ])
+ ])
+])
+
+AC_DEFUN([KDE_CHECK_STL],
+[
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="`echo $CXXFLAGS | sed s/-fno-exceptions//`"
+
+ AC_MSG_CHECKING([if C++ programs can be compiled])
+ AC_CACHE_VAL(kde_cv_stl_works,
+ [
+ AC_TRY_COMPILE([
+#include <string>
+using namespace std;
+],[
+ string astring="Hallo Welt.";
+ astring.erase(0, 6); // now astring is "Welt"
+ return 0;
+], kde_cv_stl_works=yes,
+ kde_cv_stl_works=no)
+])
+
+ AC_MSG_RESULT($kde_cv_stl_works)
+
+ if test "$kde_cv_stl_works" = "yes"; then
+ # back compatible
+ AC_DEFINE_UNQUOTED(HAVE_SGI_STL, 1, [Define if you have a STL implementation by SGI])
+ else
+ AC_MSG_ERROR([Your Installation isn't able to compile simple C++ programs.
+Check config.log for details - if you're using a Linux distribution you might miss
+a package named similar to libstdc++-dev.])
+ fi
+
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ AC_LANG_RESTORE
+])
+
+AC_DEFUN([AC_FIND_QIMGIO],
+ [AC_REQUIRE([AC_FIND_JPEG])
+AC_REQUIRE([KDE_CHECK_EXTRA_LIBS])
+AC_MSG_CHECKING([for qimgio])
+AC_CACHE_VAL(ac_cv_lib_qimgio,
+[
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+ac_save_LIBS="$LIBS"
+ac_save_CXXFLAGS="$CXXFLAGS"
+LIBS="$all_libraries -lqimgio -lpng -lz $LIBJPEG $LIBQT"
+CXXFLAGS="$CXXFLAGS -I$qt_incdir $all_includes"
+AC_TRY_RUN(dnl
+[
+#include <qimageio.h>
+#include <qstring.h>
+int main() {
+ QString t = "hallo";
+ t.fill('t');
+ qInitImageIO();
+}
+],
+ ac_cv_lib_qimgio=yes,
+ ac_cv_lib_qimgio=no,
+ ac_cv_lib_qimgio=no)
+LIBS="$ac_save_LIBS"
+CXXFLAGS="$ac_save_CXXFLAGS"
+AC_LANG_RESTORE
+])dnl
+if eval "test \"`echo $ac_cv_lib_qimgio`\" = yes"; then
+ LIBQIMGIO="-lqimgio -lpng -lz $LIBJPEG"
+ AC_MSG_RESULT(yes)
+ AC_DEFINE_UNQUOTED(HAVE_QIMGIO, 1, [Define if you have the Qt extension qimgio available])
+ AC_SUBST(LIBQIMGIO)
+else
+ AC_MSG_RESULT(not found)
+fi
+])
+
+AC_DEFUN([AM_DISABLE_LIBRARIES],
+[
+ AC_PROVIDE([AM_ENABLE_STATIC])
+ AC_PROVIDE([AM_ENABLE_SHARED])
+ enable_static=no
+ enable_shared=yes
+])
+
+
+AC_DEFUN([AC_CHECK_UTMP_FILE],
+[
+ AC_MSG_CHECKING([for utmp file])
+
+ AC_CACHE_VAL(kde_cv_utmp_file,
+ [
+ kde_cv_utmp_file=no
+
+ for ac_file in \
+ \
+ /var/run/utmp \
+ /var/adm/utmp \
+ /etc/utmp \
+ ; \
+ do
+ if test -r "$ac_file"; then
+ kde_cv_utmp_file=$ac_file
+ break
+ fi
+ done
+ ])
+
+ if test "$kde_cv_utmp_file" != "no"; then
+ AC_DEFINE_UNQUOTED(UTMP, "$kde_cv_utmp_file", [Define the file for utmp entries])
+ $1
+ AC_MSG_RESULT($kde_cv_utmp_file)
+ else
+ $2
+ AC_MSG_RESULT([non found])
+ fi
+])
+
+
+AC_DEFUN([KDE_CREATE_SUBDIRSLIST],
+[
+
+DO_NOT_COMPILE="$DO_NOT_COMPILE CVS debian bsd-port admin"
+TOPSUBDIRS=""
+
+if test ! -s $srcdir/subdirs; then
+ dnl Note: Makefile.common creates subdirs, so this is just a fallback
+ files=`cd $srcdir && ls -1`
+ dirs=`for i in $files; do if test -d $i; then echo $i; fi; done`
+ for i in $dirs; do
+ echo $i >> $srcdir/subdirs
+ done
+fi
+
+ac_topsubdirs=
+if test -s $srcdir/inst-apps; then
+ ac_topsubdirs="`cat $srcdir/inst-apps`"
+elif test -s $srcdir/subdirs; then
+ ac_topsubdirs="`cat $srcdir/subdirs`"
+fi
+
+for i in $ac_topsubdirs; do
+ AC_MSG_CHECKING([if $i should be compiled])
+ if test -d $srcdir/$i; then
+ install_it="yes"
+ for j in $DO_NOT_COMPILE; do
+ if test $i = $j; then
+ install_it="no"
+ fi
+ done
+ else
+ install_it="no"
+ fi
+ AC_MSG_RESULT($install_it)
+ vari=`echo $i | sed -e 's,[[-+.@]],_,g'`
+ if test $install_it = "yes"; then
+ TOPSUBDIRS="$TOPSUBDIRS $i"
+ eval "$vari""_SUBDIR_included=yes"
+ else
+ eval "$vari""_SUBDIR_included=no"
+ fi
+done
+
+AC_SUBST(TOPSUBDIRS)
+])
+
+AC_DEFUN([KDE_CHECK_NAMESPACES],
+[
+AC_MSG_CHECKING(whether C++ compiler supports namespaces)
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+AC_TRY_COMPILE([
+],
+[
+namespace Foo {
+ extern int i;
+ namespace Bar {
+ extern int i;
+ }
+}
+
+int Foo::i = 0;
+int Foo::Bar::i = 1;
+],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_NAMESPACES)
+], [
+AC_MSG_RESULT(no)
+])
+AC_LANG_RESTORE
+])
+
+dnl ------------------------------------------------------------------------
+dnl Check for S_ISSOCK macro. Doesn't exist on Unix SCO. faure@kde.org
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_CHECK_S_ISSOCK],
+[
+AC_MSG_CHECKING(for S_ISSOCK)
+AC_CACHE_VAL(ac_cv_have_s_issock,
+[
+AC_TRY_LINK(
+[
+#include <sys/stat.h>
+],
+[
+struct stat buff;
+int b = S_ISSOCK( buff.st_mode );
+],
+ac_cv_have_s_issock=yes,
+ac_cv_have_s_issock=no)
+])
+AC_MSG_RESULT($ac_cv_have_s_issock)
+if test "$ac_cv_have_s_issock" = "yes"; then
+ AC_DEFINE_UNQUOTED(HAVE_S_ISSOCK, 1, [Define if sys/stat.h declares S_ISSOCK.])
+fi
+
+AH_VERBATIM(_ISSOCK,
+[
+#ifndef HAVE_S_ISSOCK
+#define HAVE_S_ISSOCK
+#define S_ISSOCK(mode) (1==0)
+#endif
+])
+
+])
+
+dnl ------------------------------------------------------------------------
+dnl Check for MAXPATHLEN macro, defines KDEMAXPATHLEN. faure@kde.org
+dnl ------------------------------------------------------------------------
+dnl
+AC_DEFUN([AC_CHECK_KDEMAXPATHLEN],
+[
+AC_MSG_CHECKING(for MAXPATHLEN)
+AC_CACHE_VAL(ac_cv_maxpathlen,
+[
+cat > conftest.$ac_ext <<EOF
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+#endif
+#include <stdio.h>
+#include <sys/param.h>
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+
+KDE_HELLO MAXPATHLEN
+
+EOF
+
+ac_try="$ac_cpp conftest.$ac_ext 2>/dev/null | grep '^KDE_HELLO' >conftest.out"
+
+if AC_TRY_EVAL(ac_try) && test -s conftest.out; then
+ ac_cv_maxpathlen=`sed 's#KDE_HELLO ##' conftest.out`
+else
+ ac_cv_maxpathlen=1024
+fi
+
+rm conftest.*
+
+])
+AC_MSG_RESULT($ac_cv_maxpathlen)
+AC_DEFINE_UNQUOTED(KDEMAXPATHLEN,$ac_cv_maxpathlen, [Define a safe value for MAXPATHLEN] )
+])
+
+AC_DEFUN([KDE_CHECK_HEADER],
+[
+ kde_safe_cppflags=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $all_includes"
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_CHECK_HEADER([$1], [$2], [$3], [$4])
+ AC_LANG_RESTORE
+ CPPFLAGS=$kde_safe_cppflags
+])
+
+AC_DEFUN([KDE_CHECK_HEADERS],
+[
+ AH_CHECK_HEADERS([$1])
+ AC_LANG_SAVE
+ kde_safe_cppflags=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $all_includes"
+ AC_LANG_CPLUSPLUS
+ AC_CHECK_HEADERS([$1], [$2], [$3], [$4])
+ CPPFLAGS=$kde_safe_cppflags
+ AC_LANG_RESTORE
+])
+
+AC_DEFUN([KDE_FAST_CONFIGURE],
+[
+ dnl makes configure fast (needs perl)
+ AC_ARG_ENABLE(fast-perl, AC_HELP_STRING([--disable-fast-perl],[disable fast Makefile generation (needs perl)]),
+ with_fast_perl=$enableval, with_fast_perl=yes)
+])
+
+AC_DEFUN([KDE_CONF_FILES],
+[
+ val=
+ if test -f $srcdir/configure.files ; then
+ val=`sed -e 's%^%\$(top_srcdir)/%' $srcdir/configure.files`
+ fi
+ CONF_FILES=
+ if test -n "$val" ; then
+ for i in $val ; do
+ CONF_FILES="$CONF_FILES $i"
+ done
+ fi
+ AC_SUBST(CONF_FILES)
+])dnl
+
+dnl This sets the prefix, for arts and kdelibs
+dnl Do NOT use in any other module.
+dnl It only looks at --prefix, KDEDIR and falls back to /usr/local/kde
+AC_DEFUN([KDE_SET_PREFIX_CORE],
+[
+ unset CDPATH
+ dnl make $KDEDIR the default for the installation
+ AC_PREFIX_DEFAULT(${KDEDIR:-/usr/local/kde})
+
+ if test "x$prefix" = "xNONE"; then
+ prefix=$ac_default_prefix
+ ac_configure_args="$ac_configure_args --prefix=$prefix"
+ fi
+ # And delete superfluous '/' to make compares easier
+ prefix=`echo "$prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'`
+ exec_prefix=`echo "$exec_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'`
+
+ kde_libs_prefix='$(prefix)'
+ kde_libs_htmldir='$(kde_htmldir)'
+ AC_SUBST(kde_libs_prefix)
+ AC_SUBST(kde_libs_htmldir)
+ KDE_FAST_CONFIGURE
+ KDE_CONF_FILES
+])
+
+
+AC_DEFUN([KDE_SET_PREFIX],
+[
+ unset CDPATH
+ dnl We can't give real code to that macro, only a value.
+ dnl It only matters for --help, since we set the prefix in this function anyway.
+ AC_PREFIX_DEFAULT(${KDEDIR:-the kde prefix})
+
+ KDE_SET_DEFAULT_BINDIRS
+ if test "x$prefix" = "xNONE"; then
+ dnl no prefix given: look for kde-config in the PATH and deduce the prefix from it
+ KDE_FIND_PATH(kde-config, KDECONFIG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(kde-config)], [], prepend)
+ else
+ dnl prefix given: look for kde-config, preferrably in prefix, otherwise in PATH
+ kde_save_PATH="$PATH"
+ PATH="$exec_prefix/bin:$prefix/bin:$PATH"
+ KDE_FIND_PATH(kde-config, KDECONFIG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(kde-config)], [], prepend)
+ PATH="$kde_save_PATH"
+ fi
+
+ kde_libs_prefix=`$KDECONFIG --prefix`
+ if test -z "$kde_libs_prefix" || test ! -x "$kde_libs_prefix"; then
+ AC_MSG_ERROR([$KDECONFIG --prefix outputed the non existant prefix '$kde_libs_prefix' for kdelibs.
+ This means it has been moved since you installed it.
+ This won't work. Please recompile kdelibs for the new prefix.
+ ])
+ fi
+ kde_libs_htmldir=`$KDECONFIG --install html --expandvars`
+ kde_libs_suffix=`$KDECONFIG --libsuffix`
+
+ AC_MSG_CHECKING([where to install])
+ if test "x$prefix" = "xNONE"; then
+ prefix=$kde_libs_prefix
+ AC_MSG_RESULT([$prefix (as returned by kde-config)])
+ else
+ dnl --prefix was given. Compare prefixes and warn (in configure.in.bot.end) if different
+ given_prefix=$prefix
+ AC_MSG_RESULT([$prefix (as requested)])
+ fi
+
+ # And delete superfluous '/' to make compares easier
+ prefix=`echo "$prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'`
+ exec_prefix=`echo "$exec_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'`
+ given_prefix=`echo "$given_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'`
+
+ AC_SUBST(KDECONFIG)
+ AC_SUBST(kde_libs_prefix)
+ AC_SUBST(kde_libs_htmldir)
+
+ KDE_FAST_CONFIGURE
+ KDE_CONF_FILES
+])
+
+pushdef([AC_PROG_INSTALL],
+[
+ dnl our own version, testing for a -p flag
+ popdef([AC_PROG_INSTALL])
+ dnl as AC_PROG_INSTALL works as it works we first have
+ dnl to save if the user didn't specify INSTALL, as the
+ dnl autoconf one overwrites INSTALL and we have no chance to find
+ dnl out afterwards
+ test -n "$INSTALL" && kde_save_INSTALL_given=$INSTALL
+ test -n "$INSTALL_PROGRAM" && kde_save_INSTALL_PROGRAM_given=$INSTALL_PROGRAM
+ test -n "$INSTALL_SCRIPT" && kde_save_INSTALL_SCRIPT_given=$INSTALL_SCRIPT
+ AC_PROG_INSTALL
+
+ if test -z "$kde_save_INSTALL_given" ; then
+ # OK, user hasn't given any INSTALL, autoconf found one for us
+ # now we test, if it supports the -p flag
+ AC_MSG_CHECKING(for -p flag to install)
+ rm -f confinst.$$.* > /dev/null 2>&1
+ echo "Testtest" > confinst.$$.orig
+ ac_res=no
+ if ${INSTALL} -p confinst.$$.orig confinst.$$.new > /dev/null 2>&1 ; then
+ if test -f confinst.$$.new ; then
+ # OK, -p seems to do no harm to install
+ INSTALL="${INSTALL} -p"
+ ac_res=yes
+ fi
+ fi
+ rm -f confinst.$$.*
+ AC_MSG_RESULT($ac_res)
+ fi
+ dnl the following tries to resolve some signs and wonders coming up
+ dnl with different autoconf/automake versions
+ dnl e.g.:
+ dnl *automake 1.4 install-strip sets A_M_INSTALL_PROGRAM_FLAGS to -s
+ dnl and has INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(A_M_INSTALL_PROGRAM_FLAGS)
+ dnl it header-vars.am, so there the actual INSTALL_PROGRAM gets the -s
+ dnl *automake 1.4a (and above) use INSTALL_STRIP_FLAG and only has
+ dnl INSTALL_PROGRAM = @INSTALL_PROGRAM@ there, but changes the
+ dnl install-@DIR@PROGRAMS targets to explicitly use that flag
+ dnl *autoconf 2.13 is dumb, and thinks it can use INSTALL_PROGRAM as
+ dnl INSTALL_SCRIPT, which breaks with automake <= 1.4
+ dnl *autoconf >2.13 (since 10.Apr 1999) has not that failure
+ dnl *sometimes KDE does not use the install-@DIR@PROGRAM targets from
+ dnl automake (due to broken Makefile.am or whatever) to install programs,
+ dnl and so does not see the -s flag in automake > 1.4
+ dnl to clean up that mess we:
+ dnl +set INSTALL_PROGRAM to use INSTALL_STRIP_FLAG
+ dnl which cleans KDE's program with automake > 1.4;
+ dnl +set INSTALL_SCRIPT to only use INSTALL, to clean up autoconf's problems
+ dnl with automake<=1.4
+ dnl note that dues to this sometimes two '-s' flags are used (if KDE
+ dnl properly uses install-@DIR@PROGRAMS, but I don't care
+ dnl
+ dnl And to all this comes, that I even can't write in comments variable
+ dnl names used by automake, because it is so stupid to think I wanted to
+ dnl _use_ them, therefor I have written A_M_... instead of AM_
+ dnl hmm, I wanted to say something ... ahh yes: Arghhh.
+
+ if test -z "$kde_save_INSTALL_PROGRAM_given" ; then
+ INSTALL_PROGRAM='${INSTALL} $(INSTALL_STRIP_FLAG)'
+ fi
+ if test -z "$kde_save_INSTALL_SCRIPT_given" ; then
+ INSTALL_SCRIPT='${INSTALL}'
+ fi
+])dnl
+
+AC_DEFUN([KDE_LANG_CPLUSPLUS],
+[AC_LANG_CPLUSPLUS
+ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&AC_FD_CC'
+pushdef([AC_LANG_CPLUSPLUS], [popdef([AC_LANG_CPLUSPLUS]) KDE_LANG_CPLUSPLUS])
+])
+
+pushdef([AC_LANG_CPLUSPLUS],
+[popdef([AC_LANG_CPLUSPLUS])
+KDE_LANG_CPLUSPLUS
+])
+
+AC_DEFUN([KDE_CHECK_LONG_LONG],
+[
+AC_MSG_CHECKING(for long long)
+AC_CACHE_VAL(kde_cv_c_long_long,
+[
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_LINK([], [
+ long long foo = 0;
+ foo = foo+1;
+ ],
+ kde_cv_c_long_long=yes, kde_cv_c_long_long=no)
+ AC_LANG_RESTORE
+])
+AC_MSG_RESULT($kde_cv_c_long_long)
+if test "$kde_cv_c_long_long" = yes; then
+ AC_DEFINE(HAVE_LONG_LONG, 1, [Define if you have long long as datatype])
+fi
+])
+
+AC_DEFUN([KDE_CHECK_LIB],
+[
+ kde_save_LDFLAGS="$LDFLAGS"
+ dnl AC_CHECK_LIB modifies LIBS, so save it here
+ kde_save_LIBS="$LIBS"
+ LDFLAGS="$LDFLAGS $all_libraries"
+ case $host_os in
+ aix*) LDFLAGS="-brtl $LDFLAGS"
+ test "$GCC" = yes && LDFLAGS="-Wl,$LDFLAGS"
+ ;;
+ esac
+ AC_CHECK_LIB($1, $2, $3, $4, $5)
+ LDFLAGS="$kde_save_LDFLAGS"
+ LIBS="$kde_save_LIBS"
+])
+
+dnl this is a redefinition of autoconf 2.5x's AC_FOREACH.
+dnl When the argument list becomes big, as in KDE for AC_OUTPUT in
+dnl big packages, m4_foreach is dog-slow. So use our own version of
+dnl it. (matz@kde.org)
+m4_define([mm_foreach],
+[m4_pushdef([$1])_mm_foreach($@)m4_popdef([$1])])
+m4_define([mm_car], [[$1]])
+m4_define([mm_car2], [[$@]])
+m4_define([_mm_foreach],
+[m4_if(m4_quote($2), [], [],
+ [m4_define([$1], mm_car($2))$3[]_mm_foreach([$1],
+ mm_car2(m4_shift($2)),
+ [$3])])])
+m4_define([AC_FOREACH],
+[mm_foreach([$1], m4_split(m4_normalize([$2])), [$3])])
+
+AC_DEFUN([KDE_INIT_DOXYGEN],
+[
+AC_MSG_CHECKING([for Qt docs])
+kde_qtdir=
+if test "${with_qt_dir+set}" = set; then
+ kde_qtdir="$with_qt_dir"
+fi
+
+AC_FIND_FILE(qsql.html, [ $kde_qtdir/doc/html $QTDIR/doc/html /usr/share/doc/packages/qt3/html /usr/lib/qt/doc /usr/lib/qt3/doc /usr/lib/qt3/doc/html /usr/doc/qt3/html /usr/doc/qt3 /usr/share/doc/qt3-doc /usr/share/qt3/doc/html /usr/X11R6/share/doc/qt/html ], QTDOCDIR)
+AC_MSG_RESULT($QTDOCDIR)
+
+AC_SUBST(QTDOCDIR)
+
+KDE_FIND_PATH(dot, DOT, [], [])
+if test -n "$DOT"; then
+ KDE_HAVE_DOT="YES"
+else
+ KDE_HAVE_DOT="NO"
+fi
+AC_SUBST(KDE_HAVE_DOT)
+KDE_FIND_PATH(doxygen, DOXYGEN, [], [])
+AC_SUBST(DOXYGEN)
+
+DOXYGEN_PROJECT_NAME="$1"
+DOXYGEN_PROJECT_NUMBER="$2"
+AC_SUBST(DOXYGEN_PROJECT_NAME)
+AC_SUBST(DOXYGEN_PROJECT_NUMBER)
+
+KDE_HAS_DOXYGEN=no
+if test -n "$DOXYGEN" && test -x "$DOXYGEN" && test -f $QTDOCDIR/qsql.html; then
+ KDE_HAS_DOXYGEN=yes
+fi
+AC_SUBST(KDE_HAS_DOXYGEN)
+
+])
+
+AC_DEFUN([KDE_CHECK_STRLCPY],
+[
+ AC_REQUIRE([AC_CHECK_STRLCAT])
+ AC_REQUIRE([AC_CHECK_STRLCPY])
+ AC_CHECK_SIZEOF(size_t)
+ AC_CHECK_SIZEOF(unsigned long)
+
+ AC_MSG_CHECKING([sizeof size_t == sizeof unsigned long])
+ AC_TRY_COMPILE(,[
+ #if SIZEOF_SIZE_T != SIZEOF_UNSIGNED_LONG
+ choke me
+ #endif
+ ],AC_MSG_RESULT([yes]),[
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([
+ Apparently on your system our assumption sizeof size_t == sizeof unsigned long
+ does not apply. Please mail kde-devel@kde.org with a description of your system!
+ ])
+ ])
+])
+
+AC_DEFUN([KDE_CHECK_BINUTILS],
+[
+ AC_MSG_CHECKING([if ld supports unversioned version maps])
+
+ kde_save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map"
+ echo "{ local: extern \"C++\" { foo }; };" > conftest.map
+ AC_TRY_LINK([int foo;],
+[
+#ifdef __INTEL_COMPILER
+icc apparently does not support libtools version-info and version-script
+at the same time. Dunno where the bug is, but until somebody figured out,
+better disable the optional version scripts.
+#endif
+
+ foo = 42;
+], kde_supports_versionmaps=yes, kde_supports_versionmaps=no)
+ LDFLAGS="$kde_save_LDFLAGS"
+ rm -f conftest.map
+ AM_CONDITIONAL(include_VERSION_SCRIPT,
+ [test "$kde_supports_versionmaps" = "yes" && test "$kde_use_debug_code" = "no"])
+
+ AC_MSG_RESULT($kde_supports_versionmaps)
+])
+
+AC_DEFUN([KDE_CHECK_PERL],
+[
+ KDE_FIND_PATH(perl, PERL, [$bindir $exec_prefix/bin $prefix/bin], [
+ AC_MSG_ERROR([No Perl found in your $PATH.
+We need perl to generate some code.])
+ ])
+ AC_SUBST(PERL)
+])
+
+AC_DEFUN([KDE_CHECK_LARGEFILE],
+[
+AC_SYS_LARGEFILE
+if test "$ac_cv_sys_file_offset_bits" != no; then
+ CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits"
+fi
+
+if test "x$ac_cv_sys_large_files" != "xno"; then
+ CPPFLAGS="$CPPFLAGS -D_LARGE_FILES=1"
+fi
+
+])
+
+dnl A small extension to PKG_CHECK_MODULES (defined in pkg.m4.in)
+dnl which allows to search for libs that get installed into the KDE prefix.
+dnl
+dnl Syntax: KDE_PKG_CHECK_MODULES(KSTUFF, libkexif >= 0.2 glib = 1.3.4, action-if, action-not)
+dnl defines KSTUFF_LIBS, KSTUFF_CFLAGS, see pkg-config man page
+dnl also defines KSTUFF_PKG_ERRORS on error
+AC_DEFUN([KDE_PKG_CHECK_MODULES], [
+
+ PKG_CONFIG_PATH="$prefix/lib${kdelibsuff}/pkgconfig:$PKG_CONFIG_PATH"
+ if test "$prefix" != "$kde_libs_prefix"; then
+ PKG_CONFIG_PATH="$kde_libs_prefix/lib${kdelibsuff}/pkgconfig:$PKG_CONFIG_PATH"
+ fi
+ export PKG_CONFIG_PATH
+ PKG_CHECK_MODULES([$1],[$2],[$3],[$4])
+])
+
+
+dnl Check for PIE support in the compiler and linker
+AC_DEFUN([KDE_CHECK_PIE_SUPPORT],
+[
+ AC_CACHE_CHECK([for PIE support], kde_cv_val_pie_support,
+ [
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ safe_CXXFLAGS=$CXXFLAGS
+ safe_LDFLAGS=$LDFLAGS
+ CXXFLAGS="$CXXFLAGS -fPIE"
+ LDFLAGS="$LDFLAGS -pie"
+
+ AC_TRY_LINK([int foo;], [], [kde_cv_val_pie_support=yes], [kde_cv_val_pie_support=no])
+
+ CXXFLAGS=$safe_CXXFLAGS
+ LDFLAGS=$safe_LDFLAGS
+ AC_LANG_RESTORE
+ ])
+
+ AC_MSG_CHECKING(if enabling -pie/fPIE support)
+
+ AC_ARG_ENABLE(pie,
+ AC_HELP_STRING([--enable-pie],[platform supports PIE linking [default=detect]]),
+ [kde_has_pie_support=$enableval],
+ [kde_has_pie_support=detect])
+
+ if test "$kde_has_pie_support" = "detect"; then
+ kde_has_pie_support=$kde_cv_val_pie_support
+ fi
+
+ AC_MSG_RESULT([$kde_has_pie_support])
+
+ KDE_USE_FPIE=""
+ KDE_USE_PIE=""
+
+ AC_SUBST([KDE_USE_FPIE])
+ AC_SUBST([KDE_USE_PIE])
+
+ if test "$kde_has_pie_support" = "yes"; then
+ KDE_USE_FPIE="-fPIE"
+ KDE_USE_PIE="-pie"
+ fi
+])
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+## Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
+## Free Software Foundation, Inc.
+## Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+##
+## This file is free software; the Free Software Foundation gives
+## unlimited permission to copy and/or distribute it, with or without
+## modifications, as long as this notice is preserved.
+
+# serial 48 AC_PROG_LIBTOOL
+
+
+# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
+# -----------------------------------------------------------
+# If this macro is not defined by Autoconf, define it here.
+m4_ifdef([AC_PROVIDE_IFELSE],
+ [],
+ [m4_define([AC_PROVIDE_IFELSE],
+ [m4_ifdef([AC_PROVIDE_$1],
+ [$2], [$3])])])
+
+
+# AC_PROG_LIBTOOL
+# ---------------
+AC_DEFUN([AC_PROG_LIBTOOL],
+[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl
+dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX
+dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX.
+ AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [AC_LIBTOOL_CXX],
+ [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX
+ ])])
+dnl And a similar setup for Fortran 77 support
+ AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [AC_LIBTOOL_F77],
+ [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77
+])])
+
+dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly.
+dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run
+dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both.
+ AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [AC_LIBTOOL_GCJ],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [AC_LIBTOOL_GCJ],
+ [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],
+ [AC_LIBTOOL_GCJ],
+ [ifdef([AC_PROG_GCJ],
+ [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])
+ ifdef([A][M_PROG_GCJ],
+ [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])])
+ ifdef([LT_AC_PROG_GCJ],
+ [define([LT_AC_PROG_GCJ],
+ defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])])
+])])# AC_PROG_LIBTOOL
+
+
+# _AC_PROG_LIBTOOL
+# ----------------
+AC_DEFUN([_AC_PROG_LIBTOOL],
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Prevent multiple expansion
+define([AC_PROG_LIBTOOL], [])
+])# _AC_PROG_LIBTOOL
+
+
+# AC_LIBTOOL_SETUP
+# ----------------
+AC_DEFUN([AC_LIBTOOL_SETUP],
+[AC_PREREQ(2.50)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+
+AC_REQUIRE([AC_PROG_LN_S])dnl
+AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+AC_REQUIRE([AC_OBJEXT])dnl
+AC_REQUIRE([AC_EXEEXT])dnl
+dnl
+
+AC_LIBTOOL_SYS_MAX_CMD_LEN
+AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+AC_LIBTOOL_OBJDIR
+
+AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+_LT_AC_PROG_ECHO_BACKSLASH
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g']
+
+# Same as above, but do not quote variable references.
+[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g']
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+AC_CHECK_TOOL(AR, ar, false)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(STRIP, strip, :)
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$SED" && SED=sed
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ AC_PATH_MAGIC
+ fi
+ ;;
+esac
+
+AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no)
+AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
+enable_win32_dll=yes, enable_win32_dll=no)
+
+AC_ARG_ENABLE([libtool-lock],
+ [AC_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+AC_ARG_WITH([pic],
+ [AC_HELP_STRING([--with-pic],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [pic_mode="$withval"],
+ [pic_mode=default])
+test -z "$pic_mode" && pic_mode=default
+
+# Use C for the default configuration in the libtool script
+tagname=
+AC_LIBTOOL_LANG_C_CONFIG
+_LT_AC_TAGCONFIG
+])# AC_LIBTOOL_SETUP
+
+
+# _LT_AC_SYS_COMPILER
+# -------------------
+AC_DEFUN([_LT_AC_SYS_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_AC_SYS_COMPILER
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+AC_DEFUN([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+])
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+AC_DEFUN([_LT_COMPILER_BOILERPLATE],
+[ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+AC_DEFUN([_LT_LINKER_BOILERPLATE],
+[ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+])# _LT_LINKER_BOILERPLATE
+
+
+# _LT_AC_SYS_LIBPATH_AIX
+# ----------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX],
+[AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`; fi],[])
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+])# _LT_AC_SYS_LIBPATH_AIX
+
+
+# _LT_AC_SHELL_INIT(ARG)
+# ----------------------
+AC_DEFUN([_LT_AC_SHELL_INIT],
+[ifdef([AC_DIVERSION_NOTICE],
+ [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+ [AC_DIVERT_PUSH(NOTICE)])
+$1
+AC_DIVERT_POP
+])# _LT_AC_SHELL_INIT
+
+
+# _LT_AC_PROG_ECHO_BACKSLASH
+# --------------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH],
+[_LT_AC_SHELL_INIT([
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+ # Remove one level of quotation (which was required for Make).
+ ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+ ;;
+esac
+
+echo=${ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X[$]1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell.
+ exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+[$]*
+EOF
+ exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if (echo_test_string=`eval $cmd`) 2>/dev/null &&
+ echo_test_string=`eval $cmd` &&
+ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+ then
+ break
+ fi
+ done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ :
+else
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for dir in $PATH /usr/ucb; do
+ IFS="$lt_save_ifs"
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$dir/echo"
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+
+ if test "X$echo" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ echo='print -r'
+ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running configure again with it.
+ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+ else
+ # Try using printf.
+ echo='printf %s\n'
+ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ echo="$CONFIG_SHELL [$]0 --fallback-echo"
+ elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$CONFIG_SHELL [$]0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+ then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "[$]0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ echo=echo
+ fi
+ fi
+ fi
+ fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+ ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(ECHO)
+])])# _LT_AC_PROG_ECHO_BACKSLASH
+
+
+# _LT_AC_LOCK
+# -----------
+AC_DEFUN([_LT_AC_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AC_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+sparc*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ *) LD="${LD-ld} -64" ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+ ])
+esac
+
+need_locks="$enable_libtool_lock"
+
+])# _LT_AC_LOCK
+
+
+# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION],
+[AC_REQUIRE([LT_AC_PROG_SED])
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $rm conftest*
+])
+
+if test x"[$]$2" = xyes; then
+ ifelse([$5], , :, [$5])
+else
+ ifelse([$6], , :, [$6])
+fi
+])# AC_LIBTOOL_COMPILER_OPTION
+
+
+# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([AC_LIBTOOL_LINKER_OPTION],
+[AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $3"
+ printf "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $rm conftest*
+ LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+ ifelse([$4], , :, [$4])
+else
+ ifelse([$5], , :, [$5])
+fi
+])# AC_LIBTOOL_LINKER_OPTION
+
+
+# AC_LIBTOOL_SYS_MAX_CMD_LEN
+# --------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN],
+[# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \
+ = "XX$teststring") >/dev/null 2>&1 &&
+ new_result=`expr "X$teststring" : ".*" 2>&1` &&
+ lt_cv_sys_max_cmd_len=$new_result &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on massive
+ # amounts of additional arguments before passing them to the linker.
+ # It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ ;;
+ esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+])# AC_LIBTOOL_SYS_MAX_CMD_LEN
+
+
+# _LT_AC_CHECK_DLFCN
+# ------------------
+AC_DEFUN([_LT_AC_CHECK_DLFCN],
+[AC_CHECK_HEADERS(dlfcn.h)dnl
+])# _LT_AC_CHECK_DLFCN
+
+
+# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ---------------------------------------------------------------------
+AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
+[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ exit (status);
+}]
+EOF
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_AC_TRY_DLOPEN_SELF
+
+
+# AC_LIBTOOL_DLOPEN_SELF
+# ----------------------
+AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
+[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen="shl_load"],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen="dlopen"],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_AC_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_AC_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+])# AC_LIBTOOL_DLOPEN_SELF
+
+
+# AC_LIBTOOL_PROG_CC_C_O([TAGNAME])
+# ---------------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler
+AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O],
+[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $rm -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $rm conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+ $rm out/* && rmdir out
+ cd ..
+ rmdir conftest
+ $rm conftest*
+])
+])# AC_LIBTOOL_PROG_CC_C_O
+
+
+# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME])
+# -----------------------------------------
+# Check to see if we can do hard links to lock some files if needed
+AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS],
+[AC_REQUIRE([_LT_AC_LOCK])dnl
+
+hard_links="nottested"
+if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $rm conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test "$hard_links" = no; then
+ AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS
+
+
+# AC_LIBTOOL_OBJDIR
+# -----------------
+AC_DEFUN([AC_LIBTOOL_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+])# AC_LIBTOOL_OBJDIR
+
+
+# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME])
+# ----------------------------------------------
+# Check hardcoding attributes.
+AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_AC_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \
+ test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \
+ test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+ # We can hardcode non-existant directories.
+ if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+ test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_AC_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_AC_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_AC_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH
+
+
+# AC_LIBTOOL_SYS_LIB_STRIP
+# ------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP],
+[striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+])# AC_LIBTOOL_SYS_LIB_STRIP
+
+
+# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER],
+[AC_MSG_CHECKING([dynamic linker characteristics])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix4* | aix5*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$host_os in
+ yes,cygwin* | yes,mingw* | yes,pw32*)
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $rm \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+ ;;
+ mingw*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH printed by
+ # mingw gcc, but we are running on Cygwin. Gcc prints its search
+ # path with ; separators, and with drive letters. We can handle the
+ # drive letters (cygwin fileutils understands them), so leave them,
+ # especially as we might pass files found there to a mingw objdump,
+ # which wouldn't understand a cygwinified path. Ahh.
+ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ ;;
+
+ *)
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+ # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+ if test "$GCC" = yes; then
+ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+ else
+ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+ fi
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+kfreebsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='GNU ld.so'
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[123]]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ freebsd*) # from 4.6 on
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+interix3*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+knetbsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='GNU ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+nto-qnx*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[[89]] | openbsd2.[[89]].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ shlibpath_overrides_runpath=no
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ shlibpath_overrides_runpath=yes
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+])# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+
+
+# _LT_AC_TAGCONFIG
+# ----------------
+AC_DEFUN([_LT_AC_TAGCONFIG],
+[AC_ARG_WITH([tags],
+ [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@],
+ [include additional configurations @<:@automatic@:>@])],
+ [tagnames="$withval"])
+
+if test -f "$ltmain" && test -n "$tagnames"; then
+ if test ! -f "${ofile}"; then
+ AC_MSG_WARN([output file `$ofile' does not exist])
+ fi
+
+ if test -z "$LTCC"; then
+ eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
+ if test -z "$LTCC"; then
+ AC_MSG_WARN([output file `$ofile' does not look like a libtool script])
+ else
+ AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile'])
+ fi
+ fi
+ if test -z "$LTCFLAGS"; then
+ eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`"
+ fi
+
+ # Extract list of available tagged configurations in $ofile.
+ # Note that this assumes the entire list is on one line.
+ available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'`
+
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for tagname in $tagnames; do
+ IFS="$lt_save_ifs"
+ # Check whether tagname contains only valid characters
+ case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in
+ "") ;;
+ *) AC_MSG_ERROR([invalid tag name: $tagname])
+ ;;
+ esac
+
+ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null
+ then
+ AC_MSG_ERROR([tag name \"$tagname\" already exists])
+ fi
+
+ # Update the list of available tags.
+ if test -n "$tagname"; then
+ echo appending configuration tag \"$tagname\" to $ofile
+
+ case $tagname in
+ CXX)
+ if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ AC_LIBTOOL_LANG_CXX_CONFIG
+ else
+ tagname=""
+ fi
+ ;;
+
+ F77)
+ if test -n "$F77" && test "X$F77" != "Xno"; then
+ AC_LIBTOOL_LANG_F77_CONFIG
+ else
+ tagname=""
+ fi
+ ;;
+
+ GCJ)
+ if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
+ AC_LIBTOOL_LANG_GCJ_CONFIG
+ else
+ tagname=""
+ fi
+ ;;
+
+ RC)
+ AC_LIBTOOL_LANG_RC_CONFIG
+ ;;
+
+ *)
+ AC_MSG_ERROR([Unsupported tag name: $tagname])
+ ;;
+ esac
+
+ # Append the new tag name to the list of available tags.
+ if test -n "$tagname" ; then
+ available_tags="$available_tags $tagname"
+ fi
+ fi
+ done
+ IFS="$lt_save_ifs"
+
+ # Now substitute the updated list of available tags.
+ if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then
+ mv "${ofile}T" "$ofile"
+ chmod +x "$ofile"
+ else
+ rm -f "${ofile}T"
+ AC_MSG_ERROR([unable to update list of available tagged configurations.])
+ fi
+fi
+])# _LT_AC_TAGCONFIG
+
+
+# AC_LIBTOOL_DLOPEN
+# -----------------
+# enable checks for dlopen support
+AC_DEFUN([AC_LIBTOOL_DLOPEN],
+ [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])
+])# AC_LIBTOOL_DLOPEN
+
+
+# AC_LIBTOOL_WIN32_DLL
+# --------------------
+# declare package support for building win32 DLLs
+AC_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_BEFORE([$0], [AC_LIBTOOL_SETUP])
+])# AC_LIBTOOL_WIN32_DLL
+
+
+# AC_ENABLE_SHARED([DEFAULT])
+# ---------------------------
+# implement the --enable-shared flag
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_SHARED],
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([shared],
+ [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_shared=]AC_ENABLE_SHARED_DEFAULT)
+])# AC_ENABLE_SHARED
+
+
+# AC_DISABLE_SHARED
+# -----------------
+# set the default shared flag to --disable-shared
+AC_DEFUN([AC_DISABLE_SHARED],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)
+])# AC_DISABLE_SHARED
+
+
+# AC_ENABLE_STATIC([DEFAULT])
+# ---------------------------
+# implement the --enable-static flag
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_STATIC],
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([static],
+ [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_static=]AC_ENABLE_STATIC_DEFAULT)
+])# AC_ENABLE_STATIC
+
+
+# AC_DISABLE_STATIC
+# -----------------
+# set the default static flag to --disable-static
+AC_DEFUN([AC_DISABLE_STATIC],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)
+])# AC_DISABLE_STATIC
+
+
+# AC_ENABLE_FAST_INSTALL([DEFAULT])
+# ---------------------------------
+# implement the --enable-fast-install flag
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_FAST_INSTALL],
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([fast-install],
+ [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT)
+])# AC_ENABLE_FAST_INSTALL
+
+
+# AC_DISABLE_FAST_INSTALL
+# -----------------------
+# set the default to --disable-fast-install
+AC_DEFUN([AC_DISABLE_FAST_INSTALL],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)
+])# AC_DISABLE_FAST_INSTALL
+
+
+# AC_LIBTOOL_PICMODE([MODE])
+# --------------------------
+# implement the --with-pic flag
+# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
+AC_DEFUN([AC_LIBTOOL_PICMODE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+pic_mode=ifelse($#,1,$1,default)
+])# AC_LIBTOOL_PICMODE
+
+
+# AC_PROG_EGREP
+# -------------
+# This is predefined starting with Autoconf 2.54, so this conditional
+# definition can be removed once we require Autoconf 2.54 or later.
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP],
+[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep],
+ [if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi])
+ EGREP=$ac_cv_prog_egrep
+ AC_SUBST([EGREP])
+])])
+
+
+# AC_PATH_TOOL_PREFIX
+# -------------------
+# find a file program which can recognise shared library
+AC_DEFUN([AC_PATH_TOOL_PREFIX],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="ifelse([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+])# AC_PATH_TOOL_PREFIX
+
+
+# AC_PATH_MAGIC
+# -------------
+# find a file program which can recognise a shared library
+AC_DEFUN([AC_PATH_MAGIC],
+[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# AC_PATH_MAGIC
+
+
+# AC_PROG_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([AC_PROG_LD],
+[AC_ARG_WITH([gnu-ld],
+ [AC_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test "$withval" = no || with_gnu_ld=yes],
+ [with_gnu_ld=no])
+AC_REQUIRE([LT_AC_PROG_SED])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])# AC_PROG_LD
+
+
+# AC_PROG_LD_GNU
+# --------------
+AC_DEFUN([AC_PROG_LD_GNU],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# AC_PROG_LD_GNU
+
+
+# AC_PROG_LD_RELOAD_FLAG
+# ----------------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+AC_DEFUN([AC_PROG_LD_RELOAD_FLAG],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+])# AC_PROG_LD_RELOAD_FLAG
+
+
+# AC_DEPLIBS_CHECK_METHOD
+# -----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
+[AC_CACHE_CHECK([how to recognise dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump'.
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | kfreebsd*-gnu | dragonfly*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix3*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+nto-qnx*)
+ lt_cv_deplibs_check_method=unknown
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+])# AC_DEPLIBS_CHECK_METHOD
+
+
+# AC_PROG_NM
+# ----------
+# find the pathname to a BSD-compatible name lister
+AC_DEFUN([AC_PROG_NM],
+[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi])
+NM="$lt_cv_path_NM"
+])# AC_PROG_NM
+
+
+# AC_CHECK_LIBM
+# -------------
+# check for math library
+AC_DEFUN([AC_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM="-lm")
+ ;;
+esac
+])# AC_CHECK_LIBM
+
+
+# AC_LIBLTDL_CONVENIENCE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl convenience library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-convenience to the configure arguments. Note that
+# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided,
+# it is assumed to be `libltdl'. LIBLTDL will be prefixed with
+# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/'
+# (note the single quotes!). If your package is not flat and you're not
+# using automake, define top_builddir and top_srcdir appropriately in
+# the Makefiles.
+AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ case $enable_ltdl_convenience in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+ LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+ # For backwards non-gettext consistent compatibility...
+ INCLTDL="$LTDLINCL"
+])# AC_LIBLTDL_CONVENIENCE
+
+
+# AC_LIBLTDL_INSTALLABLE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl installable library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-install to the configure arguments. Note that
+# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided,
+# and an installed libltdl is not found, it is assumed to be `libltdl'.
+# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with
+# '${top_srcdir}/' (note the single quotes!). If your package is not
+# flat and you're not using automake, define top_builddir and top_srcdir
+# appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ AC_CHECK_LIB(ltdl, lt_dlinit,
+ [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+ [if test x"$enable_ltdl_install" = xno; then
+ AC_MSG_WARN([libltdl not installed, but installation disabled])
+ else
+ enable_ltdl_install=yes
+ fi
+ ])
+ if test x"$enable_ltdl_install" = x"yes"; then
+ ac_configure_args="$ac_configure_args --enable-ltdl-install"
+ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+ LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+ else
+ ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+ LIBLTDL="-lltdl"
+ LTDLINCL=
+ fi
+ # For backwards non-gettext consistent compatibility...
+ INCLTDL="$LTDLINCL"
+])# AC_LIBLTDL_INSTALLABLE
+
+
+# AC_LIBTOOL_CXX
+# --------------
+# enable support for C++ libraries
+AC_DEFUN([AC_LIBTOOL_CXX],
+[AC_REQUIRE([_LT_AC_LANG_CXX])
+])# AC_LIBTOOL_CXX
+
+
+# _LT_AC_LANG_CXX
+# ---------------
+AC_DEFUN([_LT_AC_LANG_CXX],
+[AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([_LT_AC_PROG_CXXCPP])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX])
+])# _LT_AC_LANG_CXX
+
+# _LT_AC_PROG_CXXCPP
+# ------------------
+AC_DEFUN([_LT_AC_PROG_CXXCPP],
+[
+AC_REQUIRE([AC_PROG_CXX])
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ AC_PROG_CXXCPP
+fi
+])# _LT_AC_PROG_CXXCPP
+
+# AC_LIBTOOL_F77
+# --------------
+# enable support for Fortran 77 libraries
+AC_DEFUN([AC_LIBTOOL_F77],
+[AC_REQUIRE([_LT_AC_LANG_F77])
+])# AC_LIBTOOL_F77
+
+
+# _LT_AC_LANG_F77
+# ---------------
+AC_DEFUN([_LT_AC_LANG_F77],
+[AC_REQUIRE([AC_PROG_F77])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77])
+])# _LT_AC_LANG_F77
+
+
+# AC_LIBTOOL_GCJ
+# --------------
+# enable support for GCJ libraries
+AC_DEFUN([AC_LIBTOOL_GCJ],
+[AC_REQUIRE([_LT_AC_LANG_GCJ])
+])# AC_LIBTOOL_GCJ
+
+
+# _LT_AC_LANG_GCJ
+# ---------------
+AC_DEFUN([_LT_AC_LANG_GCJ],
+[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[],
+ [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[],
+ [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])],
+ [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])],
+ [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ])
+])# _LT_AC_LANG_GCJ
+
+
+# AC_LIBTOOL_RC
+# -------------
+# enable support for Windows resource files
+AC_DEFUN([AC_LIBTOOL_RC],
+[AC_REQUIRE([LT_AC_PROG_RC])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC])
+])# AC_LIBTOOL_RC
+
+
+# AC_LIBTOOL_LANG_C_CONFIG
+# ------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined. Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG])
+AC_DEFUN([_LT_AC_LANG_C_CONFIG],
+[lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}\n'
+
+_LT_AC_SYS_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+AC_LIBTOOL_DLOPEN_SELF
+
+# Report which library types will actually be built
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case $host_os in
+aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+aix4* | aix5*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_C_CONFIG
+
+
+# AC_LIBTOOL_LANG_CXX_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined. Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)])
+AC_DEFUN([_LT_AC_LANG_CXX_CONFIG],
+[AC_LANG_PUSH(C++)
+AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([_LT_AC_PROG_CXXCPP])
+
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_AC_TAGVAR(allow_undefined_flag, $1)=
+_LT_AC_TAGVAR(always_export_symbols, $1)=no
+_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_direct, $1)=no
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_AC_TAGVAR(hardcode_automatic, $1)=no
+_LT_AC_TAGVAR(module_cmds, $1)=
+_LT_AC_TAGVAR(module_expsym_cmds, $1)=
+_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_AC_TAGVAR(no_undefined_flag, $1)=
+_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Dependencies to place before and after the object being linked:
+_LT_AC_TAGVAR(predep_objects, $1)=
+_LT_AC_TAGVAR(postdep_objects, $1)=
+_LT_AC_TAGVAR(predeps, $1)=
+_LT_AC_TAGVAR(postdeps, $1)=
+_LT_AC_TAGVAR(compiler_lib_search_path, $1)=
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_LD=$LD
+lt_save_GCC=$GCC
+GCC=$GXX
+lt_save_with_gnu_ld=$with_gnu_ld
+lt_save_path_LD=$lt_cv_path_LD
+if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+else
+ $as_unset lt_cv_prog_gnu_ld
+fi
+if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+else
+ $as_unset lt_cv_path_LD
+fi
+test -z "${LDCXX+set}" || LD=$LDCXX
+CC=${CXX-"c++"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+
+# We don't want -fno-exception wen compiling C++ code, so set the
+# no_builtin_flag separately
+if test "$GXX" = yes; then
+ _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+else
+ _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+fi
+
+if test "$GXX" = yes; then
+ # Set up default GNU C++ configuration
+
+ AC_PROG_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test "$with_gnu_ld" = yes; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='${wl}'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" | \
+ grep 'no-whole-archive' > /dev/null; then
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+fi
+
+# PORTME: fill in a description of your system's C++ link characteristics
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+_LT_AC_TAGVAR(ld_shlibs, $1)=yes
+case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix4* | aix5*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_AC_TAGVAR(archive_cmds, $1)=''
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+ if test "$GXX" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ else
+ # We have old collect2
+ _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an empty executable.
+ _LT_AC_SYS_LIBPATH_AIX
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an empty executable.
+ _LT_AC_SYS_LIBPATH_AIX
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_AC_TAGVAR(always_export_symbols, $1)=no
+ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ darwin* | rhapsody*)
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
+ ;;
+ *) # Darwin 1.3 on
+ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ else
+ case ${MACOSX_DEPLOYMENT_TARGET} in
+ 10.[[012]])
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ ;;
+ 10.*)
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=''
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+ if test "$GXX" = yes ; then
+ lt_int_apple_cc_single_mod=no
+ output_verbose_link_cmd='echo'
+ if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then
+ lt_int_apple_cc_single_mod=yes
+ fi
+ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ fi
+ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ case $cc_basename in
+ xlc*)
+ output_verbose_link_cmd='echo'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ ;;
+ *)
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ fi
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+ freebsd[[12]]*)
+ # C++ shared libraries reported to be fairly broken before switch to ELF
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ freebsd-elf*)
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+ freebsd* | kfreebsd*-gnu | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+ gnu*)
+ ;;
+ hpux9*)
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ hpux10*|hpux11*)
+ if test $with_gnu_ld = no; then
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+ ;;
+ *)
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test $with_gnu_ld = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ interix3*)
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test "$with_gnu_ld" = no; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
+ fi
+ fi
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+ linux*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc*)
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ ;;
+ pgCC*)
+ # Portland Group C++ compiler
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ esac
+ ;;
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ openbsd*)
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+ output_verbose_link_cmd='echo'
+ ;;
+ osf3*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~
+ $rm $lib.exp'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The C++ compiler is used as linker so we must use $wl
+ # flag to pass the commands to the underlying system
+ # linker. We must also pass each convience library through
+ # to the system linker between allextract/defaultextract.
+ # The C++ compiler will combine linker options so we
+ # cannot just pass the convience library names through
+ # without $wl.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract'
+ ;;
+ esac
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='echo'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+ if $CC --version | grep -v '^2\.7' > /dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+ else
+ # g++ 2.7 appears to require `-G' NOT `-shared' on this
+ # platform.
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+ fi
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+ fi
+ ;;
+ esac
+ ;;
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ # So that behaviour is only enabled if SCOABSPATH is set to a
+ # non-empty value in the environment. Most likely only useful for
+ # creating official distributions of packages.
+ # This is a hack until libtool officially supports absolute path
+ # names for shared libraries.
+ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+esac
+AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_AC_TAGVAR(GCC, $1)="$GXX"
+_LT_AC_TAGVAR(LD, $1)="$LD"
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+AC_LIBTOOL_POSTDEP_PREDEP($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC=$lt_save_CC
+LDCXX=$LD
+LD=$lt_save_LD
+GCC=$lt_save_GCC
+with_gnu_ldcxx=$with_gnu_ld
+with_gnu_ld=$lt_save_with_gnu_ld
+lt_cv_path_LDCXX=$lt_cv_path_LD
+lt_cv_path_LD=$lt_save_path_LD
+lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+])# AC_LIBTOOL_LANG_CXX_CONFIG
+
+# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME])
+# ------------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+ifelse([$1],[],[cat > conftest.$ac_ext <<EOF
+int a;
+void foo (void) { a = 0; }
+EOF
+],[$1],[CXX],[cat > conftest.$ac_ext <<EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+EOF
+],[$1],[F77],[cat > conftest.$ac_ext <<EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+EOF
+],[$1],[GCJ],[cat > conftest.$ac_ext <<EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+EOF
+])
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ # The `*' in the case matches for architectures that use `case' in
+ # $output_verbose_cmd can trigger glob expansion during the loop
+ # eval without this substitution.
+ output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`
+
+ for p in `eval $output_verbose_link_cmd`; do
+ case $p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" \
+ || test $p = "-R"; then
+ prev=$p
+ continue
+ else
+ prev=
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ case $p in
+ -L* | -R*)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+ else
+ _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${_LT_AC_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_AC_TAGVAR(postdeps, $1)"; then
+ _LT_AC_TAGVAR(postdeps, $1)="${prev}${p}"
+ else
+ _LT_AC_TAGVAR(postdeps, $1)="${_LT_AC_TAGVAR(postdeps, $1)} ${prev}${p}"
+ fi
+ fi
+ ;;
+
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ if test -z "$_LT_AC_TAGVAR(predep_objects, $1)"; then
+ _LT_AC_TAGVAR(predep_objects, $1)="$p"
+ else
+ _LT_AC_TAGVAR(predep_objects, $1)="$_LT_AC_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_AC_TAGVAR(postdep_objects, $1)"; then
+ _LT_AC_TAGVAR(postdep_objects, $1)="$p"
+ else
+ _LT_AC_TAGVAR(postdep_objects, $1)="$_LT_AC_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$rm -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+ifelse([$1],[CXX],
+[case $host_os in
+interix3*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_AC_TAGVAR(predep_objects,$1)=
+ _LT_AC_TAGVAR(postdep_objects,$1)=
+ _LT_AC_TAGVAR(postdeps,$1)=
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC*)
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ _LT_AC_TAGVAR(postdeps,$1)='-lCstd -lCrun'
+ ;;
+ esac
+ ;;
+esac
+])
+
+case " $_LT_AC_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+])# AC_LIBTOOL_POSTDEP_PREDEP
+
+# AC_LIBTOOL_LANG_F77_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined. Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG], [_LT_AC_LANG_F77_CONFIG(F77)])
+AC_DEFUN([_LT_AC_LANG_F77_CONFIG],
+[AC_REQUIRE([AC_PROG_F77])
+AC_LANG_PUSH(Fortran 77)
+
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_AC_TAGVAR(allow_undefined_flag, $1)=
+_LT_AC_TAGVAR(always_export_symbols, $1)=no
+_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_direct, $1)=no
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_automatic, $1)=no
+_LT_AC_TAGVAR(module_cmds, $1)=
+_LT_AC_TAGVAR(module_expsym_cmds, $1)=
+_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_AC_TAGVAR(no_undefined_flag, $1)=
+_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code=" subroutine t\n return\n end\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code=" program t\n end\n"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${F77-"f77"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case $host_os in
+aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+aix4* | aix5*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+_LT_AC_TAGVAR(GCC, $1)="$G77"
+_LT_AC_TAGVAR(LD, $1)="$LD"
+
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_F77_CONFIG
+
+
+# AC_LIBTOOL_LANG_GCJ_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined. Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG], [_LT_AC_LANG_GCJ_CONFIG(GCJ)])
+AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG],
+[AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${GCJ-"gcj"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_GCJ_CONFIG
+
+
+# AC_LIBTOOL_LANG_RC_CONFIG
+# -------------------------
+# Ensure that the configuration vars for the Windows resource compiler are
+# suitably defined. Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG], [_LT_AC_LANG_RC_CONFIG(RC)])
+AC_DEFUN([_LT_AC_LANG_RC_CONFIG],
+[AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${RC-"windres"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_RC_CONFIG
+
+
+# AC_LIBTOOL_CONFIG([TAGNAME])
+# ----------------------------
+# If TAGNAME is not passed, then create an initial libtool script
+# with a default configuration from the untagged config vars. Otherwise
+# add code to config.status for appending the configuration named by
+# TAGNAME from the matching tagged config vars.
+AC_DEFUN([AC_LIBTOOL_CONFIG],
+[# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+ # See if we are running on zsh, and set the options which allow our commands through
+ # without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+ # Now quote all the things that may contain metacharacters while being
+ # careful not to overquote the AC_SUBSTed values. We take copies of the
+ # variables and quote the copies for generation of the libtool script.
+ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+ SED SHELL STRIP \
+ libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+ old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+ deplibs_check_method reload_flag reload_cmds need_locks \
+ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+ lt_cv_sys_global_symbol_to_c_name_address \
+ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+ old_postinstall_cmds old_postuninstall_cmds \
+ _LT_AC_TAGVAR(compiler, $1) \
+ _LT_AC_TAGVAR(CC, $1) \
+ _LT_AC_TAGVAR(LD, $1) \
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1) \
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1) \
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1) \
+ _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) \
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1) \
+ _LT_AC_TAGVAR(thread_safe_flag_spec, $1) \
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1) \
+ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) \
+ _LT_AC_TAGVAR(old_archive_cmds, $1) \
+ _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) \
+ _LT_AC_TAGVAR(predep_objects, $1) \
+ _LT_AC_TAGVAR(postdep_objects, $1) \
+ _LT_AC_TAGVAR(predeps, $1) \
+ _LT_AC_TAGVAR(postdeps, $1) \
+ _LT_AC_TAGVAR(compiler_lib_search_path, $1) \
+ _LT_AC_TAGVAR(archive_cmds, $1) \
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1) \
+ _LT_AC_TAGVAR(postinstall_cmds, $1) \
+ _LT_AC_TAGVAR(postuninstall_cmds, $1) \
+ _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \
+ _LT_AC_TAGVAR(allow_undefined_flag, $1) \
+ _LT_AC_TAGVAR(no_undefined_flag, $1) \
+ _LT_AC_TAGVAR(export_symbols_cmds, $1) \
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1) \
+ _LT_AC_TAGVAR(hardcode_automatic, $1) \
+ _LT_AC_TAGVAR(module_cmds, $1) \
+ _LT_AC_TAGVAR(module_expsym_cmds, $1) \
+ _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \
+ _LT_AC_TAGVAR(exclude_expsyms, $1) \
+ _LT_AC_TAGVAR(include_expsyms, $1); do
+
+ case $var in
+ _LT_AC_TAGVAR(old_archive_cmds, $1) | \
+ _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) | \
+ _LT_AC_TAGVAR(archive_cmds, $1) | \
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1) | \
+ _LT_AC_TAGVAR(module_cmds, $1) | \
+ _LT_AC_TAGVAR(module_expsym_cmds, $1) | \
+ _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \
+ _LT_AC_TAGVAR(export_symbols_cmds, $1) | \
+ extract_expsyms_cmds | reload_cmds | finish_cmds | \
+ postinstall_cmds | postuninstall_cmds | \
+ old_postinstall_cmds | old_postuninstall_cmds | \
+ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+ # Double-quote double-evaled strings.
+ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+ ;;
+ *)
+ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+ ;;
+ esac
+ done
+
+ case $lt_echo in
+ *'\[$]0 --fallback-echo"')
+ lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\[$]0 --fallback-echo"[$]/[$]0 --fallback-echo"/'`
+ ;;
+ esac
+
+ifelse([$1], [],
+ [cfgfile="${ofile}T"
+ trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+ $rm -f "$cfgfile"
+ AC_MSG_NOTICE([creating $ofile])],
+ [cfgfile="$ofile"])
+
+ cat <<__EOF__ >> "$cfgfile"
+ifelse([$1], [],
+[#! $SHELL
+
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+#
+# This file is part of GNU Libtool:
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="$SED -e 1s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# The names of the tagged configurations supported by this script.
+available_tags=
+
+# ### BEGIN LIBTOOL CONFIG],
+[# ### BEGIN LIBTOOL TAG CONFIG: $tagname])
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
+# A language-specific compiler.
+CC=$lt_[]_LT_AC_TAGVAR(compiler, $1)
+
+# Is the compiler the GNU C compiler?
+with_gcc=$_LT_AC_TAGVAR(GCC, $1)
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_[]_LT_AC_TAGVAR(LD, $1)
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1)
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1)
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1)
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1)
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1)
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1)
+archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1)
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1)
+module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1)
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1)
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1)
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1)
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1)
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1)
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1)
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1)
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1)
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1)
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1)
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1)
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1)
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1)
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1)
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1)
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1)
+
+# Symbols that must always be exported.
+include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1)
+
+ifelse([$1],[],
+[# ### END LIBTOOL CONFIG],
+[# ### END LIBTOOL TAG CONFIG: $tagname])
+
+__EOF__
+
+ifelse([$1],[], [
+ case $host_os in
+ aix3*)
+ cat <<\EOF >> "$cfgfile"
+
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+EOF
+ ;;
+ esac
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" || \
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+])
+else
+ # If there is no Makefile yet, we rely on a make rule to execute
+ # `config.status --recheck' to rerun these tests and create the
+ # libtool script then.
+ ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+ if test -f "$ltmain_in"; then
+ test -f Makefile && make "$ltmain"
+ fi
+fi
+])# AC_LIBTOOL_CONFIG
+
+
+# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------------------
+AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI],
+[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+
+_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+
+ AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI
+
+
+# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+# ---------------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE],
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_NM])
+AC_REQUIRE([AC_OBJEXT])
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*) # Its linker distinguishes data from code symbols
+ if test "$host_cpu" = ia64; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+ ;;
+linux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[[ABCDGIRSTW]]'
+ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if grep ' nm_test_var$' "$nlist" >/dev/null; then
+ if grep ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext'
+
+ cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[[]] =
+{
+EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext
+ cat <<\EOF >> conftest.$ac_ext
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_save_LIBS="$LIBS"
+ lt_save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS="$lt_save_LIBS"
+ CFLAGS="$lt_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -f conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+
+
+# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME])
+# ---------------------------------------
+AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC],
+[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=
+
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+ ifelse([$1],[CXX],[
+ # C++ specific cases for pic, static, wl, etc.
+ if test "$GXX" = yes; then
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+ amigaos*)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | os2* | pw32*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ interix3*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix4* | aix5*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ darwin*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ case $cc_basename in
+ xlc*)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon'
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ esac
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | kfreebsd*-gnu | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ if test "$host_cpu" != ia64; then
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux*)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ icpc* | ecpc*)
+ # Intel C++
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC*)
+ # Portland Group C++ compiler.
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd*)
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+
+ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ interix3*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ hpux*)
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ darwin*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ case $cc_basename in
+ xlc*)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon'
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ esac
+ ;;
+
+ mingw* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ newsos6)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ linux*)
+ case $cc_basename in
+ icc* | ecc*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ esac
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)])
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works],
+ _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1),
+ [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\"
+AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=])
+])
+
+
+# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME])
+# ------------------------------------
+# See if the linker supports building shared libraries.
+AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS],
+[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ifelse([$1],[CXX],[
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ case $host_os in
+ aix4* | aix5*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+ ;;
+ cygwin* | mingw*)
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ *)
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+],[
+ runpath_var=
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=
+ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_AC_TAGVAR(archive_cmds, $1)=
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)=
+ _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+ _LT_AC_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_AC_TAGVAR(hardcode_automatic, $1)=no
+ _LT_AC_TAGVAR(module_cmds, $1)=
+ _LT_AC_TAGVAR(module_expsym_cmds, $1)=
+ _LT_AC_TAGVAR(always_export_symbols, $1)=no
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_AC_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_"
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ extract_expsyms_cmds=
+ # Just being paranoid about ensuring that cc_basename is set.
+ _LT_CC_BASENAME([$compiler])
+ case $host_os in
+ cygwin* | mingw* | pw32*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+ if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>/dev/null` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix3* | aix4* | aix5*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+ fi
+ ;;
+
+ amigaos*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+
+ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we can't use
+ # them.
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_AC_TAGVAR(always_export_symbols, $1)=no
+ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ interix3*)
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ linux*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ tmp_addflag=
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ esac
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test $supports_anon_versioning = yes; then
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ $echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then
+ runpath_var=
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix4* | aix5*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_AC_TAGVAR(archive_cmds, $1)=''
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ else
+ # We have old collect2
+ _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an empty executable.
+ _LT_AC_SYS_LIBPATH_AIX
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an empty executable.
+ _LT_AC_SYS_LIBPATH_AIX
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ # see comment about different semantics on the GNU ld section
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ bsdi[[45]]*)
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
+ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ darwin* | rhapsody*)
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
+ ;;
+ *) # Darwin 1.3 on
+ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ else
+ case ${MACOSX_DEPLOYMENT_TARGET} in
+ 10.[[012]])
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ ;;
+ 10.*)
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=''
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+ if test "$GCC" = yes ; then
+ output_verbose_link_cmd='echo'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ case $cc_basename in
+ xlc*)
+ output_verbose_link_cmd='echo'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ ;;
+ *)
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ fi
+ ;;
+
+ dgux*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ freebsd1*)
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | kfreebsd*-gnu | dragonfly*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+ fi
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ openbsd*)
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ else
+ case $host_os in
+ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ ;;
+ *)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ ;;
+
+ os2*)
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ else
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+ else
+ wlarc=''
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+ fi
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine linker options so we
+ # cannot just pass the convience library names through
+ # without $wl, iff we do not link with $LD.
+ # Luckily, gcc supports the same syntax we need for Sun Studio.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ case $wlarc in
+ '')
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;;
+ *)
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
+ esac ;;
+ esac
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7*)
+ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ fi
+])
+AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $_LT_AC_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+ $rm conftest*
+ printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1)
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1)
+ then
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $rm conftest*
+ AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)])
+ ;;
+ esac
+ fi
+ ;;
+esac
+])# AC_LIBTOOL_PROG_LD_SHLIBS
+
+
+# _LT_AC_FILE_LTDLL_C
+# -------------------
+# Be careful that the start marker always follows a newline.
+AC_DEFUN([_LT_AC_FILE_LTDLL_C], [
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# # ifdef __CYGWIN32__
+# # define __CYGWIN__ __CYGWIN32__
+# # endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+# __hDllInstance_base = hInst;
+# return TRUE;
+# }
+# /* ltdll.c ends here */
+])# _LT_AC_FILE_LTDLL_C
+
+
+# _LT_AC_TAGVAR(VARNAME, [TAGNAME])
+# ---------------------------------
+AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])])
+
+
+# old names
+AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL])
+AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+AC_DEFUN([AM_PROG_LD], [AC_PROG_LD])
+AC_DEFUN([AM_PROG_NM], [AC_PROG_NM])
+
+# This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])
+
+AC_DEFUN([LT_AC_PROG_GCJ],
+[AC_CHECK_TOOL(GCJ, gcj, no)
+ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)
+])
+
+AC_DEFUN([LT_AC_PROG_RC],
+[AC_CHECK_TOOL(RC, windres, no)
+])
+
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+# LT_AC_PROG_SED
+# --------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+AC_DEFUN([LT_AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f $lt_ac_sed && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test $lt_ac_count -gt 10 && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test $lt_ac_count -gt $lt_ac_max; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_MSG_RESULT([$SED])
+])
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..a4053db
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,1033 @@
+# generated automatically by aclocal 1.10 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_if(m4_PACKAGE_VERSION, [2.61],,
+[m4_fatal([this file was generated for autoconf 2.61.
+You have another version of autoconf. If you want to use that,
+you should regenerate the build system entirely.], [63])])
+
+# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+#
+# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=m4_default([$1], [0.9.0])
+ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ PKG_CONFIG=""
+ fi
+
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# Check to see whether a particular set of modules exists. Similar
+# to PKG_CHECK_MODULES(), but does not set variables or print errors.
+#
+#
+# Similar to PKG_CHECK_MODULES, make sure that the first instance of
+# this or PKG_CHECK_MODULES is called, or make sure to call
+# PKG_CHECK_EXISTS manually
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+ m4_ifval([$2], [$2], [:])
+m4_ifvaln([$3], [else
+ $3])dnl
+fi])
+
+
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
+m4_define([_PKG_CONFIG],
+[if test -n "$PKG_CONFIG"; then
+ if test -n "$$1"; then
+ pkg_cv_[]$1="$$1"
+ else
+ PKG_CHECK_EXISTS([$3],
+ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
+ [pkg_failed=yes])
+ fi
+else
+ pkg_failed=untried
+fi[]dnl
+])# _PKG_CONFIG
+
+# _PKG_SHORT_ERRORS_SUPPORTED
+# -----------------------------
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi[]dnl
+])# _PKG_SHORT_ERRORS_SUPPORTED
+
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+#
+#
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+ _PKG_SHORT_ERRORS_SUPPORTED
+ if test $_pkg_short_errors_supported = yes; then
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"`
+ else
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+ ifelse([$4], , [AC_MSG_ERROR(dnl
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT
+])],
+ [AC_MSG_RESULT([no])
+ $4])
+elif test $pkg_failed = untried; then
+ ifelse([$4], , [AC_MSG_FAILURE(dnl
+[The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://www.freedesktop.org/software/pkgconfig>.])],
+ [$4])
+else
+ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+ AC_MSG_RESULT([yes])
+ ifelse([$3], , :, [$3])
+fi[]dnl
+])# PKG_CHECK_MODULES
+
+# Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.10'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.10], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.10])dnl
+_AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], UPC, [depcc="$UPC" am_compiler_list=],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 3
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 12
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.60])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES(OBJC)],
+ [define([AC_PROG_OBJC],
+ defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $1 | $1:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+ [[\\/$]]* | ?:[[\\/]]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([acinclude.m4])
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 0000000..73c4c11
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,326 @@
+/* config.h.in. Generated from configure.in by autoheader. */
+
+/* Define to 1 if Amazon.com searching should be enabled */
+#undef AMAZON_SUPPORT
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+#undef CRAY_STACKSEG_END
+
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define to 1 if webcam support is enabled */
+#undef ENABLE_WEBCAM
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+#undef HAVE_ALLOCA_H
+
+/* Define if boolean is defined in <sys/types.h> */
+#undef HAVE_BOOLEAN
+
+/* Define if you have the CoreAudio API */
+#undef HAVE_COREAUDIO
+
+/* Define to 1 if you have the <crt_externs.h> header file. */
+#undef HAVE_CRT_EXTERNS_H
+
+/* Defines if your system has the crypt function */
+#undef HAVE_CRYPT
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#undef HAVE_DOPRNT
+
+/* Define to 1 if exempi is available */
+#undef HAVE_EXEMPI
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have libkcal */
+#undef HAVE_KCAL
+
+/* Define to 1 if you have libkcddb */
+#undef HAVE_KCDDB
+
+/* Define to 1 if you have the `btparse' library (-lbtparse). */
+#undef HAVE_LIBBTPARSE
+
+/* Define if you have libjpeg */
+#undef HAVE_LIBJPEG
+
+/* Define if you have libpng */
+#undef HAVE_LIBPNG
+
+/* Define if you have a working libpthread (will enable threaded code) */
+#undef HAVE_LIBPTHREAD
+
+/* Define if you have libz */
+#undef HAVE_LIBZ
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if your system needs _NSGetEnviron to set up the environment */
+#undef HAVE_NSGETENVIRON
+
+/* Define to 1 if poppler is available */
+#undef HAVE_POPPLER
+
+/* Define if you have res_init */
+#undef HAVE_RES_INIT
+
+/* Define if you have the res_init prototype */
+#undef HAVE_RES_INIT_PROTO
+
+/* Define to 1 if you have the <sal/config.h> header file. */
+#undef HAVE_SAL_CONFIG_H
+
+/* Define to 1 if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if strdup is declared in <string.h> */
+#undef HAVE_STRDUP_DECL
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have strlcat */
+#undef HAVE_STRLCAT
+
+/* Define if you have the strlcat prototype */
+#undef HAVE_STRLCAT_PROTO
+
+/* Define if you have strlcpy */
+#undef HAVE_STRLCPY
+
+/* Define if you have the strlcpy prototype */
+#undef HAVE_STRLCPY_PROTO
+
+/* Define to 1 if you have the `strlwr' function. */
+#undef HAVE_STRLWR
+
+/* Define to 1 if you have the `strupr' function. */
+#undef HAVE_STRUPR
+
+/* Define to 1 if you have the <sys/bitypes.h> header file. */
+#undef HAVE_SYS_BITYPES_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the TagLib library */
+#undef HAVE_TAGLIB
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if ushort is defined in <sys/types.h> */
+#undef HAVE_USHORT
+
+/* Define if you have the 'std::vector::at(std::size_t)' function */
+#undef HAVE_VECTOR_AT
+
+/* Define to 1 if you have the `vprintf' function. */
+#undef HAVE_VPRINTF
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#undef HAVE_VSNPRINTF
+
+/* Define to 1 if you have the yaz library */
+#undef HAVE_YAZ
+
+/* Define to 1 if IMDb searching should be enabled */
+#undef IMDB_SUPPORT
+
+/* Suffix for lib directories */
+#undef KDELIBSUFF
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* The size of `char', as computed by sizeof. */
+#undef SIZEOF_CHAR
+
+/* The size of `char *', as computed by sizeof. */
+#undef SIZEOF_CHAR_P
+
+/* The size of `int', as computed by sizeof. */
+#undef SIZEOF_INT
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of `short', as computed by sizeof. */
+#undef SIZEOF_SHORT
+
+/* The size of `size_t', as computed by sizeof. */
+#undef SIZEOF_SIZE_T
+
+/* The size of `unsigned char', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_CHAR
+
+/* The size of `unsigned int', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_INT
+
+/* The size of `unsigned long', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_LONG
+
+/* The size of `unsigned short', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_SHORT
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at runtime.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you want to compile CD-Text support */
+#undef USE_CDTEXT
+
+/* Version number of package */
+#undef VERSION
+
+/* Defined if compiling without arts */
+#undef WITHOUT_ARTS
+
+/*
+ * jpeg.h needs HAVE_BOOLEAN, when the system uses boolean in system
+ * headers and I'm too lazy to write a configure test as long as only
+ * unixware is related
+ */
+#ifdef _UNIXWARE
+#define HAVE_BOOLEAN
+#endif
+
+
+
+/*
+ * AIX defines FD_SET in terms of bzero, but fails to include <strings.h>
+ * that defines bzero.
+ */
+
+#if defined(_AIX)
+#include <strings.h>
+#endif
+
+
+
+#if defined(HAVE_NSGETENVIRON) && defined(HAVE_CRT_EXTERNS_H)
+# include <sys/time.h>
+# include <crt_externs.h>
+# define environ (*_NSGetEnviron())
+#endif
+
+
+
+#if !defined(HAVE_RES_INIT_PROTO)
+#ifdef __cplusplus
+extern "C" {
+#endif
+int res_init(void);
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
+
+#if !defined(HAVE_STRLCAT_PROTO)
+#ifdef __cplusplus
+extern "C" {
+#endif
+unsigned long strlcat(char*, const char*, unsigned long);
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
+
+#if !defined(HAVE_STRLCPY_PROTO)
+#ifdef __cplusplus
+extern "C" {
+#endif
+unsigned long strlcpy(char*, const char*, unsigned long);
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
+
+/*
+ * On HP-UX, the declaration of vsnprintf() is needed every time !
+ */
+
+#if !defined(HAVE_VSNPRINTF) || defined(hpux)
+#if __STDC__
+#include <stdarg.h>
+#include <stdlib.h>
+#else
+#include <varargs.h>
+#endif
+#ifdef __cplusplus
+extern "C"
+#endif
+int vsnprintf(char *str, size_t n, char const *fmt, va_list ap);
+#ifdef __cplusplus
+extern "C"
+#endif
+int snprintf(char *str, size_t n, char const *fmt, ...);
+#endif
+
+
+
+#if defined(__SVR4) && !defined(__svr4__)
+#define __svr4__ 1
+#endif
+
+
+/* type to use in place of socklen_t if not defined */
+#undef kde_socklen_t
+
+/* type to use in place of socklen_t if not defined (deprecated, use
+ kde_socklen_t) */
+#undef ksize_t
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000..80c34ee
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,723 @@
+dnl =======================================================
+dnl FILE: ./admin/configure.in.min
+dnl =======================================================
+
+dnl This file is part of the KDE libraries/packages
+dnl Copyright (C) 2001 Stephan Kulow (coolo@kde.org)
+
+dnl This file is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Library General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2 of the License, or (at your option) any later version.
+
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl Library General Public License for more details.
+
+dnl You should have received a copy of the GNU Library General Public License
+dnl along with this library; see the file COPYING.LIB. If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street, Fifh Floor,
+dnl Boston, MA 02110-1301, USA.
+
+# Original Author was Kalle@kde.org
+# I lifted it in some mater. (Stephan Kulow)
+# I used much code from Janos Farkas
+
+dnl Process this file with autoconf to produce a configure script.
+
+AC_INIT(acinclude.m4) dnl a source file from your sub dir
+
+dnl This is so we can use kde-common
+AC_CONFIG_AUX_DIR(admin)
+
+dnl This ksh/zsh feature conflicts with `cd blah ; pwd`
+unset CDPATH
+
+dnl Checking host/target/build systems, for make, install etc.
+AC_CANONICAL_SYSTEM
+dnl Perform program name transformation
+AC_ARG_PROGRAM
+
+dnl Automake doc recommends to do this only here. (Janos)
+AM_INIT_AUTOMAKE(tellico, 1.3.2.1) dnl searches for some needed programs
+
+KDE_SET_PREFIX
+
+dnl generate the config header
+AM_CONFIG_HEADER(config.h) dnl at the distribution this done
+
+dnl Checks for programs.
+AC_CHECK_COMPILERS
+AC_ENABLE_SHARED(yes)
+AC_ENABLE_STATIC(no)
+KDE_PROG_LIBTOOL
+
+dnl for NLS support. Call them in this order!
+dnl WITH_NLS is for the po files
+AM_KDE_WITH_NLS
+
+KDE_USE_QT(3.3)
+AC_PATH_KDE
+dnl =======================================================
+dnl FILE: configure.in.in
+dnl =======================================================
+
+#MIN_CONFIG(3.3)
+
+dnl PACKAGE set before
+
+dnl AM_KDE_MIN_VERSION(MIN-VERSION-MAJOR, MIN-VERSION-MINOR, MIN-VERSION-MICRO)
+dnl (taken from KMyMoney2)
+dnl
+AC_DEFUN([AM_KDE_MIN_VERSION],
+[
+ AC_MSG_CHECKING([for KDE version $1.$2.$3 or later])
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ save_CXXFLAGS=$CXXFLAGS
+ CXXFLAGS="$CXXFLAGS -I$srcdir $all_includes"
+ AC_TRY_COMPILE([
+ #include "kdeversion.h"
+ #if !( KDE_IS_VERSION( $1, $2, $3 ) )
+ #error KDE version does not meet minimum requirement
+ #endif
+ ], [], AC_MSG_RESULT(yes), AC_MSG_ERROR(no))
+ CXXFLAGS=$save_CXXFLAGS
+ AC_LANG_RESTORE
+])
+AM_KDE_MIN_VERSION(3,3,1)
+
+dnl CXXFLAGS="$NOOPT_CXXFLAGS" dnl __kdevelop[noopt]__
+dnl CFLAGS="$NOOPT_CFLAGS" dnl __kdevelop[noopt]__
+dnl CXXFLAGS="$CXXFLAGS $USE_EXCEPTIONS -DQT_NO_ASCII_CAST -DQT_NO_TRANSLATION" dnl __kdevelop[exc]__
+
+dnl KDE_NEED_FLEX dnl __kdevelop__
+dnl AC_PROG_YACC dnl __kdevelop__
+
+AC_MSG_CHECKING(for ushort in <sys/types.h>)
+AC_CACHE_VAL(bt_cv_type_ushort, [
+AC_TRY_COMPILE([
+#include <sys/types.h>
+],[
+ushort i;
+], bt_cv_type_ushort=yes, bt_cv_type_ushort=no)])
+AC_MSG_RESULT($bt_cv_type_ushort)
+if test "$bt_cv_type_ushort" = "yes" ; then
+ AC_DEFINE(HAVE_USHORT, 1, [Define if ushort is defined in <sys/types.h>])
+fi
+
+AC_MSG_CHECKING(for boolean in <sys/types.h>)
+AC_CACHE_VAL(bt_cv_type_boolean, [
+AC_TRY_COMPILE([
+#include <sys/types.h>
+],[
+boolean f;
+], bt_cv_type_boolean=yes, bt_cv_type_boolean=no)])
+AC_MSG_RESULT($bt_cv_type_boolean)
+if test "$bt_cv_type_boolean" = "yes" ; then
+ AC_DEFINE(HAVE_BOOLEAN, 1, [Define if boolean is defined in <sys/types.h>])
+fi
+
+AC_MSG_CHECKING(for strdup declaration in <string.h>)
+AC_EGREP_HEADER([strdup *\(], string.h, bt_cv_decl_strdup=yes, bt_cv_decl_strdup=no)
+AC_MSG_RESULT($bt_cv_decl_strdup)
+if test "$bt_cv_decl_strdup" = "yes" ; then
+ AC_DEFINE(HAVE_STRDUP_DECL, 1, [Define if strdup is declared in <string.h>])
+fi
+
+dnl Checks for library functions.
+AC_FUNC_ALLOCA
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS(strlwr strupr)
+
+AC_CHECK_SIZEOF(unsigned int, 4)
+AC_CHECK_SIZEOF(unsigned short, 2)
+AC_CHECK_SIZEOF(unsigned char, 1)
+AC_CHECK_SIZEOF(char, 1)
+
+AC_CACHE_CHECK([for std::vector::at(std::size_t)],
+ ac_cv_cxx_have_vector_at, [
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([
+ #include <vector>
+ ],[
+ std::vector<int> v(1);
+ v.at(0);
+ return 0;
+ ],ac_cv_cxx_have_vector_at=yes, ac_cv_cxx_have_vector_at=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_have_vector_at" = "yes"; then
+ AC_DEFINE(HAVE_VECTOR_AT,1,[Define if you have the 'std::vector::at(std::size_t)' function])
+fi
+
+KDE_FIND_PATH(xml2-config, XML_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin], [
+ AC_MSG_ERROR([[Could not find xml2-config anywhere, check ftp://xmlsoft.org/ for libxml >= 2.6.0. If you are using pre-packaged libraries, be sure to have the development files installed as well, which may be called libxml2-devel or something similar.]])
+])
+
+if test -n "$XML_CONFIG"; then
+ vers=`$XML_CONFIG --version 2>/dev/null | sed -e 's/libxml //' | awk 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
+ if test -n "$vers" && test "$vers" -ge 2006000
+ then
+ LIBXML_LIBS="`$XML_CONFIG --libs`"
+ LIBXML_RPATH=
+ for args in $LIBXML_LIBS; do
+ case $args in
+ -L*)
+ LIBXML_RPATH="$LIBXML_RPATH $args"
+ ;;
+ esac
+ done
+ LIBXML_RPATH=`echo $LIBXML_RPATH | sed -e "s/-L/-R/g"`
+ LIBXML_CFLAGS="`$XML_CONFIG --cflags`"
+ else
+ AC_MSG_ERROR([[You need at least libxml 2.6.0.]])
+ fi
+fi
+
+AC_SUBST(LIBXML_LIBS)
+AC_SUBST(LIBXML_CFLAGS)
+AC_SUBST(LIBXML_RPATH)
+
+AC_ARG_WITH([xml-catalog],
+ AC_HELP_STRING([--with-xml-catalog=CATALOG],
+ [path to XML catalog, default=without-xml-catalog]),,
+ [with_xml_catalog=no])
+
+if test x"$with_xml_catalog" != xno; then
+ KDE_FIND_PATH(xmlcatalog, XMLCATALOG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin], [
+ AC_MSG_ERROR([[Could not find xmlcatalog anywhere, check ftp://xmlsoft.org/ for libxml2 >= 2.4.23. If you are using pre-packaged libraries, be sure to have the utility files installed as well, which may be called libxml2-utils or something similar.]])
+ ])
+
+ AC_SUBST(XMLCATALOG)
+
+ if test x"$with_xml_catalog" = xyes; then
+ XML_CATALOG_FILE="/etc/xml/catalog"
+ else
+ XML_CATALOG_FILE="$with_xml_catalog"
+ fi
+
+ AC_MSG_CHECKING([for XML catalog])
+ if test -f "$XML_CATALOG_FILE"; then
+ AC_MSG_RESULT([$XML_CATALOG_FILE])
+ else
+ AC_MSG_ERROR([$XML_CATALOG_FILE not found])
+ fi
+
+ AC_SUBST(XML_CATALOG_FILE)
+fi
+
+KDE_FIND_PATH(xslt-config, XSLT_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin], [
+ AC_MSG_ERROR([[Could not find xslt-config anywhere, check ftp://xmlsoft.org/ for libxslt >= 1.0.19. If you are using pre-packaged libraries, be sure to have the development files installed as well, which may be called libxslt-devel or something similar.]])
+])
+
+if test -n "$XSLT_CONFIG"; then
+ vers=`$XSLT_CONFIG --version 2>/dev/null | awk 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
+ if test -n "$vers" && test "$vers" -ge 1000019; then
+ LIBXSLT_LIBS="`$XSLT_CONFIG --libs`"
+ LIBXSLT_RPATH=
+ for args in $LIBXSLT_LIBS; do
+ case $args in
+ -L*)
+ LIBXSLT_RPATH="$LIBXSLT_RPATH $args"
+ ;;
+ esac
+ done
+ LIBXSLT_RPATH=`echo $LIBXSLT_RPATH | sed -e "s/-L/-R/g"`
+ LIBXSLT_CFLAGS="`$XSLT_CONFIG --cflags`"
+ else
+ AC_MSG_ERROR([[You need at least libxslt 1.0.19.]])
+ fi
+fi
+
+AC_SUBST(LIBXSLT_LIBS)
+AC_SUBST(LIBXSLT_CFLAGS)
+AC_SUBST(LIBXSLT_RPATH)
+
+dnl ---------- TAGLIB CHECK ----------
+
+AC_DEFUN([AC_HAVE_TAGLIB],
+[
+ AC_DEFINE(HAVE_TAGLIB, 1, [Define to 1 if you have the TagLib library])
+ TAGLIB_CFLAGS=[`$TAGLIB_CONFIG --cflags`]
+ TAGLIB_LIBS=[`$TAGLIB_CONFIG --libs`]
+ TAGLIB_RPATH=
+ for args in $TAGLIB_LIBS; do
+ case $args in
+ -L*)
+ TAGLIB_RPATH="$TAGLIB_RPATH $args"
+ ;;
+ esac
+ done
+ TAGLIB_RPATH=`echo $TAGLIB_RPATH | sed -e "s/-L/-R/g"`
+])
+
+AC_DEFUN([AC_NO_TAGLIB],
+[
+ TAGLIB_CFLAGS=""
+ TAGLIB_LIBS=""
+ TAGLIB_RPATH=""
+])
+
+KDE_FIND_PATH(taglib-config, TAGLIB_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin])
+if test -n "$TAGLIB_CONFIG"; then
+ AC_HAVE_TAGLIB
+else
+ AC_NO_TAGLIB
+fi
+
+AC_SUBST(TAGLIB_CFLAGS)
+AC_SUBST(TAGLIB_LIBS)
+AC_SUBST(TAGLIB_RPATH)
+
+dnl ---------- END TAGLIB CHECK ----------
+
+dnl ---------- YAZ CHECK ----------
+
+AC_DEFUN([AC_HAVE_YAZ],
+[
+ AC_DEFINE(HAVE_YAZ, 1, [Define to 1 if you have the yaz library])
+ YAZ_CFLAGS=[`$YAZ_CONFIG --cflags`]
+ YAZ_LIBS=[`$YAZ_CONFIG --libs`]
+ YAZ_RPATH=
+ for args in $YAZ_LIBS; do
+ case $args in
+ -L*)
+ YAZ_RPATH="$YAZ_RPATH $args"
+ ;;
+ esac
+ done
+ YAZ_RPATH=`echo $YAZ_RPATH | sed -e "s/-L/-R/g"`
+])
+
+AC_DEFUN([AC_NO_YAZ],
+[
+ YAZ_CFLAGS=""
+ YAZ_LIBS=""
+ YAZ_RPATH=""
+])
+
+KDE_FIND_PATH(yaz-config, YAZ_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin])
+if test -n "$YAZ_CONFIG"; then
+ AC_HAVE_YAZ
+else
+ AC_NO_YAZ
+fi
+
+AC_SUBST(YAZ_CFLAGS)
+AC_SUBST(YAZ_LIBS)
+AC_SUBST(YAZ_RPATH)
+
+dnl ---------- END YAZ CHECK ----------
+
+dnl ---------- KCDDB CHECK ----------
+
+AC_ARG_ENABLE(libkcddb,
+ AC_HELP_STRING([--disable-libkcddb], [disable libkcddb, default=enable if found]),
+ [enable_libkcddb=$enableval],
+ [enable_libkcddb=yes]
+)
+
+if test x$enable_libkcddb = xyes; then
+
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+
+ac_save_libs="$LIBS"
+ac_save_cxxflags="$CXXFLAGS"
+
+LIBS="$LIBS $all_libraries -lkcddb"
+CXXFLAGS="$CXXFLAGS $all_includes"
+
+AC_MSG_CHECKING(for libkcddb library and headers)
+AC_TRY_LINK(
+ [
+#ifdef QT_NO_CAST_ASCII
+#undef QT_NO_CAST_ASCII
+#endif
+#include <libkcddb/cddb.h>
+ ],
+ [KCDDB::CDDB c],
+ [kcddb=yes],
+ [kcddb=no]
+)
+AC_MSG_RESULT($kcddb)
+
+LIBS="$ac_save_libs"
+CXXFLAGS="$ac_save_cxxflags"
+AC_LANG_RESTORE
+
+if test x$kcddb = xyes; then
+ AC_DEFINE(HAVE_KCDDB, 1, [Define to 1 if you have libkcddb])
+ KCDDB_LIBS="-lkcddb"
+else
+ KCDDB_LIBS=
+fi
+
+dnl -- kcddb was disabled ---
+else
+ KCDDB_LIBS=
+fi
+
+AC_SUBST(KCDDB_LIBS)
+
+dnl ---------- END KCDDB CHECK ----------
+
+dnl ---------- KCAL CHECK ----------
+
+AC_ARG_ENABLE(libkcal,
+ AC_HELP_STRING([--disable-libkcal], [disable libkcal, default=enable if found]),
+ [enable_libkcal=$enableval],
+ [enable_libkcal=yes]
+)
+
+if test x$enable_libkcal = xyes; then
+
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+
+ac_save_libs="$LIBS"
+ac_save_cxxflags="$CXXFLAGS"
+
+LIBS="$LIBS $all_libraries -lkcal"
+CXXFLAGS="$CXXFLAGS $all_includes"
+
+AC_MSG_CHECKING(for libkcal library and headers)
+AC_TRY_LINK(
+ [
+#ifdef QT_NO_CAST_ASCII
+#undef QT_NO_CAST_ASCII
+#endif
+#include <libkcal/todo.h>
+ ],
+ [KCal::Todo t],
+ [kcal=yes],
+ [kcal=no]
+)
+AC_MSG_RESULT($kcal)
+
+LIBS="$ac_save_libs"
+CXXFLAGS="$ac_save_cxxflags"
+AC_LANG_RESTORE
+
+if test x$kcal = xyes; then
+ AC_DEFINE(HAVE_KCAL, 1, [Define to 1 if you have libkcal])
+ KCAL_LIBS="-lkcal"
+else
+ KCAL_LIBS=
+fi
+
+dnl -- libkcal was disabled ---
+else
+ KCAL_LIBS=
+fi
+
+AC_SUBST(KCAL_LIBS)
+
+dnl ---------- END KCAL CHECK ----------
+
+AC_ARG_WITH([btparse],
+ AC_HELP_STRING([--with-btparse], [Link against libbtparse
+ as a shared lib (shared) or build it statically (static), default=static]),
+ [case "${withval}" in
+ shared) btparse=shared ;;
+ static) btparse=static ;;
+ yes) btparse=shared ;;
+ *) AC_MSG_ERROR(bad value ${withval} for --with-btparse) ;;
+ esac],
+ [btparse=static])
+
+AM_CONDITIONAL(USE_LIBBTPARSE, test x$btparse = xshared)
+
+if test x$btparse = xshared; then
+ KDE_CHECK_LIB(btparse, bt_initialize, [], [AC_MSG_ERROR(could not find libbtparse)])
+fi
+
+dnl ---------- AMAZON CHECK ----------
+
+AC_ARG_ENABLE(amazon,
+ AC_HELP_STRING([--disable-amazon], [disable Amazon.com searching, default=enable]),
+ [enable_amazon=$enableval],
+ [enable_amazon=yes]
+)
+
+if test x$enable_amazon = xyes; then
+ AC_DEFINE(AMAZON_SUPPORT, 1, [Define to 1 if Amazon.com searching should be enabled])
+fi
+
+dnl ---------- END AMAZON CHECK ----------
+
+dnl ---------- IMDB CHECK ----------
+
+AC_ARG_ENABLE(imdb,
+ AC_HELP_STRING([--disable-imdb], [disable IMDb searching, default=enable]),
+ [enable_imdb=$enableval],
+ [enable_imdb=yes]
+)
+
+if test x$enable_imdb = xyes; then
+ AC_DEFINE(IMDB_SUPPORT, 1, [Define to 1 if IMDb searching should be enabled])
+fi
+
+dnl ---------- END IMDB CHECK ----------
+
+dnl ---------- CDTEXT CHECK ----------
+dnl Not sure if my code for CDText works on all platforms, allow disabling
+
+AC_ARG_ENABLE(cdtext,
+ AC_HELP_STRING([--disable-cdtext], [disable cdtext, default=enable (Linux only)]),
+ [enable_cdtext=$enableval],
+ [enable_cdtext=yes]
+)
+
+if test x$enable_cdtext = xyes; then
+ AC_DEFINE(USE_CDTEXT, 1, [Define to 1 if you want to compile CD-Text support])
+fi
+
+dnl ---------- OpenOffice.org CHECK ----------
+
+AC_ARG_ENABLE(ooo,
+ AC_HELP_STRING([--enable-ooo], [enable support for OpenOffice.org, default=disable]),
+ [enable_ooo=$enableval],
+ [enable_ooo=no]
+)
+
+AM_CONDITIONAL(WITH_OOO, test x$enable_ooo = xyes)
+
+dnl Options: OpenOffice.org installation
+AC_ARG_WITH([ooo-dir],
+ AC_HELP_STRING([--with-ooo-dir=DIR],
+ [where the OpenOffice.org program files are installed]),
+ [ac_ooo_libdir="${withval}/program"
+ ac_ooo_datadir="${withval}/program"])
+AC_ARG_WITH([ooo-libdir],
+ AC_HELP_STRING([--with-ooo-libdir=DIR],
+ [where the OpenOffice.org program libraries are installed (<ooo-dir>/program)]),
+ [ac_ooo_libdir="${withval}"])
+AC_ARG_WITH([ooo-datadir],
+ AC_HELP_STRING([--with-ooo-datadir=DIR],
+ [where the OpenOffice.org data files are installed (<ooo-dir>/program)]),
+ [ac_ooo_datadir="${withval}"])
+
+dnl Options: OpenOffice.org SDK
+AC_ARG_WITH([ooo-sdk-dir],
+ AC_HELP_STRING([--with-ooo-sdk-dir=DIR],
+ [where the OpenOffice.org SDK is installed]),
+ [ac_ooo_sdk_bindir="${withval}/linux/bin"
+ ac_ooo_sdk_includes="${withval}/include"])
+AC_ARG_WITH([ooo-sdk-bindir],
+ AC_HELP_STRING([--with-ooo-sdk-bindir=DIR],
+ [where the OpenOffice.org SDK binaries are installed (<ooo-sdk-dir>/linux/bin)]),
+ [ac_ooo_sdk_bindir="${withval}"])
+AC_ARG_WITH([ooo-sdk-includes],
+ AC_HELP_STRING([--with-ooo-sdk-includes=DIR],
+ [where the OpenOffice.org SDK includes are installed (<ooo-sdk-dir>/include)]),
+ [ac_ooo_sdk_includes="${withval}"])
+
+if test x$enable_ooo = xyes; then
+
+dnl Check for UNO cpp binding
+KDE_FIND_PATH(cppumaker, CPPUMAKER, [$ac_ooo_sdk_bindir ${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin], [
+ AC_MSG_ERROR([[cppumaker not found, try '--with-ooo-sdk-dir=location_of_ODK']])
+])
+
+dnl Check for ODK includes
+ac_cppflags_safe="$CPPFLAGS"
+CPPFLAGS="-I$ac_ooo_sdk_includes"
+KDE_CHECK_HEADERS([sal/config.h],
+ [OFFICE_SDK_includes="$CPPFLAGS"],
+ AC_MSG_ERROR([[OpenOffice.org SDK include files not found, try '--with-ooo-sdk-dir=location_of_ODK']]))
+CPPFLAGS="$ac_cppflags_safe"
+
+dnl OpenOffice.org libraries
+if test -n "$ac_ooo_libdir" ; then
+ OFFICE_libadd="-L$ac_ooo_libdir"
+ OFFICE_libdir="$ac_ooo_libdir"
+fi
+
+dnl OpenOffice.org types.rdb
+AC_CHECK_FILE([$ac_ooo_datadir/types.rdb],
+ [OFFICE_registry="$ac_ooo_datadir"/types.rdb],
+ AC_MSG_ERROR([[types.rdb not found, try '--with-ooo-dir=OpenOffice.org_installation_path']]))
+
+dnl Substitute the values
+AC_SUBST(OFFICE_SDK_includes)
+AC_SUBST(OFFICE_libadd)
+AC_SUBST(OFFICE_libdir)
+AC_SUBST(OFFICE_registry)
+AC_SUBST(CPPUMAKER)
+
+fi
+CFLAGS="$CFLAGS -I\$(top_srcdir)/src/core"
+CXXFLAGS="$CXXFLAGS -I\$(top_srcdir)/src/core"
+
+dnl ---------- EXEMPI CHECK ----------
+
+AC_ARG_ENABLE(exempi,
+ AC_HELP_STRING([--disable-exempi], [disable exempi, default=enable if found]),
+ [enable_libexempi=$enableval],
+ [enable_libexempi=yes]
+)
+
+if test x$enable_libexempi = xyes; then
+ KDE_PKG_CHECK_MODULES(EXEMPI,
+ [exempi-2.0 >= 1.99.0],
+ [have_exempi=yes],
+ [have_exempi=no])
+ AC_SUBST(EXEMPI_LIBS)
+ AC_SUBST(EXEMPI_CFLAGS)
+else
+ have_exempi="no (disabled)"
+fi
+
+test "$have_exempi" = "yes" && AC_DEFINE(HAVE_EXEMPI, 1, [Define to 1 if exempi is available])
+
+
+dnl ---------- END EXEMPI CHECK ----------
+
+dnl ---------- POPPLER CHECK ----------
+
+AC_ARG_ENABLE(poppler,
+ AC_HELP_STRING([--disable-poppler], [disable poppler, default=enable if found]),
+ [enable_libpoppler=$enableval],
+ [enable_libpoppler=yes]
+)
+
+if test x$enable_libpoppler = xyes; then
+ KDE_PKG_CHECK_MODULES(POPPLER,
+ [poppler-qt >= 0.5],
+ [have_poppler=yes],
+ [have_poppler=no])
+ AC_SUBST(POPPLER_LIBS)
+ AC_SUBST(POPPLER_CFLAGS)
+else
+ have_poppler="no (disabled)"
+fi
+
+test "$have_poppler" = "yes" && AC_DEFINE(HAVE_POPPLER, 1, [Define to 1 if poppler is available])
+
+
+dnl ---------- END POPPLER CHECK ----------
+
+dnl ---------- WEBCAM CHECK ----------
+
+AC_ARG_ENABLE(webcam,
+ AC_HELP_STRING([--enable-webcam], [enable support for webcams (experimental), default=disable]),
+ [enable_webcam=$enableval],
+ [enable_webcam=no]
+)
+
+AM_CONDITIONAL(ENABLE_WEBCAM, test $enable_webcam = yes)
+if test x$enable_webcam = xyes; then
+ AC_DEFINE(ENABLE_WEBCAM, 1, [Define to 1 if webcam support is enabled])
+fi
+
+dnl ---------- END WEBCAM CHECK ----------
+KDE_CREATE_SUBDIRSLIST
+AC_CONFIG_FILES([ Makefile ])
+AC_CONFIG_FILES([ doc/Makefile ])
+AC_CONFIG_FILES([ doc/en/Makefile ])
+AC_CONFIG_FILES([ doc/fr/Makefile ])
+AC_CONFIG_FILES([ icons/Makefile ])
+AC_CONFIG_FILES([ po/Makefile ])
+AC_CONFIG_FILES([ src/Makefile ])
+AC_CONFIG_FILES([ src/barcode/Makefile ])
+AC_CONFIG_FILES([ src/cite/Makefile ])
+AC_CONFIG_FILES([ src/cite/ooo/Makefile ])
+AC_CONFIG_FILES([ src/collections/Makefile ])
+AC_CONFIG_FILES([ src/commands/Makefile ])
+AC_CONFIG_FILES([ src/core/Makefile ])
+AC_CONFIG_FILES([ src/fetch/Makefile ])
+AC_CONFIG_FILES([ src/fetch/scripts/Makefile ])
+AC_CONFIG_FILES([ src/gui/Makefile ])
+AC_CONFIG_FILES([ src/newstuff/Makefile ])
+AC_CONFIG_FILES([ src/rtf2html/Makefile ])
+AC_CONFIG_FILES([ src/tests/Makefile ])
+AC_CONFIG_FILES([ src/translators/Makefile ])
+AC_CONFIG_FILES([ src/translators/btparse/Makefile ])
+AC_CONFIG_FILES([ src/translators/pilotdb/Makefile ])
+AC_CONFIG_FILES([ src/translators/pilotdb/libflatfile/Makefile ])
+AC_CONFIG_FILES([ src/translators/pilotdb/libpalm/Makefile ])
+AC_CONFIG_FILES([ xslt/Makefile ])
+AC_CONFIG_FILES([ xslt/entry-templates/Makefile ])
+AC_CONFIG_FILES([ xslt/report-templates/Makefile ])
+AC_OUTPUT
+echo ""
+
+if test -z "$TAGLIB_CONFIG"; then
+ echo " *******************************************************"
+ echo " *** You don't have the TagLib headers on your system"
+ echo " *** Support for reading audio files is disabled"
+ echo " *******************************************************"
+ echo ""
+fi
+
+if test -z "$YAZ_CONFIG"; then
+ echo " *******************************************************"
+ echo " *** You don't have the yaz headers on your system"
+ echo " *** Support for z39.50 searches is disabled"
+ echo " *******************************************************"
+ echo ""
+fi
+
+if test x$kcddb != xyes; then
+ echo " *******************************************************"
+ echo " *** You don't have the kcddb headers on your system"
+ echo " *** Support for fetching CDDB info is disabled"
+ echo " *******************************************************"
+ echo ""
+fi
+
+if test x$kcal != xyes; then
+ echo " *******************************************************"
+ echo " *** You don't have the kcal headers on your system"
+ echo " *** Support for interacting with KOrganizer is disabled"
+ echo " *******************************************************"
+ echo ""
+fi
+
+if test x$have_exempi != xyes; then
+ echo " *******************************************************"
+ echo " *** You don't have the exempi headers on your system"
+ echo " *** Support for importing some PDF metadata is disabled"
+ echo " *******************************************************"
+ echo ""
+fi
+
+if test x$have_poppler != xyes; then
+ echo " *******************************************************"
+ echo " *** You don't have the poppler headers on your system"
+ echo " *** Support for searching inside PDF files is disabled"
+ echo " *******************************************************"
+ echo ""
+fi
+
+# Check if KDE_SET_PREFIX was called, and --prefix was passed to configure
+if test -n "$kde_libs_prefix" -a -n "$given_prefix"; then
+ # And if so, warn when they don't match
+ if test "$kde_libs_prefix" != "$given_prefix"; then
+ echo ""
+ echo "Warning: you chose to install this package in $given_prefix,"
+ echo "but KDE was found in $kde_libs_prefix."
+ echo "For this to work, you will need to tell KDE about the new prefix,"
+ echo "by ensuring that KDEDIRS contains it, e.g."
+ echo " export KDEDIRS=$given_prefix:$kde_libs_prefix"
+ echo "Then restart KDE."
+ echo ""
+ fi
+fi
+
+if test "$all_tests" = "bad"; then
+ if test ! "$cache_file" = "/dev/null"; then
+ echo ""
+ echo "Please remove the file $cache_file after changing your setup"
+ echo "so that configure will find the changes next time."
+ echo ""
+ fi
+else
+ echo ""
+ echo "Good - your configure finished. Start make now"
+ echo ""
+fi
diff --git a/configure.in.in b/configure.in.in
new file mode 100644
index 0000000..7b0479c
--- /dev/null
+++ b/configure.in.in
@@ -0,0 +1,552 @@
+#MIN_CONFIG(3.3)
+
+AM_INIT_AUTOMAKE(tellico,1.3.2.1)
+
+dnl AM_KDE_MIN_VERSION(MIN-VERSION-MAJOR, MIN-VERSION-MINOR, MIN-VERSION-MICRO)
+dnl (taken from KMyMoney2)
+dnl
+AC_DEFUN([AM_KDE_MIN_VERSION],
+[
+ AC_MSG_CHECKING([for KDE version $1.$2.$3 or later])
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ save_CXXFLAGS=$CXXFLAGS
+ CXXFLAGS="$CXXFLAGS -I$srcdir $all_includes"
+ AC_TRY_COMPILE([
+ #include "kdeversion.h"
+ #if !( KDE_IS_VERSION( $1, $2, $3 ) )
+ #error KDE version does not meet minimum requirement
+ #endif
+ ], [], AC_MSG_RESULT(yes), AC_MSG_ERROR(no))
+ CXXFLAGS=$save_CXXFLAGS
+ AC_LANG_RESTORE
+])
+AM_KDE_MIN_VERSION(3,3,1)
+
+dnl CXXFLAGS="$NOOPT_CXXFLAGS" dnl __kdevelop[noopt]__
+dnl CFLAGS="$NOOPT_CFLAGS" dnl __kdevelop[noopt]__
+dnl CXXFLAGS="$CXXFLAGS $USE_EXCEPTIONS -DQT_NO_ASCII_CAST -DQT_NO_TRANSLATION" dnl __kdevelop[exc]__
+
+dnl KDE_NEED_FLEX dnl __kdevelop__
+dnl AC_PROG_YACC dnl __kdevelop__
+
+AC_MSG_CHECKING(for ushort in <sys/types.h>)
+AC_CACHE_VAL(bt_cv_type_ushort, [
+AC_TRY_COMPILE([
+#include <sys/types.h>
+],[
+ushort i;
+], bt_cv_type_ushort=yes, bt_cv_type_ushort=no)])
+AC_MSG_RESULT($bt_cv_type_ushort)
+if test "$bt_cv_type_ushort" = "yes" ; then
+ AC_DEFINE(HAVE_USHORT, 1, [Define if ushort is defined in <sys/types.h>])
+fi
+
+AC_MSG_CHECKING(for boolean in <sys/types.h>)
+AC_CACHE_VAL(bt_cv_type_boolean, [
+AC_TRY_COMPILE([
+#include <sys/types.h>
+],[
+boolean f;
+], bt_cv_type_boolean=yes, bt_cv_type_boolean=no)])
+AC_MSG_RESULT($bt_cv_type_boolean)
+if test "$bt_cv_type_boolean" = "yes" ; then
+ AC_DEFINE(HAVE_BOOLEAN, 1, [Define if boolean is defined in <sys/types.h>])
+fi
+
+AC_MSG_CHECKING(for strdup declaration in <string.h>)
+AC_EGREP_HEADER([strdup *\(], string.h, bt_cv_decl_strdup=yes, bt_cv_decl_strdup=no)
+AC_MSG_RESULT($bt_cv_decl_strdup)
+if test "$bt_cv_decl_strdup" = "yes" ; then
+ AC_DEFINE(HAVE_STRDUP_DECL, 1, [Define if strdup is declared in <string.h>])
+fi
+
+dnl Checks for library functions.
+AC_FUNC_ALLOCA
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS(strlwr strupr)
+
+AC_CHECK_SIZEOF(unsigned int, 4)
+AC_CHECK_SIZEOF(unsigned short, 2)
+AC_CHECK_SIZEOF(unsigned char, 1)
+AC_CHECK_SIZEOF(char, 1)
+
+AC_CACHE_CHECK([for std::vector::at(std::size_t)],
+ ac_cv_cxx_have_vector_at, [
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([
+ #include <vector>
+ ],[
+ std::vector<int> v(1);
+ v.at(0);
+ return 0;
+ ],ac_cv_cxx_have_vector_at=yes, ac_cv_cxx_have_vector_at=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_have_vector_at" = "yes"; then
+ AC_DEFINE(HAVE_VECTOR_AT,1,[Define if you have the 'std::vector::at(std::size_t)' function])
+fi
+
+KDE_FIND_PATH(xml2-config, XML_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin], [
+ AC_MSG_ERROR([[Could not find xml2-config anywhere, check ftp://xmlsoft.org/ for libxml >= 2.6.0. If you are using pre-packaged libraries, be sure to have the development files installed as well, which may be called libxml2-devel or something similar.]])
+])
+
+if test -n "$XML_CONFIG"; then
+ vers=`$XML_CONFIG --version 2>/dev/null | sed -e 's/libxml //' | awk 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
+ if test -n "$vers" && test "$vers" -ge 2006000
+ then
+ LIBXML_LIBS="`$XML_CONFIG --libs`"
+ LIBXML_RPATH=
+ for args in $LIBXML_LIBS; do
+ case $args in
+ -L*)
+ LIBXML_RPATH="$LIBXML_RPATH $args"
+ ;;
+ esac
+ done
+ LIBXML_RPATH=`echo $LIBXML_RPATH | sed -e "s/-L/-R/g"`
+ LIBXML_CFLAGS="`$XML_CONFIG --cflags`"
+ else
+ AC_MSG_ERROR([[You need at least libxml 2.6.0.]])
+ fi
+fi
+
+AC_SUBST(LIBXML_LIBS)
+AC_SUBST(LIBXML_CFLAGS)
+AC_SUBST(LIBXML_RPATH)
+
+AC_ARG_WITH([xml-catalog],
+ AC_HELP_STRING([--with-xml-catalog=CATALOG],
+ [path to XML catalog, default=without-xml-catalog]),,
+ [with_xml_catalog=no])
+
+if test x"$with_xml_catalog" != xno; then
+ KDE_FIND_PATH(xmlcatalog, XMLCATALOG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin], [
+ AC_MSG_ERROR([[Could not find xmlcatalog anywhere, check ftp://xmlsoft.org/ for libxml2 >= 2.4.23. If you are using pre-packaged libraries, be sure to have the utility files installed as well, which may be called libxml2-utils or something similar.]])
+ ])
+
+ AC_SUBST(XMLCATALOG)
+
+ if test x"$with_xml_catalog" = xyes; then
+ XML_CATALOG_FILE="/etc/xml/catalog"
+ else
+ XML_CATALOG_FILE="$with_xml_catalog"
+ fi
+
+ AC_MSG_CHECKING([for XML catalog])
+ if test -f "$XML_CATALOG_FILE"; then
+ AC_MSG_RESULT([$XML_CATALOG_FILE])
+ else
+ AC_MSG_ERROR([$XML_CATALOG_FILE not found])
+ fi
+
+ AC_SUBST(XML_CATALOG_FILE)
+fi
+
+KDE_FIND_PATH(xslt-config, XSLT_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin], [
+ AC_MSG_ERROR([[Could not find xslt-config anywhere, check ftp://xmlsoft.org/ for libxslt >= 1.0.19. If you are using pre-packaged libraries, be sure to have the development files installed as well, which may be called libxslt-devel or something similar.]])
+])
+
+if test -n "$XSLT_CONFIG"; then
+ vers=`$XSLT_CONFIG --version 2>/dev/null | awk 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
+ if test -n "$vers" && test "$vers" -ge 1000019; then
+ LIBXSLT_LIBS="`$XSLT_CONFIG --libs`"
+ LIBXSLT_RPATH=
+ for args in $LIBXSLT_LIBS; do
+ case $args in
+ -L*)
+ LIBXSLT_RPATH="$LIBXSLT_RPATH $args"
+ ;;
+ esac
+ done
+ LIBXSLT_RPATH=`echo $LIBXSLT_RPATH | sed -e "s/-L/-R/g"`
+ LIBXSLT_CFLAGS="`$XSLT_CONFIG --cflags`"
+ else
+ AC_MSG_ERROR([[You need at least libxslt 1.0.19.]])
+ fi
+fi
+
+AC_SUBST(LIBXSLT_LIBS)
+AC_SUBST(LIBXSLT_CFLAGS)
+AC_SUBST(LIBXSLT_RPATH)
+
+dnl ---------- TAGLIB CHECK ----------
+
+AC_DEFUN([AC_HAVE_TAGLIB],
+[
+ AC_DEFINE(HAVE_TAGLIB, 1, [Define to 1 if you have the TagLib library])
+ TAGLIB_CFLAGS=[`$TAGLIB_CONFIG --cflags`]
+ TAGLIB_LIBS=[`$TAGLIB_CONFIG --libs`]
+ TAGLIB_RPATH=
+ for args in $TAGLIB_LIBS; do
+ case $args in
+ -L*)
+ TAGLIB_RPATH="$TAGLIB_RPATH $args"
+ ;;
+ esac
+ done
+ TAGLIB_RPATH=`echo $TAGLIB_RPATH | sed -e "s/-L/-R/g"`
+])
+
+AC_DEFUN([AC_NO_TAGLIB],
+[
+ TAGLIB_CFLAGS=""
+ TAGLIB_LIBS=""
+ TAGLIB_RPATH=""
+])
+
+KDE_FIND_PATH(taglib-config, TAGLIB_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin])
+if test -n "$TAGLIB_CONFIG"; then
+ AC_HAVE_TAGLIB
+else
+ AC_NO_TAGLIB
+fi
+
+AC_SUBST(TAGLIB_CFLAGS)
+AC_SUBST(TAGLIB_LIBS)
+AC_SUBST(TAGLIB_RPATH)
+
+dnl ---------- END TAGLIB CHECK ----------
+
+dnl ---------- YAZ CHECK ----------
+
+AC_DEFUN([AC_HAVE_YAZ],
+[
+ AC_DEFINE(HAVE_YAZ, 1, [Define to 1 if you have the yaz library])
+ YAZ_CFLAGS=[`$YAZ_CONFIG --cflags`]
+ YAZ_LIBS=[`$YAZ_CONFIG --libs`]
+ YAZ_RPATH=
+ for args in $YAZ_LIBS; do
+ case $args in
+ -L*)
+ YAZ_RPATH="$YAZ_RPATH $args"
+ ;;
+ esac
+ done
+ YAZ_RPATH=`echo $YAZ_RPATH | sed -e "s/-L/-R/g"`
+])
+
+AC_DEFUN([AC_NO_YAZ],
+[
+ YAZ_CFLAGS=""
+ YAZ_LIBS=""
+ YAZ_RPATH=""
+])
+
+KDE_FIND_PATH(yaz-config, YAZ_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin])
+if test -n "$YAZ_CONFIG"; then
+ AC_HAVE_YAZ
+else
+ AC_NO_YAZ
+fi
+
+AC_SUBST(YAZ_CFLAGS)
+AC_SUBST(YAZ_LIBS)
+AC_SUBST(YAZ_RPATH)
+
+dnl ---------- END YAZ CHECK ----------
+
+dnl ---------- KCDDB CHECK ----------
+
+AC_ARG_ENABLE(libkcddb,
+ AC_HELP_STRING([--disable-libkcddb], [disable libkcddb, default=enable if found]),
+ [enable_libkcddb=$enableval],
+ [enable_libkcddb=yes]
+)
+
+if test x$enable_libkcddb = xyes; then
+
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+
+ac_save_libs="$LIBS"
+ac_save_cxxflags="$CXXFLAGS"
+
+LIBS="$LIBS $all_libraries -lkcddb"
+CXXFLAGS="$CXXFLAGS $all_includes"
+
+AC_MSG_CHECKING(for libkcddb library and headers)
+AC_TRY_LINK(
+ [
+#ifdef QT_NO_CAST_ASCII
+#undef QT_NO_CAST_ASCII
+#endif
+#include <libkcddb/cddb.h>
+ ],
+ [KCDDB::CDDB c],
+ [kcddb=yes],
+ [kcddb=no]
+)
+AC_MSG_RESULT($kcddb)
+
+LIBS="$ac_save_libs"
+CXXFLAGS="$ac_save_cxxflags"
+AC_LANG_RESTORE
+
+if test x$kcddb = xyes; then
+ AC_DEFINE(HAVE_KCDDB, 1, [Define to 1 if you have libkcddb])
+ KCDDB_LIBS="-lkcddb"
+else
+ KCDDB_LIBS=
+fi
+
+dnl -- kcddb was disabled ---
+else
+ KCDDB_LIBS=
+fi
+
+AC_SUBST(KCDDB_LIBS)
+
+dnl ---------- END KCDDB CHECK ----------
+
+dnl ---------- KCAL CHECK ----------
+
+AC_ARG_ENABLE(libkcal,
+ AC_HELP_STRING([--disable-libkcal], [disable libkcal, default=enable if found]),
+ [enable_libkcal=$enableval],
+ [enable_libkcal=yes]
+)
+
+if test x$enable_libkcal = xyes; then
+
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+
+ac_save_libs="$LIBS"
+ac_save_cxxflags="$CXXFLAGS"
+
+LIBS="$LIBS $all_libraries -lkcal"
+CXXFLAGS="$CXXFLAGS $all_includes"
+
+AC_MSG_CHECKING(for libkcal library and headers)
+AC_TRY_LINK(
+ [
+#ifdef QT_NO_CAST_ASCII
+#undef QT_NO_CAST_ASCII
+#endif
+#include <libkcal/todo.h>
+ ],
+ [KCal::Todo t],
+ [kcal=yes],
+ [kcal=no]
+)
+AC_MSG_RESULT($kcal)
+
+LIBS="$ac_save_libs"
+CXXFLAGS="$ac_save_cxxflags"
+AC_LANG_RESTORE
+
+if test x$kcal = xyes; then
+ AC_DEFINE(HAVE_KCAL, 1, [Define to 1 if you have libkcal])
+ KCAL_LIBS="-lkcal"
+else
+ KCAL_LIBS=
+fi
+
+dnl -- libkcal was disabled ---
+else
+ KCAL_LIBS=
+fi
+
+AC_SUBST(KCAL_LIBS)
+
+dnl ---------- END KCAL CHECK ----------
+
+AC_ARG_WITH([btparse],
+ AC_HELP_STRING([--with-btparse], [Link against libbtparse
+ as a shared lib (shared) or build it statically (static), default=static]),
+ [case "${withval}" in
+ shared) btparse=shared ;;
+ static) btparse=static ;;
+ yes) btparse=shared ;;
+ *) AC_MSG_ERROR(bad value ${withval} for --with-btparse) ;;
+ esac],
+ [btparse=static])
+
+AM_CONDITIONAL(USE_LIBBTPARSE, test x$btparse = xshared)
+
+if test x$btparse = xshared; then
+ KDE_CHECK_LIB(btparse, bt_initialize, [], [AC_MSG_ERROR(could not find libbtparse)])
+fi
+
+dnl ---------- AMAZON CHECK ----------
+
+AC_ARG_ENABLE(amazon,
+ AC_HELP_STRING([--disable-amazon], [disable Amazon.com searching, default=enable]),
+ [enable_amazon=$enableval],
+ [enable_amazon=yes]
+)
+
+if test x$enable_amazon = xyes; then
+ AC_DEFINE(AMAZON_SUPPORT, 1, [Define to 1 if Amazon.com searching should be enabled])
+fi
+
+dnl ---------- END AMAZON CHECK ----------
+
+dnl ---------- IMDB CHECK ----------
+
+AC_ARG_ENABLE(imdb,
+ AC_HELP_STRING([--disable-imdb], [disable IMDb searching, default=enable]),
+ [enable_imdb=$enableval],
+ [enable_imdb=yes]
+)
+
+if test x$enable_imdb = xyes; then
+ AC_DEFINE(IMDB_SUPPORT, 1, [Define to 1 if IMDb searching should be enabled])
+fi
+
+dnl ---------- END IMDB CHECK ----------
+
+dnl ---------- CDTEXT CHECK ----------
+dnl Not sure if my code for CDText works on all platforms, allow disabling
+
+AC_ARG_ENABLE(cdtext,
+ AC_HELP_STRING([--disable-cdtext], [disable cdtext, default=enable (Linux only)]),
+ [enable_cdtext=$enableval],
+ [enable_cdtext=yes]
+)
+
+if test x$enable_cdtext = xyes; then
+ AC_DEFINE(USE_CDTEXT, 1, [Define to 1 if you want to compile CD-Text support])
+fi
+
+dnl ---------- OpenOffice.org CHECK ----------
+
+AC_ARG_ENABLE(ooo,
+ AC_HELP_STRING([--enable-ooo], [enable support for OpenOffice.org, default=disable]),
+ [enable_ooo=$enableval],
+ [enable_ooo=no]
+)
+
+AM_CONDITIONAL(WITH_OOO, test x$enable_ooo = xyes)
+
+dnl Options: OpenOffice.org installation
+AC_ARG_WITH([ooo-dir],
+ AC_HELP_STRING([--with-ooo-dir=DIR],
+ [where the OpenOffice.org program files are installed]),
+ [ac_ooo_libdir="${withval}/program"
+ ac_ooo_datadir="${withval}/program"])
+AC_ARG_WITH([ooo-libdir],
+ AC_HELP_STRING([--with-ooo-libdir=DIR],
+ [where the OpenOffice.org program libraries are installed (<ooo-dir>/program)]),
+ [ac_ooo_libdir="${withval}"])
+AC_ARG_WITH([ooo-datadir],
+ AC_HELP_STRING([--with-ooo-datadir=DIR],
+ [where the OpenOffice.org data files are installed (<ooo-dir>/program)]),
+ [ac_ooo_datadir="${withval}"])
+
+dnl Options: OpenOffice.org SDK
+AC_ARG_WITH([ooo-sdk-dir],
+ AC_HELP_STRING([--with-ooo-sdk-dir=DIR],
+ [where the OpenOffice.org SDK is installed]),
+ [ac_ooo_sdk_bindir="${withval}/linux/bin"
+ ac_ooo_sdk_includes="${withval}/include"])
+AC_ARG_WITH([ooo-sdk-bindir],
+ AC_HELP_STRING([--with-ooo-sdk-bindir=DIR],
+ [where the OpenOffice.org SDK binaries are installed (<ooo-sdk-dir>/linux/bin)]),
+ [ac_ooo_sdk_bindir="${withval}"])
+AC_ARG_WITH([ooo-sdk-includes],
+ AC_HELP_STRING([--with-ooo-sdk-includes=DIR],
+ [where the OpenOffice.org SDK includes are installed (<ooo-sdk-dir>/include)]),
+ [ac_ooo_sdk_includes="${withval}"])
+
+if test x$enable_ooo = xyes; then
+
+dnl Check for UNO cpp binding
+KDE_FIND_PATH(cppumaker, CPPUMAKER, [$ac_ooo_sdk_bindir ${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin], [
+ AC_MSG_ERROR([[cppumaker not found, try '--with-ooo-sdk-dir=location_of_ODK']])
+])
+
+dnl Check for ODK includes
+ac_cppflags_safe="$CPPFLAGS"
+CPPFLAGS="-I$ac_ooo_sdk_includes"
+KDE_CHECK_HEADERS([sal/config.h],
+ [OFFICE_SDK_includes="$CPPFLAGS"],
+ AC_MSG_ERROR([[OpenOffice.org SDK include files not found, try '--with-ooo-sdk-dir=location_of_ODK']]))
+CPPFLAGS="$ac_cppflags_safe"
+
+dnl OpenOffice.org libraries
+if test -n "$ac_ooo_libdir" ; then
+ OFFICE_libadd="-L$ac_ooo_libdir"
+ OFFICE_libdir="$ac_ooo_libdir"
+fi
+
+dnl OpenOffice.org types.rdb
+AC_CHECK_FILE([$ac_ooo_datadir/types.rdb],
+ [OFFICE_registry="$ac_ooo_datadir"/types.rdb],
+ AC_MSG_ERROR([[types.rdb not found, try '--with-ooo-dir=OpenOffice.org_installation_path']]))
+
+dnl Substitute the values
+AC_SUBST(OFFICE_SDK_includes)
+AC_SUBST(OFFICE_libadd)
+AC_SUBST(OFFICE_libdir)
+AC_SUBST(OFFICE_registry)
+AC_SUBST(CPPUMAKER)
+
+fi
+CFLAGS="$CFLAGS -I\$(top_srcdir)/src/core"
+CXXFLAGS="$CXXFLAGS -I\$(top_srcdir)/src/core"
+
+dnl ---------- EXEMPI CHECK ----------
+
+AC_ARG_ENABLE(exempi,
+ AC_HELP_STRING([--disable-exempi], [disable exempi, default=enable if found]),
+ [enable_libexempi=$enableval],
+ [enable_libexempi=yes]
+)
+
+if test x$enable_libexempi = xyes; then
+ KDE_PKG_CHECK_MODULES(EXEMPI,
+ [exempi-2.0 >= 1.99.0],
+ [have_exempi=yes],
+ [have_exempi=no])
+ AC_SUBST(EXEMPI_LIBS)
+ AC_SUBST(EXEMPI_CFLAGS)
+else
+ have_exempi="no (disabled)"
+fi
+
+test "$have_exempi" = "yes" && AC_DEFINE(HAVE_EXEMPI, 1, [Define to 1 if exempi is available])
+
+
+dnl ---------- END EXEMPI CHECK ----------
+
+dnl ---------- POPPLER CHECK ----------
+
+AC_ARG_ENABLE(poppler,
+ AC_HELP_STRING([--disable-poppler], [disable poppler, default=enable if found]),
+ [enable_libpoppler=$enableval],
+ [enable_libpoppler=yes]
+)
+
+if test x$enable_libpoppler = xyes; then
+ KDE_PKG_CHECK_MODULES(POPPLER,
+ [poppler-qt >= 0.5],
+ [have_poppler=yes],
+ [have_poppler=no])
+ AC_SUBST(POPPLER_LIBS)
+ AC_SUBST(POPPLER_CFLAGS)
+else
+ have_poppler="no (disabled)"
+fi
+
+test "$have_poppler" = "yes" && AC_DEFINE(HAVE_POPPLER, 1, [Define to 1 if poppler is available])
+
+
+dnl ---------- END POPPLER CHECK ----------
+
+dnl ---------- WEBCAM CHECK ----------
+
+AC_ARG_ENABLE(webcam,
+ AC_HELP_STRING([--enable-webcam], [enable support for webcams (experimental), default=disable]),
+ [enable_webcam=$enableval],
+ [enable_webcam=no]
+)
+
+AM_CONDITIONAL(ENABLE_WEBCAM, test $enable_webcam = yes)
+if test x$enable_webcam = xyes; then
+ AC_DEFINE(ENABLE_WEBCAM, 1, [Define to 1 if webcam support is enabled])
+fi
+
+dnl ---------- END WEBCAM CHECK ----------
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
new file mode 100644
index 0000000..53715b4
--- /dev/null
+++ b/doc/CMakeLists.txt
@@ -0,0 +1,4 @@
+ADD_SUBDIRECTORY( en )
+ADD_SUBDIRECTORY( fr )
+
+
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..88b7aa7
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,5 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+SUBDIRS = en fr
+
+####### kdevelop will overwrite this part!!! (end)############
diff --git a/doc/en/CMakeLists.txt b/doc/en/CMakeLists.txt
new file mode 100644
index 0000000..5cfedb9
--- /dev/null
+++ b/doc/en/CMakeLists.txt
@@ -0,0 +1,62 @@
+
+KDE_CREATE_HANDBOOK( index.docbook Xi
+ INSTALL_DESTINATION share/doc/kde/HTML/en/tellico
+ )
+
+########### install files ###############
+
+
+
+
+#original Makefile.am contents follow:
+
+######## kdevelop will overwrite this part!!! (begin)##########
+#
+#
+#EXTRA_DIST = \
+#advanced.docbook \
+#configuration.docbook \
+#details.docbook \
+#faqs.docbook \
+#fundamentals.docbook \
+#hacking.docbook \
+#importing-exporting.docbook \
+#index.docbook \
+#menus.docbook \
+#freebsd-doc-license.html \
+#entry-editor1.png \
+#entry-editor3.png \
+#entry-editor4.png \
+#entry-editor5.png \
+#fields-dialog.png \
+#general-options.png \
+#main-window.png \
+#print-options.png \
+#template-options.png \
+#source-options.png \
+#filter-dialog.png \
+#csv-dialog.png \
+#fetch-dialog.png \
+#export-options.png \
+#export-html.png \
+#export-csv.png \
+#export-pdb.png \
+#export-bibtex.png \
+#amazon-options.png \
+#z3950-options.png \
+#externalexec-options.png \
+#report-dialog.png \
+#loan-dialog.png \
+#loan-view.png \
+#filter-view.png \
+#openoffice-dialog.png \
+#sru-options.png \
+#imdb-options.png
+#
+#
+######## kdevelop will overwrite this part!!! (end)############
+#
+#KDE_LANG = en
+#KDE_DOCS = tellico
+#
+#CLEANFILES = *~
diff --git a/doc/en/Makefile.am b/doc/en/Makefile.am
new file mode 100644
index 0000000..adc1d6f
--- /dev/null
+++ b/doc/en/Makefile.am
@@ -0,0 +1,50 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+
+EXTRA_DIST = \
+advanced.docbook \
+configuration.docbook \
+details.docbook \
+faqs.docbook \
+fundamentals.docbook \
+hacking.docbook \
+importing-exporting.docbook \
+index.docbook \
+menus.docbook \
+freebsd-doc-license.html \
+entry-editor1.png \
+entry-editor3.png \
+entry-editor4.png \
+entry-editor5.png \
+fields-dialog.png \
+general-options.png \
+main-window.png \
+print-options.png \
+template-options.png \
+source-options.png \
+filter-dialog.png \
+csv-dialog.png \
+fetch-dialog.png \
+export-options.png \
+export-html.png \
+export-csv.png \
+export-pdb.png \
+export-bibtex.png \
+amazon-options.png \
+z3950-options.png \
+externalexec-options.png \
+report-dialog.png \
+loan-dialog.png \
+loan-view.png \
+filter-view.png \
+openoffice-dialog.png \
+sru-options.png \
+imdb-options.png
+
+
+####### kdevelop will overwrite this part!!! (end)############
+
+KDE_LANG = en
+KDE_DOCS = tellico
+
+CLEANFILES = *~
diff --git a/doc/en/advanced.docbook b/doc/en/advanced.docbook
new file mode 100644
index 0000000..61286ed
--- /dev/null
+++ b/doc/en/advanced.docbook
@@ -0,0 +1,151 @@
+<chapter id="advanced">
+<title>Advanced Usage</title>
+
+<sect1 id="command-line">
+<title>Command Line Options</title>
+
+<para>
+When running &appname; from the command line, there are several options for opening data files. They may be seen by running <userinput>tellico --help</userinput>.
+</para>
+
+<programlisting>
+Usage: tellico [Qt-options] [KDE-options] [options] [filename]
+
+Tellico - a collection manager for KDE
+
+Options:
+ --nofile Do not reopen the last open file
+ --bibtex Import &lt;filename&gt; as a bibtex file
+ --mods Import &lt;filename&gt; as a MODS file
+ --ris Import &lt;filename&gt; as a RIS file
+
+Arguments:
+ filename File to open
+</programlisting>
+
+</sect1>
+
+<sect1 id="dcop-interface">
+<title>&DCOP; Interface</title>
+
+<para>
+&appname; has a minimal &DCOP; interface, which can be used for scripting or interacting with a running application from the command-line. As with all &DCOP; calls, you need to specify the application you want to interface with, and the particular interface. The name of the &DCOP; application is <constant>tellico-&lt;pid&gt;</constant>, where <emphasis>&lt;pid&gt;</emphasis> is the process id of the running application.
+</para>
+
+<sect2 id="dcop-commands">
+<title>DCOP Commands</title>
+
+<para>Two &DCOP; objects are available in the tellico interface: <constant>tellico</constant> and <constant>collection</constant>.</para>
+
+<sect3 id="dcop-tellico">
+<title>The <constant>tellico</constant> Object</title>
+
+<para>The full list of &DCOP; commands in the <constant>tellico</constant> object is shown below:</para>
+
+<programlisting>
+bool importTellico(QString file, QString action)
+bool importBibtex(QString file, QString action)
+bool importMODS(QString file, QString action)
+bool importRIS(QString file, QString action)
+bool exportXML(QString file)
+bool exportZip(QString file)
+bool exportBibtex(QString file)
+bool exportHTML(QString file)
+bool exportCSV(QString file)
+bool exportPilotDB(QString file)
+QValueList&lt;long int&gt; selectedEntries()
+QValueList&lt;long int&gt; filteredEntries()
+void openFile(QString file)
+void setFilter(QString text)
+bool showEntry(long int id)
+</programlisting>
+
+<para>
+For the four import commands, the first argument is the file to import, and the second is the import action. Three actions are available: <emphasis>replace</emphasis>, <emphasis>append</emphasis>, and <emphasis>merge</emphasis>. Four file formats are supported for importing: Tellico XML files, Bibtex files, MODS files, and RIS files.
+</para>
+
+<para>
+The current open collection in &appname; may be exported to a file, in either Tellico XML format, Tellico ZIP format, Bibtex, HTML, comma-separated values (CSV), or the PilotDB format.
+</para>
+
+<para>A list of the entry IDs currently selected or being filtered is able to facilitate showing or updating entries in the view.</para>
+
+<para> A new data file may be opened by using the <command>openFile()</command> command. The full path must be specified.</para>
+
+<para>A new filter may be set using the <command>setFilter()</command> command, which is the equivalent of typing in the filter box in the main window.</para>
+
+<para>Given an entry ID, <command>showEntry()</command> will select that entry and show the entry details in the main window.</para>
+</sect3>
+
+<sect3 id="dcop-collection">
+<title>The <constant>collection</constant> Object</title>
+
+<para>The full list of &DCOP; commands in the <constant>collection</constant> object is shown below:</para>
+
+<programlisting>
+long int addEntry()
+bool removeEntry(long int entryID)
+QStringList values(QString fieldName)
+QStringList values(long int entryID,QString fieldName)
+QStringList bibtexKeys()
+QString bibtexKey(long int entryID)
+bool setFieldValue(long int entryID,QString fieldName,QString value)
+bool addFieldValue(long int entryID,QString fieldName,QString value)
+</programlisting>
+
+<para>
+A new empty entry may be created in the current collection using the <command>addEntry()</command> command. The return value is the entry ID, which can then be used to set the field values in the entry. An entry can be deleted from the collection by calling <command>removeEntry()</command>.
+</para>
+
+<para>
+Calling <command>values()</command> using just a field name will return all the values for that field for the currently selected entries. If no entries are selected, the return list is empty. If an entry ID is included in the command, the field values for that specific entry are returned.
+</para>
+
+<para>
+If the current collection is a bibliography, calling <command>bibtexKeys()</command> will return the Bibtex citation key for all selected entries. The bibtexKey for a specific entry may be found by using the <command>bibtekKey()</command> command.
+</para>
+
+<para>
+Entries can be edited directly with the &DCOP; interface. Given an entry ID, <command>setFieldValue()</command> will set the field value directly. To add a value, without affecting the existing values, use <command>addFieldValue()</command>. The new value gets appended to the end of the existing list.
+</para>
+</sect3>
+
+</sect2>
+
+<sect2 id="dcop-examples">
+<title>DCOP Examples</title>
+
+<para>
+Here are some examples for scripting &appname; using the &DCOP; interface. Since the <emphasis>pid</emphasis> must be known, the easiest way to include that in the shell command is like so: <userinput>dcop $(dcop | grep tellico) tellico</userinput>.
+</para>
+
+<screen width="40">
+<emphasis>Open a Bibtex file</emphasis>
+<prompt>%</prompt> <userinput>dcop $(dcop | grep tellico) tellico importBibtex ~/documents/reference.bib replace</userinput>
+<computeroutput>true</computeroutput>
+</screen>
+
+<screen width="40">
+<emphasis>Export a Bibtex file</emphasis>
+<prompt>%</prompt> <userinput>dcop $(dcop | grep tellico) tellico exportBibtex ~/documents/reference.bib</userinput>
+<computeroutput>true</computeroutput>
+</screen>
+
+<screen width="40">
+<emphasis>Echo the citation key of the current selection</emphasis>
+<prompt>%</prompt> <userinput>dcop $(dcop | grep tellico) collection bibtexKeys</userinput>
+<computeroutput>stephenson2004</computeroutput>
+</screen>
+
+<screen width="40">
+<emphasis>Add a new entry and set the title</emphasis>
+<prompt>%</prompt> <userinput>myid=`dcop $(dcop | grep tellico) collection addEntry`</userinput>
+<prompt>%</prompt> <userinput>dcop $(dcop | grep tellico) collection setFieldValue $myid title "My New Book"</userinput>
+<computeroutput>true</computeroutput>
+</screen>
+
+</sect2>
+
+</sect1>
+
+</chapter>
diff --git a/doc/en/amazon-options.png b/doc/en/amazon-options.png
new file mode 100644
index 0000000..549d122
--- /dev/null
+++ b/doc/en/amazon-options.png
Binary files differ
diff --git a/doc/en/configuration.docbook b/doc/en/configuration.docbook
new file mode 100644
index 0000000..3b7a617
--- /dev/null
+++ b/doc/en/configuration.docbook
@@ -0,0 +1,376 @@
+<chapter id="configuration">
+<title>Configuration</title>
+
+
+<para>
+The <interface>Configuration Dialog</interface> contains all the options for
+changing some of the default behaviour of &appname;.
+</para>
+
+<para>
+Clicking the <guibutton>Apply</guibutton> button <action>causes the changes to
+take effect immediately</action> without closing the dialog, while
+<guibutton>OK</guibutton> <action>applies the changes and closes the dialog</action>. <guibutton>Cancel</guibutton> closes the dialog, but any changes already made
+and applied will remain. The <guibutton>Default</guibutton> button <action>reverts
+the options</action> on the current page of the dialog to their default values,
+while <guibutton>Help</guibutton> <action>opens the &khelpcenter;</action> to
+the relative section of the &appname; manual.
+</para>
+
+<para>
+Some minor settings can only be changed by editing the configuration file itself. See <link linkend="hidden-options">Hidden Options</link>.
+</para>
+
+<sect1 id="general-options">
+<title><guilabel>General Options</guilabel></title>
+
+<screenshot>
+<screeninfo>The General Options Dialog</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="general-options.png"/></imageobject>
+<textobject><phrase>The General Options Dialog</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+The <guilabel>General Options</guilabel> control the general behavior. Images may be included
+in the data files, or saved separately in the &appname; application folder. Also, when &appname;
+is started, it can automatically reopen the last data file that was open. The
+<guilabel>Tip of the Day</guilabel> dialog contains helpful hints on using &appname;
+and appears at program startup. You may want to read through some of the hints and
+then disable the dialog.
+</para>
+
+<para>
+The <guilabel>Formatting Options</guilabel> control the level of automatic formatting
+that &appname; does. For examples, see the <link linkend="field-formatting">Field
+Formatting section</link>. Capitalization and formatting are distinct options, since
+a field may be capitalized without having the order of the words changed, and
+vice-versa. The auto-capitalization can be changed to ignore certain words.
+The automatic formatting includes grammatical articles in titles,
+along with prefixes and suffixes for personal names. The values are case-insensitive,
+and should be separated by a semi-colon.
+</para>
+
+<para>
+The formatting rules follow general English usage, which may not work for other languages.
+Articles are appended to the end of the title, with a comma. Personal names are formatted
+to have the last name first, followed by a comma, then the first name. Personal suffixes,
+such as Jr., are kept with the last name. Prefixes, such as <emphasis>von</emphasis>,
+are kept with the last name, but are ignored when the values are being sorted.</para>
+
+<informalexample><para><emphasis>John Q. von Public, III</emphasis> would become
+<emphasis>von Public, III, John Q.</emphasis> and <emphasis>Public</emphasis> would
+be used as the sort key.</para></informalexample>
+
+<para>
+Only single word prefixes are supported. If a name includes <emphasis>van der</emphasis>,
+for example, both <emphasis>van</emphasis> and <emphasis>der</emphasis> should be included
+in the surname prefix list. Articles ending with an apostrophe are supported for sorting
+order, as well.
+</para>
+
+<note><para>The actual values in the collection are <emphasis>not</emphasis> changed,
+only the visible text used for the interface. So the formatting options can be
+changed back and forth without affecting any of the data in the collection.</para></note>
+
+</sect1>
+
+<sect1 id="printing-options">
+<title><guilabel>Printing Options</guilabel></title>
+
+<para>
+&appname; uses an &xslt; template for creating &html;
+and then passes that to the &kde; printing service. Only the fields visible in the <link linkend="detailed-view">&detailed-view;</link> are printed. Furthermore, if the collection
+is being filtered, only the visible entries will be printed. Initially, a warning message
+is shown if filtering is active.
+</para>
+
+<screenshot>
+<screeninfo>The Print Options Dialog</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="print-options.png"/></imageobject>
+<textobject><phrase>The Print Options Dialog</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+The <guilabel>Printing Options</guilabel> allow you to change some formatting when
+printing a collection. If <guilabel>Format titles and names</guilabel> is checked,
+then the fields are <link linkend="field-formatting">auto-formatted</link> when they
+are printed. Otherwise, they are printed exactly as they were entered.
+</para>
+
+<para>
+The default printing stylesheet prints the collection with the field values in columns.
+<guilabel>Print field headers</guilabel> controls whether the field title is printed
+at the top of the column.
+</para>
+
+<para>
+In the printout, the entries will be sorted as they are in the <link linkend="detailed-view">&detailed-view;</link>. Additionally, they may be grouped as they are in the <link linkend="group-view">&group-view;</link>.
+</para>
+
+<para>
+Finally, when image fields are included in the printout, the images may be resized,
+while maintaining their aspect ratio. The maximum image width and height define the
+largest possible size of the image, though it will never be increased.
+</para>
+</sect1>
+
+<sect1 id="template-options">
+<title><guilabel>Template Options</guilabel></title>
+
+<para>
+The <link linkend="entry-view">&entry-view;</link> uses templates to show the field
+values. You can specify a different template for each collection type. Some templates,
+such as the <emphasis>Album</emphasis> or <emphasis>Video</emphasis> templates are
+for a specific collection type, and a short error message will appear in the
+&entry-view; if they are used for other types. The
+<guilabel>Preview</guilabel> button pops up a window to show you a preview of what the template looks like.
+Custom fonts and colors may be passed to the template, and all of the default templates
+will honor those settings. However, custom template may choose to ignore them.</para>
+
+<para>
+Additional templates may be installed directly, or downloaded from
+<ulink url="http://kde-files.org/index.php?amp;xcontentmode=676">kde-files.org</ulink> by clicking
+the <guilabel>Download</guilabel> button. Any templates installed by the user may also be deleted.
+Entry templates are saved in <filename class="directory">$<envar>KDEHOME</envar>/share/apps/tellico/entry-templates/</filename>.
+</para>
+
+<para>If you create a new template, please consider submitting it at <ulink url="http://kde-files.org/index.php?amp;xcontentmode=676">kde-files.org</ulink>!</para>
+
+<screenshot>
+<screeninfo>The Template Options Dialog</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="template-options.png"/></imageobject>
+<textobject><phrase>The Template Options Dialog</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+</sect1>
+
+<sect1 id="data-sources-options">
+<title><guilabel>Data Sources Options</guilabel></title>
+
+<para>
+&appname; can use various sources for importing data, which can be configured
+in the Data Sources Dialog. There are several available types of sources:</para>
+
+<itemizedlist>
+<listitem><para><link linkend="amazon-web-services">Amazon.com Web Services</link>,</para></listitem>
+<listitem><para>the <link linkend="imdb">Internet Movie Database</link>,</para></listitem>
+<listitem><para><link linkend="z3950">z39.50 servers</link>,</para></listitem>
+<listitem><para><link linkend="sru">SRU servers</link>,</para></listitem>
+<listitem><para><link linkend="entrez">Entrez (PubMed) databases</link>,</para></listitem>
+<listitem><para><link linkend="yahoo">Yahoo! Audio Search</link>,</para></listitem>
+<listitem><para><link linkend="animenfo">AnimeNfo.com</link>,</para></listitem>
+<listitem><para><link linkend="ibs">Internet Bookshop Italia</link>,</para></listitem>
+<listitem><para><link linkend="isbndb">ISBNdb.com</link>,</para></listitem>
+<listitem><para><link linkend="gcstarplugin"><application>GCstar</application> Plugins</link>,</para></listitem>
+<listitem><para><link linkend="bib-sources">arxiv.org</link>,</para></listitem>
+<listitem><para><link linkend="bib-sources">bibsonomy.org</link>,</para></listitem>
+<listitem><para><link linkend="bib-sources">citebase.org</link>,</para></listitem>
+<listitem><para><link linkend="bib-sources">crossref.org</link>,</para></listitem>
+<listitem><para><link linkend="externalexec">other external scripts or applications</link></para></listitem>
+</itemizedlist>
+
+<screenshot>
+<screeninfo>The Data Sources Options Dialog</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="source-options.png"/></imageobject>
+<textobject><phrase>The Data Sources Options Dialog</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+New sources may be added by clicking the <guibutton>New...</guibutton> button, while
+existing ones may be modified or deleted, using the <guibutton>Modify...</guibutton> or
+<guibutton>Remove</guibutton> buttons. The order of the sources, which shows up in the
+entry updating menus, can also be changed.
+</para>
+
+<para>
+Additional templates may be downloaded from the author's online repository by clicking
+the <guilabel>Download</guilabel> button. Those scripts are gpg-signed by the author to
+guard against dangerous scripts from unknown sources, which could cause damage to your system.
+</para>
+
+<warning>
+<para>
+Never install and run a script from an untrusted source. They are executed with the same permissions as the user,
+and as a result, could modify or delete files or otherwise mess up your system.
+</para>
+</warning>
+
+<para>
+Many of the data sources offer more information than the default fields in &appname;. Those other fields are
+shown on the right of the configuration box. If any of those fields are checked, they will be added
+to the collection when an entry is added from that source.
+</para>
+
+<sect2 id="amazon-web-services">
+<title>Amazon.com</title>
+
+<para>
+Using the Amazon Web Services, &appname; can search any of six different international sites operated by <ulink url="http://amazon.com">Amazon.com</ulink> for information: United States, United Kingdom, Germany, Japan,
+France, and Canada.
+</para>
+
+<screenshot>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="amazon-options.png"/></imageobject>
+</mediaobject>
+</screenshot>
+
+<para>
+Configuring each Amazon.com source involves three settings: the server location, image size, and associate's ID. Some information
+from <ulink url="http://amazon.com">Amazon.com</ulink> may include an image, such as a book or video cover. That image may be downloaded in three different sizes, depending on the item. The associate's ID must be used to access the Amazon.com Web Services, and is included in the links back to the item, as dictated by the license agreement for the use of the Amazon.com Web Services.
+</para>
+
+</sect2>
+
+<sect2 id="imdb">
+<title>Internet Movie Database</title>
+
+<para>
+The <ulink url="http://www.imdb.com">Internet Movie Database</ulink> provides information about movies and videos. When a search is conducted for a <emphasis>Person</emphasis>, if more than one possible result is returned, a dialog box is opened to allow you to select the correct person. The configuration options include setting the web server address and whether images are grabbed or not. Since IMDb can return a large number of cast members, you can limit
+that to a certain number.
+</para>
+
+<screenshot>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="imdb-options.png"/></imageobject>
+</mediaobject>
+</screenshot>
+
+</sect2>
+
+<sect2 id="z3950">
+<title>z39.50 Servers</title>
+
+<para>
+The <ulink url="http://www.cni.org/pub/NISO/docs/Z39.50-brochure/50.brochure.toc.html">z39.50 protocol</ulink> is used to access libraries and bibliographic information providers around the world. Lists of public z39.50 servers are <ulink url="http://www.indexdata.dk/targettest/">available from indexdata.dk</ulink>, among others. &appname; comes with
+several preset configurations for major libraries, or you can specify the connection information manually.</para>
+
+<para>&appname;
+is able to read data in the <acronym>MODS</acronym>, <acronym>USMARC</acronym>/<acronym>MARC21</acronym>, or <acronym>UNIMARC</acronym> format, using the <ulink url="http://www.indexdata.dk/yaz/">yaz library</ulink>.
+In addition, there is limited support for the <acronym>GRS-1</acronym> format.
+</para>
+
+<screenshot>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="z3950-options.png"/></imageobject>
+</mediaobject>
+</screenshot>
+
+
+<para>
+To use one of the preset libraries, check the box and then select the library. The other configuration entries will be disabled. If you need to set the information manually, uncheck the preset box.
+</para>
+
+<para>
+The default port for z39.50 access is 210, but some servers may use a different one. &appname; assumes the server uses the MARC-8 character encoding, unless configured otherwise. If an incorrect character encoding is used, an error message may appear on the program output, or possibly no entries are retrieved.
+</para>
+
+<para>
+Some servers require a username and password for access. &appname; can use and save that password, but be aware that is written to the &appname; configuration file in plain text and is not secure. For most public servers, the username and password fields may be left empty.
+</para>
+
+</sect2>
+
+<sect2 id="sru">
+<title>SRU Servers</title>
+
+<para>
+SRU stands for <ulink url="http://www.loc.gov/standards/sru/">Search/Retrieve via URL</ulink> and is a standard search protocol for
+Internet searches. Some libraries use it for providing access to their data catalogs. Among them, the <ulink url="http://www.loc.gov/z3950/lcserver.html#oppr">US Library of Congress</ulink> is probably
+the best known.
+</para>
+
+<screenshot>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="sru-options.png"/></imageobject>
+</mediaobject>
+</screenshot>
+
+</sect2>
+
+<sect2 id="entrez">
+<title>Entrez Databases</title>
+<para>
+<ulink url="http://www.ncbi.nlm.nih.gov/Entrez/">Entrez</ulink> is the integrated, text-based search and retrieval system used at the National Center for Biotechnology Information (NCBI). The most well-known Entrez database is <ulink url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=PubMed">PubMed</ulink>, the database for life science articles from many biological journals. At the moment, the only Entrez database supported by &appname; is PubMed.</para>
+</sect2>
+
+<sect2 id="yahoo">
+<title>Yahoo! Audio Search</title>
+<para>
+The <ulink url="http://audio.search.yahoo.com">Yahoo! Audio Search</ulink> may be used to search for music album information.
+</para>
+</sect2>
+
+<sect2 id="animenfo">
+<title>AnimeNfo.com</title>
+<para>
+<ulink url="http://www.animenfo.com">AnimeNfo</ulink> is a popular site for information on anime, or Japanese animation.
+</para>
+</sect2>
+
+<sect2 id="ibs">
+<title>Internet Bookstore Italia</title>
+<para>
+<ulink url="http://ibs.it">IBS, or Internet Bookstore Italia</ulink>, is an online Italian bookstore.
+</para>
+</sect2>
+
+<sect2 id="isbndb">
+<title>ISBNdb.com</title>
+<para>
+<ulink url="http://isbndb.com">ISBNdb.com</ulink> is an online book database, with data collection libraries around the world.
+</para>
+</sect2>
+
+<sect2 id="gcstarplugin">
+<title>GCstar Plugins</title>
+<para>
+If <application><ulink url="http://www.gcstar.org">GCstar</ulink></application> is installed, &appname; is able to take advantage of the wide range of search plugins available for GCstar. Depending on the collection type, various online resources are available for usage as a data source in &appname;
+</para>
+</sect2>
+
+<sect2 id="bib-sources">
+<title>Bibliographic Databases</title>
+<para>
+<ulink url="http://arxiv.org">arXiv.org</ulink>, <ulink url="http://bibsonomy.org">Bibsonomy</ulink>, <ulink url="http://citebase.org">Citebase</ulink>, and <ulink url="http://crossref.org">CrossRef</ulink> are online databases for academic articles and bibliographic information. For access to the CrossRef source, you must <ulink url="http://www.crossref.org/requestaccount/">request an account</ulink> and add your account information to the data source configuration.</para>
+</sect2>
+
+<sect2 id="externalexec">
+<title>External Scripts or Applications</title>
+<para>
+As an easier way for &appname; to integrate with third-party plugins, external scripts or applications may be used as an interface for searching other information sources. &appname; will execute a command, and pass the search terms as command-line options.
+</para>
+
+<para>Some scripts are distributed with &appname; itself. <ulink url="http://www.allocine.fr">Allocine.fr</ulink> is an online French bookstore. This data source requires <ulink url="http://python.org">Python</ulink> to be installed. The <ulink url="http://www.mcu.es">Spanish Ministry of Culture</ulink> is an online Spanish book database. This data source also required requires <ulink url="http://python.org">Python</ulink> to be installed. <ulink url="http://darkhorse.com">Dark Horse Comics</ulink> is a comic book publisher. This data source also requires <ulink url="http://python.org">Python</ulink>. <ulink url="http://boardgamegeek.com">BoardGameGeek</ulink> is a website with extensive data for board games, and the script requires <ulink url="http://www.ruby-lang.org">ruby</ulink>.
+</para>
+
+<screenshot>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="externalexec-options.png"/></imageobject>
+</mediaobject>
+</screenshot>
+
+<para>
+The collection type returned by the script must be set, along with the data format. Not only can &appname; import data from scripts that
+use the <link linkend="file-format">default &appname; &xml; format</link>, but it can also import other formats as well, such as bibtex.
+</para>
+
+<para>The full path to the application should be entered in the source options. Be aware that the application is executed on the system with the same permissions as the current user, so do not use scripts from untrusted sources. Check the boxes next to the search keys supported by the application, and enter the required command line options in the edit box. The search value will be inserted where <userinput>%1</userinput> appears.
+</para>
+
+<para>
+For updating entries already in the collection, the final checkbox and edit box are used to determine the command-line options. The entry fields used to find an update must be entered, in the same format as used for <emphasis><link linkend="dependent">Dependent</link></emphasis> fields.
+</para>
+</sect2>
+
+</sect1>
+
+</chapter>
diff --git a/doc/en/csv-dialog.png b/doc/en/csv-dialog.png
new file mode 100644
index 0000000..d2dbf93
--- /dev/null
+++ b/doc/en/csv-dialog.png
Binary files differ
diff --git a/doc/en/details.docbook b/doc/en/details.docbook
new file mode 100644
index 0000000..0ad0ddb
--- /dev/null
+++ b/doc/en/details.docbook
@@ -0,0 +1,547 @@
+<chapter id="details">
+<title>&appname; Details</title>
+
+<sect1 id="field-types">
+<title>Field Types</title>
+
+<para>
+Each collection may have an unlimited number of fields. &appname; supports
+eleven types of fields, which allow for a range of different data.
+</para>
+
+<sect2 id="line">
+<title>Simple Text</title>
+
+<para>
+The most basic field type is called <emphasis>Simple Text</emphasis>.
+No restrictions are placed on the field values, and the data entry
+widget is the standard line edit. This type is appropriate for fields
+which aren't expected to have long values, such as the author or the genre.
+</para>
+
+</sect2>
+<sect2 id="number">
+<title>Number</title>
+
+<para>
+The <emphasis>Number</emphasis> type is identical to the
+<emphasis>Simple Text</emphasis>, except that the data is restricted
+to being numerical. Entries will be sorted numerically in the column
+view if a <emphasis>Number</emphasis> field column is clicked. The
+standard line edit, with small arrow buttons for increasing or decreasing
+the value, is used for data entry. No formatting is ever
+applied.</para>
+
+</sect2>
+
+<sect2 id="url">
+<title>&URL;</title>
+
+<para>
+The <emphasis>&URL;</emphasis> type allows for links to other documents,
+using the standard &kde; file type associations for opening the linked
+documents. No validation is done on the actual value of a
+<emphasis>&URL;</emphasis> field, but non-valid links are not
+opened. The data entry is a line edit with a button for opening the
+standard File-Open dialog, but any &URL; may be used. Relative &URL;s are
+interpreted relative to the location of the data file, once it has been saved.
+</para>
+
+<para>
+In the <link linkend="entry-editor">&entry-editor;</link>,
+the label becomes the link, while in the <link linkend="entry-view">&entry-view;</link>, an actual
+hyperlink is used. This field type is convenient for linking to <acronym>PDF</acronym>
+files of bibliographic entries, or to movie reviews, for example. No
+formatting is ever applied.</para>
+
+<para>
+Relative &URL;s may also be used. They are interpreted relative to the location of the
+&appname; data file. In the <link linkend="entry-editor">&entry-editor;</link>, the line
+edit provides auto-completion for local file locations. If you want the &URL; from the &kde;
+File Selector Dialog Box to be interpreted relative to the document location, then an extended
+property for the &URL; field should be set to <emphasis>relative</emphasis> : <emphasis>true</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="para">
+<title>Paragraph</title>
+
+<para>
+For longer text fields, the <emphasis>Paragraph</emphasis> type offers
+a larger text edit area, and is always in its own category. A
+<emphasis>Paragraph</emphasis> field may not have multiple values, nor
+is it automatically formatted. It cannot be used for grouping. Abstracts, plot
+summaries, or reviews should be entered using this field type.</para>
+
+</sect2>
+
+<sect2 id="choice">
+<title>Choice</title>
+
+<para>
+When a field should be limited to a few preset values, a
+<emphasis>Choice</emphasis> type is used. The acceptable values are
+presented in a drop down box for selection. Obviously, multiple values
+are not applicable. Fields such as bibliography type or personal rating
+are <emphasis>Choice</emphasis>-type fields.</para>
+
+<para>Semi-colons should be used to separated the allowed values.</para>
+
+</sect2>
+
+<sect2 id="bool">
+<title>Checkbox</title>
+
+<para>
+For fields which take a yes or no value, the
+<emphasis>Checkbox</emphasis> type is available. By default, the field
+is toggled off. <emphasis>Checkbox</emphasis> fields are not formatted
+and are limited to single values. Internally, the field values are
+carried as <emphasis><constant>true</constant></emphasis> or
+<emphasis><constant>false</constant></emphasis>. Some examples are gift or loaned
+fields.</para>
+
+</sect2>
+
+<sect2 id="date">
+<title>Date</title>
+
+<para>
+A <emphasis>Date</emphasis> field can include a day, month, and year. The date is shown in the standard format of YYYY-MM-DD, which allows for easy sorting. The standard &kde; Date Selector may be used to choose the date with the mouse, or it may be entered directly. The field is not required to have non-empty values for the year, month, and day; only the year may be entered, for example. Multiple values are not allowed.
+</para>
+
+</sect2>
+
+<sect2 id="table">
+<title>Table</title>
+
+<para>
+<emphasis>Table</emphasis> fields hold a one or more columns of values.
+In the <link linkend="entry-editor">&entry-editor;</link>, the field is presented using a
+spreadsheet-like view, with numbered rows. When the last row is selected, an additional
+row is then added. Auto-completion is not available.
+This field is useful for a list of chapters in a book, scenes in a movie, or songs in an album.
+<emphasis>Table</emphasis> fields are always a category by themselves.
+</para>
+
+<para>
+The number of columns, up to a maximum of ten, is defined by adding a property to the field
+definition with the name <emphasis>columns</emphasis>. The columns may be labeled by right-clicking
+on the header, or by setting a field property named <emphasis>column1</emphasis>, etc.
+</para>
+
+<para>
+When using the &entry-editor; for <emphasis>Table</emphasis> fields, rows may be rearranged by dragging
+the mouse while holding the &Ctrl; button. A popup menu is also available by right-clicking on the table,
+which allows rows to be inserted or removed.
+</para>
+
+</sect2>
+
+<sect2 id="image">
+<title>Image</title>
+
+<para>
+<emphasis>Image</emphasis> fields hold an image, of any format supported by &kde;.
+Some of the typical ones include <acronym>PNG</acronym> or <acronym>JPEG</acronym>.
+The image can be saved inside the &appname; data file itself or in the application data
+directory. The standard &kde; File Selector is used, so you can use a &URL; or just a
+file available locally. Images can also be dragged from a file manager or browser.
+</para>
+
+</sect2>
+
+<sect2 id="rating">
+<title>Rating</title>
+
+<para>
+<emphasis>Rating</emphasis> fields show a number of stars to represent a numerical rating
+for an entry. By default, the rating is a maximum of five. The minimum and maximum may be
+changed by setting properties in the field definition in the &fields-dialog;, named
+<emphasis>minimum</emphasis> and <emphasis>maximum</emphasis>, respectively.
+</para>
+
+</sect2>
+
+<sect2 id="dependent">
+<title>Dependent</title>
+
+<para>
+The final field type is the <emphasis>Dependent</emphasis> field. You probably won't use
+this one very often. It is used to combine values from other fields using a format
+string in the field description. For example, if a <emphasis>Dependent</emphasis> field has
+a description of <userinput>%{title} %{year}</userinput>, then the value of that field will
+be the title, followed by the year. This field type is used primarily for the title field in
+the coin, stamp, trading card, and wine collections. Either the internal field name or the field title
+may be used in the description for formatting.
+The entry ID is also available using <userinput>%{id}</userinput>.
+</para>
+</sect2>
+
+</sect1>
+
+<sect1 id="collection-types">
+<title>Collection Types</title>
+
+<para>
+&appname; supports twelve specific collection types by default: books, bibliographic entries, comic books, videos, music, video games, trading cards, coins, stamps, wines, board games, and file catalogs. In addition, an empty generic collection template is available for any other collectibles. The default collections are only meant to include a general set of fields. You should add, modify, or delete them to fit your needs. The only requirement is that a collection should always have a <emphasis>Title</emphasis> field, so that the <link linkend="group-view">&group-view;</link> works correctly. For some collection types, that is just a <emphasis><link linkend="dependent">Dependent</link></emphasis> field combining two or more of the others.
+</para>
+
+<para>
+In general, there's no functional difference between the collection types. You could create a custom collection for your books just as easily as using the default book collection. But &appname; chooses icons based on collection type, and there may be some specialized functionality that is unique to a certain collection, so if you can, you should use the defaults. So, if you want to create a wine collection, but don't like any of the default fields, go ahead and create a default wine collection, then delete all the defaults. That way, &appname; still knows that it's a wine collection.
+</para>
+
+<sect2 id="book-collection">
+<title>Book Collections</title>
+<para>
+Book collections have 26 default fields:
+<emphasis>Title</emphasis>,
+<emphasis>Subtitle</emphasis>,
+<emphasis>Author</emphasis>,
+<emphasis>Binding</emphasis>,
+<emphasis>Purchase Date</emphasis>,
+<emphasis>Purchase Price</emphasis>,
+<emphasis>Publisher</emphasis>,
+<emphasis>Edition</emphasis>,
+<emphasis>Copyright Year</emphasis>,
+<emphasis>Publication Year</emphasis>,
+<emphasis>ISBN#</emphasis>,
+<emphasis>LCCN#</emphasis>,
+<emphasis>Pages</emphasis>,
+<emphasis>Language</emphasis>,
+<emphasis>Genre</emphasis>,
+<emphasis>Keywords</emphasis>,
+<emphasis>Series</emphasis>,
+<emphasis>Series Number</emphasis>,
+<emphasis>Condition</emphasis>,
+<emphasis>Signed</emphasis>,
+<emphasis>Read</emphasis>,
+<emphasis>Gift</emphasis>,
+<emphasis>Loaned</emphasis>,
+<emphasis>Rating</emphasis>,
+<emphasis>Front Cover</emphasis>, and
+<emphasis>Comments</emphasis>.
+</para>
+
+<para>
+The <emphasis>ISBN#</emphasis> field is special, since <acronym>ISBN</acronym> numbers are automatically formatted and the check-digit is calculated. &appname; recognizes the <acronym>ISBN</acronym> field if its internal field name is <emphasis>isbn</emphasis>. If you delete it, or need to add it to another type of collection, create the field with the title as <emphasis>ISBN</emphasis> and apply the change, then you can return and modify the title as you want. &appname; creates the internal name based on the initial title, but never changes it if the title is later updated.
+</para>
+
+</sect2>
+
+<sect2 id="bibliography">
+<title>Bibliographies</title>
+<para>
+Bibliographies have 25 default fields:
+<emphasis>Title</emphasis>,
+<emphasis>Entry Type</emphasis>,
+<emphasis>Author</emphasis>,
+<emphasis>Bibtex Key</emphasis>,
+<emphasis>Book Title</emphasis>,
+<emphasis>Editor</emphasis>,
+<emphasis>Organization</emphasis>,
+<emphasis>Publisher</emphasis>,
+<emphasis>ISBN#</emphasis>,
+<emphasis>Address</emphasis>,
+<emphasis>Edition</emphasis>,
+<emphasis>Pages</emphasis>,
+<emphasis>Year</emphasis>,
+<emphasis>Journal</emphasis>,
+<emphasis>Month</emphasis>,
+<emphasis>Number</emphasis>,
+<emphasis>How Published</emphasis>,
+<emphasis>Chapter</emphasis>,
+<emphasis>Series</emphasis>,
+<emphasis>Series</emphasis>,
+<emphasis>Volume</emphasis>,
+<emphasis>Cross-Reference</emphasis>, and
+<emphasis>Keywords</emphasis>,
+<emphasis>Abstract</emphasis>,
+<emphasis>Notes</emphasis>.
+</para>
+
+<para>
+Although bibliographic collections are not specifically linked to bibtex, the default set of fields is taken from a typical set of bibtex fields. When exporting to bibtex, an extended property called <emphasis>bibtex</emphasis> is used for each fields to define the corresponding bibtex field. If you add an additional field to a bibliography and want to export it to bibtex, be sure to set the <emphasis>bibtex</emphasis> extended property.
+</para>
+
+<para>
+&appname; does have some specialized functions for bibliographies. Bibtex string macros can be added, modified, or deleted from within &appname; and the bibtex export gives you the option of expanding the macros. Bibtex citations can be pushed to an external application such as <application>LyX</application> or <application>Kile</application> using the so-called <emphasis><link linkend="hidden-bibtex-options">lyxpipe</link></emphasis>.
+</para>
+
+<para>
+Book collections can be converted to bibliographies. Default bibtex fields are added, and the extended properties are set. This functionality exists primarily to convert old collections, before the bibliography type was separated from the book collection type.
+</para>
+</sect2>
+
+<sect2 id="comic-book-collection">
+<title>Comic Book Collections</title>
+<para>
+Comic book collections have 22 default fields:
+<emphasis>Title</emphasis>,
+<emphasis>Subtitle</emphasis>,
+<emphasis>Writer</emphasis>,
+<emphasis>Artist</emphasis>,
+<emphasis>Series</emphasis>,
+<emphasis>Issues</emphasis>,
+<emphasis>Publisher</emphasis>,
+<emphasis>Edition</emphasis>,
+<emphasis>Publication Year</emphasis>,
+<emphasis>Pages</emphasis>,
+<emphasis>Country</emphasis>,
+<emphasis>Language</emphasis>,
+<emphasis>Genre</emphasis>,
+<emphasis>Keywords</emphasis>,
+<emphasis>Condition</emphasis>,
+<emphasis>Purchase Date</emphasis>,
+<emphasis>Purchase Price</emphasis>,
+<emphasis>Signed</emphasis>,
+<emphasis>Gift</emphasis>,
+<emphasis>Loaned</emphasis>,
+<emphasis>Front Cover</emphasis>, and
+<emphasis>Comments</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="video-collection">
+<title>Video Collections</title>
+<para>
+Video collections have 30 default fields:
+<emphasis>Title</emphasis>,
+<emphasis>Medium</emphasis>,
+<emphasis>Production Year</emphasis>,
+<emphasis>Certification</emphasis>,
+<emphasis>Genre</emphasis>,
+<emphasis>Region</emphasis>,
+<emphasis>Nationality</emphasis>,
+<emphasis>Format</emphasis>,
+<emphasis>Cast</emphasis>,
+<emphasis>Director</emphasis>,
+<emphasis>Producer</emphasis>,
+<emphasis>Writer</emphasis>,
+<emphasis>Composer</emphasis>,
+<emphasis>Studio</emphasis>,
+<emphasis>Language Tracks</emphasis>,
+<emphasis>Subtitle Languages</emphasis>,
+<emphasis>Audio Tracks</emphasis>,
+<emphasis>Running Time</emphasis>,
+<emphasis>Aspect Ratio</emphasis>,
+<emphasis>Widescreen</emphasis>,
+<emphasis>Color Mode</emphasis>,
+<emphasis>Director's Cut</emphasis>,
+<emphasis>Plot Summary</emphasis>,
+<emphasis>Personal Rating</emphasis>,
+<emphasis>Purchase Date</emphasis>,
+<emphasis>Purchase Price</emphasis>,
+<emphasis>Gift</emphasis>,
+<emphasis>Loaned</emphasis>,
+<emphasis>Cover</emphasis>, and
+<emphasis>Comments</emphasis>.
+</para>
+
+<para>
+The <emphasis>Cast</emphasis> field is a <link linkend="table">table</link> with two columns, and the name of the actor is intended to be in the first column, with their role in the second. The <emphasis>Running Time</emphasis> is meant to be in minutes, though you can change that, of course.
+</para>
+</sect2>
+
+<sect2 id="music-collection">
+<title>Music Collections</title>
+<para>
+Music collections have 15 default fields:
+<emphasis>Title</emphasis>,
+<emphasis>Medium</emphasis>,
+<emphasis>Artist</emphasis>,
+<emphasis>Label</emphasis>,
+<emphasis>Year</emphasis>,
+<emphasis>Genre</emphasis>,
+<emphasis>Tracks</emphasis>,
+<emphasis>Rating</emphasis>,
+<emphasis>Purchase Date</emphasis>,
+<emphasis>Purchase Price</emphasis>,
+<emphasis>Gift</emphasis>,
+<emphasis>Loaned</emphasis>,
+<emphasis>Keywords</emphasis>,
+<emphasis>Cover</emphasis>, and
+<emphasis>Comments</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="game-collection">
+<title>Game Collections</title>
+<para>
+Video game collections have 16 default fields:
+<emphasis>Title</emphasis>,
+<emphasis>Platform</emphasis>,
+<emphasis>Genre</emphasis>,
+<emphasis>Release Year</emphasis>,
+<emphasis>Publisher</emphasis>,
+<emphasis>Developer</emphasis>,
+<emphasis>ESRB Rating</emphasis>,
+<emphasis>Description</emphasis>,
+<emphasis>Personal Rating</emphasis>,
+<emphasis>Completed</emphasis>,
+<emphasis>Purchase Date</emphasis>,
+<emphasis>Purchase Price</emphasis>,
+<emphasis>Gift</emphasis>,
+<emphasis>Loaned</emphasis>,
+<emphasis>Cover</emphasis>, and
+<emphasis>Comments</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="card-collection">
+<title>Card Collections</title>
+<para>
+Trading card collections have 17 default fields:
+<emphasis>Title</emphasis>,
+<emphasis>Player</emphasis>,
+<emphasis>Team</emphasis>,
+<emphasis>Brand</emphasis>,
+<emphasis>Card Number</emphasis>,
+<emphasis>Year</emphasis>,
+<emphasis>Series</emphasis>,
+<emphasis>Card Type</emphasis>,
+<emphasis>Purchase Date</emphasis>,
+<emphasis>Purchase Price</emphasis>,
+<emphasis>Location</emphasis>,
+<emphasis>Gift</emphasis>,
+<emphasis>Keywords</emphasis>,
+<emphasis>Quantity</emphasis>,
+<emphasis>Front Image</emphasis>,
+<emphasis>Back Image</emphasis>, and
+<emphasis>Comments</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="coin-collection">
+<title>Coin Collections</title>
+<para>
+Coin collections have 16 default fields:
+<emphasis>Title</emphasis>,
+<emphasis>Type</emphasis>,
+<emphasis>Denomination</emphasis>,
+<emphasis>Year</emphasis>,
+<emphasis>Mint Mark</emphasis>,
+<emphasis>Country</emphasis>,
+<emphasis>Coin Set</emphasis>,
+<emphasis>Grade</emphasis>,
+<emphasis>Grading Service</emphasis>,
+<emphasis>Purchase Date</emphasis>,
+<emphasis>Purchase Price</emphasis>,
+<emphasis>Location</emphasis>,
+<emphasis>Gift</emphasis>,
+<emphasis>Obverse</emphasis>,
+<emphasis>Reverse</emphasis>, and
+<emphasis>Comments</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="stamp-collection">
+<title>Stamp Collections</title>
+<para>
+Stamp ollections have 18 default fields:
+<emphasis>Title</emphasis>,
+<emphasis>Description</emphasis>,
+<emphasis>Denomination</emphasis>,
+<emphasis>Country</emphasis>,
+<emphasis>Issue Year</emphasis>,
+<emphasis>Color</emphasis>,
+<emphasis>Scott#</emphasis>,
+<emphasis>Grade</emphasis>,
+<emphasis>Cancelled</emphasis>,
+<emphasis>Hinged</emphasis>,
+<emphasis>Centering</emphasis>,
+<emphasis>Gummed</emphasis>,
+<emphasis>Purchase Date</emphasis>,
+<emphasis>Purchase Price</emphasis>,
+<emphasis>Location</emphasis>,
+<emphasis>Gift</emphasis>,
+<emphasis>Image</emphasis>, and
+<emphasis>Comments</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="wine-collection">
+<title>Wine Collections</title>
+<para>
+Wine collections have 15 default fields.
+<emphasis>Title</emphasis>,
+<emphasis>Producer</emphasis>,
+<emphasis>Appellation</emphasis>,
+<emphasis>Varietal</emphasis>,
+<emphasis>Type</emphasis>,
+<emphasis>Country</emphasis>,
+<emphasis>Purchase Date</emphasis>,
+<emphasis>Purchase Price</emphasis>,
+<emphasis>Location</emphasis>,
+<emphasis>Quantity</emphasis>,
+<emphasis>Drink By</emphasis>,
+<emphasis>Rating</emphasis>,
+<emphasis>Gift</emphasis>,
+<emphasis>Label Image</emphasis>, and
+<emphasis>Comments</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="board-game-collection">
+<title>Board Game Collections</title>
+<para>
+Board game collections have 15 default fields.
+<emphasis>Title</emphasis>,
+<emphasis>Genre</emphasis>,
+<emphasis>Mechanism</emphasis>,
+<emphasis>Release Year</emphasis>,
+<emphasis>Publisher</emphasis>,
+<emphasis>Designer</emphasis>,
+<emphasis>Number of Players</emphasis>,
+<emphasis>Description</emphasis>,
+<emphasis>Rating</emphasis>,
+<emphasis>Purchase Date</emphasis>,
+<emphasis>Purchase Price</emphasis>,
+<emphasis>Gift</emphasis>,
+<emphasis>Loaned</emphasis>,
+<emphasis>Cover</emphasis>, and
+<emphasis>Comments</emphasis>,
+</para>
+
+</sect2>
+
+<sect2 id="file-catalog">
+<title>File Catalogs</title>
+<para>
+File catalogs have 13 default fields.
+<emphasis>Name</emphasis>,
+<emphasis>URL</emphasis>,
+<emphasis>Description</emphasis>,
+<emphasis>Volume</emphasis>,
+<emphasis>Mimetype</emphasis>,
+<emphasis>Size</emphasis>,
+<emphasis>Permissions</emphasis>,
+<emphasis>Owner</emphasis>,
+<emphasis>Group</emphasis>,
+<emphasis>Created</emphasis>,
+<emphasis>Modified</emphasis>,
+<emphasis>Meta Info</emphasis>, and
+<emphasis>Icon</emphasis>,
+</para>
+
+</sect2>
+
+<sect2 id="custom-collection">
+<title>Custom Collections</title>
+<para>
+Custom collections have one default field, the <emphasis>Title</emphasis>. They should be used when the collectible item is not one of the default types.
+</para>
+
+</sect2>
+
+</sect1>
+
+</chapter>
diff --git a/doc/en/entry-editor1.png b/doc/en/entry-editor1.png
new file mode 100644
index 0000000..c371d9d
--- /dev/null
+++ b/doc/en/entry-editor1.png
Binary files differ
diff --git a/doc/en/entry-editor3.png b/doc/en/entry-editor3.png
new file mode 100644
index 0000000..38ff114
--- /dev/null
+++ b/doc/en/entry-editor3.png
Binary files differ
diff --git a/doc/en/entry-editor4.png b/doc/en/entry-editor4.png
new file mode 100644
index 0000000..e9bac5b
--- /dev/null
+++ b/doc/en/entry-editor4.png
Binary files differ
diff --git a/doc/en/entry-editor5.png b/doc/en/entry-editor5.png
new file mode 100644
index 0000000..73c9773
--- /dev/null
+++ b/doc/en/entry-editor5.png
Binary files differ
diff --git a/doc/en/export-bibtex.png b/doc/en/export-bibtex.png
new file mode 100644
index 0000000..0bf9cfb
--- /dev/null
+++ b/doc/en/export-bibtex.png
Binary files differ
diff --git a/doc/en/export-csv.png b/doc/en/export-csv.png
new file mode 100644
index 0000000..f2c21dd
--- /dev/null
+++ b/doc/en/export-csv.png
Binary files differ
diff --git a/doc/en/export-html.png b/doc/en/export-html.png
new file mode 100644
index 0000000..617e52e
--- /dev/null
+++ b/doc/en/export-html.png
Binary files differ
diff --git a/doc/en/export-options.png b/doc/en/export-options.png
new file mode 100644
index 0000000..881ddc5
--- /dev/null
+++ b/doc/en/export-options.png
Binary files differ
diff --git a/doc/en/export-pdb.png b/doc/en/export-pdb.png
new file mode 100644
index 0000000..067a3d0
--- /dev/null
+++ b/doc/en/export-pdb.png
Binary files differ
diff --git a/doc/en/externalexec-options.png b/doc/en/externalexec-options.png
new file mode 100644
index 0000000..bb5448f
--- /dev/null
+++ b/doc/en/externalexec-options.png
Binary files differ
diff --git a/doc/en/faqs.docbook b/doc/en/faqs.docbook
new file mode 100644
index 0000000..f03c2ae
--- /dev/null
+++ b/doc/en/faqs.docbook
@@ -0,0 +1,257 @@
+<chapter id="faqs">
+<title>Questions and Answers</title>
+
+<!-- (OPTIONAL but recommended) This chapter should include all of the silly
+(and not-so-silly) newbie questions that fill up your mailbox. This chapter
+should be reserved for BRIEF questions and answers! If one question uses more
+than a page or so then it should probably be part of the
+"Using this Application" chapter instead. You should use links to
+cross-reference questions to the parts of your documentation that answer them.
+This is also a great place to provide pointers to other FAQ's if your users
+must do some complicated configuration on other programs in order for your
+application work. -->
+
+<qandaset id="faqlist">
+
+<qandaentry>
+<question>
+<para>How do I start the program?</para>
+</question>
+<answer>
+
+<para>After downloading and unpacking &appname;, run
+<userinput><command>configure</command>
+<option>--disable-debug</option>
+<option>--enable-final</option></userinput> to configure
+everything. You may need to modify some of the command line
+options. After that, running
+<userinput><command>make</command></userinput> will compile
+&appname;. Then, as root, run <userinput><command>make
+install</command></userinput> to install everything. Being root is
+only necessary if you install somewhere where you don't have write
+permissions. The command line to start &appname; is
+<userinput><command>tellico</command></userinput>. If you install one
+of the pre-packaged binaries, a menu item will be inserted for
+&appname;. </para>
+
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question>
+<para>How do I enter multiple authors?</para>
+</question>
+<answer>
+
+<para>Author names should be separated by a semi-colon, like so:
+<userinput>Brian W. Kernighan; Dennis M. Ritchie</userinput>. Don't
+include the word "and" or anything similar, even if you have 20
+authors. If you have the auto-format option checked, then the last
+name will automatically be shown first for each author.</para>
+
+<para>Other properties which allow multiple values, like "genre" and
+"keywords", are entered in the same way, with a semi-colon (;)
+separating each value.</para>
+
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question>
+<para>Can I modify what the printed page looks like?</para>
+</question>
+<answer>
+
+<para>Yes, most certainly. Find the file <filename>tellico-printing.xsl</filename> which
+ should be in the $<envar>KDEDIR</envar>/share/apps/tellico/ directory. You can copy
+ that to $<envar>KDEHOME</envar>/share/apps/tellico/ for personal modifications.
+ You'll have to know <ulink
+ url="http://www.w3.org/TR/xslt">&xslt;</ulink>, but modifying that file
+ is how you change the printing layout. &html; is generated from the
+ file, and the easiest way to change the appearance of the printout is
+ to modify the CSS in the top portion. Feel free to email me with questions. Any alternate &xslt; printing files will be available on <ulink
+ url="&homepage;">the &appname; website</ulink>.</para>
+
+<para>Be aware that the <filename>tellico-printing.xsl</filename> references another file, <filename>tellico-common.xsl</filename>, that contains some common &xslt; templates. If you copy
+<filename>tellico-printing.xsl</filename> to $<envar>KDEHOME</envar>, you must either modify the &lt;xsl:import&gt; element to point to the actual location of the <filename>tellico-common.xsl</filename> file or copy the common file as well.
+</para>
+</answer>
+</qandaentry>
+<qandaentry>
+<question>
+<para>How do I group by a property other than the ones listed in the toolbar?</para>
+</question>
+<answer>
+<para>
+To allow grouping by a field which doesn't allow grouping by default, check the
+"Allow Grouping" box for that particular field in the "Collection Fields" dialog.
+</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question><para>Why does all that gobbledy-gook show up when I run &appname;?</para></question>
+<answer>
+<para>Stuff like:
+<screen width="40">
+<computeroutput>Tellico::updateCollectionToolBar</computeroutput>
+<computeroutput>GroupView::setGroupAttribute - author</computeroutput>
+<computeroutput>GroupView::slotAddCollection</computeroutput>
+<computeroutput>QCheckBox::property( "title" ) failed: property invalid
+or does not exist</computeroutput>
+</screen>
+
+is debug info. At compile time, this can be stopped by compiling with
+the <userinput><option>--disable-debug</option></userinput> flag. You
+might also want to use
+<userinput><option>--enable-final</option></userinput>, too, which
+takes a bit more memory when compiling, but is more efficient when
+running the application.</para>
+
+<para>The last message is slightly different, it just means your Qt
+ installation was compiled with some debugging information.</para>
+
+<para>Or, if &appname; is already installed, run
+<userinput><command>kdebugdialog</command></userinput> and make sure
+that "0 (generic)" is unchecked. That turns off debug messages from
+all generic KDE apps i.e. those not distributed officially by
+KDE.</para>
+
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question><para>How do I change which columns are shown?</para></question>
+<answer>
+<para>Right-click on the header bar. You can also drag the headers to re-order
+the columns, and click on them to sort by that field.</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question><para>How do I filter by something like the "Read"
+field?</para></question>
+<answer>
+<para>Internally, the checkbox
+fields in &appname; are saved as "true", so if you'd like to filter
+to show only the science fiction books which you've not read, for
+example, then you have two rules. Make sure the "Match all of the
+following" button is checked. Set the first rule to have "Genre"
+"contains" "Science Fiction" (no quotes) and the second rule to have
+"Read" "does not contain" "true" (no quotes).</para>
+
+<para>Also, the quick filter in the toolbar will match any field,
+and if there is a non-word character, the text is interpreted as a
+regular expression. So if you quickly want to filter your books to
+show those by Weber or Bujold, then type "weber|bujold" (no quotes) in
+the toolbar.</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question><para>How do I add new entry templates?</para></question>
+
+<answer>
+<para>Entry templates should be saved in
+<filename class="directory">$<envar>KDEHOME</envar>/share/apps/tellico/entry-templates/</filename>
+for access for a single user or
+<filename class="directory">$<envar>KDEDIR</envar>/share/apps/tellico/entry-templates/</filename>
+for access by everyone. Templates in $<envar>KDEHOME</envar> will
+override any files by the same name in $<envar>KDEDIRS</envar>. The
+entry templates can be set on a per collection-type basis in the
+settings dialog.</para>
+
+<para>Templates for the &report-dialog; are saved in <filename class="directory">$<envar>KDEHOME</envar>/share/apps/tellico/report-templates/</filename>.
+</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question><para>Compiling and installing went
+fine, but when &appname; starts up, the window is blank. What's
+wrong?</para></question>
+
+<answer>
+<para>KDE programs look for data in the locations defined in the
+ $<envar>KDEDIRS</envar> environmental variable. If you install in
+ <filename class="directory">/usr/local</filename> for example, but
+ $<envar>KDEDIRS</envar> is empty or just <filename class="directory">/usr</filename>,
+ then &appname; won't be able to find the files it needs. This is
+ particularly true for SuSE, for which you should compile with
+ <userinput><option>--prefix</option>=<filename class="directory">/opt/kde3</filename></userinput>. Alternatively,
+ you could add a line to your <filename>.profile</filename> file to
+ set $<envar>KDEDIRS</envar>. Check the documentation for your
+ shell.</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question><para>How do I export additional bibtex fields?</para></question>
+<answer>
+<para>&appname; uses the <emphasis>bibtex</emphasis> property to know how to export
+ bibtex fields. If you want to add additional fields to export, such
+ as an abstract, open up the &fields-dialog;, and click the <guibutton>Extended
+ Properties</guibutton> button. Add a <emphasis>bibtex</emphasis> property with value
+ <emphasis>abstract</emphasis>. Then, when you export to bibtex or bibtexml, that
+ property will be used for the bibtex field name.</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question>
+<para>What happened to Bookcase?</para>
+</question>
+
+<answer>
+<para>Due to a trademark conflict, Bookcase was renamed Tellico in September 2004.
+Tellico 0.12 was then released, which was identical to
+Bookcase 0.11, except for the name change.</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question>
+<para>What does the name Tellico have to do with anything?</para>
+</question>
+
+<answer>
+<para>I thought about <ulink url="http://www.periapsis.org/archives/2004/09/13/renaming_bookcase.html">several
+other names</ulink>, a few of which were connected with book collections. However,
+Tellico can handle more than just books, and besides, this is a hobby, so I chose
+a neat-sounding (to me) name, one taken from a town close to where I grew up.</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question>
+<para>What do you include those links to Amazon.com in the search results?</para>
+</question>
+
+<answer>
+<para>
+The <ulink url="http://www.amazon.com/gp/browse.html/002-0927720-5265623?node=3440661">terms of agreement for accessing the Amazon.com Web Services</ulink> require all images pulled from the service to be linked back to Amazon.com, as well as an additional link. The Amazon.com associate's ID is neccessarily included, so any referral payments are duly collected.
+</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question>
+<para>Why don't you use a real database?</para>
+</question>
+
+<answer>
+<para>
+Part of the reason I started &appname; was to learn C++. I didn't know SQL at the time, and at the moment, I only have a faint knowledge
+of how to use it. Simply put, &appname; didn't start out as a relational database, and that won't change until sometime in the future when
+I get around to learning SQL and have the time and motivation to change the data model. If that bothers you, well, don't use &appname; then.
+</para>
+
+<para>
+Of course, anyone is welcome to make any changes they want to with the source code.
+</para>
+</answer>
+</qandaentry>
+
+</qandaset>
+
+</chapter>
diff --git a/doc/en/fetch-dialog.png b/doc/en/fetch-dialog.png
new file mode 100644
index 0000000..eee5ef6
--- /dev/null
+++ b/doc/en/fetch-dialog.png
Binary files differ
diff --git a/doc/en/fields-dialog.png b/doc/en/fields-dialog.png
new file mode 100644
index 0000000..932ed29
--- /dev/null
+++ b/doc/en/fields-dialog.png
Binary files differ
diff --git a/doc/en/filter-dialog.png b/doc/en/filter-dialog.png
new file mode 100644
index 0000000..d10842c
--- /dev/null
+++ b/doc/en/filter-dialog.png
Binary files differ
diff --git a/doc/en/filter-view.png b/doc/en/filter-view.png
new file mode 100644
index 0000000..2d8752e
--- /dev/null
+++ b/doc/en/filter-view.png
Binary files differ
diff --git a/doc/en/freebsd-doc-license.html b/doc/en/freebsd-doc-license.html
new file mode 100644
index 0000000..ae93752
--- /dev/null
+++ b/doc/en/freebsd-doc-license.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html40/strict.dtd">
+<html lang="en-US">
+ <head>
+ <title>FreeBSD Documentation License</title>
+ <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
+ <meta HTTP-EQUIV="Content-Language" CONTENT="en-US">
+ <meta NAME="description" CONTENT="FreeBSD Documentation License">
+ <meta NAME="keywords" CONTENT="FreeBSD, bsd, Bsd, license, licence, documentation, FreeBSD Documentation license">
+ <meta NAME="robots" CONTENT="none">
+ <meta HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
+ <link REL="stylesheet" HREF="common/kde-default.css" TYPE="text/css">
+ </head>
+ <body CLASS="license">
+ <h1>FreeBSD Documentation License</h1>
+
+ <p>Redistribution and use in source (SGML DocBook) and 'compiled'
+ forms (SGML, HTML, PDF, PostScript, RTF and so forth) with or
+ without modification, are permitted provided that the following
+ conditions are met:</p>
+
+ <ol>
+ <li>
+ <p>Redistributions of source code (SGML DocBook)
+ must retain the above copyright notice, this list
+ of conditions and the following disclaimer as the
+ first lines of this file unmodified.</p>
+ </li>
+
+ <li>
+ <p>Redistributions in compiled form (transformed to
+ other DTDs, converted to PDF, PostScript, RTF and
+ other formats) must reproduce the above copyright
+ notice, this list of conditions and the following
+ disclaimer in the documentation and/or other
+ materials provided with the distribution.</p>
+
+ </li>
+ </ol>
+
+ <p>THIS DOCUMENTATION IS PROVIDED BY THE FREEBSD
+ DOCUMENTATION PROJECT "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ THE FREEBSD DOCUMENTATION PROJECT BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.</p>
+</body>
+</html>
diff --git a/doc/en/fundamentals.docbook b/doc/en/fundamentals.docbook
new file mode 100644
index 0000000..046a651
--- /dev/null
+++ b/doc/en/fundamentals.docbook
@@ -0,0 +1,595 @@
+<chapter id="fundamentals">
+<title>Using &appname;</title>
+
+<sect1 id="quick-start">
+<title>Quick Start</title>
+
+<para>
+By default, &appname; starts with an empty book collection. To work with some other type of collection, create it using the <menuchoice><guimenu>File</guimenu><guimenuitem>New</guimenuitem></menuchoice> menu item, or the button on the toolbar. Collections are populated with some of the more common fields, but you can add, modify, or delete them to suit your needs.
+</para>
+
+<para>
+New entries can be added by using the <link linkend="entry-editor">&entry-editor;</link>. The <menuchoice><guimenu>Collection</guimenu><guimenuitem>New Entry</guimenuitem></menuchoice> menu item will open the &entry-editor; with an empty entry ready for editing. The &entry-editor; can also be opened by using the <menuchoice><guimenu>Settings</guimenu><guimenuitem>Show &entry-editor;</guimenuitem></menuchoice> menu item. Once you've entered the values for the entry, you can save it to the collection by using the <guibutton>Save Entry</guibutton> button in the &entry-editor; dialog, which remains open in case you want to continue adding new entries. Once you've saved an entry in the collection, you can modify it by clicking on it in the main window. If the &entry-editor; is not already open, you can double click an entry to open the editor and start editing.
+</para>
+
+<para>
+If you want to include an image in the entry, you can use the standard &kde; File Selector by clicking the <guibutton>Select Image...</guibutton> button in the <link linkend="entry-editor">&entry-editor;</link>, or you can drag an image from the file manager or web browser into the &entry-editor;.
+</para>
+
+<para>
+When you select an entry, the <link linkend="entry-view">&entry-view;</link> shows a formatted view of the entry's contents. You can change the template used for showing the entry in the <link linkend="configuration">&config-dialog;</link>.
+</para>
+
+<para>
+The entries in the collection are grouped together when they share the same values for certain fields, such as the author or director. You can change the field used for grouping by using the combo box in the toolbar or the <menuchoice><guimenu>Settings</guimenu><guimenuitem>Group Selection</guimenuitem></menuchoice> menu item.
+</para>
+
+<para>
+You can use the &quick-filter; in the toolbar to quickly limit the visible entries to ones which contain the word you type. The filter is also useful when you want to quickly find an entry. You can type in the title or some other unique word that identifies the entry and the <link linkend="detailed-view">&detailed-view;</link> will only show the entries that match the filter. The status bar shows you how many entries are in the collection, and how many are currently being filtered.
+</para>
+
+</sect1>
+
+<sect1 id="main-window">
+<title>General Usage</title>
+
+<para>
+The main window has three distinct areas, all of which show information about the collection
+in a different manner. The primary view is the <link linkend="detailed-view">&detailed-view;</link> in
+the upper right area, where the value of every field for each entry may be shown. On the left side, tabs
+hold the <link linkend="group-view">&group-view;</link>, which can be used to sort the entries into groups
+in a tree-structure, the <link linkend="filter-view">&filter-view;</link>, which is used to track which
+entries meet cerrtain critera, and the <link linkend="loan-view">&loan-view;</link>, where any loans are
+listed. Finally, the <link linkend="entry-view">&entry-view;</link> shows a formatted view
+of the data for a single entry, or an icon view of a group of entries, in the lower right.
+</para>
+
+<screenshot>
+<screeninfo>The &appname; Main Window</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="main-window.png"/></imageobject>
+<textobject><phrase>The &appname; Main Window</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<sect2 id="detailed-view">
+<title>&detailed-view;</title>
+
+<para>
+Any of the fields in the collections may be shown in the &detailed-view;, although <emphasis><link linkend="para">Paragraph</link></emphasis>, <emphasis><link linkend="image">Image</link></emphasis>, and <emphasis><link linkend="table">Table</link></emphasis> fields will probably not be useful. Right-clicking on the header of the view opens a menu for selecting the visible fields. The columns may be resized and reordered in any way, and the settings will be saved between sessions.
+</para>
+</sect2>
+
+<sect2 id="group-view">
+<title>&group-view;</title>
+
+<para>
+The &group-view; groups the entries in a tree-view by any field which <link linkend="field-options">allows grouping</link>.
+The number of entries in each group is shown next to the group name. Groups may be expanded or collapsed by clicking the plus sign, or by double-clicking the item. Expanding and contracting all the groups are options in the right-click context menu. The tree may be sorted either by the group name, or by the count, by clicking on the header. A group may also be used as a filter for the <link linkend="detailed-view">&detailed-view;</link>, by right-clicking on the group item.
+</para>
+
+<para id="people-group">
+When more than one field in the collection has the <emphasis><link linkend="fields-dialog"><guilabel>Format as name</guilabel></link></emphasis> option turned on, an additional group is added to combine all those fields into one single <emphasis>People</emphasis> pseudo-group.
+</para>
+
+<para>
+If an entry does not contain a value for the field being used to form the groups, it is placed in the <emphasis>(Empty)</emphasis> group, which uses a red folder.
+</para>
+</sect2>
+
+<sect2 id="filter-view">
+<title>&filter-view;</title>
+
+<para>
+If any filters are saved for the collection, the &filter-view; becomes active. As you add or
+modify entries, they will automatically be checked against the filters and add or removed as
+appropriate. The filter may be modified by double-clicking on the item to open
+the &filter-dialog;. Right-clicking gives you the option to delete it altogether.
+</para>
+
+<screenshot>
+<screeninfo>The &filter-view;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="filter-view.png"/></imageobject>
+<textobject><phrase>The &filter-view;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+</sect2>
+
+<sect2 id="loan-view">
+<title>&loan-view;</title>
+
+<para>
+Once entries are checked-out on loan, the &loan-view; is added to the window, so those
+borrowed entries may be tracked. Loans are tracked on a per-entry bases, so right-clicking
+on an entry item has an option for modifying the loan using the &loan-dialog;.
+</para>
+
+<screenshot>
+<screeninfo>The &loan-view;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="loan-view.png"/></imageobject>
+<textobject><phrase>The &loan-view;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+</sect2>
+
+<sect2 id="entry-view">
+<title>&entry-view;</title>
+
+<para>
+A formatted representation of the entry's values is shown in the &entry-view;. Templates are used for the layout and any additional graphics. Separate templates for each type of collection may be specified in the <link linkend="template-options">&config-dialog;</link>, along with custom colors and fonts.</para>
+
+<para>All of the default templates honor the color and font selection, but other custom templates might now.
+The default templates also make &URL; fields active, which will open up with the default &kde; file association. When exporting to &html;, the current template is used for exporting the individual entry files.
+</para>
+
+<para>
+In addition, when multiple entries are selected, an icon view is shown, using the first <link linkend="image">Image</link> field in the collection. Entries may be selected as in the &detailed-view;. Right-clicking in the icon view will show a menu that changes the sorting criteria for the entries.
+</para>
+
+</sect2>
+
+<sect2 id="status-bar">
+<title>Statusbar</title>
+
+<para>
+The status bar is used to show you what &appname; is currently doing. It also includes a total count of the entries in the collection, and if a filter is being used, how many are currently visible.
+</para>
+</sect2>
+
+</sect1>
+
+<sect1 id="entry-editor">
+<title>Editing Entries</title>
+
+<para>
+The &entry-editor; is used to add and modify entries in the collection. Double-clicking on an entry in either the &group-view; or the &detailed-view; opens the &entry-editor; with that entry. New entries may be created using the <menuchoice><guimenu>Collection</guimenu></menuchoice> menu, the toolbar icon, or the button in the &entry-editor; itself.</para>
+
+<para>
+The arrow buttons on the bottom will move to the previous or next entries in the current list.
+</para>
+
+<para>Closing the &entry-editor; when changes have been made but not saved will cause a warning message to appear. The fields are grouped by category and appear in the order that they appear in the <link linkend="fields-dialog">&fields-dialog;</link>. They may also be reordered.
+</para>
+
+<screenshot>
+<screeninfo>The &entry-editor;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="entry-editor1.png"/></imageobject>
+<textobject><phrase>The &entry-editor;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+Clicking the field title for a <link linkend="url"><emphasis>&URL;</emphasis></link> field will open the link using the default &kde; file association. The <guiicon>&URL; selector</guiicon> button beside the text entry will open the default &kde; File Open Dialog, but the field is not limited to local files.
+</para>
+
+<para>
+For <link linkend="image"><emphasis>Image</emphasis></link> fields, the <guibutton>Select Image...</guibutton> button opens up the &kde; image file selection dialog. The image is saved in the collection in the original format, and a scaled version is shown in the &entry-editor;. The image may be cleared by using the <guibutton>Clear</guibutton> button. Cleared images are removed from the collection. </para>
+
+<screenshot>
+<screeninfo>The &entry-editor; for <emphasis>Image</emphasis> fields</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="entry-editor3.png"/></imageobject>
+<textobject><phrase>The &entry-editor; for <emphasis>Image</emphasis> fields</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+The edit widget also supports drag-and-drop. Dragging an image file from a file-manager or browser window does the same thing as selecting the image in the File Selector. Dragging an image from the edit widget into a &konqueror; file manager window will save the image in that folder.
+</para>
+
+<warning>
+<para>
+By default, the images are stored in the collection data file, keeping everything contained in one location. However, too many images will cause &appname; to slow down significantly as well result in a very large data file. Alternatively, &appname; can save the images separately, either in the <filename class="directory">$<envar>KDEHOME</envar>/share/apps/tellico/data/</filename> directory or in a directory in the same location as the data file. Loading and saving data files is much faster if images are stored separately, but the data files are no longer portable or archivable.
+Self-contained data files can always be created by using the <menuchoice><guimenu>File</guimenu><guimenu>Export</guimenu><guimenuitem>Export to Zip...</guimenuitem></menuchoice> menu item.
+</para>
+</warning>
+
+<para>
+<link linkend="table"><emphasis>Table</emphasis></link> fields begin with five rows, but moving the cursor to the last row automatically adds another. For multi-column tables, only the first column is used for grouping or formatting.
+</para>
+
+<screenshot>
+<screeninfo>The &entry-editor; for <emphasis>Table</emphasis> fields</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="entry-editor4.png"/></imageobject>
+<textobject><phrase>The &entry-editor; for <emphasis>Table</emphasis> fields</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<sect2 id="edit-multiple">
+<title>Editing Multiple Entries</title>
+<para>
+Multiple entries may be edited at the same time by selecting more than one in either the &group-view; or the &detailed-view;. If multiple entries are selected, the fields which contain the same value in every entry are enabled. If entries have different values, then the fields are disabled. Check boxes are added to the extreme right for each field entry which control whether the field is enabled or not, as shown in the screenshot below.
+</para>
+
+<para>
+Only enabled fields will be modified when the entries are saved, which makes large-scale editing much easier. For example, to set the Medium of all the video entries in the collection, make sure the Medium field is enabled. Change it to <acronym>DVD</acronym>, then save the entries. Only the Medium field will be modified, preserving all the other field values for the entries.
+</para>
+
+<screenshot>
+<screeninfo>The &entry-editor; for multiple entries</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="entry-editor5.png"/></imageobject>
+<textobject><phrase>The &entry-editor; for multiple entries</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+</sect2>
+
+<sect2 id="updating-entries">
+<title>Updating Entry Data</title>
+
+<para>
+Entries may be automatically updated by querying the data sources available for the current collection type, which is very useful for combining information from multiple sources. For example, you may add a movie to your collection using
+the <link linkend="amazon-web-services">Amazon.com Web Services</link>, and then update the entry with additional
+information from the <link linkend="imdb">Internet Movie Database</link>.
+</para>
+
+<para>
+Only empty fields are updated unless the <link linkend="data-sources-options">setting for that source</link> allows results to overwrite existing information. For <link linkend="externalexec">external scripts</link>, an update field must be specified in the source options.
+</para>
+
+<para>
+The entry updating may be started via the right-click menu for an entry, or by using the <menuchoice><guimenu>Collection</guimenu><guimenuitem>Update Entry</guimenuitem></menuchoice> menu item.
+</para>
+</sect2>
+
+</sect1>
+
+<sect1 id="fields-dialog">
+<title>Editing Fields</title>
+
+<para>
+The &fields-dialog; allows you to add new fields to the collection, to modify the existing ones, or to delete fields altogether.
+</para>
+
+<screenshot>
+<screeninfo>The &appname; &fields-dialog;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="fields-dialog.png"/></imageobject>
+<textobject><phrase>The &appname; &fields-dialog;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<sect2 id="field-list">
+<title>Field List</title>
+
+<para>
+On the left side of the dialog is the list of the current fields. Modified fields are shown in bold italics. The buttons below the list will add or delete a field, and the arrows can be used to change their order. The order of the fields in the list is important because the &entry-editor; uses the order for its layout. For each category, the fields will be laid out from left to right, according to the top-to-bottom order of the fields in the list.
+</para>
+</sect2>
+
+<sect2 id="field-properties">
+<title>Field Properties</title>
+
+<para>
+A field is defined by its title, type, category, description, and possibly a default value or some allowed values. The title is used everywhere to refer to the field in the user interface. The &entry-editor; uses it to prompt for values. The &detailed-view; uses it as a column header. The different types of fields are <link linkend="field-types">explained in the Field Types section</link>. The description is used as a tooltip in the &entry-editor;, perhaps to provide an explanation of the field's contents. In addition, for <link linkend="dependent"><emphasis>Dependent</emphasis></link> fields, the description is used to format the field's value. The default value is automatically added when creating a new entry. The list of allowed values for <link linkend="choice"><emphasis>Choice</emphasis></link> fields should be separated by a semi-colon.
+</para>
+
+<para>
+New fields may be any type, but changing the type of existing fields is restricted to compatible types, as shown in the table below:
+</para>
+
+<table>
+<title>Allowable Field Type Changes</title>
+<tgroup cols="2">
+<thead>
+<row>
+<entry>Current Type</entry>
+<entry>New Type Allowed</entry>
+</row>
+</thead>
+<tbody>
+<row>
+<entry><emphasis>Simple Text</emphasis></entry>
+<entry><emphasis>Simple Text</emphasis>, <emphasis>Paragraph</emphasis>, <emphasis>Number</emphasis>, <emphasis>URL</emphasis>, <emphasis>Table</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Paragraph</emphasis></entry>
+<entry><emphasis>Simple Text</emphasis>, <emphasis>Paragraph</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Choice</emphasis></entry>
+<entry><emphasis>Simple Text</emphasis>, <emphasis>Paragraph</emphasis>, <emphasis>Choice</emphasis>, <emphasis>Number</emphasis>, <emphasis>URL</emphasis>, <emphasis>Table</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Checkbox</emphasis></entry>
+<entry><emphasis>Simple Text</emphasis>, <emphasis>Paragraph</emphasis>, <emphasis>Checkbox</emphasis>, <emphasis>Number</emphasis>, <emphasis>URL</emphasis>, <emphasis>Table</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Number</emphasis></entry>
+<entry><emphasis>Simple Text</emphasis>, <emphasis>Paragraph</emphasis>, <emphasis>Number</emphasis>, <emphasis>URL</emphasis>, <emphasis>Table</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>URL</emphasis></entry>
+<entry><emphasis>Simple Text</emphasis>, <emphasis>Paragraph</emphasis>, <emphasis>Number</emphasis>, <emphasis>URL</emphasis>, <emphasis>Table</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Date</emphasis></entry>
+<entry><emphasis>Simple Text</emphasis>, <emphasis>Date</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Table</emphasis></entry>
+<entry><emphasis>Simple Text</emphasis>, <emphasis>Paragraph</emphasis>, <emphasis>Table</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Image</emphasis></entry>
+<entry><emphasis>Image</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Rating</emphasis></entry>
+<entry><emphasis>Choice</emphasis>, <emphasis>Rating</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Dependent</emphasis></entry>
+<entry><emphasis>Dependent</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+</sect2>
+
+<sect2 id="field-formatting">
+<title>Field Formatting</title>
+
+<para>
+&appname; provides some capability for automatic formatting of field values. The simplest is auto-capitalization, which capitalizes every word except the articles. Title formatting moves certain articles from the beginning to the end of the field, for example, changing "The Return of the King" to "Return of the King, The". The title articles are configurable. Finally, name formatting tries to break up the string so that the last, or family, name of the person is shown first. Name prefixes and suffixes are configurable. Also, the special <emphasis><link linkend="people-group">People</link></emphasis> group uses all fields with name formatting, even if the global setting is turned off.
+</para>
+
+<para>
+All automatic formatting can be disabled by changing the global options in the <link linkend="general-options">&config-dialog;</link>. Globally, capitalization is a distinct option from formatting, so a title can be auto-formatted without being capitalized. Not all field types allow auto-formatting.
+</para>
+
+<table>
+<title>Formatting Examples</title>
+<tgroup cols="5">
+<thead>
+<row>
+<entry>Format Type</entry>
+<entry>Field Value</entry>
+<entry>Auto-Capitalized</entry>
+<entry>Auto-Formatted</entry>
+<entry>Auto-Capitalized &amp; Auto-Formatted</entry>
+</row>
+</thead>
+<tbody>
+<row>
+<entry><emphasis>Title</emphasis></entry>
+<entry>the return of the king</entry>
+<entry>The Return of the King</entry>
+<entry>return of the king, the</entry>
+<entry>Return of the King, The</entry>
+</row>
+<row>
+<entry><emphasis>Name</emphasis></entry>
+<entry>tom swift, jr.</entry>
+<entry>Tom Swift, Jr.</entry>
+<entry>swift, jr., tom</entry>
+<entry>Swift, Jr., Tom</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+</sect2>
+<sect2 id="field-options">
+<title>Field Options</title>
+
+<para>
+Fields also have three general options. If auto-completion is enabled, &appname; caches the values for each field, and the &entry-editor; offers automatic completion, using the standard &kde; settings. Not all field types allow auto-completion. &appname; also needs to know if a field may have multiple values or may be used to group the entries. A semi-colon is used to separate multiple values when editing an entry;
+</para>
+
+<para>
+For efficiency, do not enable auto-completion unless you need it for the fields. The more fields with auto-completion in the collection, the slower it takes &appname; to load the file.
+</para>
+
+</sect2>
+</sect1>
+
+<sect1 id="filter-dialog">
+<title>Filtering Entries</title>
+<para>
+The &filter-dialog; allows you to limit the entries visible in the <link linkend="detailed-view">&detailed-view;</link>
+to those that match one or more filter rules.
+The filter may be used to find the entries that meet all of the rules in the dialog, or just to
+find those that meet any of them. The &filter-dialog; is also useful for advanced searching within a collection.
+</para>
+
+<screenshot>
+<screeninfo>The &appname; &filter-dialog;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="filter-dialog.png"/></imageobject>
+<textobject><phrase>The &appname; &filter-dialog;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+Each row contains a single filter rule. Select the field to match in the first box in the row, then select a matching rule in the center. Rules may match values that contain a certain word, or are exactly equal. A regular expression may also be used to match entries, in which case the <guibutton>Edit...</guibutton> button becomes active for editing the expression. Finally, the word or string to match should be entered in the text box.
+</para>
+
+<para>
+Up to eight (8) rules may be used in the filter. The <guibutton>More</guibutton> and <guibutton>Fewer</guibutton> buttons may be used to add or remove rules.
+</para>
+
+<para>
+Filters may be saved, so that all entries which match are grouped together in the &filter-view;. The view is dynamic, so ad entries are added or modified, the group is automatically updated. To save the filter, enter a name in the text box, and lick the <guibutton>Save Filter</guibutton> button.
+</para>
+
+<para>
+Previously saved filters may be modified by right-clicking on the filter item in the &filter-view; and selecting <guilabel>Modify Filter</guilabel>. The &filter-dialog; is opened, and changes may be made to the filter's name or rules.
+</para>
+
+<informalexample>
+<para>
+To find the science fiction books you've not read, check the <guilabel>Match all of the following</guilabel>
+button, set the first rule to <emphasis>Genre contains Science Fiction</emphasis> and the second to <emphasis>Read does not contain true</emphasis>. (For <link linkend="bool">Checkbox</link> fields, the internal value is <emphasis>true</emphasis>).
+</para>
+
+<para>
+To find the books by Bujold or Weber, check the <guilabel>Match any of the following</guilabel>
+button, set the first rule to <emphasis>Author contains Bujold</emphasis> and the second to <emphasis>Author contains Weber</emphasis>.
+</para>
+</informalexample>
+
+</sect1>
+
+<sect1 id="report-dialog">
+<title>Generating Reports</title>
+<para>
+&appname; can generate various reports about your current collection. The &report-dialog; checks for all &xslt; templates in the installation path and in <filename class="directory">$<envar>KDEHOME</envar>/share/apps/tellico/report-templates/</filename>. So you can create new ones, and they're automatically found and included as options in the &report-dialog;. Some complex reports may take a while to generate for large collections.
+</para>
+
+<para>
+The templates that are installed with &appname; include a list of titles only, the default column view, a group view, a summary of all of the groups and the most popular values in those groups, a loan report, and a large report with cover images. Select the desired template and click the <guibutton>Generate</guibutton> button. Any report may also be printed or saved to an &html; file.
+</para>
+
+<screenshot>
+<screeninfo>The &appname; &report-dialog;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="report-dialog.png"/></imageobject>
+<textobject><phrase>The &appname; &report-dialog;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+The entries included in the report will be limited to the ones in the &detailed-view; so if you've got an active filter, the &report-dialog; will use it.
+</para>
+</sect1>
+
+<sect1 id="loan-dialog">
+<title>Loan Tracking</title>
+<para>
+&appname; supports tracking loans of any entries in the collection. The &loan-dialog; may be opened by using the <guilabel>Check-out</guilabel> menu item, or right-clicking on an entry. Multiple entries may be checked-out at once.
+</para>
+
+<para>
+The borrower's name may be directly entered, or pulled from the default &kde; address book by clicking on the button next to the name entry. The check-out date is assumed to be the current date, but may be changed. The due date is optional, and other notes may be added about the loan.
+</para>
+
+<para>
+If a due date is entered, and &appname; is compiled with libkcal support, a loan reminder may be added to the default &kde; calendar as a To-Do item. &korganizer; can be used to view those items.
+</para>
+
+<para>
+When an entry is checked-out, the <emphasis>Loaned</emphasis> field is set to <emphasis>true</emphasis>. If no loaned field exists in the collection, one is added. Do not modify that field directly! Entries on-loan may be checked-in using the menu item, or right-clicking on an entry in the &loan-view;.
+</para>
+
+<screenshot>
+<screeninfo>The &appname; &loan-dialog;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="loan-dialog.png"/></imageobject>
+<textobject><phrase>The &appname; &loan-dialog;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+</sect1>
+
+<sect1 id="tips">
+<title>General Tips</title>
+
+<para>
+These are the list of tips contained in the "Tip of the Day" list for &appname;.
+</para>
+
+<tip>
+<para>If a book has more than one author, you should separate
+their names by a semi-colon, so that Tellico will know to split them
+and use them separately. Any other field which allows multiple values should be entered the
+same way. with a semi-colon (;) separating each value.
+</para>
+</tip>
+
+<tip>
+<para>You can change which fields are shown in the list view by
+right-clicking on the column header.
+</para>
+</tip>
+
+<tip>
+<para>You can add, edit, or modify the fields in the collection using
+the &fields-dialog;. The arrow buttons below the field list can be used to change the
+position of the field in the list, which affects the placement in the entry
+editor.
+</para>
+</tip>
+
+<tip>
+<para>If you want to filter by a <link linkend="bool"><emphasis>Checkbox</emphasis></link> field, a value of
+"true" should be used. If you'd like to filter to
+show only the science fiction books which you've not read, for
+example, check the <guilabel>Match all of the
+following</guilabel> button, set the first rule to have "Genre"
+"contains" "Science Fiction" (no quotes) and the second rule to
+have "Read" "does not contain" "true" (no quotes).
+</para>
+</tip>
+
+<tip>
+<para>If a non-word character is used in the Quick Filter, the text is
+interpreted as a regular expression. To show only books which are by Weber or Bujold, for example, then
+type "weber|bujold" (no quotes) in the filter box.
+</para>
+</tip>
+
+<tip>
+<para>You can edit more than one entry at a time, by holding down
+the &Shift; or &Ctrl; key and selecting multiple entries.
+</para>
+</tip>
+
+<tip>
+<para>You can convert an existing book collection to a bibliography,
+which can then be exported to bibtex or Bibtexml format.
+</para>
+</tip>
+
+
+<tip>
+<para>If more than one field is formatted as a name, then an additional
+group named "People" is added to the collection, allowing authors and editors
+to be sorted or printed together, for example.
+</para>
+</tip>
+
+<tip>
+<para>You can modify the appearance of the printed output by modifying
+the <filename>tellico-printing.xsl</filename> file. The file generates &html;, and the &css;
+within the stylesheet governs things like the font, the margins, etc.
+</para>
+</tip>
+
+<tip>
+<para>Double-clicking an entry item opens the &entry-editor;.
+</para>
+</tip>
+
+<tip>
+<para>You can add &html; tags to any <link linkend="para"><emphasis>Paragraph</emphasis></link> field for formatting, such as
+&lt;b&gt;<emphasis role="bold">bold</emphasis>&lt;/b&gt; or &lt;i&gt;<emphasis>italic</emphasis>&lt;/i&gt;.
+</para>
+</tip>
+
+<tip>
+<para>In the &detailed-view;, you can press a letter on the
+keyboard to skip to the next entry that starts with that letter.
+</para>
+</tip>
+
+<tip>
+<para>You can use Dependent Fields to combine multiple separated fields
+into a single field. Just select the type Dependent and use a description
+similar to "<userinput>Value: %{fielda}%{fieldb}</userinput>" where %{...} gets replaced with the
+appropriate field value. This is useful to collect multiple values in a
+single field, e.g. for better grouping, and to combine fields of different
+types by respecting proper sorting at the same time. Consider for example
+a number field followed by a text subfield with entries 3b, 14a.
+</para>
+</tip>
+
+</sect1>
+
+</chapter>
diff --git a/doc/en/general-options.png b/doc/en/general-options.png
new file mode 100644
index 0000000..406a271
--- /dev/null
+++ b/doc/en/general-options.png
Binary files differ
diff --git a/doc/en/hacking.docbook b/doc/en/hacking.docbook
new file mode 100644
index 0000000..89d1c54
--- /dev/null
+++ b/doc/en/hacking.docbook
@@ -0,0 +1,362 @@
+<chapter id="hacking">
+<title>Hacking &appname;</title>
+
+<para>
+In the spirit of Free Software, you're welcome to hack on &appname; as much as you like. You should be able to write scripts to import, export, or modify data very easily. This chapter gives you more information about doing that.
+</para>
+
+<sect1 id="file-format">
+<title>File Format</title>
+
+<para>
+The default &appname; data file is a zip archive, normally with a <literal role="extension">.tc</literal> file extension. Inside the archive is a top-level <filename>tellico.xml</filename> file. Images may be included inside the <filename>images/</filename> directory in the archive., or they may be included in the &xml; data directly in a base64 encoding. Images may also be saved inside the application data directory, in which case, they are not in the data file at all. &appname; can also load the &xml; file, by itself, uncompressed.
+</para>
+
+<sect2 id="xml-format">
+<title>&xml; Data</title>
+
+<para>
+</para>
+
+<sect3 id="coll-xml-data">
+<title>Collection</title>
+<programlisting>
+<![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE tellico PUBLIC "-//Robby Stephenson/DTD Tellico V9.0//EN" "http://periapsis.org/tellico/dtd/v9/tellico.dtd">
+<tellico xmlns="http://periapsis.org/tellico/" syntaxVersion="9">
+ <collection title="My Books" type="2">
+ </collection>
+</tellico>
+]]>
+</programlisting>
+
+<para>
+The file begins with the required &xml; declaration and encoding, followed by the doctype. When a new field type is added or additional properties are set on the default fields, the doctype DTD version is incremented. &appname; is always able to open and read any previous DTD version, but will save files in the current version. The DTD location does point to an actual DTD file.
+</para>
+
+<para>
+The top-level element is a <markup>&lt;tellico&gt;</markup> element, containing the default namespace declaration and the syntax version of the file, which should always match the DTD.
+</para>
+
+<para>
+The <markup>&lt;tellico&gt;</markup> element contains one <markup>&lt;collection&gt;</markup> element. Multiple collections are ignored, for now. The <markup>title</markup> attribute contains the collection title, while the <markup>type</markup> specifies what kinds of entries are contained in the collection. The allowable types are in <link linkend="collection-type-values">listed in a later section</link>. An optional <markup>entryTitle</markup> attribute may be used to specify the title of the entries for a custom collection, and should be plural.
+</para>
+</sect3>
+
+<sect3 id="fields-xml-data">
+<title>Fields</title>
+
+<programlisting>
+<![CDATA[
+ <fields>
+ <field flags="8" title="Title" category="General" format="1" type="1" name="title" />
+ <field flags="7" title="Author" category="General" format="2" type="1" name="author" />
+ <field flags="2" title="Binding" category="General" allowed="Hardback;Paperback;Trade Paperback;E-Book;Magazine;Journal" format="4" type="3" name="binding" />
+ <field flags="6" title="Publisher" category="Publishing" format="0" type="1" name="publisher" />
+ <field flags="4" title="Edition" category="Publishing" format="0" type="1" name="edition" />
+ <field flags="3" title="Copyright Year" category="Publishing" format="4" type="6" name="cr_year" />
+ <field flags="2" title="Publication Year" category="Publishing" format="4" type="6" name="pub_year" />
+ <field flags="0" title="ISBN#" category="Publishing" format="4" type="1" name="isbn" description="International Standard Book Number" />
+ <field flags="7" title="Genre" category="Classification" format="0" type="1" name="genre" />
+ <field flags="7" title="Keywords" category="Classification" format="0" type="1" name="keyword" />
+ <field flags="0" title="Front Cover" category="Front Cover" format="4" type="10" name="cover" />
+ <field flags="0" title="Comments" category="Personal" format="4" type="1" name="comments" />
+ </fields>
+]]>
+</programlisting>
+
+<para>
+All of the fields are defined inside a <markup>&lt;fields&gt;</markup> element, of which there can be only one. All of the information for a field, except for any extended properties, are included as attributes of the <markup>&lt;field&gt;</markup> element. The allowable values for the <markup>flags</markup>, <markup>format</markup>, and <markup>type</markup> attributes are given in a <link linkend="field-type-values">following section</link>.
+</para>
+
+<para>
+A <markup>&lt;field&gt;</markup> element with a name attribute equal to <emphasis>_default</emphasis> tells &appname; to include all the default fields for that collection type.
+</para>
+</sect3>
+
+<sect3 id="entries-xml-data">
+<title>Entries</title>
+
+<programlisting>
+<![CDATA[
+ <entry>
+ <title>C++ Programming Language, The</title>
+ <authors>
+ <author>Stroustrup, Bjarne</author>
+ </authors>
+ <publisher>Addison-Wesley Pub Co</publisher>
+ <edition>3rd</edition>
+ <pub_year>1997</pub_year>
+ <isbn>0-201-88954-4</isbn>
+ <genres>
+ <genre>Non-Fiction</genre>
+ </genres>
+ <keywords>
+ <keyword>Programming</keyword>
+ <keyword>Computers</keyword>
+ </keywords>
+ <cover>cf65a2f023b6cb9e9233323dca10ac7c.jpeg</cover>
+ </entry>
+]]>
+</programlisting>
+
+<para>
+For every field in the collection, an <markup>&lt;entry&gt;</markup> may contain an element whose name is identical to the field name. If multiple values are allowed for the field, then the letter <emphasis>s</emphasis> is added to the field name to create an element, and each value is added as a child of the element, as in the case of the author, genre, and keyword fields above.
+</para>
+
+<para>
+As a result, if additional fields are added to the collection, the date file will no longer conform to the DTD. However, &appname; uses a non-validating &xml; parser, so additional fields do not cause problems.
+</para>
+</sect3>
+
+<sect3 id="images-xml-data">
+<title>Images</title>
+<programlisting>
+<![CDATA[
+ <images>
+ <image width="111" format="JPEG" height="140" id="cf65a2f023b6cb9e9233323dca10ac7c.jpeg" />
+ </images>
+]]>
+</programlisting>
+
+<para>
+Inside the <markup>&lt;images&gt;</markup> element, each image referenced by an entry is listed, along with attributes describing the image's size, format, and id. If the image is contained inside the Zip file, the element is empty. Otherwise, the image data may be contained in the &xml; stream as base64-encoded text.
+</para>
+</sect3>
+
+</sect2>
+
+</sect1>
+
+<sect1 id="collection-type-values">
+<title>Collection Type Values</title>
+
+<para>
+The type of collection is given in the type attribute of the collection element. The value is equal to the <type>Type</type> enum value in <filename>src/collection.h</filename>.
+</para>
+
+<table>
+<title>Collection Type Values</title>
+<tgroup cols="2">
+<thead>
+<row>
+<entry>Collection Type</entry>
+<entry>Value</entry>
+</row>
+</thead>
+<tbody>
+<row><entry>Custom Collection</entry><entry>1</entry></row>
+<row><entry>Book Collection</entry><entry>2</entry></row>
+<row><entry>Video Collection</entry><entry>3</entry></row>
+<row><entry>Music Collection</entry><entry>4</entry></row>
+<row><entry>Bibliography</entry><entry>5</entry></row>
+<row><entry>Comic Book Collection</entry><entry>6</entry></row>
+<row><entry>Wine Collection</entry><entry>7</entry></row>
+<row><entry>Coin Collection</entry><entry>8</entry></row>
+<row><entry>Stamp Collection</entry><entry>9</entry></row>
+<row><entry>Trading Card Collection</entry><entry>10</entry></row>
+<row><entry>Video Game Collection</entry><entry>11</entry></row>
+<row><entry>File Catalog</entry><entry>12</entry></row>
+<row><entry>Board Game Collection</entry><entry>13</entry></row>
+</tbody>
+</tgroup>
+</table>
+
+
+</sect1>
+
+<sect1 id="field-type-values">
+<title>Field Type Values</title>
+
+<para>
+&appname; will include all the default fields for a collection if the first field element has the name <emphasis>_default</emphasis>. For <emphasis>Paragraph</emphasis>, <emphasis>Table</emphasis>, or <emphasis>Image</emphasis> fields, the field category should be identical to the field title.
+</para>
+
+<para>
+The type of field is given in the type attribute of the field element. The value is equal to the <type>FieldType</type> enum value in <filename>src/field.h</filename>. <emphasis>ReadOnly</emphasis> fields were intended for fields which should be retained in the collection, but which should not be editable by the user, such as some fields added when importing a collection from another file format. It is not currently used.
+</para>
+
+<table>
+<title>Field Type Values</title>
+<tgroup cols="2">
+<thead>
+<row>
+<entry>Field Type</entry>
+<entry>Value</entry>
+</row>
+</thead>
+<tbody>
+<row><entry>Simple Text</entry><entry>1</entry></row>
+<row><entry>Paragraph</entry><entry>2</entry></row>
+<row><entry>Choice</entry><entry>3</entry></row>
+<row><entry>Checkbox</entry><entry>4</entry></row>
+<row><entry><emphasis>ReadOnly</emphasis></entry><entry>5</entry></row>
+<row><entry>Number</entry><entry>6</entry></row>
+<row><entry>URL</entry><entry>7</entry></row>
+<row><entry>Single-Column Table</entry><entry>8</entry></row>
+<row><entry>Image</entry><entry>10</entry></row>
+<row><entry>Dependent</entry><entry>11</entry></row>
+<row><entry>Date</entry><entry>12</entry></row>
+<row><entry>Rating</entry><entry>14</entry></row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+The field may have different flags set, given as a bitwise OR'd value in the flags attribute on the field element. The flag for preventing the user from deleting a field is intended for such things as the citation key for bibliographic entries.
+</para>
+
+<table>
+<title>Field Flag Values</title>
+<tgroup cols="2">
+<thead>
+<row>
+<entry>Field Flags</entry>
+<entry>Value</entry>
+</row>
+</thead>
+<tbody>
+<row><entry>Allow Multiple Values</entry><entry><constant>0x01</constant></entry></row>
+<row><entry>Allow Grouping</entry><entry><constant>0x02</constant></entry></row>
+<row><entry>Allow Completion</entry><entry><constant>0x04</constant></entry></row>
+<row><entry><emphasis>Disallow Deleting</emphasis></entry><entry><constant>0x08</constant></entry></row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+The format of the field is given in the format attribute on the field element. <emphasis>Date Formatting</emphasis> is not currently used. Grouping by <emphasis>People</emphasis> uses all the fields which use <emphasis>Name Formatting</emphasis>.
+</para>
+
+<table>
+<title>Field Format Values</title>
+<tgroup cols="2">
+<thead>
+<row>
+<entry>Field Format</entry>
+<entry>Value</entry>
+</row>
+</thead>
+<tbody>
+<row><entry>Capitalization Only</entry><entry>0</entry></row>
+<row><entry>Title Formatting</entry><entry>1</entry></row>
+<row><entry>Name Formatting</entry><entry>2</entry></row>
+<row><entry><emphasis>Date Formatting</emphasis></entry><entry>3</entry></row>
+<row><entry>No Formatting</entry><entry>4</entry></row>
+</tbody>
+</tgroup>
+</table>
+
+</sect1>
+
+<sect1 id="hidden-options">
+<title>Hidden Configuration Options</title>
+
+<para>
+&appname; has some additional configuration options that are not visible in the &config-dialog;. They are not important enough to warrant cluttering the dialog with more settings, but as they represent options which may appeal to various users, the application does read them from the configuration file.
+</para>
+
+<para>
+The settings for &appname; are saved in a file in the user's home folder, namely <filename>$<envar>KDEHOME</envar>/share/config/tellicorc</filename>. Within that file, settings are put in groups, which appear with bracketed names, such as [General Options]. To add a setting to the <emphasis>General Options</emphasis> group, find the line in the settings file with that group name. If it does not appear, then create it yourself by adding a line saying [General Options]. Then, the setting can be added underneath the group name.
+</para>
+
+<sect2 id="hidden-general-options">
+<title>[General Options]</title>
+
+<para>
+These settings should be placed in the <emphasis>General Options</emphasis> group.
+</para>
+
+<sect3>
+<title>Max Icon Size</title>
+
+<para>
+The maximum size of the icons in the &icon-view; may be changed with this setting. The default value is 96. The size must be in the range of 32 to 128.
+</para>
+</sect3>
+
+<sect3>
+<title>Example</title>
+<informalexample>
+<para><userinput>Max Icon Size=72</userinput></para>
+</informalexample>
+</sect3>
+
+</sect2>
+
+<sect2 id="hidden-bibtex-options">
+<title>[Options - bibtex]</title>
+
+<para>
+These settings should be placed in the <emphasis>Options - bibtex</emphasis> group.
+</para>
+
+<sect3>
+<title>lyxpipe</title>
+
+<para>
+This setting is for the location of the lyxpipe for sending bibliographic citations. It should not include the <literal role="extension">.in</literal> suffix.
+</para>
+</sect3>
+
+<sect3>
+<title>Example</title>
+<informalexample>
+<para><userinput>lyxpipe=$HOME/.lyx/lyxpipe</userinput></para>
+</informalexample>
+</sect3>
+</sect2>
+
+<sect2 id="hidden-export-options-pilotdb">
+<title>[Export Options - PilotDB]</title>
+
+<para>
+These settings should be placed in the <emphasis>Export Options - PilotDB</emphasis> group.
+</para>
+
+<sect3>
+<title>Charset</title>
+
+<para>
+The encoding of the exported data within the PilotDB file may be changed with this setting. The default value is the character set for the user's locale.
+</para>
+</sect3>
+
+<sect3>
+<title>Example</title>
+<informalexample>
+<para><userinput>Charset=Windows-1250</userinput></para>
+</informalexample>
+</sect3>
+</sect2>
+
+</sect1>
+
+<sect1 id="bibtex-translation">
+<title>Bibtex Character Translation</title>
+
+<para>
+When bibtex files are imported or exported, certain characters are translated between their TeX equivalents and the Unicode characters. Those character mappings are contained in the <filename>bibtex-translation.xml</filename> file, located in the installation data directory. The mappings can be modified, as desired. The key element contains the Unicode character, and the string elements within contain the TeX equivalents, which may be a one-to-many mapping. The first one is the one used when exporting to bibtex.
+</para>
+
+<programlisting>
+<![CDATA[
+ <key char="À">
+ <string>{\`A}</string>
+ <string>\`{A}</string>
+ </key>
+]]>
+</programlisting>
+
+</sect1>
+
+<sect1 id="xslt-tricks">
+<title>XSLT Tricks</title>
+
+<para>
+Here are some tips for writing XSLT to parse &appname; &xml; data: (TBD).
+</para>
+</sect1>
+
+</chapter>
diff --git a/doc/en/imdb-options.png b/doc/en/imdb-options.png
new file mode 100644
index 0000000..d4b1cb1
--- /dev/null
+++ b/doc/en/imdb-options.png
Binary files differ
diff --git a/doc/en/importing-exporting.docbook b/doc/en/importing-exporting.docbook
new file mode 100644
index 0000000..c4814f5
--- /dev/null
+++ b/doc/en/importing-exporting.docbook
@@ -0,0 +1,452 @@
+<chapter id="importing-exporting">
+<title>Importing and Exporting Data</title>
+
+<para>
+&appname; is able to import and export a wide variety of data files, as well as search various Internet sites for information.
+</para>
+
+<sect1 id="internet-search">
+<title>Importing from the Internet</title>
+<para>
+&appname; is able to search various Internet sites using the &fetch-dialog;. Entries may be directly imported and added to your current collection. The various providers are configured via the <link linkend="data-sources-options">Data Sources Options</link>.
+</para>
+
+<para>
+Searches may use five different criteria: <guilabel>Title</guilabel>, <guilabel>Person</guilabel>, <guilabel>ISBN</guilabel>, <guilabel>UPC/EAN</guilabel>, or <guilabel>Keyword</guilabel>. Not all criteria are available for certain data sources.</para>
+
+<para>Once a search is initiated, the <guibutton>Search</guibutton> button becomes <guibutton>Stop</guibutton> which will end a search. As results are found, they are added to the list directly under the search box, where selecting an item will show the result without adding it to the collection. Clicking the <guibutton>Add Entry</guibutton> button will add all the selected items to your collection. If the data source has more results than were initially requested, the <guibutton>Get More Results</guibutton> button becomes active. Clicking <guibutton>Clear</guibutton> will remove all the current results and reset the search.
+</para>
+
+<screenshot>
+<screeninfo>The &appname; &fetch-dialog;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="fetch-dialog.png"/></imageobject>
+<textobject><phrase>The &appname; &fetch-dialog;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+Only entries that match the current collection type will be found. The <guilabel>Description</guilabel> column provides additional information about the entry, in order to differentiate between videos in different formats, or books in different bindings, for example. Once an entry is successfully added to the collection, a checkmark is added to the first column in the list.
+</para>
+
+<para>
+Multiple entries can be added at once by using the standard &kde; method for multiple selection, which usually involves holding the &Shift; or &Ctrl; key when clicking on an item.
+</para>
+
+<para>
+To facilitate the use of barcode scanners, searches can include multiple ISBN values. Selecting the <guilabel>Multiple ISBN search</guilabel> check box will disable the search box and enable the <guibutton>Edit ISBN list...</guibutton> button, which will open a multi-line text entry box. Each ISBN should be entered on a line by itself. After closing the box, each ISBN will be validated for correct formatting. The ISBN validation is able to convert 13-digit EAN values, as well as full <acronym>UPC</acronym> codes, to the proper formatting. The ISBN list may also be read from a text file.
+</para>
+
+</sect1>
+
+<sect1 id="importing">
+<title>Importing Data</title>
+
+<para>
+&appname; offers three different actions when importing data. <guilabel>Replace current collection</guilabel> will close the current collection, and create a new one with the data from the imported file. <guilabel>Append to current collection</guilabel> tells &appname; to add all the entries in the imported collection to the current one, and to add any fields which don't currently exist. The <guilabel>Merge collection</guilabel> action is the same as appending, except that each imported entry is compared to the current ones, and any identical entries are skipped. Future plans include an improved heuristic for identifying matching entries, but currently, except for music collections, they must be identical for every field. Music collections compare the artist and album only, and the tracks are merged for matching entries. The <link linkend="importing-audio-files">audio file importer</link> is able to correctly build track lists by merging entries.
+</para>
+
+<sect2 id="importing-tellico">
+<title>Importing &appname; Data</title>
+
+<para>
+Other &appname; data files may be imported. Replacing the current collection by importing a &appname; file is the same thing as just opening the file itself. The value of importing &appname; data is primarily for appending or merging two collections together.
+</para>
+</sect2>
+
+<sect2 id="importing-csv">
+<title>Importing CSV Data</title>
+
+<para>
+Comma-separated values (<acronym>CSV</acronym>) are a common way of importing and exporting tabular data. Each field value is separated by a comma, with one entry per line. The field titles may be included in the first line. The CSV importer is not limited to using a comma as the separator. Any character or string may be used.
+</para>
+
+<screenshot>
+<screeninfo>The CSV Import Dialog</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="csv-dialog.png"/></imageobject>
+<textobject><phrase>The CSV Import Dialog</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+First, select the type of collection that you are importing. If you are appending or merging to your open collection, the type is limited to your current collection type. If the first line of the CSV file contains the field titles, click the check box and the importer will automatically compare the titles against the fields in the current collection. If a field title matches, the header for that column changes to show that the column has been assigned to that field. If the file uses a delimiter other than a comma, be sure to change that option accordingly.
+</para>
+
+<para>
+In order for &appname; to properly import the file, it must know which field corresponds to each column. <emphasis>If the column only has a number in the header, the data in that column will not be imported.</emphasis> You should assign fields to each column by selecting a column, either by clicking in it or changing the column number itself, then selecting the field to assign from the drop down box and clicking the <guibutton>Assign Field</guibutton> button. If you need to add a new field to the collection, the last item in the dropdown list opens the <link linkend="fields-dialog">&fields-dialog;</link>.
+</para>
+
+<para>
+Only the first five lines of the imported CSV file are shown in the dialog.
+</para>
+
+</sect2>
+
+<sect2 id="importing-audio">
+<title>Importing Audio CD Data</title>
+
+<para>
+&appname; is able to use the <ulink url="http://freedb.org">freedb.org</ulink> service to lookup
+information about a <acronym>CD</acronym>, including the track list. Depending on your distribution,
+settings for access to the service may be set in the &kde; Control Center. The CD artist, title, genre,
+year, and track listing are all added.
+</para>
+
+<para>
+In addition, if the disc contains CD-Text, that information is read and added to the imported entry.
+</para>
+</sect2>
+
+<sect2 id="importing-audio-files">
+<title>Importing Audio File Metadata</title>
+
+<para>
+&appname; is able to scan a folder and read the tags for common audio file formats, such as <literal role="extension">mp3</literal> and <literal role="extension">ogg</literal>. The songs are entered in a music collection, where each entry is an album. If the song files contain the track number, the song name is inserted in the correct spot in the track list. The artist and genre information is also added to the entry. If the song tags contain comments, they are appended to the comments field in the entry, preceded by the file name.
+</para>
+
+<para>
+In addition, if a folder contains a <filename>.directory</filename> file and the folder name matches an album title, the <literal>Icon</literal> entry in the desktop file is used as the cover image for the album.
+</para>
+
+<para>
+The audio file metadata importer can recursively scan a folder to find all audio files in any subfolder, though symbolic links are not followed. &appname; uses the <ulink url="http://developer.kde.org/~wheeler/taglib.html">TagLib library</ulink> for reading the audio file metadata, and so can import data from any file type that TagLib understands.
+</para>
+
+</sect2>
+
+<sect2 id="importing-alexandria">
+<title>Importing Alexandria Libraries</title>
+
+<para>
+<application><ulink url="http://alexandria.rubyforge.org">Alexandria</ulink></application> is an alternate book collection manager for the <ulink url="http://www.gnome.org">GNOME</ulink> desktop environment. The importer offers a choice of importing any of the libraries found in <filename class="directory">$<envar>HOME</envar>/.alexandria/</filename>.
+</para>
+
+</sect2>
+
+<sect2 id="importing-amc">
+<title>Importing Ant Movie Catalog Data</title>
+
+<para>
+<application><ulink url="http://www.antp.be/software/moviecatalog/">Ant Movie Catalog</ulink></application> is an alternate movie collection manager.
+</para>
+
+</sect2>
+
+<sect2 id="importing-bibtex">
+<title>Importing Bibtex Data</title>
+
+<para>
+<ulink url="http://en.wikipedia.org/wiki/Bibtex">Bibtex</ulink> is a bibliography format used with the LaTeX document preparation system. Various type of bibliographic references may be included in the file. &appname; imports bibtex files as a Bibliographic collection.
+</para>
+
+<para>
+If the bibtex importer encounters fields in the file which are not in the default bibliography collection, they are added as <link linkend="line">Simple Text</link> fields, with two exceptions. If the field value contains more than 100 characters, it becomes a <link linkend="para">Paragraph</link> field. If the field value appears to contain a &URL; or a file reference, then a <link linkend="url">URL</link> field is created. &appname; uses an internal copy of the <ulink url="http://www.gerg.ca/software/btOOL/">btparse library</ulink> for parsing the bibtex files.
+</para>
+</sect2>
+
+<sect2 id="importing-bibtexml">
+<title>Importing Bibtexml Data</title>
+
+<para>
+<ulink url="http://bibtexml.sf.net">Bibtexml</ulink> is an &xml; representation of bibtex data, and the data from the imported bibtexml file is treated in the same way as bibtex data would be.
+</para>
+</sect2>
+
+<sect2 id="importing-delicious-library">
+<title>Importing Delicious Library Data</title>
+
+<para>
+<application><ulink url="http://www.delicious-monster.com/">Delicious Library</ulink></application> is an alternate collection manager for the Mac OS X desktop. &appname; imports a subset of the data used by Delicious Library.
+</para>
+</sect2>
+
+<sect2 id="importing-gcstar">
+<title>Importing GCstar Data</title>
+
+<para>
+<application><ulink url="http://www.gcstar.org">GCstar</ulink></application> is an alternate collection manager. Importing books, movies, music, coins, games, board games and wine collections is currently supported.
+</para>
+
+<para>
+&appname; can also import <application>GCfilms</application> data files. <application><ulink url="http://home.gna.org/gcfilms/">GCfilms</ulink></application> is the predecessor of <application>GCstar</application> and was an alternate movie collection manager. Normally, <application>GCfilms</application> data files are found in <filename class="directory">$<envar>HOME</envar>/.local/share/gcfilms/</filename>.
+</para>
+
+</sect2>
+
+<sect2 id="importing-griffith">
+<title>Importing Griffith Data</title>
+
+<para>
+<application><ulink url="http://griffith.berlios.de/">Griffith</ulink></application> is an alternate video collection manager. &appname; is able to import most data from a Griffith database.
+</para>
+</sect2>
+
+<sect2 id="importing-mods">
+<title>Importing MODS Data</title>
+
+<para>
+<acronym><ulink url="http://www.loc.gov/standards/mods/">MODS</ulink></acronym> is a format for representing various types of media collections. Currently, only books are imported by &appname;, as a Bibliographic collection.
+</para>
+
+</sect2>
+
+<sect2 id="importing-pdf">
+<title>Importing PDF Data</title>
+<para>
+If &appname; was compiled with <emphasis>exempi</emphasis> or <emphasis>poppler</emphasis> support, metadata from PDF files can be imported. Metadata may include title, author, and date information, as well as bibliographic identifiers which are then used to update other information.
+</para>
+</sect2>
+
+<sect2 id="importing-ris">
+<title>Importing RIS Data</title>
+<para>
+The <ulink url="http://www.adeptscience.co.uk/kb/article/A626"><acronym>RIS</acronym> format</ulink> is a bibliographic file format used by <application>Reference Manager</application> and others. &appname; imports RIS files as a Bibliographic collection.
+</para>
+</sect2>
+
+<sect2 id="importing-referencer">
+<title>Importing Referencer Data</title>
+<para>
+<application><ulink url="http://icculus.org/referencer/">Referencer</ulink></application> is a document organizer and bibliography manager for the GNOME desktop. &appname; will import most of the data found in a Referencer database.
+</para>
+</sect2>
+
+<sect2 id="importing-file-listing">
+<title>Importing File Listings</title>
+
+<para>
+The best way to create a <link linkend="file-catalog">File Catalog</link> is to import the contents of a folder. The folder may be searched recursively, to add all files found within. This importer is most useful for backup listings and media cataloging, such as <acronym>CD</acronym> or <acronym>DVD</acronym> listings. In addition, image previews of the file contents may be generated, although it can take some time to read a large number of files. The file previews are same as those shown in the &kde; file manager.
+</para>
+</sect2>
+
+<sect2 id="importing-xslt">
+<title>Importing &xml; Data via XSLT</title>
+
+<para>
+Any &xml; file may be imported into &appname; provided an XSL stylesheet is available to convert the file to &appname; format. &appname; automatically loads the stylesheet and performs the XSLT processing needed to load the file.
+</para>
+</sect2>
+
+</sect1>
+
+<sect1 id="drag-n-drop">
+<title>Drag and Drop</title>
+
+<para>Dragging data files to the main &appname; window and dropping them will import the files, just as if the <link linkend="importing">import command</link> was made from the menus. Drag and drop works for the following file formats: Tellico, Bibtex, RIS, and PDF. Importing multiple files at once is also supported.</para>
+
+<para>So, for example, if you want to catalog several <link linkend="importing-pdf">PDF files</link>, select them in the file manager and drag them to the &appname; window. &appname; will import as much metadata from the files as it can, and then fetch additional information from various configured Internet sources.</para>
+
+</sect1>
+
+<sect1 id="exporting">
+<title>Exporting Data</title>
+
+<para>
+When exporting the data in the collection, the entry values may be exported as entered, or with the <link linkend="field-formatting">automatic formatting</link> provided by &appname;. Additionally, the export may be limited to the currently selected entries of the collection as well, where the <link linkend="status-bar">statusbar</link> shows the number of selected entries.
+</para>
+
+<para>
+Exported text files, such as Bibtex or CSV, may use the Unicode (UTF-8) character encoding, or the current locale of the operating system.
+</para>
+
+<screenshot>
+<screeninfo>General Export Options</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="export-options.png"/></imageobject>
+<textobject><phrase>General Export Options</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<sect2 id="exporting-xml">
+<title>Exporting &xml;</title>
+
+<para>
+The file format for &appname; data is a zipped &xml; file. Exporting to &xml; merely creates the &xml; file without zipping it. Images may be included in the &xml; file as base64-encoded data in an image element, but doing so can create very large text files.
+</para>
+</sect2>
+
+<sect2 id="exporting-zip">
+<title>Exporting Zip</title>
+
+<para>
+The standard file format for &appname; is a zipped file, contained the &xml; collection file, and optionally, all the images referenced in the collection. If the images are being stored in the application folder instead, exporting to a Zip file will create a self-contained data file, which includes all the images in the collection.
+</para>
+</sect2>
+
+<sect2 id="exporting-html">
+<title>Exporting HTML</title>
+
+<para>
+The HTML export uses the <filename>tellico2html.xsl</filename> stylesheet. Images are exported to a folder with the same name as the exported HTML file with <emphasis><filename>_files</filename></emphasis> appended.
+</para>
+
+<para>
+The default format is similar to the printed output, and allows various options for modifying the HTML. Field headers may be printed at the top of each column, but unfortunately, &kde; does not yet allow the table headers to be be repeated on each page. The entries may be grouped as in the &group-view;, as well.
+</para>
+
+<para>
+Additionally, individual files may be created for each entry in the collection, with links created in the top-level HTML file. The entry files will be created in the same folder as the images. The entry HTML files will use the current stylesheet template, as shown in the &entry-view;.
+</para>
+
+<screenshot>
+<screeninfo>HTML Export Options</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="export-html.png"/></imageobject>
+<textobject><phrase>HTML Export Options</phrase></textobject>
+</mediaobject>
+</screenshot>
+</sect2>
+
+<sect2 id="exporting-csv">
+<title>Exporting CSV</title>
+
+<para>
+Comma-separated values (CSV) are a common way of importing and exporting tabular data. Each field value is separated by a comma, with one entry per line. The field titles may be included as headers in the first line. Any character or string other than a comma may also be used to delimit the fields.
+</para>
+
+<screenshot>
+<screeninfo>CSV Export Options</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="export-csv.png"/></imageobject>
+<textobject><phrase>CSV Export Options</phrase></textobject>
+</mediaobject>
+</screenshot>
+</sect2>
+
+<sect2 id="exporting-pilotdb">
+<title>Exporting Pilot-DB</title>
+
+<para>
+<ulink url="http://pilot-db.sourceforge.net">Pilot-DB</ulink> is a database format for Palm OS. Various desktop applications can read and write Pilot-DB files. Exported <literal role="extension">.pdb</literal> files can be transferred to a PDA, and used directly. At the moment, &appname; is not able to import Pilot-DB files.
+</para>
+
+<screenshot>
+<screeninfo>Pilot-DB Export Options</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="export-pdb.png"/></imageobject>
+<textobject><phrase>Pilot-DB Export Options</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+</sect2>
+
+<sect2 id="exporting-alexandria">
+<title>Exporting Alexandria</title>
+
+<para>
+<application><ulink url="http://alexandria.rubyforge.net">Alexandria</ulink></application> is a book collection manager for the <ulink url="http://www.gnome.org">GNOME</ulink> desktop environment. &appname; is able to export a limited subset of book collection fields to the default Alexandria data location.
+</para>
+
+</sect2>
+
+<sect2 id="exporting-onix">
+<title>Exporting ONIX</title>
+
+<para>
+<ulink url="http://www.editeur.org/onix.html">ONIX</ulink> is an XML format for representing and communicating book industry product information, primarily for book vendors. &appname; can export book collections using a small subset of ONIX.
+</para>
+
+</sect2>
+
+<sect2 id="exporting-bibtex">
+<title>Exporting Bibtex</title>
+
+<para>
+When exporting to <ulink url="http://en.wikipedia.org/wiki/Bibtex">Bibtex</ulink>, the field values may be escaped with braces or quotation marks. If any string macros
+are used in the collection, they may optionally be exported as macros or expanded. For &URL; fields, &appname;
+may enclose the field values with the <literal>\url{...}</literal> tag. Finally, entries with no citation key may be skipped rather than have &appname; auto-generate the key.
+</para>
+
+<screenshot>
+<screeninfo>Bibtex Export Options</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="export-bibtex.png"/></imageobject>
+<textobject><phrase>Bibtex Export Options</phrase></textobject>
+</mediaobject>
+</screenshot>
+</sect2>
+
+<sect2 id="exporting-bibtexml">
+<title>Exporting Bibtexml</title>
+
+<para>
+<ulink url="http://bibtexml.sourceforge.net">Bibtexml</ulink> is a format for expressing bibtex data via XML.
+</para>
+
+</sect2>
+
+<sect2 id="exporting-gcfilms">
+<title>Exporting GCfilms</title>
+
+<para>
+<application><ulink url="http://home.gna.org/gcfilms/">GCfilms</ulink></application> is another movie collection manager. &appname; is able to export a limited subset of video collection fields to a GCfilms data file.
+</para>
+
+</sect2>
+
+<sect2 id="exporting-xslt">
+<title>Exporting &xml; via &xslt;</title>
+
+<para>
+Finally, &appname; is able to process its internal &xml; representation of the collection data through an external XSL stylesheet before exporting. This type of export may be useful for generating text reports or other file types.
+</para>
+</sect2>
+
+</sect1>
+
+<sect1 id="citations">
+<title>Working With Citations</title>
+<para>
+When working with a <link linkend="bibliography">bibliography</link>, citations for the currently selected entries
+may be generated and used in various other applications. A citation in bibtex format can be copied to the clipboard,
+and then pasted in a latex file. Bibtex citations can also be pushed to an external application such as <application>LyX</application> or <application>Kile</application> using the so-called <emphasis><link linkend="hidden-bibtex-options">lyxpipe</link></emphasis>. Finally, limited support is available for interacting with <application>OpenOffice.org Writer</application>.
+</para>
+
+<sect2 id="openoffice-org">
+<title>Working with OpenOffice.org</title>
+<para>
+&appname; has some limited support for sending citations to <application>OpenOffice.org Writer</application> and
+updating the bibliography of a document. A special plugin is used, and if it is available, the menu command for
+citing an entry in <application>Writer</application> is enabled. If it is not enabled, then &appname; is either
+unable to find the plugin or is unable to load it. More information about building &appname; with
+OpenOffice.org support is in <link linkend="compilation-ooo">a later section</link>.
+</para>
+
+<para>
+<application>OpenOffice.org</application> must be configured to allow interaction from other applications.
+There are two methods: named pipes and TCP/IP. Named pipes are the easier and faster. To run
+<application>Writer</application> and connect with a named pipe, the following command may be used:
+
+<screen width="40">
+<prompt>%</prompt> <userinput>oowriter "-accept=pipe,name=OOo_pipe;urp;StarOffice.ServiceManager"</userinput>
+</screen>
+
+The pipe or TCP/IP port can be configured to be open every time OpenOffice.org is used. Check
+<ulink url="http://api.openoffice.org/docs/DevelopersGuide/OfficeBean/OfficeBean.xhtml#1_5_1_Default_Configuration">the OpenOffice.org documentation</ulink> for more details.
+</para>
+
+<para>
+To insert a citation, select the entry, then use the <guimenuitem>Cite Entry in OpenOffice.org</guimenuitem>.
+<application>Writer</application> must be running already. &appname;
+will attempt to connect, and if it fails, it will ask for more information about the connection.
+</para>
+
+<screenshot>
+<screeninfo>OpenOffice.org Connection Dialog</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="openoffice-dialog.png"/></imageobject>
+<textobject><phrase>OpenOffice.org Connection Dialog</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+Select the type of connection, either a pipe or a TCP/IP port. Enter the pipe name, or the hostname and port.
+&appname; will remember your connection settings for later use.
+</para>
+
+</sect2>
+
+</sect1>
+
+</chapter>
diff --git a/doc/en/index.docbook b/doc/en/index.docbook
new file mode 100644
index 0000000..1f4eeb4
--- /dev/null
+++ b/doc/en/index.docbook
@@ -0,0 +1,423 @@
+<?xml version="1.0" ?>
+<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.1.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [
+ <!ENTITY appname '<application>Tellico</application>'>
+ <!ENTITY kappname "&appname;">
+ <!ENTITY % addindex "IGNORE">
+ <!ENTITY % English "INCLUDE"><!-- change language only here -->
+
+ <!ENTITY robby "Robby Stephenson">
+ <!ENTITY email "robby@periapsis.org">
+ <!ENTITY homepage "http://www.periapsis.org/tellico/">
+ <!ENTITY maillist "http://forge.novell.com/mailman/listinfo/tellico-users">
+ <!ENTITY xml "<acronym>XML</acronym>">
+ <!ENTITY xslt "<acronym>XSLT</acronym>">
+ <!ENTITY html "<acronym>HTML</acronym>">
+ <!ENTITY css "<acronym>CSS</acronym>">
+
+ <!ENTITY group-view "<interface>Group View</interface>">
+ <!ENTITY detailed-view "<interface>Column View</interface>">
+ <!ENTITY entry-view "<interface>Entry View</interface>">
+ <!ENTITY entry-editor "<interface>Entry Editor</interface>">
+ <!ENTITY icon-view "<interface>Icon View</interface>">
+ <!ENTITY fields-dialog "<interface>Collection Fields Dialog</interface>">
+ <!ENTITY fetch-dialog "<interface>Internet Search Dialog</interface>">
+ <!ENTITY config-dialog "<interface>Configuration Dialog</interface>">
+ <!ENTITY find-dialog "<interface>Find Dialog</interface>">
+ <!ENTITY quick-filter "<interface>Quick Filter</interface>">
+ <!ENTITY filter-dialog "<interface>Advanced Filter Dialog</interface>">
+ <!ENTITY loan-dialog "<interface>Loan Dialog</interface>">
+ <!ENTITY report-dialog "<interface>Report Dialog</interface>">
+ <!ENTITY shortcut-dialog "<interface>Keyboard Shortcut Configuration Dialog</interface>">
+ <!ENTITY toolbar-dialog "<interface>Toolbar Configuration Dialog</interface>">
+ <!ENTITY filter-view "<interface>Filter View</interface>">
+ <!ENTITY loan-view "<interface>Loan View</interface>">
+
+ <!ENTITY fundamentals-chapter SYSTEM "fundamentals.docbook">
+ <!ENTITY importing-exporting-chapter SYSTEM "importing-exporting.docbook">
+ <!ENTITY configuration-chapter SYSTEM "configuration.docbook">
+ <!ENTITY fields-chapter SYSTEM "fields.docbook">
+ <!ENTITY menus-chapter SYSTEM "menus.docbook">
+ <!ENTITY advanced-chapter SYSTEM "advanced.docbook">
+ <!ENTITY hacking-chapter SYSTEM "hacking.docbook">
+ <!ENTITY faqs-chapter SYSTEM "faqs.docbook">
+ <!ENTITY details-chapter SYSTEM "details.docbook">
+
+]>
+
+<!-- ................................................................ -->
+
+<!-- The language must NOT be changed here. -->
+
+<book lang="&language;">
+
+<!-- This header contains all of the meta-information for the document such
+as Authors, publish date, the abstract, and Keywords -->
+
+<bookinfo>
+
+<!-- Date and version information of the documentation
+Don't forget to include this last date and this last revision number, we
+need them for translation coordination !
+Please respect the format of the date (DD/MM/YYYY) and of the version
+(V.MM.LL), it could be used by automation scripts.
+Do NOT change these in the translation. -->
+<date>02/01/2008</date>
+<releaseinfo>1.3</releaseinfo>
+
+<title>The &appname; Handbook</title>
+
+<authorgroup>
+<author>
+<firstname>Robby</firstname>
+<surname>Stephenson</surname>
+<affiliation>
+<address><email>&email;</email></address>
+</affiliation>
+</author>
+<!-- TRANS:ROLES_OF_TRANSLATORS -->
+</authorgroup>
+
+<copyright>
+<year>2001</year>
+<year>2002</year>
+<year>2003</year>
+<year>2004</year>
+<year>2005</year>
+<year>2006</year>
+<year>2007</year>
+<year>2008</year>
+<holder>&robby;</holder>
+</copyright>
+
+<!-- Translators: put here the copyright notice of the translation -->
+<!-- Put here the FDL notice. Read the explanation in fdl-notice.docbook
+ and in the FDL itself on how to use it. -->
+<legalnotice>
+<para>Permission is granted to copy, distribute and/or modify this
+document under the terms of the &GNU; Free Documentation License,
+Version 1.1 or any later version published by the Free Software
+Foundation; with &FDLInvariantSections;, with &FDLFrontCoverText;, and
+with &FDLBackCoverText;. A copy of the license is included in
+<xref linkend="gnu-fdl"/>.</para>
+
+<para>The author of this documentation has also granted you permission to use
+the content under the terms of the <ulink
+url="freebsd-doc-license.html">FreeBSD Documentation License</ulink>, if you so choose.
+See the notice in the <link linkend="gnu-fdl">licensing section</link>.</para>
+</legalnotice>
+<!--<legalnotice>&FDLNotice;</legalnotice>-->
+
+<legalnotice>
+<para>This program is free software; you can redistribute it and/or
+modify it under the terms of version 2 of the &GNU; General Public
+License as published by the Free Software Foundation.</para>
+
+<para>This program is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the &GNU;
+General Public License for more details.</para>
+
+<para>You should have received a copy of the &GNU; General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifh Floor, Boston, MA 02110-1301, USA.</para>
+</legalnotice>
+<!--<legalnotice>&GPLNotice;</legalnotice>-->
+
+<!-- Abstract about this handbook -->
+
+<abstract>
+<para>
+This document is a handbook for using &appname;, a collection manager software application.
+</para>
+</abstract>
+
+<!-- This is a set of Keywords for indexing by search engines.
+Please at least include KDE, the KDE package it is in, the name
+ of your application, and a few relevant keywords. -->
+
+<keywordset>
+<keyword>KDE</keyword>
+<keyword>tellico</keyword>
+<keyword>book</keyword>
+<keyword>bibliography</keyword>
+<keyword>movie</keyword>
+<keyword>collection</keyword>
+<keyword>database</keyword>
+<keyword>catalog</keyword>
+</keywordset>
+
+</bookinfo>
+
+<!-- The contents of the documentation begin here. Label each chapter
+so with the id attribute. This is necessary for two reasons: it allows
+you to easily reference the chapter from other chapters of your
+document, and if there is no ID, the name of the generated HTML files
+will vary from time to time making it hard to manage for maintainers
+and for the CVS system. Any chapter labelled (OPTIONAL) may be left
+out at the author's discretion. Other chapters should not be left out
+in order to maintain a consistent documentation style across all KDE
+apps. -->
+
+<chapter id="introduction">
+<title>Introduction</title>
+
+<!-- The introduction chapter contains a brief introduction for the
+application that explains what it does and where to report
+problems. Basically a long version of the abstract. Don't include a
+revision history. (see installation appendix comment) -->
+
+<sect1 id="tellico-intro">
+<title>&appname;</title>
+
+<para>
+&appname; is a program for managing collections. It began as a simple
+book collection manager, and has expanded to include default
+collection templates for bibliographies, comic books, videos, music,
+coins, stamps, trading cards, video games, wines, board games, and file listings.
+In addition, custom collections can be built for any other type of collectibles.
+</para>
+
+<sect2 id="what-tellico-is">
+<title>What &appname; Is</title>
+
+<para>
+&appname; keeps track of the items in a collection, and offers
+an easy way to enter data for each entry. It provides several
+field types, and allows for an unlimited number of
+user-defined fields. The entries in a collection may be grouped by any
+field for easy organization, and customizable views show as much or as
+little information as you like.
+</para>
+
+<para>
+Loans may be tracked, with optional integration with &korganizer;. Collections may be
+imported or exported using a variety of formats, to allow for easy exchange
+or publication of data.
+</para>
+
+</sect2>
+
+<sect2 id="what-tellico-is-not">
+<title>What &appname; Is Not</title>
+
+<para>
+&appname; is not an audio or video player. It does not provide
+facilities for reading or modifying multimedia files. It also does
+not provide any image-editing functionality. Although &appname; has some
+functionality for managing bibliography lists, it is not a full-blown
+bibliographic reference manager. &appname; also does not pretend to have
+all the capabilities of a full-fledged relational database,
+</para>
+
+<para>
+As somewhat of a disclaimer, &appname; is a hobby for the author, and no
+guarantees are made about its functionality, usefullness, or otherwise. It's
+very far from being a professional software package. More information is included
+in the <link linkend="gnu-fdl">license declaration</link>.
+</para>
+
+</sect2>
+</sect1>
+
+<sect1 id="terminology">
+<title>Terminology</title>
+
+<sect2 id="collections">
+<title>Collections</title>
+<para>
+In &appname;, a collection is the document. Only one collection exists in each &appname;
+file. A collection contains any number of <link linkend="fields">fields</link> and
+<link linkend="entries">entries</link>. &appname; supports 12 specific collection types by
+default: books, bibliographic entries, comic books, videos, music, trading cards, coins, stamps,
+video games, wines, board games, and file listings. In addition, an empty generic collection
+template is available for any other type of collectibles or lists.
+</para>
+</sect2>
+
+<sect2 id="fields">
+<title>Collection Fields</title>
+<para>
+Each collection may have an unlimited number of fields. &appname; supports eleven types of fields,
+which allow for a range of different data. The fields can be edited with the
+<link linkend="fields-dialog">&fields-dialog;</link> and are explained further in the
+<link linkend="field-types">Field Types</link> section.
+</para>
+</sect2>
+
+<sect2 id="entries">
+<title>Collection Entries</title>
+
+<para>
+An entry is the basic record in &appname;. Each entry contains a single value for each field in
+the collection. A collection may have an unlimited number of entries, in theory, although since
+the whole collection is always resident in memory, too many entries could slow down the application.
+</para>
+
+<para>
+&appname; has been tested with a collection of 10,000 entries, and the speed was satisfactory.
+However, if many large images are included in the collection, the loading and processing time
+does slow down greatly. Performance can be improved by having &appname; store images separate from
+the data file itself, either in the application-specific directory or a directory relative to
+the data file. More information can be found in the
+<link linkend="configuration">configuration section</link>.
+</para>
+
+</sect2>
+
+</sect1>
+
+</chapter>
+
+&fundamentals-chapter;
+
+&details-chapter;
+
+&importing-exporting-chapter;
+
+&advanced-chapter;
+
+&configuration-chapter;
+
+&hacking-chapter;
+
+&faqs-chapter;
+
+&menus-chapter;
+
+<chapter id="credits">
+
+<!-- Include credits for the programmers, documentation writers, and
+contributors here. The license for your software should then be
+included below the credits with a reference to the appropriate license
+file included in the KDE distribution. -->
+
+<title>Credits and License</title>
+
+<para>
+&appname;
+</para>
+<para>
+Program copyright 2001-2008 &robby; <email>&email;</email>
+</para>
+
+&underGPL; <!-- GPL License -->
+
+<para>
+Documentation copyright 2001-2008 &robby; <email>&email;</email>
+</para>
+
+<!-- TRANS:CREDIT_FOR_TRANSLATORS -->
+
+<para id="gnu-fdl" xreflabel="the section entitled &quot;GNU Free Documentation
+License&quot;">This documentation is licensed under the terms of the <ulink
+url="common/fdl-license.html">&GNU; Free Documentation
+License (GFDL)</ulink>.</para>
+
+<para>The author of this documentation has also granted you permission to use the content under the terms of the <ulink
+url="freebsd-doc-license.html">FreeBSD Documentation License</ulink>, if you so choose. If you wish to allow use of your version of this content only under the terms of the FreeBSD Documentation License, and not to allow others to use your version of this file under the terms of the GFDL, indicate your decision by deleting the GFDL notice and and replacing it with the notice and other provisions required by the FreeBSD Documentation License. If you do not delete the GFDL notice above, a recipient may use your version of this file under the terms of either the GFDL or the FreeBSD Documentation License.</para>
+
+</chapter>
+
+<appendix id="installation">
+<title>Installation</title>
+
+<sect1 id="getting-tellico">
+<title>How to obtain &appname;</title>
+
+<para>
+The &appname; home page can be found at
+<ulink url="&homepage;">&homepage;</ulink>.
+Updates and news can be found there.</para>
+</sect1>
+
+<sect1 id="requirements">
+<title>Requirements</title>
+
+<!--
+List any special requirements for your application here. This should include:
+.Libraries or other software that is not included in kdesupport,
+kdelibs, or kdebase.
+.Hardware requirements like amount of RAM, disk space, graphics card
+capabilities, screen resolution, special expansion cards, etc.
+.Operating systems the app will run on. If your app is designed only for a
+specific OS, (you wrote a graphical LILO configurator for example) put this
+information here.
+-->
+
+<para>
+In order to successfully use &appname;, you need &kde; 3.3.1.
+&appname; uses about 5 megabytes of memory to run, but this may vary
+depending on your platform, configuration, and most of all, your collection size.
+</para>
+
+<para>
+&kde; can be found at <ulink url="http://www.kde.org">the &kde; home page</ulink>.
+</para>
+
+<!-- For a list of updates, you may refer to the application web site
+or the ChangeLog file, or ... -->
+<para>
+You can find a list of changes at <ulink
+url="&homepage;">&homepage;</ulink>.
+</para>
+</sect1>
+
+<sect1 id="compilation">
+<title>Compilation and Installation</title>
+
+<para>
+In order to compile and install &appname; on your system, type the following
+in the base folder of the archive, where the third step must be done as
+root if you are installing in a system folder:
+
+<screen width="40">
+<prompt>%</prompt> <userinput>./configure <option>--enable-final</option> <option>--disable-debug</option></userinput>
+<prompt>%</prompt> <userinput>make</userinput>
+<prompt>%</prompt> <userinput>make install</userinput>
+</screen>
+</para>
+
+<para>Since &appname; uses autoconf and automake you should not have
+any trouble compiling it. Should you run into problems please report
+them to the the author at <email>&email;</email>.</para>
+
+<sect2 id="compilation-ooo">
+<title>Compiling With OpenOffice.org</title>
+<para>
+&appname; uses a special plugin for communicating with OpenOffice.org, which is not compiled by default.
+The Software Development Kit, available from <ulink url="http://www.openoffice.org/dev_docs/source/sdk/">
+http://www.openoffice.org/dev_docs/source/sdk/</ulink>, is required.
+
+<screen width="40">
+<prompt>%</prompt> <userinput>./configure <option>--enable-ooo</option> <option>--with-ooo-dir</option>=<filename class="directory">/usr/lib/openoffice</filename> <option>--with-ooo-sdk-dir</option>=<filename class="directory">/usr/lib/openoffice/SDK</filename></userinput>
+</screen>
+
+You'll need to use the correct locations of the OpenOffice.org libraries and SDK, of course.
+</para>
+
+<para>
+In addition, some distributions may require you to modify the <filename>/etc/ld.so.conf</filename> file
+or add a configuration file to the <filename class="directory">/etc/ld.so.conf.d</filename> directory. Check
+to see if the OpenOffice.org plugin works without any changes first. If it doesn't, try editing
+<filename>/etc/ld.so.conf</filename> and adding the location of the OpenOffice.org libraries, the same as
+you used for the <filename>configure</filename> script.
+For additional help, use the <ulink url="&maillist;">&appname; Mailing List</ulink>
+</para>
+</sect2>
+
+</sect1>
+
+</appendix>
+
+&documentation.index;
+
+</book>
+<!--
+Local Variables:
+mode: sgml
+sgml-minimize-attributes:nil
+sgml-general-insert-case:lower
+sgml-indent-step:0
+sgml-indent-data:nil
+End:
+-->
diff --git a/doc/en/loan-dialog.png b/doc/en/loan-dialog.png
new file mode 100644
index 0000000..2bfd30d
--- /dev/null
+++ b/doc/en/loan-dialog.png
Binary files differ
diff --git a/doc/en/loan-view.png b/doc/en/loan-view.png
new file mode 100644
index 0000000..a5c12bf
--- /dev/null
+++ b/doc/en/loan-view.png
Binary files differ
diff --git a/doc/en/main-window.png b/doc/en/main-window.png
new file mode 100644
index 0000000..97e968f
--- /dev/null
+++ b/doc/en/main-window.png
Binary files differ
diff --git a/doc/en/menus.docbook b/doc/en/menus.docbook
new file mode 100644
index 0000000..174eb6a
--- /dev/null
+++ b/doc/en/menus.docbook
@@ -0,0 +1,768 @@
+<chapter id="menus">
+<title>Command Reference</title>
+
+<!--
+(OPTIONAL, BUT RECOMMENDED) This chapter should list all of the
+application windows and their menubar and toolbar commands for easy reference.
+Also include any keys that have a special function but have no equivalent in the
+menus or toolbars. This may not be necessary for small apps or apps with no tool
+or menu bars.
+-->
+
+<sect1 id="main-window-menus">
+<title>The Main &appname; Window</title>
+
+<para>Each menu item is discussed below. When there is a keyboard shortcut that
+performs a menu item function, the default shortcut is listed with the menu item.
+</para>
+
+<sect2>
+<title>The <guimenu>File</guimenu> Menu</title>
+
+<para>
+<variablelist>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>File</guimenu>
+ <guimenuitem>New</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>creates a new collection</action>. &appname; supports <link linkend="collection-types">12 default collection types</link> along with an empty user-defined custom collection.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>O</keycap></keycombo>
+ </shortcut>
+ <guimenu>File</guimenu>
+ <guimenuitem>Open...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens a &appname; file</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>File</guimenu>
+ <guimenuitem>Open Recent</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens a file</action> from a submenu
+that contains a list of recently opened files.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>S</keycap></keycombo>
+ </shortcut>
+ <guimenu>File</guimenu>
+ <guimenuitem>Save...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>saves the collection</action>. If the file is
+<emphasis>Untitled</emphasis> then <guimenuitem>Save...</guimenuitem> is equivalent to
+<guimenuitem>Save As</guimenuitem>. It is only enabled when the collection has been
+modified.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>File</guimenu>
+ <guimenuitem>Save As...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>saves the collection to a new file</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>P</keycap></keycombo>
+ </shortcut>
+ <guimenu>File</guimenu>
+ <guimenuitem>Print...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>prints the collection</action>. Printing options may be set in the &config-dialog;.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>File</guimenu>
+ <guimenuitem>Import</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>imports data from another file</action>. &appname; can import data from a number of <link linkend="importing">other formats</link>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>File</guimenu>
+ <guimenuitem>Export</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>exports the collection to another format</action>. &appname; can export data to a number of <link linkend="exporting">other formats</link>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>Q</keycap></keycombo>
+ </shortcut>
+ <guimenu>File</guimenu>
+ <guimenuitem>Quit</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>closes the &appname; window</action>. If the collection has unsaved changes, you will be prompted to save them before continuing.</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+</sect2>
+
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EDIT MENU %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%-->
+<sect2>
+<title>The <guimenu>Edit</guimenu> Menu</title>
+
+<para>
+
+<variablelist>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>Z</keycap></keycombo>
+ </shortcut>
+ <guimenu>Edit</guimenu>
+ <guimenuitem>Undo</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>undoes the previous action</action>. Not all actions are supported by Undo.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>&Shift;</keycap><keycap>Z</keycap></keycombo>
+ </shortcut>
+ <guimenu>Edit</guimenu>
+ <guimenuitem>Redo</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>reverts a previous Undo.</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>X</keycap></keycombo>
+ </shortcut>
+ <guimenu>Edit</guimenu>
+ <guimenuitem>Cut</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>removes the selected text</action>, if any, and <action>places a copy of the removed text in the clipboard</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>C</keycap></keycombo>
+ </shortcut>
+ <guimenu>Edit</guimenu>
+ <guimenuitem>Copy</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>copies the selected text</action>, if any, to the clipboard.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>V</keycap></keycombo>
+ </shortcut>
+ <guimenu>Edit</guimenu>
+ <guimenuitem>Paste</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>pastes the text in the clipboard</action>,if any, into the editor at the cursor position.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>A</keycap></keycombo>
+ </shortcut>
+ <guimenu>Edit</guimenu>
+ <guimenuitem>Select All</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>selects all the entries</action> in the collection, in the &detailed-view;.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>&Shift;</keycap><keycap>A</keycap></keycombo>
+ </shortcut>
+ <guimenu>Edit</guimenu>
+ <guimenuitem>Deselect</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>deselects all the entries</action> in the collection.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Edit</guimenu>
+ <guimenuitem>Internet Search...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens the &fields-dialog;</action> to search for and import entries from various Internet sites, including <ulink url="http://amazon.com">Amazon.com</ulink>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>J</keycap></keycombo>
+ </shortcut>
+ <guimenu>Edit</guimenu>
+ <guimenuitem>Advanced Filter...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens the &filter-dialog;</action>.</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+</para>
+</sect2>
+
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% COLLECTION MENU %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%-->
+<sect2>
+<title>The <guimenu>Collection</guimenu> Menu</title>
+<para>
+
+<variablelist>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>N</keycap></keycombo>
+ </shortcut>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>New Entry</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens the &entry-editor; to edit a new entry</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>E</keycap></keycombo>
+ </shortcut>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Edit Entry</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens the &entry-editor; to edit the selected entries</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>Y</keycap></keycombo>
+ </shortcut>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Duplicate Entry</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>copies, or duplicates, the selected entries</action> as new entries in the collection.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>D</keycap></keycombo>
+ </shortcut>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Delete Entry</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>deletes the selected entries</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Update Entry</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This menu contains a list of all available data sources, and can be used to autmatically query the
+source and <action>update the selected entries</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Check-out.</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens a dialog box for loaning the selected entries.</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Check-in</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>checks-in any of the selected entries which are currently on-loan</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>R</keycap></keycombo>
+ </shortcut>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Rename Collection</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens a dialog box for renaming the collection</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>U</keycap></keycombo>
+ </shortcut>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Collection Fields...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens the &fields-dialog;</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>U</keycap></keycombo>
+ </shortcut>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Generate Reports...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens the &report-dialog;</action> for generating reports about the collection.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Convert to Bibliography</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>converts a book collection to a bibliography</action> by adding certain fields necessary for Bibtex export, and it is only enabled when a book collection is open.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>String Macros...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens a dialog box for editing the Bibtex string macros</action> in the collection. It is only enabled when editing a bibliography.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Copy Bibtex to Clipboard</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>copies a Bibtex citation</action> to the clipboard so that it can pasted in a LaTeX document.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Cite Entry in Lyx</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>sends a citation for the selected entries</action> to the so-called <emphasis><link linkend="hidden-bibtex-options">lyxpipe</link></emphasis> for use in <application>LyX</application>, <application>Kile</application>, or other LaTeX applications. It is only enabled when editing a bibliography.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Cite Entry in OpenOffice.org</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>sends a citation for the selected entries</action> to <application>OpenOffice.org Writer</application>. It is only enabled when editing a bibliography when the OpenOffice.org plugin is available.</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+</para>
+</sect2>
+
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SETTINGS MENU %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%-->
+<sect2>
+<title>The <guimenu>Settings</guimenu> Menu</title>
+<para>
+
+<variablelist>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Settings</guimenu>
+ <guimenuitem>Toolbars</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>toggles the display of the toolbars</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Settings</guimenu>
+ <guimenuitem>Show Statusbar</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>toggles the display of the statusbar</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Settings</guimenu>
+ <guimenuitem>Show &group-view;</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>toggles the display of the &group-view;</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Settings</guimenu>
+ <guimenuitem>Show &entry-editor;</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>toggles the display of the &entry-editor;</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Settings</guimenu>
+ <guimenuitem>Show &entry-view;</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>toggles the display of the &entry-view;</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Settings</guimenu>
+ <guimenuitem>Group Selection</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>changes the field used to group the entries</action> in the collection.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Settings</guimenu>
+ <guimenuitem>Configure Shortcuts...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens the the &kde; &shortcut-dialog;</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Settings</guimenu>
+ <guimenuitem>Configure Toolbars...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens the the &kde; &toolbar-dialog;</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Settings</guimenu>
+ <guimenuitem>Configure &appname;...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens the &appname; &config-dialog;</action>.</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+</para>
+</sect2>
+
+<sect2>
+<title>The <guimenu>Help</guimenu> Menu</title>
+<para>
+
+<variablelist>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Help</guimenu>
+ <guimenuitem>&appname; Handbook</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens the &appname; Handbook</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Shift;</keycap><keycap>F1</keycap></keycombo>
+ </shortcut>
+ <guimenu>Help</guimenu>
+ <guimenuitem>What's This?</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>changes the mouse cursor to an arrow with a question mark</action>. Clicking on items in the window will show a small tooltip (if one exists for that item) explaining what the item does.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Help</guimenu>
+ <guimenuitem>Tip of the Day</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens the Tip of the Day dialog</action>. You can page through all the tips by using the buttons on the dialog.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Help</guimenu>
+ <guimenuitem>Report Bug...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>open the Submit Bug Report dialog</action>. If you find
+a bug or a problem, if you have a suggestion for improvement, or a translation correction, use this interface to send the author an email.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Help</guimenu>
+ <guimenuitem>About &appname;</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens the About &appname; dialog</action>, showing version and author information for the application.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Help</guimenu>
+ <guimenuitem>About &kde;</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>This command <action>opens the About &kde; dialog</action>, showing the &kde; version and other information about the desktop environment.</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+</para>
+</sect2>
+
+</sect1>
+</chapter>
diff --git a/doc/en/openoffice-dialog.png b/doc/en/openoffice-dialog.png
new file mode 100644
index 0000000..0618807
--- /dev/null
+++ b/doc/en/openoffice-dialog.png
Binary files differ
diff --git a/doc/en/print-options.png b/doc/en/print-options.png
new file mode 100644
index 0000000..03dd7a3
--- /dev/null
+++ b/doc/en/print-options.png
Binary files differ
diff --git a/doc/en/report-dialog.png b/doc/en/report-dialog.png
new file mode 100644
index 0000000..ff6cbe0
--- /dev/null
+++ b/doc/en/report-dialog.png
Binary files differ
diff --git a/doc/en/source-options.png b/doc/en/source-options.png
new file mode 100644
index 0000000..eac74ab
--- /dev/null
+++ b/doc/en/source-options.png
Binary files differ
diff --git a/doc/en/sru-options.png b/doc/en/sru-options.png
new file mode 100644
index 0000000..a1a649a
--- /dev/null
+++ b/doc/en/sru-options.png
Binary files differ
diff --git a/doc/en/template-options.png b/doc/en/template-options.png
new file mode 100644
index 0000000..f805d73
--- /dev/null
+++ b/doc/en/template-options.png
Binary files differ
diff --git a/doc/en/z3950-options.png b/doc/en/z3950-options.png
new file mode 100644
index 0000000..5650ba1
--- /dev/null
+++ b/doc/en/z3950-options.png
Binary files differ
diff --git a/doc/fr/CMakeLists.txt b/doc/fr/CMakeLists.txt
new file mode 100644
index 0000000..8e5d934
--- /dev/null
+++ b/doc/fr/CMakeLists.txt
@@ -0,0 +1,60 @@
+INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${KDE3_INCLUDE_DIR} ${QT_INCLUDE_DIR} )
+
+
+########### install files ###############
+
+
+
+
+#original Makefile.am contents follow:
+
+######## kdevelop will overwrite this part!!! (begin)##########
+#
+#
+#EXTRA_DIST = \
+#advanced.docbook \
+#configuration.docbook \
+#details.docbook \
+#faqs.docbook \
+#fundamentals.docbook \
+#hacking.docbook \
+#importing-exporting.docbook \
+#index.docbook \
+#menus.docbook \
+#freebsd-doc-license.html \
+#entry-editor1.png \
+#entry-editor3.png \
+#entry-editor4.png \
+#entry-editor5.png \
+#fields-dialog.png \
+#general-options.png \
+#main-window.png \
+#print-options.png \
+#template-options.png \
+#source-options.png \
+#filter-dialog.png \
+#csv-dialog.png \
+#fetch-dialog.png \
+#export-options.png \
+#export-html.png \
+#export-csv.png \
+#export-pdb.png \
+#export-bibtex.png \
+#amazon-options.png \
+#z3950-options.png \
+#externalexec-options.png \
+#report-dialog.png \
+#loan-dialog.png \
+#loan-view.png \
+#filter-view.png \
+#openoffice-dialog.png \
+#sru-options.png \
+#imdb-options.png
+#
+#
+######## kdevelop will overwrite this part!!! (end)############
+#
+#KDE_LANG = fr
+#KDE_DOCS = tellico
+#
+#CLEANFILES = *~
diff --git a/doc/fr/Makefile.am b/doc/fr/Makefile.am
new file mode 100644
index 0000000..0d55385
--- /dev/null
+++ b/doc/fr/Makefile.am
@@ -0,0 +1,50 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+
+EXTRA_DIST = \
+advanced.docbook \
+configuration.docbook \
+details.docbook \
+faqs.docbook \
+fundamentals.docbook \
+hacking.docbook \
+importing-exporting.docbook \
+index.docbook \
+menus.docbook \
+freebsd-doc-license.html \
+entry-editor1.png \
+entry-editor3.png \
+entry-editor4.png \
+entry-editor5.png \
+fields-dialog.png \
+general-options.png \
+main-window.png \
+print-options.png \
+template-options.png \
+source-options.png \
+filter-dialog.png \
+csv-dialog.png \
+fetch-dialog.png \
+export-options.png \
+export-html.png \
+export-csv.png \
+export-pdb.png \
+export-bibtex.png \
+amazon-options.png \
+z3950-options.png \
+externalexec-options.png \
+report-dialog.png \
+loan-dialog.png \
+loan-view.png \
+filter-view.png \
+openoffice-dialog.png \
+sru-options.png \
+imdb-options.png
+
+
+####### kdevelop will overwrite this part!!! (end)############
+
+KDE_LANG = fr
+KDE_DOCS = tellico
+
+CLEANFILES = *~
diff --git a/doc/fr/advanced.docbook b/doc/fr/advanced.docbook
new file mode 100644
index 0000000..54f04b7
--- /dev/null
+++ b/doc/fr/advanced.docbook
@@ -0,0 +1,120 @@
+<chapter id="advanced">
+<title>Utilisation avancée</title>
+
+<sect1 id="command-line">
+<title>Options en ligne de commande</title>
+
+<para>
+Lorsque vous exécutez &appname; depuis la ligne de commande, il existe plusieurs
+options pour ouvrir des fichiers de données. Ces options peuvent être vues en
+exécutant <userinput>tellico --help</userinput>.
+</para>
+
+<programlisting>
+Usage: tellico [Qt-options] [KDE-options] [options] [filename]
+
+Tellico - a collection manager for KDE
+
+Options:
+ --nofile Do not reopen the last open file
+ --bibtex Import &lt;filename&gt; as a bibtex file
+ --mods Import &lt;filename&gt; as a MODS file
+ --ris Import &lt;filename&gt; as a RIS file
+
+Arguments:
+ filename File to open
+</programlisting>
+
+</sect1>
+
+<sect1 id="dcop-interface">
+<title>Interface &DCOP;</title>
+
+<para>
+&appname; dispose d'une interface &DCOP; minimale, qui peut être utilisée pour
+automatiser l'application ou interagir avec depuis une la ligne de commande.
+Co,,e pour tous les appels &DCOP;, vous devez spécifier l'application avec
+laquelle vous souhaitez interagir ; ainsi que l'interface spécifique. Les appels
+&DCOP; décris dans ce document sont tous disponibles dans l'interface
+<constant>tellico</constant> de &appname; ; alors que le nom de l'application
+est <constant>tellico-pid</constant>, où <emphasis>pid</emphasis> est le
+<emphasis>process id</emphasis> de l'application.
+</para>
+
+<sect2 id="dcop-commands">
+<title>Commandes DCOP</title>
+
+<para>
+La liste complète des commandes &DCOP; de l'objet <constant>tellico</constant>
+est disponible ci-dessous :
+</para>
+
+<programlisting>
+bool importTellico(QString file, QString action)
+bool importBibtex(QString file, QString action)
+bool importMODS(QString file, QString action)
+bool importRIS(QString file, QString action)
+bool exportXML(QString file)
+bool exportBibtex(QString file)
+bool exportHTML(QString file)
+bool exportCSV(QString file)
+bool exportPilotDB(QString file)
+QStringList bibtexKeys()
+</programlisting>
+
+<para>
+Pour les quatre commandes d'import, le premier paramètre est le nom du fichier
+à importer, et le second l'action lors de l'import. Trois types d'actions sont
+disponibles : <emphasis>replace</emphasis> (remplacer),
+<emphasis>append</emphasis> (ajouter) et <emphasis>merge</emphasis> (fusioner).
+Quatre formats de fichier sont possibles pour l'import : fichier XML Tellico,
+BibTeX, MODS et RIS.
+</para>
+
+<para>
+La collection ouverte dans &appname; peut être exportée vers un fichier, dans
+le format XML de Tellico, BibTeX, HTML ou CSV.
+</para>
+
+<para>
+Enfin, si la collection courante est un bibliographie, appeler
+<command>bibtexKeys()</command> donnera comme résultat la clef de citation
+BibTeX de toutes les entées sélectionnées.
+</para>
+
+</sect2>
+
+<sect2 id="dcop-examples">
+<title>Exemples DCOP</title>
+
+<para>
+Voici quelques exemples de scripts &appname; utilisant l'interface &DCOP;.
+Puisque le <emphasis>pid</emphasis> doit être connu, la façon la plus simple de
+l'inclure dans la commande shell suivante :
+<userinput>dcop $(dcop | grep tellico) tellico</userinput>.
+</para>
+
+<screen width="40">
+<emphasis>Ouvrir un fichier BibTeX</emphasis>
+<prompt>%</prompt>
+<userinput>dcop $(dcop | grep tellico) tellico importBibtex ~/documents/reference.bib replace</userinput>
+<computeroutput>true</computeroutput>
+</screen>
+
+<screen width="40">
+<emphasis>Exporter un fichier BibTeX</emphasis>
+<prompt>%</prompt> <userinput>dcop $(dcop | grep tellico) tellico exportBibtex ~/documents/reference.bib</userinput>
+<computeroutput>true</computeroutput>
+</screen>
+
+<screen width="40">
+<emphasis>Afficher la clef de citation de la sélection courante</emphasis>
+<prompt>%</prompt> <userinput>dcop $(dcop | grep tellico) tellico bibtexKeys</userinput>
+<computeroutput>stephenson2004</computeroutput>
+</screen>
+
+</sect2>
+
+</sect1>
+
+</chapter>
diff --git a/doc/fr/amazon-options.png b/doc/fr/amazon-options.png
new file mode 100644
index 0000000..2f7d673
--- /dev/null
+++ b/doc/fr/amazon-options.png
Binary files differ
diff --git a/doc/fr/configuration.docbook b/doc/fr/configuration.docbook
new file mode 100644
index 0000000..dc65eb6
--- /dev/null
+++ b/doc/fr/configuration.docbook
@@ -0,0 +1,445 @@
+<chapter id="configuration">
+<title>Configuration</title>
+
+
+<para>
+La <interface>Boite de dialogue de configuration</interface> contient toutes
+les options pour changer certains comportements par défaut de &appname;.
+</para>
+
+<para>
+Cliquer sur le bouton <guibutton>Appliquer</guibutton>
+<action>applique les modification immédiatement</action>,
+sans fermer la boite de dialogue, alors que le bouton <guibutton>OK</guibutton>
+<action>applique les changements et ferme la boite de dialogue</action>.
+<guibutton>Annuler</guibutton> ferme la boite de dialogue ; mais toutes les
+modifications déjà appliquées seront conservées.
+Le bouton <guibutton>Défaut</guibutton> <action>rétablit les options</action>
+de la page courante de la boite de dialogue à leurs valeurs par défaut, alors
+que <guibutton>Aide</guibutton> <action>ouvre &khelpcenter;</action> à la
+section relative du manuel de &appname;.
+</para>
+
+<para>
+Certains paramètres ne peuvent être modifiés qu'en éditant le fichier de
+configuration à la main. Voir les
+<link linkend="hidden-options">Options de configuration cachées</link>.
+</para>
+
+<sect1 id="general-options">
+<title><guilabel>Options Générales</guilabel></title>
+
+<screenshot>
+<screeninfo>Les options générales</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="general-options.png"/></imageobject>
+<textobject><phrase>La boite de dialogue d'options générales</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+La boite de dialogue des <guilabel>options générales</guilabel> contrôle le
+comportement global. Les images peuvent être incluses dans le fichier de
+données ; ou enregistrées dans le répertoire de &appname;. De plus, lorsque
+&appname; est démarré, il peut automatiquement ouvrir le dernier fichier ouvert.
+La boite de dialogue de l'<guilabel>astuce du jour</guilabel> contient des
+astuces utiles sur l'utilisation de &appname; et apparaît au démarrage du
+programme. Vous pouvez lire quelques astuces puis désactiver la boite de
+dialogue.
+</para>
+
+<para>
+Les <guilabel>options de mise en forme</guilabel> contrôlent le niveau de mise
+en forme automatique effectué par &appname;. Des exemples sont disponibles dans
+la section<link linkend="field-formatting">Mise en forme des champs</link>.
+La mise en majuscules et la mise en forme sont des options distinctes, un champ
+pouvant être mis en majuscules sans que l'ordre des mots soit changé et
+inversement. La mise en forme automatique inclut les articles dans les titres,
+ainsi que les préfixes et suffixes des noms propres. Les valeurs sont
+insensibles à la casse et doivent être séparées par un point)virgule.
+</para>
+
+<para>
+Les règles de mise en forme suivent les standards anglais et peuvent être
+incompatibles avec d'autres langues. Les articles sont déplacés à la fin du
+titre, précédés d'une virgule. Les noms propres sont transformés pour placer
+le nom propre en premier, suivi d'une virgule et du prénom. Les suffixes, tels
+que Jr., sont conservés avec le nom propre. Les particules, telles que
+<emphasis>von</emphasis> ou <emphasis>de</emphasis>, sont conservées avec le
+nom propre ; mais sont ignorées lorsque les noms sont triés.
+</para>
+
+<informalexample><para><emphasis>John Q. von Public, III</emphasis>
+deviendrait <emphasis>von Public, III, John Q.</emphasis> ; et
+<emphasis>Public</emphasis> serait utilisé pour le tri.</para></informalexample>
+
+<para>
+Seuls les particules en un seul mot sont gérées. Si un nom inclut
+<emphasis>de la</emphasis>, par exemple, <emphasis>de</emphasis> et
+<emphasis>la</emphasis> doivent être inclus dans la liste des particules.
+Les articles se finissant par une apostrophe sont également gérés pour le tri.
+</para>
+
+<note><para>Les données réelles contenues dans la collection
+<emphasis>ne sont pas</emphasis> modifiées, seul le texte affiché est affecté.
+Ainsi, les options de mise en forme peuvent être modifiées sans altérer les
+données de la collection.</para></note>
+
+</sect1>
+
+<sect1 id="printing-options">
+<title><guilabel>Options d'impression</guilabel></title>
+
+<para>
+&appname; utilise une feuille de style &xslt; pour générer du &html; ; puis le
+transmet au service d'impression de &kde;. Seuls les champs visibles dans la
+<link linkend="detailed-view">&detailed-view;</link> sont imprimés. De plus, si
+la collection a des filtres appliqués, seules les entrées visibles sont
+imprimées. Un message d'avertissement est affiché si un filtre est actif.
+</para>
+
+<screenshot>
+<screeninfo>La boîte de dialogue des options d'impression</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="print-options.png"/></imageobject>
+<textobject><phrase>La boîte de dialogue des options d'impression</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+Les <guilabel>Options d'impression</guilabel> vous permettent de modifier
+certains aspects de la mise en forme lorsque vous imprimez une collection.
+Si <guilabel>Mettre en forme les titres et noms</guilabel> est coché, les champs
+sont <link linkend="field-formatting">mis en forme automatiquement</link>.
+Dans le cas contraire, elles sont imprimées telles qu'elles ont été saisies.
+</para>
+
+<para>
+La feuille de style d'impression par défaut affiche les valeurs des champs en
+colonnes. <guilabel>Imprimer les en-têtes des champs</guilabel> contrôle si les
+titres des champs sont imprimés au sommet des colonnes.
+</para>
+
+<para>
+A l'impression, les entrées sont triées de la même manière que dans la
+<link linkend="detailed-view">&detailed-view;</link>. Cependant, elles peuvent
+être groupées selon la <link linkend="group-view">&group-view;</link> à la place
+en utilisant l'option <guilabel>Grouper les entrés</guilabel>.
+</para>
+
+<para>
+Enfin, lorsque les champs contenant des images sont inclus à l'impression, les
+images peuvent être re-dimensionnées, tout en conservant leur rapport
+largeur/hauteur. La largeur et la hauteur maximales définissent les dimensions
+à ne pas dépasser, une image n'étant jamais agrandie.
+</para>
+</sect1>
+
+<sect1 id="template-options">
+<title><guilabel>Options des modèles</guilabel></title>
+
+<para>
+La <link linkend="entry-view">&entry-view;</link> utilise des modèles pour
+afficher les valeurs des champs. Vous pouvez définir un modèle différent pour
+chaque type de collection. Certains modèles, tels que ceux définis pour les
+<emphasis>Albums</emphasis> ou les <emphasis>Vidéos</emphasis> sont spécifiques
+à un type de collection donné ; et un message d'erreur apparaîtra dans la
+&entry-view; s'ils sont utilisés pour d'autres types de collections.
+</para>
+
+<para>
+Les modèles additionnels peuvent être installés dans
+<filename class="directory">$<envar>KDEHOME</envar>/share/apps/tellico/entry-templates/</filename>.
+</para>
+
+<screenshot>
+<screeninfo>La boîte de dialogue des options de modèles</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="template-options.png"/></imageobject>
+<textobject><phrase>La boîte de dialogue des options de modèles</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+</sect1>
+
+<sect1 id="data-sources-options">
+<title><guilabel>Options des sources d'informations</guilabel></title>
+
+<para>
+&appname; peut utiliser différentes sources pour importer des données, qui
+peuvent être configurées dans la boîte de dialogue des sources d'informations.
+Différents types de sources sont disponibles :
+</para>
+
+<itemizedlist>
+<listitem><para><link linkend="amazon-web-services">Web Services Amazon.com</link>,</para></listitem>
+<listitem><para><link linkend="imdb">Internet Movie Database 9</link>,</para></listitem>
+<listitem><para><link linkend="z3950">Serveurs z39.50</link>,</para></listitem>
+<listitem><para><link linkend="sru">Serveurs SRU</link>,</para></listitem>
+<listitem><para><link linkend="entrez">Bases de données Entrez (PubMed)</link>,</para></listitem>
+<listitem><para><link linkend="yahoo">Yahoo! Audio Search</link>,</para></listitem>
+<listitem><para><link linkend="animenfo">AnimeNfo.com</link>,</para></listitem>
+<listitem><para><link linkend="ibs">Internet Bookshop Italia</link>,</para></listitem>
+<listitem><para><link linkend="isbndb">ISBNdb.com</link>,</para></listitem>
+<listitem><para><link linkend="allocine">Allociné.fr</link>,</para></listitem>
+<listitem><para>Le <link linkend="minculture">Ministère de la culture espagnole</link>,</para></listitem>
+<listitem><para><link linkend="darkhorse">Dark Horse Comics</link>,</para></listitem>
+<listitem><para><link linkend="externalexec">D'autres scripts ou applications externes</link></para></listitem>
+</itemizedlist>
+
+<screenshot>
+<screeninfo>La boîte de dialogue des sources d'informations</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="source-options.png"/></imageobject>
+<textobject><phrase>La boîte de dialogue des sources d'informations</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+De nouvelles sources peuvent être ajoutées en cliquant sur le bouton
+<guibutton>Ajouter...</guibutton>. Celles existantes peuvent aisément être
+modifiées ou supprimées, à l'aide des boutons <guibutton>Modifier...</guibutton>
+<guibutton>Supprimer</guibutton>.
+</para>
+
+<para>
+Certaines sources d'informations contiennent plus d'informations que les champs
+par défaut de &appname;. Ces autres champs sont affichés sur la droite de la
+boîte de dialogue. Si l'un de ces champs est coché, il est alors ajouté à la
+collection lorsqu'une entrée de cette source est ajoutée.
+</para>
+
+<sect2 id="amazon-web-services">
+<title>Amazon.com</title>
+
+<para>
+En utilisant les Services Web Amazon, &appname; peut chercher des informations
+sur six différents sites internationaux gérés par
+<ulink url="http://amazon.com">Amazon.com</ulink> : États Unis, Royaume Uni,
+Allemagne, Japon, France et Canada.
+</para>
+
+<screenshot>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="amazon-options.png"/></imageobject>
+</mediaobject>
+</screenshot>
+
+<para>
+Configurer chaque source Amazon.com nécessite trois paramètres : l'adresse du
+serveur, la taille de l'image et l'ID de l'associé. Certaines informations de
+<ulink url="http://amazon.com">Amazon.com</ulink> contiennent une image, telle
+que la couverture d'un livre ou la jaquette d'une vidéo. Cette image peut être
+télé-chargée en trois différentes tailles, en fonction du produit. Pour éviter
+qu'un trop grand nombre d'images ralentisse l'application, les images moyennes
+ou grandes ne sont pas recommandées. L'ID de l'associé doit être utilisée pour
+accéder aux Services Web Amazon.com et sont inclus dans les liens vers les
+produits, en accord avec les conditions d'utilisation des Services Web
+Amazon.com.
+</para>
+
+</sect2>
+
+<sect2 id="imdb">
+<title>Base de données de films sur Internet (IMDb)</title>
+
+<para>
+La <ulink url="http://www.imdb.com">base de données de films sur Internet (IMDb)</ulink>
+fournit des informations à propos des films et des vidéos. Quand une recherche
+est faite pour une <emphasis>personne</emphasis>, si plus d'un résultat est
+retourné, une boîte de dialogue est ouverte pour vous permettre de choisir la
+bonne référence. Les options de configuration concernent l'adresse du serveur
+web et si les images doivent être télé-chargées ou non. IMDb pouvant donner un
+nombre important de participants à un film, vous pouvez limiter ce nombre.
+</para>
+
+<screenshot>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="imdb-options.png"/></imageobject>
+</mediaobject>
+</screenshot>
+
+</sect2>
+
+<sect2 id="z3950">
+<title>Serveurs z39.50</title>
+
+<para>
+Le <ulink url="http://www.cni.org/pub/NISO/docs/Z39.50-brochure/50.brochure.toc.html">protocole z39.50</ulink>
+est utilisé pour accéder à des bibliothèques et des fournisseurs d'informations
+bibliographiques à travers le Monde. Des listes de serveurs z39.50 publics sont
+<ulink url="http://www.indexdata.dk/targettest/">disponibles sur indexdata.dk</ulink>,
+entre autres. &appname; peut accéder à tous les serveurs z39.50 fournissant des
+données dans les formats <acronym>MODS</acronym>,
+<acronym>USMARC</acronym>/<acronym>MARC21</acronym>, ou
+<acronym>UNIMARC</acronym>, en utilisant la
+<ulink url="http://www.indexdata.dk/yaz/">bibliothèque yaz</ulink>.
+Une gestion limitée du format <acronym>GRS-1</acronym> est également disponible.
+</para>
+
+<screenshot>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="z3950-options.png"/></imageobject>
+</mediaobject>
+</screenshot>
+
+<para>
+Le port par défaut pour accéder à un serveur z39.50 est 210, mais certains
+serveurs peuvent en utiliser un différent. &appname; considère que le serveur
+utilise l'encodage de caractères MARC-8, sauf s'il est configuré autrement. Si
+un encodage de caractères incorrect est utilisé, un message d'erreur peut être
+affiché, ou l'import peut ne donner aucun résultat.
+</para>
+
+<para>
+Certains serveurs nécessitent un nom d'utilisateur et un mot de passe pour y
+accéder. &appname; peut utiliser et sauvegarder ce mot de passe ; mais soyez
+conscient qu'il sera écrit en clair dans le fichier de configuration de
+&appname; et ne sera pas en sécurité. Pour la plupart des serveurs publics, le
+nom d'utilisateur et le mot de passe peut être laissé vides.
+</para>
+
+</sect2>
+
+<sect2 id="sru">
+<title>Serveurs SRU</title>
+
+<para>
+SRU signifie
+<ulink url="http://www.loc.gov/standards/sru/">Search/Retrieve via URL</ulink>.
+Il d'un protocole de recherche pour Internet. Certaines bibliothèques
+l'utilisent pour permettre l'accès à leurs catalogues de données. Parmi
+celles-ci, la
+<ulink url="http://www.loc.gov/z3950/lcserver.html#oppr">bibliothèque du congrès américain</ulink>
+est probablement la plus connue.
+</para>
+
+<screenshot>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="sru-options.png"/></imageobject>
+</mediaobject>
+</screenshot>
+
+</sect2>
+
+<sect2 id="entrez">
+<title>Bases de données Entrez</title>
+<para>
+<ulink url="http://www.ncbi.nlm.nih.gov/Entrez/">Entrez</ulink> est un système
+de recherche et de récupération d'informations, utilisé au centre national
+d'information sur la biotechnologie américain (National Center for
+Biotechnology Information, NCBI). La base de données Entrez la plus connue est
+<ulink url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=PubMed">PubMed</ulink>,
+la base de données d'articles sur les sciences de la vie pour de nombreux
+journaux traitant de biologie. Pour le moment, la seule base de données Entrez
+gérée par &appname; est PubMed.
+</para>
+</sect2>
+
+<sect2 id="yahoo">
+<title>Recherche Yahoo! Audio</title>
+<para>
+Le service de recherche
+<ulink url="http://audio.search.yahoo.com">Yahoo! Audio</ulink> peut être
+utilisé pour chercher les informations sur les albums de musique.
+</para>
+</sect2>
+
+<sect2 id="animenfo">
+<title>AnimeNfo.com</title>
+<para>
+<ulink url="http://www.animenfo.com">AnimeNfo</ulink> est un site populaire
+d'informations sur l'animation japonaise.
+</para>
+</sect2>
+
+<sect2 id="ibs">
+<title>Internet Bookstore Italia</title>
+<para>
+<ulink url="http://ibs.it">IBS, ou Internet Bookstore Italia</ulink>, est un
+magasin en ligne italien, vendant des livres.
+</para>
+</sect2>
+
+<sect2 id="isbndb">
+<title>ISBNdb.com</title>
+<para>
+<ulink url="http://isbndb.com">ISBNdb.com</ulink> est une base de données en
+ligne de livres, comprenant des informations provenant de plusieurs pays.
+</para>
+</sect2>
+
+<sect2 id="allocine">
+<title>Allociné.fr</title>
+<para>
+<ulink url="http://www.allocine.fr">Allociné.fr</ulink> est une base de données
+française en ligne de filme. Cette source
+<link linkend="externalexec">fonctionne sous la forme d'un script</link> et
+nécessite l'installation de <ulink url="http://python.org">Python</ulink>.
+</para>
+</sect2>
+
+<sect2 id="minculture">
+<title>Ministre espagnol de la culture</title>
+<para>
+Le <ulink url="http://www.mcu.es">Ministre espagnol de la culture</ulink> est
+une base de données en ligne espagnole de livres. Cette source
+<link linkend="externalexec">fonctionne sous la forme d'un script</link> et
+nécessite l'installation de <ulink url="http://python.org">Python</ulink>.
+</para>
+</sect2>
+
+<sect2 id="darkhorse">
+<title>Dark Horse Comics</title>
+<para>
+<ulink url="http://darkhorse.com">Dark Horse Comics</ulink> est une éditeur de
+bandes dessinées. Cette source
+<link linkend="externalexec">fonctionne sous la forme d'un script</link> et
+nécessite l'installation de <ulink url="http://python.org">Python</ulink>.
+</para>
+</sect2>
+
+<sect2 id="externalexec">
+<title>Scripts ou applications externes</title>
+<para>
+Pour importer plus facilement des données externes dans &appname;, il est
+possible d'utiliser des scripts ou applications externes en tant qu'interfaces
+de recherche. &appname; exécute une commande, et passe les termes recherchés en
+tant que paramètres de ligne de commande.
+</para>
+
+<screenshot>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="externalexec-options.png"/></imageobject>
+</mediaobject>
+</screenshot>
+
+<para>
+Le type de collection renvoyé par le script soit être configuré, ainsi que le
+format de données. Non seulement &appname; peut importer des données de scripts
+utilisant le
+<link linkend="file-format">format &xml; de &appname; par défaut</link> ; mais
+il peut également gérer d'autres formats tels que BibTeX.
+</para>
+
+<para>
+Le chemin complet de l'application doit être entré dans les options de source.
+L'application est exécutée avec les droits de l'utilisateur en cours, prenez
+donc garde à ne pas utiliser de script d'origine inconnue. Vérifiez que les
+boîtes à côté des clefs de recherche sont bien gérées par l'application, et
+entrez les options de la ligne de commande.La valeur cherchée est insérée à la
+place de <userinput>%1</userinput>.
+</para>
+
+<para>
+Pour mettre à jour des entrées déjà dans la collection, les dernières à cocher
+et de saisie de texte sont utilisées pour déterminer les options de ligne de
+commande. Les champs de l'entrée utilisés pour trouver une mise à jour doivent
+être saisis dans le même format que les champs de type
+<emphasis><link linkend="dependent">Dépendant</link></emphasis>.
+</para>
+</sect2>
+
+</sect1>
+
+</chapter>
diff --git a/doc/fr/csv-dialog.png b/doc/fr/csv-dialog.png
new file mode 100644
index 0000000..9b04388
--- /dev/null
+++ b/doc/fr/csv-dialog.png
Binary files differ
diff --git a/doc/fr/details.docbook b/doc/fr/details.docbook
new file mode 100644
index 0000000..f49df7c
--- /dev/null
+++ b/doc/fr/details.docbook
@@ -0,0 +1,613 @@
+<chapter id="details">
+<title>Détails de &appname;</title>
+
+<sect1 id="field-types">
+<title>Types de champs</title>
+
+<para>
+Chaque collection peut avoir un nombre illimité de champs. &appname; gère
+onze types de champs, permettant une large variété de données différentes.
+</para>
+
+<sect2 id="line">
+<title>Texte simple</title>
+
+<para>
+Le type de champ de base est appelé <emphasis>Texte Simple</emphasis>. Aucune
+restrictions ne s'applique aux valeurs, et l'élément d'édition est une simple
+ligne. Ce type convient aux champs destinés à ne pas contenir de long texte,
+tels que l' auteur ou le genre d'un livre.
+</para>
+
+</sect2>
+<sect2 id="number">
+<title>Nombre</title>
+
+<para>
+Le type <emphasis>Nombre</emphasis> est identique au
+<emphasis>Texte simple</emphasis>, mais le contenu est restreint aux valeurs
+numériques. Les entrées seront triées par ordre numérique croissant si l'on
+clique sur l'en-tête d'un champ de type <emphasis>Nombre</emphasis>. La ligne
+d'éditions classique est utilisée, avec des flèches pour augmenter ou diminuer
+la valeur. Aucune mise en forme n'est appliquée.
+</para>
+
+</sect2>
+
+<sect2 id="url">
+<title>&URL;</title>
+
+<para>
+Le type <emphasis>&URL;</emphasis> permet d'inclure un lien vers un autre
+document, en utilisant l'association au type de fichier de &kde; pour l'ouvrir.
+Aucune vérification n'est effectuée sur le contenu d'un champ
+<emphasis>&URL;</emphasis> ; mais les liens non valides ne sont pas ouverts.
+L'élément de saisie est une ligne d'édition avec un bouton pour ouvrir la boîte
+de dialogue standard d'ouverture de fichier ; mais tout type d'&URL; peut être
+utilisé. Les &URL; relatives sont interprétées par rapport au chemin du fichier
+de données, une fois qu'il a été enregistré.
+</para>
+
+<para>
+Dans l'<link linkend="entry-editor">&entry-editor;</link>, le texte devient un
+lien ; alors que dans la <link linkend="entry-view">&entry-view;</link>, un
+hyperlien classique est utilisé. Ce type de champ convient pour lier à des
+fichiers <acronym>PDF</acronym> pour des entrées bibliographiques ou des
+critiques de film par exemple. Aucune mise en forme n'est appliquée.
+</para>
+
+<para>
+Des &URL; relatives peuvent également être utilisées. Elles sont interprétées
+par rapport au chemin du fichier de données &appname;. Dans
+l'<link linkend="entry-editor">&entry-editor;</link>, la ligne d'édition
+permet l'auto-complétion pour les fichiers locaux. Si vous souhaitez que
+l"&URL; fournie par le sélecteur de fichiers &kde; soit interprétée de façon
+relative par rapport au fichier &appname;, ajoutez une propriété étendue pour
+le champ &URL; avec comme valeurs
+<emphasis>relative</emphasis> : <emphasis>true</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="para">
+<title>Paragraphe</title>
+
+<para>
+Pour les textes plus longs, le type <emphasis>Paragraphe</emphasis>offre une
+zone d'édition plus importante, dans sa propre catégorie. Un champ de type
+<emphasis>Paragraphe</emphasis> ne peut être à multiples values, ni mis en
+forme automatiquement. Il ne peut pas être utilisé pour le regroupement.
+Les résumée, introductions et critiques devraient être saisies dans ce type de
+champ.
+</para>
+
+</sect2>
+
+<sect2 id="choice">
+<title>Choix</title>
+
+<para>
+Quand un champ doit être limité à quelques valeurs pré-sélectionnées, un champ
+de type <emphasis>Choix</emphasis> est utilisé. Les valeurs possibles sont
+présentées dans une liste déroulante. Évidement, le principe des valeurs
+multiples ne s'applique pas à ce type de champ. Les champs tels que le type
+de bibliographie ou de notation sont de type <emphasis>Choix</emphasis>.
+</para>
+
+<para>Des point-virgules doivent être utilisés pour séparer les valeurs
+possibles.</para>
+
+</sect2>
+
+<sect2 id="bool">
+<title>Case à cocher</title>
+
+<para>
+Pour les champs prenant seulement comme valeurs oui ou non, le type
+<emphasis>Case à cocher</emphasis> est disponible. Par défaut, la case n'est
+pas cochée. Le champ n'est bien entendu pas mis en forme et est limité à une
+seule valeur. En interne, les valeurs sont enregistrées en tant que
+<emphasis><constant>true</constant></emphasis> et
+<emphasis><constant>false</constant></emphasis>. Les champs "offert" et "prêté"
+sont de ce type.</para>
+
+</sect2>
+
+<sect2 id="date">
+<title>Date</title>
+
+<para>
+Un champ de type <emphasis>Date</emphasis> peut inclure jour, mois et année.
+La date est affichée au format AAAA-MM-JJ, qui permet de les trier facilement.
+Le sélecteur de date &kde; peut être utilisé pour choisir la date à la souris,
+ou celle)ci peut être entrée à la main. Les trois champs jour, mois et année
+peuvent être vide. Il n'est bien sûr pas possible d'avoir des valeurs
+multiples.
+</para>
+
+</sect2>
+
+<sect2 id="table">
+<title>Tableau</title>
+
+<para>
+Les champs de type <emphasis>Tableau</emphasis> contienent une ou plusieurs
+colonnes de valeurs. Dans l'<link linkend="entry-editor">&entry-editor;</link>,
+le champ se présente comme un tableur avec des lignes numérotées. Lorsque la
+dernière ligne est sélectionnée, une ligne supplémentaire est ajoutée.
+L'auto-complétion n'est pas disponible. Ce champ est utile pour la liste des
+chapitres d'un livre, des scènes d'un livre ou des titres d'un album. Les
+champs de type <emphasis>Tableau</emphasis> sont toujours dans leur propre
+catégorie.
+</para>
+
+<para>
+Le nombre de colonnes, un maximum de dix, est défini en ajoutant une propriété
+à la définition du champ avec le nom <emphasis>columns</emphasis>. Il est
+possible de leur attribuer un titre en cliquant du bouton droit sur l'en-tête,
+ou en ajoutant une propriété au champ de type <emphasis>column1</emphasis>,
+etc.
+</para>
+
+<para>
+Lors de l'utilisation de l'&entry-editor; pour les champs de type
+<emphasis>Tableau</emphasis>, les lignes peuvent être réordonnées en les
+déplaçant avec la souris tout en maintenant le bouton &Ctrl;. Un menu est
+également disponible en cliquant du bouton droit sur le tableau, qui permet
+d'insérer ou supprimer des lignes.
+</para>
+
+</sect2>
+
+<sect2 id="image">
+<title>Image</title>
+
+<para>
+Un champ de type <emphasis>Image</emphasis> contient une image, dans un format
+reconnu par &kde;, tel que <acronym>PNG</acronym> ou <acronym>JPEG</acronym>.
+L'image peut être enregistrée dans le fichier de données &appname; lui-même ou
+dans le répertoire de données de l'application. Le sélecteur de fichiers &kde;
+est utilisé, donc vous pouvez utiliser une &URL; ou un fichier local. Les images
+peuvent également être glissée depuis un gestionnaire de fichiers ou un
+navigateur.
+</para>
+
+</sect2>
+
+<sect2 id="rating">
+<title>Note</title>
+
+<para>
+Les champs de type <emphasis>Note</emphasis> affichent un nombre d'étoiles
+représentant la note numérique d'une entrée. Par défaut, la note maximale est
+cinq. Le minimum et le maximum peuvent être configurées dans la &fields-dialog;,
+en ajoutant les propriétés <emphasis>minimum</emphasis> et
+<emphasis>maximum</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="dependent">
+<title>Dépendant</title>
+
+<para>
+Le dernier type de champ est le type <emphasis>Dépendant</emphasis>, que vous
+n'utiliserez probablement pas souvent. Il est utilisé pour combiner les valeurs
+d'autres champs en utilisant les valeurs des descriptions de champs. Par
+exemple, si un champ de type <emphasis>Dépendant</emphasis> a comme description
+<userinput>%{title} %{year}</userinput>, la valeur de ce champ sera le titre
+suivi de l'année. Ce type de champ est principalement pour le titre dans les
+collections de monnaies, timbres, cartes et vins. Le nom interne ou le titre
+de champ peut être utilisé dans la description pour la mise en forme.
+</para>
+</sect2>
+
+</sect1>
+
+<sect1 id="collection-types">
+<title>Types de collections</title>
+
+<para>
+&appname; gère onwe types de collections par défaut : livres, entrées
+bibliographiques, bandes dessinées, vidéos, musique, jeux vidéo, cartes,
+monnaie, timbres, vins; jeux de plateau et catalogues de fichiers. De plus, un modèle de
+collection générique est disponible pour tout autre type d'objet à
+collectionner. Les collections sont uniquement présentes pour inclure un jeu de
+champs, vous pouvez en ajouter, modifier et effacer pour l'adapter à vos
+besoins. La seule obligation est qu'une collection doit toujours avoir un champ
+<emphasis>Titre</emphasis>, pour que la
+<link linkend="group-view">&group-view;</link> puisse fonctionner
+correctement. Pour certains types de collections, il s'agit seulement d'un champ
+<emphasis><link linkend="dependent">Dépendant</link></emphasis> combinant les
+valeurs d'autres champs.
+</para>
+
+<para>
+Il n'y a pas de différence fonctionnelle entre les types de collections. Vous
+pourriez créer une collection personnalisée pour vos livres aussi facilement
+qu'en utilisant la collection de livres par défaut. Cependant, &appname; choisit
+les icônes en en fonction du type de collection et certaines fonctionnalités
+peuvent être spécifiques à certaines collections ; donc si vous le pouvez, il
+est recommandé d'utiliser les types par défaut. Par exemple, si vous souhaitez
+créer une collection de vins mais n'aimez pas les champs par défaut, créez une
+collection par défaut et modifiez les champs. De cette façon, &appname; sait
+qu'il s'agit d'une collection de vins.
+</para>
+
+<sect2 id="book-collection">
+<title>Collections de livres</title>
+<para>
+Les collections de livres ont 26 champs par défaut.
+<emphasis>Titre</emphasis>,
+<emphasis>Sous-titre</emphasis>,
+<emphasis>Auteur</emphasis>,
+<emphasis>Reliure</emphasis>,
+<emphasis>Date d'achat</emphasis>,
+<emphasis>Prix d'achat</emphasis>,
+<emphasis>Éditeur</emphasis>,
+<emphasis>Édition</emphasis>,
+<emphasis>Année du copyright</emphasis>,
+<emphasis>Année de publication</emphasis>,
+<emphasis>ISBN#</emphasis>,
+<emphasis>LCCN#</emphasis>,
+<emphasis>Pages</emphasis>,
+<emphasis>Langue</emphasis>,
+<emphasis>Genre</emphasis>,
+<emphasis>Mots clef</emphasis>,
+<emphasis>Série</emphasis>,
+<emphasis>Numéro</emphasis>,
+<emphasis>État</emphasis>,
+<emphasis>Signé</emphasis>,
+<emphasis>Lu</emphasis>,
+<emphasis>Offert</emphasis>,
+<emphasis>Prêté</emphasis>,
+<emphasis>Note</emphasis>,
+<emphasis>Couverture</emphasis>, et
+<emphasis>Commentaires</emphasis>.
+</para>
+
+<para>
+Le champ <emphasis>ISBN#</emphasis> est spécial, les numéros
+<acronym>ISBN</acronym> étant automatiquement mis en forme et leur chiffre de
+vérification calculé.
+&appname; reconnaît un champ <acronym>ISBN</acronym> si son nom interne est
+<emphasis>isbn</emphasis>. Si vous l'effacez ou souhaitez l'ajouter à un autre
+type de collection, créez un champ avec comme titre <emphasis>ISBN</emphasis>,
+appliquez la modification, puis donnez-lui le titre désiré. &appname; crée le
+nom interne en fonction du titre initial ; mais ne le met pas à jour en cas de
+changement.
+</para>
+
+</sect2>
+
+<sect2 id="bibliography">
+<title>Bibliographies</title>
+<para>
+Les Bibliographies ont 22 champs par défaut.
+<emphasis>Titre</emphasis>,
+<emphasis>Type d'entrée</emphasis>,
+<emphasis>Auteur</emphasis>,
+<emphasis>Clef BibTeX</emphasis>,
+<emphasis>Titre du livre</emphasis>,
+<emphasis>Éditeur</emphasis>,
+<emphasis>Organisation</emphasis>,
+<emphasis>Publié par</emphasis>,
+<emphasis>Adresse</emphasis>,
+<emphasis>Édition</emphasis>,
+<emphasis>Pages</emphasis>,
+<emphasis>Année</emphasis>,
+<emphasis>Journal</emphasis>,
+<emphasis>Mois</emphasis>,
+<emphasis>Numéro</emphasis>,
+<emphasis>Publié</emphasis>,
+<emphasis>Chapitre</emphasis>,
+<emphasis>Série</emphasis>,
+<emphasis>Volume</emphasis>,
+<emphasis>Référence croisée</emphasis>, et
+<emphasis>Notes</emphasis>.
+</para>
+
+<para>
+Bien que les collections bibliographiques ne soient pas spécifiquement liées à
+BibTeX, les champs par défaut sont ceux habituellement trouvés dans BibTeX.
+Lors de l'export au format BibTeX, une propriété étendue appelée
+<emphasis>bibtex</emphasis> est utilisée pour chaque champ afin de définir le
+champ BibTeX correspondant. Si vous ajoutez un champ supplémentaire et souhaitez
+le voir exporté vers BibTeX, assurez-vous qu'il dispose bien de la propriété
+étendue <emphasis>bibtex</emphasis>.
+</para>
+
+<para>
+&appname; dispose de certaines fonctions spécifiques aux bibliographies. Des
+macros BibTeX peuvent être ajoutées, modifiées ou effacées depuis &appname; ;
+et l'export au format BibTeX vous donne la possibilité d'appliques les macros.
+Les citations BibTeX peuvent être transmises à une application externe telle
+que <application>LyX</application> ou <application>Kile</application>, à l'aide
+ de ce qu'on appelle des
+<emphasis><link linkend="hidden-bibtex-options">lyxpipe</link></emphasis>.
+</para>
+
+<para>
+Les collections de livres peuvent être converties en bibliographies. Les champs
+liés à BibTeX sont alors ajoutés, et les propriétés étendues configurées. Cette
+fonctionnalité existe principalement pour convertir les anciennes collections,
+avant que le type "bibliographie" soit séparé de celui "collection de livres.
+</para>
+</sect2>
+
+<sect2 id="comic-book-collection">
+<title>Collections de bandes dessinées</title>
+<para>
+Les collections de bandes dessinées ont 22 champs par défaut.
+<emphasis>Titre</emphasis>,
+<emphasis>Sous-titre</emphasis>,
+<emphasis>Auteur</emphasis>,
+<emphasis>Artiste</emphasis>,
+<emphasis>Collection</emphasis>,
+<emphasis>Numéro</emphasis>,
+<emphasis>Éditeur</emphasis>,
+<emphasis>Édition</emphasis>,
+<emphasis>Année de publication</emphasis>,
+<emphasis>Pages</emphasis>,
+<emphasis>Pays</emphasis>,
+<emphasis>Langue</emphasis>,
+<emphasis>Genre</emphasis>,
+<emphasis>Mots clef</emphasis>,
+<emphasis>État</emphasis>,
+<emphasis>Date d'achat</emphasis>,
+<emphasis>Prix d'achat</emphasis>,
+<emphasis>Signé</emphasis>,
+<emphasis>Offert</emphasis>,
+<emphasis>Prêté</emphasis>,
+<emphasis>Couverture</emphasis>, et
+<emphasis>Commentaires</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="video-collection">
+<title>Collections de vidéos</title>
+<para>
+Les collections de vidéos ont 30 champs par défaut.
+<emphasis>Titre</emphasis>,
+<emphasis>Support</emphasis>,
+<emphasis>Année de production</emphasis>,
+<emphasis>Certification</emphasis>,
+<emphasis>Genre</emphasis>,
+<emphasis>Région</emphasis>,
+<emphasis>Nationalité</emphasis>,
+<emphasis>Format</emphasis>,
+<emphasis>Acteurs</emphasis>,
+<emphasis>Réalisateur</emphasis>,
+<emphasis>Producteur</emphasis>,
+<emphasis>Auteur</emphasis>,
+<emphasis>Compositeur</emphasis>,
+<emphasis>Studio</emphasis>,
+<emphasis>Langues disponibles</emphasis>,
+<emphasis>Langues des sous-titres</emphasis>,
+<emphasis>Plages audio</emphasis>,
+<emphasis>Durée</emphasis>,
+<emphasis>Format</emphasis>,
+<emphasis>Écran large</emphasis>,
+<emphasis>Couleurs</emphasis>,
+<emphasis>Version du réalisateur</emphasis>,
+<emphasis>Trame</emphasis>,
+<emphasis>Note personnelle</emphasis>,
+<emphasis>Date d'achat</emphasis>,
+<emphasis>Prix d'achat</emphasis>,
+<emphasis>Offert</emphasis>,
+<emphasis>Prêté</emphasis>,
+<emphasis>Jaquette</emphasis>, et
+<emphasis>Commentaires</emphasis>.
+</para>
+
+<para>
+Le champ <emphasis>Acteurs</emphasis> est un <link linkend="table">table</link>
+à deux colonnes, avec en principe le nom de l'acteur dans la première colonne
+et son rôle dans la seconde. La <emphasis>Durée</emphasis> est supposée être en
+minutes ; mais vous pouvez bien entendu changer cela.
+</para>
+</sect2>
+
+<sect2 id="music-collection">
+<title>Collections musicales</title>
+<para>
+Les collections musicales ont 15 champs par défaut.
+<emphasis>Titre</emphasis>,
+<emphasis>Support</emphasis>,
+<emphasis>Artiste</emphasis>,
+<emphasis>Label</emphasis>,
+<emphasis>Année</emphasis>,
+<emphasis>Genre</emphasis>,
+<emphasis>Pistes</emphasis>,
+<emphasis>Note</emphasis>,
+<emphasis>Date d'achat</emphasis>,
+<emphasis>Prix d'achat</emphasis>,
+<emphasis>Offert</emphasis>,
+<emphasis>Prêté</emphasis>,
+<emphasis>Mots clef</emphasis>,
+<emphasis>Jaquette</emphasis>, et
+<emphasis>Commentaires</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="game-collection">
+<title>Collections de jeux</title>
+<para>
+Les collections de jeux vidéos ont 16 champs par défaut.
+<emphasis>Titre</emphasis>,
+<emphasis>Plateforme</emphasis>,
+<emphasis>Genre</emphasis>,
+<emphasis>Année de parution</emphasis>,
+<emphasis>Éditeur</emphasis>,
+<emphasis>Développeur</emphasis>,
+<emphasis>ESRB Rating</emphasis>,
+<emphasis>Description</emphasis>,
+<emphasis>Note personnelle</emphasis>,
+<emphasis>Terminé</emphasis>,
+<emphasis>Date d'achat</emphasis>,
+<emphasis>Prix d'achat</emphasis>,
+<emphasis>Offert</emphasis>,
+<emphasis>Prêté</emphasis>,
+<emphasis>Couverture</emphasis>, et
+<emphasis>Commentaires</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="card-collection">
+<title>Collections de cartes</title>
+<para>
+Les collections de cartes ont 17 champs par défaut.
+<emphasis>Titre</emphasis>,
+<emphasis>Joueur</emphasis>,
+<emphasis>Équipe</emphasis>,
+<emphasis>Marque</emphasis>,
+<emphasis>Numéro de carte</emphasis>,
+<emphasis>Année</emphasis>,
+<emphasis>Séries</emphasis>,
+<emphasis>Type de carte</emphasis>,
+<emphasis>Date d'achat</emphasis>,
+<emphasis>Prix d'achat</emphasis>,
+<emphasis>Lieu</emphasis>,
+<emphasis>Offert</emphasis>,
+<emphasis>Mots clef</emphasis>,
+<emphasis>Quantité</emphasis>,
+<emphasis>Image recto</emphasis>,
+<emphasis>Image verso</emphasis>, et
+<emphasis>Commentaires</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="coin-collection">
+<title>Collections de monnaie</title>
+<para>
+Les collections de monnaie ont 16 champs par défaut.
+<emphasis>Titre</emphasis>,
+<emphasis>Type</emphasis>,
+<emphasis>Dénomination</emphasis>,
+<emphasis>Année</emphasis>,
+<emphasis>Mint Mark</emphasis>,
+<emphasis>Pays</emphasis>,
+<emphasis>Coin Set</emphasis>,
+<emphasis>Grade</emphasis>,
+<emphasis>Grading Service</emphasis>,
+<emphasis>Purchase Date</emphasis>,
+<emphasis>Purchase Price</emphasis>,
+<emphasis>Location</emphasis>,
+<emphasis>Offert</emphasis>,
+<emphasis>Obverse</emphasis>,
+<emphasis>Reverse</emphasis>, et
+<emphasis>Commentaires</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="stamp-collection">
+<title>Collections de timbres</title>
+<para>
+Les collections de timbres ont 1_ champs par défaut.
+<emphasis>Titre</emphasis>,
+<emphasis>Description</emphasis>,
+<emphasis>Dénomination</emphasis>,
+<emphasis>Pays</emphasis>,
+<emphasis>Année d'emission</emphasis>,
+<emphasis>Couleur</emphasis>,
+<emphasis>Scott#</emphasis>,
+<emphasis>Grade</emphasis>,
+<emphasis>Annulé</emphasis>,
+<emphasis>Hinged</emphasis>,
+<emphasis>Centrage</emphasis>,
+<emphasis>Gommé</emphasis>,
+<emphasis>Date d'achat</emphasis>,
+<emphasis>Prix d'achat</emphasis>,
+<emphasis>Lieu</emphasis>,
+<emphasis>Offert</emphasis>,
+<emphasis>Image</emphasis>, et
+<emphasis>Commentaires</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="wine-collection">
+<title>Collections de vins</title>
+<para>
+Les collections de vins ont 15 champs par défaut.
+<emphasis>Titre</emphasis>,
+<emphasis>Producteur</emphasis>,
+<emphasis>Appellation</emphasis>,
+<emphasis>Variété</emphasis>,
+<emphasis>Type</emphasis>,
+<emphasis>Pays</emphasis>,
+<emphasis>Date d'achat</emphasis>,
+<emphasis>Prix d'achat</emphasis>,
+<emphasis>Lieu</emphasis>,
+<emphasis>Quantité</emphasis>,
+<emphasis>Bu par</emphasis>,
+<emphasis>Note</emphasis>,
+<emphasis>Offert</emphasis>,
+<emphasis>Étiquette</emphasis>, et
+<emphasis>Commentaires</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="board-game-collection">
+<title>Collections de jeux plateau</title>
+<para>
+Les collections de jeux de plateau ont 15 champs par défaut.
+<emphasis>Titre</emphasis>,
+<emphasis>Genre</emphasis>,
+<emphasis>Mécanisme</emphasis>,
+<emphasis>Année de parution</emphasis>,
+<emphasis>Éditeur</emphasis>,
+<emphasis>Créateur</emphasis>,
+<emphasis>Nombre de joueurs</emphasis>,
+<emphasis>Description</emphasis>,
+<emphasis>Note personnelle</emphasis>,
+<emphasis>Date d'achat</emphasis>,
+<emphasis>Prix d'achat</emphasis>,
+<emphasis>Offert</emphasis>,
+<emphasis>Prêté</emphasis>,
+<emphasis>Couverture</emphasis>, et
+<emphasis>Commentaires</emphasis>.
+</para>
+
+</sect2>
+
+<sect2 id="file-catalog">
+<title>Catalogues de fichiers</title>
+<para>
+Les catalogues de fichiers ont 13 champs par défaut.
+<emphasis>Nom</emphasis>,
+<emphasis>URL</emphasis>,
+<emphasis>Description</emphasis>,
+<emphasis>Volume</emphasis>,
+<emphasis>Type mime</emphasis>,
+<emphasis>Taille</emphasis>,
+<emphasis>Permissions</emphasis>,
+<emphasis>Propriétaire</emphasis>,
+<emphasis>Groupe</emphasis>,
+<emphasis>Date de création</emphasis>,
+<emphasis>Date de modification</emphasis>,
+<emphasis>Autres informations</emphasis>, et
+<emphasis>Icône</emphasis>,
+</para>
+
+</sect2>
+
+<sect2 id="custom-collection">
+<title>Collections personnalisées</title>
+<para>
+Les collections personnalisées ont un champ par défaut, le
+<emphasis>Titre</emphasis>. Elle sont prévues pour pouvoir être utilisées
+lorsque aucun type par défaut ne convient.
+</para>
+
+</sect2>
+
+</sect1>
+
+</chapter>
diff --git a/doc/fr/entry-editor1.png b/doc/fr/entry-editor1.png
new file mode 100644
index 0000000..a7d6249
--- /dev/null
+++ b/doc/fr/entry-editor1.png
Binary files differ
diff --git a/doc/fr/entry-editor3.png b/doc/fr/entry-editor3.png
new file mode 100644
index 0000000..b2b4c3e
--- /dev/null
+++ b/doc/fr/entry-editor3.png
Binary files differ
diff --git a/doc/fr/entry-editor4.png b/doc/fr/entry-editor4.png
new file mode 100644
index 0000000..f4ea2fa
--- /dev/null
+++ b/doc/fr/entry-editor4.png
Binary files differ
diff --git a/doc/fr/entry-editor5.png b/doc/fr/entry-editor5.png
new file mode 100644
index 0000000..c3764b4
--- /dev/null
+++ b/doc/fr/entry-editor5.png
Binary files differ
diff --git a/doc/fr/export-bibtex.png b/doc/fr/export-bibtex.png
new file mode 100644
index 0000000..3304207
--- /dev/null
+++ b/doc/fr/export-bibtex.png
Binary files differ
diff --git a/doc/fr/export-csv.png b/doc/fr/export-csv.png
new file mode 100644
index 0000000..a25f272
--- /dev/null
+++ b/doc/fr/export-csv.png
Binary files differ
diff --git a/doc/fr/export-html.png b/doc/fr/export-html.png
new file mode 100644
index 0000000..06423f7
--- /dev/null
+++ b/doc/fr/export-html.png
Binary files differ
diff --git a/doc/fr/export-options.png b/doc/fr/export-options.png
new file mode 100644
index 0000000..af2bfe2
--- /dev/null
+++ b/doc/fr/export-options.png
Binary files differ
diff --git a/doc/fr/export-pdb.png b/doc/fr/export-pdb.png
new file mode 100644
index 0000000..0eb1d4a
--- /dev/null
+++ b/doc/fr/export-pdb.png
Binary files differ
diff --git a/doc/fr/externalexec-options.png b/doc/fr/externalexec-options.png
new file mode 100644
index 0000000..f0773cb
--- /dev/null
+++ b/doc/fr/externalexec-options.png
Binary files differ
diff --git a/doc/fr/faqs.docbook b/doc/fr/faqs.docbook
new file mode 100644
index 0000000..8929818
--- /dev/null
+++ b/doc/fr/faqs.docbook
@@ -0,0 +1,279 @@
+<chapter id="faqs">
+<title>Questions et réponses</title>
+
+<!-- (OPTIONAL but recommended) This chapter should include all of the silly
+(and not-so-silly) newbie questions that fill up your mailbox. This chapter
+should be reserved for BRIEF questions and answers! If one question uses more
+than a page or so then it should probably be part of the
+"Using this Application" chapter instead. You should use links to
+cross-reference questions to the parts of your documentation that answer them.
+This is also a great place to provide pointers to other FAQ's if your users
+must do some complicated configuration on other programs in order for your
+application work. -->
+
+<qandaset id="faqlist">
+
+<qandaentry>
+<question>
+<para>Comment démarrer le programme ?</para>
+</question>
+<answer>
+
+<para>Après avoir télé-chargé et décompressé &appname;, exécutez
+<userinput><command>configure</command>
+<option>--disable-debug</option>
+<option>--enable-final</option></userinput> pour tout configurer:
+Il se peut que vous ayez à modifier certaines options de la ligne
+de commande. ensuite, exécuter
+<userinput><command>make</command></userinput> compilera
+&appname;. Ensuite, en tant qu'utilisateur root, exécutez
+<userinput><command>make install</command></userinput> pour tout installer.
+Être root n'est
+nécessaire que si vous installez à un endroit où vous n'avez pas
+les droits d'écriture. La commande pour démarrer &appname; est
+<userinput><command>tellico</command></userinput>. Si vous installez
+un binaire pré-empaqueté, une entrée dans le menu sera ajoutée pour
+&appname;. </para>
+
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question>
+<para>Comment saisir des auteurs multiples ?</para>
+</question>
+<answer>
+
+<para>Les noms des auteurs doivent être séparés par un point-virgule,
+de la façon suivante :
+<userinput>Brian W. Kernighan; Dennis M. Ritchie</userinput>. N'ajoutez
+pas le mot "et" ou un autre similaire, même s'il y a 20 auteurs.
+Si l'option de mise en forme automatique est activée, le nom de famille
+sera automatiquement affiché en premier pour chaque auteur.</para>
+
+<para>Les autres propriétés permettant des valeurs multiples, telles que
+"genre" ou "mots-clef" sont saisis de la même manière, avec un point-virgule
+entre chaque valeur.</para>
+
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question>
+<para>Est-il possible de modifier l'apparence des pages imprimées ?</para>
+</question>
+<answer>
+
+<para>Oui, bien sûr. Trouvez le fichier
+<filename>tellico-printing.xsl</filename> qui devrait se trouver dans le
+repertoire $<envar>KDEDIR</envar>/share/apps/tellico/. Vous pouvez le copier
+dans $<envar>KDEHOME</envar>/share/apps/tellico/ pour y apporter des
+modifications personnelles. Il est nécessaire de connaître le langage
+<ulink url="http://www.w3.org/TR/xslt">&xslt;</ulink>, mais modifier ce fichier
+est la seule façon de changer la mise en forme. Les données &html; sont
+produites à partir de ce fichier, et la manière la plus simple de changer
+l'apparence à l'impression est de modifier le CSS dans la partie supérieure du
+fichier. N'hésitez pas à poser des questions par e-mail. Les fichiers
+d'impression alternatifs &xslt; seront disponibles sur
+<ulink url="&homepage;">le site web &appname;</ulink>.</para>
+
+<para>Prenez garde au fait que le fichier
+<filename>tellico-printing.xsl</filename> fait référence à un autre,
+<filename>tellico-common.xsl</filename>, qui contient certaines structures
+&xslt; génériques. Si vous copiez <filename>tellico-printing.xsl</filename>
+dans $<envar>KDEHOME</envar>, vous devrez soit modifier l'élément
+&lt;xsl:import&gt; pour pointer vers la position du fichier
+<filename>tellico-common.xsl</filename> ou copier le fichier commun avec.
+</para>
+</answer>
+</qandaentry>
+<qandaentry>
+<question>
+<para>Comment regrouper selon un critère que ceux disponibles dans la barre d'outils ?</para>
+</question>
+<answer>
+<para>
+Pour permettre de regrouper selon un champs qui le permet pas par défaut,
+valider la case "Autoriser le regroupement" pour ce champs en particulier dans
+la boite de dialogue "Champs de la collection".
+</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question><para>Qu'est-ce que tous ces messages qui s'affichent quand je lance &appname;?</para></question>
+<answer>
+<para>Des choses telles que :
+<screen width="40">
+<computeroutput>Tellico::updateCollectionToolBar</computeroutput>
+<computeroutput>BCGroupView::setGroupAttribute - author</computeroutput>
+<computeroutput>BCGroupView::slotAddCollection</computeroutput>
+<computeroutput>QCheckBox::property( "title" ) failed: property invalid
+or does not exist</computeroutput>
+</screen>
+
+sont des informations de déboggage. Lors de la compilation, ils peuvent être
+désactivés avec l'option <userinput><option>--disable-debug</option></userinput>.
+Vous pouvez également utiliser l'option
+<userinput><option>--enable-final</option></userinput>, qui utilise
+un peu plus de mémoire lors de la compilation, mais rend l'application
+plus efficace à l'exécution.</para>
+
+<para>Le dernier message est légèrement différent, il indique que votre
+installation de Qt a été compilée avec des informations de déboggage.</para>
+
+<para>Ou, si &appname; est déjà installé, executez
+<userinput><command>kdebugdialog</command></userinput> et assurez-vous
+que "0 (generic)" n'est pas coché. Cette option désactive l'affichage de tous
+les messages de déboggage venant d'applications KDE générique (i.e. celles qui
+ne sont pas distribuées officiellement par KDE).</para>
+
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question><para>Comment modifier les colonnes affichées ?</para></question>
+<answer>
+<para>Cliquez du bouton droit sur la barre d'en-tête. Vous pouvez également
+déplacer les en-tête pour les ré-ordonner, ou cliquer dessus pour trier
+selon un champ particulier.</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question><para>Comment puis-je filtrer par rapport à un critère
+comme le champs "Lu" ?</para></question>
+<answer>
+<para>En interne, le champ des cases à cocher de &appname; est sauvegardé avec
+la valeur "true" ; donc si vous souhaitez filtrer pour n'afficher que les
+livres de science fiction que vous n'avez pas lu par exemple, vous devez faire
+deux règles de filtrage. Assurez-vous que la case "Vérifie toutes les règles"
+est cochée. Configurez la première règle telle que "Genre" "contenant"
+"Science Fiction" (sans guillemets) et la seconde pour avoir
+"Lu" "ne contenant pas" "true" (sans guillemets).</para>
+
+<para>De plus, le filtre rapide de la barre d'outils fonctionne pour tous les
+champs ; et s'il contient un caractère non alpha-numérique, le texte sera
+interprété comme étant une expression régulière. Ainsi, si vous voulez rapidement
+filtrer vos livres pour afficher ceux de Weber ou Bujold, tapez "weber|bujold"
+(sans guillemets) dans la barre d'outils.</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question><para>Comment ajouter de nouveaux modèles d'entrées ?</para></question>
+
+<answer>
+<para>Les modèles d'entrées devraient être savés dans
+<filename class="directory">$<envar>KDEHOME</envar>/share/apps/tellico/entry-templates/</filename>
+pour un utilisateur simple, ou dans
+<filename class="directory">$<envar>KDEDIR</envar>/share/apps/tellico/entry-templates/</filename>
+pour qu'ils soient accessibles à tous. Les modèles dans $<envar>KDEHOME</envar>
+sont prioritaires sur les fichiers portant le même nom dans $<envar>KDEDIRS</envar>.
+Les modèles d'entrées peuvent être configurés par type de collection dans la
+boite de dialogue de configuration.</para>
+
+<para>Les modèles pour la &report-dialog; sont enregistrés dans
+<filename class="directory">$<envar>KDEHOME</envar>/share/apps/tellico/report-templates/</filename>.
+</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question><para>La compilation et l'installation se sont bien déroulées,
+mais quand &appname; démarre, la fenêtre est vide. Qu'est-ce qui
+ne va pas ?</para></question>
+
+<answer>
+<para>Les logiciels KDE cherchent les données à l'endroit défini par la variable
+ d'environnement $<envar>KDEDIRS</envar>. Si vous installez dans
+ <filename class="directory">/usr/local</filename> par exemple, mais que
+ $<envar>KDEDIRS</envar> est vide ou seulement <filename class="directory">/usr</filename>,
+ alors &appname; ne pourra pas trouver les fichiers dont il a besoin. Ceci est
+ particulièrement vrai pour SuSE, pour lequel vous devriez compiler avec
+ <userinput><option>--prefix</option>=<filename class="directory">/opt/kde3</filename></userinput>. Alternativement,
+ vous pouvez ajouter une ligne à votre fichier <filename>.profile</filename> pour
+ configurer $<envar>KDEDIRS</envar>. Veuillez consulter la documentation
+ de votre shell pour plus de détails.</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question><para>Comment exporter des champs BibTeX supplémentaires ?</para></question>
+<answer>
+<para>&appname; utilise la propriété <emphasis>bibtex</emphasis> pour savoir
+comment exporter les champs BibTeX. Si vous souhaitez ajouter de nouveaux
+champs à exporter, tels qu'un résumé (abstract), ouvrez la &fields-dialog;, et
+cliquez sur le bouton <guibutton>Propriétés étendues</guibutton>. Ajoutez une
+propriété <emphasis>bibtex</emphasis> avec la valeur
+<emphasis>abstract</emphasis>. Par la suite, lorsque vous exporterez vos
+données vers un format BibTeX ou BibTeXML, cette propriété sera utilisée pour
+le nom du champs BibTeX.</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question>
+<para>Qu'est-il arrivé à Bookcase ?</para>
+</question>
+
+<answer>
+<para>En raison d'un conflit de marques, Bookcase a été renommé Tellico en septembre 2004.
+Tellico 0.12 est alors paru, qui était identique à
+Bookcase 0.11, à l'exception du changement de nom.</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question>
+<para>Le nom Tellico est-il une référence à quoi que ce soit ?</para>
+</question>
+
+<answer>
+<para>L'auteur a pensé à
+<ulink url="http://www.periapsis.org/archives/2004/09/13/renaming_bookcase.html">plusieurs autres noms</ulink>, dont certains étaient liés à des colletions de
+livres. Cependant, Tellico permet de gérer plus que des livres: En outre; le
+développement de tellico est un passe-temps ; l'auteur a donc choisi un nom qui
+lui plaisait, celui d'une ville proche de l'endroit où il a grandi.</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question>
+<para>Pourquoi incluez-vous ces liens vers Amazon.com dans les résultats des recherches ?</para>
+</question>
+
+<answer>
+<para>
+Les <ulink url="http://www.amazon.com/gp/browse.html/002-0927720-5265623?node=3440661">termes de l'accord pour accéder aux Services Web Amazon.com</ulink>
+requièrent que toutes les images chargées par ce service disposent d'un lien
+vers Amazon.com, ainsi que d'un lien additionnel.
+Le numéro d'identification d'associé à Amazon.com est obligatoirement inclus,
+afin que des paiements ultérieurs puissent être dûment collectés.
+</para>
+</answer>
+</qandaentry>
+
+<qandaentry>
+<question>
+<para>Pourquoi ne pas utiliser une vraie base de données?</para>
+</question>
+
+<answer>
+<para>
+L'une des raisons pour lesquelles l'auteur a écrit &appname; était d'apprendre
+le C++. Il ne connaissait pas le SQL à l'époque, et pour le moment il a une
+vague idée sur la façon de s'en servir. Dit simplement, &appname; n'a pas été
+conçu au départ comme une base de données relationnelle, et cela ne changera pas
+avant qu'il ait appris le SQL et eu le temps et la motivation de changer le
+modèle de données. Si ça vous pose un problème, n'utilisez pas &appname;.
+</para>
+
+<para>
+Bien entendu, toute modification apportée au code est la bienvenue.
+</para>
+</answer>
+</qandaentry>
+
+</qandaset>
+</chapter>
diff --git a/doc/fr/fetch-dialog.png b/doc/fr/fetch-dialog.png
new file mode 100644
index 0000000..640d6c6
--- /dev/null
+++ b/doc/fr/fetch-dialog.png
Binary files differ
diff --git a/doc/fr/fields-dialog.png b/doc/fr/fields-dialog.png
new file mode 100644
index 0000000..ba6adb1
--- /dev/null
+++ b/doc/fr/fields-dialog.png
Binary files differ
diff --git a/doc/fr/filter-dialog.png b/doc/fr/filter-dialog.png
new file mode 100644
index 0000000..430355b
--- /dev/null
+++ b/doc/fr/filter-dialog.png
Binary files differ
diff --git a/doc/fr/filter-view.png b/doc/fr/filter-view.png
new file mode 100644
index 0000000..11420df
--- /dev/null
+++ b/doc/fr/filter-view.png
Binary files differ
diff --git a/doc/fr/freebsd-doc-license.html b/doc/fr/freebsd-doc-license.html
new file mode 100644
index 0000000..ae93752
--- /dev/null
+++ b/doc/fr/freebsd-doc-license.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html40/strict.dtd">
+<html lang="en-US">
+ <head>
+ <title>FreeBSD Documentation License</title>
+ <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
+ <meta HTTP-EQUIV="Content-Language" CONTENT="en-US">
+ <meta NAME="description" CONTENT="FreeBSD Documentation License">
+ <meta NAME="keywords" CONTENT="FreeBSD, bsd, Bsd, license, licence, documentation, FreeBSD Documentation license">
+ <meta NAME="robots" CONTENT="none">
+ <meta HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
+ <link REL="stylesheet" HREF="common/kde-default.css" TYPE="text/css">
+ </head>
+ <body CLASS="license">
+ <h1>FreeBSD Documentation License</h1>
+
+ <p>Redistribution and use in source (SGML DocBook) and 'compiled'
+ forms (SGML, HTML, PDF, PostScript, RTF and so forth) with or
+ without modification, are permitted provided that the following
+ conditions are met:</p>
+
+ <ol>
+ <li>
+ <p>Redistributions of source code (SGML DocBook)
+ must retain the above copyright notice, this list
+ of conditions and the following disclaimer as the
+ first lines of this file unmodified.</p>
+ </li>
+
+ <li>
+ <p>Redistributions in compiled form (transformed to
+ other DTDs, converted to PDF, PostScript, RTF and
+ other formats) must reproduce the above copyright
+ notice, this list of conditions and the following
+ disclaimer in the documentation and/or other
+ materials provided with the distribution.</p>
+
+ </li>
+ </ol>
+
+ <p>THIS DOCUMENTATION IS PROVIDED BY THE FREEBSD
+ DOCUMENTATION PROJECT "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ THE FREEBSD DOCUMENTATION PROJECT BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.</p>
+</body>
+</html>
diff --git a/doc/fr/fundamentals.docbook b/doc/fr/fundamentals.docbook
new file mode 100644
index 0000000..7750615
--- /dev/null
+++ b/doc/fr/fundamentals.docbook
@@ -0,0 +1,841 @@
+<chapter id="fundamentals">
+<title>Utiliser &appname;</title>
+
+<sect1 id="quick-start">
+<title>Démarrage rapide</title>
+
+<para>
+Par défaut, &appname; démarre avec une collection de livres vide. Pour
+travailler avec un autre type de collection, créez-la en utilisant le menu
+<menuchoice><guimenu>Fichier</guimenu><guimenuitem>Nouveau</guimenuitem></menuchoice>,
+ou le bouton dans la barre d'outils. Les collections sont remplies avec
+certains des champs les plus communs ; mais vous pouvez en ajouter, enlever ou
+les modifier selon vos besoins.
+</para>
+
+<para>
+Les nouvelles entrées peuvent être ajoutées en utilisant
+l'<link linkend="entry-editor">&entry-editor;</link>. Le menu
+<menuchoice><guimenu>Collection</guimenu><guimenuitem>Nouvelle entrée</guimenuitem></menuchoice>
+ouvre l'&entry-editor; avec une entrée vide pour la compléter.
+L'&entry-editor; peut également être ouvert en utilisant le menu
+<menuchoice><guimenu>Paramètres</guimenu><guimenuitem>Afficher l'&entry-editor;</guimenuitem></menuchoice>.
+Une fois que vous avez entré les valeurs pour une entrée, vous pouvez les
+inclure à la collection en cliquant sur
+<guibutton>Enregistrer l'entrée</guibutton> dans la boite de dialogue de
+l'&entry-editor;, qui reste ouverte dans le cas où vous souhaiteriez ajouter de
+nouvelles entrées.
+Une fois que vous avez enregistré une entrée dans la collection, vous pouvez la
+modifier en cliquant dessus dans la fenêtre principale.
+Si l'&entry-editor; n'est pas déjà ouvert, vous pouvez double-cliquer sur une
+entrée pour ouvrir l'éditeur et la modifier.
+</para>
+
+<para>
+Si vous souhaitez inclure une image avec une entrée, vous pouvez utiliser le
+sélecteur de fichiers standard &kde; en cliquant sur le bouton
+<guibutton>Sélectionner une image...</guibutton> dans
+l'<link linkend="entry-editor">&entry-editor;</link>, ou vous pouvez déplacer
+une image depuis le gestionnaire de fichiers ou le navigateur internet dans
+l'&entry-editor;.
+</para>
+
+<para>
+Quand vous sélectionnez une entrée, la
+<link linkend="entry-view">&entry-view;</link> affiche une vue mise en forme du
+contenu de l'entrée.
+Vous pouvez modifier le modèle utilisé pour afficher l'entrée dans la
+<link linkend="configuration">&config-dialog;</link>.
+</para>
+
+<para>
+Les entrées d'une collection sont groupées ensemble lorsqu'elles ont la même
+valeur dans certains champs, tels que l'auteur ou le réalisateur.
+Vous pouvez modifier le champ utilisé pour grouper en utilisant le menu
+déroulant dans la barre d'outils ou dans le menu
+<menuchoice><guimenu>Configuration</guimenu><guimenuitem>Options de regroupement</guimenuitem></menuchoice>.
+</para>
+
+<para>
+Vous pouvez utiliser le &quick-filter; dans la barre d'outils pour limiter
+rapidement le nombre d'entrées visibles à celles contenant le mot que vous y
+entrez. Ce filtre est également utile quand vous souhaitez trouver rapidement
+une entrée. Vous pouvez y entrer le titre ou une autre mot unique qui identifie
+l'entrée et la <link linkend="detailed-view">&detailed-view;</link> affichera
+uniquement les entrées correspondant au filtre. La barre d'état indique
+combien d'entrées existent dans la collection, et combien sont actuellement
+filtrées.
+</para>
+
+</sect1>
+
+<sect1 id="main-window">
+<title>Utilisation générale</title>
+
+<para>
+La fenêtre principale a trois parties distinctes ; chacune affichant des
+informations sur la collection de manière différente. La partie principale est
+la <link linkend="detailed-view">&detailed-view;</link> dans la partie
+supérieure droite ; où les valeurs tous les champs de chaque entrée peuvent
+être affichées.
+Dans la partie gauche, la <link linkend="group-view">&group-view;</link> peut
+être utilisée pour afficher les entrées sous forme de groupes dans une
+arborescence.
+La <link linkend="filter-view">&filter-view;</link> permet de ne voir que les
+entrées répondant à certains critères.
+La <link linkend="loan-view">&loan-view;</link> affiche les entrées prêtées.
+Enfin, la <link linkend="entry-view">&entry-view;</link> affiche les données
+d'une entrée mises en forme, ou une vue par icônes d'un groupe d'entrées, dans
+la partie inférieure droite.
+</para>
+
+<screenshot>
+<screeninfo>La fenêtre principale de &appname;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="main-window.png"/></imageobject>
+<textobject><phrase>La fenêtre principale de &appname;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<sect2 id="detailed-view">
+<title>&detailed-view;</title>
+
+<para>
+Tous les champs d'une collection peuvent être affichés dans la &detailed-view; ;
+bien que les champs de type
+<emphasis><link linkend="para">Paragraphe</link></emphasis>,
+<emphasis><link linkend="image">Image</link></emphasis> et
+<emphasis><link linkend="table">Table</link></emphasis> ne soient probablement
+pas utiles. Cliquer du bouton droit sur l'en-tête affiche un menu permettant de
+choisir les champs visibles. Les colonnes peuvent être dimensionnées et
+réordonnées ; et les paramètres sont conservés d'une session à l'autre.
+</para>
+</sect2>
+
+<sect2 id="group-view">
+<title>&group-view;</title>
+
+<para>
+La &group-view; rassemble les les entrées dans une arborescence selon un champ
+<link linkend="field-options">permettant le regroupement</link>.
+Le nombre d'entrées dans chaque groupe peut être affiché à coté de son nom en
+changeant une option dans la
+<link linkend="general-options">&config-dialog;</link>.
+Les groupes peuvent être développés en cliquant sur le signe plus, ou en
+double-cliquant sur le groupe.
+Développer ou refermer tous les groupes sont des options dans le menu
+contextuel du clic droit.
+L'arbre peut être trié, soit par nom de groupe, soit par nombre d'entrées, en
+cliquant du bouton droit sur un groupe.
+Un groupe peut également être utilisé en tant que filtre pour la
+<link linkend="detailed-view">&detailed-view;</link> en cliquant du bouton droit
+sur le groupe.
+</para>
+
+<para id="people-group">
+Quand plus d'un champ de la collection a l'option
+<emphasis><link linkend="fields-dialog"><guilabel>Mise en forme comme un nom</guilabel></link></emphasis>
+activée, un groupe supplémentaire est ajouté, regroupant tous ces champs dans
+un seul pseudo-groupe <emphasis>Personnes</emphasis>.
+</para>
+
+<para>
+Si une entrés ne contient pas de valeur pour le champ utilisé pour former les
+groupes, celle-ci est placées dans le groupe <emphasis>(Vide)</emphasis>, qui
+utilise un répertoire rouge.
+</para>
+</sect2>
+
+<sect2 id="filter-view">
+<title>&filter-view;</title>
+
+<para>
+Si des filtres ont été enregistrés pour la collection, la &filter-view; devient
+active. Au fur et à mesure que vous ajoutez et modifiez des entrées, celles-ci
+seront automatiquement vérifiées par les filtres et ajoutées ou enlevées en
+fonction des résultats. Le filtre peut être modifié en double-cliquant dessus
+pour ouvrir la &filter-dialog;. Un clic du bouton droit dessus vous permet
+également de le supprimer complètement.
+</para>
+
+<screenshot>
+<screeninfo>La &filter-view;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="filter-view.png"/></imageobject>
+<textobject><phrase>La &filter-view;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+</sect2>
+
+<sect2 id="loan-view">
+<title>&loan-view;</title>
+
+<para>
+Une fois que des entrées ont été marquées comme prêtées, la &loan-view; est
+ajoutée à la fenêtre, pour que les entrées empruntées puissent être suivies.
+Ceci est fait individuellement pour chaque entrée. Cliquer du bouton droit sur
+une entrée propose une option pour modifier le prêt avec la &loan-dialog;.
+</para>
+
+<screenshot>
+<screeninfo>La &loan-view;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="loan-view.png"/></imageobject>
+<textobject><phrase>La &loan-view;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+</sect2>
+
+<sect2 id="entry-view">
+<title>&entry-view;</title>
+
+<para>
+Une représentation mise en forme des valeurs de l'entrée sélectionnée est
+affichée dans la &entry-view;.
+Des modèles sont utilisés pour le format d'affichage et les images
+supplémentaires.
+Des modèles différents pour chaque type de collection peuvent être spécifiés
+dans la <link linkend="template-options">&config-dialog;</link>.
+Les modèles par défaut affichent les champs de type &URL; actifs, qui s'ouvrent
+avec l'association de fichier par défaut de &kde;
+Lors des exports en &html;, le modèle courant est utilisé pour exporter les
+fichiers d'entrées individuels.
+</para>
+
+<para>
+De plus, lorsque plusieurs entrées sont sélectionnées, une vue par icônes
+des entrées est affichée, en utilisant le
+premier champ de type <link linkend="image">Image</link> de la collection.
+Les entrées peuvent être sélectionnées dans la &detailed-view;. Un clic
+droit sur la vue par icônes affiche un menu qui permet de changer les critères
+de tri des entrées.
+</para>
+
+</sect2>
+
+<sect2 id="status-bar">
+<title>Barre d'état</title>
+
+<para>
+La barre d'état est utilisée pour indiquer ce que &appname; est en train de
+faire. Elle contient également le nombre total d'entrées dans la collection ;
+et si un filtre est utilisé, combien sont visibles.
+</para>
+</sect2>
+
+</sect1>
+
+<sect1 id="entry-editor">
+<title>Modifier des entrées</title>
+
+<para>
+L'&entry-editor; est utilisé pour ajouter et modifier des entrées dans la
+collection.
+Double-cliquer sur une entrée dans la &group-view; ou la &detailed-view;
+ouvre l'&entry-editor; avec cette entrée.
+De nouvelles entrées peuvent être créées par le menu
+<menuchoice><guimenu>Collection</guimenu></menuchoice>,
+l'icône de la barre d'outils, ou le bouton dans l'&entry-editor;.
+</para>
+
+<para>
+Fermer l'&entry-editor; alors que des changements n'ont pas été enregistrés
+provoque l'affichage d'un message.
+Les champs sont regroupés par catégorie et apparaissent suivant l'ordre dans
+lequel ils sont classés dans la
+<link linkend="fields-dialog">&fields-dialog;</link>.
+Ils peuvent donc également être réordonnées.
+</para>
+
+<screenshot>
+<screeninfo>L'&entry-editor;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="entry-editor1.png"/></imageobject>
+<textobject><phrase>L'&entry-editor;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+Cliquer sur le champ du titre d'une
+<link linkend="url"><emphasis>&URL;</emphasis></link> ouvre le lien en fonction
+du type de fichier défini dans &kde;. Le bouton
+<guiicon>sélecteur d'&URL;</guiicon> à côté de l'entrée de texte ouvre la
+boite de dialogue de fichier &kde; par défaut ; mais le champ n'est pas limité
+aux fichiers locaux. Tout type d'&URL; peut être entré. Les &URL; relatives ne
+sont pas gérées pour le moment, la valeur étant interprétée par rapport à
+l'endroit où se trouve la feuille de style du modèle.
+</para>
+
+<para>
+Pour les champs de type <link linkend="image"><emphasis>Image</emphasis></link>,
+le bouton <guibutton>Sélectionner l'image...</guibutton> ouvre la boite de
+dialogue de sélection d'image &kde;. L'image est enregistrée dans la
+collection dans son format d'origine, et une version mise à l'échelle est
+affichée dans l'&entry-editor;. L'image peut être effacée avec le bouton
+<guibutton>Effacer</guibutton>. Les images effacées sont retirées de la
+collection.
+</para>
+
+<screenshot>
+<screeninfo>L'&entry-editor; pour les champs de type <emphasis>Image</emphasis></screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="entry-editor3.png"/></imageobject>
+<textobject><phrase>L'&entry-editor; pour les champs de type <emphasis>Image</emphasis></phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+L'éditeur gère également le glisser-déposer. Déplacer une image depuis une
+fenêtre &konqueror; aura le même effet que de la choisir à l'aide du
+sélecteur de fichiers. Glisser une image depuis l'éditeur vers une fenêtre
+&konqueror; enregistrera l'image dans le répertoire.
+</para>
+
+<warning>
+<para>
+Par défaut, les images sont enregistrées dans le fichier de données de la
+collection, conservant ainsi toutes les données au même endroit. Cependant,
+un trop grand nombre d'images ralentira &appname; et générera des fichiers de
+taille importante. Cependant, &appname; peut également enregistrer les images
+séparément, soit dans le répertoire
+<filename class="directory">$<envar>KDEHOME</envar>/share/apps/tellico/data/</filename>,
+soit dans un répertoire au même endroit que le fichier de données Tellico.
+Dans ce cas, le chargement et l'enregistrement des fichiers de données est
+nettement plus rapide ; mais les fichiers de données ne peuvent alors plus être
+transférés ou sauvegardés sans perdre les images. Des fichiers autonomes
+(contenant les images) peuvent toujours être créés en utilisant le menu
+<menuchoice><guimenu>Fichier</guimenu><guimenu>Exporter</guimenu><guimenuitem>Exporter au format Zip...</guimenuitem></menuchoice>.
+</para>
+</warning>
+
+<para>
+Les champs de type <link linkend="table"><emphasis>Tableau</emphasis></link> sont
+initialement créés avec 5 lignes ; mais déplacer le curseur jusqu'à la
+dernière ligne en ajoutera une autre. Dans les tableaux à é colonnes, seule
+la première est utilisée pour le regroupement ou la mise en forme.
+</para>
+
+<screenshot>
+<screeninfo>L'&entry-editor; pour les champs de type <emphasis>Tableau</emphasis></screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="entry-editor4.png"/></imageobject>
+<textobject><phrase>L'&entry-editor; pour les champs de type <emphasis>Tableau</emphasis></phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<sect2 id="edit-multiple">
+<title>Editer plusieurs Entrées</title>
+<para>
+Plusieurs entrées peuvent être modifiées en même temps, en les sélectionnant
+dans la &group-view; ou la &detailed-view;. Si plusieurs entrées sont
+sélectionnées, les champs contenant la même valeur sont actifs. Dans les cas
+contraire, ils sont désactivés. Une case à cocher est ajoutée à droite de
+chaque champ, permettant de contrôler si le champ est actif ou non.
+</para>
+
+<para>
+Seuls les champs actifs seront modifiés à la sauvegarde des entrées, ce qui
+rend la modification de nombreuses entrées plus simple. Par exemple, pour
+changer le type de medium dans une collection de vidéos, éditez les entrées
+simultanément, cochez la case pour activer le champ Medium, entrez la valeur
+<acronym>DVD</acronym>, et enregistrez les entrées. Seul le champ Medium a été
+modifié, préservant les valeurs originales de tous les autres champs.
+</para>
+
+<screenshot>
+<screeninfo>L'&entry-editor; pour plusieurs entrées</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="entry-editor5.png"/></imageobject>
+<textobject><phrase>L'&entry-editor; pour plusieurs entrées</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+</sect2>
+
+<sect2 id="updating-entries">
+<title>Mettre à jour les données d'une entrée</title>
+
+<para>
+Les entrées peuvent être automatiquement mises à jour par des requêtes aux
+sources de données disponibles pour le type de collection en cours. Ceci peut
+être très utile pour combiner les informations de plusieurs sources. Par
+exemple, vous pouvez vouloir ajouter un film à votre collection avec les
+<link linkend="amazon-web-services">services web Amazon.com</link>, puis mettre
+à jour l'entrée avec des informations supplémentaires en provenance de
+<link linkend="imdb">IMDb</link>.
+</para>
+
+<para>
+Seuls les champs vides sont mis à jour ! Si vous voulez mettre à jour la liste
+des acteurs d'un film, effacez les données avant de mettre à jour. Pour les
+<link linkend="externalexec">scripts externes</link>, un champ mis à jour peut
+être spécifié dans les options de la source.
+</para>
+
+<para>
+La mise à jour d'entrée peut être démarrée via un clic droit pour une entrée, ou
+en utilisant le menu
+<menuchoice><guimenu>Collection</guimenu><guimenuitem>Mettre à jour l"entrée</guimenuitem></menuchoice>.
+</para>
+</sect2>
+
+</sect1>
+
+<sect1 id="fields-dialog">
+<title>Editer les champs</title>
+
+<para>
+La &fields-dialog; vous permet d'ajouter de nouveaux champs à la collection,
+de modifier ceux existant ou en effacer.
+</para>
+
+<screenshot>
+<screeninfo>La &fields-dialog; de &appname;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="fields-dialog.png"/></imageobject>
+<textobject><phrase>La &fields-dialog; de &appname;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<sect2 id="field-list">
+<title>Liste des champs</title>
+
+<para>
+Sur le côté gauche de la boîte de dialogue se trouve la liste des champs. Ceux
+qui ont été modifiés apparaissent en gras et italique. Les boutons sous la liste
+permettent d'ajouter ou de supprimer des champs, et les flèches de changer leur
+ordre. L'ordre des champs dans la liste est important, puisqu'il est utilisé par
+l'&entry-editor; pour leur affichage. Pour chaque catégorie, les
+champs sont disposés de gauche à droite, en fonction de l'ordre (de haut en bas)
+dans lequel ils apparaissent dans la liste.
+</para>
+</sect2>
+
+<sect2 id="field-properties">
+<title>Propriétés des champs</title>
+
+<para>
+Un champ est défini par ses titre, type, catégorie, description et
+éventuellement d'autres valeurs autorisées. Le titre est utilisé partout pour
+référer au champ dans l'interface utilisateur. L'&entry-editor; l'utilise pour
+l'affichage de valeurs. La &detailed-view; l'utilise en tant qu'en-tête de
+colonnes. Les différents types de champs sont détaillés dans la section
+<link linkend="field-types">Types de champs</link>. La description est utilisée
+en dans une bulle d'information dans l'&entry-editor;, pour fournir des
+explications complémentaires sur le contenu du champ. De plus pour les champs
+de type <link linkend="dependent"><emphasis>Dépendant</emphasis></link>, la
+description est utilisée pour mettre en forme la valeur du champ. Les valeurs
+possibles pour un champ de type
+<link linkend="choice"><emphasis>Choix</emphasis></link> doivent être séparées
+par des point-virgule.
+</para>
+
+<para>
+Les nouveaux champs peuvent être de n'importe quel type ; mais la modification
+du type de champs existant est limitée à ceux compatibles, tels qu'indiqués dans
+le tableau suivant :
+</para>
+
+<table>
+<title>Changements de type de champ autorisés</title>
+<tgroup cols="2">
+<thead>
+<row>
+<entry>Type d'origine</entry>
+<entry>Nouveaux types possibles</entry>
+</row>
+</thead>
+<tbody>
+<row>
+<entry><emphasis>Texte simple</emphasis></entry>
+<entry><emphasis>Texte simple</emphasis>, <emphasis>Paragraphe</emphasis>, <emphasis>Nombre</emphasis>, <emphasis>URL</emphasis>, <emphasis>Tableau</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Paragraphe</emphasis></entry>
+<entry><emphasis>Texte simple</emphasis>, <emphasis>Paragraphe</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Choix</emphasis></entry>
+<entry><emphasis>Texte simple</emphasis>, <emphasis>Paragraphe</emphasis>, <emphasis>Choix</emphasis>, <emphasis>Nombre</emphasis>, <emphasis>URL</emphasis>, <emphasis>Tableau</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Case à cocher</emphasis></entry>
+<entry><emphasis>Texte simple</emphasis>, <emphasis>Paragraphe</emphasis>, <emphasis>Case à cocher</emphasis>, <emphasis>Nombre</emphasis>, <emphasis>URL</emphasis>, <emphasis>Tableau</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Nombre</emphasis></entry>
+<entry><emphasis>Texte simple</emphasis>, <emphasis>Paragraphe</emphasis>, <emphasis>Nombre</emphasis>, <emphasis>URL</emphasis>, <emphasis>Tableau</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>URL</emphasis></entry>
+<entry><emphasis>Texte simple</emphasis>, <emphasis>Paragraphe</emphasis>, <emphasis>Nombre</emphasis>, <emphasis>URL</emphasis>, <emphasis>Tableau</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Date</emphasis></entry>
+<entry><emphasis>Texte simple</emphasis>, <emphasis>Date</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Tableau</emphasis></entry>
+<entry><emphasis>Texte simple</emphasis>, <emphasis>Paragraphe</emphasis>, <emphasis>Tableau</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Image</emphasis></entry>
+<entry><emphasis>Image</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Note</emphasis></entry>
+<entry><emphasis>Choix</emphasis>, <emphasis>Note</emphasis></entry>
+</row>
+<row>
+<entry><emphasis>Dependant</emphasis></entry>
+<entry><emphasis>Dependant</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+</sect2>
+
+<sect2 id="field-formatting">
+<title>Mise en forme des champs</title>
+
+<para>
+&appname; propose la possibilité de mettre en forme automatiquement la valeur
+de certains champs. La plis simple mise en forme est la mise en majuscules
+automatique, qui met en majuscule la première lettre de chaque mot, à
+l'exception des articles. La mise en forme des titres déplace certains articles
+du début à la fin du champ. Par exemple "Le Retour du Roi" devient "Retour du
+Roi, Le". Les articles apparaissant dans les titres sont configurables. Enfin,
+la mise en forme des noms essaie de décomposer le texte, de manière à afficher
+le nom de famille en premier. Les différentes particules ou attributs sont
+configurables. De plus, le groupe spécial
+<emphasis><link linkend="people-group">Personnes</link></emphasis> utilise tous
+les champs mis en forme en tant que noms, même si le paramètre global est
+désactivé.
+</para>
+
+<para>
+Toute mise en forme automatique peut être désactivée en modifiant les options
+générales dans la <link linkend="general-options">&config-dialog;</link>.
+Généralement, la mise en majuscules est une opération distincte de la mise en
+forme ; donc un titre peut être automatiquement mis en fome sans activer la mise
+en majuscules.
+Tous les champs ne permettent pas la mise en forme automatique.
+</para>
+
+<table>
+<title>Exemples de mise en forme</title>
+<tgroup cols="5">
+<thead>
+<row>
+<entry>Type de mise en forme</entry>
+<entry>Valeur du champ</entry>
+<entry>Majuscules automatiques</entry>
+<entry>Mise en forme automatique</entry>
+<entry>Majuscules et mise en fome automatiques</entry>
+</row>
+</thead>
+<tbody>
+<row>
+<entry><emphasis>Titre</emphasis></entry>
+<entry>le retour du roi</entry>
+<entry>Le Retour du Roi</entry>
+<entry>retour du roi, le</entry>
+<entry>Retour du Roi, Le</entry>
+</row>
+<row>
+<entry><emphasis>Nom</emphasis></entry>
+<entry>tom swift, jr.</entry>
+<entry>Tom Swift, Jr.</entry>
+<entry>swift, jr., tom</entry>
+<entry>Swift, Jr., Tom</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+</sect2>
+<sect2 id="field-options">
+<title>Options de champ</title>
+
+<para>
+Les champs ont également trois options générales. Si l'auto-complétion est
+activée, &appname; conserve en mémoire les valeurs de chaque champ et
+l'&entry-editor; propose de compléter automatiquement les mots, suivant les
+paramètres standard de &kde;.
+Tous les champs ne permettent pas l'auto-complétion.
+&appname; doit également savoir si un champ peut avoir des valeurs multiples
+ou s'il peut être utilisé pour regrouper les entrées.
+Un point-virgule est utilisé pour différencier les valeurs multiples lors de
+l'édition d'une entrée.
+</para>
+
+<para>
+Pour des raisons d'efficacité, n'activez pas l'auto-complétion, sauf si vous en
+avez besoin pour les champs. Plus il y a de champs avec l'auto-complétion
+activée dans une collection, plus &appname; est lent à charger le fichier.
+</para>
+
+</sect2>
+</sect1>
+
+<sect1 id="filter-dialog">
+<title>Filtrer les entrées</title>
+<para>
+La &filter-dialog; permet de limiter les entrées visibles dans la
+<link linkend="detailed-view">&detailed-view;</link> à celles respectant une ou
+plusieurs règles de filtrage.
+Le filtre peut être utilisé pour trouver les entrées respectant toutes les
+règles de la boite de dialogue, ou celles en respectant au moins une.
+</para>
+
+<screenshot>
+<screeninfo>La &filter-dialog; de &appname;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="filter-dialog.png"/></imageobject>
+<textobject><phrase>La &filter-dialog; de &appname;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+Chaque ligne contient une seule règle de filtrage.
+Sélectionner un champ à vérifier dans la première boite de la ligne, puis une
+règle de filtrage dans celle du centre.
+Les règles permettent de chercher des valeurs contenant un certain mot ou sont
+exactement identiques.
+Une expression régulière peut également être utilisée pour filtrer les entrées,
+auquel cas le bouton <guibutton>Éditer...</guibutton> devient actif pour
+modifier l'expression.
+Enfin, le mot ou la chaîne de caractères doit être entré dans la boite de texte.
+</para>
+
+<para>
+Jusqu'à huit (8) règles peuvent être utilisées dans le filtre. Les boutons
+<guibutton>Plus</guibutton> et <guibutton>Moins</guibutton> peuvent être
+utilisés pour ajouter ou enlever des règles.
+</para>
+
+<informalexample>
+<para>
+Pour trouver les livres de science fiction que vous n'avez pas lu, validez
+le bouton <guilabel>Vérifier toutes les règles</guilabel>, configurez la
+première règle sur <emphasis>Genre contenant science fiction</emphasis>, et la
+seconde sur <emphasis>Read ne contient pas true</emphasis>.
+<emphasis>Read ne contenant pas true</emphasis>.
+(Pour les champs de type <link linkend="bool">Case à cocher</link>, la valeur
+interne est <emphasis>true</emphasis>).
+</para>
+
+<para>
+Pour trouver les livres écrits par Bujold et Weber, validez le bouton
+<guilabel>Vérifie une des règles</guilabel>, configurez la première règle sur
+<emphasis>Auteur contenant Bujold</emphasis>, et la seconde sur
+<emphasis>Auteur contenant Weber</emphasis>.
+</para>
+</informalexample>
+
+</sect1>
+
+<sect1 id="report-dialog">
+<title>Generating Reports</title>
+<para>
+&appname; peut générer divers rapports concernant votre collection. La
+&report-dialog; vérifie les modèles &xslt; dans le répertoire d'installation
+ainsi que dans
+<filename class="directory">$<envar>KDEHOME</envar>/share/apps/tellico/report-templates/</filename>.
+Vous pouvez ainsi en créer de nouveaux, qui seront automatiquement inclus sous
+forme d'options dans la &report-dialog;. Certains rapports complexes peuvent
+nécessiter un certain temps pour leur génération.
+</para>
+
+<para>
+Les modèles installés avec &appname; incluent seulement une liste des titres,
+la vue en colonne, une vue de groupe, une résumé des groupes et des valeurs les
+plus présentes dans ces groupes, un rapport de prêts, et un rapport plus complet
+contenant les images. Sélectionnez le modèle désiré et cliquez sur le bouton
+<guibutton>Générer</guibutton>. Tout rapport peut également être imprimé ou
+enregistré dans un fichier &html;.
+</para>
+
+<screenshot>
+<screeninfo>La &report-dialog; &appname;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="report-dialog.png"/></imageobject>
+<textobject><phrase>La &report-dialog; &appname;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+Les entrées incluses dans le rapport seront limitées à celles de la
+&detailed-view; ; donc si vous avez un filtre activé, la &report-dialog;
+l'utilisera.
+</para>
+</sect1>
+
+<sect1 id="loan-dialog">
+<title>Gestion des prêts</title>
+<para>
+&appname; gère les prêts d'entrées de la collection. La &loan-dialog; peut être
+ouverte en utilisant le menu <guilabel>Prêter</guilabel>, ou en cliquant du
+bouton droit sur une entrée. Plusieurs entrées peuvent être prêtées en une seule
+opération.
+</para>
+
+<para>
+Le nom des personnes empruntant peut être entré directement, ou être extrait
+du carnet d'adresses par défaut de &kde; en cliquant sur le bouton à côté du
+champ "Nom". La date du prêt est par défaut celle du jour courant ; mais peut
+être modifiée. La date de retour dû est optionnelle, et d'autres notes peuvent
+être ajoutées à propos du prêt.
+</para>
+
+<para>
+Si une date de retour dû est entrée, et si &appname; a été compilé avec la
+gestion de la libkcal, une alarme peut être ajoutée au calendrier par défaut
+de &kde; en tant qu'item "à faire". &korganizer; peut être utilisé pour voir
+ces entrées.
+</para>
+
+<para>
+Lorsqu'une entrée est prêtée, la valeur du champ <emphasis>Prêté</emphasis>
+est mise à la valeur <emphasis>true</emphasis>. Si aucun autre champ "Prêté"
+n'existe dans la collection, celui-ci est ajouté. Ne modifiez pas ce champ
+manuellement ! Les entrées prêtées peuvent être marquées comme rendus en
+utilisant le menu ou en cliquant du bouton droit sur une entrée dans la
+&loan-view;.
+</para>
+
+<screenshot>
+<screeninfo>La &loan-dialog; &appname;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="loan-dialog.png"/></imageobject>
+<textobject><phrase>La &loan-dialog; &appname;</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+</sect1>
+
+<sect1 id="tips">
+<title>Astuces générales</title>
+
+<para>
+Ceci est la liste des astuces contenues dans les "astuces du jour de &appname;.
+</para>
+
+<tip>
+<para>
+Si un livre a plus d'un auteur, les noms doivent être séparés par des
+point-virgule, afin que &appname; puisse les dissocier et les utiliser
+séparément. Tous les autres champs permettant d'avoir plusieurs valeurs doivent
+être saisis de la même manière.
+</para>
+</tip>
+
+<tip>
+<para>
+Vous pouvez choisir quels champs doivent être affichés dans la vue en liste en
+cliquant du bouton droit sur l'en-tête des colonnes.
+</para>
+</tip>
+
+<tip>
+<para>
+Vous pouvez ajouter ou modifier les champs de la collection avec la
+&fields-dialog;. Les boutons avec des flèches sous la liste peuvent être
+utilisés pour changer la position dans la liste, ce qui affecte le
+positionnement dans l'&entry-editor;.
+</para>
+</tip>
+
+<tip>
+<para>
+Si vous souhaitez filtrer selon un champ
+<link linkend="bool"><emphasis>Case à cocher</emphasis></link>, la valeur
+"true" doit être utilisée. Si vous voulez afficher uniquement les films de
+science fiction que vous n'avez pas lus, par exemple, cochez la case
+<guilabel>Vérifie tout</guilabel>, configurez la première règle en tant que
+"Genre" "contient" "Science Fiction" (sans guillemets) et la seconde règle en
+tant que "Lu" "ne contient pas" "true" (sans guillemets).
+</para>
+</tip>
+
+<tip>
+<para>
+Si un caractère non alphabétique est utilisé dans le filtre rapide, le texte
+est interprété en tant qu'expression régulière. Pour afficher uniquement les
+livres de Weber ou Bujold par exemple, entrez "weber|bujold" (sans guillemets)
+dans la boîte de filtre.
+</para>
+</tip>
+
+<tip>
+<para>
+Vous pouvez modifier plus d'une entrée à la fois, en gardant appuyée la touche
+Maj ou Control et en sélectionnant plusieurs entrées.
+</para>
+</tip>
+
+<tip>
+<para>
+Vous pouvez convertir une collection de livres en bibliographie, qui peut alors
+être exportée au format BibTeX ou BibTeXML.
+</para>
+</tip>
+
+
+<tip>
+<para>
+Si plus d'un champ est mis en forme en tant que nom, un group supplémentaire
+appelé "Personnes" est ajouté à la collection, permettant ainsi aux auteurs et
+éditeurs d'être affichés ensemble, par exemple.
+</para>
+</tip>
+
+<tip>
+<para>
+Vous pouvez modifier l'apparence des données affichées en modifiant le fichier
+<filename>tellico-printing.xsl</filename>. Le fichier génère du &html; ; et le
+&css; contenu dans la feuille de style détermine les aspects tels que les
+polices, marges, etc.
+</para>
+</tip>
+
+<tip>
+<para>
+Double-cliquer sur une entrée ouvre l'&entry-editor;.
+</para>
+</tip>
+
+<tip>
+<para>
+Vous pouvez ajouter des tags &html; aux champs de type
+<link linkend="para"><emphasis>paragraphe</emphasis></link> pour la mise en
+forme, tels que &lt;b&gt;<emphasis role="bold">bold</emphasis>&lt;/b&gt; (gras)
+ou &lt;i&gt;<emphasis>italic</emphasis>&lt;/i&gt; (italique).
+</para>
+</tip>
+
+<tip>
+<para>
+Dans la &detailed-view;, vous pouvez presser une lettre au clavier pour
+aller directement you can press a letter on the
+keyboard to skip to the next entry that starts with that letter.
+</para>
+</tip>
+
+<tip>
+<para>
+Vous pouvez utiliser les champs dépendant pour combiner plusieurs champs dans
+un seul. Sélectionez le type dépendant pour le champ et entrez une description
+similaire à "<userinput>Value: %{fielda}%{fieldb}</userinput>" en remplaçant le
+contenu de %{...} par le nom de champ approprié. Ceci est utile pour regrouper
+plusieurs valeurs dans un seul champ ; par exemple pour un meilleur
+regroupement ou combiner différents champs tout en respectant les critères de
+tri. Considérez par éxemple un champ numérique suivi par un champ de text avec
+des entrées 3b et 14a.
+</para>
+</tip>
+
+</sect1>
+
+</chapter>
diff --git a/doc/fr/general-options.png b/doc/fr/general-options.png
new file mode 100644
index 0000000..6ba694d
--- /dev/null
+++ b/doc/fr/general-options.png
Binary files differ
diff --git a/doc/fr/hacking.docbook b/doc/fr/hacking.docbook
new file mode 100644
index 0000000..ed30c0a
--- /dev/null
+++ b/doc/fr/hacking.docbook
@@ -0,0 +1,448 @@
+<chapter id="hacking">
+<title>Hacking &appname;</title>
+
+<para>
+Suivant l'esprit du Logiciel Libre, vous pouvez modifier &appname; autant que
+vous le désirez. Il devrait être très simple d'écrire des scripts pour importer,
+exporter ou modifier des données.
+Ce chapitre vous donne plus d'informations sur ce sujet.
+</para>
+
+<sect1 id="file-format">
+<title>Format de fichiers</title>
+
+<para>
+Le format de fichier par défaut de &appname; est une archive zip, normallement
+avec une extension de fichier en <literal role="extension">.tc</literal>.
+A l'intérieur de l'archive se trouve un fichier
+<filename>tellico.xml</filename>.
+Les images peuvent être placées dans le répertoire <filename>images/</filename>
+dans l'archive, ou être incluses directement dans le flux &xml; encodées au
+format base64. Les images peuvent également être enregistrées dqns le repertoire
+de données de l'application ; auquel cas elles ne sont pas du tout présentes
+dans le fichier de données.
+&appname; peut également charger le fichier &xml; directement; non compressé.
+</para>
+
+<sect2 id="xml-format">
+<title>Données &xml;</title>
+
+<para>
+</para>
+
+<sect3 id="coll-xml-data">
+<title>Collection</title>
+<programlisting>
+<![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE tellico PUBLIC "-//Robby Stephenson/DTD Tellico V9.0//EN" "http://periapsis.org/tellico/dtd/v9/tellico.dtd">
+<tellico xmlns="http://periapsis.org/tellico/" syntaxVersion="9">
+ <collection title="My Books" type="2">
+ </collection>
+</tellico>
+]]>
+</programlisting>
+
+<para>
+Le fichier commence par la déclaration et l'encodage &xml; requis, suivis par
+le type de document ("doctype"). Quand un nouveau champs est ajouté ou une
+propriété aditionelle attribuée aux champs par défaut, la version de DTD du
+doctype est incrémentée.
+&appname; est toujours capable d'ouvrir et lire les versions de DTD
+précédentes, mais sauvegarde les fichiers dans la version courante.
+La localisation DTD pointe vers le ficher DTD lui-même.
+</para>
+
+<para>
+L'élément racine est un élément <markup>&lt;tellico&gt;</markup>, contenant la
+déclaration de l'espace de nommage par défaut et la version de la syntaxe du
+fichier, qui devraient toujours etre identiques à ceux de la DTD.
+</para>
+
+<para>
+L'élément <markup>&lt;tellico&gt;</markup> contient un élément
+<markup>&lt;collection&gt;</markup>.
+Les collections multiples sont ignorées pour le moment. L'attribut
+<markup>title</markup> contient le nom de la collection, alors que l'attribut
+<markup>type</markup> specifie quel type d'entrées est contenu dans la
+collection. La liste des types disponibles est disponible dans
+<link linkend="collection-type-values">une autre section</link>. Un attribut
+optionnel <markup>entryTitle</markup> peut être utilisé pour spécifier le nom
+des entrées dans une collection personnalisée, et devrait être au pluriel.
+</para>
+</sect3>
+
+<sect3 id="fields-xml-data">
+<title>Champs</title>
+
+<programlisting>
+<![CDATA[
+ <fields>
+ <field flags="8" title="Title" category="General" format="1" type="1" name="title" />
+ <field flags="7" title="Author" category="General" format="2" type="1" name="author" />
+ <field flags="2" title="Binding" category="General" allowed="Hardback;Paperback;Trade Paperback;E-Book;Magazine;Journal" format="4" type="3" name="binding" />
+ <field flags="6" title="Publisher" category="Publishing" format="0" type="1" name="publisher" />
+ <field flags="4" title="Edition" category="Publishing" format="0" type="1" name="edition" />
+ <field flags="3" title="Copyright Year" category="Publishing" format="4" type="6" name="cr_year" />
+ <field flags="2" title="Publication Year" category="Publishing" format="4" type="6" name="pub_year" />
+ <field flags="0" title="ISBN#" category="Publishing" format="4" type="1" name="isbn" description="International Standard Book Number" />
+ <field flags="7" title="Genre" category="Classification" format="0" type="1" name="genre" />
+ <field flags="7" title="Keywords" category="Classification" format="0" type="1" name="keyword" />
+ <field flags="0" title="Front Cover" category="Front Cover" format="4" type="10" name="cover" />
+ <field flags="0" title="Comments" category="Personal" format="4" type="1" name="comments" />
+ </fields>
+]]>
+</programlisting>
+
+<para>
+Tous les champs sont définis dans un élément <markup>&lt;fields&gt;</markup>,
+qui doit être unique. Toutes les informations d'un champ, à l'exception des
+propriétés étendues, sont incluses dans l'élément
+<markup>&lt;field&gt;</markup>. Les valeurs possibles pour les attributs
+<markup>flags</markup>, <markup>format</markup>, et <markup>type</markup> sont
+données dans une <link linkend="field-type-values">section suivante</link>.
+</para>
+
+<para>
+Un élément <markup>&lt;field&gt;</markup> avec un attribut "name" égal à
+<emphasis>_default</emphasis> indique à &appname; d'inclure tous les champs
+par défaut de ce type de collection.
+</para>
+</sect3>
+
+<sect3 id="entries-xml-data">
+<title>Entrées</title>
+
+<programlisting>
+<![CDATA[
+ <entry>
+ <title>Le langage C++, édition revue et corrigée</title>
+ <authors>
+ <author>Stroustrup, Bjarne</author>
+ </authors>
+ <publisher>Pearson Education</publisher>
+ <edition>3rd</edition>
+ <pub_year>2003</pub_year>
+ <isbn>2-7440-7003-3</isbn>
+ <genres>
+ <genre>Non-Fiction</genre>
+ </genres>
+ <keywords>
+ <keyword>Programmation et langages</keyword>
+ <keyword>Informatique et Internet</keyword>
+ </keywords>
+ <cover>cf65a2f023b6cb9e9233323dca10ac7c.jpeg</cover>
+ </entry>
+]]>
+</programlisting>
+
+<para>
+Pour chaque champs de la collection, un élément <markup>&lt;entry&gt;</markup>
+peut contenir un élément dont le nom est identique à celui du champs.
+Si des valeurs multiples sont possibles pour ce champ, la lettre
+<emphasis>s</emphasis> est ajoutée au nom du champ pour créer un élément.
+Chaque valeur est ajoutée en tant que descendant de cet élément, comme c'est le
+cas pour les champs author, genre et keyword ci-dessus.
+</para>
+
+<para>
+En conséquence, si de nouveaux champs sont ajoutés à la collection, le fichier
+de données ne sera plus conforme à la DTD. Cependant, &appname; utilise un
+analyseur &xml; ne vérifiant pas la validité des champs, ceux-ci ne posent donc
+pas problème.
+</para>
+</sect3>
+
+<sect3 id="images-xml-data">
+<title>Images</title>
+<programlisting>
+<![CDATA[
+ <images>
+ <image width="111" format="JPEG" height="140" id="cf65a2f023b6cb9e9233323dca10ac7c.jpeg" />
+ </images>
+]]>
+</programlisting>
+
+<para>
+A l'intérieur de chaque élément <markup>&lt;images&gt;</markup> apparait chaque
+image référencée par une entrée, ainsi que les attributs décrivant la taille
+de l'image, son format et son numéro d'identification. Si l'image est contenue
+dans le fichier Zip, l'élément est vide. Dans le cas contraire les données de
+l'image peuvent être contenues dans le flux &xml; sous forme de text encodé au
+format base64.
+</para>
+</sect3>
+
+</sect2>
+
+</sect1>
+
+<sect1 id="collection-type-values">
+<title>Valeurs des types de collections</title>
+
+<para>
+Le type de collection est donné dans l'attribut "type" de l'élément
+"collection". La valeur est égale à celle de l'enum <type>Type</type> défini
+dans <filename>src/collection.h</filename>.
+</para>
+
+<table>
+<title>Valeurs des types de collections</title>
+<tgroup cols="2">
+<thead>
+<row>
+<entry>Type de collection</entry>
+<entry>Valeur</entry>
+</row>
+</thead>
+<tbody>
+<row><entry>Custom Collection</entry><entry>1</entry></row>
+<row><entry>Book Collection</entry><entry>2</entry></row>
+<row><entry>Video Collection</entry><entry>3</entry></row>
+<row><entry>Music Collection</entry><entry>4</entry></row>
+<row><entry>Bibliography</entry><entry>5</entry></row>
+<row><entry>Comic Book Collection</entry><entry>6</entry></row>
+<row><entry>Wine Collection</entry><entry>7</entry></row>
+<row><entry>Coin Collection</entry><entry>8</entry></row>
+<row><entry>Stamp Collection</entry><entry>9</entry></row>
+<row><entry>Trading Card Collection</entry><entry>10</entry></row>
+<row><entry>Video Game Collection</entry><entry>11</entry></row>
+<row><entry>File Catalog</entry><entry>12</entry></row>
+</tbody>
+</tgroup>
+</table>
+
+
+</sect1>
+
+<sect1 id="field-type-values">
+<title>Valeurs des types de champs</title>
+
+<para>
+&appname; inclut tous les champs par défaut de la collection si le premier
+élément est nommé <emphasis>_default</emphasis>. Pour les champs
+<emphasis>Paragraphe</emphasis>, <emphasis>Tableau</emphasis> ou
+<emphasis>Image</emphasis>, la catégorie du champ doit être identique au titre
+du champ.
+</para>
+
+<para>
+Le type de champ est donné dans l'attribut type de l'élément.
+La valeur est égale à celle de l'enum <type>FieldType</type> défini dans
+<filename>src/field.h</filename>. Le type <emphasis>Lecture seule</emphasis>
+était prévu pour pour les champs devant être conservés ; mais ne pouvant
+pas être modifiés par l'utilisateur, tels que les champs ajoutés lors de
+l'import d'une collection dans une autre format. Il n'est pas utilisé.
+</para>
+
+<table>
+<title>Valeurs des types de champs</title>
+<tgroup cols="2">
+<thead>
+<row>
+<entry>Type de champ</entry>
+<entry>Valeur</entry>
+</row>
+</thead>
+<tbody>
+<row><entry>Texte simple</entry><entry>1</entry></row>
+<row><entry>Paragraphe</entry><entry>2</entry></row>
+<row><entry>Choix</entry><entry>3</entry></row>
+<row><entry>Case à cocher</entry><entry>4</entry></row>
+<row><entry><emphasis>Lecture seule</emphasis></entry><entry>5</entry></row>
+<row><entry>Nombre</entry><entry>6</entry></row>
+<row><entry>URL</entry><entry>7</entry></row>
+<row><entry>Tableau à une colonne</entry><entry>8</entry></row>
+<row><entry>Tableau à deux colonnes</entry><entry>9</entry></row>
+<row><entry>Image</entry><entry>10</entry></row>
+<row><entry>Dépendant</entry><entry>11</entry></row>
+<row><entry>Date</entry><entry>12</entry></row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+Le champ peut avoir plusieurs options, données par la valeur d'un champ de bits
+dans l'attribut flags de l'élément du champ. L'option interdisant à
+l'utilisateur d'effacer un champ est prévue pour des données telles qu'une
+citation dans une entrée bibliographique.
+</para>
+
+<table>
+<title>Valeurs des options de champ</title>
+<tgroup cols="2">
+<thead>
+<row>
+<entry>Option de champ</entry>
+<entry>Valeur</entry>
+</row>
+</thead>
+<tbody>
+<row><entry>Autoriser des valeurs multiples</entry><entry><constant>0x01</constant></entry></row>
+<row><entry>Autoriser le regroupement</entry><entry><constant>0x02</constant></entry></row>
+<row><entry>Activer l'auto-complétion</entry><entry><constant>0x04</constant></entry></row>
+<row><entry><emphasis>Interdire l'effacement</emphasis></entry><entry><constant>0x08</constant></entry></row>
+</tbody>
+</tgroup>
+</table>
+
+<para>
+La mise en forme du champ est donnée dans l'attribut format de l'élément.
+<emphasis>Date</emphasis> n'est pas utilisé pour le moment. Le regroupement par
+<emphasis>Personne</emphasis> utilise tous les champs ayant une mise en forme
+de <emphasis>Nom</emphasis>.
+</para>
+
+<table>
+<title>Valeurs de mises en forme de champ</title>
+<tgroup cols="2">
+<thead>
+<row>
+<entry>Format de champ</entry>
+<entry>Valeur</entry>
+</row>
+</thead>
+<tbody>
+<row><entry>Capitales</entry><entry>0</entry></row>
+<row><entry>Title</entry><entry>1</entry></row>
+<row><entry>Nom</entry><entry>2</entry></row>
+<row><entry><emphasis>Date</emphasis></entry><entry>3</entry></row>
+<row><entry>Pas de mise en forme</entry><entry>4</entry></row>
+</tbody>
+</tgroup>
+</table>
+
+</sect1>
+
+<sect1 id="hidden-options">
+<title>Options de configuration cachées</title>
+
+<para>
+&appname; dispose de certaines options de configuration qui ne sont pas visibles
+dans la &config-dialog;. Elles ne sont pas suffisament importantes pour charger
+la boite de dialogue avec plus d'options, mais puisqu'elles peuvent être utiles
+à certains utilisateurs, l'application les lit dans le fichier de configuration.
+</para>
+
+<para>
+Les paramètres de &appname; sont enregistrés dans un fichier du répertoire de
+l'utilisateur,
+<filename>$<envar>KDEHOME</envar>/share/config/tellicorc</filename>.
+Dans ce fichier; les paramètres sont rassemblés dans des groupes qui
+apparaissent avec un nom entre crochet, tel que [General Options].
+Pour ajouter un paramètre au groupe <emphasis>General Options</emphasis>,
+trouvez la ligne dans le fichier de configuration avec ce nom de groupe.
+S'il n'apparait pas, créez-le vous-même en ajoutant une ligne [General Options].
+Les paramètres peuvent alors être ajoutés sur les lignes suivantes.
+</para>
+
+<sect2 id="hidden-general-options">
+<title>[General Options]</title>
+
+<para>
+Ces paramètres doivent être placés dans le groupe
+<emphasis>General Options</emphasis>.
+</para>
+
+<sect3>
+<title>Max Icon Size</title>
+
+<para>
+La taille maximum des icones dans la &icon-view; peut être changée avec cette
+option. La valeur par défaut est 96, et peut être modifiée entre 32 et 128.
+</para>
+</sect3>
+
+<sect3>
+<title>Exemple</title>
+<informalexample>
+<para><userinput>Max Icon Size=72</userinput></para>
+</informalexample>
+</sect3>
+
+</sect2>
+
+<sect2 id="hidden-bibtex-options">
+<title>[Options - bibtex]</title>
+
+<para>
+Ces paramètres doivent être placés dans le groupe <emphasis>Options - bibtex</emphasis>.
+</para>
+
+<sect3>
+<title>lyxpipe</title>
+
+<para>
+Ce paramètre indique l'adresse lyxpipe pour envoyer les citations bibliographiques. Il ne doit pas inclure le suffixe <literal role="extension">.in</literal>.
+</para>
+</sect3>
+
+<sect3>
+<title>Exemple</title>
+<informalexample>
+<para><userinput>lyxpipe=$HOME/.lyx/lyxpipe</userinput></para>
+</informalexample>
+</sect3>
+</sect2>
+
+<sect2 id="hidden-export-options-pilotdb">
+<title>[Export Options - PilotDB]</title>
+
+<para>
+Ces paramètres doivent être placés dans le groupe <emphasis>Export Options - PilotDB</emphasis>.
+</para>
+
+<sect3>
+<title>Charset</title>
+
+<para>
+L'encodage des données exportées dans le fichier PilotDB peut être changé avec
+ce paramètre.
+La valeur par défaut est le jeu de caractères de la locale de l'utilisateur.
+</para>
+</sect3>
+
+<sect3>
+<title>Exemple</title>
+<informalexample>
+<para><userinput>Charset=Windows-1250</userinput></para>
+</informalexample>
+</sect3>
+</sect2>
+
+</sect1>
+
+<sect1 id="bibtex-translation">
+<title>Conversion de cqrqctères BibTeX</title>
+
+<para>
+Lorsque des fichiers BibTeX sont i,portés ou exportés, certains caractères sont
+convertis entre leur équivalent TeX et unicode. Ces tables de conversions sont
+contenues dans le fichier <filename>bibtex-translation.xml</filename>, se
+trouvant dans le repertoire de données installées par le logiciel. Ces tables
+de conversion peuvent être modifiée librement.
+L'élément clef contient le caractère Unicode, et les chaines contiennent les
+équivalents TeX, qui peuvent être multiples.
+Le premier est celui utilisé lors des exports qu format BibTeX.
+</para>
+
+<programlisting>
+<![CDATA[
+ <key char="À">
+ <string>{\`A}</string>
+ <string>\`{A}</string>
+ </key>
+]]>
+</programlisting>
+
+</sect1>
+
+<sect1 id="xslt-tricks">
+<title>Astuces XSLT</title>
+
+<para>
+Quelques astuces pour écrire du XSLT pour traiter les données &xml; de &appname; : (à écrire).
+</para>
+</sect1>
+
+</chapter>
diff --git a/doc/fr/imdb-options.png b/doc/fr/imdb-options.png
new file mode 100644
index 0000000..83c914b
--- /dev/null
+++ b/doc/fr/imdb-options.png
Binary files differ
diff --git a/doc/fr/importing-exporting.docbook b/doc/fr/importing-exporting.docbook
new file mode 100644
index 0000000..61596fe
--- /dev/null
+++ b/doc/fr/importing-exporting.docbook
@@ -0,0 +1,594 @@
+<chapter id="importing-exporting">
+<title>Importer et exporter des données</title>
+
+<para>
+&appname; peut importer et exporter une grande variété de fichiers de données,
+ainsi que chercher des informations sur divers sites Internet.
+</para>
+
+<sect1 id="internet-search">
+<title>Importer depuis Internet</title>
+<para>
+&appname; peut chercher sur divers sites Internet en utilisant la
+&fetch-dialog;. Les entrées peuvent être directement importées et ajoutées à
+votre collection. Les différents fournisseurs peuvent être configurés via les
+<link linkend="data-sources-options">Options de sources de données</link>.
+</para>
+
+<para>
+Les recherches peuvent utiliser cinq critères différents :
+<guilabel>Titre</guilabel>, <guilabel>Personne</guilabel>,
+<guilabel>ISBN</guilabel>, <guilabel>UPC/EAN</guilabel> ou
+<guilabel>mot)clef</guilabel>. Tous les critères ne sont pas disponibles pour
+certaines sources. Une fois la recherche débutée, le bouton
+<guibutton>Chercher</guibutton> se transforme en bouton
+<guibutton>Stop</guibutton> qui permet d'arrêter la recherche. Au fur et à
+mesure que les résultats sont obtenus, ils sont automatiquement ajoutés à la
+liste sous la boite de recherche. Cliquer sur une entrée affiche le résultat
+sans l'ajouter à la collection. Cliquer sur le bouton <guibutton>Ajouter
+l'entrée</guibutton> ajoute toutes les entrées sélectionnées à votre collection.
+Cliquer sur le bouton <guibutton>Effacer</guibutton> efface tous les résultats
+et initialise la recherche.
+</para>
+
+<screenshot>
+<screeninfo>La &fetch-dialog; &appname;</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="fetch-dialog.png"/></imageobject>
+<textobject><phrase>La &fetch-dialog; &appname;</phrase></textobject>
+<caption><para>La &fetch-dialog; &appname;</para></caption>
+</mediaobject>
+</screenshot>
+
+<para>
+Seules les entrées ayant le même type de collection peuvent être trouvées.
+La colonne <guilabel>Description</guilabel> fournit des informations
+supplémentaires à propos de l'entrée, afin de différencier les vidéos de
+différents formats ou les livres ayant des reliures différentes. Une fois
+qu'une entrée a été ajoutée à la collection, une icône est ajoutée dans la
+première colonne de la liste.
+</para>
+
+<para>
+Afin de faciliter l'utilisation de lecteurs de code barre, les recherches
+peuvent porter sur plusieurs valeurs ISBN à la fois. Cocher la case
+<guilabel>Recherche ISBN multiple</guilabel> désactive la boite de recherche et
+active le bouton <guibutton>Liste ISBN...</guibutton>, qui ouvre une boite de
+dialogue permettant d'entrer plusieurs lignes. Chaque numéro ISBN doit être sur
+une ligne différente. Après avoir fermé la boite de dialogue, la mise en forme
+de chaque numéro ISBN est vérifiée. Le procédé de validation ISBN permet de
+convertir les valeurs EAN à 13 chiffres, ainsi que les codes
+<acronym>UPC</acronym> au format ISBN classique. La liste de numéros ISBN peut
+également être lue à partir d'un fichier texte.
+</para>
+
+</sect1>
+
+<sect1 id="importing">
+<title>Importer des données</title>
+
+<para>
+&appname; propose trois différentes actions lors de l'import de données.
+<guilabel>Remplacer la collection</guilabel> indique que la collection ouverte
+doit être fermée, et une nouvelle créée à partir des données importées.
+<guilabel>Ajouter à la collection</guilabel> indique à &appname; d'ajouter
+toutes les entrées de la collection importée à celle ouverte, et d'ajouter les
+champs manquant.
+<guilabel>Fusionner avec la collection ouverte</guilabel> a le même effet
+qu'ajouter ; mais chaque entrée importée est comparée avec celles existant déjà,
+et celles en double sont ignorées.
+Il est prévu dans le futur d'améliorer l'algorithme pour identifier les
+entrées en double ; mais pour le moment, en dehors des collections musicales,
+tous les champs doivent être identiques.
+Pour les collections musicales, &appname; compare seulement l'artiste et
+l'album, et les plages sont fusionnées pour les entrées correspondantes.
+L'<link linkend="importing-audio-files">import de fichiers audio</link> peut
+générer des listes de titres en fusionnant les entrées.
+</para>
+
+<sect2 id="importing-tellico">
+<title>Importer des données &appname;</title>
+
+<para>
+D'autres fichiers de données &appname; peuvent être importés. Remplacer la
+collection actuelle en important un fichier &appname; donne le même résultat
+qu'une simple ouverture du fichier.
+L'intérêt d'importer des données &appname; est principalement pour les ajouter
+ou les fusionner deux collections ensemble.
+</para>
+</sect2>
+
+<sect2 id="importing-csv">
+<title>Importer des données CSV</title>
+
+<para>
+Les valeurs séparées par des virgules (CSV) sont un moyen courant d'importer
+et d'exporter des données tabulaires.
+Les différentes valeurs de champs sont séparées par des virgules, chaque entrée
+occupant une ligne.
+Les titres des champs peuvent être inclus comme en-tête en première ligne.
+N'importe quel caractère ou chaîne de caractère autre que la virgule peut
+également être utilisé pour délimiter les champs.
+</para>
+
+<screenshot>
+<screeninfo>La boite de dialogue d'import CVS</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="csv-dialog.png"/></imageobject>
+<textobject><phrase>La boite de dialogue d'import CVS</phrase></textobject>
+<caption><para>La boite de dialogue d'import CVS</para></caption>
+</mediaobject>
+</screenshot>
+
+<para>
+Commencer par sélectionner le type de collection que vous souhaitez importer.
+Si vous ajoutez ou fusionnez avec la collection ouverte, le type est limité à
+celui la collection courante. Si la première ligne du fichier CSV contient les
+titres des champs, cochez la case correspondante et l'outil d'import comparera
+automatiquement les titres avec ceux des champs de la collection ouverte. Si
+les titres concordent, l'en-tête de cette colonne change pour indiquer que cette
+colonne a été assignée à un champ. Si le fichier utilise un autre séparateur
+que la virgule, assurez-vous de changer l'option en conséquence.
+</para>
+
+<para>
+Pour que &appname; puisse importer correctement le fichier, il doit connaître
+la correspondance entre les champs et les numéros de colonne. <emphasis>Si la
+colonne a seulement un nombre dans son en-tête, les données de cette colonne ne seront pas importées</emphasis>. Vous devez assigner un champ à chaque colonne
+en sélectionnant une colonne, soit en cliquant dessus, soit en changeant le
+numéro de colonne manuellement, puis en sélectionnant le champ à y associer
+depuis la liste déroulante et en cliquant sur le bouton <guibutton>Assigner le
+champ</guibutton>. Si vous souhaitez ajouter un nouveau champ à la collection,
+la dernière entrée du menu déroulant ouvre la
+<link linkend="fields-dialog">&fields-dialog;</link>.
+</para>
+
+<para>
+Seules les cinq premières lignes du fichier CSV importé sont affichées dans la
+boite de dialogue.
+</para>
+
+</sect2>
+
+<sect2 id="importing-audio">
+<title>Importer les données d'un CD audio</title>
+
+<para>
+&appname;peut utiliser le service
+<ulink url="http://freedb.org">freedb.org</ulink> pour trouver des informations
+à propos d'un <acronym>CD</acronym>, y compris la liste des titres. En fonction
+de la distribution que vous utilisez, les paramètres d'accès à ce service
+peuvent être configurés dans le centre de contrôle &kde;. L'artiste et le titre
+du CD, le genre, l'année et la liste des titres sont tous ajoutés.
+</para>
+
+<para>
+De plus, si le disque est de type CD-Text, les informations contenues sont lues
+et ajoutées à l'entrée importée.
+</para>
+</sect2>
+
+<sect2 id="importing-audio-files">
+<title>Importer les données d'un fichier audio</title>
+
+<para>
+&appname; peut parcourir un répertoire et lire les tags de formats de fichiers
+audio communs, tels que <literal role="extension">mp3</literal> ou
+<literal role="extension">ogg</literal>. Les titres sont ajoutés à une
+collection musicale, dans laquelle chaque entrée représente un album.
+Si le fichier musical contient un numéro de piste, le titre est ajouté a la
+position correcte dans la liste de l'album.
+L'artiste et le genre de musique sont également ajoutés à l'entrée.
+Si les données contiennent des commentaires, ceux-ci sont ajoutés au champ
+commentaires de l'entrée, précédés du nom de fichier.
+</para>
+
+<para>
+De plus, si un répertoire contient un ficher <filename>.directory</filename> et
+que le nom du répertoire concorde avec le titre d'un album, l'entrée
+<literal>Icon</literal> du fichier desktop est utilisée en tant que couverture
+de l'album.
+</para>
+
+<para>
+L'import de méta-données de fichiers audio peut être fait en parcourant un
+répertoire de façon récursive pour trouver tous les fichiers audio contenus dans
+ce répertoire. Cependant, les liens symboliques ne sont pas suivis. &appname;
+utilise la bibliothèque
+<ulink url="http://developer.kde.org/~wheeler/taglib.html">TagLib</ulink> pour
+lire les données des fichiers audio, et peut donc importer les données de tous
+les formats reconnus par TagLib.
+</para>
+
+</sect2>
+
+<sect2 id="importing-alexandria">
+<title>Importer des bibliothèques Alexandria</title>
+
+<para>
+<application><ulink url="http://alexandria.rubyforge.org">Alexandria</ulink></application> est un gestionnaire de collection de livres pour le bureau
+<ulink url="http://www.gnome.org">Gnome</ulink>. L'importeur offre la
+possibilité d'importer les bibliothèques trouvées dans
+<filename class="directory">$<envar>HOME</envar>/.alexandria/</filename>.
+</para>
+
+</sect2>
+
+<sect2 id="importing-bibtex">
+<title>Importer des données BibTeX</title>
+
+<para>
+<ulink url="http://www.ecst.csuchico.edu/~jacobsd/bib/formats/bibtex.html">BibTeX</ulink> est un format de bibliographie utilisé avec le système de préparation
+de documents LaTeX. Différents types de références bibliographiques peuvent
+être incluses dans le fichier. &appname; importe les fichiers BibTeX sous forme
+de collection bibliographique.
+</para>
+
+<para>
+Si l'outil d'import BibTeX rencontre des champs dans le fichier qui ne sont pas
+dans la collection bibliographique par défaut, ils sont ajoutés en tant que
+champs de type <link linkend="line">Texte Simple</link>; avec deux exceptions.
+Si la valeur du champ contient plus de 100 caractères, il est transformé en
+champs de type <link linkend="para">Paragraphe</link>.
+Si la valeur du champs contient un &URL; ou une référence à un fichier, un
+champs de type <link linkend="url">URL</link> est créé.
+&appname; utilise une copie interne de la
+<ulink url="http://www.gerg.ca/software/btOOL/">bibliothèque btparse</ulink>
+pour traiter les fichier BibTeX.
+</para>
+</sect2>
+
+<sect2 id="importing-bibtexml">
+<title>Importer des données BibTeXML</title>
+
+<para>
+<ulink url="http://bibtexml.sf.net">BibTeXML</ulink> est une représentation
+&xml; de données BibTeX. Les données importées d'un fichier BibTeXML sont
+traitées de la même manière que les données BibTeX.
+</para>
+
+</sect2>
+
+<sect2 id="importing-mods">
+<title>Importer des données MODS</title>
+
+<para>
+<acronym><ulink url="http://www.loc.gov/standards/mods/">MODS</ulink></acronym>
+est un format pour représenter divers types de collections. Pour le moment,
+seuls les livres peuvent être importés dans &appname;.
+</para>
+
+</sect2>
+
+<sect2 id="importing-ris">
+<title>Importer des données RIS</title>
+<para>
+Le <ulink url="http://www.adeptscience.co.uk/kb/article/A626">format
+<acronym>RIS</acronym></ulink> est un format de fichier bibliographique utilisé
+entre autres par <application>Référence Manager</application>. &appname; les
+fichiers <acronym>RIS</acronym> en tant que collection bibliographique.
+</para>
+</sect2>
+
+<sect2 id="importing-gcfilms">
+<title>Importer des données GCfilms</title>
+
+<para>
+<application><ulink url="http://home.gna.org/gcfilms/">GCfilms</ulink></application>
+est un gestionnaire de collection de films. Normalement, les fichiers de données
+<application>GCfilms</application> se trouvent dans le répertoire
+<filename class="directory">$<envar>HOME</envar>/.local/share/gcfilms/</filename>.
+</para>
+
+</sect2>
+
+<sect2 id="importing-file-listing">
+<title>Importer une liste de fichiers</title>
+
+<para>
+Le meilleur moyen de créer un <link linkend="file-catalog">catalogue de
+fichiers</link> est d'importer le contenu d'un répertoire. La recherche dans le
+répertoire peut être récursive, pour ajouter tous les fichiers trouvés.
+L'outil d'import est particulièrement utile pour les listes de sauvegardes et
+les catalogues de fichiers, tels que les <acronym>CD</acronym> or
+<acronym>DVD</acronym>. De plus, des prévisualisations en image des fichiers
+peuvent être créées. Cependant, ceci peut prendre du temps s'il est nécessaire
+de lire un nombre important de fichiers. Les prévisualisations sont du même
+type que celles affichées dans le gestionnaire de fichiers &kde;.
+</para>
+</sect2>
+
+<sect2 id="importing-xslt">
+<title>Importer des données &xml; via XSLT</title>
+
+<para>
+N'importe quel fichier peut être importé dans &appname;, pourvu qu'il existe une
+feuille de style XSL disponible pour convertir le fichier au format &appname;.
+&appname; charge automatiquement la feuille de style et effectue le traitement
+XSLT nécessaire pour charger le fichier &xml;.
+</para>
+</sect2>
+
+</sect1>
+
+<sect1 id="exporting">
+<title>Exporter des données</title>
+
+<para>
+Lors de l'export de données de la collection, les valeurs des entrées peuvent
+être exportées telles qu'elles ont été créées, ou avec la
+<link linkend="field-formatting">mise en forme automatique</link> fournie par
+&appname;. De plus, l'export peut être limité aux entrées sélectionnées, la
+<link linkend="status-bar">barre d'état</link> indiquant le nombre d'entrées
+sélectionnées.
+</para>
+
+<para>
+Les fichiers texte exportés, tels que BibTeX ou CSV, peuvent utiliser l'encodage
+de caractères Unicode (UTF-8) ou celui de la locale du système d'exploitation.
+</para>
+
+<screenshot>
+<screeninfo>Options d'export générales</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="export-options.png"/></imageobject>
+<textobject><phrase>Options d'export générales</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<sect2 id="exporting-xml">
+<title>Exporter en &xml;</title>
+
+<para>
+Le format de fichier pour &appname; est un fichier &xml; compressé au format
+zip. Exporter en &xml; crée le fichier &xml; sans le compresser. Les images
+peuvent être intégrées dans le fichier &xml; sous forme de donnée encodée au
+format base64 dans un élément image.
+</para>
+</sect2>
+
+<sect2 id="exporting-zip">
+<title>Exporter au format Zip</title>
+
+<para>
+Le format de fichier standard pour &appname; est un fichier zip, contenant le
+fichier de collection &xml;, et, si souhaité, toutes les images référencées
+dans la collection. Si les images sont conservées dans le répertoire de
+l'application, exporter au format Zip créera un fichier de données contenant
+toutes les images de la collection.
+</para>
+</sect2>
+
+<sect2 id="exporting-html">
+<title>Exporter en HTML</title>
+
+<para>
+L'export HTML utilise la feuille de style <filename>tellico2html.xsl</filename>.
+Les images sont exportées dans un répertoire portant le même nom que le fichier
+HTML avec le suffixe <emphasis><filename>_files</filename></emphasis>.
+</para>
+
+<para>
+Le format par défaut est similaire à celui pour l'impression et permet de
+modifier le code HTML de plusieurs manières. Les en-tête des champs peuvent
+être imprimés en haut de chaque colonne ; malheureusement &kde; ne permet pas
+encore de répéter les en-tête des tableaux sur chaque page. Les entrées peuvent
+être regroupées de la même manière que dans la &group-view;.
+</para>
+
+<para>
+De plus, des fichiers individuels peuvent être créés pour chaque entrée de la
+collection, avec les liens générés dans le fichier HTML racine. Les fichiers
+d'entrées sont créés dans le même répertoire que les images.
+Les fichiers d'entrées HTML utilisent la feuille de style courante, comme dans
+la &entry-view;.
+</para>
+
+<screenshot>
+<screeninfo>Options d'export HTML</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="export-html.png"/></imageobject>
+<textobject><phrase>Options d'export HTML</phrase></textobject>
+</mediaobject>
+</screenshot>
+</sect2>
+
+<sect2 id="exporting-csv">
+<title>Exporter en CSV</title>
+
+<para>
+Les valeurs séparées par des virgules (CSV) sont un moyen courant d'importer
+et d'exporter des données tabulaires. Les différentes valeurs de champs sont
+séparées par des virgules, chaque entrée occupant une ligne. Les titres des
+champs peuvent être inclus comme en-tête en première ligne. N'importe quel
+caractère ou chaîne de caractère autre que la virgule peut également être
+utilisé pour délimiter les champs.
+</para>
+
+<screenshot>
+<screeninfo>Options d'export CSV</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="export-csv.png"/></imageobject>
+<textobject><phrase>Options d'export CSV</phrase></textobject>
+</mediaobject>
+</screenshot>
+</sect2>
+
+<sect2 id="exporting-pilotdb">
+<title>Exporter en Pilot-DB</title>
+
+<para>
+<ulink url="http://pilot-db.sourceforge.net">Pilot-DB</ulink> est un format de
+base de données pour Palm OS. Diverses applications de bureau peuvent lire et
+écrire les fichiers Pilot-DB. Les fichiers
+<literal role="extension">.pdb</literal> exportés peuvent être transférés vers
+un PDA et utilisés directement. Pour le moment, &appname; ne peut pas importer
+de fichier Pilot-DB.
+</para>
+
+<screenshot>
+<screeninfo>Options d'export Pilot-DB Export</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="export-pdb.png"/></imageobject>
+<textobject><phrase>Options d'export Pilot-DB Export</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+</sect2>
+
+<sect2 id="exporting-alexandria">
+<title>Exporting Alexandria</title>
+
+<para>
+<application><ulink url="http://alexandria.rubyforge.net">Alexandria</ulink></application>
+est un outil de gestion de bibliothèques pour l'environnement de bureau
+<ulink url="http://www.gnome.org">GNOME</ulink>. &appname; peut importer une
+partie limitée des champs des collections de livres vers le point
+d'enregistrement par défaut des données Alexandria.
+</para>
+
+</sect2>
+
+<sect2 id="exporting-onix">
+<title>Exporting ONIX</title>
+
+<para>
+<ulink url="http://www.editeur.org/onix.html">ONIX</ulink> est un format XML
+pour la représentation et transmettre les informations des livres dans un cadre
+industriel, essentiellement pour les vendeurs. &appname; peut exporter des
+collections de livres en utilisant un sous-ensemble d'ONIX.
+</para>
+
+</sect2>
+
+<sect2 id="exporting-bibtex">
+<title>Exporter en BibTeX</title>
+
+<para>
+Lors de l'export en format
+<ulink url="http://en.wikipedia.org/wiki/Bibtex">BibTeX</ulink>,
+les valeurs de champs peuvent être échappées avec des parenthèses ou des
+guillemets. Si des macros sont utilisées dans la collection, elles peuvent être exportées en tant que macros ou appliquées. Pour les champs de type &URL;,
+&appname; peut peut inclure les valeurs du champs dans un tag
+<literal>\url{...}</literal>. Enfin, les entrées de contenant pas de clef de
+citation peuvent être ignorées au lieu de voir des clefs automatiquement
+générées par &appname;.
+</para>
+
+<screenshot>
+<screeninfo>Options d'export BibTeX</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="export-bibtex.png"/></imageobject>
+<textobject><phrase>Options d'export BibTeX</phrase></textobject>
+</mediaobject>
+</screenshot>
+</sect2>
+
+<sect2 id="exporting-bibtexml">
+<title>Exporter en BibTeXML</title>
+
+<para>
+<ulink url="http://bibtexml.sourceforge.net">Bibtexml</ulink> est un format
+permettant de conserver des données BibTeX au format XML.
+</para>
+
+</sect2>
+
+<sect2 id="exporting-gcfilms">
+<title>Exporting GCfilms</title>
+
+<para>
+<application><ulink url="http://home.gna.org/gcfilms/">GCfilms</ulink></application>
+est un autre outil de gestion de collection de fil,s. &appname; peut exporter
+un nombre limité de champs d'une collection de vidéos vers un fichier GCfilms.
+</para>
+
+</sect2>
+
+<sect2 id="exporting-xslt">
+<title>Exporter en &xml; via &xslt;</title>
+
+<para>
+Enfin, &appname; est capable de traiter sa représentation &xml; interne des
+données de la collection avec une feuille de style XSL externe avant d'exporter.
+Ce type d'opération peut être utile pour générer des rapports en texte ou
+d'autres types de fichiers.
+</para>
+</sect2>
+
+</sect1>
+
+<sect1 id="citations">
+<title>Travailler avec des citations</title>
+<para>
+Lorsque vous travaillez avec une
+<link linkend="bibliography">bibliographie</link>, les citations de l'entrée
+sélectionnée peuvent être générées et utilisées par d'autres applications. Une
+citation dans le format BibTeX peut être copiée vers le presse-papier, puis
+collée dans un fichier LaTeX. Les citations BibTeX peuvent également être
+transmises à une application externe telle que <application>LyX</application>
+ou <application>Kile</application> grâce à ce que l'on appelle des
+<emphasis><link linkend="hidden-bibtex-options">lyxpipe</link></emphasis>.
+Enfin une gestion limitée de l'export vers
+<application>OpenOffice.org Writer</application> est disponible.
+</para>
+
+<sect2 id="openoffice-org">
+<title>Travailler avec OpenOffice.org</title>
+<para>
+&appname; dispose d'une gestion limitée de l'envoi de citation vers
+<application>OpenOffice.org Writer</application> et de la mise à jour de la
+bibliographie d'un document. Un greffon spécifique est utilisé, et si ce
+dernier est disponible, le menu permettant de citer une entrée dans
+<application>Writer</application> est disponible. S'il ne l'est pas, c'est que
+&appname; n'a pas pu trouver ou charger le greffon. Plus d'informations
+concernant la compilation de &appname; avec la gestion de OpenOffice.org
+activée sont disponibles dans
+<link linkend="compilation-ooo">une section ultérieure.</link>.
+</para>
+
+<para>
+<application>OpenOffice.org</application> doit être configuré pour permettre
+les interactions avec d'autres applications.
+Deux méthodes sont disponibles : les tuyaux ou TCP/IP. Les tuyaux sont plus
+simples et plus rapides. Pour lancer <application>Writer</application> et s'y
+connecter a l'aide de tuyaux, la commande suivante peut être utilisée :
+
+<screen width="40">
+<prompt>%</prompt> <userinput>oowriter "-accept=pipe,name=OOo_pipe;urp;StarOffice.ServiceManager"</userinput>
+</screen>
+
+Le tuyau ou le port TCP peuvent être configurés à chaque fois que
+OpenOffice.org est exécuté. Consultez
+<ulink url="http://api.openoffice.org/docs/DevelopersGuide/OfficeBean/OfficeBean.xhtml#1_5_1_Default_Configuration">la documentation OpenOffice.org</ulink>
+pour plus de détails.
+</para>
+
+<para>
+Pour insérer une citation, sélectionnez une entrée, puis utilisez
+<guimenuitem>Citer l'entrée dans OpenOffice.org</guimenuitem>.
+<application>Writer</application> doit déjà être en cours d'exécution.
+&appname; tentera de s'y connecter. En cas d'échec, il vous demandera plus
+d'informations concernant la connexion.
+</para>
+
+<screenshot>
+<screeninfo>Boite de dialogue de connexion OpenOffice.org Connection Dialog</screeninfo>
+<mediaobject>
+<imageobject><imagedata format="PNG" fileref="openoffice-dialog.png"/></imageobject>
+<textobject><phrase>Boite de dialogue de connexion OpenOffice.org Connection Dialog</phrase></textobject>
+</mediaobject>
+</screenshot>
+
+<para>
+Sélectionnez le type de connexion, soit tuyau ou TCP!IP. Puis entrez le nom
+du tuyau, ou le nom d'hôte et le port TCP.
+&appname; conservera en mémoire vos paramètres de connexion pour les futures
+utilisations.
+</para>
+
+</sect2>
+
+</sect1>
+
+</chapter>
diff --git a/doc/fr/index.docbook b/doc/fr/index.docbook
new file mode 100644
index 0000000..7d41871
--- /dev/null
+++ b/doc/fr/index.docbook
@@ -0,0 +1,452 @@
+<?xml version="1.0" ?>
+<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.1.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [
+ <!ENTITY appname '<application>Tellico</application>'>
+ <!ENTITY kappname "&appname;">
+ <!ENTITY % addindex "IGNORE">
+ <!ENTITY % French "INCLUDE"><!-- change language only here -->
+
+ <!ENTITY robby "Robby Stephenson">
+ <!ENTITY email "robby@periapsis.org">
+ <!ENTITY homepage "http://www.periapsis.org/tellico/">
+ <!ENTITY maillist "http://forge.novell.com/mailman/listinfo/tellico-users">
+ <!ENTITY xml "<acronym>XML</acronym>">
+ <!ENTITY xslt "<acronym>XSLT</acronym>">
+ <!ENTITY html "<acronym>HTML</acronym>">
+ <!ENTITY css "<acronym>CSS</acronym>">
+
+ <!ENTITY group-view "<interface>Vue de groupe</interface>">
+ <!ENTITY detailed-view "<interface>Vue en colonnes</interface>">
+ <!ENTITY entry-view "<interface>Vue des entrées</interface>">
+ <!ENTITY entry-editor "<interface>Éditeur d'entrée</interface>">
+ <!ENTITY icon-view "<interface>Vue d'icônes</interface>">
+ <!ENTITY fields-dialog "<interface>Boite de dialogue de champs de collection</interface>">
+ <!ENTITY fetch-dialog "<interface>Boite de dialogue de recherche sur Internet</interface>">
+ <!ENTITY config-dialog "<interface>Boite de dialogue de configuration</interface>">
+ <!ENTITY find-dialog "<interface>Boite de dialogue de recherche</interface>">
+ <!ENTITY quick-filter "<interface>Filtre rapide</interface>">
+ <!ENTITY filter-dialog "<interface>Boite de dialogue de filtre avancé</interface>">
+ <!ENTITY loan-dialog "<interface>Boite de dialogue de prêt</interface>">
+ <!ENTITY report-dialog "<interface>Boite de dialogue de rapport</interface>">
+ <!ENTITY shortcut-dialog "<interface>Boite de dialogue de raccourcis clavier</interface>">
+ <!ENTITY toolbar-dialog "<interface>Boite de dialogue de configuration de la barre d'outils</interface>">
+ <!ENTITY filter-view "<interface>Vue des filtres</interface>">
+ <!ENTITY loan-view "<interface>Vue des prêts</interface>">
+
+ <!ENTITY fundamentals-chapter SYSTEM "fundamentals.docbook">
+ <!ENTITY importing-exporting-chapter SYSTEM "importing-exporting.docbook">
+ <!ENTITY configuration-chapter SYSTEM "configuration.docbook">
+ <!ENTITY fields-chapter SYSTEM "fields.docbook">
+ <!ENTITY menus-chapter SYSTEM "menus.docbook">
+ <!ENTITY advanced-chapter SYSTEM "advanced.docbook">
+ <!ENTITY hacking-chapter SYSTEM "hacking.docbook">
+ <!ENTITY faqs-chapter SYSTEM "faqs.docbook">
+ <!ENTITY details-chapter SYSTEM "details.docbook">
+
+]>
+
+<!-- ................................................................ -->
+
+<!-- The language must NOT be changed here. -->
+
+<book lang="&language;">
+
+<!-- This header contains all of the meta-information for the document such
+as Authors, publish date, the abstract, and Keywords -->
+
+<bookinfo>
+
+<!-- Date and version information of the documentation
+Don't forget to include this last date and this last revision number, we
+need them for translation coordination !
+Please respect the format of the date (DD/MM/YYYY) and of the version
+(V.MM.LL), it could be used by automation scripts.
+Do NOT change these in the translation. -->
+<date>26/01/2008</date>
+<releaseinfo>1.3</releaseinfo>
+
+<title>Le guide &appname;</title>
+
+<authorgroup>
+<author>
+<firstname>Robby</firstname>
+<surname>Stephenson</surname>
+<affiliation>
+<address><email>&email;</email></address>
+</affiliation>
+</author>
+
+<!-- TRANS:ROLES_OF_TRANSLATORS -->
+
+<othercredit role="translator">
+<firstname>Régis</firstname>
+<surname>Boudin</surname>
+<contrib>Traduction Française</contrib>
+<affiliation>
+<address><email>regis@boudin.name</email></address>
+</affiliation>
+</othercredit>
+</authorgroup>
+
+<copyright>
+<year>2001</year>
+<year>2002</year>
+<year>2003</year>
+<year>2004</year>
+<year>2005</year>
+<year>2006</year>
+<year>2007</year>
+<year>2008</year>
+<holder>&robby;</holder>
+</copyright>
+
+<!-- Translators: put here the copyright notice of the translation -->
+<!-- Put here the FDL notice. Read the explanation in fdl-notice.docbook
+ and in the FDL itself on how to use it. -->
+<legalnotice>
+<para>Permission is granted to copy, distribute and/or modify this
+document under the terms of the &GNU; Free Documentation License,
+Version 1.1 or any later version published by the Free Software
+Foundation; with &FDLInvariantSections;, with &FDLFrontCoverText;, and
+with &FDLBackCoverText;. A copy of the license is included in
+<xref linkend="gnu-fdl"/>.</para>
+
+<para>The author of this documentation has also granted you permission to use
+the content under the terms of the <ulink
+url="freebsd-doc-license.html">FreeBSD Documentation License</ulink>, if you so choose.
+See the notice in the <link linkend="gnu-fdl">licensing section</link>.</para>
+</legalnotice>
+<!--<legalnotice>&FDLNotice;</legalnotice>-->
+
+<legalnotice>
+<para>This program is free software; you can redistribute it and/or
+modify it under the terms of version 2 of the &GNU; General Public
+License as published by the Free Software Foundation.</para>
+
+<para>This program is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the &GNU;
+General Public License for more details.</para>
+
+<para>You should have received a copy of the &GNU; General Public
+License along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifh Floor, Boston, MA 02110-1301, USA.</para>
+</legalnotice>
+<!--<legalnotice>&GPLNotice;</legalnotice>-->
+
+<!-- Abstract about this handbook -->
+
+<abstract>
+<para>
+Ce document est le manuel d'utilisation pour &appname;, un logiciel de gestion de collection.
+</para>
+</abstract>
+
+<!-- This is a set of Keywords for indexing by search engines.
+Please at least include KDE, the KDE package it is in, the name
+ of your application, and a few relevant keywords. -->
+
+<keywordset>
+<keyword>KDE</keyword>
+<keyword>tellico</keyword>
+<keyword>livre</keyword>
+<keyword>bibliographie</keyword>
+<keyword>film</keyword>
+<keyword>collection</keyword>
+<keyword>base de données</keyword>
+<keyword>catalogue</keyword>
+</keywordset>
+
+</bookinfo>
+
+<!-- The contents of the documentation begin here. Label each chapter
+so with the id attribute. This is necessary for two reasons: it allows
+you to easily reference the chapter from other chapters of your
+document, and if there is no ID, the name of the generated HTML files
+will vary from time to time making it hard to manage for maintainers
+and for the CVS system. Any chapter labelled (OPTIONAL) may be left
+out at the author's discretion. Other chapters should not be left out
+in order to maintain a consistent documentation style across all KDE
+apps. -->
+
+<chapter id="introduction">
+<title>Introduction</title>
+
+<!-- The introduction chapter contains a brief introduction for the
+application that explains what it does and where to report
+problems. Basically a long version of the abstract. Don't include a
+revision history. (see installation appendix comment) -->
+
+<sect1 id="tellico-intro">
+<title>&appname;</title>
+
+<para>
+&appname; est un programme pour gérer des collections. Au départ simple
+gestionnaire de collections de livres, il a été étendu pour intégrer des
+modèles de collections de bibliographies, bandes dessinées, vidéos,
+musique, monnaies, timbres, cartes, jeux vidéo, vins, jeux de plateau et
+fichiers. De plus, des collections personnalisées peuvent être créées
+pour tout ce qui peut être collectionné.
+</para>
+
+<sect2 id="what-tellico-is">
+<title>Ce qu'est &appname;</title>
+
+<para>
+&appname; garde la trace des entrées dans une collection, et propose un
+moyen simple d'ajouter des information à chaque entrée. Il propose
+plusieurs types de champs, et permet un nombre illimité de champs
+définis par l'utilisateur.
+Les entrées d'une collection peuvent être regroupées selon n'importe quel
+champ pour une organisation facile, et les vues personnalisables affichent
+autant d'informations que vous le souhaitez.
+</para>
+
+<para>
+Les entrées prêtées peuvent être suivies, avec une intégration possible
+à &korganizer;.
+Les collections peuvent être importées ou exportées depuis et vers
+plusieurs formats, pour permettre un échange et une publication aisés
+des données.
+</para>
+
+</sect2>
+
+<sect2 id="what-tellico-is-not">
+<title>Ce que &appname; n'est pas</title>
+
+<para>
+&appname; n'est pas un lecteur audio ou vidéo. Il ne propose rien pour lire ou
+modifier des fichiers multimédia. Il ne propose pas non plus de fonction pour
+modifier les images. Bien que Tellico ait certaines fonctions pour
+gérer des listes de bibliographies, ce n'est pas un outil complet de gestion de
+références bibliographiques. &appname; n'a pas non plus la prétention d'avoir
+toutes les capacités d'un outil de base de données relationnelle.
+</para>
+
+<para>
+Enfin, &appname; est un passe-temps pour l'auteur, et il n'est fait aucune
+garantie concernant ses fonctionnalités, son utilisabilité ou quoi que ce soit
+d'autre. &appname; est loin d'être un outil logiciel professionnel. Plus
+d'informations sont disponibles dans la <link linkend="gnu-fdl">licence</link>.
+</para>
+
+</sect2>
+</sect1>
+
+<sect1 id="terminology">
+<title>Terminologie</title>
+
+<sect2 id="collections">
+<title>Collections</title>
+<para>
+Dans &appname;, le document est une collection. Une seule collection peut
+exister dans chaque fichier &appname;. Une collection contient un nombre non
+déterminé de <link linkend="fields">champs</link> et
+d'<link linkend="entries">entrées</link>.
+&appname; peut gérer douze types de collections génériques par défaut : livres,
+entrées bibliographiques, bandes dessinées, vidéos, musique, cartes, pièces de
+monnaie, timbres, jeux vidéos, vins, jeux de plateau et listes de fichiers.
+En outre, un type de collection générique vide existe pour tout autre type
+d'objet collectionnable.
+</para>
+</sect2>
+
+<sect2 id="fields">
+<title>Champs de collection</title>
+<para>
+Chaque collection peut avoir un nombre illimité de champs. &appname; gère onze
+types de champs , permettant une large variété de données différentes. Les
+champs peuvent être modifiés avec la
+<link linkend="fields-dialog">&fields-dialog;</link> et sont expliqués plus en
+détails dans la section <link linkend="field-types">types de champs</link>.
+</para>
+</sect2>
+
+<sect2 id="entries">
+<title>Entrées de collection</title>
+
+<para>
+Une entrée est un enregistrement de base dans &appname;. Chaque entrée contient
+une valeur pour chaque champ de la collection. Une collection peut avoir un
+nombre théoriquement illimité d'entrées. Cependant, la collection complète étant
+conservée en mémoire, un trop grand nombre d'entrées ralentirait l'application.
+</para>
+
+<para>
+&appname; a été testé avec une collection de 10.000 entrées, et la vitesse
+était satisfaisante. Cependant, si des images nombreuses ou volumineuses sont
+incluses dans la collection, le chargement et le traitement seront ralentis
+de façon importante. Les performances peuvent être améliorées en faisant en sorte
+que &appname; conserve les images séparées du fichier de données lui-même ; soit
+dans le répertoire de données de l'application, soit dans un répertoire situé
+relativement au fichier lui-même. Plus d'informations sont disponibles
+dans la section concernant la
+<link linkend="configuration">configuration</link>.
+</para>
+
+</sect2>
+
+</sect1>
+
+</chapter>
+
+&fundamentals-chapter;
+
+&details-chapter;
+
+&importing-exporting-chapter;
+
+&advanced-chapter;
+
+&configuration-chapter;
+
+&menus-chapter;
+
+&hacking-chapter;
+
+&faqs-chapter;
+
+<chapter id="credits">
+
+<!-- Include credits for the programmers, documentation writers, and
+contributors here. The license for your software should then be
+included below the credits with a reference to the appropriate license
+file included in the KDE distribution. -->
+
+<title>Crédits et Licence</title>
+
+<para>
+&appname;
+</para>
+<para>
+Program copyright 2001-2006 &robby; <email>&email;</email>
+</para>
+<para>
+</para>
+
+<para>
+Documentation copyright 2001-2006 &robby; <email>&email;</email>
+</para>
+
+<!-- TRANS:CREDIT_FOR_TRANSLATORS -->
+
+<para id="gnu-fdl" xreflabel="the section entitled &quot;GNU Free Documentation
+License&quot;">This documentation is licensed under the terms of the <ulink
+url="../en/common/fdl-license.html">&GNU; Free Documentation
+License (GFDL)</ulink>.</para>
+
+<para>The author of this documentation has also granted you permission to use the content under the terms of the <ulink
+url="freebsd-doc-license.html">FreeBSD Documentation License</ulink>, if you so choose. If you wish to allow use of your version of this content only under the terms of the FreeBSD Documentation License, and not to allow others to use your version of this file under the terms of the GFDL, indicate your decision by deleting the GFDL notice and and replacing it with the notice and other provisions required by the FreeBSD Documentation License. If you do not delete the GFDL notice above, a recipient may use your version of this file under the terms of either the GFDL or the FreeBSD Documentation License.</para>
+
+</chapter>
+
+<appendix id="installation">
+<title>Installation</title>
+
+<sect1 id="getting-tellico">
+<title>Comment obtenir &appname;</title>
+
+<para>
+La page web de &appname; se trouve à
+<ulink url="&homepage;">&homepage;</ulink>.
+Les mises à jour et les nouvelles informations s'y trouvent.</para>
+</sect1>
+
+<sect1 id="requirements">
+<title>Pré-requis</title>
+
+<!--
+List any special requirements for your application here. This should include:
+.Libraries or other software that is not included in kdesupport,
+kdelibs, or kdebase.
+.Hardware requirements like amount of RAM, disk space, graphics card
+capabilities, screen resolution, special expansion cards, etc.
+.Operating systems the app will run on. If your app is designed only for a
+specific OS, (you wrote a graphical LILO configurator for example) put this
+information here.
+-->
+
+<para>
+Pour pouvoir utiliser &appname;, vous avez besoin de KDE 3.2.x.
+&appname; nécessite environ 5 mega-octets de mémoire ; mais cela peut varier
+en fonction de vos platefome, configuration et essentiellement la taille de
+votre collection.
+</para>
+
+<para>
+&kde; peut être trouvé sur <ulink url="http://www.kde.org">le site web de
+KDE</ulink>.
+</para>
+
+<!-- For a list of updates, you may refer to the application web site
+or the ChangeLog file, or ... -->
+<para>
+Vous pouvez trouver une liste des dernières modifications sur <ulink
+url="&homepage;">&homepage;</ulink>.
+</para>
+</sect1>
+
+<sect1 id="compilation">
+<title>Compilation et installation</title>
+
+<para>
+Pour compiler et installer &appname; sur votre système, entrez les commandes
+suivantes à la racine de l'archive décompressée, la troisième devant être
+effectuée en tant que root si vous souhaitez installer dans un répertoire système :
+
+<screen width="40">
+<prompt>%</prompt> <userinput>./configure <option>--enable-final</option> <option>--disable-debug</option></userinput>
+<prompt>%</prompt> <userinput>make</userinput>
+<prompt>%</prompt> <userinput>make install</userinput>
+</screen>
+</para>
+
+<para>&appname; utilisant autoconf et automake, vous ne devriez pas avoir de
+problème pour le compiler. Cependant, si vous deviez rencontrer des problèmes,
+vous pouvez les rapporter à l'auteur à : <email>&email;</email>.</para>
+
+<sect2 id="compilation-ooo">
+<title>Compiller avec OpenOffice.org</title>
+<para>
+&appname; utilise greffon spécial pour communiquer avec OpenOffice.org, qui
+n'est pas compilé par défaut.
+Le kit de développement (SDK), disponible à <ulink url="http://www.openoffice.org/dev_docs/source/sdk/">
+http://www.openoffice.org/dev_docs/source/sdk/</ulink>, est nécessaire.
+
+<screen width="40">
+<prompt>%</prompt> <userinput>./configure <option>--enable-ooo</option> <option>--with-ooo-dir</option>=<filename class="directory">/usr/lib/openoffice</filename> <option>--with-ooo-sdk-dir</option>=<filename class="directory">/usr/lib/openoffice/SDK</filename></userinput>
+</screen>
+
+Vous devez utiliser le chemin correct des bibliothèques et du SDK
+OpenOffice.org, bien sûr.
+</para>
+
+<para>
+De plus, certaines distributions peuvent nécessiter que vous modifiiez le
+fichier <filename>/etc/ld.so.conf</filename> ou ajoutiez un fichier de
+configuration dans le répertoire
+<filename class="directory">/etc/ld.so.conf.d</filename>.
+Vérifiez si le greffon OpenOffice.org fonctionne sans changer la configuration
+d'abord. Si cela ne fonctionne pas, essayez d'ajouter le chemin le chemin
+d'OpenOffice.org (le même que celui que vous avez utilisé avec le script
+<filename>configure</filename>.
+Si vous avez besoin de plus d'aide, utilisez la <ulink url="&maillist;">liste de discussion de &appname;</ulink>
+</para>
+</sect2>
+
+</sect1>
+
+</appendix>
+
+&documentation.index;
+
+</book>
+<!--
+Local Variables:
+mode: sgml
+sgml-minimize-attributes:nil
+sgml-general-insert-case:lower
+sgml-indent-step:0
+sgml-indent-data:nil
+End:
+-->
diff --git a/doc/fr/loan-dialog.png b/doc/fr/loan-dialog.png
new file mode 100644
index 0000000..59636d2
--- /dev/null
+++ b/doc/fr/loan-dialog.png
Binary files differ
diff --git a/doc/fr/loan-view.png b/doc/fr/loan-view.png
new file mode 100644
index 0000000..b022949
--- /dev/null
+++ b/doc/fr/loan-view.png
Binary files differ
diff --git a/doc/fr/main-window.png b/doc/fr/main-window.png
new file mode 100644
index 0000000..949fc01
--- /dev/null
+++ b/doc/fr/main-window.png
Binary files differ
diff --git a/doc/fr/menus.docbook b/doc/fr/menus.docbook
new file mode 100644
index 0000000..a3e676b
--- /dev/null
+++ b/doc/fr/menus.docbook
@@ -0,0 +1,821 @@
+<chapter id="menus">
+<title>Références des commandes</title>
+
+<!--
+(OPTIONAL, BUT RECOMMENDED) This chapter should list all of the
+application windows and their menubar and toolbar commands for easy reference.
+Also include any keys that have a special function but have no equivalent in the
+menus or toolbars. This may not be necessary for small apps or apps with no tool
+or menu bars.
+-->
+
+<sect1 id="main-window-menus">
+<title>La fenêtre principale de &appname;</title>
+
+<para>
+Chaque commande du menu est documentée ci-dessous. Lorsqu'il existe un racourci
+clavier effectuant la même opération, le racourci par défaut est indiqué.
+</para>
+
+<sect2>
+<title>Le menu <guimenu>Fichier</guimenu></title>
+
+<para>
+<variablelist>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Fichier</guimenu>
+ <guimenuitem>Nouveau</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>crée une nouvelle collection</action>.
+&appname; reconnait <link linkend="collection-types">douze types de collections
+par défaut</link> ; ainsi qu'une collection personalisable vide.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>O</keycap></keycombo>
+ </shortcut>
+ <guimenu>Fichier</guimenu>
+ <guimenuitem>Ouvrir...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre un fichier &appname;</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Fichier</guimenu>
+ <guimenuitem>Ouvrir un fichier récent</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre un fichier</action> depuis un sous-menu
+contenant une liste des fichiers récement ouverts.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>S</keycap></keycombo>
+ </shortcut>
+ <guimenu>Fichier</guimenu>
+ <guimenuitem>Enregistrer...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>enregistre la collection</action>. Si le fichier
+est <emphasis>Sans titre</emphasis>, <guimenuitem>Enregistrer...</guimenuitem>
+est équivalent à <guimenuitem>Enregistrer sous</guimenuitem>. Cette commande
+est seulement disponible lorsque la collection a été modifiée.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Fichier</guimenu>
+ <guimenuitem>Enregistrer sous...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>enregistre collection dans un nouveau fichier</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>P</keycap></keycombo>
+ </shortcut>
+ <guimenu>Fichier</guimenu>
+ <guimenuitem>Imprimer...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>imprime la collection</action>. Les options
+d'impression peuvent être configurées dans la &config-dialog;.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Fichier</guimenu>
+ <guimenuitem>Importer</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>importe les données d'un autre fichier</action>.
+&appname; peut importer peut importer les données depuis
+<link linkend="importing">différents formats</link>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Fichier</guimenu>
+ <guimenuitem>Exporter</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>exporte la collection dans un autre format</action>. &appname; peut exporter les données dans
+<link linkend="exporting">différents formats</link>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>Q</keycap></keycombo>
+ </shortcut>
+ <guimenu>Fichier</guimenu>
+ <guimenuitem>Quitter</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ferme la fenêtre &appname;</action>. Si la
+collection a des changements non sauvegardés, il vous sera proposé de les
+enregistrer avant de continuer.</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+</sect2>
+
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EDIT MENU %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%-->
+<sect2>
+<title>Le menu <guimenu>Editer</guimenu></title>
+
+<para>
+
+<variablelist>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>Z</keycap></keycombo>
+ </shortcut>
+ <guimenu>Editer</guimenu>
+ <guimenuitem>Annuler</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>annule la dernière action</action>. Toutes les
+actions ne peuvent pas être annulées.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>Maj</keycap><keycap>Z</keycap></keycombo>
+ </shortcut>
+ <guimenu>Editer</guimenu>
+ <guimenuitem>Refaire</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>refait une opération précédement annulée</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>X</keycap></keycombo>
+ </shortcut>
+ <guimenu>Editer</guimenu>
+ <guimenuitem>Couper</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>efface le texte sélectioné</action>, et
+<action>copie celui-ci dans le presse-papier</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>C</keycap></keycombo>
+ </shortcut>
+ <guimenu>Editer</guimenu>
+ <guimenuitem>Copier</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>copie le texte sélectioné</action> dans le
+presse-papier.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>V</keycap></keycombo>
+ </shortcut>
+ <guimenu>Editer</guimenu>
+ <guimenuitem>Coller</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>colle le texte du presse-papier</action>, à la
+position où se trouve le curseur.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>A</keycap></keycombo>
+ </shortcut>
+ <guimenu>Editer</guimenu>
+ <guimenuitem>Selectioner tout</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>selectione toutes les entrées</action> de la
+collection dans la &detailed-view;.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>Maj</keycap><keycap>A</keycap></keycombo>
+ </shortcut>
+ <guimenu>Editer</guimenu>
+ <guimenuitem>Désélectioner</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ddésélectione toutes les entrées</action> de la
+collection.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Editer</guimenu>
+ <guimenuitem>Recherche Internet...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre la &fields-dialog;</action> pour chercher et
+importer des entrées depuis divers sites Internet, dont
+<ulink url="http://amazon.com">Amazon.com</ulink>.</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+</para>
+</sect2>
+
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% COLLECTION MENU %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%-->
+<sect2>
+<title>Le menu <guimenu>Collection</guimenu></title>
+<para>
+
+<variablelist>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>N</keycap></keycombo>
+ </shortcut>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Nouvelle entrée</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre l'&entry-editor; pour éditer une nouvelle
+entrée</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>E</keycap></keycombo>
+ </shortcut>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Editer l'entrée</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre l'&entry-editor; pour modifier les entrées sélectionées</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>Y</keycap></keycombo>
+ </shortcut>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Copier l'entrée</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>copie les entrées sélectionées</action> en tant
+que nouvelles entrées de la collection.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>D</keycap></keycombo>
+ </shortcut>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Effacer l'entrée</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>efface les entrées sélectionées</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Mettre à jour l'entrée</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Ce sous-menu contient la liste des sources de données disponibles, et peut
+être utilisé pour demander des informations et
+<action>mettre à jour les entrées sélectionées</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Prêter</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre une boîte de dialogue pour prêter les
+entrées sélectionées.</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Retour de prêt</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>marque comme rendues les entrées sélectionées qui
+on été prêtées</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>R</keycap></keycombo>
+ </shortcut>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Renommer la collection</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre une boîte de dialogue permettant de renommer
+la collection</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>U</keycap></keycombo>
+ </shortcut>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Champs de la collection...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre la &fields-dialog;</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>U</keycap></keycombo>
+ </shortcut>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Générer des rapports...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre la &report-dialog;</action> pour générer des
+rapports concernant la collection.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Convertir en bibliographie</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>convertit une collection de livres en
+bibliographie</action>, en ajoutant certains champs nécessaires à l'export au
+format BibTeX ; et est uniquement disponible pour les collection de
+livres.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Macros...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre une boîte de dialogue pour modifier les
+macros BibTeX </action> dans la collection. Elle est uniquement disponible pour
+les bibliographies.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Copier la citation BibTeX</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>copie une citation au format BibTeX</action> dans
+le presse-papier, afin qu"elle puisse être collée dans un document LaTeX.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Citer l'entrée dans Lyx</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>envoie une citation des entrées
+sélectionées</action> vers ce qu'on appelle un
+<emphasis><link linkend="hidden-bibtex-options">lyxpipe</link></emphasis>
+pour l'utiliser dans <application>LyX</application>,
+<application>Kile</application>, ou d'autres applications LaTeX. Cette commande
+est seulement disponible pour les bibliographies.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Collection</guimenu>
+ <guimenuitem>Citer l'entrée dans OpenOffice.org</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>envoie une citationn des entrées
+sélectionées</action> vers <application>OpenOffice.org Writer</application>.
+Cette commande est seulement disponible pour les bibliographies, lorsque le
+module OpenOffice.org est disponible.</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+</para>
+</sect2>
+
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SETTINGS MENU %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%-->
+<sect2>
+<title>Le menu <guimenu>Paramètres</guimenu></title>
+<para>
+
+<variablelist>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Paramètres</guimenu>
+ <guimenuitem>Barres d'outils</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>permet d'afficher ou masquer les différentes
+barres d'outils</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Paramètres</guimenu>
+ <guimenuitem>Afficher la barre d'état</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>permet d'afficher ou masquer la barre
+d'état</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Paramètres</guimenu>
+ <guimenuitem>Afficher la &group-view;</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>permet d'afficher ou masquer la
+&group-view;</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Paramètres</guimenu>
+ <guimenuitem>Afficher l' &entry-editor;</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>permet d'afficher ou masquer
+l'&entry-editor;</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Paramètres</guimenu>
+ <guimenuitem>Afficher la &entry-view;</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>permet d'afficher ou masquer la
+&entry-view;</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Paramètres</guimenu>
+ <guimenuitem>Sélection de groupe</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>permet de changer le champ utilisé pour grouper
+les entrées</action> de la collection.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>&Ctrl;</keycap><keycap>J</keycap></keycombo>
+ </shortcut>
+ <guimenu>Paramètres</guimenu>
+ <guimenuitem>Filtre avancé...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre la &filter-dialog;</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Paramètres</guimenu>
+ <guimenuitem>Configurer les racourcis...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre la &shortcut-dialog; &kde;</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Paramètres</guimenu>
+ <guimenuitem>Configurer les barres d'outils...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre la &toolbar-dialog; &kde;</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Paramètres</guimenu>
+ <guimenuitem>Configurer &appname;...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre la &config-dialog; &appname;</action>.</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+</para>
+</sect2>
+
+<sect2>
+<title>Le menu <guimenu>Aide</guimenu></title>
+<para>
+
+<variablelist>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Aide</guimenu>
+ <guimenuitem>Manuel &appname;</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre le manuel de &appname;</action>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <shortcut>
+ <keycombo><keycap>Maj</keycap><keycap>F1</keycap></keycombo>
+ </shortcut>
+ <guimenu>Aide</guimenu>
+ <guimenuitem>Qu'est-ce?</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>transforme le curseur de la souris en flèche avec
+un point d'intérogation</action>. Cliquer sur les différents éléments de la
+fenêtre affichera une bulle d'aide expliquant à quoi sert l'élément.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Aide</guimenu>
+ <guimenuitem>Astuce du jour</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre la boîte de dialogue de l'astuce du
+jour</action>. Vous pouvez ainsi parcourir toutes les astuces à l'aide des
+boutons de cette boîte de dialogue.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Aide</guimenu>
+ <guimenuitem>Rapporter un boggue...</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre la boîte de dialogue de rapport de
+boggue</action>. Si vous trouvez un boggue ou un problème, si vous avez une
+idée pour améliorer le logiciel ou corriger sa traduction, utilisez cette interface pour envoyer un message à son auteur.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Aide</guimenu>
+ <guimenuitem>A propos de &appname;</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre la boîte de dialogue à propos de
+&appname;</action>, affichant la version et les informations de l'auteur de
+l'application.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ <menuchoice>
+ <guimenu>Aide</guimenu>
+ <guimenuitem>A propos de &kde;</guimenuitem>
+ </menuchoice>
+</term>
+
+<listitem>
+<para>Cette commande <action>ouvre la boîte de dialogue à propos de
+&kde;</action>, affichant la version de &kde; et d'autres informations à
+propos de l'environement de bureau.</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+</para>
+</sect2>
+
+</sect1>
+</chapter>
diff --git a/doc/fr/openoffice-dialog.png b/doc/fr/openoffice-dialog.png
new file mode 100644
index 0000000..a2a2b40
--- /dev/null
+++ b/doc/fr/openoffice-dialog.png
Binary files differ
diff --git a/doc/fr/print-options.png b/doc/fr/print-options.png
new file mode 100644
index 0000000..f99fe33
--- /dev/null
+++ b/doc/fr/print-options.png
Binary files differ
diff --git a/doc/fr/report-dialog.png b/doc/fr/report-dialog.png
new file mode 100644
index 0000000..78364ac
--- /dev/null
+++ b/doc/fr/report-dialog.png
Binary files differ
diff --git a/doc/fr/source-options.png b/doc/fr/source-options.png
new file mode 100644
index 0000000..3d37dd5
--- /dev/null
+++ b/doc/fr/source-options.png
Binary files differ
diff --git a/doc/fr/sru-options.png b/doc/fr/sru-options.png
new file mode 100644
index 0000000..d699fa8
--- /dev/null
+++ b/doc/fr/sru-options.png
Binary files differ
diff --git a/doc/fr/template-options.png b/doc/fr/template-options.png
new file mode 100644
index 0000000..596e6c7
--- /dev/null
+++ b/doc/fr/template-options.png
Binary files differ
diff --git a/doc/fr/z3950-options.png b/doc/fr/z3950-options.png
new file mode 100644
index 0000000..89264e7
--- /dev/null
+++ b/doc/fr/z3950-options.png
Binary files differ
diff --git a/icons/Makefile.am b/icons/Makefile.am
new file mode 100644
index 0000000..2e751e5
--- /dev/null
+++ b/icons/Makefile.am
@@ -0,0 +1,81 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+
+EXTRA_DIST = \
+album.png hi16-app-tellico.png hi22-app-tellico.png \
+hi32-app-tellico.png hi48-app-tellico.png hi64-app-tellico.png \
+hi128-app-tellico.png \
+hi16-mime-application-x-tellico.png hi22-mime-application-x-tellico.png \
+hi32-mime-application-x-tellico.png hi48-mime-application-x-tellico.png \
+hi64-mime-application-x-tellico.png hi128-mime-application-x-tellico.png \
+bibtex.png person-open.png \
+tellico.png person.png \
+book.png stamp.png \
+card.png star_on.png \
+coin.png star_off.png \
+comic.png video.png \
+wine.png checkmark.png \
+tellico.svg tellico_mime.svg stars10.png \
+stars1.png stars2.png stars3.png \
+stars4.png stars5.png stars6.png \
+stars7.png stars8.png stars9.png \
+README.icons README.quesnay game.png \
+file.png nocover_book.png nocover_video.png \
+nocover_album.png nocover_game.png nocover_bibtex.png \
+nocover_comic.png script.svg script.png \
+boardgame.png nocover_boardgame.png
+
+####### kdevelop will overwrite this part!!! (end)############
+
+KDE_OPTIONS = noautodist
+
+KDE_ICON = tellico
+
+picdir = ${kde_datadir}/tellico/pics
+pic_DATA = \
+album.png \
+bibtex.png \
+tellico.png \
+tellico.svg \
+tellico.svg \
+tellico_mime.svg \
+boardgame.png \
+book.png \
+card.png \
+coin.png \
+comic.png \
+game.png \
+person-open.png \
+person.png \
+stamp.png \
+star_on.png \
+star_off.png \
+stars1.png \
+stars2.png \
+stars3.png \
+stars4.png \
+stars5.png \
+stars6.png \
+stars7.png \
+stars8.png \
+stars9.png \
+stars10.png \
+video.png \
+wine.png \
+checkmark.png \
+README.icons \
+README.quesnay \
+file.png \
+nocover_album.png \
+nocover_boardgame.png \
+nocover_book.png \
+nocover_bibtex.png \
+nocover_comic.png \
+nocover_game.png \
+nocover_video.png \
+script.svg \
+script.png
+
+# probably a better way to do this
+uninstall-hook:
+ -if [ -d $(picdir) ]; then rmdir $(picdir); fi
diff --git a/icons/README.icons b/icons/README.icons
new file mode 100644
index 0000000..a4b0bd5
--- /dev/null
+++ b/icons/README.icons
@@ -0,0 +1,18 @@
+Some license information:
+
+checkmark.png comes from
+http://jimmac.musichall.cz/ikony/i43/stock_ok-16.png so thanks to the
+Gnome Project, licensed as GPL.
+
+comic.png comes from
+http://jimmac.musichall.cz/ikony/i77/stock_draw-callouts-16.png thanks
+to the Gnome Project, licensed as GPL.
+
+The app and mime icons comes fromVirginie Quesnay, see README.Quesnay,
+licensed as LGPL.
+
+edit_add_user.png and edit_remove_user.png come from the ikons icon set, by
+Kristof Borrey, GPL licensed.
+
+nocover_bibtex.png is adapted from the text mimetype image from the
+Tango Project, licensed under the Creative Commons Attribution Share-Alike license
diff --git a/icons/README.quesnay b/icons/README.quesnay
new file mode 100644
index 0000000..8c4b268
--- /dev/null
+++ b/icons/README.quesnay
@@ -0,0 +1,62 @@
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+This copyright applies to all *tellico* images in this directory.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Note the license notice contains an add-on.
+************************************************************************
+
+TITLE: "NUVOLA ICONS" FOR TELLICO
+AUTHOR: Virginie Quesnay
+SITE: http://virginie.quesnay.free.fr
+
+Copyright (c) 2004 David Vignoni.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation,
+version 2.1 of the License.
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+You should have received a copy of the GNU Lesser General Public
+License along with this library (see the the license.txt file); if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifh Floor, Boston, MA 02110-1301 USA
+#######**** NOTE THIS ADD-ON ****#######
+The GNU Lesser General Public License or LGPL is written for software libraries
+in the first place. The LGPL has to be considered valid for this artwork
+library too.
+Nuvola icons for Tellico is a special kind of software library, it is an
+artwork library, it's elements can be used in a Graphical User Interface, or
+GUI.
+Source code, for this library means:
+ - png images.
+ - svg images.
+The LGPL in some sections obliges you to make the files carry
+notices. With images this is in some cases impossible or hardly usefull.
+With this library a notice is placed at a prominent place in the directory
+containing the elements. You may follow this practice.
+The exception in section 6 of the GNU Lesser General Public License covers
+the use of elements of this art library in a GUI.
+
+Date: 6 september 2004
+Version: 1.0
+
+DESCRIPTION:
+
+"NUVOLA ICONS" FOR TELLICO are a set of icon for Tellico, a collection manager for KDE (http://www.periapsis.org/tellico/).
+They are SVG based icons.
+This mean that all icons where designed with a vector graphics
+application and SVG files are available (in the "Scalable" directory).
+
+
+LICENSE:
+
+Released under GNU Lesser General Public License (LGPL)
+Look at the license.txt file.
+
+CONTACT
+
+Virignie Quesnay
+e-mail : virginie.quesnay [at] free.fr
+ICQ : 8120945
+http: http://virginie.quesnay.free.fr
diff --git a/icons/album.png b/icons/album.png
new file mode 100644
index 0000000..c05f2e4
--- /dev/null
+++ b/icons/album.png
Binary files differ
diff --git a/icons/bibtex.png b/icons/bibtex.png
new file mode 100644
index 0000000..6ec2c7c
--- /dev/null
+++ b/icons/bibtex.png
Binary files differ
diff --git a/icons/boardgame.png b/icons/boardgame.png
new file mode 100644
index 0000000..81e7b80
--- /dev/null
+++ b/icons/boardgame.png
Binary files differ
diff --git a/icons/book.png b/icons/book.png
new file mode 100644
index 0000000..aa1cea9
--- /dev/null
+++ b/icons/book.png
Binary files differ
diff --git a/icons/card.png b/icons/card.png
new file mode 100644
index 0000000..628bef5
--- /dev/null
+++ b/icons/card.png
Binary files differ
diff --git a/icons/checkmark.png b/icons/checkmark.png
new file mode 100644
index 0000000..276dc9f
--- /dev/null
+++ b/icons/checkmark.png
Binary files differ
diff --git a/icons/coin.png b/icons/coin.png
new file mode 100644
index 0000000..ddc8a61
--- /dev/null
+++ b/icons/coin.png
Binary files differ
diff --git a/icons/comic.png b/icons/comic.png
new file mode 100644
index 0000000..17695f6
--- /dev/null
+++ b/icons/comic.png
Binary files differ
diff --git a/icons/file.png b/icons/file.png
new file mode 100644
index 0000000..4f1116f
--- /dev/null
+++ b/icons/file.png
Binary files differ
diff --git a/icons/game.png b/icons/game.png
new file mode 100644
index 0000000..2af33f5
--- /dev/null
+++ b/icons/game.png
Binary files differ
diff --git a/icons/hi128-app-tellico.png b/icons/hi128-app-tellico.png
new file mode 100644
index 0000000..e188614
--- /dev/null
+++ b/icons/hi128-app-tellico.png
Binary files differ
diff --git a/icons/hi128-mime-application-x-tellico.png b/icons/hi128-mime-application-x-tellico.png
new file mode 100644
index 0000000..1de8dcc
--- /dev/null
+++ b/icons/hi128-mime-application-x-tellico.png
Binary files differ
diff --git a/icons/hi16-app-tellico.png b/icons/hi16-app-tellico.png
new file mode 100644
index 0000000..cb09537
--- /dev/null
+++ b/icons/hi16-app-tellico.png
Binary files differ
diff --git a/icons/hi16-mime-application-x-tellico.png b/icons/hi16-mime-application-x-tellico.png
new file mode 100644
index 0000000..affb758
--- /dev/null
+++ b/icons/hi16-mime-application-x-tellico.png
Binary files differ
diff --git a/icons/hi22-app-tellico.png b/icons/hi22-app-tellico.png
new file mode 100644
index 0000000..9b1af11
--- /dev/null
+++ b/icons/hi22-app-tellico.png
Binary files differ
diff --git a/icons/hi22-mime-application-x-tellico.png b/icons/hi22-mime-application-x-tellico.png
new file mode 100644
index 0000000..e61264f
--- /dev/null
+++ b/icons/hi22-mime-application-x-tellico.png
Binary files differ
diff --git a/icons/hi32-app-tellico.png b/icons/hi32-app-tellico.png
new file mode 100644
index 0000000..2c6b61e
--- /dev/null
+++ b/icons/hi32-app-tellico.png
Binary files differ
diff --git a/icons/hi32-mime-application-x-tellico.png b/icons/hi32-mime-application-x-tellico.png
new file mode 100644
index 0000000..41a80a9
--- /dev/null
+++ b/icons/hi32-mime-application-x-tellico.png
Binary files differ
diff --git a/icons/hi48-app-tellico.png b/icons/hi48-app-tellico.png
new file mode 100644
index 0000000..f01d328
--- /dev/null
+++ b/icons/hi48-app-tellico.png
Binary files differ
diff --git a/icons/hi48-mime-application-x-tellico.png b/icons/hi48-mime-application-x-tellico.png
new file mode 100644
index 0000000..5672458
--- /dev/null
+++ b/icons/hi48-mime-application-x-tellico.png
Binary files differ
diff --git a/icons/hi64-app-tellico.png b/icons/hi64-app-tellico.png
new file mode 100644
index 0000000..e2a132f
--- /dev/null
+++ b/icons/hi64-app-tellico.png
Binary files differ
diff --git a/icons/hi64-mime-application-x-tellico.png b/icons/hi64-mime-application-x-tellico.png
new file mode 100644
index 0000000..0bc4ce7
--- /dev/null
+++ b/icons/hi64-mime-application-x-tellico.png
Binary files differ
diff --git a/icons/nocover_album.png b/icons/nocover_album.png
new file mode 100644
index 0000000..2d1dc35
--- /dev/null
+++ b/icons/nocover_album.png
Binary files differ
diff --git a/icons/nocover_bibtex.png b/icons/nocover_bibtex.png
new file mode 100644
index 0000000..2f6b220
--- /dev/null
+++ b/icons/nocover_bibtex.png
Binary files differ
diff --git a/icons/nocover_boardgame.png b/icons/nocover_boardgame.png
new file mode 100644
index 0000000..2b8b7c7
--- /dev/null
+++ b/icons/nocover_boardgame.png
Binary files differ
diff --git a/icons/nocover_book.png b/icons/nocover_book.png
new file mode 100644
index 0000000..2b8b7c7
--- /dev/null
+++ b/icons/nocover_book.png
Binary files differ
diff --git a/icons/nocover_comic.png b/icons/nocover_comic.png
new file mode 100644
index 0000000..2b8b7c7
--- /dev/null
+++ b/icons/nocover_comic.png
Binary files differ
diff --git a/icons/nocover_game.png b/icons/nocover_game.png
new file mode 100644
index 0000000..457db33
--- /dev/null
+++ b/icons/nocover_game.png
Binary files differ
diff --git a/icons/nocover_video.png b/icons/nocover_video.png
new file mode 100644
index 0000000..2b8b7c7
--- /dev/null
+++ b/icons/nocover_video.png
Binary files differ
diff --git a/icons/person-open.png b/icons/person-open.png
new file mode 100644
index 0000000..5a68d7c
--- /dev/null
+++ b/icons/person-open.png
Binary files differ
diff --git a/icons/person.png b/icons/person.png
new file mode 100644
index 0000000..5a68d7c
--- /dev/null
+++ b/icons/person.png
Binary files differ
diff --git a/icons/script.png b/icons/script.png
new file mode 100644
index 0000000..abbc624
--- /dev/null
+++ b/icons/script.png
Binary files differ
diff --git a/icons/script.svg b/icons/script.svg
new file mode 100644
index 0000000..1c8d982
--- /dev/null
+++ b/icons/script.svg
@@ -0,0 +1,1499 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/"
+ xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/"
+ xmlns:xap="http://ns.adobe.com/xap/1.0/"
+ xmlns:pdf="http://ns.adobe.com/pdf/1.3/"
+ xmlns:x="adobe:ns:meta/"
+ xmlns:ns="http://ns.adobe.com/SaveForWeb/1.0/"
+ xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48pt"
+ height="48pt"
+ viewBox="0 0 256 256"
+ overflow="visible"
+ enable-background="new 0 0 256 256"
+ xml:space="preserve"
+ id="svg548"
+ sodipodi:version="0.32"
+ sodipodi:docname="tellico_pencil.svg"
+ sodipodi:docbase="/home/robby/projects/tellico/icons"
+ inkscape:version="0.42">
+ <defs
+ id="defs654"><linearGradient
+ gradientTransform="matrix(-4.388724,0.000000,0.000000,4.148002,-53.30885,-874.2942)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5576"
+ inkscape:collect="always"
+ x1="100.76616"
+ x2="125.25793"
+ xlink:href="#linearGradient1724"
+ y1="77.379333"
+ y2="77.379333" /><linearGradient
+ id="linearGradient1724"><stop
+ id="stop1725"
+ offset="0.0000000"
+ style="stop-color:#ff41a0;stop-opacity:1.0000000;" /><stop
+ id="stop1726"
+ offset="1.0000000"
+ style="stop-color:#fd4bae;stop-opacity:1.0000000;" /></linearGradient><linearGradient
+ gradientTransform="matrix(-4.387166,0.000000,0.000000,4.149479,-53.30885,-874.2942)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5575"
+ inkscape:collect="always"
+ x1="104.09006"
+ x2="123.82494"
+ xlink:href="#linearGradient1724"
+ y1="83.359146"
+ y2="70.956947" /><linearGradient
+ id="linearGradient1716"><stop
+ id="stop1717"
+ offset="0.0000000"
+ style="stop-color:#ff74ba;stop-opacity:1.0000000;" /><stop
+ id="stop1718"
+ offset="1.0000000"
+ style="stop-color:#ff91ce;stop-opacity:1.0000000;" /></linearGradient><linearGradient
+ gradientTransform="matrix(-4.104683,0.000000,0.000000,4.435042,-53.30887,-874.2942)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5577"
+ inkscape:collect="always"
+ x1="97.281265"
+ x2="127.84677"
+ xlink:href="#linearGradient1716"
+ y1="84.255211"
+ y2="61.142742" /><linearGradient
+ id="linearGradient4873"><stop
+ id="stop4874"
+ offset="0.0000000"
+ style="stop-color:#d88721;stop-opacity:1.0000000;" /><stop
+ id="stop4876"
+ offset="0.50000000"
+ style="stop-color:#a85c00;stop-opacity:1.0000000;" /><stop
+ id="stop4875"
+ offset="1.0000000"
+ style="stop-color:#643e0e;stop-opacity:1.0000000;" /></linearGradient><linearGradient
+ gradientTransform="matrix(-4.095463,0.000000,0.000000,4.445031,-156.4589,-729.8842)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5526"
+ inkscape:collect="always"
+ x1="168.25160"
+ x2="185.96996"
+ xlink:href="#linearGradient4873"
+ y1="181.01073"
+ y2="172.51707" /><linearGradient
+ id="linearGradient1741"><stop
+ id="stop1742"
+ offset="0.0000000"
+ style="stop-color:#868686;stop-opacity:1.0000000;" /><stop
+ id="stop1743"
+ offset="1.0000000"
+ style="stop-color:#e2e2e2;stop-opacity:1.0000000;" /></linearGradient><linearGradient
+ gradientTransform="matrix(-5.149470,0.000000,0.000000,3.535207,-53.30885,-878.6374)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5527"
+ inkscape:collect="always"
+ spreadMethod="reflect"
+ x1="97.345161"
+ x2="99.206970"
+ xlink:href="#linearGradient1741"
+ y1="112.84396"
+ y2="115.81121" /><linearGradient
+ id="linearGradient2152">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#2f9eff;stop-opacity:1.0000000;"
+ id="stop2154" />
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#2077e0;stop-opacity:1.0000000;"
+ id="stop2156" />
+
+ </linearGradient>
+<linearGradient
+ id="linearGradient2144">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#60baff;stop-opacity:1.0000000;"
+ id="stop2146" />
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#1674cd;stop-opacity:1.0000000;"
+ id="stop2148" />
+
+ </linearGradient>
+
+ <linearGradient
+ id="linearGradient3029">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#a1ffa2;stop-opacity:1.0000000;"
+ id="stop3030" />
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#4ed64e;stop-opacity:1.0000000;"
+ id="stop3031" />
+
+ </linearGradient>
+
+ <linearGradient
+ id="linearGradient2400">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#ccffcc;stop-opacity:1.0000000;"
+ id="stop2403" />
+
+ <stop
+ offset="0.41010001"
+ style="stop-color:#99ff66;stop-opacity:1.0000000;"
+ id="stop2402" />
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#66cc33;stop-opacity:1.0000000;"
+ id="stop2401" />
+
+ </linearGradient>
+
+ <linearGradient
+ id="linearGradient2099">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#ff999b;stop-opacity:1.0000000;"
+ id="stop2100" />
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#ff4e4e;stop-opacity:1.0000000;"
+ id="stop2101" />
+
+ </linearGradient>
+
+ <linearGradient
+ id="linearGradient2094">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#ff9999;stop-opacity:1.0000000;"
+ id="stop2096" />
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#ff6666;stop-opacity:1.0000000;"
+ id="stop2095" />
+
+ </linearGradient>
+
+ <linearGradient
+ id="XMLID_1_"
+ gradientUnits="userSpaceOnUse"
+ x1="128.9995"
+ y1="11"
+ x2="128.9995"
+ y2="245.0005">
+ <stop
+ offset="0"
+ style="stop-color:#494949"
+ id="stop555" />
+
+
+
+ <stop
+ offset="1"
+ style="stop-color:#000000"
+ id="stop556" />
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#494949"
+ id="midPointStop557" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#494949"
+ id="midPointStop558" />
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#000000"
+ id="midPointStop559" />
+
+
+
+ </linearGradient>
+
+ <linearGradient
+ id="XMLID_2_"
+ gradientUnits="userSpaceOnUse"
+ x1="29.0532"
+ y1="29.0532"
+ x2="226.9471"
+ y2="226.9471">
+ <stop
+ offset="0"
+ style="stop-color:#FFFFFF"
+ id="stop563" />
+
+
+
+ <stop
+ offset="1"
+ style="stop-color:#DADADA"
+ id="stop564" />
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FFFFFF"
+ id="midPointStop565" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FFFFFF"
+ id="midPointStop566" />
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#DADADA"
+ id="midPointStop567" />
+
+
+
+ </linearGradient>
+
+ <linearGradient
+ id="XMLID_3_"
+ gradientUnits="userSpaceOnUse"
+ x1="139.8662"
+ y1="75.7139"
+ x2="202.4969"
+ y2="138.3446">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#1a2993;stop-opacity:1.0000000;"
+ id="stop575" />
+
+
+
+ <stop
+ offset="0.47189999"
+ style="stop-color:#003044;stop-opacity:1.0000000;"
+ id="stop576" />
+
+
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#003344;stop-opacity:1.0000000;"
+ id="stop577" />
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#E14E30"
+ id="midPointStop578" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#E14E30"
+ id="midPointStop579" />
+
+
+
+ <a:midPointStop
+ offset="0.4719"
+ style="stop-color:#FF5B00"
+ id="midPointStop580" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF5B00"
+ id="midPointStop581" />
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#C51700"
+ id="midPointStop582" />
+
+
+
+ </linearGradient>
+
+ <linearGradient
+ id="XMLID_4_"
+ gradientUnits="userSpaceOnUse"
+ x1="50.0991"
+ y1="75.9434"
+ x2="112.7299"
+ y2="138.5741">
+ <stop
+ offset="0"
+ style="stop-color:#990000"
+ id="stop600" />
+
+
+
+ <stop
+ offset="0.4551"
+ style="stop-color:#7C0000"
+ id="stop601" />
+
+
+
+ <stop
+ offset="1"
+ style="stop-color:#600000"
+ id="stop602" />
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#990000"
+ id="midPointStop603" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#990000"
+ id="midPointStop604" />
+
+
+
+ <a:midPointStop
+ offset="0.4551"
+ style="stop-color:#7C0000"
+ id="midPointStop605" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#7C0000"
+ id="midPointStop606" />
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#600000"
+ id="midPointStop607" />
+
+
+
+ </linearGradient>
+
+ <linearGradient
+ id="XMLID_5_"
+ gradientUnits="userSpaceOnUse"
+ x1="94.5244"
+ y1="116.9331"
+ x2="157.1558"
+ y2="179.5645">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#009933;stop-opacity:1.0000000;"
+ id="stop625" />
+
+
+
+ <stop
+ offset="0.4551"
+ style="stop-color:#006A00"
+ id="stop626" />
+
+
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#003333;stop-opacity:1.0000000;"
+ id="stop627" />
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#009933"
+ id="midPointStop628" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#009933"
+ id="midPointStop629" />
+
+
+
+ <a:midPointStop
+ offset="0.4551"
+ style="stop-color:#006A00"
+ id="midPointStop630" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#006A00"
+ id="midPointStop631" />
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#003333"
+ id="midPointStop632" />
+
+
+
+ </linearGradient>
+
+
+
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_5_"
+ id="linearGradient2397"
+ x1="50.099098"
+ y1="75.943398"
+ x2="112.72990"
+ y2="138.57410"
+ gradientUnits="userSpaceOnUse" />
+
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2400"
+ id="linearGradient2404"
+ x1="-2.6281061e-16"
+ y1="0.50000000"
+ x2="1.0000000"
+ y2="0.50000000" />
+
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3029"
+ id="linearGradient3032"
+ x1="0.56435645"
+ y1="0.54666668"
+ x2="0.72277230"
+ y2="0.22000000"
+ spreadMethod="reflect" />
+
+<linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2400"
+ id="linearGradient2046"
+ x1="50.019157"
+ y1="90.537178"
+ x2="93.079155"
+ y2="88.270393"
+ gradientUnits="userSpaceOnUse" />
+<linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2144"
+ id="linearGradient2150"
+ x1="50.019157"
+ y1="90.537178"
+ x2="93.079155"
+ y2="88.270393"
+ gradientUnits="userSpaceOnUse" />
+<linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_3_"
+ id="linearGradient2151"
+ x1="50.099098"
+ y1="75.943398"
+ x2="112.72990"
+ y2="138.57410"
+ gradientUnits="userSpaceOnUse" />
+<linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2152"
+ id="linearGradient2158"
+ x1="0.36138615"
+ y1="0.44000000"
+ x2="0.26732674"
+ y2="0.65333331"
+ spreadMethod="reflect" />
+<linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1724"
+ id="linearGradient1614"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-4.387166,0.000000,0.000000,4.149479,-53.30885,-874.2942)"
+ x1="104.09006"
+ y1="83.359146"
+ x2="123.82494"
+ y2="70.956947" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1724"
+ id="linearGradient1616"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-4.388724,0.000000,0.000000,4.148002,-53.30885,-874.2942)"
+ x1="100.76616"
+ y1="77.379333"
+ x2="125.25793"
+ y2="77.379333" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1716"
+ id="linearGradient1618"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-4.104683,0.000000,0.000000,4.435042,-53.30887,-874.2942)"
+ x1="97.281265"
+ y1="84.255211"
+ x2="127.84677"
+ y2="61.142742" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4873"
+ id="linearGradient1620"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-4.095463,0.000000,0.000000,4.445031,-156.4589,-729.8842)"
+ x1="168.25160"
+ y1="181.01073"
+ x2="185.96996"
+ y2="172.51707" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1741"
+ id="linearGradient1622"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-5.149470,0.000000,0.000000,3.535207,-53.30885,-878.6374)"
+ spreadMethod="reflect"
+ x1="97.345161"
+ y1="112.84396"
+ x2="99.206970"
+ y2="115.81121" /></defs>
+ <sodipodi:namedview
+ id="base"
+ inkscape:zoom="2.0000000"
+ inkscape:cx="34.142135"
+ inkscape:cy="22.808912"
+ inkscape:window-width="1184"
+ inkscape:window-height="882"
+ inkscape:window-x="61"
+ inkscape:window-y="95"
+ inkscape:current-layer="g2493" />
+ <metadata
+ id="metadata549">
+ <ns:sfw
+ id="sfw9">
+ <ns:slices
+ id="slices11">
+ <ns:slice
+ x="0"
+ y="0"
+ width="256"
+ height="256"
+ sliceID="124417176"
+ id="slice13" />
+
+
+
+ </ns:slices>
+
+
+
+ <ns:sliceSourceBounds
+ x="0"
+ y="0"
+ width="256"
+ height="256"
+ bottomLeftOrigin="true"
+ id="sliceSourceBounds16" />
+
+
+
+ <ns:optimizationSettings
+ id="optimizationSettings18">
+ <ns:targetSettings
+ fileFormat="PNG24Format"
+ targetSettingsID="0"
+ id="targetSettings20">
+ <ns:PNG24Format
+ transparency="true"
+ includeCaption="false"
+ interlaced="false"
+ noMatteColor="false"
+ matteColor="#FFFFFF"
+ filtered="false"
+ id="PNG24Format22" />
+
+
+
+ </ns:targetSettings>
+
+
+
+ </ns:optimizationSettings>
+
+
+
+ </ns:sfw>
+
+
+
+ <xpacket
+ id="xpacket27">begin='' id='W5M0MpCehiHzreSzNTczkc9d' </xpacket>
+
+
+
+ <x:xmpmeta
+ x:xmptk="XMP toolkit 3.0-29, framework 1.6"
+ id="xmpmeta30">
+
+ <metadata
+ id="metadata334">
+ <rdf:RDF>
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f">
+ <pdf:Producer>
+Adobe PDF library 5.00</pdf:Producer>
+
+
+
+ </rdf:Description>
+
+
+
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f" />
+
+
+
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f" />
+
+
+
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f">
+ <xap:CreateDate>
+2004-01-26T11:58:28+02:00</xap:CreateDate>
+
+
+
+ <xap:ModifyDate>
+2004-03-28T20:44:56Z</xap:ModifyDate>
+
+
+
+ <xap:CreatorTool>
+Adobe Illustrator 10.0</xap:CreatorTool>
+
+
+
+ <xap:MetadataDate>
+2004-02-16T23:42:57+01:00</xap:MetadataDate>
+
+
+
+ <xap:Thumbnails>
+ <rdf:Alt>
+ <rdf:li
+ rdf:parseType="Resource">
+ <xapGImg:format>
+JPEG</xapGImg:format>
+
+
+
+ <xapGImg:width>
+256</xapGImg:width>
+
+
+
+ <xapGImg:height>
+256</xapGImg:height>
+
+
+
+ <xapGImg:image>
+/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
+AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
+DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
+Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER
+AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
+AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
+UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
+1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
+qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
+obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
+0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
++DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7
+FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqlvmDzFo
+3l7TJdT1e5W1tItuTbszHoiKN2Y+AxV4j5g/5ydvTcMnl/SYlgU0Se/LOzDxMcTIF/4M4qk//QzP
+nv8A5YNL/wCRVx/2UYq7/oZnz3/ywaX/AMirj/soxV3/AEMz57/5YNL/AORVx/2UYq7/AKGZ89/8
+sGl/8irj/soxV3/QzPnv/lg0v/kVcf8AZRirv+hmfPf/ACwaX/yKuP8AsoxV3/QzPnv/AJYNL/5F
+XH/ZRirv+hmfPf8AywaX/wAirj/soxV3/QzPnv8A5YNL/wCRVx/2UYq7/oZnz3/ywaX/AMirj/so
+xV3/AEMz57/5YNL/AORVx/2UYq7/AKGZ89/8sGl/8irj/soxV3/QzPnv/lg0v/kVcf8AZRirv+hm
+fPf/ACwaX/yKuP8AsoxV3/QzPnv/AJYNL/5FXH/ZRirv+hmfPf8AywaX/wAirj/soxV3/QzPnv8A
+5YNL/wCRVx/2UYq7/oZnz3/ywaX/AMirj/soxV3/AEMz57/5YNL/AORVx/2UYq7/AKGZ89/8sGl/
+8irj/soxV3/QzPnv/lg0v/kVcf8AZRirv+hmfPf/ACwaX/yKuP8AsoxVFad/zk75oS4B1HSbG4t+
+6W/qwP8A8E7zj/hcVeyeRfzJ8tec7Vn0yUx3kQBuLCaizJ25AAkMlf2l+mmKsqxV2KuxV2KuxV2K
+vm/XDqf5ufmk+j287Q+XtJLqJF3VIY2CSzAHYvM9AvtTwOKvePLfk/y35bs0tdHsYrZVFGlCgyuf
+GSQ/Ex+ZxVOK4q6oxVrkMVdyGKu5jFWvUGKu9RffFWvVX3xV3rL74q71l8DirXrp4HFXfWE8DirX
+1hPA4q76yngcVd9Zj8D+GKtfWo/A/hirvrcfgfw/rirvrcfgfw/rirX1yLwb8P64q765F4N+H9cV
+d9di8G/D+uKtfXovBvw/riqVa/5X8r+abR7TV7GO55CiyMoWZP8AKjkHxKR7HFXzB5n0XXfys8/R
+NZXBJgIudOujsJYGJUpIB8ijj+oxV9VeWtfs/MGhWWsWf9xexLKErUoxHxI3up2OKplirsVdirsV
+Q+oMy2Fyy/aWJyvzCnFXhP8AziwqvL5nmYcpQLIBz1oxuC2/uVGKvficVaxVrFWicVaJxVrFWsVa
+JxVonFWsVaxVrFWicVaxVrFWicVaJxVrFWsVaJxVonFWsVaxVdCSJkp/MP14q8V/5ypRBJ5ZkCjm
+wvVZu5CmAgfRyOKsn/5x3vJX8lwWzElQZmSvbjMR/wAbYq9XxV2KuxV2KofUv+Oddf8AGGT/AIic
+VeE/84pn/lKP+jD/ALGcVe+nFWsVaJxVonFWsVaxVonFWicVaxVrFWsVaJxVrFWsVaJxVonFWsVa
+xVonFWicVaxVrFWicVXQ/wB9H/rD9eKvFv8AnKw/8ov/ANH/AP2LYqn/APzjn/yisHyuP+T4xV6/
+irsVdirsVQ+pf8c66/4wyf8AETirwf8A5xRNf8U/9GH/AGM4q9+PXFWicVaJxVrFWsVaJxVonFWs
+VaxVrFWicVaxVrFWicVaJxVrFWsVaJxVonFWsVaxVonFWicVXQ/30f8ArD9eKvFf+crjT/C3/R//
+ANi2Ksg/5xy/5RS3+Vx/yfGKvYMVdirsVdiqH1L/AI511/xhk/4icVeDf84nmv8Ain/ow/7GcVe/
+HrirROKtYq1irROKtE4q1irWKtYq0TirWKtYq0TirROKtYq1irROKtE4q1irWKtE4q0TirWKroP7
++P8A1h+vFXiv/OWBp/hb/o//AOxbFWQf844f8onb/K4/5PjFXsOKuxV2KuxVD6l/xzrr/jDJ/wAR
+OKvBP+cTD/ylX/Rh/wBjOKvf2O5xVrFWsVaJxVazAAkmgG5JxV4p+ZX/ADkRY6bK+ieTEXVtZc+k
+bxQZII3O1Igv9+/hT4fn0zEy6oDaO5eh7P7ClP15fTHu6n9X3sL0n8/fzM8tanFF5zgF9Z3FGDGK
+KKRV2r6bQBI2pUVU7jKseqkD6t3P1fYOKcf3Xpl8aPz3e/8AlLzv5d816et7pF0sykfHFWjoe4Ze
+uZ0ZCQsPKZsE8UuGYop6TkmprFWsVaJxVonFWsVaxVonFWJebvzD0vQg9tBS71MbCBT8MZ/4tYdP
+9Xr8swNVr44thvL8c3c9ndjZNR6j6cff3+79bB/8b/mFasNRuqm0kNTC0aBVFdtgOa+ALZocfbkj
+kI4hIjmPx+O96GXY2jnHgjtLvs/2FnXlfz7pmtIscjC3vOhRjQE+1c6PTayGYek79zyuu7My6Y+o
+enoejJycynXtE4q1irWKroD+/j/1l/XirxT/AJyzP/KK/wDR/wD9i2Ksh/5xv/5RK3+Vx/yfxV7F
+irsVdirsVQ+pf8c66/4wyf8AETirwL/nEo/8pV/0Yf8AYzir6AbqcVaxVonFUl81+cPLvlXTG1HX
+LxLW3FRGp3klcCvCNB8TN8vp2yE5iIsuRptLkzS4YCy+cfNX5lee/wA0bmXStCibSfLAJWck0LqP
++WiVepP++k+mtK5r8ueU9hsHsdD2Vi03ql6sn3e79aZ+WfJOj+XYq26+vesoEt7IPjO24QbhFPgP
+pJplDtLJ5o/UtPstQtXtb2FZ7eT7UbjbwqCNwRXYjcYGyred3XlrzP5N1D9N+UbqVo4yC8A3lC9w
+yjaVfl8Q+jlk8eQxNhxdVpIZY8MxY7+57F+WH/OQmjeYRFpuvFdP1c0VXJ/dSn/JPY+2bHFnEve8
+dr+yZ4Nx6od/d73sCurqHUhlYVDA1BGXupcTirROKtYq1iqheXtpZ2z3N3MkFvGKvK5CqPvyMpiI
+s7BnjxSnIRiLJeY6/wDmHq2uXDaV5XjeOI1El39mRl6VBP8Adr7nf5Zz3aHbEYRNHhj3/q/FvW6L
+sXHgHiag2e7p+0/Yo6N5StdNpPcEXN9sfUP2Ebr8APev7R/DPP8AXdszy+mHpj9p/U5mbWHJsNop
+lMKgg9Dsc1cJEGw1xYxqXl1RL9Z05vQnBJ9IbKT/AJJ/Z+XT5Zv9H2rIEcRo/wA52OPUCUeDIOKJ
+/HxTnyz+Y15YuLDWlZkWi822dfv/AI522h7bjKo5f9N0+Lou0fZ3bxNPvH+b+r9XN6TZ31reQLPb
+SCWNu47HwI7HOhBBFh5SUSDR5q2FDROKr4P7+P8A1l/XirxL/nLU/wDKK/8AR/8A9i2Ksi/5xt/5
+RG2+Vz/yfxV7HirsVdirsVQ+pf8AHOuv+MMn/ETirwH/AJxINf8AFf8A27/+xnFX0C32j88VWk4q
+8o/ND8/NB8qerpmj8NW8wCqGJTWCB+n751+0wP7CmviVzGzakR2G5d32d2LPPUp+nH9p9363kln5
+N81ectUPmHz5dTEsR6Vix4OUG/DiKCCP/JA5deh3OCbkbk9VjGPDHgxCh+Pm9AtrK0srWO1tIlgt
+4RxjiQUUD6PxwMgskyJbYoaTAW2KHfrkW0MT81fl/putcrq2IstTNW9ZR8EjHf8AeqO9f2hv41yQ
+k1Tw3yd5L/OTzj5Cvk0XzTFJeaWNo5GPJwn88cn+7F/Ed99szMWoI2O4eZ1/Y0ZXLH6Zd3T9n3Pp
+Hyz5t0HzLpyX+j3SXELipCn4lPgw6jM4SBFh5jJilCXDIUU3wtbWKsd81+eNH8vRFZm9e+IrHZxk
+czXoXP7C+5+iuYuo1cMQ33Pc7LQdl5dSdtofzv1d7z0WfmfztcLfarKbTSlNYYlBCkf8VIeu37bf
+j0ziO2PaCMDRPFP+aOnv/FvUx8DRR4cY4p9T+v8AUyuy0qx021FtZxCOMfaP7TH+Zj3OcLqdZkzy
+4pn9QcCeaWSVyK2XK4tkUFLl0W+KCly6LkRQV7p9tex8Jl3H2JBsy/I/wzLw6mWP3dzfiyygbCX2
+V9rnlmcSwSGS0ruR9kjwZe3+dDnS9m9tTxfT6ofzT+NvuXV9n4NcL+jL3/jn970fy3510zWkVOQh
+u9uUTHqT4V/V+vO30mux6iNwO/d1DxGu7NzaWVTG3Q9CyEnMxwF8H9/H/rr+vFXiX/OW5p/hT/t4
+f9i2Ksj/AOca/wDlD7b5XP8AyfxV7HirsVdirsVQ+pf8c66/4wyf8ROKvn//AJxGNf8AFf8A27/+
+xnFXvWp6hZ6dZXN/eyrBZ2qPNcTP9lUQVZj9AwE0LLOEDOQjEWS+b/OP5y+b/P17J5e8iwS2OlMe
+Fzfn4JnjPVpJBtBGadAeTdO/HNfk1BntHk9houxseAceb1T7un7fu+9FeTfyy0jy6Eu7il9q9Km5
+cfBGTufRU9P9Y/F8q0yoRpz8mcz9zKpMSiKGkyJbYoeTIluihpMBbYoZ+uRbQtwJQup6Xp+p2jWl
+/AtxA2/FhuD05KRup36jCDTGcBLmwF9G84eQb8615Vu5JrJPjmi6sqr/AL9jFA6gftrQjfYDMjHl
+I5Op1ugjkFTF+fc94/Kf86LDzpbG3uoTaarBxWZRujFq0YH3pmwxZBIPG63RSwSo7g8iq+afzHvZ
+71tD8rxNNdljE92BU8hswiHTbu7bfrzVa7tSOMGjQHORd12f2LER8XOajzr9f6v7FLy7+XccMn6R
+15/ruoSHmYWPONWJrVyf7xvw+fXPNO1PaSWQmOHYfzup93d7+fucrVdqEjgxemH4+TLJRnMg3zdd
+FBS5dFvigpcui5EUHLl0XIigpcui5EVLJs2iAQQRUEUIO4IPY4YyINhUi1Dy/NHJ9a0pzFMu/o1o
+D/qk/qO36s22j7RMZA3wy7/x/Y5g1EckeDKOKJT7yh+ZVyLhdL1mNvUX4RIdnBHYg7/fnfdmdq+M
+eCf1d/e8t2z2GMEfFxG8f3X94en2ciSSQyIao7KVPsSM3bzTxP8A5y5NP8Kf9vD/ALFsVZJ/zjV/
+yh1t8rn/AKiMVeyYq7FXYq7FUPqX/HOuv+MMn/ETir59/wCcQz/yln/bv/7GcVeofnOf+QY+ZP8A
+mEb/AIkMqz/QXYdlf4zD3vl78v8AznqOgW4SMCaxd2Mts1BU/wAysBUNmglnMJeT63h7Kx6nBZ2n
+vv8ArezaJ5k0rXLb1rKWrqP3sDbSIf8AKX+I2zMx5YzGzzmr0GXTyqY9x6FGSZItEUNJkS2xQ0mA
+tsUNJkS3RQ75FtCzAlSubq3tYGnuJFihTdnY0GJLKMSTQYD5i8+XFzyttLLQW/RrjpI/+r/KPx+W
+UyydzsMOkA3kiP8AnHkk+YdRJ68Y/wBb5uNL1fOu3/4feXovk69ubPVNQlgbi3IVHUEcm2Oed+0U
+RMRB5WXo9XhjPHESelabrtteqI3/AHVx/Ieh/wBU/wAM4jNpTDcbh5zPo5Y9xvFES5VFqig5cui5
+EUFLl0XIigpcvi3xQcuXRciKjk2xokAVOwHU4qld9rIWsdtuehk7fRmVj0/WTm4dL1kxa2kZ/NkR
+YlmLCpO5/u863sEfvYfH7i1duitDOv6P+6D6C0A/6LZf7H/iWdy+avHP+cvD/wAon/28P+xbFWS/
+840f8oba/K5/6iMVey4q7FXYq7FUPqX/ABzrr/jDJ/xE4q+fP+cQT/yln/bv/wCxnFXqH5z/APks
+fMv/ADCN/wASGVZ/oLsOyv8AGYe98faP/vEP9Y5zOo+p9u7I/uPiU0s7y6s7hLm1laGeM1WRDQjK
+oyINh2GXFHJHhkLBekeW/wAx7e8C2ur8be56LcjaJz/lfyH8Plmfi1QO0nk9f2FLH6sXqj3dR+v7
+2XOQRUGoPQjMl0YQ8mAtsUNJkS2xQz5FuCR6/wCadO0dCrn1rsiqW6nf5sf2RkJSAcjFglP3PN9Z
+17UdWn9S6k+AH93AuyJ8h4++UykS7TFhjAbJeiO7BUBZj0AyIDXqtXi0+M5MshCEeZLJ/wAun1ry
+xPdX1nAt1MyB7hODukcaVNWKEU+1uembCOp4OT4F217VfmMlYI3CN7m9/h0HvZn5N8zWkt9cpdFb
+eWehjqfhJqSRU9Oucj27pZmIlHcC3tey/ajT66EY/RlH8J/R3s7B7j6DnKu8Taw16VAIrqskfQSf
+tD5+OYmXTA7x2Lg5tGDvHYpoZY5UDxsGQ9CMxeEg0XD4SDRQsuWxbooKXLouRFBS5dFyIoO5u4bd
+OUjU8FHU/LL4YzLk348ZkdkivdRmuSV+xF2QfxzOx4hH3uyxYBD3oTLW9KbRv+dwiH+UP+TWdJ2E
+P3sP877i6vt7/EZ/5v8Aug+h9A/3lsv9j/xLO2fNXjn/ADl8f+UT/wC3h/2LYqyX/nGf/lDLX5XP
+/URir2bFXYq7FXYqh9S/4511/wAYZP8AiJxV89f84fmv+Lf+3f8A9jWKvUfzo/8AJY+Zf+YVv+JD
+Ks/0Fz+y/wDGYe98f6N/vEP9Y5zWo+p9u7H/ALj4lHZQ7V2Ksi8u+dNR0njBJW5sf98sfiQf8Vt2
++XTL8Wcx26Oq13ZWPP6h6Z9/f73ounaxp+qW/r2cocftodnU+DL2zOjMSFh5XPpcmGXDMUuuJY4o
+2klcJGgq7sQAAO5JwljEW898y/mByLW2jnbo94R/ybB/Wf7colk7na4NH1l8mDu7yOzyMXdjVmY1
+JJ7knKXYAUrWtjNcGo+GPu56fR45KMbeW9ova3S9mRqR483SA5/5380fb3AvQ/J/5a3l+iXNwrWe
+nNQ+qw/ezA7/ALsHt/lHbwrlebURx7Dcvh/avbGr7UyceolUB9MR9I9w/wB8d3pdrpdhpdqtrYwi
+GJdzT7TN/MzHdj881OTLKZsuJGIiKDDvM/kmyvma6sCLO9rUgbROfcD7J91+6prmVh1dbS3DCWLf
+ijtJItI85avoNyNO1qJzEvTluyitKqw2ZduozD1vZEMo48ex+x6zsf2qnirHqd4/zuvx7/e9E07U
+7HUbdbi0lWWNvA7j5jOWzYZY5VIUX0LDnhliJQNxKPt7qa3asbbHqp6HMeUBLmmeMS5pnFexXAoP
+hfup/hmNLEYuJLEY+5TmyUWcWP6nrUURMdvSSTu37I/rmww6YneTs9PpCd5bBIJZZJXLyMWY9zme
+AAKDs4xAFBZhZOxVJLVv+d2iH+UP+TOdN2EPXD/O/S6vt7/EZ/5v+6D6M0D/AHlsv9j/AMSztHzV
+41/zmAaf4S/7eH/YrirJv+cZf+ULtPlc/wDURir2fFXYq7FXYqh9S/4511/xhk/4icVfPH/OHpr/
+AIt/7d3/AGNYq9S/Oj/yWPmX/mFb/iQyrP8AQXP7L/xiHvfH+i/7wj/WOc1qPqfbuxv7j4lH5Q7V
+2KuxVXsr67sbhbi0laGVejL3HgR0I9jhjIg2GrLhhkjwyFh3mHzTq+rv6dzIEgSgEEdVQkftEdz8
+8yjkMhu6SOkhikRFJlUsQqipOwAyKcuWOOJlMiMRuSdgE80TyxfahdxW8MD3FzKaR20Yqfmx7Ad+
+w75aIVuXyP2j/wCCHKZODQe45P8AiB/vj8B1e1+UvypsdMRLvWlS7vQKpajeCLwqCPjb5/D89jmH
+qdSaqL5sNOSTPIeOZ53v/aWXXI65qm5KrkdcVSq5HXFUm1PSrDU7c297EJE34N0ZCf2kbsdv65bj
+yygdkEA82C3uleYvKVyb/TJWuNPBq5ArxHWkqDt/lDbxpWmZOSGLUxqQ3c3s/tHPo5XjPp6jp+PN
+mflbz/pesqsMrC2vabxsaBj/AJJzmdb2Vkw7jeL6R2X25h1YoemfcWVA03Gat3SW67qN38FuHpGy
+1amxO/c5k6bFHnW7l6PBH6q3SPM12LsVdirsVY/at/zvkQ/yh/yYzqOwh6of536XV9vf4jP/ADf9
+0H0hoH+8tl/sf+JZ2T5q8Z/5zCNP8Jf9vH/sVxVlH/OMf/KFWnyuf+ojFXs+KuxV2KuxVD6l/wAc
+66/4wyf8ROKvnf8A5w6P/KXf9u7/ALGsVep/nOrN+WXmYKCx+qOSBvsGBJ+gZVm+gud2Yf8ACIe9
+8e6HLGbT0ww5qxJXvQ5zepieK32vsTLE4uG/UCdkxzHdy7FXYq7FULHZzXNw6xjYH4mPQZk44kh4
+v2j9otL2ZEzzH1G+GI+qXu/STs9D8hflZquvOssKfV9PH97qUq7GhoViX9s9em3icyoYnwntj2g1
+vbM/WfD0/SA5fH+cfPkOlPddA8paJ5cszb6bDR2/vrl6NNIR/M1Bt7Db2yvM4WPBHGKiiZ81OZjN
+LLkdcw2pKrkdcVSq5HXFUAeuKuBINR1wqw3zJ+X1tc8r3RiLO9X4hAvwxOwNfhp/dt8vh6dNzmdh
+1Y+me4TEmJsGiEH5f/MTVNGuv0T5jicemQvqMKOvgT2K+BG2Ymu7DjkHHh59z2fZPtMRUM/+m/X+
+tmupXdvdmGe3cPGyVBHzOc/hxmFg830jQzEoWEFlznOxV2KtO6RoXdgqKKszGgA9ycQCdgrGNInW
++8+RTWtZIuVeQB6CLhX5cs63sXGYyiDz3/S6vt81opg/0f8AdB9L6BX6tZf7D9eda+avGf8AnMU/
+8oj/ANvH/sVxVlH/ADjF/wAoTafK6/6iMVe0Yq7FXYq7FUPqX/HOuv8AjDJ/xE4q+df+cOD/AMpf
+/wBu7/saxV9CXUMM6SwzossMoZJInAZWVtmVlOxBHUYpBINh88/mb/zjY6vJrHkQ8HFXl0Z2p8/q
+0jH/AIRj8j0GYWbSg8vk9N2d29KJAyGiOUh+l4nHqVxbXUljqsL2t3CxjlWRSjK67FXU0KnNPl0p
+HJ9I7P7djMAZD/ndD+PkmQIIqNwehzDeiBt2KXYqmnlfib6BXUOrXiBkYAqRyXYg9RmXGRGMkdz8
+5f8ABSF9rY/+FR/6aTfS/lzzbp9xFFZTollKihIlUBYSAKAJ2X5YdN2hGe0tpfY81izA7ck9nyzM
+yml8+anM400tuR1zCakpuR1xVKrkdcVS9upxVrFULqGp2lhF6lw9CfsIN2b5DLsWCWQ0GrLljAWX
+mnn3WJdStI3dFRI5QIRQFlDK1fjpXegr2ze6TAMewaNNqDkme5lXlsk6ba1P+6E/jnJa4fvJf1i+
+8ez/APi8f6o+5Nsw3fOxVBalq1np8fKZqufsRL9o/wBnvl2HBLIdkiNpPYaX5j84XIWJTBYcqBqH
+h1psP22zpOz+yr5fN1/aHa2HSDf1T/m/r7g9k8m/lrpWhwBmj5TNu7Nu7f6zD9QzqcGmhiFReA1/
+aWXVSuZ26DoGdWoC3EIAoA6gAfMZe694b/zmOf8AlEP+3j/2K4qyn/nGD/lB7P5XX/UTir2nFXYq
+7FXYqh9S/wCOddf8YZP+InFXzn/zhsa/4v8A+3d/2NYq+iJP7xvmcVWE4qwf8xvyk8q+ebUm9i+q
+asq0t9VgUeqtOiyDYSJ/kt9BGVZMQk52j1+TAdt49z5d85eRPOX5eXwg1SD6xpcjEW1/FVoJPYNT
+92/+Q34jfNXqNJ3/ADe97H9oqFRNx6xPT3fikHaXtvdJyhapH2lOzD5jNVkxmJ3e80mtx543A/Dq
+FfIOWmPlg01K2H/L5H/xJcyT/dH3H7n50/4KA/12h/wqP+7m9ZzRvGJ/o3my7swsFzWe1Gwr9tB7
+E9R7HMvFqpRFHcNkchGxZTHeW15CJreQSIe46g+BHbJZJAiwmRtCXPfMJqSm574qlVz3xVLm6nFW
+P6x5pgtuUNnSacbM/wCwv9Tmw0+iMt5bBws+sEdo7liVxcT3EplncySN1Y5tYxERQ5OslIyNlJPM
+5ppif8Zl/wCIPl+Eer4Od2d9Z9zO/LP/ABzLX/mHj/jnFa/+8l/WL797P/4vH+qPuTckAVOwHU5h
+O+SDVPMtH+q6avr3DHiHUchX/JA+0c2Gm0BkfV8mVAC5Ggnvk/8AKvUNVuBfayS1TyMTGo/56N/x
+qP1Z1+j7KEQDP5freS7U9pecNP8A6b9X6/7Xs+k6HYaXAsVtGAVHEMABQdKAdhm6AAFB46UjI2TZ
+KYYWKpa/70xf66/rxV4X/wA5kmn+EP8At4/9iuKsq/5xf/5Qaz+V1/1E4q9qxV2KuxV2KofUv+Od
+df8AGGT/AIicVfOX/OGhr/jD/t3f9jWKvoiT+8b5n9eKrCcVaxVDahp9jqNnLZX9vHdWc6lJreZQ
+6Mp7FTtgItlGZibBovnL8zP+cb77Tnl1ryKzzwrV5NHY1mQdT6DH+8X/ACG+L3bMPNpQRtyel7O7
+dlCQ4jwy/nD9P4p5HaazSVrW/Q291GxRw4K/EDQhgd1PzzTZtKRvF9J7O7ehkqOX0y7+h/V9zI/L
+TD9K2o/5fI/+JLkD/dH3H7nxj/gn/wDGrD/hUf8AdzeuZpHinYqr2l7c2kvqW7lG7jsR4Ed8INKy
+Oz12C8UJJSK4/l/ZP+qf4Yqtue+BUi1a/tLKEzXMgjToK9SfADucsx45TNBhPIIiy8+1nzNc3xaK
+GsNqdiv7TD/KP8M3Gn0kYbneTq8+qM9hsElzLcR2KpP5qNNMT/jMv/EHzI0w9Xwdj2b9Z9zMtC1G
+zttFtZpZRw+roAAakkVqAPHOM1mGUs0gB/EX3/2fifAH9UfcsiGueZ7g21jGYrQGjtuF/wBm3c+w
+zYaDssyOws9/QOz1uvw6WNzO/QdT+O96v5J/K2w0pFuLpedwQOTsPjPy/lH451um0cMQ23l3vAdp
+dsZdUaPph/NH6e96DHHHEgjjUIi9FGwzLdS3irWKqlr/AL1Q/wCuv68VeF/85lmn+D/+3j/2K4qy
+r/nF3/lBbP5XX/UTir2vFXYq7FXYqh9S/wCOddf8YZP+InFXzh/zhia/4w/7dv8A2NYq+iZT+8b5
+n9eKrMVaxVonFWicVee/mX+S3lbzxG1zIv6O1wLSLU4VBLU6CdPhEo+kMOxplWTEJe9ztJr54duc
+e54Zc/l9f+Q/M+m6Pe3kd7LcSQXaywhlUK8vphSG3r+6zTa+HCCP6P63mPabVDPq4Sr+AD/ZSei5
+zLrHYq7FXYqu1HzFdafpU0xUTtGB6fM03Zgu/jSuXYMYnMRLVmycESXm2oale6hcG4u5DJIeg7KP
+BR2Gb7HjjAUHSzyGRsobJsHYq7FUl82mmlp/xnX/AIg+ZWkHr+H6nZdmfWfc9H/L38n/ANKWFvey
+X4Ns8ccpt+JQ/EK05gt+rBPswSnxSOz67pfaKWLTiEI+rhAv9j23QfLGm6PbpHBEoZBtQAAfIfxz
+ZQgIigKDosuaeSRlM3IpuTkmtrFWsVaxVUtT/pUP+uv6xirwr/nM40/wf/28v+xXFWV/84uf8oJZ
+fK6/6icVe2Yq7FXYq7FUPqX/ABzrr/jDJ/xE4q+b/wDnC81/xj/27f8AsaxV9Ey/3j/M/rxVZirR
+OKtE4q1irWKvA/zvdV/M7QyxAUW1qSTsAPrcuaXtTr/V/W832t/fx/qj7yjs5Vx3Yq7FXYqlfmf/
+AI4dz/sP+Ti5laP+9Hx+5xtX/dn8dWB5vXTOxV2KuxVIvOEiDTY4yw5tMrBa7kBWBNPpzN0MSZn3
+O07LieInpT6T/KIEeWbSop/o0P8AxHNiXt8f0j3M7JwM2sVaxVrFWicVVLX/AHqh/wBdf1jFXhX/
+ADmgaf4O/wC3l/2K4qyz/nFr/lA7L5XX/UScVe2Yq7FXYq7FUPqX/HOuv+MMn/ETir5t/wCcLTX/
+ABj/ANu3/saxV9FS/wB6/wDrH9eKrCcVaJxVrFWsVaJxVhn5iflppPnK2RpJDaapbqVtbxRyHEmv
+CRduS1+kfrx9RpxkHm4Ws0Ucw7pDq8Ru5vN3kK+XTPMNs09gdre4Q8lZR3hkNOVB+w1CPbOc1egI
+PcfsLoMmGeI1IMq03VLDUrYXFlMs0R2JHVT4MDuD881M4GJooBRWQS7FUr8z/wDHDuf9h/ycXMrR
+/wB6Pj9zjav+7P46sDzeumdirsVSTUvMSrILTTk+tXbnipUclDE0AUD7bfLb9WZuDSGW8tg7XS9n
+GW8/kzf8v/yO1PWLlNU8zcuJIf6oT93qn/jQZshURUXqNPohEC/k+iNK0q10y1FvbigAAJ6dOgA8
+Mi7FGYq1irWKtE4q1iqpa/71Q/66/rGKvCf+c0jT/B3/AG8v+xXFWW/84sf8oFY/K6/6iTir23FX
+Yq7FXYqh9S/4511/xhk/4icVfNf/ADhWf+Uy/wC3b/2N4q+i5T+9f/WP68VWE4q1irWKtE4q0Tir
+WKoLVtI0zV7GSw1O2ju7SUUeGQVHzHcEdiNxkZQEhRYThGQoiw8H85fk75j8qXL635NllvLJamay
++1PGvUjiNpk+jkPA9c1Wp7PBG24dLqOzzDeG4QHlnz7p+qlbW7pZ6iaL6bGiSN0+AnvX9k/jnP6j
+RShuN4uAynMJUr8z/wDHDuf9h/ycXMrR/wB6Pj9zjav+7P46sDzeumUbu8t7SEzTuEQdK9SfADuc
+nCBkaDbiwyyGohK9PsvMnnG8Njo8DR2YNJpmqFAP+/GH/ER+ObPDphDc7l6HQ9m0b5nve9/lz+S+
+keXo0urpfXvyPjncfHv1CD9hfxzIJehxYIw9706OOOJBHGoVF2CjYYG9vFWsVaxVonFWsVaxVUtP
+964f+Mi/rGKvCP8AnNQ/8ob/ANvL/sUxVl3/ADiv/wAoDY/K6/6ijir27FXYq7FXYqh9S/4511/x
+hk/4icVfNP8AzhQa/wCMv+3b/wBjeKvoyY/vX/1j+vFVmKtYq0TirROKtYq1irROKtE4q84/Mb8l
+tA81iS+s+Oma4RX6yg/dTN/xcg7/AOWu/jXplOTCJb9XD1Gijk3G0njv6c82+R9RGjebrSV4P903
+P2iU/mjk6Sr9NR+GaTV9lCW8fTL7C6bLglA0WS6vqNjqPlma6splnt34cXX/AIyLsR1B8Qd81Onx
+ShmEZCjv9zgasfuz+OrzbVdft7ImGIevdbjgPsqf8oj9Q/DOiw6cz35BxNNoZT3ltFkXkj8n/MHm
+m6TUNe5wWhoVt/syMvv/AL7X8TmzhAQFB6nS9niI3FDufRXlvylo+g2cdvZQJGIxRQq0A+Q8fc75
+J2sYgCgnROKWsVaxVrFWicVaxVrFWsVVLQ/6XD/xkX9YxV4P/wA5rmn+Df8At5f9imKsv/5xV/8A
+Jf2Pyu/+oo4q9vxV2KuxV2KofUv+Oddf8YZP+InFXzR/zhMa/wCM/wDt2/8AY3ir6Nm/vX/1j+vF
+VPFWicVaJxVrFWsVaJxVonFWsVaxVLPMHlzRPMOnPp2sWiXdq/7Lj4lb+ZGFGRvdTgIthPGJCi8G
+8x/849ecNOvZ08pX4n0m7oHhml9GVQCCBJQcHp2Yb+3jVLBEkEi6dZl7PJO2482T/l1+Q9norpe6
+xxuNQXfmaFUPhGu//BHLnNwaWMNzuXrtvbw28QihQIg7D+OLkrycVaxVrFWsVaJxVrFWsVaxVonF
+VW0/3rg/4yL/AMSGKvBv+c2TT/Bn/by/7FMVZf8A84qf+S+sPld/9RRxV7hirsVdirsVQ+pf8c66
+/wCMMn/ETir5m/5wkP8Aymf/AG7P+xvFX0dN/fP/AKx/XiqmTirROKtYq1irROKtE4q1irWKtE4q
+1irWKtYq0TirWKtYq1irROKtYq1irWKtE4q1iqrZ/wC9cH/GRf8AiQxV4L/zm2f+UM/7ef8A2KYq
+zD/nFL/yXth8rv8A6ijir3HFXYq7FXYqh9S/4511/wAYZP8AiJxV8y/84RH/AJTT/t2f9jeKvo6c
+/vn/ANY/rxVTJxVrFWsVaJxVonFWsVaxVonFWsVaxVrFWicVaxVrFWsVaJxVrFWsVaxVonFWsVax
+VVs/97IP+Mi/8SGKvBf+c3T/AMoX/wBvP/sUxVmP/OKH/kvLD5Xf/UUcVe44q7FXYq7FUPqX/HOu
+v+MMn/ETir5j/wCcHzX/ABp/27P+xvFX0fOf30n+sf14qp4q1irROKtE4q1irWKtE4q1irWKtYq0
+TirWKtYq1irROKtYq1irWKtE4q1irWKtYqq2Z/0yD/jIn/EhirwT/nOA0/wX/wBvP/sUxVmX/OJ/
+/ku9P+V3/wBRRxV7lirsVdirsVQ+pf8AHOuv+MMn/ETir5g/5wgkVJ/Olu54zkacwjOzUQ3Qbb2L
+CuKvpG4qJpK/zH9eKqeKtE4q0TirWKtYq0TirWKtYq1irROKtYq1irWKtE4q1irWKtYq0TirWKtY
+q1irROKq1iCbyAAVPNT9xrirwD/nOGaMy+TIgwMiLqTsncKxtQp+nicVZt/zieGH5dafUEHjdnfw
+N0SMVe5Yq7FXYq7FVskayRtG32XBVvkRTFXxjrN7rf5Efnjca1FbNP5e1ZpDLAtFWW2mcPLGldg8
+MlGT2p2JxV9U+U/PHknzvp8d/wCX9UhvA61eFHC3EZ7rLCfjQj3Hy2xVPP0dF/M34Yq79GxfzN+G
+KtfoyL+dvwxV36Mi/nb8MVd+i4f52/DFWv0VD/O34Yq79FQ/zt+H9MVa/RMP87fhirv0TD/O34Yq
+79EQfzt+H9MVa/Q8H87fh/TFXfoeD+dvw/pirv0NB/O34f0xVr9Cwfzt+H9MVd+hYP8Afj/h/TFW
+v0Jb/wC/H/D+mKu/Qdv/AL8f8P6Yq1+g7f8A34/4f0xV36Ct/wDfj/h/TFXfoK3/AN+P+H9MVa/Q
+Nv8A78f8P6Yq79AW3+/H/D+mKpN5n84eRPIlhLqGvanDacVJSKRw1xJ4LFCvxuT7D57Yq+IvzF87
+a9+cH5kLcWtu0ccvG00myJr6NshLcpCNqmrO5+joBir7H/J7y5HoWhW1jAP3NpbpEGIoWJp8R924
+VPzxV6FirsVdirsVdirE/wAxvy38v+etDk0zVYlL0rBPSrI46Ed/uxV8j+b/APnFvzbpN66WEyyw
+En0zMGK8faSMNX6UGKsd/wChfPP3ja/8FP8A9UsVd/0L55+8bX/gp/8Aqlirv+hfPP3ja/8ABT/9
+UsVd/wBC+efvG1/4Kf8A6pYq7/oXzz942v8AwU//AFSxV3/Qvnn7xtf+Cn/6pYq7/oXzz942v/BT
+/wDVLFXf9C+efvG1/wCCn/6pYq7/AKF88/eNr/wU/wD1SxV3/Qvnn7xtf+Cn/wCqWKu/6F88/eNr
+/wAFP/1SxV3/AEL55+8bX/gp/wDqlirv+hfPP3ja/wDBT/8AVLFXf9C+efvG1/4Kf/qlirv+hfPP
+3ja/8FP/ANUsVd/0L55+8bX/AIKf/qlirv8AoXzz942v/BT/APVLFXf9C+efvG1/4Kf/AKpYq7/o
+Xzz942v/AAU//VLFXf8AQvnn7xtf+Cn/AOqWKu/6F88/eNr/AMFP/wBUsVd/0L55+8bX/gp/+qWK
+ovTP+cc/OVxcBLueCCLu8Ylkb/gWWP8AXir3r8rPyT0zy4P9FhM97IB691LQuR1oxAoif5I698Ve
+76bYR2NqsKbnq7eLHviqKxV2KuxV2KuxV2KrZIo5VKSIHQ9VYAj8cVQp0bSyf95k+7FXfobS/wDl
+mT8cVd+htL/5Zk/HFXfobS/+WZPxxV36G0v/AJZk/HFXfobS/wDlmT8cVd+htL/5Zk/HFXfobS/+
+WZPxxV36G0v/AJZk/HFXfobS/wDlmT8cVd+htL/5Zk/HFXfobS/+WZPxxV36G0v/AJZk/HFXfobS
+/wDlmT8cVd+htL/5Zk/HFXfobS/+WZPxxV36G0v/AJZk/HFXfobS/wDlmT8cVd+htL/5Zk/HFXfo
+bS/+WZPxxV36G0v/AJZk/HFXfobS/wDlmT8cVcNG0sH/AHmT7sVRUcUcShI0CIOiqAB+GKrsVdir
+sVf/2Q==</xapGImg:image>
+
+
+
+ </rdf:li>
+
+
+
+ </rdf:Alt>
+
+
+
+ </xap:Thumbnails>
+
+
+
+ </rdf:Description>
+
+
+
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f">
+ <xapMM:DocumentID>
+uuid:ef18cd8d-b4e0-42e1-badd-bdf8b8440881</xapMM:DocumentID>
+
+
+
+ </rdf:Description>
+
+
+
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f">
+ <dc:format>
+image/svg+xml</dc:format>
+
+
+
+ <dc:title>
+ <rdf:Alt>
+ <rdf:li
+ xml:lang="x-default">
+mime.ai</rdf:li>
+
+
+
+ </rdf:Alt>
+
+
+
+ </dc:title>
+
+
+
+ </rdf:Description>
+
+
+
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+
+
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+
+
+</cc:Work>
+
+
+</rdf:RDF>
+
+
+</metadata>
+
+
+</x:xmpmeta>
+
+
+
+ <xpacket
+ id="xpacket103">end='w' </xpacket>
+
+
+
+ </metadata>
+ <g
+ id="g2493"
+ inkscape:export-xdpi="192.00000"
+ inkscape:export-ydpi="192.00000"
+ inkscape:export-filename="/home/vqu/Desktop/icon tellico/bookcase.png">
+ <path
+ opacity="0.2"
+ d="M44,15.5c-9.374,0-17,7.626-17,17v200c0,9.374,7.626,17,17,17h176c9.375,0,17-7.626,17-17v-200 c0-9.374-7.625-17-17-17H44z"
+ id="path551"
+ style="opacity:0.20000000;" />
+ <path
+ opacity="0.2"
+ d="M42,13.5c-9.374,0-17,7.626-17,17v200c0,9.374,7.626,17,17,17h176c9.375,0,17-7.626,17-17v-200 c0-9.374-7.625-17-17-17H42z"
+ id="path552"
+ style="opacity:0.20000000;" />
+ <path
+ opacity="0.2"
+ d="M40,12.5c-9.374,0-17,7.626-17,17v200c0,9.374,7.626,17,17,17h176c9.375,0,17-7.626,17-17v-200 c0-9.374-7.625-17-17-17H40z"
+ id="path553"
+ style="opacity:0.20000000;" />
+ <path
+ fill="url(#XMLID_1_)"
+ d="M41,11c-9.374,0-17,7.626-17,17v200c0,9.374,7.626,17,17,17h176c9.375,0,17-7.626,17-17V28 c0-9.374-7.625-17-17-17H41z"
+ id="path560"
+ style="fill:url(#XMLID_1_);" />
+ <path
+ d="M28,228c0,6.627,5.373,12,12,12h176c6.627,0,12-5.373,12-12V28c0-6.627-5.373-12-12-12H40 c-6.627,0-12,5.373-12,12V228z"
+ id="path561"
+ style="fill:#ffffff;"
+ fill="#FFFFFF" />
+ <path
+ fill="url(#XMLID_2_)"
+ d="M40,21c-3.86,0-7,3.14-7,7v200c0,3.859,3.14,7,7,7h176c3.859,0,7-3.141,7-7V28c0-3.86-3.141-7-7-7 H40z"
+ id="path568"
+ style="fill:url(#XMLID_2_);" />
+ <rect
+ id="_x3C_Slice_x3E_"
+ fill="none"
+ width="256"
+ height="256"
+ style="fill:none;" />
+ <g
+ id="g2047"
+ transform="matrix(1.730570,0.000000,0.000000,1.844339,-382.2522,-461.2119)">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<path
+ opacity="0.2"
+ d="M 299.78022,316.80616 L 261.13022,329.80676 C 260.02222,330.17975 259.32022,330.77819 259.32022,331.43081 L 259.32022,349.22517 C 259.32022,349.88359 259.99322,350.50089 261.11922,350.87147 L 299.80922,363.64953 C 301.22122,364.11589 303.08222,364.11202 304.48722,363.63937 L 340.06286,352.02185 C 341.16986,351.64886 341.83086,351.03784 341.83086,350.38475 C 341.83086,347.78595 342.45373,345.65430 341.51942,345.23555 C 341.57133,344.19568 339.59890,345.02442 339.33937,344.14027 C 339.18365,344.08661 338.87222,337.33708 339.65081,337.43914 C 339.65081,336.44942 341.98658,337.48403 341.83086,336.65003 C 342.55754,336.23128 341.88277,332.54246 341.83086,330.41081 C 341.83086,329.75094 340.37727,328.97841 339.25027,328.60686 L 304.45322,316.79503 C 303.04222,316.33012 301.18222,316.33399 299.78022,316.80616 z "
+ id="path2191"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+
+<path
+ opacity="0.2"
+ d="M 297.71922,316.47332 L 259.06822,329.47392 C 257.96022,329.84691 257.25922,330.44535 257.25922,331.09797 L 257.25922,348.89136 C 257.25922,349.55076 257.93222,350.16758 259.05722,350.53863 L 297.28007,363.00428 C 298.69207,363.47162 300.55407,363.46726 301.95807,362.99460 L 339.24561,350.28754 C 340.35361,349.91455 341.01561,349.30304 341.01561,348.64995 C 341.01561,346.79089 341.48277,345.71041 340.70417,345.09709 C 340.91179,344.22424 338.78365,344.28571 338.67984,343.72429 C 338.36841,343.52144 338.05697,335.68842 338.83556,335.64129 C 338.93937,334.86748 340.91180,335.33941 341.01561,334.72132 C 341.48276,333.95228 341.01561,331.62607 341.01561,330.07844 C 341.01561,329.41857 339.09386,328.49032 337.96686,328.11878 L 302.39222,316.46268 C 300.98022,315.99777 299.12122,316.00164 297.71922,316.47332 z "
+ id="path2194"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+
+<path
+ fill="url(#XMLID_4_)"
+ d="M 295.41091,315.22758 L 258.16137,327.76103 C 257.05337,328.13402 256.35237,328.73246 256.35237,329.38508 C 254.32804,335.21239 252.92658,339.94969 256.35237,348.26849 C 256.35237,348.92789 257.02537,349.54471 258.15137,349.91576 L 295.43991,362.06998 C 296.85191,362.53732 298.71291,362.53296 300.11691,362.06030 L 336.93830,349.82040 C 338.04530,349.44741 338.70630,348.83590 338.70630,348.18281 C 338.70630,346.80388 339.17345,344.33493 338.70630,344.04602 C 338.75820,343.30465 337.09722,343.65329 337.14912,342.60048 C 336.83768,342.58579 336.52625,334.00663 337.14912,333.36907 C 337.35674,332.82063 338.49868,333.20651 338.70630,332.65807 C 339.38108,332.05773 338.65439,330.21164 338.70630,328.98843 C 338.70630,328.32856 338.03130,327.71174 336.90430,327.34020 L 300.08291,315.21694 C 298.67191,314.75203 296.81291,314.75590 295.41091,315.22758 z "
+ id="path2205"
+ style="fill:url(#linearGradient2397);"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+
+<g
+ id="g2207"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,216.3650,286.7469)">
+ <polygon
+ id="polygon2209"
+ fill="#FFFFFF"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:#ffffff;" />
+
+
+
+ </g>
+
+<g
+ id="g2212"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,216.3650,286.7469)"
+ style="fill:url(#linearGradient2404);">
+ <linearGradient
+ id="linearGradient2214"
+ gradientUnits="userSpaceOnUse"
+ x1="152.20509"
+ y1="1062.5635"
+ x2="264.34052"
+ y2="1056.6604"
+ gradientTransform="matrix(0.384000,0.000000,0.000000,0.384000,-8.427600,-317.4872)"
+ spreadMethod="pad"
+ xlink:href="#linearGradient2094"
+ style="fill:url(#linearGradient2404);">
+
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FF9999;fill:url(#linearGradient2404);"
+ id="midPointStop2218" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF9999;fill:url(#linearGradient2404);"
+ id="midPointStop2220" />
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FF6666;fill:url(#linearGradient2404);"
+ id="midPointStop2222" />
+
+
+
+ </linearGradient>
+
+
+
+ <polygon
+ id="polygon2225"
+ fill="url(#path266_7_)"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:url(#linearGradient2046);" />
+
+
+
+ </g>
+
+
+ <path
+ style="fill:#009933;fill-opacity:1.0000000;"
+ d="M 297.76400,360.42407 L 336.45400,347.40509 L 336.45400,345.80372 L 332.40534,344.20236 L 331.47103,332.90231 L 336.45400,331.25676 L 336.45400,329.61122 L 297.76400,342.63019 C 295.34160,348.34127 294.68095,353.61190 297.76400,360.42407 z "
+ id="path2231"
+ sodipodi:nodetypes="ccccccccc" />
+
+
+
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;"
+ d="M 297.45257,359.02261 L 334.89682,346.62650 L 335.05254,331.79126 L 297.45257,344.34309 C 295.03017,350.05416 294.36951,352.21044 297.45257,359.02261 z "
+ id="path2233"
+ sodipodi:nodetypes="ccccc" />
+
+<g
+ id="g2235"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,216.3650,286.7469)">
+ <path
+ style="fill:url(#linearGradient3032);fill-opacity:1.0000000;fill-rule:nonzero;"
+ d="M 81.399000,152.29500 L 42.708000,125.88200 C 38.815056,110.40322 40.527951,99.430733 42.708000,89.102000 L 81.404000,115.51400 C 79.200152,125.95352 77.436740,136.84824 81.399000,152.29500 z "
+ id="path2237"
+ sodipodi:nodetypes="ccccc" />
+
+
+
+ </g>
+
+<path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#003333;stroke-width:1.0000000pt;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1.0000000;"
+ d="M 259.24295,330.42313 L 297.62542,343.35150 C 294.24874,350.39848 295.08292,353.62160 297.87235,359.78771"
+ id="path2249"
+ sodipodi:nodetypes="ccc" />
+
+
+</g>
+ <g
+ id="g2159"
+ transform="matrix(1.730570,0.000000,0.000000,1.844339,-245.8950,-436.2256)">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <path
+ opacity="0.2"
+ d="M 310.68046,263.55069 L 272.03046,276.55129 C 270.92246,276.92428 270.22046,277.52272 270.22046,278.17534 L 270.22046,295.96970 C 270.22046,296.62812 270.89346,297.24542 272.01946,297.61600 L 310.70946,310.39406 C 312.12146,310.86042 313.98246,310.85655 315.38746,310.38390 L 350.96310,298.76638 C 352.07010,298.39339 352.73110,297.78237 352.73110,297.12928 C 352.73110,294.53048 353.35397,292.39883 352.41966,291.98008 C 352.47157,290.94021 350.49914,291.76895 350.23961,290.88480 C 350.08389,290.83114 349.77246,284.08161 350.55105,284.18367 C 350.55105,283.19395 352.88682,284.22856 352.73110,283.39456 C 353.45778,282.97581 352.78301,279.28699 352.73110,277.15534 C 352.73110,276.49547 351.27751,275.72294 350.15051,275.35139 L 315.35346,263.53956 C 313.94246,263.07465 312.08246,263.07852 310.68046,263.55069 z "
+ id="path2265"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ transform="translate(-99.03649,19.15329)" />
+
+
+
+
+
+ <path
+ opacity="0.2"
+ d="M 308.61946,263.21785 L 269.96846,276.21845 C 268.86046,276.59144 268.15946,277.18988 268.15946,277.84250 L 268.15946,295.63589 C 268.15946,296.29529 268.83246,296.91211 269.95746,297.28316 L 308.18031,309.74881 C 309.59231,310.21615 311.45431,310.21179 312.85831,309.73913 L 350.14585,297.03207 C 351.25385,296.65908 351.91585,296.04757 351.91585,295.39448 C 351.91585,293.53542 352.38301,292.45494 351.60441,291.84162 C 351.81203,290.96877 349.68389,291.03024 349.58008,290.46882 C 349.26865,290.26597 348.95721,282.43295 349.73580,282.38582 C 349.83961,281.61201 351.81204,282.08394 351.91585,281.46585 C 352.38300,280.69681 351.91585,278.37060 351.91585,276.82297 C 351.91585,276.16310 349.99410,275.23485 348.86710,274.86331 L 313.29246,263.20721 C 311.88046,262.74230 310.02146,262.74617 308.61946,263.21785 z "
+ id="path2268"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ transform="translate(-99.03649,19.15329)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <path
+ fill="url(#XMLID_4_)"
+ d="M 306.31115,261.97211 L 269.06161,274.50556 C 267.95361,274.87855 267.25261,275.47699 267.25261,276.12961 C 265.22828,281.95692 263.82682,286.69422 267.25261,295.01302 C 267.25261,295.67242 267.92561,296.28924 269.05161,296.66029 L 306.34015,308.81451 C 307.75215,309.28185 309.61315,309.27749 311.01715,308.80483 L 347.83854,296.56493 C 348.94554,296.19194 349.60654,295.58043 349.60654,294.92734 C 349.60654,293.54841 350.07369,291.07946 349.60654,290.79055 C 349.65844,290.04918 347.99746,290.39782 348.04936,289.34501 C 347.73792,289.33032 347.42649,280.75116 348.04936,280.11360 C 348.25698,279.56516 349.39892,279.95104 349.60654,279.40260 C 350.28132,278.80226 349.55463,276.95617 349.60654,275.73296 C 349.60654,275.07309 348.93154,274.45627 347.80454,274.08473 L 310.98315,261.96147 C 309.57215,261.49656 307.71315,261.50043 306.31115,261.97211 z "
+ id="path2279"
+ style="fill:url(#linearGradient2151);"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ transform="translate(-99.03649,19.15329)" />
+
+
+
+ <g
+ id="g2281"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,128.2287,252.6448)">
+ <polygon
+ id="polygon2283"
+ fill="#FFFFFF"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:#ffffff;" />
+
+
+
+ </g>
+
+
+
+ <g
+ id="g2286"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,128.2287,252.6448)">
+ <linearGradient
+ id="linearGradient2288"
+ gradientUnits="userSpaceOnUse"
+ x1="152.20509"
+ y1="1062.5635"
+ x2="264.34052"
+ y2="1056.6604"
+ gradientTransform="matrix(0.384000,0.000000,0.000000,0.384000,-8.427600,-317.4872)"
+ spreadMethod="pad"
+ xlink:href="#linearGradient2094">
+
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FF9999"
+ id="midPointStop2292" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF9999"
+ id="midPointStop2294" />
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FF6666"
+ id="midPointStop2296" />
+
+
+
+ </linearGradient>
+
+
+
+ <polygon
+ id="polygon2299"
+ fill="url(#path266_7_)"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:url(#linearGradient2150);" />
+
+
+
+ </g>
+
+
+
+
+
+ <g
+ id="g2303"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,128.2287,252.6448)">
+ <path
+ style="fill:#0056d5;fill-opacity:1.0000000;"
+ d="M 81.399000,152.29500 L 120.08900,125.38400 L 120.08900,122.07388 L 116.04034,118.76377 L 115.10603,95.405896 L 120.08900,92.004448 L 120.08900,88.603000 L 81.399000,115.51400 C 78.976600,127.31913 78.315946,138.21385 81.399000,152.29500 z "
+ id="path2305"
+ sodipodi:nodetypes="ccccccccc" />
+
+
+
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;"
+ d="M 81.087564,149.39810 L 118.53182,123.77461 L 118.68754,93.109290 L 81.087564,119.05466 C 78.665164,130.85979 78.004510,135.31695 81.087564,149.39810 z "
+ id="path2307"
+ sodipodi:nodetypes="ccccc" />
+
+</g>
+
+
+
+ <g
+ id="g2309"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,128.2287,252.6448)">
+ <path
+ style="fill:url(#linearGradient2158);fill-opacity:1.0000000;"
+ d="M 81.399000,152.29500 L 42.708000,125.88200 C 38.815056,110.40322 40.527951,99.430733 42.708000,89.102000 L 81.404000,115.51400 C 79.200152,125.95352 77.436740,136.84824 81.399000,152.29500 z "
+ id="path2311"
+ sodipodi:nodetypes="ccccc" />
+
+
+
+ </g>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#003344;stroke-width:1.0000000pt;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1.0000000;"
+ d="M 270.14319,277.16766 L 308.52566,290.09603 C 305.14898,297.14301 305.98316,300.36613 308.77259,306.53224"
+ id="path2323"
+ sodipodi:nodetypes="ccc"
+ transform="translate(-99.03649,19.15329)" />
+
+</g>
+
+ <g
+ id="g1598"
+ transform="matrix(0.105000,0.000000,0.000000,0.105000,196.4088,94.59167)"><path
+ style="fill:url(#linearGradient1614);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient1616);stroke-width:1.0666668pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ sodipodi:nodetypes="cccccc"
+ id="path1719"
+ d="M -495.54391,-595.42858 C -495.54391,-595.42858 -526.25465,-605.40958 -537.00342,-603.87404 C -547.75218,-602.33851 -558.50098,-590.05420 -558.50098,-590.05420 L -603.03159,-508.67067 L -550.82329,-502.52852 L -495.54391,-595.42858 z " /><path
+ style="fill:url(#linearGradient1618);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ sodipodi:nodetypes="ccccccc"
+ id="path1086"
+ d="M -482.49183,-471.04999 L -437.96123,-543.22028 C -434.89017,-553.20128 -436.42570,-557.04012 -448.70999,-569.32443 C -460.99432,-581.60873 -480.95630,-589.28643 -491.70506,-593.89304 C -502.45382,-598.49965 -502.45382,-596.96412 -502.45382,-596.96412 L -554.66214,-510.97398 L -482.49183,-471.04999 z " /><path
+ style="fill:url(#linearGradient1620);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0666668pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ sodipodi:nodetypes="ccccccc"
+ id="path4247"
+ d="M -802.15271,46.495779 L -895.82052,118.66607 L -924.22799,109.45284 L -915.87569,5.0908052 L -894.28499,-26.442296 L -790.63617,21.927158 L -802.15271,46.495779 z " /><path
+ style="fill:#feb400;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0666668pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ sodipodi:nodetypes="ccccc"
+ id="path1745"
+ d="M -513.20258,-420.11379 L -794.25016,37.329101 L -826.49644,17.367115 L -540.84227,-444.68237 L -513.20258,-420.11379 z " /><path
+ style="fill:#fe4900;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0666668pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ sodipodi:nodetypes="ccccc"
+ id="path1747"
+ d="M -589.21173,-463.10885 L -870.98050,-7.0232011 L -900.92350,-24.681869 L -624.52911,-468.48323 L -589.21173,-463.10885 z " /><path
+ style="fill:#fe8300;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0666668pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ sodipodi:nodetypes="ccccc"
+ id="path1746"
+ d="M -542.37780,-441.61131 L -826.72134,17.049121 L -869.71641,-9.8228173 L -587.67620,-465.41216 L -542.37780,-441.61131 z " /><path
+ style="fill:url(#linearGradient1622);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0666668pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ sodipodi:nodetypes="ccccccccccc"
+ id="path1736"
+ d="M -522.65670,-406.82082 C -528.08561,-405.73504 -548.76087,-429.08612 -581.00714,-439.83488 C -613.25346,-450.58368 -631.43902,-455.43116 -635.27786,-460.80554 C -639.11671,-466.17992 -635.44977,-478.87166 -622.22579,-479.99977 C -608.37120,-481.18166 -630.65211,-503.03380 -615.31588,-503.80061 C -599.96049,-504.56838 -613.78035,-526.83368 -599.96049,-525.29814 C -584.62288,-523.59397 -561.57205,-520.69153 -536.23564,-509.94276 C -510.89926,-499.19400 -477.88520,-477.69646 -476.34967,-474.62538 C -474.81414,-471.55431 -472.51082,-458.50223 -484.02736,-453.89562 C -495.54391,-449.28901 -483.25958,-440.07578 -497.84718,-432.39808 C -512.43483,-424.72039 -498.85587,-402.98197 -522.65670,-406.82082 z " /><path
+ style="fill:#feb400;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0666668pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ sodipodi:nodetypes="ccccccc"
+ id="path1748"
+ d="M -794.21040,37.261304 L -825.95355,16.648737 C -825.95355,16.648737 -833.15137,29.604855 -834.30303,39.585827 C -835.30672,48.284665 -838.71771,57.724367 -831.90376,61.275343 C -825.96993,64.367567 -821.63487,62.618916 -816.93228,58.972025 C -812.22969,55.325134 -802.34467,47.455480 -800.52118,45.248163 C -798.69774,43.040803 -794.21040,37.261304 -794.21040,37.261304 z " /><path
+ style="fill:#feb300;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ sodipodi:nodetypes="ccccc"
+ id="path2372"
+ d="M -792.50040,33.221794 L -795.54032,37.959117 L -826.21339,18.516726 L -823.87811,14.319350 L -792.50040,33.221794 z " /><path
+ style="fill:#fe8300;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0666668pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ sodipodi:nodetypes="ccccccc"
+ id="path3001"
+ d="M -826.79818,16.799990 C -826.79818,16.799990 -841.72780,37.837133 -847.15675,41.773133 C -852.58570,45.709091 -869.67067,52.059683 -875.11583,48.559353 C -880.69971,44.969720 -880.68051,32.503927 -880.68051,26.300620 C -880.68046,20.057334 -876.60874,4.3133758 -875.79441,2.1418129 C -874.98007,-0.029749907 -869.82257,-9.6661453 -869.82257,-9.6661453 L -826.79818,16.799990 z " /><path
+ style="fill:#fe8300;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ sodipodi:nodetypes="ccccc"
+ id="path3002"
+ d="M -825.98384,14.696267 L -828.63046,18.225100 L -870.22973,-7.5624652 L -867.78672,-11.362657 L -825.98384,14.696267 z " /><path
+ style="fill:#fe4900;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0666668pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ sodipodi:nodetypes="ccccccc"
+ id="path3624"
+ d="M -871.63581,-6.4803104 C -871.63581,-6.4803104 -886.60729,18.856097 -890.25423,21.927158 C -893.90112,24.998220 -899.08354,29.604855 -903.69017,30.180684 C -908.29681,30.756514 -917.12612,31.716215 -916.74225,21.543286 C -916.35838,11.370358 -917.12616,3.5007037 -912.51949,-5.3286517 C -907.70703,-14.552546 -901.19494,-24.330936 -901.19494,-24.330936 L -871.63581,-6.4803104 z " /><path
+ style="fill:#fe4900;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ sodipodi:nodetypes="ccccc"
+ id="path3625"
+ d="M -899.08354,-26.058381 L -901.96268,-22.027618 L -873.29542,-5.1366943 L -868.99121,-12.378252 L -899.08354,-26.058381 z " /><path
+ style="fill:#000000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0666668pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ sodipodi:nodetypes="cccccc"
+ id="path4877"
+ d="M -895.05278,118.28215 L -928.06684,143.23465 L -924.22799,107.53339 C -924.22799,107.53339 -916.34212,92.598737 -914.63089,98.320167 C -911.17591,109.83671 -909.26730,111.31008 -899.27550,105.61395 C -889.13248,99.831762 -895.05278,118.28215 -895.05278,118.28215 z " /></g></g>
+</svg> \ No newline at end of file
diff --git a/icons/stamp.png b/icons/stamp.png
new file mode 100644
index 0000000..eab333d
--- /dev/null
+++ b/icons/stamp.png
Binary files differ
diff --git a/icons/star_off.png b/icons/star_off.png
new file mode 100644
index 0000000..3b67cdb
--- /dev/null
+++ b/icons/star_off.png
Binary files differ
diff --git a/icons/star_on.png b/icons/star_on.png
new file mode 100644
index 0000000..469e374
--- /dev/null
+++ b/icons/star_on.png
Binary files differ
diff --git a/icons/stars1.png b/icons/stars1.png
new file mode 100644
index 0000000..69a6068
--- /dev/null
+++ b/icons/stars1.png
Binary files differ
diff --git a/icons/stars10.png b/icons/stars10.png
new file mode 100644
index 0000000..63f1517
--- /dev/null
+++ b/icons/stars10.png
Binary files differ
diff --git a/icons/stars2.png b/icons/stars2.png
new file mode 100644
index 0000000..f747a2f
--- /dev/null
+++ b/icons/stars2.png
Binary files differ
diff --git a/icons/stars3.png b/icons/stars3.png
new file mode 100644
index 0000000..a9c3519
--- /dev/null
+++ b/icons/stars3.png
Binary files differ
diff --git a/icons/stars4.png b/icons/stars4.png
new file mode 100644
index 0000000..c3d3ebd
--- /dev/null
+++ b/icons/stars4.png
Binary files differ
diff --git a/icons/stars5.png b/icons/stars5.png
new file mode 100644
index 0000000..fdb01df
--- /dev/null
+++ b/icons/stars5.png
Binary files differ
diff --git a/icons/stars6.png b/icons/stars6.png
new file mode 100644
index 0000000..e401b7c
--- /dev/null
+++ b/icons/stars6.png
Binary files differ
diff --git a/icons/stars7.png b/icons/stars7.png
new file mode 100644
index 0000000..a98a84a
--- /dev/null
+++ b/icons/stars7.png
Binary files differ
diff --git a/icons/stars8.png b/icons/stars8.png
new file mode 100644
index 0000000..1e798a9
--- /dev/null
+++ b/icons/stars8.png
Binary files differ
diff --git a/icons/stars9.png b/icons/stars9.png
new file mode 100644
index 0000000..f48fd09
--- /dev/null
+++ b/icons/stars9.png
Binary files differ
diff --git a/icons/tellico.png b/icons/tellico.png
new file mode 100644
index 0000000..2c6b61e
--- /dev/null
+++ b/icons/tellico.png
Binary files differ
diff --git a/icons/tellico.svg b/icons/tellico.svg
new file mode 100644
index 0000000..4242fa0
--- /dev/null
+++ b/icons/tellico.svg
@@ -0,0 +1,2024 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ width="48pt"
+ height="48pt"
+ viewBox="0 0 256 256"
+ overflow="visible"
+ enable-background="new 0 0 256 256"
+ xml:space="preserve"
+ id="svg548"
+ sodipodi:version="0.32"
+ sodipodi:docname="tellico.svg"
+ sodipodi:docbase="/home/vqu/Desktop/icon tellico"
+ inkscape:version="0.39"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:xap="http://ns.adobe.com/xap/1.0/"
+ xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:ns="http://ns.adobe.com/SaveForWeb/1.0/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:xml="http://www.w3.org/XML/1998/namespace"
+ xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/"
+ xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+ xmlns:pdf="http://ns.adobe.com/pdf/1.3/"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:x="adobe:ns:meta/">
+ <defs
+ id="defs654"><linearGradient
+ id="linearGradient2152">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#2f9eff;stop-opacity:1.0000000;"
+ id="stop2154" />
+
+
+
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#2077e0;stop-opacity:1.0000000;"
+ id="stop2156" />
+
+
+
+
+ </linearGradient>
+
+
+
+<linearGradient
+ id="linearGradient2144">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#60baff;stop-opacity:1.0000000;"
+ id="stop2146" />
+
+
+
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#1674cd;stop-opacity:1.0000000;"
+ id="stop2148" />
+
+
+
+
+ </linearGradient>
+
+
+
+
+ <linearGradient
+ id="linearGradient3029">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#a1ffa2;stop-opacity:1.0000000;"
+ id="stop3030" />
+
+
+
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#4ed64e;stop-opacity:1.0000000;"
+ id="stop3031" />
+
+
+
+
+ </linearGradient>
+
+
+
+
+ <linearGradient
+ id="linearGradient2400">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#ccffcc;stop-opacity:1.0000000;"
+ id="stop2403" />
+
+
+
+
+ <stop
+ offset="0.41010001"
+ style="stop-color:#99ff66;stop-opacity:1.0000000;"
+ id="stop2402" />
+
+
+
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#66cc33;stop-opacity:1.0000000;"
+ id="stop2401" />
+
+
+
+
+ </linearGradient>
+
+
+
+
+ <linearGradient
+ id="linearGradient2099">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#ff999b;stop-opacity:1.0000000;"
+ id="stop2100" />
+
+
+
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#ff4e4e;stop-opacity:1.0000000;"
+ id="stop2101" />
+
+
+
+
+ </linearGradient>
+
+
+
+
+ <linearGradient
+ id="linearGradient2094">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#ff9999;stop-opacity:1.0000000;"
+ id="stop2096" />
+
+
+
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#ff6666;stop-opacity:1.0000000;"
+ id="stop2095" />
+
+
+
+
+ </linearGradient>
+
+
+
+
+ <linearGradient
+ id="XMLID_1_"
+ gradientUnits="userSpaceOnUse"
+ x1="128.9995"
+ y1="11"
+ x2="128.9995"
+ y2="245.0005">
+ <stop
+ offset="0"
+ style="stop-color:#494949"
+ id="stop555" />
+
+
+
+
+
+
+ <stop
+ offset="1"
+ style="stop-color:#000000"
+ id="stop556" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#494949"
+ id="midPointStop557" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#494949"
+ id="midPointStop558" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#000000"
+ id="midPointStop559" />
+
+
+
+
+
+
+ </linearGradient>
+
+
+
+
+ <linearGradient
+ id="XMLID_2_"
+ gradientUnits="userSpaceOnUse"
+ x1="29.0532"
+ y1="29.0532"
+ x2="226.9471"
+ y2="226.9471">
+ <stop
+ offset="0"
+ style="stop-color:#FFFFFF"
+ id="stop563" />
+
+
+
+
+
+
+ <stop
+ offset="1"
+ style="stop-color:#DADADA"
+ id="stop564" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FFFFFF"
+ id="midPointStop565" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FFFFFF"
+ id="midPointStop566" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#DADADA"
+ id="midPointStop567" />
+
+
+
+
+
+
+ </linearGradient>
+
+
+
+
+ <linearGradient
+ id="XMLID_3_"
+ gradientUnits="userSpaceOnUse"
+ x1="139.8662"
+ y1="75.7139"
+ x2="202.4969"
+ y2="138.3446">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#1a2993;stop-opacity:1.0000000;"
+ id="stop575" />
+
+
+
+
+
+
+ <stop
+ offset="0.47189999"
+ style="stop-color:#003044;stop-opacity:1.0000000;"
+ id="stop576" />
+
+
+
+
+
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#003344;stop-opacity:1.0000000;"
+ id="stop577" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#E14E30"
+ id="midPointStop578" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#E14E30"
+ id="midPointStop579" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0.4719"
+ style="stop-color:#FF5B00"
+ id="midPointStop580" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF5B00"
+ id="midPointStop581" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#C51700"
+ id="midPointStop582" />
+
+
+
+
+
+
+ </linearGradient>
+
+
+
+
+ <linearGradient
+ id="XMLID_4_"
+ gradientUnits="userSpaceOnUse"
+ x1="50.0991"
+ y1="75.9434"
+ x2="112.7299"
+ y2="138.5741">
+ <stop
+ offset="0"
+ style="stop-color:#990000"
+ id="stop600" />
+
+
+
+
+
+
+ <stop
+ offset="0.4551"
+ style="stop-color:#7C0000"
+ id="stop601" />
+
+
+
+
+
+
+ <stop
+ offset="1"
+ style="stop-color:#600000"
+ id="stop602" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#990000"
+ id="midPointStop603" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#990000"
+ id="midPointStop604" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0.4551"
+ style="stop-color:#7C0000"
+ id="midPointStop605" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#7C0000"
+ id="midPointStop606" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#600000"
+ id="midPointStop607" />
+
+
+
+
+
+
+ </linearGradient>
+
+
+
+
+ <linearGradient
+ id="XMLID_5_"
+ gradientUnits="userSpaceOnUse"
+ x1="94.5244"
+ y1="116.9331"
+ x2="157.1558"
+ y2="179.5645">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#009933;stop-opacity:1.0000000;"
+ id="stop625" />
+
+
+
+
+
+
+ <stop
+ offset="0.4551"
+ style="stop-color:#006A00"
+ id="stop626" />
+
+
+
+
+
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#003333;stop-opacity:1.0000000;"
+ id="stop627" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#009933"
+ id="midPointStop628" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#009933"
+ id="midPointStop629" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0.4551"
+ style="stop-color:#006A00"
+ id="midPointStop630" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#006A00"
+ id="midPointStop631" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#003333"
+ id="midPointStop632" />
+
+
+
+
+
+
+ </linearGradient>
+
+
+
+
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2099"
+ id="linearGradient2098"
+ x1="0.36138615"
+ y1="0.44000000"
+ x2="0.26732674"
+ y2="0.65333331"
+ spreadMethod="reflect" />
+
+
+
+
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_5_"
+ id="linearGradient2397"
+ x1="50.099098"
+ y1="75.943398"
+ x2="112.72990"
+ y2="138.57410"
+ gradientUnits="userSpaceOnUse" />
+
+
+
+
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2400"
+ id="linearGradient2404"
+ x1="-2.6281061e-16"
+ y1="0.50000000"
+ x2="1.0000000"
+ y2="0.50000000" />
+
+
+
+
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3029"
+ id="linearGradient3032"
+ x1="0.56435645"
+ y1="0.54666668"
+ x2="0.72277230"
+ y2="0.22000000"
+ spreadMethod="reflect" />
+
+
+
+
+<linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2400"
+ id="linearGradient2046"
+ x1="50.019157"
+ y1="90.537178"
+ x2="93.079155"
+ y2="88.270393"
+ gradientUnits="userSpaceOnUse" />
+
+
+
+<linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2144"
+ id="linearGradient2150"
+ x1="50.019157"
+ y1="90.537178"
+ x2="93.079155"
+ y2="88.270393"
+ gradientUnits="userSpaceOnUse" />
+
+
+
+<linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_3_"
+ id="linearGradient2151"
+ x1="50.099098"
+ y1="75.943398"
+ x2="112.72990"
+ y2="138.57410"
+ gradientUnits="userSpaceOnUse" />
+
+
+
+<linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2152"
+ id="linearGradient2158"
+ x1="0.36138615"
+ y1="0.44000000"
+ x2="0.26732674"
+ y2="0.65333331"
+ spreadMethod="reflect" />
+
+
+
+</defs>
+ <sodipodi:namedview
+ id="base"
+ inkscape:zoom="12.109204"
+ inkscape:cx="22.655324"
+ inkscape:cy="22.569240"
+ inkscape:window-width="852"
+ inkscape:window-height="771"
+ inkscape:window-x="117"
+ inkscape:window-y="175" />
+ <metadata
+ id="metadata549">
+ <ns:sfw
+ id="sfw9">
+ <ns:slices
+ id="slices11">
+ <ns:slice
+ x="0"
+ y="0"
+ width="256"
+ height="256"
+ sliceID="124417176"
+ id="slice13" />
+
+
+
+
+
+
+ </ns:slices>
+
+
+
+
+
+
+ <ns:sliceSourceBounds
+ x="0"
+ y="0"
+ width="256"
+ height="256"
+ bottomLeftOrigin="true"
+ id="sliceSourceBounds16" />
+
+
+
+
+
+
+ <ns:optimizationSettings
+ id="optimizationSettings18">
+ <ns:targetSettings
+ fileFormat="PNG24Format"
+ targetSettingsID="0"
+ id="targetSettings20">
+ <ns:PNG24Format
+ transparency="true"
+ includeCaption="false"
+ interlaced="false"
+ noMatteColor="false"
+ matteColor="#FFFFFF"
+ filtered="false"
+ id="PNG24Format22" />
+
+
+
+
+
+
+ </ns:targetSettings>
+
+
+
+
+
+
+ </ns:optimizationSettings>
+
+
+
+
+
+
+ </ns:sfw>
+
+
+
+
+
+
+ <xpacket
+ id="xpacket27">begin='' id='W5M0MpCehiHzreSzNTczkc9d' </xpacket>
+
+
+
+
+
+
+ <x:xmpmeta
+ x:xmptk="XMP toolkit 3.0-29, framework 1.6"
+ id="xmpmeta30">
+
+ <metadata
+ id="metadata334">
+ <rdf:RDF
+ id="RDF32">
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f"
+ id="Description34">
+ <pdf:Producer
+ id="Producer36">
+Adobe PDF library 5.00</pdf:Producer>
+
+
+
+
+
+
+ </rdf:Description>
+
+
+
+
+
+
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f"
+ id="Description40" />
+
+
+
+
+
+
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f"
+ id="Description42" />
+
+
+
+
+
+
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f"
+ id="Description44">
+ <xap:CreateDate
+ id="CreateDate46">
+2004-01-26T11:58:28+02:00</xap:CreateDate>
+
+
+
+
+
+
+ <xap:ModifyDate
+ id="ModifyDate49">
+2004-03-28T20:44:56Z</xap:ModifyDate>
+
+
+
+
+
+
+ <xap:CreatorTool
+ id="CreatorTool52">
+Adobe Illustrator 10.0</xap:CreatorTool>
+
+
+
+
+
+
+ <xap:MetadataDate
+ id="MetadataDate55">
+2004-02-16T23:42:57+01:00</xap:MetadataDate>
+
+
+
+
+
+
+ <xap:Thumbnails
+ id="Thumbnails58">
+ <rdf:Alt
+ id="Alt60">
+ <rdf:li
+ rdf:parseType="Resource"
+ id="li62">
+ <xapGImg:format
+ id="format64">
+JPEG</xapGImg:format>
+
+
+
+
+
+
+ <xapGImg:width
+ id="width67">
+256</xapGImg:width>
+
+
+
+
+
+
+ <xapGImg:height
+ id="height70">
+256</xapGImg:height>
+
+
+
+
+
+
+ <xapGImg:image
+ id="image73">
+/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
+AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
+DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
+Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER
+AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
+AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
+UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
+1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
+qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
+obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
+0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
++DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7
+FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqlvmDzFo
+3l7TJdT1e5W1tItuTbszHoiKN2Y+AxV4j5g/5ydvTcMnl/SYlgU0Se/LOzDxMcTIF/4M4qk//QzP
+nv8A5YNL/wCRVx/2UYq7/oZnz3/ywaX/AMirj/soxV3/AEMz57/5YNL/AORVx/2UYq7/AKGZ89/8
+sGl/8irj/soxV3/QzPnv/lg0v/kVcf8AZRirv+hmfPf/ACwaX/yKuP8AsoxV3/QzPnv/AJYNL/5F
+XH/ZRirv+hmfPf8AywaX/wAirj/soxV3/QzPnv8A5YNL/wCRVx/2UYq7/oZnz3/ywaX/AMirj/so
+xV3/AEMz57/5YNL/AORVx/2UYq7/AKGZ89/8sGl/8irj/soxV3/QzPnv/lg0v/kVcf8AZRirv+hm
+fPf/ACwaX/yKuP8AsoxV3/QzPnv/AJYNL/5FXH/ZRirv+hmfPf8AywaX/wAirj/soxV3/QzPnv8A
+5YNL/wCRVx/2UYq7/oZnz3/ywaX/AMirj/soxV3/AEMz57/5YNL/AORVx/2UYq7/AKGZ89/8sGl/
+8irj/soxV3/QzPnv/lg0v/kVcf8AZRirv+hmfPf/ACwaX/yKuP8AsoxVFad/zk75oS4B1HSbG4t+
+6W/qwP8A8E7zj/hcVeyeRfzJ8tec7Vn0yUx3kQBuLCaizJ25AAkMlf2l+mmKsqxV2KuxV2KuxV2K
+vm/XDqf5ufmk+j287Q+XtJLqJF3VIY2CSzAHYvM9AvtTwOKvePLfk/y35bs0tdHsYrZVFGlCgyuf
+GSQ/Ex+ZxVOK4q6oxVrkMVdyGKu5jFWvUGKu9RffFWvVX3xV3rL74q71l8DirXrp4HFXfWE8DirX
+1hPA4q76yngcVd9Zj8D+GKtfWo/A/hirvrcfgfw/rirvrcfgfw/rirX1yLwb8P64q765F4N+H9cV
+d9di8G/D+uKtfXovBvw/riqVa/5X8r+abR7TV7GO55CiyMoWZP8AKjkHxKR7HFXzB5n0XXfys8/R
+NZXBJgIudOujsJYGJUpIB8ijj+oxV9VeWtfs/MGhWWsWf9xexLKErUoxHxI3up2OKplirsVdirsV
+Q+oMy2Fyy/aWJyvzCnFXhP8AziwqvL5nmYcpQLIBz1oxuC2/uVGKvficVaxVrFWicVaJxVrFWsVa
+JxVonFWsVaxVrFWicVaxVrFWicVaJxVrFWsVaJxVonFWsVaxVdCSJkp/MP14q8V/5ypRBJ5ZkCjm
+wvVZu5CmAgfRyOKsn/5x3vJX8lwWzElQZmSvbjMR/wAbYq9XxV2KuxV2KofUv+Oddf8AGGT/AIic
+VeE/84pn/lKP+jD/ALGcVe+nFWsVaJxVonFWsVaxVonFWicVaxVrFWsVaJxVrFWsVaJxVonFWsVa
+xVonFWicVaxVrFWicVXQ/wB9H/rD9eKvFv8AnKw/8ov/ANH/AP2LYqn/APzjn/yisHyuP+T4xV6/
+irsVdirsVQ+pf8c66/4wyf8AETirwf8A5xRNf8U/9GH/AGM4q9+PXFWicVaJxVrFWsVaJxVonFWs
+VaxVrFWicVaxVrFWicVaJxVrFWsVaJxVonFWsVaxVonFWicVXQ/30f8ArD9eKvFf+crjT/C3/R//
+ANi2Ksg/5xy/5RS3+Vx/yfGKvYMVdirsVdiqH1L/AI511/xhk/4icVeDf84nmv8Ain/ow/7GcVe/
+HrirROKtYq1irROKtE4q1irWKtYq0TirWKtYq0TirROKtYq1irROKtE4q1irWKtE4q0TirWKroP7
++P8A1h+vFXiv/OWBp/hb/o//AOxbFWQf844f8onb/K4/5PjFXsOKuxV2KuxVD6l/xzrr/jDJ/wAR
+OKvBP+cTD/ylX/Rh/wBjOKvf2O5xVrFWsVaJxVazAAkmgG5JxV4p+ZX/ADkRY6bK+ieTEXVtZc+k
+bxQZII3O1Igv9+/hT4fn0zEy6oDaO5eh7P7ClP15fTHu6n9X3sL0n8/fzM8tanFF5zgF9Z3FGDGK
+KKRV2r6bQBI2pUVU7jKseqkD6t3P1fYOKcf3Xpl8aPz3e/8AlLzv5d816et7pF0sykfHFWjoe4Ze
+uZ0ZCQsPKZsE8UuGYop6TkmprFWsVaJxVonFWsVaxVonFWJebvzD0vQg9tBS71MbCBT8MZ/4tYdP
+9Xr8swNVr44thvL8c3c9ndjZNR6j6cff3+79bB/8b/mFasNRuqm0kNTC0aBVFdtgOa+ALZocfbkj
+kI4hIjmPx+O96GXY2jnHgjtLvs/2FnXlfz7pmtIscjC3vOhRjQE+1c6PTayGYek79zyuu7My6Y+o
+enoejJycynXtE4q1irWKroD+/j/1l/XirxT/AJyzP/KK/wDR/wD9i2Ksh/5xv/5RK3+Vx/yfxV7F
+irsVdirsVQ+pf8c66/4wyf8AETirwL/nEo/8pV/0Yf8AYzir6AbqcVaxVonFUl81+cPLvlXTG1HX
+LxLW3FRGp3klcCvCNB8TN8vp2yE5iIsuRptLkzS4YCy+cfNX5lee/wA0bmXStCibSfLAJWck0LqP
++WiVepP++k+mtK5r8ueU9hsHsdD2Vi03ql6sn3e79aZ+WfJOj+XYq26+vesoEt7IPjO24QbhFPgP
+pJplDtLJ5o/UtPstQtXtb2FZ7eT7UbjbwqCNwRXYjcYGyred3XlrzP5N1D9N+UbqVo4yC8A3lC9w
+yjaVfl8Q+jlk8eQxNhxdVpIZY8MxY7+57F+WH/OQmjeYRFpuvFdP1c0VXJ/dSn/JPY+2bHFnEve8
+dr+yZ4Nx6od/d73sCurqHUhlYVDA1BGXupcTirROKtYq1iqheXtpZ2z3N3MkFvGKvK5CqPvyMpiI
+s7BnjxSnIRiLJeY6/wDmHq2uXDaV5XjeOI1El39mRl6VBP8Adr7nf5Zz3aHbEYRNHhj3/q/FvW6L
+sXHgHiag2e7p+0/Yo6N5StdNpPcEXN9sfUP2Ebr8APev7R/DPP8AXdszy+mHpj9p/U5mbWHJsNop
+lMKgg9Dsc1cJEGw1xYxqXl1RL9Z05vQnBJ9IbKT/AJJ/Z+XT5Zv9H2rIEcRo/wA52OPUCUeDIOKJ
+/HxTnyz+Y15YuLDWlZkWi822dfv/AI522h7bjKo5f9N0+Lou0fZ3bxNPvH+b+r9XN6TZ31reQLPb
+SCWNu47HwI7HOhBBFh5SUSDR5q2FDROKr4P7+P8A1l/XirxL/nLU/wDKK/8AR/8A9i2Ksi/5xt/5
+RG2+Vz/yfxV7HirsVdirsVQ+pf8AHOuv+MMn/ETirwH/AJxINf8AFf8A27/+xnFX0C32j88VWk4q
+8o/ND8/NB8qerpmj8NW8wCqGJTWCB+n751+0wP7CmviVzGzakR2G5d32d2LPPUp+nH9p9363kln5
+N81ectUPmHz5dTEsR6Vix4OUG/DiKCCP/JA5deh3OCbkbk9VjGPDHgxCh+Pm9AtrK0srWO1tIlgt
+4RxjiQUUD6PxwMgskyJbYoaTAW2KHfrkW0MT81fl/putcrq2IstTNW9ZR8EjHf8AeqO9f2hv41yQ
+k1Tw3yd5L/OTzj5Cvk0XzTFJeaWNo5GPJwn88cn+7F/Ed99szMWoI2O4eZ1/Y0ZXLH6Zd3T9n3Pp
+Hyz5t0HzLpyX+j3SXELipCn4lPgw6jM4SBFh5jJilCXDIUU3wtbWKsd81+eNH8vRFZm9e+IrHZxk
+czXoXP7C+5+iuYuo1cMQ33Pc7LQdl5dSdtofzv1d7z0WfmfztcLfarKbTSlNYYlBCkf8VIeu37bf
+j0ziO2PaCMDRPFP+aOnv/FvUx8DRR4cY4p9T+v8AUyuy0qx021FtZxCOMfaP7TH+Zj3OcLqdZkzy
+4pn9QcCeaWSVyK2XK4tkUFLl0W+KCly6LkRQV7p9tex8Jl3H2JBsy/I/wzLw6mWP3dzfiyygbCX2
+V9rnlmcSwSGS0ruR9kjwZe3+dDnS9m9tTxfT6ofzT+NvuXV9n4NcL+jL3/jn970fy3510zWkVOQh
+u9uUTHqT4V/V+vO30mux6iNwO/d1DxGu7NzaWVTG3Q9CyEnMxwF8H9/H/rr+vFXiX/OW5p/hT/t4
+f9i2Ksj/AOca/wDlD7b5XP8AyfxV7HirsVdirsVQ+pf8c66/4wyf8ROKvn//AJxGNf8AFf8A27/+
+xnFXvWp6hZ6dZXN/eyrBZ2qPNcTP9lUQVZj9AwE0LLOEDOQjEWS+b/OP5y+b/P17J5e8iwS2OlMe
+Fzfn4JnjPVpJBtBGadAeTdO/HNfk1BntHk9houxseAceb1T7un7fu+9FeTfyy0jy6Eu7il9q9Km5
+cfBGTufRU9P9Y/F8q0yoRpz8mcz9zKpMSiKGkyJbYoeTIluihpMBbYoZ+uRbQtwJQup6Xp+p2jWl
+/AtxA2/FhuD05KRup36jCDTGcBLmwF9G84eQb8615Vu5JrJPjmi6sqr/AL9jFA6gftrQjfYDMjHl
+I5Op1ugjkFTF+fc94/Kf86LDzpbG3uoTaarBxWZRujFq0YH3pmwxZBIPG63RSwSo7g8iq+afzHvZ
+71tD8rxNNdljE92BU8hswiHTbu7bfrzVa7tSOMGjQHORd12f2LER8XOajzr9f6v7FLy7+XccMn6R
+15/ruoSHmYWPONWJrVyf7xvw+fXPNO1PaSWQmOHYfzup93d7+fucrVdqEjgxemH4+TLJRnMg3zdd
+FBS5dFvigpcui5EUHLl0XIigpcui5EVLJs2iAQQRUEUIO4IPY4YyINhUi1Dy/NHJ9a0pzFMu/o1o
+D/qk/qO36s22j7RMZA3wy7/x/Y5g1EckeDKOKJT7yh+ZVyLhdL1mNvUX4RIdnBHYg7/fnfdmdq+M
+eCf1d/e8t2z2GMEfFxG8f3X94en2ciSSQyIao7KVPsSM3bzTxP8A5y5NP8Kf9vD/ALFsVZJ/zjV/
+yh1t8rn/AKiMVeyYq7FXYq7FUPqX/HOuv+MMn/ETir59/wCcQz/yln/bv/7GcVeofnOf+QY+ZP8A
+mEb/AIkMqz/QXYdlf4zD3vl78v8AznqOgW4SMCaxd2Mts1BU/wAysBUNmglnMJeT63h7Kx6nBZ2n
+vv8ArezaJ5k0rXLb1rKWrqP3sDbSIf8AKX+I2zMx5YzGzzmr0GXTyqY9x6FGSZItEUNJkS2xQ0mA
+tsUNJkS3RQ75FtCzAlSubq3tYGnuJFihTdnY0GJLKMSTQYD5i8+XFzyttLLQW/RrjpI/+r/KPx+W
+UyydzsMOkA3kiP8AnHkk+YdRJ68Y/wBb5uNL1fOu3/4feXovk69ubPVNQlgbi3IVHUEcm2Oed+0U
+RMRB5WXo9XhjPHESelabrtteqI3/AHVx/Ieh/wBU/wAM4jNpTDcbh5zPo5Y9xvFES5VFqig5cui5
+EUFLl0XIigpcvi3xQcuXRciKjk2xokAVOwHU4qld9rIWsdtuehk7fRmVj0/WTm4dL1kxa2kZ/NkR
+YlmLCpO5/u863sEfvYfH7i1duitDOv6P+6D6C0A/6LZf7H/iWdy+avHP+cvD/wAon/28P+xbFWS/
+840f8oba/K5/6iMVey4q7FXYq7FUPqX/ABzrr/jDJ/xE4q+fP+cQT/yln/bv/wCxnFXqH5z/APks
+fMv/ADCN/wASGVZ/oLsOyv8AGYe98faP/vEP9Y5zOo+p9u7I/uPiU0s7y6s7hLm1laGeM1WRDQjK
+oyINh2GXFHJHhkLBekeW/wAx7e8C2ur8be56LcjaJz/lfyH8Plmfi1QO0nk9f2FLH6sXqj3dR+v7
+2XOQRUGoPQjMl0YQ8mAtsUNJkS2xQz5FuCR6/wCadO0dCrn1rsiqW6nf5sf2RkJSAcjFglP3PN9Z
+17UdWn9S6k+AH93AuyJ8h4++UykS7TFhjAbJeiO7BUBZj0AyIDXqtXi0+M5MshCEeZLJ/wAun1ry
+xPdX1nAt1MyB7hODukcaVNWKEU+1uembCOp4OT4F217VfmMlYI3CN7m9/h0HvZn5N8zWkt9cpdFb
+eWehjqfhJqSRU9Oucj27pZmIlHcC3tey/ajT66EY/RlH8J/R3s7B7j6DnKu8Taw16VAIrqskfQSf
+tD5+OYmXTA7x2Lg5tGDvHYpoZY5UDxsGQ9CMxeEg0XD4SDRQsuWxbooKXLouRFBS5dFyIoO5u4bd
+OUjU8FHU/LL4YzLk348ZkdkivdRmuSV+xF2QfxzOx4hH3uyxYBD3oTLW9KbRv+dwiH+UP+TWdJ2E
+P3sP877i6vt7/EZ/5v8Aug+h9A/3lsv9j/xLO2fNXjn/ADl8f+UT/wC3h/2LYqyX/nGf/lDLX5XP
+/URir2bFXYq7FXYqh9S/4511/wAYZP8AiJxV89f84fmv+Lf+3f8A9jWKvUfzo/8AJY+Zf+YVv+JD
+Ks/0Fz+y/wDGYe98f6N/vEP9Y5zWo+p9u7H/ALj4lHZQ7V2Ksi8u+dNR0njBJW5sf98sfiQf8Vt2
++XTL8Wcx26Oq13ZWPP6h6Z9/f73ounaxp+qW/r2cocftodnU+DL2zOjMSFh5XPpcmGXDMUuuJY4o
+2klcJGgq7sQAAO5JwljEW898y/mByLW2jnbo94R/ybB/Wf7colk7na4NH1l8mDu7yOzyMXdjVmY1
+JJ7knKXYAUrWtjNcGo+GPu56fR45KMbeW9ova3S9mRqR483SA5/5380fb3AvQ/J/5a3l+iXNwrWe
+nNQ+qw/ezA7/ALsHt/lHbwrlebURx7Dcvh/avbGr7UyceolUB9MR9I9w/wB8d3pdrpdhpdqtrYwi
+GJdzT7TN/MzHdj881OTLKZsuJGIiKDDvM/kmyvma6sCLO9rUgbROfcD7J91+6prmVh1dbS3DCWLf
+ijtJItI85avoNyNO1qJzEvTluyitKqw2ZduozD1vZEMo48ex+x6zsf2qnirHqd4/zuvx7/e9E07U
+7HUbdbi0lWWNvA7j5jOWzYZY5VIUX0LDnhliJQNxKPt7qa3asbbHqp6HMeUBLmmeMS5pnFexXAoP
+hfup/hmNLEYuJLEY+5TmyUWcWP6nrUURMdvSSTu37I/rmww6YneTs9PpCd5bBIJZZJXLyMWY9zme
+AAKDs4xAFBZhZOxVJLVv+d2iH+UP+TOdN2EPXD/O/S6vt7/EZ/5v+6D6M0D/AHlsv9j/AMSztHzV
+41/zmAaf4S/7eH/YrirJv+cZf+ULtPlc/wDURir2fFXYq7FXYqh9S/4511/xhk/4icVfPH/OHpr/
+AIt/7d3/AGNYq9S/Oj/yWPmX/mFb/iQyrP8AQXP7L/xiHvfH+i/7wj/WOc1qPqfbuxv7j4lH5Q7V
+2KuxVXsr67sbhbi0laGVejL3HgR0I9jhjIg2GrLhhkjwyFh3mHzTq+rv6dzIEgSgEEdVQkftEdz8
+8yjkMhu6SOkhikRFJlUsQqipOwAyKcuWOOJlMiMRuSdgE80TyxfahdxW8MD3FzKaR20Yqfmx7Ad+
+w75aIVuXyP2j/wCCHKZODQe45P8AiB/vj8B1e1+UvypsdMRLvWlS7vQKpajeCLwqCPjb5/D89jmH
+qdSaqL5sNOSTPIeOZ53v/aWXXI65qm5KrkdcVSq5HXFUm1PSrDU7c297EJE34N0ZCf2kbsdv65bj
+yygdkEA82C3uleYvKVyb/TJWuNPBq5ArxHWkqDt/lDbxpWmZOSGLUxqQ3c3s/tHPo5XjPp6jp+PN
+mflbz/pesqsMrC2vabxsaBj/AJJzmdb2Vkw7jeL6R2X25h1YoemfcWVA03Gat3SW67qN38FuHpGy
+1amxO/c5k6bFHnW7l6PBH6q3SPM12LsVdirsVY/at/zvkQ/yh/yYzqOwh6of536XV9vf4jP/ADf9
+0H0hoH+8tl/sf+JZ2T5q8Z/5zCNP8Jf9vH/sVxVlH/OMf/KFWnyuf+ojFXs+KuxV2KuxVD6l/wAc
+66/4wyf8ROKvnf8A5w6P/KXf9u7/ALGsVep/nOrN+WXmYKCx+qOSBvsGBJ+gZVm+gud2Yf8ACIe9
+8e6HLGbT0ww5qxJXvQ5zepieK32vsTLE4uG/UCdkxzHdy7FXYq7FULHZzXNw6xjYH4mPQZk44kh4
+v2j9otL2ZEzzH1G+GI+qXu/STs9D8hflZquvOssKfV9PH97qUq7GhoViX9s9em3icyoYnwntj2g1
+vbM/WfD0/SA5fH+cfPkOlPddA8paJ5cszb6bDR2/vrl6NNIR/M1Bt7Db2yvM4WPBHGKiiZ81OZjN
+LLkdcw2pKrkdcVSq5HXFUAeuKuBINR1wqw3zJ+X1tc8r3RiLO9X4hAvwxOwNfhp/dt8vh6dNzmdh
+1Y+me4TEmJsGiEH5f/MTVNGuv0T5jicemQvqMKOvgT2K+BG2Ymu7DjkHHh59z2fZPtMRUM/+m/X+
+tmupXdvdmGe3cPGyVBHzOc/hxmFg830jQzEoWEFlznOxV2KtO6RoXdgqKKszGgA9ycQCdgrGNInW
++8+RTWtZIuVeQB6CLhX5cs63sXGYyiDz3/S6vt81opg/0f8AdB9L6BX6tZf7D9eda+avGf8AnMU/
+8oj/ANvH/sVxVlH/ADjF/wAoTafK6/6iMVe0Yq7FXYq7FUPqX/HOuv8AjDJ/xE4q+df+cOD/AMpf
+/wBu7/saxV9CXUMM6SwzossMoZJInAZWVtmVlOxBHUYpBINh88/mb/zjY6vJrHkQ8HFXl0Z2p8/q
+0jH/AIRj8j0GYWbSg8vk9N2d29KJAyGiOUh+l4nHqVxbXUljqsL2t3CxjlWRSjK67FXU0KnNPl0p
+HJ9I7P7djMAZD/ndD+PkmQIIqNwehzDeiBt2KXYqmnlfib6BXUOrXiBkYAqRyXYg9RmXGRGMkdz8
+5f8ABSF9rY/+FR/6aTfS/lzzbp9xFFZTollKihIlUBYSAKAJ2X5YdN2hGe0tpfY81izA7ck9nyzM
+yml8+anM400tuR1zCakpuR1xVKrkdcVS9upxVrFULqGp2lhF6lw9CfsIN2b5DLsWCWQ0GrLljAWX
+mnn3WJdStI3dFRI5QIRQFlDK1fjpXegr2ze6TAMewaNNqDkme5lXlsk6ba1P+6E/jnJa4fvJf1i+
+8ez/APi8f6o+5Nsw3fOxVBalq1np8fKZqufsRL9o/wBnvl2HBLIdkiNpPYaX5j84XIWJTBYcqBqH
+h1psP22zpOz+yr5fN1/aHa2HSDf1T/m/r7g9k8m/lrpWhwBmj5TNu7Nu7f6zD9QzqcGmhiFReA1/
+aWXVSuZ26DoGdWoC3EIAoA6gAfMZe694b/zmOf8AlEP+3j/2K4qyn/nGD/lB7P5XX/UTir2nFXYq
+7FXYqh9S/wCOddf8YZP+InFXzn/zhsa/4v8A+3d/2NYq+iJP7xvmcVWE4qwf8xvyk8q+ebUm9i+q
+asq0t9VgUeqtOiyDYSJ/kt9BGVZMQk52j1+TAdt49z5d85eRPOX5eXwg1SD6xpcjEW1/FVoJPYNT
+92/+Q34jfNXqNJ3/ADe97H9oqFRNx6xPT3fikHaXtvdJyhapH2lOzD5jNVkxmJ3e80mtx543A/Dq
+FfIOWmPlg01K2H/L5H/xJcyT/dH3H7n50/4KA/12h/wqP+7m9ZzRvGJ/o3my7swsFzWe1Gwr9tB7
+E9R7HMvFqpRFHcNkchGxZTHeW15CJreQSIe46g+BHbJZJAiwmRtCXPfMJqSm574qlVz3xVLm6nFW
+P6x5pgtuUNnSacbM/wCwv9Tmw0+iMt5bBws+sEdo7liVxcT3EplncySN1Y5tYxERQ5OslIyNlJPM
+5ppif8Zl/wCIPl+Eer4Od2d9Z9zO/LP/ABzLX/mHj/jnFa/+8l/WL797P/4vH+qPuTckAVOwHU5h
+O+SDVPMtH+q6avr3DHiHUchX/JA+0c2Gm0BkfV8mVAC5Ggnvk/8AKvUNVuBfayS1TyMTGo/56N/x
+qP1Z1+j7KEQDP5freS7U9pecNP8A6b9X6/7Xs+k6HYaXAsVtGAVHEMABQdKAdhm6AAFB46UjI2TZ
+KYYWKpa/70xf66/rxV4X/wA5kmn+EP8At4/9iuKsq/5xf/5Qaz+V1/1E4q9qxV2KuxV2KofUv+Od
+df8AGGT/AIicVfOX/OGhr/jD/t3f9jWKvoiT+8b5n9eKrCcVaxVDahp9jqNnLZX9vHdWc6lJreZQ
+6Mp7FTtgItlGZibBovnL8zP+cb77Tnl1ryKzzwrV5NHY1mQdT6DH+8X/ACG+L3bMPNpQRtyel7O7
+dlCQ4jwy/nD9P4p5HaazSVrW/Q291GxRw4K/EDQhgd1PzzTZtKRvF9J7O7ehkqOX0y7+h/V9zI/L
+TD9K2o/5fI/+JLkD/dH3H7nxj/gn/wDGrD/hUf8AdzeuZpHinYqr2l7c2kvqW7lG7jsR4Ed8INKy
+Oz12C8UJJSK4/l/ZP+qf4Yqtue+BUi1a/tLKEzXMgjToK9SfADucsx45TNBhPIIiy8+1nzNc3xaK
+GsNqdiv7TD/KP8M3Gn0kYbneTq8+qM9hsElzLcR2KpP5qNNMT/jMv/EHzI0w9Xwdj2b9Z9zMtC1G
+zttFtZpZRw+roAAakkVqAPHOM1mGUs0gB/EX3/2fifAH9UfcsiGueZ7g21jGYrQGjtuF/wBm3c+w
+zYaDssyOws9/QOz1uvw6WNzO/QdT+O96v5J/K2w0pFuLpedwQOTsPjPy/lH451um0cMQ23l3vAdp
+dsZdUaPph/NH6e96DHHHEgjjUIi9FGwzLdS3irWKqlr/AL1Q/wCuv68VeF/85lmn+D/+3j/2K4qy
+r/nF3/lBbP5XX/UTir2vFXYq7FXYqh9S/wCOddf8YZP+InFXzh/zhia/4w/7dv8A2NYq+iZT+8b5
+n9eKrMVaxVonFWicVee/mX+S3lbzxG1zIv6O1wLSLU4VBLU6CdPhEo+kMOxplWTEJe9ztJr54duc
+e54Zc/l9f+Q/M+m6Pe3kd7LcSQXaywhlUK8vphSG3r+6zTa+HCCP6P63mPabVDPq4Sr+AD/ZSei5
+zLrHYq7FXYqu1HzFdafpU0xUTtGB6fM03Zgu/jSuXYMYnMRLVmycESXm2oale6hcG4u5DJIeg7KP
+BR2Gb7HjjAUHSzyGRsobJsHYq7FUl82mmlp/xnX/AIg+ZWkHr+H6nZdmfWfc9H/L38n/ANKWFvey
+X4Ns8ccpt+JQ/EK05gt+rBPswSnxSOz67pfaKWLTiEI+rhAv9j23QfLGm6PbpHBEoZBtQAAfIfxz
+ZQgIigKDosuaeSRlM3IpuTkmtrFWsVaxVUtT/pUP+uv6xirwr/nM40/wf/28v+xXFWV/84uf8oJZ
+fK6/6icVe2Yq7FXYq7FUPqX/ABzrr/jDJ/xE4q+b/wDnC81/xj/27f8AsaxV9Ey/3j/M/rxVZirR
+OKtE4q1irWKvA/zvdV/M7QyxAUW1qSTsAPrcuaXtTr/V/W832t/fx/qj7yjs5Vx3Yq7FXYqlfmf/
+AI4dz/sP+Ti5laP+9Hx+5xtX/dn8dWB5vXTOxV2KuxVIvOEiDTY4yw5tMrBa7kBWBNPpzN0MSZn3
+O07LieInpT6T/KIEeWbSop/o0P8AxHNiXt8f0j3M7JwM2sVaxVrFWicVVLX/AHqh/wBdf1jFXhX/
+ADmgaf4O/wC3l/2K4qyz/nFr/lA7L5XX/UScVe2Yq7FXYq7FUPqX/HOuv+MMn/ETir5t/wCcLTX/
+ABj/ANu3/saxV9FS/wB6/wDrH9eKrCcVaJxVrFWsVaJxVhn5iflppPnK2RpJDaapbqVtbxRyHEmv
+CRduS1+kfrx9RpxkHm4Ws0Ucw7pDq8Ru5vN3kK+XTPMNs09gdre4Q8lZR3hkNOVB+w1CPbOc1egI
+PcfsLoMmGeI1IMq03VLDUrYXFlMs0R2JHVT4MDuD881M4GJooBRWQS7FUr8z/wDHDuf9h/ycXMrR
+/wB6Pj9zjav+7P46sDzeumdirsVSTUvMSrILTTk+tXbnipUclDE0AUD7bfLb9WZuDSGW8tg7XS9n
+GW8/kzf8v/yO1PWLlNU8zcuJIf6oT93qn/jQZshURUXqNPohEC/k+iNK0q10y1FvbigAAJ6dOgA8
+Mi7FGYq1irWKtE4q1iqpa/71Q/66/rGKvCf+c0jT/B3/AG8v+xXFWW/84sf8oFY/K6/6iTir23FX
+Yq7FXYqh9S/4511/xhk/4icVfNf/ADhWf+Uy/wC3b/2N4q+i5T+9f/WP68VWE4q1irWKtE4q0Tir
+WKoLVtI0zV7GSw1O2ju7SUUeGQVHzHcEdiNxkZQEhRYThGQoiw8H85fk75j8qXL635NllvLJamay
++1PGvUjiNpk+jkPA9c1Wp7PBG24dLqOzzDeG4QHlnz7p+qlbW7pZ6iaL6bGiSN0+AnvX9k/jnP6j
+RShuN4uAynMJUr8z/wDHDuf9h/ycXMrR/wB6Pj9zjav+7P46sDzeumUbu8t7SEzTuEQdK9SfADuc
+nCBkaDbiwyyGohK9PsvMnnG8Njo8DR2YNJpmqFAP+/GH/ER+ObPDphDc7l6HQ9m0b5nve9/lz+S+
+keXo0urpfXvyPjncfHv1CD9hfxzIJehxYIw9706OOOJBHGoVF2CjYYG9vFWsVaxVonFWsVaxVUtP
+964f+Mi/rGKvCP8AnNQ/8ob/ANvL/sUxVl3/ADiv/wAoDY/K6/6ijir27FXYq7FXYqh9S/4511/x
+hk/4icVfNP8AzhQa/wCMv+3b/wBjeKvoyY/vX/1j+vFVmKtYq0TirROKtYq1irROKtE4q84/Mb8l
+tA81iS+s+Oma4RX6yg/dTN/xcg7/AOWu/jXplOTCJb9XD1Gijk3G0njv6c82+R9RGjebrSV4P903
+P2iU/mjk6Sr9NR+GaTV9lCW8fTL7C6bLglA0WS6vqNjqPlma6splnt34cXX/AIyLsR1B8Qd81Onx
+ShmEZCjv9zgasfuz+OrzbVdft7ImGIevdbjgPsqf8oj9Q/DOiw6cz35BxNNoZT3ltFkXkj8n/MHm
+m6TUNe5wWhoVt/syMvv/AL7X8TmzhAQFB6nS9niI3FDufRXlvylo+g2cdvZQJGIxRQq0A+Q8fc75
+J2sYgCgnROKWsVaxVrFWicVaxVrFWsVVLQ/6XD/xkX9YxV4P/wA5rmn+Df8At5f9imKsv/5xV/8A
+Jf2Pyu/+oo4q9vxV2KuxV2KofUv+Oddf8YZP+InFXzR/zhMa/wCM/wDt2/8AY3ir6Nm/vX/1j+vF
+VPFWicVaJxVrFWsVaJxVonFWsVaxVLPMHlzRPMOnPp2sWiXdq/7Lj4lb+ZGFGRvdTgIthPGJCi8G
+8x/849ecNOvZ08pX4n0m7oHhml9GVQCCBJQcHp2Yb+3jVLBEkEi6dZl7PJO2482T/l1+Q9norpe6
+xxuNQXfmaFUPhGu//BHLnNwaWMNzuXrtvbw28QihQIg7D+OLkrycVaxVrFWsVaJxVrFWsVaxVonF
+VW0/3rg/4yL/AMSGKvBv+c2TT/Bn/by/7FMVZf8A84qf+S+sPld/9RRxV7hirsVdirsVQ+pf8c66
+/wCMMn/ETir5m/5wkP8Aymf/AG7P+xvFX0dN/fP/AKx/XiqmTirROKtYq1irROKtE4q1irWKtE4q
+1irWKtYq0TirWKtYq1irROKtYq1irWKtE4q1iqrZ/wC9cH/GRf8AiQxV4L/zm2f+UM/7ef8A2KYq
+zD/nFL/yXth8rv8A6ijir3HFXYq7FXYqh9S/4511/wAYZP8AiJxV8y/84RH/AJTT/t2f9jeKvo6c
+/vn/ANY/rxVTJxVrFWsVaJxVonFWsVaxVonFWsVaxVrFWicVaxVrFWsVaJxVrFWsVaxVonFWsVax
+VVs/97IP+Mi/8SGKvBf+c3T/AMoX/wBvP/sUxVmP/OKH/kvLD5Xf/UUcVe44q7FXYq7FUPqX/HOu
+v+MMn/ETir5j/wCcHzX/ABp/27P+xvFX0fOf30n+sf14qp4q1irROKtE4q1irWKtE4q1irWKtYq0
+TirWKtYq1irROKtYq1irWKtE4q1irWKtYqq2Z/0yD/jIn/EhirwT/nOA0/wX/wBvP/sUxVmX/OJ/
+/ku9P+V3/wBRRxV7lirsVdirsVQ+pf8AHOuv+MMn/ETir5g/5wgkVJ/Olu54zkacwjOzUQ3Qbb2L
+CuKvpG4qJpK/zH9eKqeKtE4q0TirWKtYq0TirWKtYq1irROKtYq1irWKtE4q1irWKtYq0TirWKtY
+q1irROKq1iCbyAAVPNT9xrirwD/nOGaMy+TIgwMiLqTsncKxtQp+nicVZt/zieGH5dafUEHjdnfw
+N0SMVe5Yq7FXYq7FVskayRtG32XBVvkRTFXxjrN7rf5Efnjca1FbNP5e1ZpDLAtFWW2mcPLGldg8
+MlGT2p2JxV9U+U/PHknzvp8d/wCX9UhvA61eFHC3EZ7rLCfjQj3Hy2xVPP0dF/M34Yq79GxfzN+G
+KtfoyL+dvwxV36Mi/nb8MVd+i4f52/DFWv0VD/O34Yq79FQ/zt+H9MVa/RMP87fhirv0TD/O34Yq
+79EQfzt+H9MVa/Q8H87fh/TFXfoeD+dvw/pirv0NB/O34f0xVr9Cwfzt+H9MVd+hYP8Afj/h/TFW
+v0Jb/wC/H/D+mKu/Qdv/AL8f8P6Yq1+g7f8A34/4f0xV36Ct/wDfj/h/TFXfoK3/AN+P+H9MVa/Q
+Nv8A78f8P6Yq79AW3+/H/D+mKpN5n84eRPIlhLqGvanDacVJSKRw1xJ4LFCvxuT7D57Yq+IvzF87
+a9+cH5kLcWtu0ccvG00myJr6NshLcpCNqmrO5+joBir7H/J7y5HoWhW1jAP3NpbpEGIoWJp8R924
+VPzxV6FirsVdirsVdirE/wAxvy38v+etDk0zVYlL0rBPSrI46Ed/uxV8j+b/APnFvzbpN66WEyyw
+En0zMGK8faSMNX6UGKsd/wChfPP3ja/8FP8A9UsVd/0L55+8bX/gp/8Aqlirv+hfPP3ja/8ABT/9
+UsVd/wBC+efvG1/4Kf8A6pYq7/oXzz942v8AwU//AFSxV3/Qvnn7xtf+Cn/6pYq7/oXzz942v/BT
+/wDVLFXf9C+efvG1/wCCn/6pYq7/AKF88/eNr/wU/wD1SxV3/Qvnn7xtf+Cn/wCqWKu/6F88/eNr
+/wAFP/1SxV3/AEL55+8bX/gp/wDqlirv+hfPP3ja/wDBT/8AVLFXf9C+efvG1/4Kf/qlirv+hfPP
+3ja/8FP/ANUsVd/0L55+8bX/AIKf/qlirv8AoXzz942v/BT/APVLFXf9C+efvG1/4Kf/AKpYq7/o
+Xzz942v/AAU//VLFXf8AQvnn7xtf+Cn/AOqWKu/6F88/eNr/AMFP/wBUsVd/0L55+8bX/gp/+qWK
+ovTP+cc/OVxcBLueCCLu8Ylkb/gWWP8AXir3r8rPyT0zy4P9FhM97IB691LQuR1oxAoif5I698Ve
+76bYR2NqsKbnq7eLHviqKxV2KuxV2KuxV2KrZIo5VKSIHQ9VYAj8cVQp0bSyf95k+7FXfobS/wDl
+mT8cVd+htL/5Zk/HFXfobS/+WZPxxV36G0v/AJZk/HFXfobS/wDlmT8cVd+htL/5Zk/HFXfobS/+
+WZPxxV36G0v/AJZk/HFXfobS/wDlmT8cVd+htL/5Zk/HFXfobS/+WZPxxV36G0v/AJZk/HFXfobS
+/wDlmT8cVd+htL/5Zk/HFXfobS/+WZPxxV36G0v/AJZk/HFXfobS/wDlmT8cVd+htL/5Zk/HFXfo
+bS/+WZPxxV36G0v/AJZk/HFXfobS/wDlmT8cVcNG0sH/AHmT7sVRUcUcShI0CIOiqAB+GKrsVdir
+sVf/2Q==</xapGImg:image>
+
+
+
+
+
+
+ </rdf:li>
+
+
+
+
+
+
+ </rdf:Alt>
+
+
+
+
+
+
+ </xap:Thumbnails>
+
+
+
+
+
+
+ </rdf:Description>
+
+
+
+
+
+
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f"
+ id="Description80">
+ <xapMM:DocumentID
+ id="DocumentID82">
+uuid:ef18cd8d-b4e0-42e1-badd-bdf8b8440881</xapMM:DocumentID>
+
+
+
+
+
+
+ </rdf:Description>
+
+
+
+
+
+
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f"
+ id="Description86">
+ <dc:format
+ id="format88">
+image/svg+xml</dc:format>
+
+
+
+
+
+
+ <dc:title
+ id="title91">
+ <rdf:Alt
+ id="Alt93">
+ <rdf:li
+ xml:lang="x-default"
+ id="li95">
+mime.ai</rdf:li>
+
+
+
+
+
+
+ </rdf:Alt>
+
+
+
+
+
+
+ </dc:title>
+
+
+
+
+
+
+ </rdf:Description>
+
+
+
+
+
+
+ <cc:Work
+ rdf:about=""
+ id="Work404">
+ <dc:format
+ id="format405">image/svg+xml</dc:format>
+
+
+
+
+
+ <dc:type
+ id="type407"
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+
+
+
+
+
+</cc:Work>
+
+
+
+
+
+</rdf:RDF>
+
+
+
+
+
+</metadata>
+
+
+
+
+
+</x:xmpmeta>
+
+
+
+
+
+
+ <xpacket
+ id="xpacket103">end='w' </xpacket>
+
+
+
+
+
+
+ </metadata>
+ <g
+ id="g1413"
+ inkscape:export-filename="/home/vqu/Desktop/icon tellico/bookcase.png"
+ inkscape:export-xdpi="96.000000"
+ inkscape:export-ydpi="96.000000">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <rect
+ id="_x3C_Slice_x3E_"
+ fill="none"
+ width="256"
+ height="256"
+ style="fill:none;" />
+
+
+
+ <g
+ id="g2047"
+ transform="matrix(2.491580,0.000000,0.000000,2.609211,-608.2880,-703.9475)">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<path
+ opacity="0.2"
+ d="M 299.78022,316.80616 L 261.13022,329.80676 C 260.02222,330.17975 259.32022,330.77819 259.32022,331.43081 L 259.32022,349.22517 C 259.32022,349.88359 259.99322,350.50089 261.11922,350.87147 L 299.80922,363.64953 C 301.22122,364.11589 303.08222,364.11202 304.48722,363.63937 L 340.06286,352.02185 C 341.16986,351.64886 341.83086,351.03784 341.83086,350.38475 C 341.83086,347.78595 342.45373,345.65430 341.51942,345.23555 C 341.57133,344.19568 339.59890,345.02442 339.33937,344.14027 C 339.18365,344.08661 338.87222,337.33708 339.65081,337.43914 C 339.65081,336.44942 341.98658,337.48403 341.83086,336.65003 C 342.55754,336.23128 341.88277,332.54246 341.83086,330.41081 C 341.83086,329.75094 340.37727,328.97841 339.25027,328.60686 L 304.45322,316.79503 C 303.04222,316.33012 301.18222,316.33399 299.78022,316.80616 z "
+ id="path2191"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+
+
+
+
+<path
+ opacity="0.2"
+ d="M 297.71922,316.47332 L 259.06822,329.47392 C 257.96022,329.84691 257.25922,330.44535 257.25922,331.09797 L 257.25922,348.89136 C 257.25922,349.55076 257.93222,350.16758 259.05722,350.53863 L 297.28007,363.00428 C 298.69207,363.47162 300.55407,363.46726 301.95807,362.99460 L 339.24561,350.28754 C 340.35361,349.91455 341.01561,349.30304 341.01561,348.64995 C 341.01561,346.79089 341.48277,345.71041 340.70417,345.09709 C 340.91179,344.22424 338.78365,344.28571 338.67984,343.72429 C 338.36841,343.52144 338.05697,335.68842 338.83556,335.64129 C 338.93937,334.86748 340.91180,335.33941 341.01561,334.72132 C 341.48276,333.95228 341.01561,331.62607 341.01561,330.07844 C 341.01561,329.41857 339.09386,328.49032 337.96686,328.11878 L 302.39222,316.46268 C 300.98022,315.99777 299.12122,316.00164 297.71922,316.47332 z "
+ id="path2194"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+
+
+
+
+<path
+ fill="url(#XMLID_4_)"
+ d="M 295.41091,315.22758 L 258.16137,327.76103 C 257.05337,328.13402 256.35237,328.73246 256.35237,329.38508 C 254.32804,335.21239 252.92658,339.94969 256.35237,348.26849 C 256.35237,348.92789 257.02537,349.54471 258.15137,349.91576 L 295.43991,362.06998 C 296.85191,362.53732 298.71291,362.53296 300.11691,362.06030 L 336.93830,349.82040 C 338.04530,349.44741 338.70630,348.83590 338.70630,348.18281 C 338.70630,346.80388 339.17345,344.33493 338.70630,344.04602 C 338.75820,343.30465 337.09722,343.65329 337.14912,342.60048 C 336.83768,342.58579 336.52625,334.00663 337.14912,333.36907 C 337.35674,332.82063 338.49868,333.20651 338.70630,332.65807 C 339.38108,332.05773 338.65439,330.21164 338.70630,328.98843 C 338.70630,328.32856 338.03130,327.71174 336.90430,327.34020 L 300.08291,315.21694 C 298.67191,314.75203 296.81291,314.75590 295.41091,315.22758 z "
+ id="path2205"
+ style="fill:url(#linearGradient2397);"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+
+
+
+
+<g
+ id="g2207"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,216.3650,286.7469)">
+ <polygon
+ id="polygon2209"
+ fill="#FFFFFF"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:#ffffff;" />
+
+
+
+
+
+
+ </g>
+
+
+
+
+<g
+ id="g2212"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,216.3650,286.7469)"
+ style="fill:url(#linearGradient2404);">
+ <linearGradient
+ id="linearGradient2214"
+ gradientUnits="userSpaceOnUse"
+ x1="152.20509"
+ y1="1062.5635"
+ x2="264.34052"
+ y2="1056.6604"
+ gradientTransform="matrix(0.384000,0.000000,0.000000,0.384000,-8.427600,-317.4872)"
+ spreadMethod="pad"
+ xlink:href="#linearGradient2094"
+ style="fill:url(#linearGradient2404);">
+
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FF9999;fill:url(#linearGradient2404);"
+ id="midPointStop2218" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF9999;fill:url(#linearGradient2404);"
+ id="midPointStop2220" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FF6666;fill:url(#linearGradient2404);"
+ id="midPointStop2222" />
+
+
+
+
+
+
+ </linearGradient>
+
+
+
+
+
+
+ <polygon
+ id="polygon2225"
+ fill="url(#path266_7_)"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:url(#linearGradient2046);" />
+
+
+
+
+
+
+ </g>
+
+
+
+
+
+ <path
+ style="fill:#009933;fill-opacity:1.0000000;"
+ d="M 297.76400,360.42407 L 336.45400,347.40509 L 336.45400,345.80372 L 332.40534,344.20236 L 331.47103,332.90231 L 336.45400,331.25676 L 336.45400,329.61122 L 297.76400,342.63019 C 295.34160,348.34127 294.68095,353.61190 297.76400,360.42407 z "
+ id="path2231"
+ sodipodi:nodetypes="ccccccccc" />
+
+
+
+
+
+
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;"
+ d="M 297.45257,359.02261 L 334.89682,346.62650 L 335.05254,331.79126 L 297.45257,344.34309 C 295.03017,350.05416 294.36951,352.21044 297.45257,359.02261 z "
+ id="path2233"
+ sodipodi:nodetypes="ccccc" />
+
+
+
+
+<g
+ id="g2235"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,216.3650,286.7469)">
+ <path
+ style="fill:url(#linearGradient3032);fill-opacity:1.0000000;fill-rule:nonzero;"
+ d="M 81.399000,152.29500 L 42.708000,125.88200 C 38.815056,110.40322 40.527951,99.430733 42.708000,89.102000 L 81.404000,115.51400 C 79.200152,125.95352 77.436740,136.84824 81.399000,152.29500 z "
+ id="path2237"
+ sodipodi:nodetypes="ccccc" />
+
+
+
+
+
+
+ </g>
+
+
+
+
+<path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#003333;stroke-width:1.0000000pt;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1.0000000;"
+ d="M 259.24295,330.42313 L 297.62542,343.35150 C 294.24874,350.39848 295.08292,353.62160 297.87235,359.78771"
+ id="path2249"
+ sodipodi:nodetypes="ccc" />
+
+
+
+
+
+</g>
+
+
+
+ <g
+ id="g2159"
+ transform="matrix(2.491580,0.000000,0.000000,2.609211,-411.9683,-668.5990)">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <path
+ opacity="0.2"
+ d="M 310.68046,263.55069 L 272.03046,276.55129 C 270.92246,276.92428 270.22046,277.52272 270.22046,278.17534 L 270.22046,295.96970 C 270.22046,296.62812 270.89346,297.24542 272.01946,297.61600 L 310.70946,310.39406 C 312.12146,310.86042 313.98246,310.85655 315.38746,310.38390 L 350.96310,298.76638 C 352.07010,298.39339 352.73110,297.78237 352.73110,297.12928 C 352.73110,294.53048 353.35397,292.39883 352.41966,291.98008 C 352.47157,290.94021 350.49914,291.76895 350.23961,290.88480 C 350.08389,290.83114 349.77246,284.08161 350.55105,284.18367 C 350.55105,283.19395 352.88682,284.22856 352.73110,283.39456 C 353.45778,282.97581 352.78301,279.28699 352.73110,277.15534 C 352.73110,276.49547 351.27751,275.72294 350.15051,275.35139 L 315.35346,263.53956 C 313.94246,263.07465 312.08246,263.07852 310.68046,263.55069 z "
+ id="path2265"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ transform="translate(-99.03649,19.15329)" />
+
+
+
+
+
+
+
+
+ <path
+ opacity="0.2"
+ d="M 308.61946,263.21785 L 269.96846,276.21845 C 268.86046,276.59144 268.15946,277.18988 268.15946,277.84250 L 268.15946,295.63589 C 268.15946,296.29529 268.83246,296.91211 269.95746,297.28316 L 308.18031,309.74881 C 309.59231,310.21615 311.45431,310.21179 312.85831,309.73913 L 350.14585,297.03207 C 351.25385,296.65908 351.91585,296.04757 351.91585,295.39448 C 351.91585,293.53542 352.38301,292.45494 351.60441,291.84162 C 351.81203,290.96877 349.68389,291.03024 349.58008,290.46882 C 349.26865,290.26597 348.95721,282.43295 349.73580,282.38582 C 349.83961,281.61201 351.81204,282.08394 351.91585,281.46585 C 352.38300,280.69681 351.91585,278.37060 351.91585,276.82297 C 351.91585,276.16310 349.99410,275.23485 348.86710,274.86331 L 313.29246,263.20721 C 311.88046,262.74230 310.02146,262.74617 308.61946,263.21785 z "
+ id="path2268"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ transform="translate(-99.03649,19.15329)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <path
+ fill="url(#XMLID_4_)"
+ d="M 306.31115,261.97211 L 269.06161,274.50556 C 267.95361,274.87855 267.25261,275.47699 267.25261,276.12961 C 265.22828,281.95692 263.82682,286.69422 267.25261,295.01302 C 267.25261,295.67242 267.92561,296.28924 269.05161,296.66029 L 306.34015,308.81451 C 307.75215,309.28185 309.61315,309.27749 311.01715,308.80483 L 347.83854,296.56493 C 348.94554,296.19194 349.60654,295.58043 349.60654,294.92734 C 349.60654,293.54841 350.07369,291.07946 349.60654,290.79055 C 349.65844,290.04918 347.99746,290.39782 348.04936,289.34501 C 347.73792,289.33032 347.42649,280.75116 348.04936,280.11360 C 348.25698,279.56516 349.39892,279.95104 349.60654,279.40260 C 350.28132,278.80226 349.55463,276.95617 349.60654,275.73296 C 349.60654,275.07309 348.93154,274.45627 347.80454,274.08473 L 310.98315,261.96147 C 309.57215,261.49656 307.71315,261.50043 306.31115,261.97211 z "
+ id="path2279"
+ style="fill:url(#linearGradient2151);"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ transform="translate(-99.03649,19.15329)" />
+
+
+
+
+
+
+ <g
+ id="g2281"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,128.2287,252.6448)">
+ <polygon
+ id="polygon2283"
+ fill="#FFFFFF"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:#ffffff;" />
+
+
+
+
+
+
+ </g>
+
+
+
+
+
+
+ <g
+ id="g2286"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,128.2287,252.6448)">
+ <linearGradient
+ id="linearGradient2288"
+ gradientUnits="userSpaceOnUse"
+ x1="152.20509"
+ y1="1062.5635"
+ x2="264.34052"
+ y2="1056.6604"
+ gradientTransform="matrix(0.384000,0.000000,0.000000,0.384000,-8.427600,-317.4872)"
+ spreadMethod="pad"
+ xlink:href="#linearGradient2094">
+
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FF9999"
+ id="midPointStop2292" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF9999"
+ id="midPointStop2294" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FF6666"
+ id="midPointStop2296" />
+
+
+
+
+
+
+ </linearGradient>
+
+
+
+
+
+
+ <polygon
+ id="polygon2299"
+ fill="url(#path266_7_)"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:url(#linearGradient2150);" />
+
+
+
+
+
+
+ </g>
+
+
+
+
+
+
+
+
+ <g
+ id="g2303"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,128.2287,252.6448)">
+ <path
+ style="fill:#0056d5;fill-opacity:1.0000000;"
+ d="M 81.399000,152.29500 L 120.08900,125.38400 L 120.08900,122.07388 L 116.04034,118.76377 L 115.10603,95.405896 L 120.08900,92.004448 L 120.08900,88.603000 L 81.399000,115.51400 C 78.976600,127.31913 78.315946,138.21385 81.399000,152.29500 z "
+ id="path2305"
+ sodipodi:nodetypes="ccccccccc" />
+
+
+
+
+
+
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;"
+ d="M 81.087564,149.39810 L 118.53182,123.77461 L 118.68754,93.109290 L 81.087564,119.05466 C 78.665164,130.85979 78.004510,135.31695 81.087564,149.39810 z "
+ id="path2307"
+ sodipodi:nodetypes="ccccc" />
+
+
+
+
+</g>
+
+
+
+
+
+
+ <g
+ id="g2309"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,128.2287,252.6448)">
+ <path
+ style="fill:url(#linearGradient2158);fill-opacity:1.0000000;"
+ d="M 81.399000,152.29500 L 42.708000,125.88200 C 38.815056,110.40322 40.527951,99.430733 42.708000,89.102000 L 81.404000,115.51400 C 79.200152,125.95352 77.436740,136.84824 81.399000,152.29500 z "
+ id="path2311"
+ sodipodi:nodetypes="ccccc" />
+
+
+
+
+
+
+ </g>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#003344;stroke-width:1.0000000pt;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1.0000000;"
+ d="M 270.14319,277.16766 L 308.52566,290.09603 C 305.14898,297.14301 305.98316,300.36613 308.77259,306.53224"
+ id="path2323"
+ sodipodi:nodetypes="ccc"
+ transform="translate(-99.03649,19.15329)" />
+
+
+
+
+</g>
+
+
+
+ <g
+ id="g2102"
+ transform="matrix(2.491580,0.000000,0.000000,2.609211,-625.3589,-668.1927)">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <path
+ opacity="0.2"
+ d="M 310.68046,263.55069 L 272.03046,276.55129 C 270.92246,276.92428 270.22046,277.52272 270.22046,278.17534 L 270.22046,295.96970 C 270.22046,296.62812 270.89346,297.24542 272.01946,297.61600 L 310.70946,310.39406 C 312.12146,310.86042 313.98246,310.85655 315.38746,310.38390 L 350.96310,298.76638 C 352.07010,298.39339 352.73110,297.78237 352.73110,297.12928 C 352.73110,294.53048 353.35397,292.39883 352.41966,291.98008 C 352.47157,290.94021 350.49914,291.76895 350.23961,290.88480 C 350.08389,290.83114 349.77246,284.08161 350.55105,284.18367 C 350.55105,283.19395 352.88682,284.22856 352.73110,283.39456 C 353.45778,282.97581 352.78301,279.28699 352.73110,277.15534 C 352.73110,276.49547 351.27751,275.72294 350.15051,275.35139 L 315.35346,263.53956 C 313.94246,263.07465 312.08246,263.07852 310.68046,263.55069 z "
+ id="path570"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+
+
+
+
+
+
+
+
+ <path
+ opacity="0.2"
+ d="M 308.61946,263.21785 L 269.96846,276.21845 C 268.86046,276.59144 268.15946,277.18988 268.15946,277.84250 L 268.15946,295.63589 C 268.15946,296.29529 268.83246,296.91211 269.95746,297.28316 L 308.18031,309.74881 C 309.59231,310.21615 311.45431,310.21179 312.85831,309.73913 L 350.14585,297.03207 C 351.25385,296.65908 351.91585,296.04757 351.91585,295.39448 C 351.91585,293.53542 352.38301,292.45494 351.60441,291.84162 C 351.81203,290.96877 349.68389,291.03024 349.58008,290.46882 C 349.26865,290.26597 348.95721,282.43295 349.73580,282.38582 C 349.83961,281.61201 351.81204,282.08394 351.91585,281.46585 C 352.38300,280.69681 351.91585,278.37060 351.91585,276.82297 C 351.91585,276.16310 349.99410,275.23485 348.86710,274.86331 L 313.29246,263.20721 C 311.88046,262.74230 310.02146,262.74617 308.61946,263.21785 z "
+ id="path572"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <path
+ fill="url(#XMLID_4_)"
+ d="M 306.31115,261.97211 L 269.06161,274.50556 C 267.95361,274.87855 267.25261,275.47699 267.25261,276.12961 C 265.22828,281.95692 263.82682,286.69422 267.25261,295.01302 C 267.25261,295.67242 267.92561,296.28924 269.05161,296.66029 L 306.34015,308.81451 C 307.75215,309.28185 309.61315,309.27749 311.01715,308.80483 L 347.83854,296.56493 C 348.94554,296.19194 349.60654,295.58043 349.60654,294.92734 C 349.60654,293.54841 350.07369,291.07946 349.60654,290.79055 C 349.65844,290.04918 347.99746,290.39782 348.04936,289.34501 C 347.73792,289.33032 347.42649,280.75116 348.04936,280.11360 C 348.25698,279.56516 349.39892,279.95104 349.60654,279.40260 C 350.28132,278.80226 349.55463,276.95617 349.60654,275.73296 C 349.60654,275.07309 348.93154,274.45627 347.80454,274.08473 L 310.98315,261.96147 C 309.57215,261.49656 307.71315,261.50043 306.31115,261.97211 z "
+ id="path608"
+ style="fill:url(#XMLID_4_);"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+
+
+
+
+
+
+ <g
+ id="g253_3_"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,227.2652,233.4915)">
+ <polygon
+ id="path266_3_"
+ fill="#FFFFFF"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:#ffffff;" />
+
+
+
+
+
+
+ </g>
+
+
+
+
+
+
+ <g
+ id="g253_1_"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,227.2652,233.4915)">
+ <linearGradient
+ id="path266_7_"
+ gradientUnits="userSpaceOnUse"
+ x1="152.20509"
+ y1="1062.5635"
+ x2="264.34052"
+ y2="1056.6604"
+ gradientTransform="matrix(0.384000,0.000000,0.000000,0.384000,-8.427600,-317.4872)"
+ spreadMethod="pad"
+ xlink:href="#linearGradient2094">
+
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FF9999"
+ id="midPointStop615" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF9999"
+ id="midPointStop616" />
+
+
+
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FF6666"
+ id="midPointStop617" />
+
+
+
+
+
+
+ </linearGradient>
+
+
+
+
+
+
+ <polygon
+ id="path266_1_"
+ fill="url(#path266_7_)"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:url(#path266_7_);" />
+
+
+
+
+
+
+ </g>
+
+
+
+
+
+
+
+
+ <g
+ id="g267_1_"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,227.2652,233.4915)">
+ <path
+ style="fill:#cf0000;"
+ d="M 81.399000,152.29500 L 120.08900,125.38400 L 120.08900,122.07388 L 116.04034,118.76377 L 115.10603,95.405896 L 120.08900,92.004448 L 120.08900,88.603000 L 81.399000,115.51400 C 78.976600,127.31913 78.315946,138.21385 81.399000,152.29500 z "
+ id="path277_2_"
+ sodipodi:nodetypes="ccccccccc" />
+
+
+
+
+
+
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;"
+ d="M 81.087564,149.39810 L 118.53182,123.77461 L 118.68754,93.109290 L 81.087564,119.05466 C 78.665164,130.85979 78.004510,135.31695 81.087564,149.39810 z "
+ id="path1472"
+ sodipodi:nodetypes="ccccc" />
+
+
+
+
+</g>
+
+
+
+
+
+
+ <g
+ id="g278_1_"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,227.2652,233.4915)">
+ <path
+ style="fill:url(#linearGradient2098);fill-opacity:1.0000000;"
+ d="M 81.399000,152.29500 L 42.708000,125.88200 C 38.815056,110.40322 40.527951,99.430733 42.708000,89.102000 L 81.404000,115.51400 C 79.200152,125.95352 77.436740,136.84824 81.399000,152.29500 z "
+ id="path279_1_"
+ sodipodi:nodetypes="ccccc" />
+
+
+
+
+
+
+ </g>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#600000;stroke-width:1.0000000pt;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1.0000000;"
+ d="M 270.14319,277.16766 L 308.52566,290.09603 C 305.14898,297.14301 305.98316,300.36613 308.77259,306.53224"
+ id="path1469"
+ sodipodi:nodetypes="ccc" />
+
+
+
+
+</g>
+
+
+
+
+
+
+</g>
+</svg>
diff --git a/icons/tellico_mime.svg b/icons/tellico_mime.svg
new file mode 100644
index 0000000..d4103a7
--- /dev/null
+++ b/icons/tellico_mime.svg
@@ -0,0 +1,1560 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ width="48pt"
+ height="48pt"
+ viewBox="0 0 256 256"
+ overflow="visible"
+ enable-background="new 0 0 256 256"
+ xml:space="preserve"
+ id="svg548"
+ sodipodi:version="0.32"
+ sodipodi:docname="tellico_mime.svg"
+ sodipodi:docbase="/home/vqu/Desktop/icon tellico"
+ inkscape:version="0.39"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:xap="http://ns.adobe.com/xap/1.0/"
+ xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:ns="http://ns.adobe.com/SaveForWeb/1.0/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:xml="http://www.w3.org/XML/1998/namespace"
+ xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/"
+ xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+ xmlns:pdf="http://ns.adobe.com/pdf/1.3/"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:x="adobe:ns:meta/">
+ <defs
+ id="defs654"><linearGradient
+ id="linearGradient2152">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#2f9eff;stop-opacity:1.0000000;"
+ id="stop2154" />
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#2077e0;stop-opacity:1.0000000;"
+ id="stop2156" />
+
+ </linearGradient>
+<linearGradient
+ id="linearGradient2144">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#60baff;stop-opacity:1.0000000;"
+ id="stop2146" />
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#1674cd;stop-opacity:1.0000000;"
+ id="stop2148" />
+
+ </linearGradient>
+
+ <linearGradient
+ id="linearGradient3029">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#a1ffa2;stop-opacity:1.0000000;"
+ id="stop3030" />
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#4ed64e;stop-opacity:1.0000000;"
+ id="stop3031" />
+
+ </linearGradient>
+
+ <linearGradient
+ id="linearGradient2400">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#ccffcc;stop-opacity:1.0000000;"
+ id="stop2403" />
+
+ <stop
+ offset="0.41010001"
+ style="stop-color:#99ff66;stop-opacity:1.0000000;"
+ id="stop2402" />
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#66cc33;stop-opacity:1.0000000;"
+ id="stop2401" />
+
+ </linearGradient>
+
+ <linearGradient
+ id="linearGradient2099">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#ff999b;stop-opacity:1.0000000;"
+ id="stop2100" />
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#ff4e4e;stop-opacity:1.0000000;"
+ id="stop2101" />
+
+ </linearGradient>
+
+ <linearGradient
+ id="linearGradient2094">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#ff9999;stop-opacity:1.0000000;"
+ id="stop2096" />
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#ff6666;stop-opacity:1.0000000;"
+ id="stop2095" />
+
+ </linearGradient>
+
+ <linearGradient
+ id="XMLID_1_"
+ gradientUnits="userSpaceOnUse"
+ x1="128.9995"
+ y1="11"
+ x2="128.9995"
+ y2="245.0005">
+ <stop
+ offset="0"
+ style="stop-color:#494949"
+ id="stop555" />
+
+
+
+ <stop
+ offset="1"
+ style="stop-color:#000000"
+ id="stop556" />
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#494949"
+ id="midPointStop557" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#494949"
+ id="midPointStop558" />
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#000000"
+ id="midPointStop559" />
+
+
+
+ </linearGradient>
+
+ <linearGradient
+ id="XMLID_2_"
+ gradientUnits="userSpaceOnUse"
+ x1="29.0532"
+ y1="29.0532"
+ x2="226.9471"
+ y2="226.9471">
+ <stop
+ offset="0"
+ style="stop-color:#FFFFFF"
+ id="stop563" />
+
+
+
+ <stop
+ offset="1"
+ style="stop-color:#DADADA"
+ id="stop564" />
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FFFFFF"
+ id="midPointStop565" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FFFFFF"
+ id="midPointStop566" />
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#DADADA"
+ id="midPointStop567" />
+
+
+
+ </linearGradient>
+
+ <linearGradient
+ id="XMLID_3_"
+ gradientUnits="userSpaceOnUse"
+ x1="139.8662"
+ y1="75.7139"
+ x2="202.4969"
+ y2="138.3446">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#1a2993;stop-opacity:1.0000000;"
+ id="stop575" />
+
+
+
+ <stop
+ offset="0.47189999"
+ style="stop-color:#003044;stop-opacity:1.0000000;"
+ id="stop576" />
+
+
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#003344;stop-opacity:1.0000000;"
+ id="stop577" />
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#E14E30"
+ id="midPointStop578" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#E14E30"
+ id="midPointStop579" />
+
+
+
+ <a:midPointStop
+ offset="0.4719"
+ style="stop-color:#FF5B00"
+ id="midPointStop580" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF5B00"
+ id="midPointStop581" />
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#C51700"
+ id="midPointStop582" />
+
+
+
+ </linearGradient>
+
+ <linearGradient
+ id="XMLID_4_"
+ gradientUnits="userSpaceOnUse"
+ x1="50.0991"
+ y1="75.9434"
+ x2="112.7299"
+ y2="138.5741">
+ <stop
+ offset="0"
+ style="stop-color:#990000"
+ id="stop600" />
+
+
+
+ <stop
+ offset="0.4551"
+ style="stop-color:#7C0000"
+ id="stop601" />
+
+
+
+ <stop
+ offset="1"
+ style="stop-color:#600000"
+ id="stop602" />
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#990000"
+ id="midPointStop603" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#990000"
+ id="midPointStop604" />
+
+
+
+ <a:midPointStop
+ offset="0.4551"
+ style="stop-color:#7C0000"
+ id="midPointStop605" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#7C0000"
+ id="midPointStop606" />
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#600000"
+ id="midPointStop607" />
+
+
+
+ </linearGradient>
+
+ <linearGradient
+ id="XMLID_5_"
+ gradientUnits="userSpaceOnUse"
+ x1="94.5244"
+ y1="116.9331"
+ x2="157.1558"
+ y2="179.5645">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#009933;stop-opacity:1.0000000;"
+ id="stop625" />
+
+
+
+ <stop
+ offset="0.4551"
+ style="stop-color:#006A00"
+ id="stop626" />
+
+
+
+ <stop
+ offset="1.0000000"
+ style="stop-color:#003333;stop-opacity:1.0000000;"
+ id="stop627" />
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#009933"
+ id="midPointStop628" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#009933"
+ id="midPointStop629" />
+
+
+
+ <a:midPointStop
+ offset="0.4551"
+ style="stop-color:#006A00"
+ id="midPointStop630" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#006A00"
+ id="midPointStop631" />
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#003333"
+ id="midPointStop632" />
+
+
+
+ </linearGradient>
+
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2099"
+ id="linearGradient2098"
+ x1="0.36138615"
+ y1="0.44000000"
+ x2="0.26732674"
+ y2="0.65333331"
+ spreadMethod="reflect" />
+
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_5_"
+ id="linearGradient2397"
+ x1="50.099098"
+ y1="75.943398"
+ x2="112.72990"
+ y2="138.57410"
+ gradientUnits="userSpaceOnUse" />
+
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2400"
+ id="linearGradient2404"
+ x1="-2.6281061e-16"
+ y1="0.50000000"
+ x2="1.0000000"
+ y2="0.50000000" />
+
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3029"
+ id="linearGradient3032"
+ x1="0.56435645"
+ y1="0.54666668"
+ x2="0.72277230"
+ y2="0.22000000"
+ spreadMethod="reflect" />
+
+<linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2400"
+ id="linearGradient2046"
+ x1="50.019157"
+ y1="90.537178"
+ x2="93.079155"
+ y2="88.270393"
+ gradientUnits="userSpaceOnUse" />
+<linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2144"
+ id="linearGradient2150"
+ x1="50.019157"
+ y1="90.537178"
+ x2="93.079155"
+ y2="88.270393"
+ gradientUnits="userSpaceOnUse" />
+<linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_3_"
+ id="linearGradient2151"
+ x1="50.099098"
+ y1="75.943398"
+ x2="112.72990"
+ y2="138.57410"
+ gradientUnits="userSpaceOnUse" />
+<linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2152"
+ id="linearGradient2158"
+ x1="0.36138615"
+ y1="0.44000000"
+ x2="0.26732674"
+ y2="0.65333331"
+ spreadMethod="reflect" />
+</defs>
+ <sodipodi:namedview
+ id="base"
+ inkscape:zoom="12.109204"
+ inkscape:cx="16.778270"
+ inkscape:cy="29.415457"
+ inkscape:window-width="852"
+ inkscape:window-height="771"
+ inkscape:window-x="117"
+ inkscape:window-y="175" />
+ <metadata
+ id="metadata549">
+ <ns:sfw
+ id="sfw9">
+ <ns:slices
+ id="slices11">
+ <ns:slice
+ x="0"
+ y="0"
+ width="256"
+ height="256"
+ sliceID="124417176"
+ id="slice13" />
+
+
+
+ </ns:slices>
+
+
+
+ <ns:sliceSourceBounds
+ x="0"
+ y="0"
+ width="256"
+ height="256"
+ bottomLeftOrigin="true"
+ id="sliceSourceBounds16" />
+
+
+
+ <ns:optimizationSettings
+ id="optimizationSettings18">
+ <ns:targetSettings
+ fileFormat="PNG24Format"
+ targetSettingsID="0"
+ id="targetSettings20">
+ <ns:PNG24Format
+ transparency="true"
+ includeCaption="false"
+ interlaced="false"
+ noMatteColor="false"
+ matteColor="#FFFFFF"
+ filtered="false"
+ id="PNG24Format22" />
+
+
+
+ </ns:targetSettings>
+
+
+
+ </ns:optimizationSettings>
+
+
+
+ </ns:sfw>
+
+
+
+ <xpacket
+ id="xpacket27">begin='' id='W5M0MpCehiHzreSzNTczkc9d' </xpacket>
+
+
+
+ <x:xmpmeta
+ x:xmptk="XMP toolkit 3.0-29, framework 1.6"
+ id="xmpmeta30">
+
+ <metadata
+ id="metadata334">
+ <rdf:RDF
+ id="RDF32">
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f"
+ id="Description34">
+ <pdf:Producer
+ id="Producer36">
+Adobe PDF library 5.00</pdf:Producer>
+
+
+
+ </rdf:Description>
+
+
+
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f"
+ id="Description40" />
+
+
+
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f"
+ id="Description42" />
+
+
+
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f"
+ id="Description44">
+ <xap:CreateDate
+ id="CreateDate46">
+2004-01-26T11:58:28+02:00</xap:CreateDate>
+
+
+
+ <xap:ModifyDate
+ id="ModifyDate49">
+2004-03-28T20:44:56Z</xap:ModifyDate>
+
+
+
+ <xap:CreatorTool
+ id="CreatorTool52">
+Adobe Illustrator 10.0</xap:CreatorTool>
+
+
+
+ <xap:MetadataDate
+ id="MetadataDate55">
+2004-02-16T23:42:57+01:00</xap:MetadataDate>
+
+
+
+ <xap:Thumbnails
+ id="Thumbnails58">
+ <rdf:Alt
+ id="Alt60">
+ <rdf:li
+ rdf:parseType="Resource"
+ id="li62">
+ <xapGImg:format
+ id="format64">
+JPEG</xapGImg:format>
+
+
+
+ <xapGImg:width
+ id="width67">
+256</xapGImg:width>
+
+
+
+ <xapGImg:height
+ id="height70">
+256</xapGImg:height>
+
+
+
+ <xapGImg:image
+ id="image73">
+/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
+AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
+DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
+Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER
+AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
+AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
+UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
+1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
+qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
+obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
+0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
++DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7
+FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqlvmDzFo
+3l7TJdT1e5W1tItuTbszHoiKN2Y+AxV4j5g/5ydvTcMnl/SYlgU0Se/LOzDxMcTIF/4M4qk//QzP
+nv8A5YNL/wCRVx/2UYq7/oZnz3/ywaX/AMirj/soxV3/AEMz57/5YNL/AORVx/2UYq7/AKGZ89/8
+sGl/8irj/soxV3/QzPnv/lg0v/kVcf8AZRirv+hmfPf/ACwaX/yKuP8AsoxV3/QzPnv/AJYNL/5F
+XH/ZRirv+hmfPf8AywaX/wAirj/soxV3/QzPnv8A5YNL/wCRVx/2UYq7/oZnz3/ywaX/AMirj/so
+xV3/AEMz57/5YNL/AORVx/2UYq7/AKGZ89/8sGl/8irj/soxV3/QzPnv/lg0v/kVcf8AZRirv+hm
+fPf/ACwaX/yKuP8AsoxV3/QzPnv/AJYNL/5FXH/ZRirv+hmfPf8AywaX/wAirj/soxV3/QzPnv8A
+5YNL/wCRVx/2UYq7/oZnz3/ywaX/AMirj/soxV3/AEMz57/5YNL/AORVx/2UYq7/AKGZ89/8sGl/
+8irj/soxV3/QzPnv/lg0v/kVcf8AZRirv+hmfPf/ACwaX/yKuP8AsoxVFad/zk75oS4B1HSbG4t+
+6W/qwP8A8E7zj/hcVeyeRfzJ8tec7Vn0yUx3kQBuLCaizJ25AAkMlf2l+mmKsqxV2KuxV2KuxV2K
+vm/XDqf5ufmk+j287Q+XtJLqJF3VIY2CSzAHYvM9AvtTwOKvePLfk/y35bs0tdHsYrZVFGlCgyuf
+GSQ/Ex+ZxVOK4q6oxVrkMVdyGKu5jFWvUGKu9RffFWvVX3xV3rL74q71l8DirXrp4HFXfWE8DirX
+1hPA4q76yngcVd9Zj8D+GKtfWo/A/hirvrcfgfw/rirvrcfgfw/rirX1yLwb8P64q765F4N+H9cV
+d9di8G/D+uKtfXovBvw/riqVa/5X8r+abR7TV7GO55CiyMoWZP8AKjkHxKR7HFXzB5n0XXfys8/R
+NZXBJgIudOujsJYGJUpIB8ijj+oxV9VeWtfs/MGhWWsWf9xexLKErUoxHxI3up2OKplirsVdirsV
+Q+oMy2Fyy/aWJyvzCnFXhP8AziwqvL5nmYcpQLIBz1oxuC2/uVGKvficVaxVrFWicVaJxVrFWsVa
+JxVonFWsVaxVrFWicVaxVrFWicVaJxVrFWsVaJxVonFWsVaxVdCSJkp/MP14q8V/5ypRBJ5ZkCjm
+wvVZu5CmAgfRyOKsn/5x3vJX8lwWzElQZmSvbjMR/wAbYq9XxV2KuxV2KofUv+Oddf8AGGT/AIic
+VeE/84pn/lKP+jD/ALGcVe+nFWsVaJxVonFWsVaxVonFWicVaxVrFWsVaJxVrFWsVaJxVonFWsVa
+xVonFWicVaxVrFWicVXQ/wB9H/rD9eKvFv8AnKw/8ov/ANH/AP2LYqn/APzjn/yisHyuP+T4xV6/
+irsVdirsVQ+pf8c66/4wyf8AETirwf8A5xRNf8U/9GH/AGM4q9+PXFWicVaJxVrFWsVaJxVonFWs
+VaxVrFWicVaxVrFWicVaJxVrFWsVaJxVonFWsVaxVonFWicVXQ/30f8ArD9eKvFf+crjT/C3/R//
+ANi2Ksg/5xy/5RS3+Vx/yfGKvYMVdirsVdiqH1L/AI511/xhk/4icVeDf84nmv8Ain/ow/7GcVe/
+HrirROKtYq1irROKtE4q1irWKtYq0TirWKtYq0TirROKtYq1irROKtE4q1irWKtE4q0TirWKroP7
++P8A1h+vFXiv/OWBp/hb/o//AOxbFWQf844f8onb/K4/5PjFXsOKuxV2KuxVD6l/xzrr/jDJ/wAR
+OKvBP+cTD/ylX/Rh/wBjOKvf2O5xVrFWsVaJxVazAAkmgG5JxV4p+ZX/ADkRY6bK+ieTEXVtZc+k
+bxQZII3O1Igv9+/hT4fn0zEy6oDaO5eh7P7ClP15fTHu6n9X3sL0n8/fzM8tanFF5zgF9Z3FGDGK
+KKRV2r6bQBI2pUVU7jKseqkD6t3P1fYOKcf3Xpl8aPz3e/8AlLzv5d816et7pF0sykfHFWjoe4Ze
+uZ0ZCQsPKZsE8UuGYop6TkmprFWsVaJxVonFWsVaxVonFWJebvzD0vQg9tBS71MbCBT8MZ/4tYdP
+9Xr8swNVr44thvL8c3c9ndjZNR6j6cff3+79bB/8b/mFasNRuqm0kNTC0aBVFdtgOa+ALZocfbkj
+kI4hIjmPx+O96GXY2jnHgjtLvs/2FnXlfz7pmtIscjC3vOhRjQE+1c6PTayGYek79zyuu7My6Y+o
+enoejJycynXtE4q1irWKroD+/j/1l/XirxT/AJyzP/KK/wDR/wD9i2Ksh/5xv/5RK3+Vx/yfxV7F
+irsVdirsVQ+pf8c66/4wyf8AETirwL/nEo/8pV/0Yf8AYzir6AbqcVaxVonFUl81+cPLvlXTG1HX
+LxLW3FRGp3klcCvCNB8TN8vp2yE5iIsuRptLkzS4YCy+cfNX5lee/wA0bmXStCibSfLAJWck0LqP
++WiVepP++k+mtK5r8ueU9hsHsdD2Vi03ql6sn3e79aZ+WfJOj+XYq26+vesoEt7IPjO24QbhFPgP
+pJplDtLJ5o/UtPstQtXtb2FZ7eT7UbjbwqCNwRXYjcYGyred3XlrzP5N1D9N+UbqVo4yC8A3lC9w
+yjaVfl8Q+jlk8eQxNhxdVpIZY8MxY7+57F+WH/OQmjeYRFpuvFdP1c0VXJ/dSn/JPY+2bHFnEve8
+dr+yZ4Nx6od/d73sCurqHUhlYVDA1BGXupcTirROKtYq1iqheXtpZ2z3N3MkFvGKvK5CqPvyMpiI
+s7BnjxSnIRiLJeY6/wDmHq2uXDaV5XjeOI1El39mRl6VBP8Adr7nf5Zz3aHbEYRNHhj3/q/FvW6L
+sXHgHiag2e7p+0/Yo6N5StdNpPcEXN9sfUP2Ebr8APev7R/DPP8AXdszy+mHpj9p/U5mbWHJsNop
+lMKgg9Dsc1cJEGw1xYxqXl1RL9Z05vQnBJ9IbKT/AJJ/Z+XT5Zv9H2rIEcRo/wA52OPUCUeDIOKJ
+/HxTnyz+Y15YuLDWlZkWi822dfv/AI522h7bjKo5f9N0+Lou0fZ3bxNPvH+b+r9XN6TZ31reQLPb
+SCWNu47HwI7HOhBBFh5SUSDR5q2FDROKr4P7+P8A1l/XirxL/nLU/wDKK/8AR/8A9i2Ksi/5xt/5
+RG2+Vz/yfxV7HirsVdirsVQ+pf8AHOuv+MMn/ETirwH/AJxINf8AFf8A27/+xnFX0C32j88VWk4q
+8o/ND8/NB8qerpmj8NW8wCqGJTWCB+n751+0wP7CmviVzGzakR2G5d32d2LPPUp+nH9p9363kln5
+N81ectUPmHz5dTEsR6Vix4OUG/DiKCCP/JA5deh3OCbkbk9VjGPDHgxCh+Pm9AtrK0srWO1tIlgt
+4RxjiQUUD6PxwMgskyJbYoaTAW2KHfrkW0MT81fl/putcrq2IstTNW9ZR8EjHf8AeqO9f2hv41yQ
+k1Tw3yd5L/OTzj5Cvk0XzTFJeaWNo5GPJwn88cn+7F/Ed99szMWoI2O4eZ1/Y0ZXLH6Zd3T9n3Pp
+Hyz5t0HzLpyX+j3SXELipCn4lPgw6jM4SBFh5jJilCXDIUU3wtbWKsd81+eNH8vRFZm9e+IrHZxk
+czXoXP7C+5+iuYuo1cMQ33Pc7LQdl5dSdtofzv1d7z0WfmfztcLfarKbTSlNYYlBCkf8VIeu37bf
+j0ziO2PaCMDRPFP+aOnv/FvUx8DRR4cY4p9T+v8AUyuy0qx021FtZxCOMfaP7TH+Zj3OcLqdZkzy
+4pn9QcCeaWSVyK2XK4tkUFLl0W+KCly6LkRQV7p9tex8Jl3H2JBsy/I/wzLw6mWP3dzfiyygbCX2
+V9rnlmcSwSGS0ruR9kjwZe3+dDnS9m9tTxfT6ofzT+NvuXV9n4NcL+jL3/jn970fy3510zWkVOQh
+u9uUTHqT4V/V+vO30mux6iNwO/d1DxGu7NzaWVTG3Q9CyEnMxwF8H9/H/rr+vFXiX/OW5p/hT/t4
+f9i2Ksj/AOca/wDlD7b5XP8AyfxV7HirsVdirsVQ+pf8c66/4wyf8ROKvn//AJxGNf8AFf8A27/+
+xnFXvWp6hZ6dZXN/eyrBZ2qPNcTP9lUQVZj9AwE0LLOEDOQjEWS+b/OP5y+b/P17J5e8iwS2OlMe
+Fzfn4JnjPVpJBtBGadAeTdO/HNfk1BntHk9houxseAceb1T7un7fu+9FeTfyy0jy6Eu7il9q9Km5
+cfBGTufRU9P9Y/F8q0yoRpz8mcz9zKpMSiKGkyJbYoeTIluihpMBbYoZ+uRbQtwJQup6Xp+p2jWl
+/AtxA2/FhuD05KRup36jCDTGcBLmwF9G84eQb8615Vu5JrJPjmi6sqr/AL9jFA6gftrQjfYDMjHl
+I5Op1ugjkFTF+fc94/Kf86LDzpbG3uoTaarBxWZRujFq0YH3pmwxZBIPG63RSwSo7g8iq+afzHvZ
+71tD8rxNNdljE92BU8hswiHTbu7bfrzVa7tSOMGjQHORd12f2LER8XOajzr9f6v7FLy7+XccMn6R
+15/ruoSHmYWPONWJrVyf7xvw+fXPNO1PaSWQmOHYfzup93d7+fucrVdqEjgxemH4+TLJRnMg3zdd
+FBS5dFvigpcui5EUHLl0XIigpcui5EVLJs2iAQQRUEUIO4IPY4YyINhUi1Dy/NHJ9a0pzFMu/o1o
+D/qk/qO36s22j7RMZA3wy7/x/Y5g1EckeDKOKJT7yh+ZVyLhdL1mNvUX4RIdnBHYg7/fnfdmdq+M
+eCf1d/e8t2z2GMEfFxG8f3X94en2ciSSQyIao7KVPsSM3bzTxP8A5y5NP8Kf9vD/ALFsVZJ/zjV/
+yh1t8rn/AKiMVeyYq7FXYq7FUPqX/HOuv+MMn/ETir59/wCcQz/yln/bv/7GcVeofnOf+QY+ZP8A
+mEb/AIkMqz/QXYdlf4zD3vl78v8AznqOgW4SMCaxd2Mts1BU/wAysBUNmglnMJeT63h7Kx6nBZ2n
+vv8ArezaJ5k0rXLb1rKWrqP3sDbSIf8AKX+I2zMx5YzGzzmr0GXTyqY9x6FGSZItEUNJkS2xQ0mA
+tsUNJkS3RQ75FtCzAlSubq3tYGnuJFihTdnY0GJLKMSTQYD5i8+XFzyttLLQW/RrjpI/+r/KPx+W
+UyydzsMOkA3kiP8AnHkk+YdRJ68Y/wBb5uNL1fOu3/4feXovk69ubPVNQlgbi3IVHUEcm2Oed+0U
+RMRB5WXo9XhjPHESelabrtteqI3/AHVx/Ieh/wBU/wAM4jNpTDcbh5zPo5Y9xvFES5VFqig5cui5
+EUFLl0XIigpcvi3xQcuXRciKjk2xokAVOwHU4qld9rIWsdtuehk7fRmVj0/WTm4dL1kxa2kZ/NkR
+YlmLCpO5/u863sEfvYfH7i1duitDOv6P+6D6C0A/6LZf7H/iWdy+avHP+cvD/wAon/28P+xbFWS/
+840f8oba/K5/6iMVey4q7FXYq7FUPqX/ABzrr/jDJ/xE4q+fP+cQT/yln/bv/wCxnFXqH5z/APks
+fMv/ADCN/wASGVZ/oLsOyv8AGYe98faP/vEP9Y5zOo+p9u7I/uPiU0s7y6s7hLm1laGeM1WRDQjK
+oyINh2GXFHJHhkLBekeW/wAx7e8C2ur8be56LcjaJz/lfyH8Plmfi1QO0nk9f2FLH6sXqj3dR+v7
+2XOQRUGoPQjMl0YQ8mAtsUNJkS2xQz5FuCR6/wCadO0dCrn1rsiqW6nf5sf2RkJSAcjFglP3PN9Z
+17UdWn9S6k+AH93AuyJ8h4++UykS7TFhjAbJeiO7BUBZj0AyIDXqtXi0+M5MshCEeZLJ/wAun1ry
+xPdX1nAt1MyB7hODukcaVNWKEU+1uembCOp4OT4F217VfmMlYI3CN7m9/h0HvZn5N8zWkt9cpdFb
+eWehjqfhJqSRU9Oucj27pZmIlHcC3tey/ajT66EY/RlH8J/R3s7B7j6DnKu8Taw16VAIrqskfQSf
+tD5+OYmXTA7x2Lg5tGDvHYpoZY5UDxsGQ9CMxeEg0XD4SDRQsuWxbooKXLouRFBS5dFyIoO5u4bd
+OUjU8FHU/LL4YzLk348ZkdkivdRmuSV+xF2QfxzOx4hH3uyxYBD3oTLW9KbRv+dwiH+UP+TWdJ2E
+P3sP877i6vt7/EZ/5v8Aug+h9A/3lsv9j/xLO2fNXjn/ADl8f+UT/wC3h/2LYqyX/nGf/lDLX5XP
+/URir2bFXYq7FXYqh9S/4511/wAYZP8AiJxV89f84fmv+Lf+3f8A9jWKvUfzo/8AJY+Zf+YVv+JD
+Ks/0Fz+y/wDGYe98f6N/vEP9Y5zWo+p9u7H/ALj4lHZQ7V2Ksi8u+dNR0njBJW5sf98sfiQf8Vt2
++XTL8Wcx26Oq13ZWPP6h6Z9/f73ounaxp+qW/r2cocftodnU+DL2zOjMSFh5XPpcmGXDMUuuJY4o
+2klcJGgq7sQAAO5JwljEW898y/mByLW2jnbo94R/ybB/Wf7colk7na4NH1l8mDu7yOzyMXdjVmY1
+JJ7knKXYAUrWtjNcGo+GPu56fR45KMbeW9ova3S9mRqR483SA5/5380fb3AvQ/J/5a3l+iXNwrWe
+nNQ+qw/ezA7/ALsHt/lHbwrlebURx7Dcvh/avbGr7UyceolUB9MR9I9w/wB8d3pdrpdhpdqtrYwi
+GJdzT7TN/MzHdj881OTLKZsuJGIiKDDvM/kmyvma6sCLO9rUgbROfcD7J91+6prmVh1dbS3DCWLf
+ijtJItI85avoNyNO1qJzEvTluyitKqw2ZduozD1vZEMo48ex+x6zsf2qnirHqd4/zuvx7/e9E07U
+7HUbdbi0lWWNvA7j5jOWzYZY5VIUX0LDnhliJQNxKPt7qa3asbbHqp6HMeUBLmmeMS5pnFexXAoP
+hfup/hmNLEYuJLEY+5TmyUWcWP6nrUURMdvSSTu37I/rmww6YneTs9PpCd5bBIJZZJXLyMWY9zme
+AAKDs4xAFBZhZOxVJLVv+d2iH+UP+TOdN2EPXD/O/S6vt7/EZ/5v+6D6M0D/AHlsv9j/AMSztHzV
+41/zmAaf4S/7eH/YrirJv+cZf+ULtPlc/wDURir2fFXYq7FXYqh9S/4511/xhk/4icVfPH/OHpr/
+AIt/7d3/AGNYq9S/Oj/yWPmX/mFb/iQyrP8AQXP7L/xiHvfH+i/7wj/WOc1qPqfbuxv7j4lH5Q7V
+2KuxVXsr67sbhbi0laGVejL3HgR0I9jhjIg2GrLhhkjwyFh3mHzTq+rv6dzIEgSgEEdVQkftEdz8
+8yjkMhu6SOkhikRFJlUsQqipOwAyKcuWOOJlMiMRuSdgE80TyxfahdxW8MD3FzKaR20Yqfmx7Ad+
+w75aIVuXyP2j/wCCHKZODQe45P8AiB/vj8B1e1+UvypsdMRLvWlS7vQKpajeCLwqCPjb5/D89jmH
+qdSaqL5sNOSTPIeOZ53v/aWXXI65qm5KrkdcVSq5HXFUm1PSrDU7c297EJE34N0ZCf2kbsdv65bj
+yygdkEA82C3uleYvKVyb/TJWuNPBq5ArxHWkqDt/lDbxpWmZOSGLUxqQ3c3s/tHPo5XjPp6jp+PN
+mflbz/pesqsMrC2vabxsaBj/AJJzmdb2Vkw7jeL6R2X25h1YoemfcWVA03Gat3SW67qN38FuHpGy
+1amxO/c5k6bFHnW7l6PBH6q3SPM12LsVdirsVY/at/zvkQ/yh/yYzqOwh6of536XV9vf4jP/ADf9
+0H0hoH+8tl/sf+JZ2T5q8Z/5zCNP8Jf9vH/sVxVlH/OMf/KFWnyuf+ojFXs+KuxV2KuxVD6l/wAc
+66/4wyf8ROKvnf8A5w6P/KXf9u7/ALGsVep/nOrN+WXmYKCx+qOSBvsGBJ+gZVm+gud2Yf8ACIe9
+8e6HLGbT0ww5qxJXvQ5zepieK32vsTLE4uG/UCdkxzHdy7FXYq7FULHZzXNw6xjYH4mPQZk44kh4
+v2j9otL2ZEzzH1G+GI+qXu/STs9D8hflZquvOssKfV9PH97qUq7GhoViX9s9em3icyoYnwntj2g1
+vbM/WfD0/SA5fH+cfPkOlPddA8paJ5cszb6bDR2/vrl6NNIR/M1Bt7Db2yvM4WPBHGKiiZ81OZjN
+LLkdcw2pKrkdcVSq5HXFUAeuKuBINR1wqw3zJ+X1tc8r3RiLO9X4hAvwxOwNfhp/dt8vh6dNzmdh
+1Y+me4TEmJsGiEH5f/MTVNGuv0T5jicemQvqMKOvgT2K+BG2Ymu7DjkHHh59z2fZPtMRUM/+m/X+
+tmupXdvdmGe3cPGyVBHzOc/hxmFg830jQzEoWEFlznOxV2KtO6RoXdgqKKszGgA9ycQCdgrGNInW
++8+RTWtZIuVeQB6CLhX5cs63sXGYyiDz3/S6vt81opg/0f8AdB9L6BX6tZf7D9eda+avGf8AnMU/
+8oj/ANvH/sVxVlH/ADjF/wAoTafK6/6iMVe0Yq7FXYq7FUPqX/HOuv8AjDJ/xE4q+df+cOD/AMpf
+/wBu7/saxV9CXUMM6SwzossMoZJInAZWVtmVlOxBHUYpBINh88/mb/zjY6vJrHkQ8HFXl0Z2p8/q
+0jH/AIRj8j0GYWbSg8vk9N2d29KJAyGiOUh+l4nHqVxbXUljqsL2t3CxjlWRSjK67FXU0KnNPl0p
+HJ9I7P7djMAZD/ndD+PkmQIIqNwehzDeiBt2KXYqmnlfib6BXUOrXiBkYAqRyXYg9RmXGRGMkdz8
+5f8ABSF9rY/+FR/6aTfS/lzzbp9xFFZTollKihIlUBYSAKAJ2X5YdN2hGe0tpfY81izA7ck9nyzM
+yml8+anM400tuR1zCakpuR1xVKrkdcVS9upxVrFULqGp2lhF6lw9CfsIN2b5DLsWCWQ0GrLljAWX
+mnn3WJdStI3dFRI5QIRQFlDK1fjpXegr2ze6TAMewaNNqDkme5lXlsk6ba1P+6E/jnJa4fvJf1i+
+8ez/APi8f6o+5Nsw3fOxVBalq1np8fKZqufsRL9o/wBnvl2HBLIdkiNpPYaX5j84XIWJTBYcqBqH
+h1psP22zpOz+yr5fN1/aHa2HSDf1T/m/r7g9k8m/lrpWhwBmj5TNu7Nu7f6zD9QzqcGmhiFReA1/
+aWXVSuZ26DoGdWoC3EIAoA6gAfMZe694b/zmOf8AlEP+3j/2K4qyn/nGD/lB7P5XX/UTir2nFXYq
+7FXYqh9S/wCOddf8YZP+InFXzn/zhsa/4v8A+3d/2NYq+iJP7xvmcVWE4qwf8xvyk8q+ebUm9i+q
+asq0t9VgUeqtOiyDYSJ/kt9BGVZMQk52j1+TAdt49z5d85eRPOX5eXwg1SD6xpcjEW1/FVoJPYNT
+92/+Q34jfNXqNJ3/ADe97H9oqFRNx6xPT3fikHaXtvdJyhapH2lOzD5jNVkxmJ3e80mtx543A/Dq
+FfIOWmPlg01K2H/L5H/xJcyT/dH3H7n50/4KA/12h/wqP+7m9ZzRvGJ/o3my7swsFzWe1Gwr9tB7
+E9R7HMvFqpRFHcNkchGxZTHeW15CJreQSIe46g+BHbJZJAiwmRtCXPfMJqSm574qlVz3xVLm6nFW
+P6x5pgtuUNnSacbM/wCwv9Tmw0+iMt5bBws+sEdo7liVxcT3EplncySN1Y5tYxERQ5OslIyNlJPM
+5ppif8Zl/wCIPl+Eer4Od2d9Z9zO/LP/ABzLX/mHj/jnFa/+8l/WL797P/4vH+qPuTckAVOwHU5h
+O+SDVPMtH+q6avr3DHiHUchX/JA+0c2Gm0BkfV8mVAC5Ggnvk/8AKvUNVuBfayS1TyMTGo/56N/x
+qP1Z1+j7KEQDP5freS7U9pecNP8A6b9X6/7Xs+k6HYaXAsVtGAVHEMABQdKAdhm6AAFB46UjI2TZ
+KYYWKpa/70xf66/rxV4X/wA5kmn+EP8At4/9iuKsq/5xf/5Qaz+V1/1E4q9qxV2KuxV2KofUv+Od
+df8AGGT/AIicVfOX/OGhr/jD/t3f9jWKvoiT+8b5n9eKrCcVaxVDahp9jqNnLZX9vHdWc6lJreZQ
+6Mp7FTtgItlGZibBovnL8zP+cb77Tnl1ryKzzwrV5NHY1mQdT6DH+8X/ACG+L3bMPNpQRtyel7O7
+dlCQ4jwy/nD9P4p5HaazSVrW/Q291GxRw4K/EDQhgd1PzzTZtKRvF9J7O7ehkqOX0y7+h/V9zI/L
+TD9K2o/5fI/+JLkD/dH3H7nxj/gn/wDGrD/hUf8AdzeuZpHinYqr2l7c2kvqW7lG7jsR4Ed8INKy
+Oz12C8UJJSK4/l/ZP+qf4Yqtue+BUi1a/tLKEzXMgjToK9SfADucsx45TNBhPIIiy8+1nzNc3xaK
+GsNqdiv7TD/KP8M3Gn0kYbneTq8+qM9hsElzLcR2KpP5qNNMT/jMv/EHzI0w9Xwdj2b9Z9zMtC1G
+zttFtZpZRw+roAAakkVqAPHOM1mGUs0gB/EX3/2fifAH9UfcsiGueZ7g21jGYrQGjtuF/wBm3c+w
+zYaDssyOws9/QOz1uvw6WNzO/QdT+O96v5J/K2w0pFuLpedwQOTsPjPy/lH451um0cMQ23l3vAdp
+dsZdUaPph/NH6e96DHHHEgjjUIi9FGwzLdS3irWKqlr/AL1Q/wCuv68VeF/85lmn+D/+3j/2K4qy
+r/nF3/lBbP5XX/UTir2vFXYq7FXYqh9S/wCOddf8YZP+InFXzh/zhia/4w/7dv8A2NYq+iZT+8b5
+n9eKrMVaxVonFWicVee/mX+S3lbzxG1zIv6O1wLSLU4VBLU6CdPhEo+kMOxplWTEJe9ztJr54duc
+e54Zc/l9f+Q/M+m6Pe3kd7LcSQXaywhlUK8vphSG3r+6zTa+HCCP6P63mPabVDPq4Sr+AD/ZSei5
+zLrHYq7FXYqu1HzFdafpU0xUTtGB6fM03Zgu/jSuXYMYnMRLVmycESXm2oale6hcG4u5DJIeg7KP
+BR2Gb7HjjAUHSzyGRsobJsHYq7FUl82mmlp/xnX/AIg+ZWkHr+H6nZdmfWfc9H/L38n/ANKWFvey
+X4Ns8ccpt+JQ/EK05gt+rBPswSnxSOz67pfaKWLTiEI+rhAv9j23QfLGm6PbpHBEoZBtQAAfIfxz
+ZQgIigKDosuaeSRlM3IpuTkmtrFWsVaxVUtT/pUP+uv6xirwr/nM40/wf/28v+xXFWV/84uf8oJZ
+fK6/6icVe2Yq7FXYq7FUPqX/ABzrr/jDJ/xE4q+b/wDnC81/xj/27f8AsaxV9Ey/3j/M/rxVZirR
+OKtE4q1irWKvA/zvdV/M7QyxAUW1qSTsAPrcuaXtTr/V/W832t/fx/qj7yjs5Vx3Yq7FXYqlfmf/
+AI4dz/sP+Ti5laP+9Hx+5xtX/dn8dWB5vXTOxV2KuxVIvOEiDTY4yw5tMrBa7kBWBNPpzN0MSZn3
+O07LieInpT6T/KIEeWbSop/o0P8AxHNiXt8f0j3M7JwM2sVaxVrFWicVVLX/AHqh/wBdf1jFXhX/
+ADmgaf4O/wC3l/2K4qyz/nFr/lA7L5XX/UScVe2Yq7FXYq7FUPqX/HOuv+MMn/ETir5t/wCcLTX/
+ABj/ANu3/saxV9FS/wB6/wDrH9eKrCcVaJxVrFWsVaJxVhn5iflppPnK2RpJDaapbqVtbxRyHEmv
+CRduS1+kfrx9RpxkHm4Ws0Ucw7pDq8Ru5vN3kK+XTPMNs09gdre4Q8lZR3hkNOVB+w1CPbOc1egI
+PcfsLoMmGeI1IMq03VLDUrYXFlMs0R2JHVT4MDuD881M4GJooBRWQS7FUr8z/wDHDuf9h/ycXMrR
+/wB6Pj9zjav+7P46sDzeumdirsVSTUvMSrILTTk+tXbnipUclDE0AUD7bfLb9WZuDSGW8tg7XS9n
+GW8/kzf8v/yO1PWLlNU8zcuJIf6oT93qn/jQZshURUXqNPohEC/k+iNK0q10y1FvbigAAJ6dOgA8
+Mi7FGYq1irWKtE4q1iqpa/71Q/66/rGKvCf+c0jT/B3/AG8v+xXFWW/84sf8oFY/K6/6iTir23FX
+Yq7FXYqh9S/4511/xhk/4icVfNf/ADhWf+Uy/wC3b/2N4q+i5T+9f/WP68VWE4q1irWKtE4q0Tir
+WKoLVtI0zV7GSw1O2ju7SUUeGQVHzHcEdiNxkZQEhRYThGQoiw8H85fk75j8qXL635NllvLJamay
++1PGvUjiNpk+jkPA9c1Wp7PBG24dLqOzzDeG4QHlnz7p+qlbW7pZ6iaL6bGiSN0+AnvX9k/jnP6j
+RShuN4uAynMJUr8z/wDHDuf9h/ycXMrR/wB6Pj9zjav+7P46sDzeumUbu8t7SEzTuEQdK9SfADuc
+nCBkaDbiwyyGohK9PsvMnnG8Njo8DR2YNJpmqFAP+/GH/ER+ObPDphDc7l6HQ9m0b5nve9/lz+S+
+keXo0urpfXvyPjncfHv1CD9hfxzIJehxYIw9706OOOJBHGoVF2CjYYG9vFWsVaxVonFWsVaxVUtP
+964f+Mi/rGKvCP8AnNQ/8ob/ANvL/sUxVl3/ADiv/wAoDY/K6/6ijir27FXYq7FXYqh9S/4511/x
+hk/4icVfNP8AzhQa/wCMv+3b/wBjeKvoyY/vX/1j+vFVmKtYq0TirROKtYq1irROKtE4q84/Mb8l
+tA81iS+s+Oma4RX6yg/dTN/xcg7/AOWu/jXplOTCJb9XD1Gijk3G0njv6c82+R9RGjebrSV4P903
+P2iU/mjk6Sr9NR+GaTV9lCW8fTL7C6bLglA0WS6vqNjqPlma6splnt34cXX/AIyLsR1B8Qd81Onx
+ShmEZCjv9zgasfuz+OrzbVdft7ImGIevdbjgPsqf8oj9Q/DOiw6cz35BxNNoZT3ltFkXkj8n/MHm
+m6TUNe5wWhoVt/syMvv/AL7X8TmzhAQFB6nS9niI3FDufRXlvylo+g2cdvZQJGIxRQq0A+Q8fc75
+J2sYgCgnROKWsVaxVrFWicVaxVrFWsVVLQ/6XD/xkX9YxV4P/wA5rmn+Df8At5f9imKsv/5xV/8A
+Jf2Pyu/+oo4q9vxV2KuxV2KofUv+Oddf8YZP+InFXzR/zhMa/wCM/wDt2/8AY3ir6Nm/vX/1j+vF
+VPFWicVaJxVrFWsVaJxVonFWsVaxVLPMHlzRPMOnPp2sWiXdq/7Lj4lb+ZGFGRvdTgIthPGJCi8G
+8x/849ecNOvZ08pX4n0m7oHhml9GVQCCBJQcHp2Yb+3jVLBEkEi6dZl7PJO2482T/l1+Q9norpe6
+xxuNQXfmaFUPhGu//BHLnNwaWMNzuXrtvbw28QihQIg7D+OLkrycVaxVrFWsVaJxVrFWsVaxVonF
+VW0/3rg/4yL/AMSGKvBv+c2TT/Bn/by/7FMVZf8A84qf+S+sPld/9RRxV7hirsVdirsVQ+pf8c66
+/wCMMn/ETir5m/5wkP8Aymf/AG7P+xvFX0dN/fP/AKx/XiqmTirROKtYq1irROKtE4q1irWKtE4q
+1irWKtYq0TirWKtYq1irROKtYq1irWKtE4q1iqrZ/wC9cH/GRf8AiQxV4L/zm2f+UM/7ef8A2KYq
+zD/nFL/yXth8rv8A6ijir3HFXYq7FXYqh9S/4511/wAYZP8AiJxV8y/84RH/AJTT/t2f9jeKvo6c
+/vn/ANY/rxVTJxVrFWsVaJxVonFWsVaxVonFWsVaxVrFWicVaxVrFWsVaJxVrFWsVaxVonFWsVax
+VVs/97IP+Mi/8SGKvBf+c3T/AMoX/wBvP/sUxVmP/OKH/kvLD5Xf/UUcVe44q7FXYq7FUPqX/HOu
+v+MMn/ETir5j/wCcHzX/ABp/27P+xvFX0fOf30n+sf14qp4q1irROKtE4q1irWKtE4q1irWKtYq0
+TirWKtYq1irROKtYq1irWKtE4q1irWKtYqq2Z/0yD/jIn/EhirwT/nOA0/wX/wBvP/sUxVmX/OJ/
+/ku9P+V3/wBRRxV7lirsVdirsVQ+pf8AHOuv+MMn/ETir5g/5wgkVJ/Olu54zkacwjOzUQ3Qbb2L
+CuKvpG4qJpK/zH9eKqeKtE4q0TirWKtYq0TirWKtYq1irROKtYq1irWKtE4q1irWKtYq0TirWKtY
+q1irROKq1iCbyAAVPNT9xrirwD/nOGaMy+TIgwMiLqTsncKxtQp+nicVZt/zieGH5dafUEHjdnfw
+N0SMVe5Yq7FXYq7FVskayRtG32XBVvkRTFXxjrN7rf5Efnjca1FbNP5e1ZpDLAtFWW2mcPLGldg8
+MlGT2p2JxV9U+U/PHknzvp8d/wCX9UhvA61eFHC3EZ7rLCfjQj3Hy2xVPP0dF/M34Yq79GxfzN+G
+KtfoyL+dvwxV36Mi/nb8MVd+i4f52/DFWv0VD/O34Yq79FQ/zt+H9MVa/RMP87fhirv0TD/O34Yq
+79EQfzt+H9MVa/Q8H87fh/TFXfoeD+dvw/pirv0NB/O34f0xVr9Cwfzt+H9MVd+hYP8Afj/h/TFW
+v0Jb/wC/H/D+mKu/Qdv/AL8f8P6Yq1+g7f8A34/4f0xV36Ct/wDfj/h/TFXfoK3/AN+P+H9MVa/Q
+Nv8A78f8P6Yq79AW3+/H/D+mKpN5n84eRPIlhLqGvanDacVJSKRw1xJ4LFCvxuT7D57Yq+IvzF87
+a9+cH5kLcWtu0ccvG00myJr6NshLcpCNqmrO5+joBir7H/J7y5HoWhW1jAP3NpbpEGIoWJp8R924
+VPzxV6FirsVdirsVdirE/wAxvy38v+etDk0zVYlL0rBPSrI46Ed/uxV8j+b/APnFvzbpN66WEyyw
+En0zMGK8faSMNX6UGKsd/wChfPP3ja/8FP8A9UsVd/0L55+8bX/gp/8Aqlirv+hfPP3ja/8ABT/9
+UsVd/wBC+efvG1/4Kf8A6pYq7/oXzz942v8AwU//AFSxV3/Qvnn7xtf+Cn/6pYq7/oXzz942v/BT
+/wDVLFXf9C+efvG1/wCCn/6pYq7/AKF88/eNr/wU/wD1SxV3/Qvnn7xtf+Cn/wCqWKu/6F88/eNr
+/wAFP/1SxV3/AEL55+8bX/gp/wDqlirv+hfPP3ja/wDBT/8AVLFXf9C+efvG1/4Kf/qlirv+hfPP
+3ja/8FP/ANUsVd/0L55+8bX/AIKf/qlirv8AoXzz942v/BT/APVLFXf9C+efvG1/4Kf/AKpYq7/o
+Xzz942v/AAU//VLFXf8AQvnn7xtf+Cn/AOqWKu/6F88/eNr/AMFP/wBUsVd/0L55+8bX/gp/+qWK
+ovTP+cc/OVxcBLueCCLu8Ylkb/gWWP8AXir3r8rPyT0zy4P9FhM97IB691LQuR1oxAoif5I698Ve
+76bYR2NqsKbnq7eLHviqKxV2KuxV2KuxV2KrZIo5VKSIHQ9VYAj8cVQp0bSyf95k+7FXfobS/wDl
+mT8cVd+htL/5Zk/HFXfobS/+WZPxxV36G0v/AJZk/HFXfobS/wDlmT8cVd+htL/5Zk/HFXfobS/+
+WZPxxV36G0v/AJZk/HFXfobS/wDlmT8cVd+htL/5Zk/HFXfobS/+WZPxxV36G0v/AJZk/HFXfobS
+/wDlmT8cVd+htL/5Zk/HFXfobS/+WZPxxV36G0v/AJZk/HFXfobS/wDlmT8cVd+htL/5Zk/HFXfo
+bS/+WZPxxV36G0v/AJZk/HFXfobS/wDlmT8cVcNG0sH/AHmT7sVRUcUcShI0CIOiqAB+GKrsVdir
+sVf/2Q==</xapGImg:image>
+
+
+
+ </rdf:li>
+
+
+
+ </rdf:Alt>
+
+
+
+ </xap:Thumbnails>
+
+
+
+ </rdf:Description>
+
+
+
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f"
+ id="Description80">
+ <xapMM:DocumentID
+ id="DocumentID82">
+uuid:ef18cd8d-b4e0-42e1-badd-bdf8b8440881</xapMM:DocumentID>
+
+
+
+ </rdf:Description>
+
+
+
+ <rdf:Description
+ rdf:about="uuid:726872f6-5367-4b00-9d2b-f84f92608d1f"
+ id="Description86">
+ <dc:format
+ id="format88">
+image/svg+xml</dc:format>
+
+
+
+ <dc:title
+ id="title91">
+ <rdf:Alt
+ id="Alt93">
+ <rdf:li
+ xml:lang="x-default"
+ id="li95">
+mime.ai</rdf:li>
+
+
+
+ </rdf:Alt>
+
+
+
+ </dc:title>
+
+
+
+ </rdf:Description>
+
+
+
+ <cc:Work
+ rdf:about=""
+ id="Work404">
+ <dc:format
+ id="format405">image/svg+xml</dc:format>
+
+
+ <dc:type
+ id="type407"
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+
+
+</cc:Work>
+
+
+</rdf:RDF>
+
+
+</metadata>
+
+
+</x:xmpmeta>
+
+
+
+ <xpacket
+ id="xpacket103">end='w' </xpacket>
+
+
+
+ </metadata>
+ <g
+ id="g2493"
+ inkscape:export-xdpi="192.00000"
+ inkscape:export-ydpi="192.00000"
+ inkscape:export-filename="/home/vqu/Desktop/icon tellico/bookcase.png">
+ <path
+ opacity="0.2"
+ d="M44,15.5c-9.374,0-17,7.626-17,17v200c0,9.374,7.626,17,17,17h176c9.375,0,17-7.626,17-17v-200 c0-9.374-7.625-17-17-17H44z"
+ id="path551"
+ style="opacity:0.20000000;" />
+ <path
+ opacity="0.2"
+ d="M42,13.5c-9.374,0-17,7.626-17,17v200c0,9.374,7.626,17,17,17h176c9.375,0,17-7.626,17-17v-200 c0-9.374-7.625-17-17-17H42z"
+ id="path552"
+ style="opacity:0.20000000;" />
+ <path
+ opacity="0.2"
+ d="M40,12.5c-9.374,0-17,7.626-17,17v200c0,9.374,7.626,17,17,17h176c9.375,0,17-7.626,17-17v-200 c0-9.374-7.625-17-17-17H40z"
+ id="path553"
+ style="opacity:0.20000000;" />
+ <path
+ fill="url(#XMLID_1_)"
+ d="M41,11c-9.374,0-17,7.626-17,17v200c0,9.374,7.626,17,17,17h176c9.375,0,17-7.626,17-17V28 c0-9.374-7.625-17-17-17H41z"
+ id="path560"
+ style="fill:url(#XMLID_1_);" />
+ <path
+ fill="#FFFFFF"
+ d="M28,228c0,6.627,5.373,12,12,12h176c6.627,0,12-5.373,12-12V28c0-6.627-5.373-12-12-12H40 c-6.627,0-12,5.373-12,12V228z"
+ id="path561"
+ style="fill:#ffffff;" />
+ <path
+ fill="url(#XMLID_2_)"
+ d="M40,21c-3.86,0-7,3.14-7,7v200c0,3.859,3.14,7,7,7h176c3.859,0,7-3.141,7-7V28c0-3.86-3.141-7-7-7 H40z"
+ id="path568"
+ style="fill:url(#XMLID_2_);" />
+ <rect
+ id="_x3C_Slice_x3E_"
+ fill="none"
+ width="256"
+ height="256"
+ style="fill:none;" />
+ <g
+ id="g2047"
+ transform="matrix(1.730570,0.000000,0.000000,1.844339,-382.2522,-461.2119)">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<path
+ opacity="0.2"
+ d="M 299.78022,316.80616 L 261.13022,329.80676 C 260.02222,330.17975 259.32022,330.77819 259.32022,331.43081 L 259.32022,349.22517 C 259.32022,349.88359 259.99322,350.50089 261.11922,350.87147 L 299.80922,363.64953 C 301.22122,364.11589 303.08222,364.11202 304.48722,363.63937 L 340.06286,352.02185 C 341.16986,351.64886 341.83086,351.03784 341.83086,350.38475 C 341.83086,347.78595 342.45373,345.65430 341.51942,345.23555 C 341.57133,344.19568 339.59890,345.02442 339.33937,344.14027 C 339.18365,344.08661 338.87222,337.33708 339.65081,337.43914 C 339.65081,336.44942 341.98658,337.48403 341.83086,336.65003 C 342.55754,336.23128 341.88277,332.54246 341.83086,330.41081 C 341.83086,329.75094 340.37727,328.97841 339.25027,328.60686 L 304.45322,316.79503 C 303.04222,316.33012 301.18222,316.33399 299.78022,316.80616 z "
+ id="path2191"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+
+<path
+ opacity="0.2"
+ d="M 297.71922,316.47332 L 259.06822,329.47392 C 257.96022,329.84691 257.25922,330.44535 257.25922,331.09797 L 257.25922,348.89136 C 257.25922,349.55076 257.93222,350.16758 259.05722,350.53863 L 297.28007,363.00428 C 298.69207,363.47162 300.55407,363.46726 301.95807,362.99460 L 339.24561,350.28754 C 340.35361,349.91455 341.01561,349.30304 341.01561,348.64995 C 341.01561,346.79089 341.48277,345.71041 340.70417,345.09709 C 340.91179,344.22424 338.78365,344.28571 338.67984,343.72429 C 338.36841,343.52144 338.05697,335.68842 338.83556,335.64129 C 338.93937,334.86748 340.91180,335.33941 341.01561,334.72132 C 341.48276,333.95228 341.01561,331.62607 341.01561,330.07844 C 341.01561,329.41857 339.09386,328.49032 337.96686,328.11878 L 302.39222,316.46268 C 300.98022,315.99777 299.12122,316.00164 297.71922,316.47332 z "
+ id="path2194"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+
+<path
+ fill="url(#XMLID_4_)"
+ d="M 295.41091,315.22758 L 258.16137,327.76103 C 257.05337,328.13402 256.35237,328.73246 256.35237,329.38508 C 254.32804,335.21239 252.92658,339.94969 256.35237,348.26849 C 256.35237,348.92789 257.02537,349.54471 258.15137,349.91576 L 295.43991,362.06998 C 296.85191,362.53732 298.71291,362.53296 300.11691,362.06030 L 336.93830,349.82040 C 338.04530,349.44741 338.70630,348.83590 338.70630,348.18281 C 338.70630,346.80388 339.17345,344.33493 338.70630,344.04602 C 338.75820,343.30465 337.09722,343.65329 337.14912,342.60048 C 336.83768,342.58579 336.52625,334.00663 337.14912,333.36907 C 337.35674,332.82063 338.49868,333.20651 338.70630,332.65807 C 339.38108,332.05773 338.65439,330.21164 338.70630,328.98843 C 338.70630,328.32856 338.03130,327.71174 336.90430,327.34020 L 300.08291,315.21694 C 298.67191,314.75203 296.81291,314.75590 295.41091,315.22758 z "
+ id="path2205"
+ style="fill:url(#linearGradient2397);"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+
+<g
+ id="g2207"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,216.3650,286.7469)">
+ <polygon
+ id="polygon2209"
+ fill="#FFFFFF"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:#ffffff;" />
+
+
+
+ </g>
+
+<g
+ id="g2212"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,216.3650,286.7469)"
+ style="fill:url(#linearGradient2404);">
+ <linearGradient
+ id="linearGradient2214"
+ gradientUnits="userSpaceOnUse"
+ x1="152.20509"
+ y1="1062.5635"
+ x2="264.34052"
+ y2="1056.6604"
+ gradientTransform="matrix(0.384000,0.000000,0.000000,0.384000,-8.427600,-317.4872)"
+ spreadMethod="pad"
+ xlink:href="#linearGradient2094"
+ style="fill:url(#linearGradient2404);">
+
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FF9999;fill:url(#linearGradient2404);"
+ id="midPointStop2218" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF9999;fill:url(#linearGradient2404);"
+ id="midPointStop2220" />
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FF6666;fill:url(#linearGradient2404);"
+ id="midPointStop2222" />
+
+
+
+ </linearGradient>
+
+
+
+ <polygon
+ id="polygon2225"
+ fill="url(#path266_7_)"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:url(#linearGradient2046);" />
+
+
+
+ </g>
+
+
+ <path
+ style="fill:#009933;fill-opacity:1.0000000;"
+ d="M 297.76400,360.42407 L 336.45400,347.40509 L 336.45400,345.80372 L 332.40534,344.20236 L 331.47103,332.90231 L 336.45400,331.25676 L 336.45400,329.61122 L 297.76400,342.63019 C 295.34160,348.34127 294.68095,353.61190 297.76400,360.42407 z "
+ id="path2231"
+ sodipodi:nodetypes="ccccccccc" />
+
+
+
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;"
+ d="M 297.45257,359.02261 L 334.89682,346.62650 L 335.05254,331.79126 L 297.45257,344.34309 C 295.03017,350.05416 294.36951,352.21044 297.45257,359.02261 z "
+ id="path2233"
+ sodipodi:nodetypes="ccccc" />
+
+<g
+ id="g2235"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,216.3650,286.7469)">
+ <path
+ style="fill:url(#linearGradient3032);fill-opacity:1.0000000;fill-rule:nonzero;"
+ d="M 81.399000,152.29500 L 42.708000,125.88200 C 38.815056,110.40322 40.527951,99.430733 42.708000,89.102000 L 81.404000,115.51400 C 79.200152,125.95352 77.436740,136.84824 81.399000,152.29500 z "
+ id="path2237"
+ sodipodi:nodetypes="ccccc" />
+
+
+
+ </g>
+
+<path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#003333;stroke-width:1.0000000pt;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1.0000000;"
+ d="M 259.24295,330.42313 L 297.62542,343.35150 C 294.24874,350.39848 295.08292,353.62160 297.87235,359.78771"
+ id="path2249"
+ sodipodi:nodetypes="ccc" />
+
+
+</g>
+ <g
+ id="g2159"
+ transform="matrix(1.730570,0.000000,0.000000,1.844339,-245.8950,-436.2256)">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <path
+ opacity="0.2"
+ d="M 310.68046,263.55069 L 272.03046,276.55129 C 270.92246,276.92428 270.22046,277.52272 270.22046,278.17534 L 270.22046,295.96970 C 270.22046,296.62812 270.89346,297.24542 272.01946,297.61600 L 310.70946,310.39406 C 312.12146,310.86042 313.98246,310.85655 315.38746,310.38390 L 350.96310,298.76638 C 352.07010,298.39339 352.73110,297.78237 352.73110,297.12928 C 352.73110,294.53048 353.35397,292.39883 352.41966,291.98008 C 352.47157,290.94021 350.49914,291.76895 350.23961,290.88480 C 350.08389,290.83114 349.77246,284.08161 350.55105,284.18367 C 350.55105,283.19395 352.88682,284.22856 352.73110,283.39456 C 353.45778,282.97581 352.78301,279.28699 352.73110,277.15534 C 352.73110,276.49547 351.27751,275.72294 350.15051,275.35139 L 315.35346,263.53956 C 313.94246,263.07465 312.08246,263.07852 310.68046,263.55069 z "
+ id="path2265"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ transform="translate(-99.03649,19.15329)" />
+
+
+
+
+
+ <path
+ opacity="0.2"
+ d="M 308.61946,263.21785 L 269.96846,276.21845 C 268.86046,276.59144 268.15946,277.18988 268.15946,277.84250 L 268.15946,295.63589 C 268.15946,296.29529 268.83246,296.91211 269.95746,297.28316 L 308.18031,309.74881 C 309.59231,310.21615 311.45431,310.21179 312.85831,309.73913 L 350.14585,297.03207 C 351.25385,296.65908 351.91585,296.04757 351.91585,295.39448 C 351.91585,293.53542 352.38301,292.45494 351.60441,291.84162 C 351.81203,290.96877 349.68389,291.03024 349.58008,290.46882 C 349.26865,290.26597 348.95721,282.43295 349.73580,282.38582 C 349.83961,281.61201 351.81204,282.08394 351.91585,281.46585 C 352.38300,280.69681 351.91585,278.37060 351.91585,276.82297 C 351.91585,276.16310 349.99410,275.23485 348.86710,274.86331 L 313.29246,263.20721 C 311.88046,262.74230 310.02146,262.74617 308.61946,263.21785 z "
+ id="path2268"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ transform="translate(-99.03649,19.15329)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <path
+ fill="url(#XMLID_4_)"
+ d="M 306.31115,261.97211 L 269.06161,274.50556 C 267.95361,274.87855 267.25261,275.47699 267.25261,276.12961 C 265.22828,281.95692 263.82682,286.69422 267.25261,295.01302 C 267.25261,295.67242 267.92561,296.28924 269.05161,296.66029 L 306.34015,308.81451 C 307.75215,309.28185 309.61315,309.27749 311.01715,308.80483 L 347.83854,296.56493 C 348.94554,296.19194 349.60654,295.58043 349.60654,294.92734 C 349.60654,293.54841 350.07369,291.07946 349.60654,290.79055 C 349.65844,290.04918 347.99746,290.39782 348.04936,289.34501 C 347.73792,289.33032 347.42649,280.75116 348.04936,280.11360 C 348.25698,279.56516 349.39892,279.95104 349.60654,279.40260 C 350.28132,278.80226 349.55463,276.95617 349.60654,275.73296 C 349.60654,275.07309 348.93154,274.45627 347.80454,274.08473 L 310.98315,261.96147 C 309.57215,261.49656 307.71315,261.50043 306.31115,261.97211 z "
+ id="path2279"
+ style="fill:url(#linearGradient2151);"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ transform="translate(-99.03649,19.15329)" />
+
+
+
+ <g
+ id="g2281"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,128.2287,252.6448)">
+ <polygon
+ id="polygon2283"
+ fill="#FFFFFF"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:#ffffff;" />
+
+
+
+ </g>
+
+
+
+ <g
+ id="g2286"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,128.2287,252.6448)">
+ <linearGradient
+ id="linearGradient2288"
+ gradientUnits="userSpaceOnUse"
+ x1="152.20509"
+ y1="1062.5635"
+ x2="264.34052"
+ y2="1056.6604"
+ gradientTransform="matrix(0.384000,0.000000,0.000000,0.384000,-8.427600,-317.4872)"
+ spreadMethod="pad"
+ xlink:href="#linearGradient2094">
+
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FF9999"
+ id="midPointStop2292" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF9999"
+ id="midPointStop2294" />
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FF6666"
+ id="midPointStop2296" />
+
+
+
+ </linearGradient>
+
+
+
+ <polygon
+ id="polygon2299"
+ fill="url(#path266_7_)"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:url(#linearGradient2150);" />
+
+
+
+ </g>
+
+
+
+
+
+ <g
+ id="g2303"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,128.2287,252.6448)">
+ <path
+ style="fill:#0056d5;fill-opacity:1.0000000;"
+ d="M 81.399000,152.29500 L 120.08900,125.38400 L 120.08900,122.07388 L 116.04034,118.76377 L 115.10603,95.405896 L 120.08900,92.004448 L 120.08900,88.603000 L 81.399000,115.51400 C 78.976600,127.31913 78.315946,138.21385 81.399000,152.29500 z "
+ id="path2305"
+ sodipodi:nodetypes="ccccccccc" />
+
+
+
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;"
+ d="M 81.087564,149.39810 L 118.53182,123.77461 L 118.68754,93.109290 L 81.087564,119.05466 C 78.665164,130.85979 78.004510,135.31695 81.087564,149.39810 z "
+ id="path2307"
+ sodipodi:nodetypes="ccccc" />
+
+</g>
+
+
+
+ <g
+ id="g2309"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,128.2287,252.6448)">
+ <path
+ style="fill:url(#linearGradient2158);fill-opacity:1.0000000;"
+ d="M 81.399000,152.29500 L 42.708000,125.88200 C 38.815056,110.40322 40.527951,99.430733 42.708000,89.102000 L 81.404000,115.51400 C 79.200152,125.95352 77.436740,136.84824 81.399000,152.29500 z "
+ id="path2311"
+ sodipodi:nodetypes="ccccc" />
+
+
+
+ </g>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#003344;stroke-width:1.0000000pt;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1.0000000;"
+ d="M 270.14319,277.16766 L 308.52566,290.09603 C 305.14898,297.14301 305.98316,300.36613 308.77259,306.53224"
+ id="path2323"
+ sodipodi:nodetypes="ccc"
+ transform="translate(-99.03649,19.15329)" />
+
+</g>
+ <g
+ id="g2102"
+ transform="matrix(1.730570,0.000000,0.000000,1.844339,-394.1092,-435.9384)">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <path
+ opacity="0.2"
+ d="M 310.68046,263.55069 L 272.03046,276.55129 C 270.92246,276.92428 270.22046,277.52272 270.22046,278.17534 L 270.22046,295.96970 C 270.22046,296.62812 270.89346,297.24542 272.01946,297.61600 L 310.70946,310.39406 C 312.12146,310.86042 313.98246,310.85655 315.38746,310.38390 L 350.96310,298.76638 C 352.07010,298.39339 352.73110,297.78237 352.73110,297.12928 C 352.73110,294.53048 353.35397,292.39883 352.41966,291.98008 C 352.47157,290.94021 350.49914,291.76895 350.23961,290.88480 C 350.08389,290.83114 349.77246,284.08161 350.55105,284.18367 C 350.55105,283.19395 352.88682,284.22856 352.73110,283.39456 C 353.45778,282.97581 352.78301,279.28699 352.73110,277.15534 C 352.73110,276.49547 351.27751,275.72294 350.15051,275.35139 L 315.35346,263.53956 C 313.94246,263.07465 312.08246,263.07852 310.68046,263.55069 z "
+ id="path570"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+
+
+
+
+
+ <path
+ opacity="0.2"
+ d="M 308.61946,263.21785 L 269.96846,276.21845 C 268.86046,276.59144 268.15946,277.18988 268.15946,277.84250 L 268.15946,295.63589 C 268.15946,296.29529 268.83246,296.91211 269.95746,297.28316 L 308.18031,309.74881 C 309.59231,310.21615 311.45431,310.21179 312.85831,309.73913 L 350.14585,297.03207 C 351.25385,296.65908 351.91585,296.04757 351.91585,295.39448 C 351.91585,293.53542 352.38301,292.45494 351.60441,291.84162 C 351.81203,290.96877 349.68389,291.03024 349.58008,290.46882 C 349.26865,290.26597 348.95721,282.43295 349.73580,282.38582 C 349.83961,281.61201 351.81204,282.08394 351.91585,281.46585 C 352.38300,280.69681 351.91585,278.37060 351.91585,276.82297 C 351.91585,276.16310 349.99410,275.23485 348.86710,274.86331 L 313.29246,263.20721 C 311.88046,262.74230 310.02146,262.74617 308.61946,263.21785 z "
+ id="path572"
+ style="opacity:0.20000000;"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <path
+ fill="url(#XMLID_4_)"
+ d="M 306.31115,261.97211 L 269.06161,274.50556 C 267.95361,274.87855 267.25261,275.47699 267.25261,276.12961 C 265.22828,281.95692 263.82682,286.69422 267.25261,295.01302 C 267.25261,295.67242 267.92561,296.28924 269.05161,296.66029 L 306.34015,308.81451 C 307.75215,309.28185 309.61315,309.27749 311.01715,308.80483 L 347.83854,296.56493 C 348.94554,296.19194 349.60654,295.58043 349.60654,294.92734 C 349.60654,293.54841 350.07369,291.07946 349.60654,290.79055 C 349.65844,290.04918 347.99746,290.39782 348.04936,289.34501 C 347.73792,289.33032 347.42649,280.75116 348.04936,280.11360 C 348.25698,279.56516 349.39892,279.95104 349.60654,279.40260 C 350.28132,278.80226 349.55463,276.95617 349.60654,275.73296 C 349.60654,275.07309 348.93154,274.45627 347.80454,274.08473 L 310.98315,261.96147 C 309.57215,261.49656 307.71315,261.50043 306.31115,261.97211 z "
+ id="path608"
+ style="fill:url(#XMLID_4_);"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+
+
+
+ <g
+ id="g253_3_"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,227.2652,233.4915)">
+ <polygon
+ id="path266_3_"
+ fill="#FFFFFF"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:#ffffff;" />
+
+
+
+ </g>
+
+
+
+ <g
+ id="g253_1_"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,227.2652,233.4915)">
+ <linearGradient
+ id="path266_7_"
+ gradientUnits="userSpaceOnUse"
+ x1="152.20509"
+ y1="1062.5635"
+ x2="264.34052"
+ y2="1056.6604"
+ gradientTransform="matrix(0.384000,0.000000,0.000000,0.384000,-8.427600,-317.4872)"
+ spreadMethod="pad"
+ xlink:href="#linearGradient2094">
+
+
+
+
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FF9999"
+ id="midPointStop615" />
+
+
+
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF9999"
+ id="midPointStop616" />
+
+
+
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FF6666"
+ id="midPointStop617" />
+
+
+
+ </linearGradient>
+
+
+
+ <polygon
+ id="path266_1_"
+ fill="url(#path266_7_)"
+ points="81.399000,115.51400 42.708000,89.156000 81.399000,62.256000 120.08900,88.603000 81.399000,115.51400 "
+ style="fill:url(#path266_7_);" />
+
+
+
+ </g>
+
+
+
+
+
+ <g
+ id="g267_1_"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,227.2652,233.4915)">
+ <path
+ style="fill:#cf0000;"
+ d="M 81.399000,152.29500 L 120.08900,125.38400 L 120.08900,122.07388 L 116.04034,118.76377 L 115.10603,95.405896 L 120.08900,92.004448 L 120.08900,88.603000 L 81.399000,115.51400 C 78.976600,127.31913 78.315946,138.21385 81.399000,152.29500 z "
+ id="path277_2_"
+ sodipodi:nodetypes="ccccccccc" />
+
+
+
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;"
+ d="M 81.087564,149.39810 L 118.53182,123.77461 L 118.68754,93.109290 L 81.087564,119.05466 C 78.665164,130.85979 78.004510,135.31695 81.087564,149.39810 z "
+ id="path1472"
+ sodipodi:nodetypes="ccccc" />
+
+</g>
+
+
+
+ <g
+ id="g278_1_"
+ transform="matrix(1.000000,0.000000,0.000000,0.483779,227.2652,233.4915)">
+ <path
+ style="fill:url(#linearGradient2098);fill-opacity:1.0000000;"
+ d="M 81.399000,152.29500 L 42.708000,125.88200 C 38.815056,110.40322 40.527951,99.430733 42.708000,89.102000 L 81.404000,115.51400 C 79.200152,125.95352 77.436740,136.84824 81.399000,152.29500 z "
+ id="path279_1_"
+ sodipodi:nodetypes="ccccc" />
+
+
+
+ </g>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#600000;stroke-width:1.0000000pt;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1.0000000;"
+ d="M 270.14319,277.16766 L 308.52566,290.09603 C 305.14898,297.14301 305.98316,300.36613 308.77259,306.53224"
+ id="path1469"
+ sodipodi:nodetypes="ccc" />
+
+</g>
+ </g>
+</svg>
diff --git a/icons/video.png b/icons/video.png
new file mode 100644
index 0000000..dd45cc0
--- /dev/null
+++ b/icons/video.png
Binary files differ
diff --git a/icons/wine.png b/icons/wine.png
new file mode 100644
index 0000000..90f03c9
--- /dev/null
+++ b/icons/wine.png
Binary files differ
diff --git a/install-sh b/install-sh
new file mode 100755
index 0000000..e9de238
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt
new file mode 100644
index 0000000..6b60c4a
--- /dev/null
+++ b/po/CMakeLists.txt
@@ -0,0 +1,5 @@
+file(GLOB _po_files *.po)
+
+#GETTEXT_CREATE_TRANSLATIONS(tellico.pot ALL ${_po_files} )
+
+
diff --git a/po/Makefile.am b/po/Makefile.am
new file mode 100644
index 0000000..bf7803b
--- /dev/null
+++ b/po/Makefile.am
@@ -0,0 +1,9 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+
+EXTRA_DIST = tellico.pot README
+
+####### kdevelop will overwrite this part!!! (end)############
+POFILES = AUTO
+
+CLEANFILES = *~
diff --git a/po/README b/po/README
new file mode 100644
index 0000000..29c6eff
--- /dev/null
+++ b/po/README
@@ -0,0 +1,5 @@
+To regenerate the message strings, type
+
+make package-messages
+
+from the top-level directory
diff --git a/po/bg.po b/po/bg.po
new file mode 100644
index 0000000..ccb43b7
--- /dev/null
+++ b/po/bg.po
@@ -0,0 +1,5968 @@
+# translation of tellico.po to Bulgarian
+# This file is distributed under the same license as the tellico package.
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+# Boyan Ivanov <boyan17@bulgaria.com>, 2003
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: tellico\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2003-07-01 11:27+0300\n"
+"Last-Translator: Boyan Ivanov <boyan17@bulgaria.com>\n"
+"Language-Team: Bulgarian <bg@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Report-Msgid-Bugs-To: \n"
+"X-Generator: KBabel 1.0.1\n"
+
+#: cite/lyxpipe.cpp:50
+#, fuzzy
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "Tellico не може да пише във файл %1."
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr ""
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr ""
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr ""
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:181
+#, fuzzy
+msgid "Rename Column"
+msgstr "Преименувай колекцията"
+
+#: gui/tablefieldwidget.cpp:181
+#, fuzzy
+msgid "New column name:"
+msgstr "Ново име за колекция"
+
+#: gui/tablefieldwidget.cpp:206
+#, fuzzy, c-format
+msgid "Column %1"
+msgstr "Показва колони"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+#, fuzzy
+msgid "Rename Column..."
+msgstr "Преименувай колекцията"
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:295
+#, fuzzy
+msgid "Clear Table"
+msgstr "Изтриване на поле?"
+
+#: gui/previewdialog.cpp:27
+#, fuzzy
+msgid "Template Preview"
+msgstr "Опции за форматиране"
+
+#: gui/stringmapdialog.cpp:57
+#, fuzzy
+msgid "&Set"
+msgstr "Запиши като ..."
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr ""
+
+#: gui/kwidgetlister.cpp:58
+#, fuzzy
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "повече интерфейсни елементи"
+
+#: gui/kwidgetlister.cpp:62
+#, fuzzy
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "по-малко интерфейсни елементи"
+
+#: gui/kwidgetlister.cpp:69
+#, fuzzy
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "изчиства интерфейсните елементи"
+
+#: gui/imagewidget.cpp:57
+#, fuzzy
+msgid "Select Image..."
+msgstr "Избор на XSLT файл..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr ""
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr ""
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, fuzzy, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Изтриване на поле"
+
+#: commands/collectioncommand.cpp:110
+#, fuzzy
+msgid "Append Collection"
+msgstr "Преименувай колекцията"
+
+#: commands/collectioncommand.cpp:112
+#, fuzzy
+msgid "Merge Collection"
+msgstr "BCCollection"
+
+#: commands/collectioncommand.cpp:114
+#, fuzzy
+msgid "Replace Collection"
+msgstr "Преименувай колекцията"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+#, fuzzy
+msgid "Modify Entries"
+msgstr "Изтрий книга"
+
+#: commands/fieldcommand.cpp:104
+#, fuzzy
+msgid "Add %1 Field"
+msgstr "Някое поле"
+
+#: commands/fieldcommand.cpp:106
+#, fuzzy
+msgid "Modify %1 Field"
+msgstr "Бърз филтър"
+
+#: commands/fieldcommand.cpp:108
+#, fuzzy
+msgid "Delete %1 Field"
+msgstr "Изтриване на поле?"
+
+#: commands/addentries.cpp:50
+#, fuzzy
+msgid "Add Entries"
+msgstr "Изтрий книга"
+
+#: commands/addentries.cpp:51
+#, fuzzy, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Изтриване на поле"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+#, fuzzy
+msgid "Rename Collection"
+msgstr "Преименувай колекцията"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+#, fuzzy
+msgid "Modify Loan"
+msgstr "Промяна на книга"
+
+#: commands/filtercommand.cpp:98
+#, fuzzy
+msgid "Add Filter"
+msgstr "Разширен филтър"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+#, fuzzy
+msgid "Modify Filter"
+msgstr "Бърз филтър"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+#, fuzzy
+msgid "Delete Filter"
+msgstr "Изтриване на поле?"
+
+#: commands/addloans.cpp:108
+#, fuzzy
+msgid "Check-out Items"
+msgstr "Изтриване на няколко книги ?"
+
+#: commands/addloans.cpp:109
+#, fuzzy, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Изтриване на поле"
+
+#: commands/removeentries.cpp:48
+#, fuzzy
+msgid "Delete Entries"
+msgstr "Изтриване на поле"
+
+#: commands/removeentries.cpp:49
+#, fuzzy, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Изтриване на поле"
+
+#: commands/reorderfields.cpp:54
+#, fuzzy
+msgid "Reorder Fields"
+msgstr "Текущи полета"
+
+#: commands/removeloans.cpp:79
+#, fuzzy
+msgid "Check-in Entries"
+msgstr "Кутийка"
+
+#: commands/removeloans.cpp:80
+#, fuzzy, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Изтриване на поле"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Общи"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Състояние"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Лични"
+
+#: collections/stampcollection.cpp:27
+#, fuzzy
+msgid "My Stamps"
+msgstr "Моите клипове"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Заглавие"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+#, fuzzy
+msgid "Description"
+msgstr "Описание:"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+#, fuzzy
+msgid "Denomination"
+msgstr "Описание:"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+#, fuzzy
+msgid "Country"
+msgstr "Показва колони"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr ""
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+#, fuzzy
+msgid "Color"
+msgstr "Е&кспортиране"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr ""
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr ""
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+#, fuzzy
+msgid "Grade"
+msgstr "Жанр"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr ""
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+#, fuzzy
+msgid "Hinged"
+msgstr "С автограф"
+
+#: collections/stampcollection.cpp:95
+#, fuzzy
+msgid "Centering"
+msgstr "Оценка"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Дата на покупка"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Цена"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+#, fuzzy
+msgid "Location"
+msgstr "BCCollection"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Подарък"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+#, fuzzy
+msgid "Image"
+msgstr "Страници"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Коментар"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Издателски"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Класификация"
+
+#: collections/comicbookcollection.cpp:28
+#, fuzzy
+msgid "My Comic Books"
+msgstr "Моите книги"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Подзаглавие"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+#, fuzzy
+msgid "Writer"
+msgstr "Изтрий книга"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Поредица"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Издател"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Издание"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Година на публикуване"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Страници"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Език"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Жанр"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Ключови думи"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr ""
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "С автограф"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Дадена"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+#, fuzzy
+msgid "Front Cover"
+msgstr "Е&кспортиране"
+
+#: collections/coincollection.cpp:26
+#, fuzzy
+msgid "My Coins"
+msgstr "Моите песни"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+#, fuzzy
+msgid "Type"
+msgstr "Тип:"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Година"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr ""
+
+#: collections/coincollection.cpp:73
+#, fuzzy
+msgid "Coin Set"
+msgstr "съдържа"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr ""
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr ""
+
+#: collections/coincollection.cpp:122
+#, fuzzy
+msgid "Obverse"
+msgstr "Презаписване"
+
+#: collections/coincollection.cpp:125
+#, fuzzy
+msgid "Reverse"
+msgstr "Презаписване"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Моите книги"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Автор"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Твърда корица"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Хартиена корица"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Опаковъчна хартия"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "Електронна книга"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Списание"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Журнал"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Корица"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Авторско право (година)"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Международен стандартен книжен номер"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr ""
+"Библиотека на конгреса,контролен номер"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr ""
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Номер от поредица"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Нова"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Използвана"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Прочетена"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Оценка"
+
+#: collections/filecatalog.cpp:25
+#, fuzzy
+msgid "My Files"
+msgstr "Моите клипове"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+#, fuzzy
+msgid "Name"
+msgstr "Номер от поредица"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+#, fuzzy
+msgid "Volume"
+msgstr "Показва колони"
+
+#: collections/filecatalog.cpp:55
+#, fuzzy
+msgid "Folder"
+msgstr "Изтрий книга"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr ""
+
+#: collections/filecatalog.cpp:65
+#, fuzzy
+msgid "Size"
+msgstr "С автограф"
+
+#: collections/filecatalog.cpp:69
+#, fuzzy
+msgid "Permissions"
+msgstr "Лични"
+
+#: collections/filecatalog.cpp:74
+#, fuzzy
+msgid "Owner"
+msgstr " "
+
+#: collections/filecatalog.cpp:79
+#, fuzzy
+msgid "Group"
+msgstr "Групирай по:"
+
+#: collections/filecatalog.cpp:85
+#, fuzzy
+msgid "Created"
+msgstr "Коментар"
+
+#: collections/filecatalog.cpp:89
+#, fuzzy
+msgid "Modified"
+msgstr "Бърз филтър"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+#, fuzzy
+msgid "Property"
+msgstr "Година на публикуване"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+#, fuzzy
+msgid "Value"
+msgstr "Показва колони"
+
+#: collections/filecatalog.cpp:99
+#, fuzzy
+msgid "Icon"
+msgstr "съдържа"
+
+#: collections/winecollection.cpp:26
+#, fuzzy
+msgid "My Wines"
+msgstr "Моите клипове"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+#, fuzzy
+msgid "Producer"
+msgstr "Година на публикуване"
+
+#: collections/winecollection.cpp:49
+#, fuzzy
+msgid "Appellation"
+msgstr "Преименувай колекцията"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr ""
+
+#: collections/winecollection.cpp:61
+#, fuzzy
+msgid "Vintage"
+msgstr "С автограф"
+
+#: collections/winecollection.cpp:67
+#, fuzzy
+msgid "Red Wine"
+msgstr "Моите клипове"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr ""
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr ""
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr ""
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr ""
+
+#: collections/winecollection.cpp:111
+#, fuzzy
+msgid "Label Image"
+msgstr "Заглавие"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr ""
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr ""
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Моите клипове"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr ""
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+#, fuzzy
+msgid "HD DVD"
+msgstr "DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Медия"
+
+#: collections/videocollection.cpp:52
+#, fuzzy
+msgid "Production Year"
+msgstr "Година на публикуване"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr ""
+
+#: collections/videocollection.cpp:62
+#, fuzzy
+msgid "Certification"
+msgstr "Класификация"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr ""
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr ""
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr ""
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr ""
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr ""
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr ""
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr ""
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr ""
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr ""
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr ""
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr ""
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr ""
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr ""
+
+#: collections/videocollection.cpp:95
+#, fuzzy
+msgid "Format"
+msgstr "Опции за форматиране"
+
+#: collections/videocollection.cpp:100
+#, fuzzy
+msgid "Cast"
+msgstr "Касета"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr ""
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+#, fuzzy
+msgid "Role"
+msgstr "Показва колони"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr ""
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr ""
+
+#: collections/videocollection.cpp:127
+#, fuzzy
+msgid "Composer"
+msgstr "Е&кспортиране"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr ""
+
+#: collections/videocollection.cpp:139
+#, fuzzy
+msgid "Language Tracks"
+msgstr "Език"
+
+#: collections/videocollection.cpp:145
+#, fuzzy
+msgid "Subtitle Languages"
+msgstr "Подзаглавие"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr ""
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr ""
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr ""
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr ""
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr ""
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr ""
+
+#: collections/videocollection.cpp:173
+#, fuzzy
+msgid "Color Mode"
+msgstr "Е&кспортиране"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr ""
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr ""
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+#, fuzzy
+msgid "Personal Rating"
+msgstr "Лични"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+#, fuzzy
+msgid "Cover"
+msgstr "Е&кспортиране"
+
+#: collections/gamecollection.cpp:26
+#, fuzzy
+msgid "My Games"
+msgstr "Моите клипове"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr ""
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+#, fuzzy
+msgid "GameCube"
+msgstr "Номер от поредица"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr ""
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr ""
+
+#: collections/gamecollection.cpp:47
+#, fuzzy
+msgid "Game Boy Color"
+msgstr "Преименувай колекцията"
+
+#: collections/gamecollection.cpp:47
+#, fuzzy
+msgid "Game Boy"
+msgstr "Номер от поредица"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr ""
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr ""
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr ""
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr ""
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Издател"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr ""
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+
+#: collections/gamecollection.cpp:82
+#, fuzzy
+msgid "ESRB Rating"
+msgstr "Оценка"
+
+#: collections/gamecollection.cpp:95
+#, fuzzy
+msgid "Completed"
+msgstr "Коментар"
+
+#: collections/cardcollection.cpp:26
+#, fuzzy
+msgid "My Cards"
+msgstr "Касета"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr ""
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr ""
+
+#: collections/cardcollection.cpp:55
+#, fuzzy
+msgid "Brand"
+msgstr "Жанр"
+
+#: collections/cardcollection.cpp:62
+#, fuzzy
+msgid "Card Number"
+msgstr "Номер от поредица"
+
+#: collections/cardcollection.cpp:77
+#, fuzzy
+msgid "Card Type"
+msgstr "Тип:"
+
+#: collections/cardcollection.cpp:109
+#, fuzzy
+msgid "Front Image"
+msgstr "Страници"
+
+#: collections/cardcollection.cpp:112
+#, fuzzy
+msgid "Back Image"
+msgstr "Страници"
+
+#: collections/boardgamecollection.cpp:26
+#, fuzzy
+msgid "My Board Games"
+msgstr "Моите клипове"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:72
+#, fuzzy
+msgid "Number of Players"
+msgstr "Изтриване на поле"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+#, fuzzy
+msgid "Bibliography"
+msgstr "Импортира Bibtexml файл ..."
+
+#: collections/bibtexcollection.cpp:72
+#, fuzzy
+msgid "Entry Type"
+msgstr "Поредица"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+
+#: collections/bibtexcollection.cpp:86
+#, fuzzy
+msgid "Bibtex Key"
+msgstr "Настройки на полето"
+
+#: collections/bibtexcollection.cpp:92
+#, fuzzy
+msgid "Book Title"
+msgstr "Заглавие"
+
+#: collections/bibtexcollection.cpp:98
+#, fuzzy
+msgid "Editor"
+msgstr "Издание"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+#, fuzzy
+msgid "Number"
+msgstr "Номер от поредица"
+
+#: collections/bibtexcollection.cpp:183
+#, fuzzy
+msgid "How Published"
+msgstr "Издател"
+
+#: collections/bibtexcollection.cpp:195
+#, fuzzy
+msgid "Chapter"
+msgstr "Категория:"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:236
+#, fuzzy
+msgid "Notes"
+msgstr "Е&кспортиране"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr ""
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Албум"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr ""
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Касета"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr ""
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Изпълнител"
+
+#: collections/musiccollection.cpp:56
+#, fuzzy
+msgid "Label"
+msgstr "Заглавие"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr ""
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr ""
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr "и,в,от,към"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr " "
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "мл.,мл,iii,iv"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "де,ван де,фон"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr ""
+
+#: fetch/entrezfetcher.cpp:56
+#, fuzzy
+msgid "Entrez Database"
+msgstr "Тип:"
+
+#: fetch/entrezfetcher.cpp:485
+#, fuzzy
+msgid "Institution"
+msgstr "Състояние"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr ""
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr ""
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr ""
+
+#: fetch/z3950connection.cpp:345
+#, fuzzy
+msgid "Connection error %1: %2"
+msgstr "Летна \"Колекция\""
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr ""
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+#, fuzzy
+msgid "Library of Congress (US)"
+msgstr ""
+"Библиотека на конгреса,контролен номер"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+#, fuzzy
+msgid "Hos&t: "
+msgstr "Е&кспортиране"
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr ""
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+#, fuzzy
+msgid "&Port: "
+msgstr "Е&кспортиране"
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr ""
+
+#: fetch/srufetcher.cpp:450
+#, fuzzy
+msgid "Path: "
+msgstr "Е&кспортиране"
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr ""
+
+#: fetch/srufetcher.cpp:460
+#, fuzzy
+msgid "Format: "
+msgstr "Опции за форматиране"
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr ""
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:848
+#, fuzzy
+msgid "Co&untry: "
+msgstr "Показва колони"
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:855
+#, fuzzy
+msgid "France"
+msgstr "&Търси"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:869
+#, fuzzy
+msgid "Small Image"
+msgstr "Заглавие"
+
+#: fetch/amazonfetcher.cpp:870
+#, fuzzy
+msgid "Medium Image"
+msgstr "Медия"
+
+#: fetch/amazonfetcher.cpp:871
+#, fuzzy
+msgid "Large Image"
+msgstr "Заглавие"
+
+#: fetch/amazonfetcher.cpp:872
+#, fuzzy
+msgid "No Image"
+msgstr "Страници"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:525
+#, fuzzy
+msgid "&Database: "
+msgstr "Тип:"
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:550
+#, fuzzy
+msgid "&Format: "
+msgstr "Опции за форматиране"
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+#, fuzzy
+msgid "Optional"
+msgstr "Настройки на полето"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:82
+#, fuzzy
+msgid "External Application"
+msgstr "Изход от приложението"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+#, fuzzy
+msgid "Collection &type:"
+msgstr "BCCollection"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+#, fuzzy
+msgid "Update"
+msgstr "Изтрий книга"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+
+#: fetch/configwidget.cpp:29
+#, fuzzy
+msgid "Source Options"
+msgstr "Настройки на полето"
+
+#: fetch/configwidget.cpp:40
+#, fuzzy
+msgid "Available Fields"
+msgstr "Налични полета"
+
+#: fetch/imdbfetcher.cpp:89
+#, fuzzy
+msgid "Internet Movie Database"
+msgstr "Тип:"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+#, fuzzy
+msgid "IMDB Rating"
+msgstr "Оценка"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+#, fuzzy
+msgid "Certifications"
+msgstr "Класификация"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr ""
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:69
+#, fuzzy
+msgid "Person"
+msgstr "Лични"
+
+#: fetch/fetchmanager.cpp:70
+#, fuzzy
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:72
+#, fuzzy
+msgid "Keyword"
+msgstr "Ключови думи"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:76
+#, fuzzy
+msgid "Raw Query"
+msgstr "Търси в :"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr ""
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:343
+#, fuzzy
+msgid "&Username: "
+msgstr "Изтрий книга"
+
+#: fetch/crossreffetcher.cpp:348
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:354
+#, fuzzy
+msgid "&Password: "
+msgstr "Е&кспортиране"
+
+#: fetch/gcstarpluginfetcher.cpp:190
+#, fuzzy
+msgid "GCstar Plugin"
+msgstr "Касета"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:420
+#, fuzzy
+msgid "Author: "
+msgstr "Автор"
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr ""
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr ""
+
+#: newstuff/dialog.cpp:114
+#, fuzzy
+msgid "Version"
+msgstr "Лични"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr ""
+
+#: newstuff/dialog.cpp:117
+#, fuzzy
+msgid "Release Date"
+msgstr "Дата на покупка"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+
+#: newstuff/dialog.cpp:137
+#, fuzzy
+msgid "The name and license of the selected item"
+msgstr "Изтриване на няколко книги ?"
+
+#: newstuff/dialog.cpp:140
+#, fuzzy
+msgid "The author of the selected item"
+msgstr "Изтриване на няколко книги ?"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr ""
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr ""
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+
+#: newstuff/dialog.cpp:194
+#, fuzzy
+msgid "A description of the selected item is shown here."
+msgstr "Изтриване на няколко книги ?"
+
+#: newstuff/dialog.cpp:224
+#, fuzzy
+msgid "Downloading information..."
+msgstr "Експортирам..."
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Готово."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr ""
+
+#: newstuff/dialog.cpp:413
+#, fuzzy
+msgid "Installing item..."
+msgstr "Записва файл..."
+
+#: translators/bibteximporter.cpp:79
+msgid "No valid bibtex entries were found"
+msgstr ""
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+#, fuzzy
+msgid "Bibtex Options"
+msgstr "Настройки на полето"
+
+#: translators/bibteximporter.cpp:287
+msgid "Use Unicode (UTF-8) encoding"
+msgstr ""
+
+#: translators/bibteximporter.cpp:288
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr ""
+
+#: translators/bibteximporter.cpp:289
+msgid "Use user locale (%1) encoding"
+msgstr ""
+
+#: translators/bibteximporter.cpp:293
+msgid "Read the imported file in the local encoding."
+msgstr ""
+
+#: translators/tellicozipexporter.cpp:35
+#, fuzzy
+msgid "Tellico Zip File"
+msgstr "Лавица"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+#, fuzzy
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Tellico файлове (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+#, fuzzy
+msgid "*|All Files"
+msgstr "*|Всички файлове"
+
+#: translators/alexandriaexporter.cpp:43
+#, fuzzy
+msgid "Alexandria"
+msgstr "Общи настройки"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr ""
+"Грешка при четене на XML на ред %1,колона %2"
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "Съобщението за грешка е :"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Това е бъдеща версия на Tellico."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Непознат"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr ""
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr ""
+
+#: translators/tellicoimporter.cpp:940
+#, fuzzy
+msgid "Unread Books"
+msgstr "Въвеждане на книга"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr ""
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr ""
+
+#: translators/tellicoimporter.cpp:980
+#, fuzzy
+msgid "Favorites"
+msgstr "Изтрий книга"
+
+#: translators/audiofileimporter.cpp:69
+#, fuzzy
+msgid "Scanning audio files..."
+msgstr "Записва файл..."
+
+#: translators/audiofileimporter.cpp:129
+#, fuzzy
+msgid "Bitrate"
+msgstr "Настройки на полето"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:340
+#, fuzzy
+msgid "Audio File Options"
+msgstr "Настройки на полето"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:348
+#, fuzzy
+msgid "If checked, the file names for each track are added to the entries."
+msgstr ""
+"Ако е избрано,заглавията на полетата ще "
+"бъдат отпечатани."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:353
+#, fuzzy
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr ""
+"Ако е избрано,заглавията на полетата ще "
+"бъдат отпечатани."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr ""
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+#, fuzzy
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.xsl|XSLT файлове (*.xsl)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+#, fuzzy
+msgid "CSV Options"
+msgstr "Настройки на полето"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr ""
+
+#: translators/csvexporter.cpp:114
+#, fuzzy
+msgid "If checked, a header row will be added with the field titles."
+msgstr ""
+"Ако е избрано,книгите ще бъдат групирани "
+"по даден признак."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+#, fuzzy
+msgid "Delimiter"
+msgstr "Изтриване на поле?"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+
+#: translators/csvexporter.cpp:124
+#, fuzzy
+msgid "Comma"
+msgstr "Коментар"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr ""
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:135
+#, fuzzy
+msgid "Tab"
+msgstr "Заглавие"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:140
+#, fuzzy
+msgid "Other"
+msgstr " "
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr ""
+
+#: translators/filelistingimporter.cpp:63
+#, fuzzy
+msgid "Scanning files..."
+msgstr "Записва файл..."
+
+#: translators/filelistingimporter.cpp:191
+#, fuzzy
+msgid "File Listing Options"
+msgstr "Настройки за печат"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr ""
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+
+#: translators/filelistingimporter.cpp:198
+#, fuzzy
+msgid "Generate file previews"
+msgstr "Създава нов документ"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+
+#: translators/onixexporter.cpp:63
+#, fuzzy
+msgid "ONIX Archive"
+msgstr "Настройки на полето"
+
+#: translators/onixexporter.cpp:67
+#, fuzzy
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.bib|Bibtex файлове (*.bib)"
+
+#: translators/onixexporter.cpp:176
+#, fuzzy
+msgid "ONIX Archive Options"
+msgstr "Настройки на полето"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr ""
+
+#: translators/onixexporter.cpp:181
+#, fuzzy
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Ако е избрано,броя на книгите в груптата "
+"ще бъде добавен към името й."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+#, fuzzy
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr "Tellico не може да пише във файл %1."
+
+#: translators/freedbimporter.cpp:196
+#, fuzzy
+msgid "Select CDDB Entry"
+msgstr "Изтриване на поле"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr ""
+
+#: translators/freedbimporter.cpp:220
+#, fuzzy
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "Tellico не може да пише във файл %1."
+
+#: translators/freedbimporter.cpp:238
+#, fuzzy
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "Tellico не може да пише във файл %1."
+
+#: translators/freedbimporter.cpp:470
+#, fuzzy
+msgid "Various"
+msgstr "Групирай по:"
+
+#: translators/freedbimporter.cpp:489
+#, fuzzy
+msgid "Audio CD Options"
+msgstr "Настройки на полето"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr ""
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr ""
+
+#: translators/freedbimporter.cpp:502
+#, fuzzy
+msgid "Read all CDDB cache files only"
+msgstr "Записва файл..."
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr ""
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+#, fuzzy
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.xsl|XSLT файлове (*.xsl)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+#, fuzzy
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.xsl|XSLT файлове (*.xsl)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr ""
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+#, fuzzy
+msgid "XSLT Options"
+msgstr "Настройки на полето"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+#, fuzzy
+msgid "XSLT file:"
+msgstr "Заглавие:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr ""
+
+#: translators/alexandriaimporter.cpp:194
+#, fuzzy
+msgid "Alexandria Options"
+msgstr "Общи настройки"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr ""
+
+#: translators/bibtexmlexporter.cpp:36
+#, fuzzy
+msgid "Bibtexml"
+msgstr "Експортира към Bibtexml файл"
+
+#: translators/bibtexmlexporter.cpp:40
+#, fuzzy
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Bibtexml файлове (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr ""
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+#, fuzzy
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|XML файлове (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+#, fuzzy
+msgid "Tellico XML Options"
+msgstr "TellicoDoc"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr ""
+
+#: translators/tellicoxmlexporter.cpp:485
+#, fuzzy
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Ако е избрано,броя на книгите в груптата "
+"ще бъде добавен към името й."
+
+#: translators/importer.h:100
+#, fuzzy
+msgid "Loading data..."
+msgstr "Експортирам..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:48
+#, fuzzy
+msgid "Bibtex"
+msgstr "Настройки на полето"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+#, fuzzy
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Bibtex файлове (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+#, fuzzy
+msgid "Expand string macros"
+msgstr "Оценка"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:210
+#, fuzzy
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr ""
+"Ако е избрано,заглавията на полетата ще "
+"бъдат отпечатани."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:219
+#, fuzzy
+msgid "Bibtex quotation style:"
+msgstr "Настройки на полето"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+#, fuzzy
+msgid "Braces"
+msgstr "&Търси"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr ""
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr ""
+
+#: translators/csvimporter.cpp:236
+#, fuzzy
+msgid "If checked, the first row is used as field titles."
+msgstr ""
+"Ако е избрано,низът за търсене се "
+"използва като регулярен израз."
+
+#: translators/csvimporter.cpp:248
+#, fuzzy
+msgid "&Comma"
+msgstr "Коментар"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr ""
+
+#: translators/csvimporter.cpp:259
+#, fuzzy
+msgid "Ta&b"
+msgstr "Заглавие"
+
+#: translators/csvimporter.cpp:264
+#, fuzzy
+msgid "Ot&her:"
+msgstr " "
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr ""
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+
+#: translators/csvimporter.cpp:298
+#, fuzzy
+msgid "Co&lumn:"
+msgstr "Показва колони"
+
+#: translators/csvimporter.cpp:307
+#, fuzzy
+msgid "&Data field in this column:"
+msgstr "Полета на колекцията..."
+
+#: translators/csvimporter.cpp:315
+#, fuzzy
+msgid "&Assign Field"
+msgstr "Някое поле"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Ново поле"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr ""
+
+#: translators/pilotdbexporter.cpp:43
+#, fuzzy
+msgid "PilotDB"
+msgstr "Настройки на полето"
+
+#: translators/pilotdbexporter.cpp:47
+#, fuzzy
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.tc *.bc|Tellico файлове (*.tc)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Показва колони"
+
+#: translators/pilotdbexporter.cpp:210
+#, fuzzy
+msgid "PilotDB Options"
+msgstr "Настройки на полето"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr ""
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+#, fuzzy
+msgid "Tellico encountered an error in XSLT processing."
+msgstr ""
+"Програмата се натъкна на грешка при XSLT "
+"процедирането.\n"
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr ""
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+#, fuzzy
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xml|XML файлове (*.xml)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr ""
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+#, fuzzy
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.xml|XML файлове (*.xml)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr ""
+
+#: translators/htmlexporter.cpp:320
+#, fuzzy
+msgid "(grouped by %1)"
+msgstr "(сортирано по %1)"
+
+#: translators/htmlexporter.cpp:465
+#, fuzzy
+msgid "HTML Options"
+msgstr "Настройки на полето"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Печатане заглавията на полетата"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr ""
+"Ако е избрано,заглавията на полетата ще "
+"бъдат отпечатани."
+
+#: translators/htmlexporter.cpp:473
+#, fuzzy
+msgid "Group the entries"
+msgstr "Групиране на книгите"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+#, fuzzy
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr ""
+"Ако е избрано,книгите ще бъдат групирани "
+"по даден признак."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr ""
+
+#: translators/htmlexporter.cpp:479
+#, fuzzy
+msgid "If checked, individual files will be created for each entry."
+msgstr ""
+"Ако е избрано,заглавията на полетата ще "
+"бъдат отпечатани."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+#, fuzzy
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico не може да зареди файла %1."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+#, fuzzy
+msgid "Data Source Properties"
+msgstr "Настройки на поле"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr ""
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr ""
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr ""
+
+#: fetcherconfigdialog.cpp:114
+#, fuzzy
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Ако е избрано,книгите ще бъдат групирани "
+"по даден признак."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Някое поле"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "съдържа"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "не съдържа"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "е равно на"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "не е равно на"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "пасва на регул. израз"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "не пасва на регул. израз"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Редакция..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Разширен филтър"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Критерии за филтриране"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Съдържа в&сички :"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Съдържа н&якое от :"
+
+#: filterdialog.cpp:311
+#, fuzzy
+msgid "Filter name:"
+msgstr "Изтрий книга"
+
+#: filterdialog.cpp:319
+#, fuzzy
+msgid "&Save Filter"
+msgstr "Разширен филтър"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Прост текст"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Параграф"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr ""
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Кутийка"
+
+#: field.cpp:496
+#, fuzzy
+msgid "Table"
+msgstr "Заглавие"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr ""
+
+#: field.cpp:500
+msgid "Date"
+msgstr ""
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr ""
+
+#: entryupdater.cpp:83
+#, fuzzy
+msgid "Updating entries..."
+msgstr "Изтрий книга"
+
+#: entryupdater.cpp:85
+#, fuzzy
+msgid "Update Entries"
+msgstr "Изтрий книга"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr ""
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr ""
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Разшири всички групи"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Свий всички групи"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr ""
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr ""
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr ""
+
+#: importdialog.cpp:54 importdialog.cpp:60
+#, fuzzy
+msgid "Import Options"
+msgstr "Опции за форматиране"
+
+#: importdialog.cpp:62
+#, fuzzy
+msgid "&Replace current collection"
+msgstr "Преименувай колекцията"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr ""
+
+#: importdialog.cpp:65
+#, fuzzy
+msgid "A&ppend to current collection"
+msgstr "Промяна на групирането на колекцията"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+
+#: importdialog.cpp:69
+#, fuzzy
+msgid "&Merge with current collection"
+msgstr "Промяна на групирането на колекцията"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, fuzzy, no-c-format
+msgid "&Import"
+msgstr "И&мпортиране"
+
+#: importdialog.cpp:268
+#, fuzzy
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.xsl|XSLT файлове (*.xsl)"
+
+#: importdialog.cpp:277
+#, fuzzy
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.xsl|XSLT файлове (*.xsl)"
+
+#: importdialog.cpp:281
+#, fuzzy
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.tc *.bc|Tellico файлове (*.tc)"
+
+#: importdialog.cpp:285
+#, fuzzy
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.xsl|XSLT файлове (*.xsl)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico не може да зареди файла %1."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico не може да пише във файл %1."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico не може да качи файла %1."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+
+#: tellico_strings.cpp:27
+#, fuzzy, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico не може да зареди файла %1."
+
+#: entryiconview.cpp:287
+#, fuzzy
+msgid "&Sort By"
+msgstr "Е&кспортиране"
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr ""
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr ""
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr ""
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr ""
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr ""
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr ""
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+
+#: loandialog.cpp:144
+#, fuzzy
+msgid "&Note:"
+msgstr "Е&кспортиране"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr ""
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr ""
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+
+#: mainwindow.cpp:188
+#, fuzzy
+msgid "Create a new collection"
+msgstr "Създава нов документ"
+
+#: mainwindow.cpp:192
+#, fuzzy
+msgid "New &Book Collection"
+msgstr "Колекция от книги"
+
+#: mainwindow.cpp:194
+#, fuzzy
+msgid "Create a new book collection"
+msgstr "Създава нов документ"
+
+#: mainwindow.cpp:200
+#, fuzzy
+msgid "New B&ibliography"
+msgstr "Импортира Bibtexml файл ..."
+
+#: mainwindow.cpp:202
+#, fuzzy
+msgid "Create a new bibtex bibliography"
+msgstr "Импортира Bibtexml файл ..."
+
+#: mainwindow.cpp:208
+#, fuzzy
+msgid "New &Comic Book Collection"
+msgstr "Колекция от книги"
+
+#: mainwindow.cpp:210
+#, fuzzy
+msgid "Create a new comic book collection"
+msgstr "Създава нов документ"
+
+#: mainwindow.cpp:216
+#, fuzzy
+msgid "New &Video Collection"
+msgstr "Видео колекция"
+
+#: mainwindow.cpp:218
+#, fuzzy
+msgid "Create a new video collection"
+msgstr "Създава нов документ"
+
+#: mainwindow.cpp:224
+#, fuzzy
+msgid "New &Music Collection"
+msgstr "Ново име за колекция"
+
+#: mainwindow.cpp:226
+#, fuzzy
+msgid "Create a new music collection"
+msgstr "Създава нов документ"
+
+#: mainwindow.cpp:232
+#, fuzzy
+msgid "New C&oin Collection"
+msgstr "Ново име за колекция"
+
+#: mainwindow.cpp:234
+#, fuzzy
+msgid "Create a new coin collection"
+msgstr "Създава нов документ"
+
+#: mainwindow.cpp:240
+#, fuzzy
+msgid "New &Stamp Collection"
+msgstr "Ново име за колекция"
+
+#: mainwindow.cpp:242
+#, fuzzy
+msgid "Create a new stamp collection"
+msgstr "Създава нов документ"
+
+#: mainwindow.cpp:248
+#, fuzzy
+msgid "New C&ard Collection"
+msgstr "Видео колекция"
+
+#: mainwindow.cpp:250
+#, fuzzy
+msgid "Create a new trading card collection"
+msgstr "Създава нов документ"
+
+#: mainwindow.cpp:256
+#, fuzzy
+msgid "New &Wine Collection"
+msgstr "Видео колекция"
+
+#: mainwindow.cpp:258
+#, fuzzy
+msgid "Create a new wine collection"
+msgstr "Създава нов документ"
+
+#: mainwindow.cpp:264
+#, fuzzy
+msgid "New &Game Collection"
+msgstr "Ново име за колекция"
+
+#: mainwindow.cpp:266
+#, fuzzy
+msgid "Create a new game collection"
+msgstr "Създава нов документ"
+
+#: mainwindow.cpp:272
+#, fuzzy
+msgid "New Boa&rd Game Collection"
+msgstr "Ново име за колекция"
+
+#: mainwindow.cpp:274
+#, fuzzy
+msgid "Create a new board game collection"
+msgstr "Създава нов документ"
+
+#: mainwindow.cpp:280
+#, fuzzy
+msgid "New &File Catalog"
+msgstr "Ново поле"
+
+#: mainwindow.cpp:282
+#, fuzzy
+msgid "Create a new file catalog"
+msgstr "Създава нов документ"
+
+#: mainwindow.cpp:288
+#, fuzzy
+msgid "New C&ustom Collection"
+msgstr "Ново име за колекция"
+
+#: mainwindow.cpp:290
+#, fuzzy
+msgid "Create a new custom collection"
+msgstr "Създава нов документ"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Отваря съществуващ документ"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Отваря наскоро използван файл"
+
+#: mainwindow.cpp:303
+#, fuzzy
+msgid "Save the document"
+msgstr "Записва текущия документ"
+
+#: mainwindow.cpp:305
+#, fuzzy
+msgid "Save the document as a different file..."
+msgstr "Записва текущия документ като ..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Отпечатва съдържанието на документа..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Изход от приложението"
+
+#: mainwindow.cpp:320
+#, fuzzy
+msgid "Import collection data from other formats"
+msgstr ""
+"Филтриране на колекцията за показване "
+"само на дадени книги..."
+
+#: mainwindow.cpp:324
+#, fuzzy
+msgid "Import Tellico Data..."
+msgstr "Импортира Bibtex файл..."
+
+#: mainwindow.cpp:325
+#, fuzzy
+msgid "Import another Tellico data file"
+msgstr "Импортира Bibtex файл..."
+
+#: mainwindow.cpp:331
+#, fuzzy
+msgid "Import CSV Data..."
+msgstr "Експортирам..."
+
+#: mainwindow.cpp:332
+#, fuzzy
+msgid "Import a CSV file"
+msgstr "Импортира Bibtexml файл ..."
+
+#: mainwindow.cpp:338
+#, fuzzy
+msgid "Import MODS Data..."
+msgstr "Експортирам..."
+
+#: mainwindow.cpp:339
+#, fuzzy
+msgid "Import a MODS data file"
+msgstr "Импортира Bibtexml файл ..."
+
+#: mainwindow.cpp:345
+#, fuzzy
+msgid "Import Alexandria Data..."
+msgstr "Импортира Bibtex файл..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr ""
+
+#: mainwindow.cpp:352
+#, fuzzy
+msgid "Import Delicious Library Data..."
+msgstr "Импортира Bibtex файл..."
+
+#: mainwindow.cpp:353
+#, fuzzy
+msgid "Import data from Delicious Library"
+msgstr "Импортиране от Bibtexml..."
+
+#: mainwindow.cpp:359
+#, fuzzy
+msgid "Import Referencer Data..."
+msgstr "Експортирам..."
+
+#: mainwindow.cpp:360
+#, fuzzy
+msgid "Import data from Referencer"
+msgstr "Импортира Bibtexml файл ..."
+
+#: mainwindow.cpp:366
+#, fuzzy
+msgid "Import Bibtex Data..."
+msgstr "Импортира Bibtex файл..."
+
+#: mainwindow.cpp:367
+#, fuzzy
+msgid "Import a bibtex bibliography file"
+msgstr "Импортира Bibtexml файл ..."
+
+#: mainwindow.cpp:373
+#, fuzzy
+msgid "Import Bibtexml Data..."
+msgstr "Импортира Bibtexml файл..."
+
+#: mainwindow.cpp:374
+#, fuzzy
+msgid "Import a Bibtexml bibliography file"
+msgstr "Импортира Bibtexml файл ..."
+
+#: mainwindow.cpp:380
+#, fuzzy
+msgid "Import RIS Data..."
+msgstr "Експортирам..."
+
+#: mainwindow.cpp:381
+#, fuzzy
+msgid "Import an RIS reference file"
+msgstr "Импортира Bibtexml файл ..."
+
+#: mainwindow.cpp:387
+#, fuzzy
+msgid "Import PDF File..."
+msgstr "Импортира Bibtex файл..."
+
+#: mainwindow.cpp:388
+#, fuzzy
+msgid "Import a PDF file"
+msgstr "Импортира Bibtexml файл ..."
+
+#: mainwindow.cpp:394
+#, fuzzy
+msgid "Import Audio File Metadata..."
+msgstr "Експортирам..."
+
+#: mainwindow.cpp:395
+#, fuzzy
+msgid "Import meta-data from audio files"
+msgstr "Импортиране от Bibtexml..."
+
+#: mainwindow.cpp:404
+#, fuzzy
+msgid "Import Audio CD Data..."
+msgstr "Експортирам..."
+
+#: mainwindow.cpp:405
+#, fuzzy
+msgid "Import audio CD information"
+msgstr "Експортирам..."
+
+#: mainwindow.cpp:414
+#, fuzzy
+msgid "Import GCstar Data..."
+msgstr "Експортирам..."
+
+#: mainwindow.cpp:415
+#, fuzzy
+msgid "Import a GCstar data file"
+msgstr "Импортира Bibtexml файл ..."
+
+#: mainwindow.cpp:421
+#, fuzzy
+msgid "Import Griffith Data..."
+msgstr "Експортирам..."
+
+#: mainwindow.cpp:422
+#, fuzzy
+msgid "Import a Griffith database"
+msgstr "Експортира към Bibtex файл..."
+
+#: mainwindow.cpp:428
+#, fuzzy
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Експортирам..."
+
+#: mainwindow.cpp:429
+#, fuzzy
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Импортира Bibtex файл..."
+
+#: mainwindow.cpp:435
+#, fuzzy
+msgid "Import File Listing..."
+msgstr "Импортира Bibtex файл..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr ""
+
+#: mainwindow.cpp:442
+#, fuzzy
+msgid "Import XSL Transform..."
+msgstr "Експортира,използвайки XSL Transform..."
+
+#: mainwindow.cpp:443
+#, fuzzy
+msgid "Import using an XSL Transform"
+msgstr "Експортира файл,използвайки XSL transform..."
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, fuzzy, no-c-format
+msgid "&Export"
+msgstr "Експортиране..."
+
+#: mainwindow.cpp:457
+#, fuzzy
+msgid "Export the collection data to other formats"
+msgstr ""
+"Филтриране на колекцията за показване "
+"само на дадени книги..."
+
+#: mainwindow.cpp:461
+#, fuzzy
+msgid "Export to XML..."
+msgstr "Е&кспортиране"
+
+#: mainwindow.cpp:462
+#, fuzzy
+msgid "Export to a Tellico XML file"
+msgstr "Експортира към Bibtex файл..."
+
+#: mainwindow.cpp:468
+#, fuzzy
+msgid "Export to Zip..."
+msgstr "Е&кспортиране"
+
+#: mainwindow.cpp:469
+#, fuzzy
+msgid "Export to a Tellico Zip file"
+msgstr "Експортира към Bibtex файл..."
+
+#: mainwindow.cpp:475
+#, fuzzy
+msgid "Export to HTML..."
+msgstr "Е&кспортиране"
+
+#: mainwindow.cpp:476
+#, fuzzy
+msgid "Export to an HTML file"
+msgstr "Експортира към Bibtex файл..."
+
+#: mainwindow.cpp:482
+#, fuzzy
+msgid "Export to CSV..."
+msgstr "Е&кспортиране"
+
+#: mainwindow.cpp:483
+#, fuzzy
+msgid "Export to a comma-separated values file"
+msgstr "Експортира към Bibtexml файл..."
+
+#: mainwindow.cpp:489
+#, fuzzy
+msgid "Export to PilotDB..."
+msgstr "Експортира към Bibtex файл..."
+
+#: mainwindow.cpp:490
+#, fuzzy
+msgid "Export to a PilotDB database"
+msgstr "Експортира към Bibtex файл..."
+
+#: mainwindow.cpp:496
+#, fuzzy
+msgid "Export to Alexandria..."
+msgstr "Експортира към Bibtex файл..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr ""
+
+#: mainwindow.cpp:503
+#, fuzzy
+msgid "Export to Bibtex..."
+msgstr "Експортира към Bibtex файл..."
+
+#: mainwindow.cpp:504
+#, fuzzy
+msgid "Export to a bibtex file"
+msgstr "Експортира към Bibtex файл..."
+
+#: mainwindow.cpp:510
+#, fuzzy
+msgid "Export to Bibtexml..."
+msgstr "Експортира към Bibtexml файл"
+
+#: mainwindow.cpp:511
+#, fuzzy
+msgid "Export to a Bibtexml file"
+msgstr "Експортира към Bibtexml файл..."
+
+#: mainwindow.cpp:517
+#, fuzzy
+msgid "Export to ONIX..."
+msgstr "Е&кспортиране"
+
+#: mainwindow.cpp:518
+#, fuzzy
+msgid "Export to an ONIX file"
+msgstr "Експортира към Bibtex файл..."
+
+#: mainwindow.cpp:524
+#, fuzzy
+msgid "Export to GCfilms..."
+msgstr "Е&кспортиране"
+
+#: mainwindow.cpp:525
+#, fuzzy
+msgid "Export to a GCfilms data file"
+msgstr "Експортира към Bibtex файл..."
+
+#: mainwindow.cpp:531
+#, fuzzy
+msgid "Export to GCstar..."
+msgstr "Е&кспортиране"
+
+#: mainwindow.cpp:532
+#, fuzzy
+msgid "Export to a GCstar data file"
+msgstr "Експортира към Bibtex файл..."
+
+#: mainwindow.cpp:536
+#, fuzzy
+msgid "Export XSL Transform..."
+msgstr "Експортира,използвайки XSL Transform..."
+
+#: mainwindow.cpp:537
+#, fuzzy
+msgid "Export using an XSL Transform"
+msgstr "Експортира файл,използвайки XSL transform..."
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr ""
+
+#: mainwindow.cpp:548
+#, fuzzy
+msgid "Copy the selected text to the clipboard"
+msgstr ""
+"Копиране на избраното в буфера за обмен..."
+
+#: mainwindow.cpp:550
+#, fuzzy
+msgid "Paste the clipboard contents"
+msgstr "Поставяне на съдържанието на буфера"
+
+#: mainwindow.cpp:552
+#, fuzzy
+msgid "Select all the entries in the collection"
+msgstr "Няма избрани полета в тази колекция"
+
+#: mainwindow.cpp:554
+#, fuzzy
+msgid "Deselect all the entries in the collection"
+msgstr "Няма избрани полета в тази колекция"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr ""
+
+#: mainwindow.cpp:559
+#, fuzzy
+msgid "Search the internet..."
+msgstr "Търсене в документа..."
+
+#: mainwindow.cpp:561
+#, fuzzy
+msgid "Advanced &Filter..."
+msgstr "Разширен филтър..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+#, fuzzy
+msgid "Filter the collection"
+msgstr "Редакция на полетата на колекцията..."
+
+#: mainwindow.cpp:569
+#, fuzzy
+msgid "&New Entry..."
+msgstr "Дуплициране на книга"
+
+#: mainwindow.cpp:572
+#, fuzzy
+msgid "Create a new entry"
+msgstr "Създава нов документ"
+
+#: controller.cpp:620 mainwindow.cpp:573
+#, fuzzy
+msgid "&Edit Entry..."
+msgstr "Изтрий книга"
+
+#: mainwindow.cpp:576
+#, fuzzy
+msgid "Edit the selected entries"
+msgstr "Изтриване на няколко книги ?"
+
+#: controller.cpp:621 mainwindow.cpp:577
+#, fuzzy
+msgid "D&uplicate Entry"
+msgstr "Дуплициране на книга"
+
+#: mainwindow.cpp:580
+#, fuzzy
+msgid "Copy the selected entries"
+msgstr "Изтриване на няколко книги ?"
+
+#: controller.cpp:623 mainwindow.cpp:581
+#, fuzzy
+msgid "&Delete Entry"
+msgstr "Изтриване на поле"
+
+#: mainwindow.cpp:584
+#, fuzzy
+msgid "Delete the selected entries"
+msgstr "Изтриване на няколко книги ?"
+
+#: mainwindow.cpp:585
+#, fuzzy
+msgid "&Merge Entries"
+msgstr "Изтриване на поле"
+
+#: mainwindow.cpp:588
+#, fuzzy
+msgid "Merge the selected entries"
+msgstr "Изтриване на няколко книги ?"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr ""
+
+#: mainwindow.cpp:594
+#, fuzzy
+msgid "Generate collection reports"
+msgstr "Създава нов документ"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr ""
+
+#: mainwindow.cpp:598
+#, fuzzy
+msgid "Check-out the selected items"
+msgstr "Изтриване на няколко книги ?"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr ""
+
+#: mainwindow.cpp:602
+#, fuzzy
+msgid "Check-in the selected items"
+msgstr "Изтриване на няколко книги ?"
+
+#: mainwindow.cpp:604
+#, fuzzy
+msgid "&Rename Collection..."
+msgstr "Преименувай колекцията"
+
+#: mainwindow.cpp:607
+#, fuzzy
+msgid "Rename the collection"
+msgstr "Преименувай колекцията"
+
+#: mainwindow.cpp:608
+#, fuzzy
+msgid "Collection &Fields..."
+msgstr "Полета на колекцията..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Редакция на полетата на колекцията..."
+
+#: mainwindow.cpp:612
+#, fuzzy
+msgid "Convert to &Bibliography"
+msgstr "Импортира Bibtexml файл ..."
+
+#: mainwindow.cpp:615
+#, fuzzy
+msgid "Convert a book collection to a bibliography"
+msgstr "Импортира Bibtexml файл ..."
+
+#: mainwindow.cpp:616
+#, fuzzy
+msgid "String &Macros..."
+msgstr "Оценка"
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr ""
+
+#: mainwindow.cpp:626
+#, fuzzy
+msgid "Copy Bibtex to Cli&pboard"
+msgstr ""
+"Копиране на избраното в буфера за обмен..."
+
+#: mainwindow.cpp:627
+#, fuzzy
+msgid "Copy bibtex citations to the clipboard"
+msgstr ""
+"Копиране на избраното в буфера за обмен..."
+
+#: mainwindow.cpp:632
+#, fuzzy
+msgid "Cite Entry in &LyX"
+msgstr "Изтрий книга"
+
+#: mainwindow.cpp:633
+#, fuzzy
+msgid "Cite the selected entries in LyX"
+msgstr "Изтриване на няколко книги ?"
+
+#: mainwindow.cpp:638
+#, fuzzy
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Изтрий книга"
+
+#: mainwindow.cpp:639
+#, fuzzy
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Изтриване на няколко книги ?"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, fuzzy, no-c-format
+msgid "&Update Entry"
+msgstr "Изтрий книга"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr ""
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr ""
+
+#: mainwindow.cpp:665
+#, fuzzy
+msgid "Show Grou&p View"
+msgstr "BCGroupView"
+
+#: mainwindow.cpp:668
+#, fuzzy
+msgid "Enable/disable the group view"
+msgstr "Показва/скрива тази лента"
+
+#: mainwindow.cpp:669
+#, fuzzy
+msgid "Hide Grou&p View"
+msgstr "BCGroupView"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr ""
+
+#: mainwindow.cpp:674
+#, fuzzy
+msgid "Enable/disable the editor"
+msgstr "Показва/скрива тази лента"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr ""
+
+#: mainwindow.cpp:677
+#, fuzzy
+msgid "Show Entry &View"
+msgstr "BCGroupView"
+
+#: mainwindow.cpp:680
+#, fuzzy
+msgid "Enable/disable the entry view"
+msgstr "Показва/скрива тази лента"
+
+#: mainwindow.cpp:681
+#, fuzzy
+msgid "Hide Entry &View"
+msgstr "BCGroupView"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr ""
+
+#: mainwindow.cpp:697
+#, fuzzy
+msgid "&Group Selection"
+msgstr "Опции за групиране"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Промяна на групирането на колекцията"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+#, fuzzy
+msgid "Filter"
+msgstr "Изтрий книга"
+
+#: mainwindow.cpp:705
+#, fuzzy
+msgid "Clear Filter"
+msgstr "Изтриване на поле?"
+
+#: mainwindow.cpp:710
+#, fuzzy
+msgid "Filter here..."
+msgstr "Критерии за филтриране"
+
+#: mainwindow.cpp:768
+#, fuzzy
+msgid "Groups"
+msgstr "Групирай по:"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:831
+#, fuzzy
+msgid "Welcome to the Tellico Collection Manager"
+msgstr ""
+"Tellico (Лавица) - програма за картотекиране "
+"на книги"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Създава нов документ..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Отваря файл..."
+
+#: mainwindow.cpp:1108
+#, fuzzy
+msgid "Open File"
+msgstr "Отваря файл..."
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Записва файл..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr ""
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr ""
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Записва файла с ново име ..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Отпечатване..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Процедирам с документа..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Излизам..."
+
+#: mainwindow.cpp:1498
+#, fuzzy, c-format
+msgid "Total entries: %1"
+msgstr "Изтриване на поле"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr ""
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr ""
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr ""
+
+#: mainwindow.cpp:1679
+#, fuzzy, c-format
+msgid "Print %1"
+msgstr "Печатане"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Страница %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Моля проверете инсталацията си."
+
+#: mainwindow.cpp:1849
+#, fuzzy
+msgid "Importing data..."
+msgstr "Експортирам..."
+
+#: mainwindow.cpp:1858
+#, fuzzy
+msgid "Import File"
+msgstr "Импортира Bibtex файл..."
+
+#: mainwindow.cpp:1864
+#, fuzzy
+msgid "Import Directory"
+msgstr "И&мпортиране"
+
+#: mainwindow.cpp:1885
+#, fuzzy
+msgid "Exporting data..."
+msgstr "Експортирам..."
+
+#: mainwindow.cpp:1907
+#, fuzzy
+msgid "Export As"
+msgstr "Е&кспортиране"
+
+#: mainwindow.cpp:1935
+#, fuzzy
+msgid "String Macros"
+msgstr "Оценка"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr ""
+
+#: mainwindow.cpp:1936
+#, fuzzy
+msgid "String"
+msgstr "Оценка"
+
+#: mainwindow.cpp:1999
+#, fuzzy
+msgid "Creating citations..."
+msgstr "Отрязване на избраното..."
+
+#: mainwindow.cpp:2104
+#, fuzzy
+msgid "Filters"
+msgstr "Изтрий книга"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:2121
+#, fuzzy
+msgid "Loans"
+msgstr "Дадена"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr ""
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+
+#: filehandler.cpp:193
+#, fuzzy, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico не може да зареди файла %1."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+"Файл с името \"%1\" вече съществува.Сигурни "
+"ли сте,че желаете да го презапишете ?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Презаписване на файл?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Презаписване"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr ""
+
+#: controller.cpp:427
+#, fuzzy
+msgid "Do you really want to delete this entry?"
+msgstr ""
+"Наистина ли жалете да изтриете тези книги "
+"?"
+
+#: controller.cpp:429
+#, fuzzy
+msgid "Delete Entry"
+msgstr "Изтриване на поле"
+
+#: controller.cpp:439
+#, fuzzy
+msgid "Do you really want to delete these entries?"
+msgstr ""
+"Наистина ли жалете да изтриете тези книги "
+"?"
+
+#: controller.cpp:443
+#, fuzzy
+msgid "Delete Multiple Entries"
+msgstr "Изтриване на няколко книги ?"
+
+#: controller.cpp:626
+#, fuzzy
+msgid "&Edit Entries..."
+msgstr "Изтрий книга"
+
+#: controller.cpp:627
+#, fuzzy
+msgid "D&uplicate Entries"
+msgstr "Дуплициране на книга"
+
+#: controller.cpp:628
+#, fuzzy
+msgid "&Update Entries"
+msgstr "Изтрий книга"
+
+#: controller.cpp:629
+#, fuzzy
+msgid "&Delete Entries"
+msgstr "Изтриване на поле"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr ""
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr ""
+
+#: calendarhandler.cpp:203
+#, fuzzy
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico не може да прочете файла %1."
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(Празно)"
+
+#: main.cpp:23
+#, fuzzy
+msgid "Tellico - a collection manager for KDE"
+msgstr ""
+"Tellico (Лавица) - програма за картотекиране "
+"на книги"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr ""
+
+#: main.cpp:28
+#, fuzzy
+msgid "Import <filename> as a bibtex file"
+msgstr "Експортира към Bibtex файл..."
+
+#: main.cpp:29
+#, fuzzy
+msgid "Import <filename> as a MODS file"
+msgstr "Импортира Bibtexml файл ..."
+
+#: main.cpp:30
+#, fuzzy
+msgid "Import <filename> as a RIS file"
+msgstr "Импортира Bibtexml файл ..."
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Файл за отваряне"
+
+#: main.cpp:42
+#, fuzzy
+msgid "Data source scripts"
+msgstr "Опции за форматиране"
+
+#: main.cpp:44
+#, fuzzy
+msgid "Icons"
+msgstr "съдържа"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr ""
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr ""
+
+#: main.cpp:50
+msgid "Author of libcsv library"
+msgstr ""
+
+#: main.cpp:52
+msgid "Author of rtf2html library"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:56
+#, fuzzy
+msgid "Collection Fields"
+msgstr "Полета на колекцията..."
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Текущи полета"
+
+#: collectionfieldsdialog.cpp:84
+#, fuzzy
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "Ново поле"
+
+#: collectionfieldsdialog.cpp:86
+#, fuzzy
+msgid "Add a new field to the collection"
+msgstr "Създава нов документ"
+
+#: collectionfieldsdialog.cpp:87
+#, fuzzy
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "Изтриване на поле"
+
+#: collectionfieldsdialog.cpp:89
+#, fuzzy
+msgid "Remove a field from the collection"
+msgstr "Редакция на полетата на колекцията..."
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Настройки на поле"
+
+#: collectionfieldsdialog.cpp:119
+#, fuzzy
+msgid "&Title:"
+msgstr "Заглавие:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:129
+#, fuzzy
+msgid "T&ype:"
+msgstr "Тип:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:157
+#, fuzzy
+msgid "Cate&gory:"
+msgstr "Категория:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:179
+#, fuzzy
+msgid "Descr&iption:"
+msgstr "Описание:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:203
+#, fuzzy
+msgid "A&llowed values:"
+msgstr "Позволено:"
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:215
+#, fuzzy
+msgid "Extended &properties:"
+msgstr "Настройки на поле"
+
+#: collectionfieldsdialog.cpp:217
+#, fuzzy
+msgid "&Set..."
+msgstr "Запиши като ..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Опции за форматиране"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Без форматиране"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Форматиране като заглавие"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Форматиране като име"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Настройки на полето"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Разрешава автоматично завършване"
+
+#: collectionfieldsdialog.cpp:243
+#, fuzzy
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Ако е избрано,книгите ще бъдат групирани "
+"по даден признак."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Позволява няколко стойности"
+
+#: collectionfieldsdialog.cpp:246
+#, fuzzy
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Позволени стойности,за това "
+"поле,разделени с ;"
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Позволява групиране"
+
+#: collectionfieldsdialog.cpp:249
+#, fuzzy
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Ако е избрано,броя на книгите в груптата "
+"ще бъде добавен към името й."
+
+#: collectionfieldsdialog.cpp:263
+#, fuzzy
+msgid "Revert the selected field's properties to the default values."
+msgstr "Няма избрани полета в тази колекция"
+
+#: collectionfieldsdialog.cpp:306
+#, fuzzy
+msgid "Modify Fields"
+msgstr "Бърз филтър"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:745
+#, fuzzy
+msgid "Revert Field Properties"
+msgstr "Настройки на поле"
+
+#: collectionfieldsdialog.cpp:746
+#, fuzzy
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"Настина ли желаете да изтриете полето %1? "
+"Няма връщане назад,ако го изтриете."
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:872
+#, fuzzy
+msgid "Extended Field Properties"
+msgstr "Настройки на поле"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr ""
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Текущият файл бе променен.\n"
+"Желаете ли да го запишете?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr ""
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr ""
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Настройка на Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Общи настройки"
+
+#: configdialog.cpp:201
+#, fuzzy
+msgid "&Reopen file at startup"
+msgstr ""
+"Отваряне на файл при пускане на "
+"приложението"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Ако е избрано,последно отвореният файл ще "
+"бъде отворен при повторно пускане на "
+"програмата."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr ""
+
+#: configdialog.cpp:208
+#, fuzzy
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr ""
+"Ако е избрано,последно отвореният файл ще "
+"бъде отворен при повторно пускане на "
+"програмата."
+
+#: configdialog.cpp:213
+#, fuzzy
+msgid "Image Storage Options"
+msgstr "Опции за форматиране"
+
+#: configdialog.cpp:214
+#, fuzzy
+msgid "Store images in data file"
+msgstr "Импортира Bibtexml файл ..."
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr ""
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr ""
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Настройки за форматиране"
+
+#: configdialog.cpp:227
+#, fuzzy
+msgid "Auto capitalize &titles and names"
+msgstr ""
+"Автоматично прави буквите в имената и "
+"заглавията главни"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Ако е избрана,заглавията и имената "
+"автоматично ще получат главни букви"
+
+#: configdialog.cpp:232
+#, fuzzy
+msgid "Auto &format titles and names"
+msgstr ""
+"Автоматично форматиране на заглавията и "
+"имената"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr ""
+"Ако е избрано,заглавията и имената ще "
+"бъдат форматирани автоматично."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr ""
+
+#: configdialog.cpp:243
+#, fuzzy
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"Списък от междуметия,думи със "
+"запетая,които не се числят към "
+"заглавие,ако са в началото му."
+
+#: configdialog.cpp:249
+#, fuzzy
+msgid "Artic&les:"
+msgstr "Междуметия:"
+
+#: configdialog.cpp:252
+#, fuzzy
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"Списък от междуметия,думи със "
+"запетая,които не се числят към "
+"заглавие,ако са в началото му."
+
+#: configdialog.cpp:259
+#, fuzzy
+msgid "Personal suffi&xes:"
+msgstr "Лични наставки:"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+
+#: configdialog.cpp:268
+#, fuzzy
+msgid "Surname &prefixes:"
+msgstr "Фамилни наставки:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Печатане"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Настройки за печат"
+
+#: configdialog.cpp:302
+#, fuzzy
+msgid "&Format titles and names"
+msgstr "Форматиране на заглавия и имена"
+
+#: configdialog.cpp:306
+#, fuzzy
+msgid "&Print field headers"
+msgstr "Печатане заглавията на полетата"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Опции за групиране"
+
+#: configdialog.cpp:313
+#, fuzzy
+msgid "&Group the entries"
+msgstr "Групиране на книгите"
+
+#: configdialog.cpp:317
+#, fuzzy
+msgid "Image Options"
+msgstr "Опции за форматиране"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr ""
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr ""
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr ""
+
+#: configdialog.cpp:355
+#, fuzzy
+msgid "Template Options"
+msgstr "Опции за форматиране"
+
+#: configdialog.cpp:369
+#, fuzzy
+msgid "Template:"
+msgstr "Опции за форматиране"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+
+#: configdialog.cpp:380
+#, fuzzy
+msgid "&Preview..."
+msgstr "Нова"
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr ""
+
+#: configdialog.cpp:398
+#, fuzzy
+msgid "Font Options"
+msgstr "Опции за форматиране"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr ""
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:415
+#, fuzzy
+msgid "Size:"
+msgstr "С автограф"
+
+#: configdialog.cpp:425
+#, fuzzy
+msgid "Color Options"
+msgstr "Настройки на полето"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr ""
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr ""
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr ""
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr ""
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr ""
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr ""
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr ""
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr ""
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr ""
+
+#: configdialog.cpp:487
+#, fuzzy
+msgid "Delete..."
+msgstr "Избор на XSLT файл..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr ""
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr ""
+
+#: configdialog.cpp:501
+#, fuzzy
+msgid "Data Source Options"
+msgstr "Опции за форматиране"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr ""
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr ""
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr ""
+
+#: configdialog.cpp:528
+#, fuzzy
+msgid "&New..."
+msgstr "Нова"
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr ""
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr ""
+
+#: configdialog.cpp:533
+#, fuzzy
+msgid "Click to modify the selected data source."
+msgstr "Изтриване на няколко книги ?"
+
+#: configdialog.cpp:536
+#, fuzzy
+msgid "Click to delete the selected data source."
+msgstr "Изтриване на няколко книги ?"
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr ""
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr ""
+
+#: configdialog.cpp:1049
+#, fuzzy
+msgid "Delete Template"
+msgstr "Изтриване на поле?"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr ""
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr ""
+
+#: loanview.cpp:74
+#, fuzzy
+msgid "Check-in"
+msgstr "Кутийка"
+
+#: loanview.cpp:76
+#, fuzzy
+msgid "Modify Loan..."
+msgstr "Промяна на книга"
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr ""
+
+#: collectionfactory.cpp:81
+#, fuzzy
+msgid "My Collection"
+msgstr "BCCollection"
+
+#: collectionfactory.cpp:124
+#, fuzzy
+msgid "Book Collection"
+msgstr "Колекция от книги"
+
+#: collectionfactory.cpp:126
+#, fuzzy
+msgid "Comic Book Collection"
+msgstr "Колекция от книги"
+
+#: collectionfactory.cpp:127
+#, fuzzy
+msgid "Video Collection"
+msgstr "Видео колекция"
+
+#: collectionfactory.cpp:128
+#, fuzzy
+msgid "Music Collection"
+msgstr "BCCollection"
+
+#: collectionfactory.cpp:129
+#, fuzzy
+msgid "Coin Collection"
+msgstr "Музикална колекция"
+
+#: collectionfactory.cpp:130
+#, fuzzy
+msgid "Stamp Collection"
+msgstr "Преименувай колекцията"
+
+#: collectionfactory.cpp:131
+#, fuzzy
+msgid "Wine Collection"
+msgstr "Видео колекция"
+
+#: collectionfactory.cpp:132
+#, fuzzy
+msgid "Card Collection"
+msgstr "BCCollection"
+
+#: collectionfactory.cpp:133
+#, fuzzy
+msgid "Game Collection"
+msgstr "Преименувай колекцията"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr ""
+
+#: collectionfactory.cpp:135
+#, fuzzy
+msgid "Board Game Collection"
+msgstr "Преименувай колекцията"
+
+#: collectionfactory.cpp:136
+#, fuzzy
+msgid "Custom Collection"
+msgstr "Ново име за колекция"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+
+#: exportdialog.cpp:48
+#, fuzzy
+msgid "Export Options"
+msgstr "Опции за форматиране"
+
+#: exportdialog.cpp:53
+#, fuzzy
+msgid "Formatting"
+msgstr "Без форматиране"
+
+#: exportdialog.cpp:55
+#, fuzzy
+msgid "Format all fields"
+msgstr "Форматиране като заглавие"
+
+#: exportdialog.cpp:57
+#, fuzzy
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Ако е избрано,заглавията и имената ще "
+"бъдат форматирани автоматично."
+
+#: exportdialog.cpp:59
+#, fuzzy
+msgid "Export selected entries only"
+msgstr "Изтриване на няколко книги ?"
+
+#: exportdialog.cpp:61
+#, fuzzy
+msgid "If checked, only the currently selected entries will be exported."
+msgstr ""
+"Ако е избрано,заглавията на полетата ще "
+"бъдат отпечатани."
+
+#: exportdialog.cpp:64
+#, fuzzy
+msgid "Encoding"
+msgstr "Корица"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr ""
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr ""
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr ""
+
+#: exportdialog.cpp:72
+msgid "Encode the exported file in the local encoding."
+msgstr ""
+
+#: fetchdialog.cpp:65
+#, fuzzy
+msgid "&Search"
+msgstr "Търси в :"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr ""
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr ""
+
+#: fetchdialog.cpp:94
+#, fuzzy
+msgid "Search Query"
+msgstr "Търси в :"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr ""
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr ""
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr ""
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr ""
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr ""
+
+#: fetchdialog.cpp:138
+#, fuzzy
+msgid "Edit List..."
+msgstr "Редакция..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+
+#: fetchdialog.cpp:146
+#, fuzzy
+msgid "Search s&ource:"
+msgstr "Търси в :"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr ""
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+
+#: fetchdialog.cpp:192
+#, fuzzy
+msgid "&Add Entry"
+msgstr "Изтрий книга"
+
+#: fetchdialog.cpp:196
+#, fuzzy
+msgid "Add the selected entry to the current collection"
+msgstr "Създава нов документ"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr ""
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr ""
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr ""
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr ""
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+#, fuzzy
+msgid "Searching..."
+msgstr "Търси в :"
+
+#: fetchdialog.cpp:368
+#, fuzzy
+msgid "The search returned no items."
+msgstr "Стринг за търсене"
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+
+#: fetchdialog.cpp:412
+msgid "No results were found for the following ISBN values:"
+msgstr ""
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr ""
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr ""
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr ""
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr ""
+
+#: fetchdialog.cpp:604
+#, fuzzy
+msgid "&Load From File..."
+msgstr "Импортира Bibtex файл..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr ""
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+#, fuzzy
+msgid "Edit Entry"
+msgstr "Изтрий книга"
+
+#: entryeditdialog.cpp:52
+#, fuzzy
+msgid "&New Entry"
+msgstr "Дуплициране на книга"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+#, fuzzy
+msgid "Sa&ve Entry"
+msgstr "Дуплициране на книга"
+
+#: entryeditdialog.cpp:77
+#, fuzzy
+msgid "Go to the previous entry in the collection"
+msgstr "Промяна на групирането на колекцията"
+
+#: entryeditdialog.cpp:82
+#, fuzzy
+msgid "Go to the next entry in the collection"
+msgstr "Няма избрани полета в тази колекция"
+
+#: entryeditdialog.cpp:315
+#, fuzzy
+msgid "Do you really want to modify these entries?"
+msgstr ""
+"Наистина ли жалете да изтриете тези книги "
+"?"
+
+#: entryeditdialog.cpp:317
+#, fuzzy
+msgid "Modify Multiple Entries"
+msgstr "Редакция на няколко книги ?"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr ""
+
+#: entryeditdialog.cpp:456
+#, fuzzy
+msgid "Edit Entries"
+msgstr "Изтрий книга"
+
+#: entryeditdialog.cpp:488
+#, fuzzy
+msgid "Sa&ve Entries"
+msgstr "Изтриване на поле"
+
+#: entryeditdialog.cpp:656
+#, fuzzy
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"Текущата книга бе променена.\n"
+"Желаете ли да запазите промените?"
+
+#: entryeditdialog.cpp:659
+#, fuzzy
+msgid "Save Entry"
+msgstr "Дуплициране на книга"
+
+#: reportdialog.cpp:53
+#, fuzzy
+msgid "Collection Report"
+msgstr "Летна \"Колекция\""
+
+#: reportdialog.cpp:60
+#, fuzzy
+msgid "&Report template:"
+msgstr "Импортира Bibtexml файл..."
+
+#: reportdialog.cpp:83
+#, fuzzy
+msgid "&Generate"
+msgstr "Общи"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr ""
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+
+#: tellico_kernel.cpp:285
+#, fuzzy
+msgid "Do you really want to delete this filter?"
+msgstr ""
+"Наистина ли жалете да изтриете тези книги "
+"?"
+
+#: tellico_kernel.cpp:287
+#, fuzzy
+msgid "Delete Filter?"
+msgstr "Изтриване на поле?"
+
+#: tellico_kernel.cpp:323
+#, fuzzy
+msgid "New collection name:"
+msgstr "Ново име за колекция"
+
+#: tellico_kernel.cpp:377
+#, fuzzy
+msgid "Entry 1"
+msgstr "Поредица"
+
+#: tellico_kernel.cpp:378
+#, fuzzy
+msgid "Entry 2"
+msgstr "Поредица"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr ""
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+#, fuzzy
+msgid "Merge Entries"
+msgstr "Изтриване на поле"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr ""
+
+#: entryview.cpp:186
+#, fuzzy
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico не може да зареди файла %1."
+
+#: rc.cpp:6
+#, fuzzy, no-c-format
+msgid "&New"
+msgstr "Нова"
+
+#: rc.cpp:15
+#, fuzzy, no-c-format
+msgid "&Collection"
+msgstr "BCCollection"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Летна \"Колекция\""
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Боян Иванов"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "boyan17@bulgaria.com"
+
+#: entrymerger.cpp:35
+#, fuzzy
+msgid "Merging entries..."
+msgstr "Изтрий книга"
+
+#: entrymerger.cpp:49
+#, fuzzy
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Изтриване на поле"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr ""
+
+#: xslt.cpp:3
+#, fuzzy
+msgid "This template is meant for music collections only."
+msgstr "Създава нов документ"
+
+#: xslt.cpp:5
+#, fuzzy
+msgid "Total:"
+msgstr "%1 Общо"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr ""
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr ""
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr ""
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr ""
+
+#: xslt.cpp:14 xslt.cpp:43
+#, fuzzy
+msgid "This template is meant for video collections only."
+msgstr "Създава нов документ"
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr ""
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ""
+
+#: xslt.cpp:18
+#, fuzzy
+msgid "Total number of fields:"
+msgstr "Изтриване на поле"
+
+#: xslt.cpp:19
+#, fuzzy
+msgid "Total number of entries:"
+msgstr "Изтриване на поле"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+#, fuzzy
+msgid "Generated by Tellico"
+msgstr "Общи"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr ""
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr ""
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr ""
+
+#: xslt.cpp:27 xslt.cpp:29
+#, fuzzy
+msgid "Loan Date"
+msgstr "Дадена"
+
+#: xslt.cpp:28 xslt.cpp:31
+#, fuzzy
+msgid "Note"
+msgstr "Е&кспортиране"
+
+#: xslt.cpp:30
+#, fuzzy
+msgid "Due Date"
+msgstr "Дата на покупка"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr ""
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr ""
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr ""
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr ""
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr ""
+
+#: xslt.cpp:44
+#, fuzzy
+msgid "Search"
+msgstr "Търси в :"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr ""
+
+#: z3950.cpp:6
+#, fuzzy
+msgid "Sudoc (France)"
+msgstr "&Търси"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr ""
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr ""
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr ""
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr ""
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr ""
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr ""
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr ""
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr ""
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr ""
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr ""
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr ""
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr ""
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr ""
+
+#, fuzzy
+#~ msgid "GCstar"
+#~ msgstr "Касета"
+
+#, fuzzy
+#~ msgid "Griffith"
+#~ msgstr "Подарък"
+
+#, fuzzy
+#~ msgid "Comics"
+#~ msgstr "съдържа"
+
+#, fuzzy
+#~ msgid "Coins"
+#~ msgstr "съдържа"
+
+#~ msgid "Books"
+#~ msgstr "Книги"
+
+#, fuzzy
+#~ msgid "Wines"
+#~ msgstr "Моите клипове"
+
+#~ msgid "Videos"
+#~ msgstr "Клипове"
+
+#, fuzzy
+#~ msgid "Games"
+#~ msgstr "Номер от поредица"
+
+#, fuzzy
+#~ msgid "Cards"
+#~ msgstr "Касета"
+
+#, fuzzy
+#~ msgid "Entries"
+#~ msgstr "Поредица"
+
+#, fuzzy
+#~ msgid "Albums"
+#~ msgstr "Албум"
+
+#, fuzzy
+#~ msgid "Copac"
+#~ msgstr "Коментар"
+
+#~ msgid "Tellico"
+#~ msgstr "Лавица"
+
+#, fuzzy
+#~ msgid "&Copy Entry"
+#~ msgstr "Дуплициране на книга"
+
+#, fuzzy
+#~ msgid "&Copy Entries"
+#~ msgstr "Дуплициране на книга"
+
+#, fuzzy
+#~ msgid "Scanning CDDB cache files..."
+#~ msgstr "Записва файл..."
+
+#, fuzzy
+#~ msgid "Collection &type: "
+#~ msgstr "BCCollection"
+
+#, fuzzy
+#~ msgid "Save Entries"
+#~ msgstr "Изтриване на поле"
+
+#, fuzzy
+#~ msgid ""
+#~ "_: Save (Entry Title)\n"
+#~ "Save %1"
+#~ msgstr "Изтриване на поле"
+
+#~ msgid "Enable/disable the statusbar"
+#~ msgstr "Показва/скрива долната лента"
+
+#, fuzzy
+#~ msgid "Reading files..."
+#~ msgstr "Записва файл..."
+
+#, fuzzy
+#~ msgid "S&earch:"
+#~ msgstr "Търси в :"
+
+#, fuzzy
+#~ msgid "Group by:"
+#~ msgstr "Групирай по:"
+
+#, fuzzy
+#~ msgid "Quick filter:"
+#~ msgstr "Бърз филтър"
+
+#, fuzzy
+#~ msgid "Filter Entry"
+#~ msgstr "Изтрий книга"
+
+#, fuzzy
+#~ msgid "Tellico: %1 is due to return %2"
+#~ msgstr "Tellico не може да прочете файла %1."
+
+#~ msgid "Find Text"
+#~ msgstr "Търси текст"
+
+#~ msgid "&Find"
+#~ msgstr "&Търси"
+
+#, fuzzy
+#~ msgid "Find"
+#~ msgstr "&Търси"
+
+#~ msgid "&Text to find:"
+#~ msgstr "Текст за търсене"
+
+#~ msgid "The search string"
+#~ msgstr "Стринг за търсене"
+
+#~ msgid "As regular e&xpression"
+#~ msgstr "Като &регулярен израз"
+
+#~ msgid "If checked, the search string is used as a regular expression."
+#~ msgstr ""
+#~ "Ако е избрано,низът за търсене се "
+#~ "използва като регулярен израз."
+
+#, fuzzy
+#~ msgid "&Edit Regular Expression..."
+#~ msgstr "&Редакция на обикновените изрази..."
+
+#, fuzzy
+#~ msgid "Field"
+#~ msgstr "Полета"
+
+#~ msgid "Search in:"
+#~ msgstr "Търси в :"
+
+#~ msgid "Select which field should be searched."
+#~ msgstr "Указва полетата,в които ще се търси."
+
+#~ msgid "C&ase sensitive"
+#~ msgstr ""
+#~ "&Чувствително към главни и малки букви"
+
+#~ msgid "If checked, the search is case-sensitive."
+#~ msgstr ""
+#~ "Ако е избрано,прави разлика м/у малки и "
+#~ "големи букви."
+
+#~ msgid "Find &backwards"
+#~ msgstr "Търси &назад"
+
+#~ msgid "If checked, the document is searched in reverse."
+#~ msgstr ""
+#~ "Ако е избрано се провежда търсене назад."
+
+#~ msgid "&Whole words only"
+#~ msgstr "Само &цели думи"
+
+#~ msgid "If checked, the search is limited to whole words."
+#~ msgstr ""
+#~ "Ако е избрано,търсенето се ограничава до "
+#~ "цели думи"
+
+#~ msgid "All Fields"
+#~ msgstr "Всички полета"
+
+#~ msgid "Invalid regular expression."
+#~ msgstr "Грешен израз"
+
+#~ msgid "5 - Best"
+#~ msgstr "5 - Невероятна"
+
+#~ msgid "4 - Good"
+#~ msgstr "4 - Добра"
+
+#~ msgid "3 - Neutral"
+#~ msgstr "3 - Средна"
+
+#~ msgid "2 - Bad"
+#~ msgstr "2 - Лоша"
+
+#~ msgid "1 - Worst"
+#~ msgstr "1 - Ужасна"
+
+#, fuzzy
+#~ msgid "Table (2 Columns)"
+#~ msgstr "Показва колони"
+
+#, fuzzy
+#~ msgid "Delete Entry?"
+#~ msgstr "Изтриване на поле"
+
+#~ msgid "Warning!"
+#~ msgstr "Предупреждение !"
+
+#, fuzzy
+#~ msgid "(grouped by %1; sorted by %2)"
+#~ msgstr "(сортирано по %1)"
+
+#~ msgid "(sorted by %1)"
+#~ msgstr "(сортирано по %1)"
+
+#, fuzzy
+#~ msgid ""
+#~ "<qt><p>Do you really want to delete the <em>%1</em> field? This action "
+#~ "occurs immediately and can not be undone!</p></qt>"
+#~ msgstr ""
+#~ "Настина ли желаете да изтриете полето %1? "
+#~ "Няма връщане назад,ако го изтриете."
+
+#, fuzzy
+#~ msgid "Search the collection"
+#~ msgstr "Преименувай колекцията"
+
+#, fuzzy
+#~ msgid "Find next match in the collection"
+#~ msgstr ""
+#~ "Промяна на групирането на колекцията"
+
+#, fuzzy
+#~ msgid "Reports"
+#~ msgstr "Експортиране..."
+
+#~ msgid "Show number of items in group"
+#~ msgstr "Показва броя участници в групата"
+
+#~ msgid "Search string '%1' not found."
+#~ msgstr "Търсеният низ \"%1\" не бе намерен."
+
+#, fuzzy
+#~ msgid "Video"
+#~ msgstr "Клипове"
+
+#, fuzzy
+#~ msgid "*.bc .tc|Tellico files (*.tc)"
+#~ msgstr "*.tc *.bc|Tellico файлове (*.tc)"
+
+#, fuzzy
+#~ msgid "*.ogg|Ogg files (*.ogg)"
+#~ msgstr "*.xml|XML файлове (*.xml)"
+
+#~ msgid "&From Beginning"
+#~ msgstr "&От началото"
+
+#~ msgid "If checked, the document is searched from the beginning."
+#~ msgstr ""
+#~ "Ако е избрано,търсенето започва от "
+#~ "началото на документа."
+
+#~ msgid "Do you really want to modify these books?"
+#~ msgstr ""
+#~ "Наистина ли желаете да редактирате тези "
+#~ "книги ?"
+
+#, fuzzy
+#~ msgid "Export images"
+#~ msgstr "Е&кспортиране"
+
+#~ msgid "(Requires restart)"
+#~ msgstr "(Изисква повторно стартиране)"
+
+#~ msgid ""
+#~ "A comma-separated list of suffixes which might be used in personal names."
+#~ msgstr ""
+#~ "Списък от думи,разделени със "
+#~ "запетая,които се използват за създаване "
+#~ "на фамилни имена."
+
+#~ msgid "A comma-separated list of prefixes which might be used in surnames."
+#~ msgstr ""
+#~ "Списък от думи,разделени със "
+#~ "запетая,които могат да бъдат използвани "
+#~ "за фамилии."
+
+#~ msgid "Enable/disable the toolbar"
+#~ msgstr "Показва/скрива тази лента"
+
+#~ msgid "Show Co&llection ToolBar"
+#~ msgstr "Показва лентата \"ко&лекция\""
+
+#~ msgid "Enable/disable the collection toolbar"
+#~ msgstr "Показва/скрива лента \"колекция\""
+
+#, fuzzy
+#~ msgid "*.bcz|Tellico files(*.bcz)"
+#~ msgstr "*.tc *.bc|Tellico файлове (*.tc)"
+
+#~ msgid "List"
+#~ msgstr "Списък"
+
+#, fuzzy
+#~ msgid "Good"
+#~ msgstr "4 - Добра"
+
+#, fuzzy
+#~ msgid "New Entry"
+#~ msgstr "Дуплициране на книга"
+
+#~ msgid "Toggling toolbar..."
+#~ msgstr "Промяна на лентата с инструменти..."
+
+#~ msgid "Toggling collection toolbar..."
+#~ msgstr "Промяна на лента \"Колекции\""
+
+#~ msgid "Toggle the statusbar..."
+#~ msgstr "Промяна на статус лентата..."
+
+#~ msgid "Tellico is unable to find a required file - %1.\n"
+#~ msgstr ""
+#~ "Tellico не може да намери необходимият файл "
+#~ "%1.\n"
+
+#, fuzzy
+#~ msgid "&New Collection"
+#~ msgstr "Ново име за колекция"
+
+#~ msgid "BCUnitEditWidget"
+#~ msgstr "BCUnitEditWidget"
+
+#, fuzzy
+#~ msgid "TextImporter"
+#~ msgstr "И&мпортиране"
+
+#, fuzzy
+#~ msgid "XSLTImporter"
+#~ msgstr "И&мпортиране"
+
+#, fuzzy
+#~ msgid "CSVImporter"
+#~ msgstr "Е&кспортиране"
+
+#, fuzzy
+#~ msgid "BibtexImporter"
+#~ msgstr "И&мпортиране"
+
+#~ msgid "BCAttributeWidget"
+#~ msgstr "BCAttributeWidget"
+
+#~ msgid "Tellico is unable to open the file - %1."
+#~ msgstr "Tellico не може да отвори файла %1."
+
+#~ msgid "BCTabControl"
+#~ msgstr "BCTabControl"
+
+#, fuzzy
+#~ msgid "Processing new entries..."
+#~ msgstr "Процедирам с документа..."
+
+#, fuzzy
+#~ msgid "If checked, the first row is used as field headers."
+#~ msgstr ""
+#~ "Ако е избрано,заглавията на полетата ще "
+#~ "бъдат отпечатани."
+
+#, fuzzy
+#~ msgid "Collection Field in this Column:"
+#~ msgstr "Полета на колекцията..."
+
+#~ msgid "Tellico is unable to find the file - %1."
+#~ msgstr "Tellico не може да намери файла %1."
+
+#~ msgid "Tellico is unable to download the file - %1."
+#~ msgstr "Tellico не може да свали файла %1."
+
+#~ msgid "Edit Collection Fields"
+#~ msgstr "Редакция на полетата за колекция"
+
+#~ msgid "The fields are grouped by common categories for editing."
+#~ msgstr "Полетата са групирани по категории."
+
+#~ msgid "The collection is grouped by this field."
+#~ msgstr ""
+#~ "Колекцията е групирана по този признак."
+
+#~ msgid "These are the available fields in the collection."
+#~ msgstr ""
+#~ "Това са наличните полета за колекцията."
+
+#~ msgid "Selected Fields"
+#~ msgstr "Избрани полета"
+
+#, fuzzy
+#~ msgid "Import..."
+#~ msgstr "Експортиране..."
+
+#, fuzzy
+#~ msgid "Read Only"
+#~ msgstr "Готово."
+
+#, fuzzy
+#~ msgid "Text"
+#~ msgstr "Търси текст"
+
+#, fuzzy
+#~ msgid "Enoding Options"
+#~ msgstr "Опции за групиране"
+
+#~ msgid "Edit Collection Fields..."
+#~ msgstr "Редакция на полетата на колекцията"
+
+#, fuzzy
+#~ msgid "&Create new collection"
+#~ msgstr "Създава нов документ"
+
+#, fuzzy
+#~ msgid "*.txt|Text files (*.txt)"
+#~ msgstr "*.xsl|XSLT файлове (*.xsl)"
+
+#~ msgid "New Book"
+#~ msgstr "Нова книга"
+
+#~ msgid "Modify Books"
+#~ msgstr "Редакция на книги"
+
+#~ msgid "Delete Books"
+#~ msgstr "Изтриване на книги"
+
+#~ msgid "Lookup book..."
+#~ msgstr "Търсене на книга..."
+
+#~ msgid "Group Books By"
+#~ msgstr "Групира книги по"
+
+#~ msgid "Configure the options for the application..."
+#~ msgstr "Настройва приложението"
+
+#~ msgid "Importing from Bibtex..."
+#~ msgstr "Импортиране от Bibtex..."
+
+#~ msgid "Import from Bibtex..."
+#~ msgstr "Импортиране от Bibtex..."
+
+#~ msgid "Importing from Bibtexml..."
+#~ msgstr "Импортиране от Bibtexml..."
+
+#~ msgid "Song"
+#~ msgstr "Песен"
+
+#~ msgid "CD"
+#~ msgstr "Диск"
diff --git a/po/ca.po b/po/ca.po
new file mode 100644
index 0000000..1cc6a64
--- /dev/null
+++ b/po/ca.po
@@ -0,0 +1,5375 @@
+# translation of ca.po to Català
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+# David Majà <davidmaja@gmail.com>, 2005.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ca\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2005-06-21 17:16+0200\n"
+"Last-Translator: David Majà <davidmaja@gmail.com>\n"
+"Language-Team: Català\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.9.1\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "<qt>No es pot escriure al conducte del servidor en <b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr ""
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr ""
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+
+#: cite/openoffice.cpp:191
+#, fuzzy
+msgid "Pipe"
+msgstr "Persones"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:181
+#, fuzzy
+msgid "Rename Column"
+msgstr "&Reanomena col·lecció"
+
+#: gui/tablefieldwidget.cpp:181
+#, fuzzy
+msgid "New column name:"
+msgstr "Nova col·lecció de música"
+
+#: gui/tablefieldwidget.cpp:206
+#, fuzzy, c-format
+msgid "Column %1"
+msgstr "Veure columnes"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+#, fuzzy
+msgid "Rename Column..."
+msgstr "&Reanomena col·lecció"
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:295
+#, fuzzy
+msgid "Clear Table"
+msgstr "Voleu suprimir l'entrada?"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr ""
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr ""
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr ""
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr ""
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr ""
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr ""
+
+#: gui/imagewidget.cpp:57
+#, fuzzy
+msgid "Select Image..."
+msgstr "Imatge de la etiqueta"
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr ""
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr ""
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr ""
+
+#: commands/collectioncommand.cpp:110
+#, fuzzy
+msgid "Append Collection"
+msgstr "Afegeix a la col·lecció actual"
+
+#: commands/collectioncommand.cpp:112
+#, fuzzy
+msgid "Merge Collection"
+msgstr "Nova col·lecció de vídeos"
+
+#: commands/collectioncommand.cpp:114
+#, fuzzy
+msgid "Replace Collection"
+msgstr "Reemplaça la col·lecció actual"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+#, fuzzy
+msgid "Modify Entries"
+msgstr "&Edita les entrades"
+
+#: commands/fieldcommand.cpp:104
+#, fuzzy
+msgid "Add %1 Field"
+msgstr "Qualsevol camp"
+
+#: commands/fieldcommand.cpp:106
+#, fuzzy
+msgid "Modify %1 Field"
+msgstr "Qualsevol camp"
+
+#: commands/fieldcommand.cpp:108
+#, fuzzy
+msgid "Delete %1 Field"
+msgstr "&Suprimeix les entrades"
+
+#: commands/addentries.cpp:50
+#, fuzzy
+msgid "Add Entries"
+msgstr "&Edita les entrades"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr ""
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr ""
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr ""
+
+#: commands/filtercommand.cpp:98
+#, fuzzy
+msgid "Add Filter"
+msgstr "Filtre avançat"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+#, fuzzy
+msgid "Modify Filter"
+msgstr "Filtre ràpid:"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+#, fuzzy
+msgid "Delete Filter"
+msgstr "Voleu suprimir l'entrada?"
+
+#: commands/addloans.cpp:108
+#, fuzzy
+msgid "Check-out Items"
+msgstr "Copia les entrades seleccionades"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr ""
+
+#: commands/removeentries.cpp:48
+#, fuzzy
+msgid "Delete Entries"
+msgstr "&Suprimeix les entrades"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr ""
+
+#: commands/reorderfields.cpp:54
+#, fuzzy
+msgid "Reorder Fields"
+msgstr "Qualsevol camp"
+
+#: commands/removeloans.cpp:79
+#, fuzzy
+msgid "Check-in Entries"
+msgstr "&Edita les entrades"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr ""
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "General"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Condició"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Personal"
+
+#: collections/stampcollection.cpp:27
+#, fuzzy
+msgid "My Stamps"
+msgstr "Els meus vins"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Títol"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Descripció"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Denominació"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "País"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Any d'edició"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Color"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr ""
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr ""
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+#, fuzzy
+msgid "Grade"
+msgstr "Pàgines"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Cancel·lat"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+#, fuzzy
+msgid "Hinged"
+msgstr "Dedicat"
+
+#: collections/stampcollection.cpp:95
+#, fuzzy
+msgid "Centering"
+msgstr "Cadena"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Data de compra"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Preu de compra"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Localitat"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr ""
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Imatge"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Comentaris"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Publicació"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Classificació"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Els meus còmics"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Subtítol"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Escriptor"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Sèrie"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Edició"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Editor"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Edició"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Any de publicació"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Pàgines"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Idioma"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Gènere"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Paraules clau"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr ""
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Dedicat"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr ""
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr ""
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Les meves monedes"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Tipus"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Any"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr ""
+
+#: collections/coincollection.cpp:73
+#, fuzzy
+msgid "Coin Set"
+msgstr "Monedes"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr ""
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr ""
+
+#: collections/coincollection.cpp:122
+#, fuzzy
+msgid "Obverse"
+msgstr "Sobreescriu"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr ""
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Els meus llibres"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Autor"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr ""
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr ""
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr ""
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "Llibre electronic"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Revista"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Diari"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Vinculació"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Any del Copyright"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN#"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Número internacional estàndard del llibre"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN#"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr ""
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr ""
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Número de sèrie"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Nou"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Usat"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Llegit"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Puntuació"
+
+#: collections/filecatalog.cpp:25
+#, fuzzy
+msgid "My Files"
+msgstr "Els meus vins"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+#, fuzzy
+msgid "Name"
+msgstr "Número"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Volum"
+
+#: collections/filecatalog.cpp:55
+#, fuzzy
+msgid "Folder"
+msgstr "Filtra entrada"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr ""
+
+#: collections/filecatalog.cpp:65
+#, fuzzy
+msgid "Size"
+msgstr "Dedicat"
+
+#: collections/filecatalog.cpp:69
+#, fuzzy
+msgid "Permissions"
+msgstr "Personal"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr ""
+
+#: collections/filecatalog.cpp:79
+#, fuzzy
+msgid "Group"
+msgstr "Agrupa per:"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr ""
+
+#: collections/filecatalog.cpp:89
+#, fuzzy
+msgid "Modified"
+msgstr "Qualsevol camp"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr ""
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr ""
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Els meus vins"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Productor"
+
+#: collections/winecollection.cpp:49
+#, fuzzy
+msgid "Appellation"
+msgstr "Afegeix a la col·lecció actual"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr ""
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr ""
+
+#: collections/winecollection.cpp:67
+#, fuzzy
+msgid "Red Wine"
+msgstr "Els meus vins"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr ""
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr ""
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Qunatitat"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr ""
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Imatge de la etiqueta"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+#, fuzzy
+msgid "Other People"
+msgstr "Persones"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Característiques"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Els meus vídeos"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr ""
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+#, fuzzy
+msgid "HD DVD"
+msgstr "DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Suport"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Any de producció"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Certificació"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Regió 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Regió 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Regió 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Regió 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Regió 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Regió 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Regió 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Regió 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Regió"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Nacionalitat"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Format"
+
+#: collections/videocollection.cpp:100
+#, fuzzy
+msgid "Cast"
+msgstr "Cassette"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr ""
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+#, fuzzy
+msgid "Role"
+msgstr "Volum"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr ""
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Director"
+
+#: collections/videocollection.cpp:127
+#, fuzzy
+msgid "Composer"
+msgstr "Color"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Estudi"
+
+#: collections/videocollection.cpp:139
+#, fuzzy
+msgid "Language Tracks"
+msgstr "Idioma"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Idiomes dels Subtítols"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Pistes d'àudio"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr ""
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr ""
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Ràtio d'aspecte"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr ""
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Blanc i negre"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Color"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+#, fuzzy
+msgid "Director's Cut"
+msgstr "Director"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr ""
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Puntuació personal"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+#, fuzzy
+msgid "Cover"
+msgstr "Color"
+
+#: collections/gamecollection.cpp:26
+#, fuzzy
+msgid "My Games"
+msgstr "Els meus vins"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr ""
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+#, fuzzy
+msgid "Nintendo Wii"
+msgstr "Regió"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+#, fuzzy
+msgid "GameCube"
+msgstr "Pàgines"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr ""
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr ""
+
+#: collections/gamecollection.cpp:47
+#, fuzzy
+msgid "Game Boy Color"
+msgstr "&Reanomena col·lecció"
+
+#: collections/gamecollection.cpp:47
+#, fuzzy
+msgid "Game Boy"
+msgstr "Pàgines"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr ""
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr ""
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr ""
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+#, fuzzy
+msgid "Release Year"
+msgstr "Any d'edició"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Editor"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr ""
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+
+#: collections/gamecollection.cpp:82
+#, fuzzy
+msgid "ESRB Rating"
+msgstr "Puntuació"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr ""
+
+#: collections/cardcollection.cpp:26
+#, fuzzy
+msgid "My Cards"
+msgstr "Les meves monedes"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr ""
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr ""
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr ""
+
+#: collections/cardcollection.cpp:62
+#, fuzzy
+msgid "Card Number"
+msgstr "Número"
+
+#: collections/cardcollection.cpp:77
+#, fuzzy
+msgid "Card Type"
+msgstr "Tipus"
+
+#: collections/cardcollection.cpp:109
+#, fuzzy
+msgid "Front Image"
+msgstr "Imatge"
+
+#: collections/cardcollection.cpp:112
+#, fuzzy
+msgid "Back Image"
+msgstr "Imatge de la etiqueta"
+
+#: collections/boardgamecollection.cpp:26
+#, fuzzy
+msgid "My Board Games"
+msgstr "Els meus vins"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:72
+#, fuzzy
+msgid "Number of Players"
+msgstr "Total d'entrades: %1"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Clau Bibtex"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Títol del llibre"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Editorial"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organització"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Adreça"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Mes"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Número"
+
+#: collections/bibtexcollection.cpp:183
+#, fuzzy
+msgid "How Published"
+msgstr "Editor"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Capítol"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Referencia creuada"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Notes"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "La meva música"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Àlbum"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "Disc comptacte"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Cassette"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Vinil"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Artista"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Etiqueta"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Pistes"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr ""
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr ""
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr ""
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr ""
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr ""
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr ""
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr ""
+
+#: fetch/entrezfetcher.cpp:485
+#, fuzzy
+msgid "Institution"
+msgstr "Condició"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr ""
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr ""
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr ""
+
+#: fetch/z3950connection.cpp:345
+#, fuzzy
+msgid "Connection error %1: %2"
+msgstr "C&amps de la col·lecció..."
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr ""
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+#, fuzzy
+msgid "Hos&t: "
+msgstr "Notes"
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr ""
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+#, fuzzy
+msgid "&Port: "
+msgstr "Notes"
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr ""
+
+#: fetch/srufetcher.cpp:450
+#, fuzzy
+msgid "Path: "
+msgstr "Notes"
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr ""
+
+#: fetch/srufetcher.cpp:460
+#, fuzzy
+msgid "Format: "
+msgstr "Format"
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr ""
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:53
+#, fuzzy
+msgid "Amazon Link"
+msgstr "Amazon (Japó)"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (US)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (UK)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Alemanya)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japó)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (França)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Canadà)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:848
+#, fuzzy
+msgid "Co&untry: "
+msgstr "País"
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:853
+#, fuzzy
+msgid "Germany"
+msgstr "Amazon (Alemanya)"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:869
+#, fuzzy
+msgid "Small Image"
+msgstr "Imatge de la etiqueta"
+
+#: fetch/amazonfetcher.cpp:870
+#, fuzzy
+msgid "Medium Image"
+msgstr "Suport"
+
+#: fetch/amazonfetcher.cpp:871
+#, fuzzy
+msgid "Large Image"
+msgstr "Imatge de la etiqueta"
+
+#: fetch/amazonfetcher.cpp:872
+#, fuzzy
+msgid "No Image"
+msgstr "Imatge"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:550
+#, fuzzy
+msgid "&Format: "
+msgstr "Format"
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+#, fuzzy
+msgid "Optional"
+msgstr "Nacionalitat"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:82
+#, fuzzy
+msgid "External Application"
+msgstr "Surt d'aquesta aplicació"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+#, fuzzy
+msgid "Collection &type:"
+msgstr "C&amps de la col·lecció..."
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+#, fuzzy
+msgid "Update"
+msgstr "&Nova entrada"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr ""
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+#, fuzzy
+msgid "IMDB Rating"
+msgstr "Puntuació"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+#, fuzzy
+msgid "Certifications"
+msgstr "Certificació"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr ""
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:69
+#, fuzzy
+msgid "Person"
+msgstr "Personal"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:72
+#, fuzzy
+msgid "Keyword"
+msgstr "Paraules clau"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:264
+#, fuzzy
+msgid "Distributor"
+msgstr "Director"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr ""
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:343
+#, fuzzy
+msgid "&Username: "
+msgstr "Filtra entrada"
+
+#: fetch/crossreffetcher.cpp:348
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:354
+#, fuzzy
+msgid "&Password: "
+msgstr "Notes"
+
+#: fetch/gcstarpluginfetcher.cpp:190
+#, fuzzy
+msgid "GCstar Plugin"
+msgstr "Cassette"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:420
+#, fuzzy
+msgid "Author: "
+msgstr "Autor"
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr ""
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr ""
+
+#: newstuff/dialog.cpp:114
+#, fuzzy
+msgid "Version"
+msgstr "Personal"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr ""
+
+#: newstuff/dialog.cpp:117
+#, fuzzy
+msgid "Release Date"
+msgstr "Any d'edició"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+
+#: newstuff/dialog.cpp:137
+#, fuzzy
+msgid "The name and license of the selected item"
+msgstr "Copia les entrades seleccionades"
+
+#: newstuff/dialog.cpp:140
+#, fuzzy
+msgid "The author of the selected item"
+msgstr "Copia les entrades seleccionades"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr ""
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr ""
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+
+#: newstuff/dialog.cpp:194
+#, fuzzy
+msgid "A description of the selected item is shown here."
+msgstr "Copia les entrades seleccionades"
+
+#: newstuff/dialog.cpp:224
+#, fuzzy
+msgid "Downloading information..."
+msgstr "Importa la informació del CD d'àudio de FreeDB"
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Preparat."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr ""
+
+#: newstuff/dialog.cpp:413
+#, fuzzy
+msgid "Installing item..."
+msgstr "S'està desant el fitxer..."
+
+#: translators/bibteximporter.cpp:79
+msgid "No valid bibtex entries were found"
+msgstr ""
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+#, fuzzy
+msgid "Bibtex Options"
+msgstr "Opcions d'importació"
+
+#: translators/bibteximporter.cpp:287
+msgid "Use Unicode (UTF-8) encoding"
+msgstr ""
+
+#: translators/bibteximporter.cpp:288
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr ""
+
+#: translators/bibteximporter.cpp:289
+msgid "Use user locale (%1) encoding"
+msgstr ""
+
+#: translators/bibteximporter.cpp:293
+msgid "Read the imported file in the local encoding."
+msgstr ""
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr ""
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Fitxers Tellico (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+#, fuzzy
+msgid "*|All Files"
+msgstr "*|Tots els fitxers"
+
+#: translators/alexandriaexporter.cpp:43
+#, fuzzy
+msgid "Alexandria"
+msgstr "Exporta a Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr ""
+"Hi ha un error en l'anàlisi sintàctic XML a la línia %1, columna %2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "El missatge d'error de Qt es:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr ""
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr ""
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr ""
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr ""
+
+#: translators/tellicoimporter.cpp:940
+#, fuzzy
+msgid "Unread Books"
+msgstr "Els meus llibres"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr ""
+
+#: translators/tellicoimporter.cpp:968
+#, fuzzy
+msgid "80's Music"
+msgstr "La meva música"
+
+#: translators/tellicoimporter.cpp:980
+#, fuzzy
+msgid "Favorites"
+msgstr "Filtra entrada"
+
+#: translators/audiofileimporter.cpp:69
+#, fuzzy
+msgid "Scanning audio files..."
+msgstr "S'està desant el fitxer..."
+
+#: translators/audiofileimporter.cpp:129
+#, fuzzy
+msgid "Bitrate"
+msgstr "Clau Bibtex"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr ""
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:353
+#, fuzzy
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr ""
+"Si és activat, la cadena a cerca és utilitzada com a expresió regular."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr ""
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+#, fuzzy
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|Fitxers CSV (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+#, fuzzy
+msgid "CSV Options"
+msgstr "Opcions d'importació"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr ""
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr ""
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+#, fuzzy
+msgid "Delimiter"
+msgstr "Voleu suprimir l'entrada?"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+
+#: translators/csvexporter.cpp:124
+#, fuzzy
+msgid "Comma"
+msgstr "Comentaris"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr ""
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:135
+#, fuzzy
+msgid "Tab"
+msgstr "Taula"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr ""
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr ""
+
+#: translators/filelistingimporter.cpp:63
+#, fuzzy
+msgid "Scanning files..."
+msgstr "S'està desant el fitxer..."
+
+#: translators/filelistingimporter.cpp:191
+#, fuzzy
+msgid "File Listing Options"
+msgstr "Opcions d'importació"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr ""
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+
+#: translators/filelistingimporter.cpp:198
+#, fuzzy
+msgid "Generate file previews"
+msgstr "Reanomena la col·lecció"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr ""
+
+#: translators/onixexporter.cpp:67
+#, fuzzy
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.bib|Fitxers Bibtex (*.bib)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr ""
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr ""
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+#, fuzzy
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr "<qt>No es pot escriure al conducte del servidor en <b>%1</b>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+#, fuzzy
+msgid "Select CDDB Entry"
+msgstr "Voleu suprimir l'entrada?"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr ""
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr ""
+
+#: translators/freedbimporter.cpp:238
+#, fuzzy
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "<qt>No es pot escriure al conducte del servidor en <b>%1</b>.</qt>"
+
+#: translators/freedbimporter.cpp:470
+#, fuzzy
+msgid "Various"
+msgstr "Agrupa per:"
+
+#: translators/freedbimporter.cpp:489
+#, fuzzy
+msgid "Audio CD Options"
+msgstr "Opcions d'importació"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr ""
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr ""
+
+#: translators/freedbimporter.cpp:502
+#, fuzzy
+msgid "Read all CDDB cache files only"
+msgstr "S'està desant el fitxer..."
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr ""
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+#, fuzzy
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.csv|Fitxers CSV (*.csv)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+#, fuzzy
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.csv|Fitxers CSV (*.csv)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr ""
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+#, fuzzy
+msgid "XSLT Options"
+msgstr "Opcions d'importació"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr ""
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr ""
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr ""
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr ""
+
+#: translators/bibtexmlexporter.cpp:36
+#, fuzzy
+msgid "Bibtexml"
+msgstr "Clau Bibtex"
+
+#: translators/bibtexmlexporter.cpp:40
+#, fuzzy
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Fitxers XML (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr ""
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+#, fuzzy
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|Fitxers XML (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr ""
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr ""
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+
+#: translators/importer.h:100
+#, fuzzy
+msgid "Loading data..."
+msgstr "S'estan important les dades..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:48
+#, fuzzy
+msgid "Bibtex"
+msgstr "Clau Bibtex"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+#, fuzzy
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Fitxers Bibtex (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+#, fuzzy
+msgid "Expand string macros"
+msgstr "Cadenes de les macros"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+#, fuzzy
+msgid "Braces"
+msgstr "Pistes"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+#, fuzzy
+msgid "Quotes"
+msgstr "Notes"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr ""
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr ""
+
+#: translators/csvimporter.cpp:236
+#, fuzzy
+msgid "If checked, the first row is used as field titles."
+msgstr ""
+"Si és activat, la cadena a cerca és utilitzada com a expresió regular."
+
+#: translators/csvimporter.cpp:248
+#, fuzzy
+msgid "&Comma"
+msgstr "Comentaris"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr ""
+
+#: translators/csvimporter.cpp:259
+#, fuzzy
+msgid "Ta&b"
+msgstr "Taula"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr ""
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr ""
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+
+#: translators/csvimporter.cpp:298
+#, fuzzy
+msgid "Co&lumn:"
+msgstr "Veure columnes"
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr ""
+
+#: translators/csvimporter.cpp:315
+#, fuzzy
+msgid "&Assign Field"
+msgstr "Qualsevol camp"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr ""
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr ""
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr ""
+
+#: translators/pilotdbexporter.cpp:47
+#, fuzzy
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.bib|Fitxers Bibtex (*.bib)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Veure columnes"
+
+#: translators/pilotdbexporter.cpp:210
+#, fuzzy
+msgid "PilotDB Options"
+msgstr "Opcions d'importació"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr ""
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr ""
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr ""
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+#, fuzzy
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xml|Fitxers XML (*.xml)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr ""
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+#, fuzzy
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.xml|Fitxers XML (*.xml)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Persones"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr ""
+
+#: translators/htmlexporter.cpp:465
+#, fuzzy
+msgid "HTML Options"
+msgstr "Opcions d'importació"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr ""
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr ""
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr ""
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr ""
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr ""
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr ""
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+#, fuzzy
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico no ha pogut carregar la imatge - %1."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr ""
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr ""
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr ""
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr ""
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Qualsevol camp"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "conté"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "no conté"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "igual"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "no és igual"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "coincideix amb expr. regular"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "no coincideix amb expr. regular"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Edita..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Filtre avançat"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Criteris de filtre"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Coincideix amb t&ots els següents"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Coincideix amb q&ualsevol dels següents"
+
+#: filterdialog.cpp:311
+#, fuzzy
+msgid "Filter name:"
+msgstr "Filtra entrada"
+
+#: filterdialog.cpp:319
+#, fuzzy
+msgid "&Save Filter"
+msgstr "Filtre avançat"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Text pla"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Paràgraf"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Opció"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Quadre de verificació"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Taula"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Dependent"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Data"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr ""
+
+#: entryupdater.cpp:83
+#, fuzzy
+msgid "Updating entries..."
+msgstr "&Edita les entrades"
+
+#: entryupdater.cpp:85
+#, fuzzy
+msgid "Update Entries"
+msgstr "&Edita les entrades"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr ""
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr ""
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Expandeix tots els grups"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Redueix tots els grups"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Filtrar per grup"
+
+#: groupview.cpp:466
+#, fuzzy
+msgid "%1 (Sort by Count)"
+msgstr "Ordenat per comptador, Ascendent"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr ""
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Opcions d'importació"
+
+#: importdialog.cpp:62
+#, fuzzy
+msgid "&Replace current collection"
+msgstr "Reemplaça la col·lecció actual"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr ""
+"Reemplaça la col·lecció actual amb el contingut del fitxer importat."
+
+#: importdialog.cpp:65
+#, fuzzy
+msgid "A&ppend to current collection"
+msgstr "Afegeix a la col·lecció actual"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Afegeix el contingut del fitxer importat a la col·lecció actual. Nomes es "
+"possible quan el tipus de col·lecció coincideix"
+
+#: importdialog.cpp:69
+#, fuzzy
+msgid "&Merge with current collection"
+msgstr "Afegeix a la col·lecció actual"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Importa"
+
+#: importdialog.cpp:268
+#, fuzzy
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|Fitxers RIS (*.ris)"
+
+#: importdialog.cpp:277
+#, fuzzy
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.csv|Fitxers CSV (*.csv)"
+
+#: importdialog.cpp:281
+#, fuzzy
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.bib|Fitxers Bibtex (*.bib)"
+
+#: importdialog.cpp:285
+#, fuzzy
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.ris|Fitxers RIS (*.ris)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr ""
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr ""
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr ""
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+
+#: tellico_strings.cpp:27
+#, fuzzy, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico no ha pogut carregar la imatge - %1."
+
+#: entryiconview.cpp:287
+#, fuzzy
+msgid "&Sort By"
+msgstr "Notes"
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr ""
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr ""
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr ""
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr ""
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr ""
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr ""
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+
+#: loandialog.cpp:144
+#, fuzzy
+msgid "&Note:"
+msgstr "Notes"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr ""
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr ""
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Crear una nova col·lecció"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Nova col·lecció de lli&bres"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Crear una nova col·lecció de llibres"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr ""
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr ""
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Nova col·lecció de còmics"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Crear una nova col·lecció de còmics"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Nova col·lecció de vídeos"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Crear una nova col·lecció de vídeos"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Nova col·lecció de música"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Crear una nova col·lecció de música"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Nova col·lecció de monedes"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Crear una nova col·lecció de monedes"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Nova col·lecció de segells"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Crear una nova col·lecció de segells"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr ""
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr ""
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr ""
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr ""
+
+#: mainwindow.cpp:264
+#, fuzzy
+msgid "New &Game Collection"
+msgstr "Nova col·lecció de segells"
+
+#: mainwindow.cpp:266
+#, fuzzy
+msgid "Create a new game collection"
+msgstr "Crear una nova col·lecció de segells"
+
+#: mainwindow.cpp:272
+#, fuzzy
+msgid "New Boa&rd Game Collection"
+msgstr "Nova col·lecció de segells"
+
+#: mainwindow.cpp:274
+#, fuzzy
+msgid "Create a new board game collection"
+msgstr "Crear una nova col·lecció de segells"
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr ""
+
+#: mainwindow.cpp:282
+#, fuzzy
+msgid "Create a new file catalog"
+msgstr "Crear una nova col·lecció"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr ""
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr ""
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Obrir un document existent"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Obre un fitxer utilitzat recentment"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Desa el document"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Desa el document com a un fitxer diferent..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Imprimir el contingut del document..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Surt d'aquesta aplicació"
+
+#: mainwindow.cpp:320
+#, fuzzy
+msgid "Import collection data from other formats"
+msgstr "Importa dades a la col·lecció des de altres formats..."
+
+#: mainwindow.cpp:324
+#, fuzzy
+msgid "Import Tellico Data..."
+msgstr "Importa dades de Tellico"
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Importa dades d'un altre fitxer Tellico"
+
+#: mainwindow.cpp:331
+#, fuzzy
+msgid "Import CSV Data..."
+msgstr "Importa dades de CSV"
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Importa un fitxer CSV"
+
+#: mainwindow.cpp:338
+#, fuzzy
+msgid "Import MODS Data..."
+msgstr "Importa dades MODS"
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Importa un fitxer de dades MODS"
+
+#: mainwindow.cpp:345
+#, fuzzy
+msgid "Import Alexandria Data..."
+msgstr "Importa dades Alexandria"
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr ""
+
+#: mainwindow.cpp:352
+#, fuzzy
+msgid "Import Delicious Library Data..."
+msgstr "Importa dades de Tellico"
+
+#: mainwindow.cpp:353
+#, fuzzy
+msgid "Import data from Delicious Library"
+msgstr "Importa les metadades dels fitxers d'àudio"
+
+#: mainwindow.cpp:359
+#, fuzzy
+msgid "Import Referencer Data..."
+msgstr "Importa dades RIS"
+
+#: mainwindow.cpp:360
+#, fuzzy
+msgid "Import data from Referencer"
+msgstr "Importa un fitxer de referencia RIS"
+
+#: mainwindow.cpp:366
+#, fuzzy
+msgid "Import Bibtex Data..."
+msgstr "Importa dades Bibtex"
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr ""
+
+#: mainwindow.cpp:373
+#, fuzzy
+msgid "Import Bibtexml Data..."
+msgstr "Importa dades Bibtexml"
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr ""
+
+#: mainwindow.cpp:380
+#, fuzzy
+msgid "Import RIS Data..."
+msgstr "Importa dades RIS"
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Importa un fitxer de referencia RIS"
+
+#: mainwindow.cpp:387
+#, fuzzy
+msgid "Import PDF File..."
+msgstr "Importa el fitxer..."
+
+#: mainwindow.cpp:388
+#, fuzzy
+msgid "Import a PDF file"
+msgstr "Importa un fitxer CSV"
+
+#: mainwindow.cpp:394
+#, fuzzy
+msgid "Import Audio File Metadata..."
+msgstr "Importa les metadades d'un fitxer d'àudio"
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Importa les metadades dels fitxers d'àudio"
+
+#: mainwindow.cpp:404
+#, fuzzy
+msgid "Import Audio CD Data..."
+msgstr "Importa les dades del CD d'àudio"
+
+#: mainwindow.cpp:405
+#, fuzzy
+msgid "Import audio CD information"
+msgstr "Importa la informació del CD d'àudio de FreeDB"
+
+#: mainwindow.cpp:414
+#, fuzzy
+msgid "Import GCstar Data..."
+msgstr "Importa dades de CSV"
+
+#: mainwindow.cpp:415
+#, fuzzy
+msgid "Import a GCstar data file"
+msgstr "Importa un fitxer de dades MODS"
+
+#: mainwindow.cpp:421
+#, fuzzy
+msgid "Import Griffith Data..."
+msgstr "Importa dades de CSV"
+
+#: mainwindow.cpp:422
+#, fuzzy
+msgid "Import a Griffith database"
+msgstr "Exporta a una base de dades PilotDB"
+
+#: mainwindow.cpp:428
+#, fuzzy
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Importa les dades del CD d'àudio"
+
+#: mainwindow.cpp:429
+#, fuzzy
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Importa dades d'un altre fitxer Tellico"
+
+#: mainwindow.cpp:435
+#, fuzzy
+msgid "Import File Listing..."
+msgstr "Importa el fitxer..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr ""
+
+#: mainwindow.cpp:442
+#, fuzzy
+msgid "Import XSL Transform..."
+msgstr "Importa una transformació XSL"
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Importa utilitzant una transformació XSL"
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Exporta"
+
+#: mainwindow.cpp:457
+#, fuzzy
+msgid "Export the collection data to other formats"
+msgstr "Exporta la col·lecció de dades a altres formats..."
+
+#: mainwindow.cpp:461
+#, fuzzy
+msgid "Export to XML..."
+msgstr "Exporta a HTML"
+
+#: mainwindow.cpp:462
+#, fuzzy
+msgid "Export to a Tellico XML file"
+msgstr "Exporta a fitxer XML de Tellico"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Exporta a Zip"
+
+#: mainwindow.cpp:469
+#, fuzzy
+msgid "Export to a Tellico Zip file"
+msgstr "Exporta a fitxer XML de Tellico"
+
+#: mainwindow.cpp:475
+#, fuzzy
+msgid "Export to HTML..."
+msgstr "Exporta a HTML"
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Exporta a un fitxer HTML"
+
+#: mainwindow.cpp:482
+#, fuzzy
+msgid "Export to CSV..."
+msgstr "Exporta a CSV"
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Exporta a un fitxer de valors separats per comes"
+
+#: mainwindow.cpp:489
+#, fuzzy
+msgid "Export to PilotDB..."
+msgstr "Exporta a PilotDB"
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Exporta a una base de dades PilotDB"
+
+#: mainwindow.cpp:496
+#, fuzzy
+msgid "Export to Alexandria..."
+msgstr "Exporta a Alexandria"
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Exporta a una llibreria d'Alexandria"
+
+#: mainwindow.cpp:503
+#, fuzzy
+msgid "Export to Bibtex..."
+msgstr "Exporta a Bibtex"
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Exporta a un fitxer bibtex"
+
+#: mainwindow.cpp:510
+#, fuzzy
+msgid "Export to Bibtexml..."
+msgstr "Exporta a Bibtexml"
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Exporta a un fitxer Bibtexml"
+
+#: mainwindow.cpp:517
+#, fuzzy
+msgid "Export to ONIX..."
+msgstr "Exporta a XML"
+
+#: mainwindow.cpp:518
+#, fuzzy
+msgid "Export to an ONIX file"
+msgstr "Exporta a un fitxer HTML"
+
+#: mainwindow.cpp:524
+#, fuzzy
+msgid "Export to GCfilms..."
+msgstr "Exporta a CSV"
+
+#: mainwindow.cpp:525
+#, fuzzy
+msgid "Export to a GCfilms data file"
+msgstr "Exporta a un fitxer bibtex"
+
+#: mainwindow.cpp:531
+#, fuzzy
+msgid "Export to GCstar..."
+msgstr "Exporta a CSV"
+
+#: mainwindow.cpp:532
+#, fuzzy
+msgid "Export to a GCstar data file"
+msgstr "Exporta a un fitxer bibtex"
+
+#: mainwindow.cpp:536
+#, fuzzy
+msgid "Export XSL Transform..."
+msgstr "Exporta a transformació XSL"
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Exporta utilitzant un fitxer de transformació XSL"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Talla el text seleccionat i posa'l al porta-retalls"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Còpia el text seleccionat al porta-retalls"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Enganxa el contingut del porta-retalls"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Selecciona totes les entrades de la col·lecció"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Desselecciona totes les entrades de la col·lecció"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Cerca d'Internet..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Cerca a Internet..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "&Filtre avançat"
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Filtra per col·lecció"
+
+#: mainwindow.cpp:569
+#, fuzzy
+msgid "&New Entry..."
+msgstr "&Nova entrada"
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Crea una nova entrada"
+
+#: controller.cpp:620 mainwindow.cpp:573
+#, fuzzy
+msgid "&Edit Entry..."
+msgstr "&Edita entrada"
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Edita les entrades seleccionades"
+
+#: controller.cpp:621 mainwindow.cpp:577
+#, fuzzy
+msgid "D&uplicate Entry"
+msgstr "&Nova entrada"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Copia les entrades seleccionades"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "E&limina entrada"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Elimina les entrades seleccionades"
+
+#: mainwindow.cpp:585
+#, fuzzy
+msgid "&Merge Entries"
+msgstr "&Suprimeix les entrades"
+
+#: mainwindow.cpp:588
+#, fuzzy
+msgid "Merge the selected entries"
+msgstr "Elimina les entrades seleccionades"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr ""
+
+#: mainwindow.cpp:594
+#, fuzzy
+msgid "Generate collection reports"
+msgstr "Reanomena la col·lecció"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr ""
+
+#: mainwindow.cpp:598
+#, fuzzy
+msgid "Check-out the selected items"
+msgstr "Copia les entrades seleccionades"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr ""
+
+#: mainwindow.cpp:602
+#, fuzzy
+msgid "Check-in the selected items"
+msgstr "Copia les entrades seleccionades"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "&Reanomena col·lecció"
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Reanomena la col·lecció"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "C&amps de la col·lecció..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Modifica els camps de la col·lecció"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "Converteix a &bibliografía"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Converteix una col·lecció de llibres a bibliografia"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr ""
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr ""
+
+#: mainwindow.cpp:626
+#, fuzzy
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Còpia el text seleccionat al porta-retalls"
+
+#: mainwindow.cpp:627
+#, fuzzy
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Còpia el text seleccionat al porta-retalls"
+
+#: mainwindow.cpp:632
+#, fuzzy
+msgid "Cite Entry in &LyX"
+msgstr "Filtra entrada"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr ""
+
+#: mainwindow.cpp:638
+#, fuzzy
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Filtra entrada"
+
+#: mainwindow.cpp:639
+#, fuzzy
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Edita les entrades seleccionades"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, fuzzy, no-c-format
+msgid "&Update Entry"
+msgstr "&Nova entrada"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr ""
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr ""
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Mostra la vista de gru&p"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Activa/desactiva la vista de grup"
+
+#: mainwindow.cpp:669
+#, fuzzy
+msgid "Hide Grou&p View"
+msgstr "Mostra la vista de gru&p"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Mostra l'&editor d'entrades"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Activa/desactiva l'editor"
+
+#: mainwindow.cpp:675
+#, fuzzy
+msgid "Hide Entry &Editor"
+msgstr "Mostra l'&editor d'entrades"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Mostra la vistra d'entrades"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Activa/desactiva la vista d'entrades"
+
+#: mainwindow.cpp:681
+#, fuzzy
+msgid "Hide Entry &View"
+msgstr "Mostra la vistra d'entrades"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr ""
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "Selecció de &grup"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Canvia l'agrupació de la col·lecció"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+#, fuzzy
+msgid "Filter"
+msgstr "Filtra entrada"
+
+#: mainwindow.cpp:705
+#, fuzzy
+msgid "Clear Filter"
+msgstr "Voleu suprimir l'entrada?"
+
+#: mainwindow.cpp:710
+#, fuzzy
+msgid "Filter here..."
+msgstr "Criteris de filtre"
+
+#: mainwindow.cpp:768
+#, fuzzy
+msgid "Groups"
+msgstr "Agrupa per:"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt>La <i>vista de grup</i> ordena les entrades en grups basats en el camp "
+"seleccionat.</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt>La <i>vista de columna</i> mostra el valor de multiples camps per a cada "
+"entrada.</qt>"
+
+#: mainwindow.cpp:831
+msgid "Welcome to the Tellico Collection Manager"
+msgstr ""
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "S'està creant un nou document..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "S'està obrint el fitxer..."
+
+#: mainwindow.cpp:1108
+#, fuzzy
+msgid "Open File"
+msgstr "Obre el fitxer..."
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "S'està desant el fitxer..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr ""
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr ""
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "S'està desant el fitxer amb un nom nou..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "S'està imprimint..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "S'està processant el document..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "S'està sortint..."
+
+#: mainwindow.cpp:1498
+#, fuzzy, c-format
+msgid "Total entries: %1"
+msgstr "Total d'entrades: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 filtrats; %2 seleccionats)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 filtrats)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 seleccionats)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Imprimeix %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Pàgina %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Comproveu la instal·lació."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "S'estan important les dades..."
+
+#: mainwindow.cpp:1858
+#, fuzzy
+msgid "Import File"
+msgstr "Importa el fitxer..."
+
+#: mainwindow.cpp:1864
+#, fuzzy
+msgid "Import Directory"
+msgstr "Director"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "S'estan exportant les dades..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Exporta com"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Cadenes de les macros"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Macro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Cadena"
+
+#: mainwindow.cpp:1999
+#, fuzzy
+msgid "Creating citations..."
+msgstr "Certificació"
+
+#: mainwindow.cpp:2104
+#, fuzzy
+msgid "Filters"
+msgstr "Filtra entrada"
+
+#: mainwindow.cpp:2105
+#, fuzzy
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt>La <i>vista de grup</i> ordena les entrades en grups basats en el camp "
+"seleccionat.</qt>"
+
+#: mainwindow.cpp:2121
+#, fuzzy
+msgid "Loans"
+msgstr "Localitat"
+
+#: mainwindow.cpp:2122
+#, fuzzy
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt>La <i>vista de columna</i> mostra el valor de multiples camps per a cada "
+"entrada.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr ""
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico no ha pogut carregar la imatge - %1."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+"Ja existeix un fitxer anomenat \"%1\". Esteu segur que el voleu "
+"sobreescriure?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Voleu sobreescriure el fitxer?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Sobreescriu"
+
+#: filterview.cpp:87
+#, fuzzy
+msgid "Filter (Sort by Count)"
+msgstr "Filtrar per grup"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Esteu segur que voleu suprimir aquesta entrada?"
+
+#: controller.cpp:429
+#, fuzzy
+msgid "Delete Entry"
+msgstr "Voleu suprimir l'entrada?"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Esteu segur que voleu suprimir aquestes entrades?"
+
+#: controller.cpp:443
+#, fuzzy
+msgid "Delete Multiple Entries"
+msgstr "Voleu suprimir les entrades?"
+
+#: controller.cpp:626
+#, fuzzy
+msgid "&Edit Entries..."
+msgstr "&Edita les entrades"
+
+#: controller.cpp:627
+#, fuzzy
+msgid "D&uplicate Entries"
+msgstr "&Edita les entrades"
+
+#: controller.cpp:628
+#, fuzzy
+msgid "&Update Entries"
+msgstr "&Edita les entrades"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "&Suprimeix les entrades"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr ""
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr ""
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr ""
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(Buit)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr ""
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr ""
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr ""
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr ""
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr ""
+
+#: main.cpp:31
+msgid "File to open"
+msgstr ""
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr ""
+
+#: main.cpp:44
+msgid "Icons"
+msgstr ""
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr ""
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr ""
+
+#: main.cpp:50
+msgid "Author of libcsv library"
+msgstr ""
+
+#: main.cpp:52
+msgid "Author of rtf2html library"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:119
+#, fuzzy
+msgid "&Title:"
+msgstr "Títol"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:129
+#, fuzzy
+msgid "T&ype:"
+msgstr "Tipus"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:179
+#, fuzzy
+msgid "Descr&iption:"
+msgstr "Descripció"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:306
+#, fuzzy
+msgid "Modify Fields"
+msgstr "Qualsevol camp"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr ""
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr ""
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr ""
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr ""
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr ""
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr ""
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr ""
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr ""
+
+#: configdialog.cpp:213
+#, fuzzy
+msgid "Image Storage Options"
+msgstr "Opcions d'importació"
+
+#: configdialog.cpp:214
+#, fuzzy
+msgid "Store images in data file"
+msgstr "Importa un fitxer de dades MODS"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr ""
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr ""
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr ""
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr ""
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr ""
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr ""
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr ""
+
+#: configdialog.cpp:243
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+
+#: configdialog.cpp:249
+#, fuzzy
+msgid "Artic&les:"
+msgstr "Artista"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr ""
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr ""
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr ""
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr ""
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr ""
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr ""
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr ""
+
+#: configdialog.cpp:313
+#, fuzzy
+msgid "&Group the entries"
+msgstr "&Edita les entrades"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr ""
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr ""
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr ""
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr ""
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr ""
+
+#: configdialog.cpp:369
+#, fuzzy
+msgid "Template:"
+msgstr "Importa dades Bibtexml"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr ""
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr ""
+
+#: configdialog.cpp:398
+#, fuzzy
+msgid "Font Options"
+msgstr "Opcions d'importació"
+
+#: configdialog.cpp:405
+#, fuzzy
+msgid "Font:"
+msgstr "Mes"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:415
+#, fuzzy
+msgid "Size:"
+msgstr "Dedicat"
+
+#: configdialog.cpp:425
+#, fuzzy
+msgid "Color Options"
+msgstr "Opcions d'importació"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr ""
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr ""
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr ""
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr ""
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr ""
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr ""
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr ""
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr ""
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr ""
+
+#: configdialog.cpp:487
+#, fuzzy
+msgid "Delete..."
+msgstr "Imatge de la etiqueta"
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr ""
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr ""
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr ""
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr ""
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr ""
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr ""
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr ""
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr ""
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr ""
+
+#: configdialog.cpp:533
+#, fuzzy
+msgid "Click to modify the selected data source."
+msgstr "Copia les entrades seleccionades"
+
+#: configdialog.cpp:536
+#, fuzzy
+msgid "Click to delete the selected data source."
+msgstr "Elimina les entrades seleccionades"
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr ""
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr ""
+
+#: configdialog.cpp:1049
+#, fuzzy
+msgid "Delete Template"
+msgstr "Voleu suprimir l'entrada?"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr ""
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr ""
+
+#: loanview.cpp:74
+#, fuzzy
+msgid "Check-in"
+msgstr "Quadre de verificació"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr ""
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr ""
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr ""
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr ""
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr ""
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr ""
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr ""
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr ""
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr ""
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr ""
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr ""
+
+#: collectionfactory.cpp:133
+#, fuzzy
+msgid "Game Collection"
+msgstr "&Reanomena col·lecció"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr ""
+
+#: collectionfactory.cpp:135
+#, fuzzy
+msgid "Board Game Collection"
+msgstr "&Reanomena col·lecció"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr ""
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr ""
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr ""
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr ""
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr ""
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr ""
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr ""
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr ""
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr ""
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr ""
+
+#: exportdialog.cpp:72
+msgid "Encode the exported file in the local encoding."
+msgstr ""
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr ""
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr ""
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr ""
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr ""
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr ""
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr ""
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr ""
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr ""
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr ""
+
+#: fetchdialog.cpp:138
+#, fuzzy
+msgid "Edit List..."
+msgstr "Edita..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+
+#: fetchdialog.cpp:146
+#, fuzzy
+msgid "Search s&ource:"
+msgstr "Cerca en:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr ""
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+
+#: fetchdialog.cpp:192
+#, fuzzy
+msgid "&Add Entry"
+msgstr "&Edita entrada"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr ""
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr ""
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr ""
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr ""
+
+#: fetchdialog.cpp:298
+#, fuzzy
+msgid "Cancelling the search..."
+msgstr "Cerca d'Internet..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr ""
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr ""
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+
+#: fetchdialog.cpp:412
+msgid "No results were found for the following ISBN values:"
+msgstr ""
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr ""
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr ""
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr ""
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr ""
+
+#: fetchdialog.cpp:604
+#, fuzzy
+msgid "&Load From File..."
+msgstr "Importa el fitxer..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr ""
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr ""
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Nova entrada"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr ""
+
+#: entryeditdialog.cpp:77
+#, fuzzy
+msgid "Go to the previous entry in the collection"
+msgstr "Busca la coincidència anterior en la col·lecció"
+
+#: entryeditdialog.cpp:82
+#, fuzzy
+msgid "Go to the next entry in the collection"
+msgstr "Selecciona totes les entrades de la col·lecció"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr ""
+
+#: entryeditdialog.cpp:317
+#, fuzzy
+msgid "Modify Multiple Entries"
+msgstr "Voleu suprimir les entrades?"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr ""
+
+#: entryeditdialog.cpp:456
+#, fuzzy
+msgid "Edit Entries"
+msgstr "&Edita les entrades"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr ""
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr ""
+
+#: reportdialog.cpp:53
+#, fuzzy
+msgid "Collection Report"
+msgstr "C&amps de la col·lecció..."
+
+#: reportdialog.cpp:60
+#, fuzzy
+msgid "&Report template:"
+msgstr "Importa dades Bibtexml"
+
+#: reportdialog.cpp:83
+#, fuzzy
+msgid "&Generate"
+msgstr "General"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr ""
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+
+#: tellico_kernel.cpp:285
+#, fuzzy
+msgid "Do you really want to delete this filter?"
+msgstr "Esteu segur que voleu suprimir aquesta entrada?"
+
+#: tellico_kernel.cpp:287
+#, fuzzy
+msgid "Delete Filter?"
+msgstr "Voleu suprimir l'entrada?"
+
+#: tellico_kernel.cpp:323
+#, fuzzy
+msgid "New collection name:"
+msgstr "Nova col·lecció de música"
+
+#: tellico_kernel.cpp:377
+msgid "Entry 1"
+msgstr ""
+
+#: tellico_kernel.cpp:378
+msgid "Entry 2"
+msgstr ""
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr ""
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+#, fuzzy
+msgid "Merge Entries"
+msgstr "&Suprimeix les entrades"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr ""
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr ""
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr ""
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr ""
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr ""
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr ""
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr ""
+
+#: entrymerger.cpp:35
+#, fuzzy
+msgid "Merging entries..."
+msgstr "&Edita les entrades"
+
+#: entrymerger.cpp:49
+#, fuzzy
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Total d'entrades: %1"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr ""
+
+#: xslt.cpp:3
+#, fuzzy
+msgid "This template is meant for music collections only."
+msgstr "Crear una nova col·lecció de música"
+
+#: xslt.cpp:5
+#, fuzzy
+msgid "Total:"
+msgstr "Títol"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr ""
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr ""
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr ""
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr ""
+
+#: xslt.cpp:14 xslt.cpp:43
+#, fuzzy
+msgid "This template is meant for video collections only."
+msgstr "Crear una nova col·lecció de vídeos"
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr ""
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ""
+
+#: xslt.cpp:18
+#, fuzzy
+msgid "Total number of fields:"
+msgstr "Total d'entrades: %1"
+
+#: xslt.cpp:19
+#, fuzzy
+msgid "Total number of entries:"
+msgstr "Total d'entrades: %1"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+#, fuzzy
+msgid "Generated by Tellico"
+msgstr "General"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr ""
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr ""
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr ""
+
+#: xslt.cpp:27 xslt.cpp:29
+#, fuzzy
+msgid "Loan Date"
+msgstr "Data"
+
+#: xslt.cpp:28 xslt.cpp:31
+#, fuzzy
+msgid "Note"
+msgstr "Notes"
+
+#: xslt.cpp:30
+#, fuzzy
+msgid "Due Date"
+msgstr "Data"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr ""
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr ""
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr ""
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr ""
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr ""
+
+#: xslt.cpp:44
+#, fuzzy
+msgid "Search"
+msgstr "Cerca en:"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr ""
+
+#: z3950.cpp:6
+#, fuzzy
+msgid "Sudoc (France)"
+msgstr "Amazon (França)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr ""
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr ""
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr ""
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr ""
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr ""
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr ""
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr ""
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr ""
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr ""
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr ""
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr ""
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr ""
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr ""
+
+#, fuzzy
+#~ msgid "CrossRef"
+#~ msgstr "Referencia creuada"
+
+#, fuzzy
+#~ msgid "GCstar"
+#~ msgstr "Cassette"
+
+#, fuzzy
+#~ msgid "Referencer"
+#~ msgstr "Referencia creuada"
+
+#~ msgid "Comics"
+#~ msgstr "Còmics"
+
+#~ msgid "Coins"
+#~ msgstr "Monedes"
+
+#~ msgid "Books"
+#~ msgstr "Llibres"
+
+#~ msgid "Wines"
+#~ msgstr "Vins"
+
+#~ msgid "Videos"
+#~ msgstr "Vídeos"
+
+#, fuzzy
+#~ msgid "Games"
+#~ msgstr "Pàgines"
+
+#, fuzzy
+#~ msgid "Entries"
+#~ msgstr "&Suprimeix les entrades"
+
+#~ msgid "Albums"
+#~ msgstr "Àlbums"
+
+#, fuzzy
+#~ msgid "Copac"
+#~ msgstr "Comentaris"
+
+#~ msgid "&Copy Entry"
+#~ msgstr "&Copia entrada"
+
+#~ msgid "&Copy Entries"
+#~ msgstr "&Copia les entrades"
+
+#, fuzzy
+#~ msgid "Scanning CDDB cache files..."
+#~ msgstr "S'està desant el fitxer..."
+
+#, fuzzy
+#~ msgid "Collection &type: "
+#~ msgstr "C&amps de la col·lecció..."
+
+#, fuzzy
+#~ msgid "Save Entries"
+#~ msgstr "&Suprimeix les entrades"
+
+#~ msgid "Enable/disable the statusbar"
+#~ msgstr "Activa/desactiva la barra d'estat"
+
+#, fuzzy
+#~ msgid "Reading files..."
+#~ msgstr "S'està desant el fitxer..."
+
+#, fuzzy
+#~ msgid "Group by:"
+#~ msgstr "Agrupa per:"
+
+#, fuzzy
+#~ msgid "Quick filter:"
+#~ msgstr "Filtre ràpid:"
+
+#~ msgid "5 - Best"
+#~ msgstr "5 - Molt bo"
+
+#~ msgid "4 - Good"
+#~ msgstr "4 - Bo"
+
+#~ msgid "3 - Neutral"
+#~ msgstr "3 - Normal"
+
+#~ msgid "2 - Bad"
+#~ msgstr "2 - Dolent"
+
+#~ msgid "1 - Worst"
+#~ msgstr "1 - Molt dolent"
+
+#~ msgid "Table (2 Columns)"
+#~ msgstr "Taula (2 columnes)"
+
+#~ msgid "Sort by Group, Ascending"
+#~ msgstr "Ordenat per grup, Ascendent"
+
+#~ msgid "Sort by Group, Descending"
+#~ msgstr "Ordenat per grup, Descendent"
+
+#~ msgid "Sort by Count, Descending"
+#~ msgstr "Ordenat per comptador, Descendent"
+
+#~ msgid "Search the collection"
+#~ msgstr "Busca en la col·lecció"
+
+#~ msgid "Find next match in the collection"
+#~ msgstr "Busca la coincidència següent en la col·lecció"
+
+#~ msgid "Find Text"
+#~ msgstr "Cerca un text"
+
+#~ msgid "&Find"
+#~ msgstr "Ce&rca"
+
+#~ msgid "Find"
+#~ msgstr "Cerca"
+
+#~ msgid "&Text to find:"
+#~ msgstr "&Text a cercar:"
+
+#~ msgid "The search string"
+#~ msgstr "La cadena de cerca"
+
+#~ msgid "As regular e&xpression"
+#~ msgstr "Com a e&xpresió regular"
+
+#~ msgid "&Edit regular expression..."
+#~ msgstr "&Edita l'expresió regular..."
+
+#~ msgid "Field"
+#~ msgstr "Camp"
diff --git a/po/cs.po b/po/cs.po
new file mode 100644
index 0000000..061f93b
--- /dev/null
+++ b/po/cs.po
@@ -0,0 +1,5344 @@
+# translation of cs.po to čeština
+# This file is distributed under the same license as the tellico package.
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+#
+# Robert Kratky <kratky@rob.cz>, 2004, 2006.
+msgid ""
+msgstr ""
+"Project-Id-Version: cs\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2006-11-04 17:40+0100\n"
+"Last-Translator: Robert Kratky <kratky@rob.cz>\n"
+"Language-Team: čeština <cs@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Report-Msgid-Bugs-To: \n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "<qt>Tellico se nedaří zapisovat do roury serveru na <b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr "Připojuji k OpenOffice.org..."
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr "Spojení OpenOffice.org"
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+"Tellico se nepodařilo spojit s OpenOffice.org. Zkontrolujte prosím "
+"nastavení spojení níže a ujistěte se, že je OpenOffice.org Writer "
+"spuštěn."
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr "Roura"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr "TCP/IP"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr "Přejmenovat sloupec"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr "Nový název sloupce:"
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr "Sloupec %1"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr "Přejmenovat sloupec..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr "Vložit řádek"
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr "Odstranit řádek"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr "Posunout řádek výše"
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr "Posunout řádek níže"
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr "Vyčistit tabulku"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr "Náhled šablony"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Nastavit"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr "%1:"
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Více"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Méně"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Žádné"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Vybrat obrázek..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr ""
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr ""
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Upravit %1"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Připojit sbírku"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Sloučit sbírky"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Nahradit sbírku"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr "Upravit záznamy"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "Přidat pole %1"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Upravit pole %1"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Smazat pole %1"
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr "Přidat záznamy"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Přidat %1"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Přejmenovat sbírku"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Upravit půjčku"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Přidat filtr"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Upravit filtr"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Smazat filtr"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Půjčit položky"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Půjčit %1"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Smazat záznamy"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Smazat %1"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Přeskupit pole"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Vrátit záznamy"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Vrátit %1"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Obecné"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Stav"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Osobní"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Moje známky"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Název"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Popis"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Hodnota"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "Země"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Rok vydání"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Barevné"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Scott č. "
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr ""
+"Vynikající,Výjimečně kvalitní,Velmi "
+"kvalitní,Kvalitní,Průměrná,Mizerná"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Stupeň"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Zrušeno"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Rozevírací"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Centrovaná"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Pogumovaná"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Datum koupě"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Kupní cena"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Místo"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Dárek"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Obrázek"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Komentáře"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Publikování"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Klasifikace"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Moje komiksy"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Podtitul"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Napsal"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr "Ilustrátor"
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Série"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Číslo"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Vydavatel"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Vydání"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Rok vydání"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Stran"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Jazyk"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Žánr"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Klíčová slova"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr ""
+"Zbrusu nový,Téměř nový,Velmi kvalitní,Kvalitní,Velmi "
+"dobrý,Dobrý,Ucházející,Mizerný"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Podepsaná"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Půjčená"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Přední obálka"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Moje mince"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Druh"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Rok"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Značka mincovny"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Sada mincí"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+"Ověřená-65,Ověřená-60,Zbrusu nová-65,Zbrusu nová-60,Téměř "
+"nepoužitá-55,Téměř nepoužitá-50,Výjimečně kvalitní-40,Velmi "
+"kvalitní-30,Velmi kvalitní-20,Dobrý-12,Velmi "
+"dobrý-8,Dobrý-4,Ucházející"
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr "PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Hodnotící služba"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Líc"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Rub"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Moje knihy"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Autor"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Pevná vazba"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Paperback"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Velký paperback"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "E-Book"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Časopis"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Žurnál"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Vazba"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Rok copyrightu"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "č. ISBN"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Mezinárodní standardní knižní číslo"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "č. LCCN"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Kontrolní číslo Knihovny kongresu"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr ""
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Číslo série"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Nová"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Použitá"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Přečtená"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Hodnocení"
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr "Mé soubory"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "Název"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Svazek"
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr "Složka"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr "Mimetyp"
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr "Velikost"
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr "Práva"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr "Vlastník"
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr "Skupina"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr "Vytvořen"
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr "Upraven"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr "Meta info"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Vlastnost"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Hodnota"
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr "Ikona"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Moje vína"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Výrobce"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Název"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Odrůda"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Ročník"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Červené víno"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Bílé víno"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Šumivé víno"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Množství"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Vypít do"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Obrázek etikety"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Jiné osoby"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Vlastnosti"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Moje videa"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr ""
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+#, fuzzy
+msgid "HD DVD"
+msgstr "DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Médium"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Rok výroby"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Certifikace"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Region 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Region 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Region 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Region 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Region 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Region 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Region 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Region 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Region"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Země"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Formát"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Obsazení"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr "Herec/herečka"
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr "Role"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr "Tabulka pro herecké obsazení spolu s jejich rolemi"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Režisér"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Skladatel"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Studio"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Jazykové stopy"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Jazyky titulků"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Audio stopy"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Celkový čas"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "Celkový čas videa (v minutách)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Poměr stran"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Širokoúhlé"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Černobílé"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Barevný režim"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Režisérský sestřih"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Shrnutí děje"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Osobní hodnocení"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Přebal"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "Moje hry"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr "Xbox 360"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr "PlayStation3"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr "Nintendo Wii"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr ""
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Platforma"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Rok vydání"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Vydavatel"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Vývojář"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+"Bez hodnocení, Jen pro dospělé, Pro vyspělé, Teen, Všichni, Pro děti, "
+"Nerozhodnuto"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "Hodnocení ESRB"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Dohráno"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Moje karty"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Hráč"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Tým"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Značka"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Číslo karty"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Druh karty"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Přední obrázek"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Zadní obrázek"
+
+#: collections/boardgamecollection.cpp:26
+#, fuzzy
+msgid "My Board Games"
+msgstr "Moje hry"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr ""
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Bibliografie"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Druh záznamu"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+"Tyto druhy záznamu jsou specifické pro Bibtex. Viz dokumentaci k Bibtex."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Bibtex klíč"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Název knihy"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Redaktor"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organizace"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Adresa"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Měsíc"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Číslo"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Jak vydáno"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Kapitola"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Křížový odkaz"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Výtažek"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Poznámky"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Moje hudba"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Album"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "Kompaktní disk"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Kazeta"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Vinyl"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Umělec"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Nahrávací společnost"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Stopy"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr "Délka"
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "the"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "ml., iii, iv"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,van,der,van der,von"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr "ISBNdb.com"
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 neumožňuje vyhledávání u tohoto typu sbírky."
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Výsledky z %1: %2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "Tento zdroj nemá žádné volby."
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "Databáze záznamů"
+
+#: fetch/entrezfetcher.cpp:485
+msgid "Institution"
+msgstr "Instituce"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Chyba hledání!"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Chyba spojení při hledání %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Chyba syntaxe záznamu"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Chyba spojení %1: %2"
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr "SRU server"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Knihovna kongresu (US)"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr "Hos&titel:"
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr "Zadejte host name serveru."
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Port: "
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Zadejte číslo portu. Výchozí je %1."
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr "Cesta: "
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr "Zadejte cestu k databázi používané serverem."
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr "Formát: "
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr "Zadejte výsledkový formát používaný serverem."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr "Yahoo! Audio vyhledávání"
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "Nepodařilo načíst obrázek obálky."
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr "Amazon odkaz"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (US)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (UK)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Německo)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japonsko)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (Francie)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Kanada)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Amazon.com webové služby"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "Ze&mě: "
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "Spojené státy"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Spojené království"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Německo"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Japonsko"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "Francie"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Kanada"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon.com poskytuje data z několika lokalizovaných stránek. Vyberte tu, "
+"kterou chcete použít pro tento datový zdroj."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "&Velikost obrázku: "
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Malý obrázek"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Střední obrázek"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Velký obrázek"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Žádný obrázek"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"Lze stáhnout i obrázek obálky. Hodně velkých souborů ve sbírce se "
+"však může projevit na rychlosti."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "&ID společníka: "
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+"ID společníka identifikuje osobu, která přistupuje k Amazon.com webovým "
+"službám, a je obsaženo v každém odkazu na stránky Amazon.com."
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr "z39.50 server"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr "Použít přednastavený &server:"
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "&Databáze: "
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr "Zadejte název databáze používané serverem."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "&Kódování znaků: "
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Zadejte kódování znaků, které používá server z39.50. "
+"Nejpravděpodobnější je MARC-8, i když ISO-8859-2 je také časté."
+
+#: fetch/z3950fetcher.cpp:550
+msgid "&Format: "
+msgstr "&Formát: "
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr "Autodetekce"
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+"Zadejte datový formát, který používá z39.50 server. Je-li zvolena "
+"<i>autodetekce</i>, pokusí se Tellico automaticky rozpoznat nejlepší "
+"nastavení."
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "&Uživatel: "
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Nepovinné"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Zadejte autentizační uživatelské jméno používané databází z39.50. "
+"Většina serverů žádné nepotřebuje."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "Hes&lo: "
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Zadejte autentizační heslo používané databází z39.50. Většina "
+"serverů žádné nepotřebuje. Heslo bude v konfiguračním souboru Tellico "
+"uloženo jako prostý text."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr "Ilustrátor"
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Externí program"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "&Druh sbírky:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+"Nastavte, jaký druh sbírky obsahují data vracená externím programem."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr "&Druh výsledku: "
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr ""
+"Nastavte, jaký druh výsledku obsahují data vracená externím programem."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "Cesta k &programu: "
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+"Nastavte cestu k programu, který by měl vracet platný datový soubor "
+"Tellico."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr "Vyberte vyhledávací klíče podporované zdrojem dat."
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+"Přidejte všechny potřebné parametry. <b>%1</b> bude nahrazeno "
+"vyhledávaným termínem."
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr "Parametry"
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+msgid "Update"
+msgstr "Aktualizovat"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+"<p>Zadejte parametry, které by měly být použity pro vyhledávání "
+"dostupných aktualizací záznamu.</p><p>Formát je stejný jako pro "
+"<i>závislá</i> pole, tj. hodnoty jsou vloženy do složených závorek. "
+"Např. <i>%{author}</i>. Vizte dokumentaci pro více podrobností.</p>"
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Možnosti zdroje"
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr "Dostupná pole"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "Internetová databáze filmů"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Vyberte výsledek z IMDB"
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+"<qt>Vyhledávání vrátilo více výsledků. Vyberte jeden z "
+"uvedených.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Vyberte výsledek vyhledávání.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr "IMDB odkaz"
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Alternativní názvy"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+msgid "IMDB Rating"
+msgstr "IMDB hodnocení"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Certifikace"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"Internetová databáze filmů používá více serverů. Vyberte ten, který "
+"chcete používat."
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr "&Herecké obsazení: "
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+"Seznam členů obsazení může obsahovat mnoho lidí. Nastavte maximální "
+"počet, který má vyhledávání vrátit."
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr "Stáhnout obrázek &obálky"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr "Internet Bookshop (ibs.it)"
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Osoba"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+#, fuzzy
+msgid "UPC/EAN"
+msgstr "UPC"
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Klíčové slovo"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Hrubé hledání"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr "Původní název"
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr "Distributor"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr "Epizody"
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:343
+#, fuzzy
+msgid "&Username: "
+msgstr "&Uživatel: "
+
+#: fetch/crossreffetcher.cpp:348
+#, fuzzy
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+"Zadejte autentizační heslo používané databází z39.50. Většina "
+"serverů žádné nepotřebuje. Heslo bude v konfiguračním souboru Tellico "
+"uloženo jako prostý text."
+
+#: fetch/crossreffetcher.cpp:354
+#, fuzzy
+msgid "&Password: "
+msgstr "Hes&lo: "
+
+#: fetch/gcstarpluginfetcher.cpp:190
+#, fuzzy
+msgid "GCstar Plugin"
+msgstr "GCstar"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+#, fuzzy
+msgid "Set the collection type of the data returned from the plugin."
+msgstr ""
+"Nastavte, jaký druh sbírky obsahují data vracená externím programem."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:415
+#, fuzzy
+msgid "Select the GCstar plugin used for the data source."
+msgstr "Vyberte vyhledávací klíče podporované zdrojem dat."
+
+#: fetch/gcstarpluginfetcher.cpp:420
+#, fuzzy
+msgid "Author: "
+msgstr "Autor"
+
+#: fetch/discogsfetcher.cpp:58
+#, fuzzy
+msgid "Discogs Audio Search"
+msgstr "Yahoo! Audio vyhledávání"
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr ""
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr "Get Hot New Stuff"
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr "Verze"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr "Stahování"
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr "Datum vydání"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+"Toto je seznam všech položek dostupných ke stažení. Dříve "
+"nainstalované položky mají ikonku zaškrtnutí, zatímco nové mají "
+"ikonku aktualizace."
+
+#: newstuff/dialog.cpp:137
+msgid "The name and license of the selected item"
+msgstr "Název a licence zvolené položky"
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr "Autor zvolené položky"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr "Instalace"
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr "Stáhnout a nainstalovat zvolenou šablonu"
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+"Stáhnout a nainstalovat zvolený skript. Některé skripty je nutné po "
+"instalaci nakonfigurovat."
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr "Popis zvolené položky."
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr "Stahuji informace..."
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Připraven."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr "Aktualizace"
+
+#: newstuff/dialog.cpp:413
+msgid "Installing item..."
+msgstr "Instaluji položku..."
+
+#: translators/bibteximporter.cpp:79
+#, fuzzy
+msgid "No valid bibtex entries were found"
+msgstr "V souboru %1 nebyly nalezeny žádné platné Bibtex záznamy"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "V souboru %1 nebyly nalezeny žádné platné Bibtex záznamy"
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Možnosti Bibtex"
+
+#: translators/bibteximporter.cpp:287
+#, fuzzy
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Kódovat v Unicode (UTF-8)"
+
+#: translators/bibteximporter.cpp:288
+#, fuzzy
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Kódovat exportovaný soubor v Unicode (UTF-8)."
+
+#: translators/bibteximporter.cpp:289
+#, fuzzy
+msgid "Use user locale (%1) encoding"
+msgstr "Kódovat podle uživatelského nastavení (%1)"
+
+#: translators/bibteximporter.cpp:293
+#, fuzzy
+msgid "Read the imported file in the local encoding."
+msgstr "Kódovat exportovaný soubor v místním formátu."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "Tellico zip soubor"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.tc|soubory Tellico (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Všechny soubory"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>Knihovna formátu Alexandria s názvem <i>%1</i> už existuje. Všechny "
+"knihy v této knihovně mohou být přepsány.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "Při načítání XML byla na řádce %1, sloupci %2 chyba."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "Chybová zpráva z Qt je:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Je to z budoucí verze Tellico."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Tellico soubor převádí na současnější verzi formátu dokumentu. Pokud "
+"by by byla ke čtení tohoto souboru v budoucnu použita starší verze "
+"Tellico, mohlo by dojít ke ztrátě dat."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Neznámé"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "Soubor je prázdný."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "Soubor neobsahuje žádná data sbírky."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Nepřečtené knihy"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Staré filmy"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "Hudba 80. let"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Oblíbené"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Procházím audio soubory..."
+
+#: translators/audiofileimporter.cpp:129
+#, fuzzy
+msgid "Bitrate"
+msgstr "Bibtex"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(Různé)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Možnosti audio souboru"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Rekurzívní hledání v &adresářích"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+"Je-li zaškrtnuto, v adresářích budou rekurzívně vyhledávány audio "
+"soubory."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr "&Začlenit umístění souboru"
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr ""
+"Je-li zaškrtnuto, budou názvy souborů každé stopy přidány do "
+"záznamů."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:353
+#, fuzzy
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr ""
+"Je-li zaškrtnuto, budou názvy souborů každé stopy přidány do "
+"záznamů."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|CSV soubory (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "Možnosti CSV"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Začlenit názvy polí coby hlavičky sloupců"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr "Je-li zaškrtnuto, bude přidána řada hlaviček s názvy polí."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Oddělovač"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"Kromě čárky mohou být jako oddělovač oddělující všechny hodnoty v "
+"souboru použity i jiné znaky."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Čárka"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Použít čárku jako oddělovač."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Středník"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Použít střední jako oddělovač."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Tabulátor"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Použít tabulátor jako oddělovač."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Jiné"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Použít vlastní řetězec jako oddělovač."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr ""
+"Jako oddělovač může být použit vlastní řetězec, třeba dvojtečka."
+
+#: translators/filelistingimporter.cpp:63
+msgid "Scanning files..."
+msgstr "Procházím soubory..."
+
+#: translators/filelistingimporter.cpp:191
+msgid "File Listing Options"
+msgstr "Možnosti výpisu souborů"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr "Rekurzívní hledání v adresářích"
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+"Je-li zaškrtnuto, budou v adresářích rekurzívně vyhledávány všechny "
+"soubory."
+
+#: translators/filelistingimporter.cpp:198
+msgid "Generate file previews"
+msgstr "Generovat náhledy souborů"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+"Je-li zaškrtnuto, budou generovány náhledy obsahu souborů, což může "
+"zpomalit výpis adresáře."
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "ONIX archív"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.zip|Zip soubory (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "Možnosti ONIX archívu"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Začlenit do archívu obrázky"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Je-li zaškrtnuto, budou obrázky dokumentu začleněny do zipovaného ONIX "
+"archívu."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr ""
+"<qt>Tellico se nepodařilo přistoupit na zařízení CD-ROM - "
+"<i>%1</i>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+msgid "Select CDDB Entry"
+msgstr "Vybrat záznam z CDDB"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr "Vybrat záznam z CDDB:"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>Nebyly nalezeny žádné záznamy, které by odpovídaly CD.</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "<qt>Tellico se nepodařilo dokončit hledání CD.</qt>"
+
+#: translators/freedbimporter.cpp:470
+msgid "Various"
+msgstr "Různé"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Možnosti audio CD"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Číst data za zařízení CD-ROM"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Vyberte nebo zadejte umístění zařízení CD-ROM."
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Číst pouze všechny soubory CDDB keše"
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+"Číst rekurzívně data ze všech souborů CDDB keše ve standardních "
+"adresářích keše."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr "GCfilms"
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.gcf|Datové soubory GCfilms (*.gcf)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.gcs|Datové soubory GCstar (*.gcs)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "Možnosti XSLT"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "XSLT soubor:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr "Zvolte XSLT soubor použitý pro transformaci XML Tellico dat."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Možnosti Alexandria"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr "&Knihovna:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "Bibtexml"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Bibtexml soubory (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|XML soubory (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Možnosti Tellico XML"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Začlenit do XML dokumentu obrázky"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Je-li zaškrtnuto, budou obrázky dokumentu začleněny do XML proudu jako "
+"base64 kódované elementy."
+
+#: translators/importer.h:100
+msgid "Loading data..."
+msgstr "Načítám data..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr "Načítám %1..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "Bibtex"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Bibtex soubory (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Expandovat řetězcová makra"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Je-li zaškrtnuto, řetězcová makra budou expandována a nebudou zapsány "
+"žádné záznamy @řetězec{}."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Použít zabalení URL"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr "Je-li zaškrtnuto, budou URL pole zabalena do deklarace \\url."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Přeskočit záznamy s prázdnými citačními klíči"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr ""
+"Je-li zaškrtnuto, budou přeskočeny všechny záznamy bez Bibtex "
+"citačního klíče."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Způsob Bibtex citace:"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Závorky"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Uvozovky"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"<qt>Způsob citace při exportu Bibtex. Všechny hodnoty polí budou "
+"vloženy buď do složených závorek nebo do uvozovek.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Vyberte importovaný druh sbírky."
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr "&První řada obsahuje názvy polí"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr "Je-li zaškrtnuto, bude první řada použita jako názvy polí."
+
+#: translators/csvimporter.cpp:248
+msgid "&Comma"
+msgstr "Čár&ka"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr "&Středník"
+
+#: translators/csvimporter.cpp:259
+msgid "Ta&b"
+msgstr "Ta&bulátor"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr "&Jiný:"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "Tabulka se zobrazuje až po prvních pět řádků souboru CSV."
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt> Nastavte každý sloupec tak, aby odpovídal poli ve sbírce. Vyberte "
+"sloupec, označte pole a klepněte na tlačítko <i>Přiřadit pole</i>.</qt>"
+
+#: translators/csvimporter.cpp:298
+msgid "Co&lumn:"
+msgstr "S&loupec:"
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr "&Datové pole v tomto sloupci:"
+
+#: translators/csvimporter.cpp:315
+msgid "&Assign Field"
+msgstr "Přiř&adit pole"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Nové pole"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|soubory databáze Pilot (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Zobrazit sloupce"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "Možnosti PilotDB"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Nastavit pro databázi značku zálohování na PDA"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>Soubor není platným datovým souborem GCstar.</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Tellico narazil na chybu při zpracovávání XSLT."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "K importu tohoto souboru je potřeba platný XSLT soubor."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|XSL soubory (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|HTML soubory (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Lidé"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(seskupeno podle %1)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "Možnosti HTML"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Tisk hlaviček polí"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr ""
+"Je-li zaškrtnuto, budou názvy polí vytištěny jako hlavičky tabulky."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Seskupit záznamy"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr "Je-li zaškrtnuto, budou záznamy seskupeny podle zvoleného pole."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Exportovat samostatné soubory záznamů"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr ""
+"Je-li zaškrtnuto, budou pro každý záznam vytvořeny samostatné soubory."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+#, fuzzy
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico nemůže načíst obrázek ze souboru %1."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Vlastnosti datového zdroje"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "&Název zdroje: "
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr ""
+"Název identifikuje datový zdroj a měl by být unikátní a informativní."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "&Druh zdroje: "
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr "Tellico podporuje několik různých datových zdrojů."
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr "Aktualizace ze zdroje má přepsat uživatelská data"
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Je-li zaškrtnuto, aktualizace záznamů přepíše stávající informace."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Jakékoliv pole"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "obsahuje"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "neobsahuje"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "je shodné"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "není rovno"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "odpovídá reg. výrazu"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "neodpovídá reg. výrazu"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Upravit..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Pokročilý filtr"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Kritéria filtru"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "&Odpovídá všemu, co následuje"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "O&dpovídá něčemu z toho, co následuje"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Název filtru:"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "&Uložit filtr"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Prostý text"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Odstavec"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Volba"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Přepínač"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Tabulka"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Závislé"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Datum"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr "Aktualizuji %1..."
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr "Aktualizuji záznamy..."
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr "Aktualizovat záznamy"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr "Aktualizuji <b>%1</b>..."
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr "Vyberte správný výsledek"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+"<qt><b>%1</b> vrátil více výsledků, které by mohly odpovídat "
+"<b>%2</b>, záznamu, který je ve sbírce teď. Vyberte prosím správný "
+"výsledek.</qt>"
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Rozvinout všechny skupiny"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Zavinout všechny skupiny"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Filtrovat podle skupin"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (seřadit podle počtu)"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Skupina"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Možnosti importu"
+
+#: importdialog.cpp:62
+msgid "&Replace current collection"
+msgstr "&Nahradit stávající sbírku"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr "Nahradit stávající sbírku obsahem importovaného souboru."
+
+#: importdialog.cpp:65
+msgid "A&ppend to current collection"
+msgstr "Př&ipojit ke stávající sbírce"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Připojit obsah importovaného souboru ke stávající sbírce. Toto je "
+"možné, pouze pokud se shodují druhy sbírek."
+
+#: importdialog.cpp:69
+msgid "&Merge with current collection"
+msgstr "&Sloučit se stávající sbírkou"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Připojit obsah importovaného souboru ke stávající sbírce. Toto je "
+"možné, pouze pokud se shodují druhy sbírek. Aby byly záznamy sloučeny, "
+"musí být v přesně stejném pořadí."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Importovat"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|RIS soubory (*.ris)"
+
+#: importdialog.cpp:277
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.amc|AMC datové soubory (*.amc)"
+
+#: importdialog.cpp:281
+#, fuzzy
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdb|soubory databáze Pilot (*.pdb)"
+
+#: importdialog.cpp:285
+#, fuzzy
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.ris|RIS soubory (*.ris)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico nemůže načíst soubor %1."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico nemůže zapsat soubor %1."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico nemůže uploadovat soubor %1."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Připojeny mohou být pouze sbírky se stejným druhem záznamů. "
+"Stávající sbírka nebude změněna."
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Sloučeny mohou být pouze sbírky se stejným druhem záznamů. "
+"Stávající sbírka nebude změněna."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico nemůže načíst obrázek ze souboru %1."
+
+#: entryiconview.cpp:287
+#, fuzzy
+msgid "&Sort By"
+msgstr "&Port: "
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Zápůjčka"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "Následující položky budou zapůjčeny:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "Následující položka je zapůjčena:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "&Komu půjčit:"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Zadejte jméno osoby, které položky půjčujete. Kliknutím na tlačítko "
+"můžete vybrat z knihy adres."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "&Datum zápůjčky:"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+"Datum zápůjčky je den, kdy byly položky půjčeny. Ve výchozím "
+"nastavení se použije dnešní datum."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "Datum &vrácení:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"Datum vrácení je den, kdy mají být položky vráceny. Pokud nechcete "
+"zápůjčku vložit do aktivního kalendáře, není datum vrácení "
+"vyžadováno."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "Po&známka:"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "K zápůjčce můžete připojit poznámky."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "&Vložit upomínku do aktivního kalendáře"
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"<qt>Zaškrtnutím tohoto přepínače vložíte do svého aktivního "
+"kalendáře <em>úkol</em>, který můžete spravovat pomocí programu "
+"KOrganizer. Přepínač je aktivní, pouze pokud nastavíte datum vrácení."
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Vytvořit novou sbírku"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Nová sbírka &knih"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Vytvořit novou sbírku knih"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Nová &bibliografie"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Vytvořit novou bibtex bibliografii"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Nová sbírka ko&miksů"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Vytvořit novou sbírku komiksů"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Nová &video sbírka"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Vytvořit novou video sbírku"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Nová sbírka &hudby"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Vytvořit novou sbírku hudby"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Nová sbírka min&cí"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Vytvořit novou sbírku mincí"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Nová sbírka &známek"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Vytvořit novou sbírku známek"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Nová sbírka &karet"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Vytvořit novou sbírku výměnných karet"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Nová sbírka &vín"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Vytvořit novou sbírku vín"
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Nová sbírka &her"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Vytvořit novou sbírku her"
+
+#: mainwindow.cpp:272
+#, fuzzy
+msgid "New Boa&rd Game Collection"
+msgstr "Nová sbírka &her"
+
+#: mainwindow.cpp:274
+#, fuzzy
+msgid "Create a new board game collection"
+msgstr "Vytvořit novou sbírku her"
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr "Nový katalog &souborů"
+
+#: mainwindow.cpp:282
+msgid "Create a new file catalog"
+msgstr "Vytvořit nový katalog souborů"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Nová &vlastní sbírka"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Vytvořit novou vlastní sbírku"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Otevřít existující dokument"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Otevřít nedávno používaný soubor"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Uložit dokument"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Uložit dokument jako jiný soubor..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Tisk obsahu dokumentu..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Ukončit program"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Importovat data sbírky z jiných formátů"
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Importovat data Tellico..."
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Importovat další datový soubor Tellico"
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "Importovat CSV data..."
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Importovat CSV soubor"
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "Importovat MODS data..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Importovat MODS soubor"
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Importovat Alexandria data..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Importovat data ze správce sbírek knih Alexandria"
+
+#: mainwindow.cpp:352
+#, fuzzy
+msgid "Import Delicious Library Data..."
+msgstr "Importovat data Tellico..."
+
+#: mainwindow.cpp:353
+#, fuzzy
+msgid "Import data from Delicious Library"
+msgstr "Importovat metadata z audio souborů"
+
+#: mainwindow.cpp:359
+#, fuzzy
+msgid "Import Referencer Data..."
+msgstr "Importovat RIS data..."
+
+#: mainwindow.cpp:360
+#, fuzzy
+msgid "Import data from Referencer"
+msgstr "Importovat referenční RIS soubor"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Importovat Bibtex data..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Importovat soubor s bibliografií Bibtex"
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Importovat Bibtexml data..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Importovat soubor s bibliografií Bibtexml"
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "Importovat RIS data..."
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Importovat referenční RIS soubor"
+
+#: mainwindow.cpp:387
+#, fuzzy
+msgid "Import PDF File..."
+msgstr "Importovat soubor"
+
+#: mainwindow.cpp:388
+#, fuzzy
+msgid "Import a PDF file"
+msgstr "Importovat CSV soubor"
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Importovat metadata audio souboru..."
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Importovat metadata z audio souborů"
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Importovat Audio CD data"
+
+#: mainwindow.cpp:405
+msgid "Import audio CD information"
+msgstr "Importovat informace z audio CD"
+
+#: mainwindow.cpp:414
+msgid "Import GCstar Data..."
+msgstr "Importovat GCstar data"
+
+#: mainwindow.cpp:415
+msgid "Import a GCstar data file"
+msgstr "Importovat datový soubor GCstar"
+
+#: mainwindow.cpp:421
+#, fuzzy
+msgid "Import Griffith Data..."
+msgstr "Importovat GCstar data"
+
+#: mainwindow.cpp:422
+#, fuzzy
+msgid "Import a Griffith database"
+msgstr "Exportovat do databáze PilotDB"
+
+#: mainwindow.cpp:428
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Importovat data z programu Ant Movie Catalog"
+
+#: mainwindow.cpp:429
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Importovat datový soubor z Ant Movie Catalog"
+
+#: mainwindow.cpp:435
+msgid "Import File Listing..."
+msgstr "Importovat výpis souborů..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr "Importovat informace o souborech v adresáři"
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "Importovat XSL Transform..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Importovat s pomocí XSL Transform"
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Exportovat"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Exportovat data sbírky do jiných formátů"
+
+#: mainwindow.cpp:461
+msgid "Export to XML..."
+msgstr "Exportovat do XML..."
+
+#: mainwindow.cpp:462
+msgid "Export to a Tellico XML file"
+msgstr "Exportovat do Tellico XML souboru"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Exportovat do Zip..."
+
+#: mainwindow.cpp:469
+msgid "Export to a Tellico Zip file"
+msgstr "Exportovat do Tellico Zip souboru"
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "Exportovat do HTML..."
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Exportovat do HTML souboru"
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "Exportovat do CSV..."
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Exportovat do souboru s hodnotami oddělenými čárkou"
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "Exportovat do PilotDB..."
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Exportovat do databáze PilotDB"
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Exportovat do Alexandria..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Exportovat do knihovny Alexandria"
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Exportovat do Bibtex..."
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Exportovat souboru Bibtex"
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Exportovat do Bibtexml..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Exportovat do souboru Bibtexml"
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "Exportovat do ONIX..."
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Exportovat do ONIX souboru"
+
+#: mainwindow.cpp:524
+msgid "Export to GCfilms..."
+msgstr "Exportovat do GCfilms..."
+
+#: mainwindow.cpp:525
+msgid "Export to a GCfilms data file"
+msgstr "Exportovat datového souboru GCfilms"
+
+#: mainwindow.cpp:531
+#, fuzzy
+msgid "Export to GCstar..."
+msgstr "Exportovat do GCfilms..."
+
+#: mainwindow.cpp:532
+#, fuzzy
+msgid "Export to a GCstar data file"
+msgstr "Exportovat datového souboru GCfilms"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "Exportovat XSL Transform..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Exportovat s pomocí XSL Transform"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Vyjmout označený text a vložit jej do schránky"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Kopírovat označený text do schránky"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Vložit obsah schránky"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Vybrat všechny záznamy ve sbírce"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Zrušit výběr všech záznamů ve sbírce"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Hledání na internetu..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Hledat na internetu..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "Pokročilý &filtr..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Filtrovat sbírku"
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&Nový záznam..."
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Vytvořit nový záznam"
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "&Upravit záznam..."
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Upravit označené záznamy"
+
+#: controller.cpp:621 mainwindow.cpp:577
+msgid "D&uplicate Entry"
+msgstr "&Klonovat záznam"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Kopírovat označené záznamy"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "&Smazat záznam"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Smazat označené záznamy"
+
+#: mainwindow.cpp:585
+#, fuzzy
+msgid "&Merge Entries"
+msgstr "&Smazat záznamy"
+
+#: mainwindow.cpp:588
+#, fuzzy
+msgid "Merge the selected entries"
+msgstr "Smazat označené záznamy"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "&Generovat zprávy..."
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Generovat zprávy o sbírce"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "&Zapůjčit..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Zapůjčit označené položky"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "&Vrátit"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Vrátit označené položky"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "&Přejmenovat sbírku..."
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Přejmenovat sbírku"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "P&ole sbírky..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Změnit pole sbírky"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "Převést na &bibliografii"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Převést sbírku knih na bibliografii"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "Řetězová &makra..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Upravit řetězová makra Bibtex"
+
+#: mainwindow.cpp:626
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Kopírovat Bibtex do schránky"
+
+#: mainwindow.cpp:627
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Kopírovat citace Bibtex do schránky"
+
+#: mainwindow.cpp:632
+msgid "Cite Entry in &LyX"
+msgstr "Citovat záznam v &LyX"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Citovat označené záznamy v LyX"
+
+#: mainwindow.cpp:638
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Citovat záznam v &OpenOffice.org"
+
+#: mainwindow.cpp:639
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Citovat označené záznamy v OpenOffice.org"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, no-c-format
+msgid "&Update Entry"
+msgstr "&Aktualizovat záznam"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr "Všechny zdroje"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr "Aktualizovat data záznamu ze všech dostupných zdrojů"
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Zobrazit sku&pinový pohled"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Povolit/zakázat skupinový pohled"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Skrýt sku&pinový pohled"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Zobrazit &editor záznamů"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Povolit/zakázat editor"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "Skrýt &editor záznamů"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Zobrazit pohled na &záznam"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Povolit/zakázat pohled na záznam"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "Skrýt pohled na &záznam"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Změnit seskupení"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "&Výběr skupin"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Změnit seskupení sbírky"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Filtr"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Vyčistit filtr"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Filtrovat zde..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Skupiny"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt><i>Skupinový pohled</i> záznamy seřadí do skupin podle zvoleného "
+"pole.</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt><i>Sloupcový pohled</i> zobrazí u každého záznamu hodnoty více "
+"polí.</qt>"
+
+#: mainwindow.cpp:831
+#, fuzzy
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Tellico - správce sbírek pro KDE"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Vytvářím nový dokument..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Otevírám soubor..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Otevřít soubor"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Ukládám soubor..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+"<qt><p>Ukládáte soubor s mnoha obrázky, což může způsobit značné "
+"zpomalení programu Tellico. Chcete tyto obrázky uložit samostatně v "
+"datovém adresáři Tellico, aby se zlepšila rychlost?</p><p>Toto "
+"nastavení lze kdykoliv později změnit v konfiguračním okně.</p></qt>"
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr "Uložit obrázky samostatně"
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr "Uložit obrázky do souboru"
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Ukládám soubor s novým názvem..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Probíhá tisk..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"Sbírka má nastaven filtr tak, aby byla zobrazena jen určitá část "
+"záznamů. Vytištěny budou pouze viditelné záznamy. Pokračovat?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Zpracovávám dokument..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Ukončuji..."
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Celkem záznamů: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 filtrováno, %2 označeno)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 filtrováno)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 označeno)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Vytisknout %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Strana %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Zkontrolujte instalaci programu."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Importuji data..."
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Importovat soubor"
+
+#: mainwindow.cpp:1864
+msgid "Import Directory"
+msgstr "Importovat adresář"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Exportuji data..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Exportovat jako"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Řetězcová makra"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Makro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Řetězec"
+
+#: mainwindow.cpp:1999
+msgid "Creating citations..."
+msgstr "Vytvářím citace..."
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Filtry"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt><i>Filtrový pohled</i> ukazuje záznamy, které splňují pravidla "
+"filtru.</qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Půjčky"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt><i>Půjčkový pohled</i> ukazuje seznam všech osob, které si ze "
+"sbírky půjčili položky.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr "Aktualizovat data záznamu z %1"
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico nemůže načíst obrázek %1."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr "Soubor s názvem \"%1\" již existuje. Opravdu jej chcete přepsat?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Přepsat soubor?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Přepsat"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Filtr (seřadit podle počtu)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Opravdu chcete smazat tento záznam?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Smazat záznam"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Opravdu chcete smazat tyto záznamy?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Smazat více záznamů"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "&Upravit záznamy..."
+
+#: controller.cpp:627
+msgid "D&uplicate Entries"
+msgstr "&Klonovat záznamy"
+
+#: controller.cpp:628
+msgid "&Update Entries"
+msgstr "&Upravit záznamy"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "&Smazat záznamy"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+"Následující položky jsou už zapůjčené, ale Tellico v současné "
+"době nepodporuje půjčování jedné položky vícekrát. Položky budou "
+"odstraněny ze seznamu položek k zapůjčení."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Výchozí kalendář"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"V současné době podporuje Tellico pouze lokální kalendáře. Aktivní "
+"kalendář je vzdálená, a proto nebudou zápůjčky zařazeny."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Aktivní kalendář"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 by měl vrátit \"%2\""
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(Prázdné)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - správce sbírek pro KDE"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Neotvírat znovu poslední otevřený soubor"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Importovat <filename> jako Bibtex soubor"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Importovat <filename> jako MODS soubor"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Importovat <filename> jako RIS soubor"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Soubor k otevření"
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr "Skripty datových zdrojů"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Ikony"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Autor knihovny btparse"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr "Příklady kódu a všeobecná inspirace"
+
+#: main.cpp:50
+#, fuzzy
+msgid "Author of libcsv library"
+msgstr "Autor knihovny btparse"
+
+#: main.cpp:52
+#, fuzzy
+msgid "Author of rtf2html library"
+msgstr "Autor knihovny btparse"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Pole sbírky"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Aktuální pole"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "&Nové"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Přidat do sbírky nové pole"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "&Smazat"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Odstranit pole ze sbírky"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Posunout pole v seznamu nahoru. Pořadí v seznamu je důležité pro "
+"rozložení editoru záznamů."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Posunout pole v seznamu dolu. Pořadí v seznamu je důležité pro "
+"rozložení editoru záznamů."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Vlastnosti pole"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "&Název:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "Název pole"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "D&ruh:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "Druh pole určuje, jaké hodnoty lze použít. "
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "Pro většinu polí se používá <i>běžný text</i>. "
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "Pro větší kusy textu se používá <i>odstavec</i>. "
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Volba</i> omezuje pole na určité hodnoty. "
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "<i>Přepínač</i> je pro jednoduchou hodnotu ano/ne. "
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr "<i>Číslo</i> značí, že pole obsahuje číselnou hodnotu. "
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+"<i>URL</i> je pro pole, která obsahují URL, včetně odkazů na další "
+"soubory. "
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr ""
+"<i>Tabulka</i> může obsahovat jeden nebo více sloupců s hodnotami. "
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "Pole <i>obrázek</i> obsahuje obrázek. "
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+"Pole <i>datum</i> může být použito pro hodnoty obsahující den, měsíc "
+"a rok. "
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+"Pole <i>hodnocení</i> používá hvězdičky k zobrazení čísla "
+"hodnocení. "
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"<i>Závislé</i> pole závisí na dalších polích a je formátováno podle "
+"popisu. "
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"<i>Pouze pro čtení</i> je pro interní hodnoty, může se hodit pro import "
+"a export. "
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "Kate&gorie:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr "Kategorie určuje, kde bude pole v editoru umístěno."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "Pop&is:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"Popis je šikovnou připomínkou informací, které pole obsahuje. U "
+"<i>závislých</i> polí je popis řetězcem typu \"%{year} %{title}\", ve "
+"kterém budou pojmenovaná pole nahrazena."
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr "&Výchozí hodnota:"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr "<qt>Pro nové položky lze nastavit výchozí hodnotu.</qt>"
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr "Povo&lené hodnoty:"
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>U polí druhu <i>volba</i> jsou povoleny pouze tyto hodnoty. Naleznete "
+"je v kombinovaném seznamu. Dostupné možnosti jsou odděleny středníkem, "
+"např. \"pes; kočka; myš\"</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "Rozšířené &vlastnosti:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "&Nastavit..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"Rozšířené vlastnosti pole se používají k určení věcí jako je "
+"například odpovídající bibtexové pole."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Možnosti formátování"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Žádné formátování"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+"Tato volba zabraňuje automatickému formátování pole nebo nahrazení "
+"písmen velkými."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Povolit pouze náhradu za velká písmena"
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+"Tato volba umožňuje náhradu za velká písmena, ale ne speciální "
+"formátování."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Formátovat jako název"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Tato volba nahradí písmena za velké a zformátuje pole jako název, ale "
+"pouze pokud jsou tyto možnosti nastaveny globálně."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Formátovat jako název"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Tato volba nahradí písmena za velké a zformátuje pole jako název, ale "
+"pouze pokud jsou tyto možnosti nastaveny globálně."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Možnosti pole"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Povolit automatické doplňování"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Je-li zaškrtnuto, bude v při úpravě textu v tomto poli povolena funkce "
+"automatického doplňování KDE."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Povolit více hodnot"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Je-li zaškrtnuto, bude Tellico v poli očekávat více hodnot oddělených "
+"středníkem."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Povolit seskupování"
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Je-li zaškrtnuto, bude možné toto pole použít k seskupení záznamů ve "
+"skupinovém pohledu."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr "Vrátit vlastnosti označeného pole na výchozí."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Upravit pole"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Odstranění povolených hodnot, které v současné době sbírka "
+"obsahuje, z pole <i>%1</i>, může způsobit poškození dat. Chcete si "
+"ponechat své upravené hodnoty nebo akci zrušit a vrátit se ke "
+"stávajícím?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Ponechat upravené hodnoty"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Vrátit vlastnosti pole"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Opravdu chcete vrátit vlastnosti pole <em>%1</em> na výchozí "
+"hodnoty?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Vrátit"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Rozšířené vlastnosti pole"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr "Pole s tímto názvem už existuje. Zadejte prosím jiný název."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr "<qt>Kategorie možná není prázdná. Zadejte prosím kategorii.</qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>Pole nemůže být ve stejné kategorii jako pole <em>odstavec</em>, "
+"<em>tabulka</em> nebo <em>obrázek</em>. Zadejte prosím jinou "
+"kategorii.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"Název pole nemůže být stejný jako existující kategorie. Zadejte "
+"prosím jiný název."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+"Rozsah pole hodnocení musí být mezi 1 a 10 a spodní hranice musí být "
+"nižší než horní. Zadejte prosím jiné spodní a horní hodnoty."
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "Tabulky jsou omezeny na maximálně deset sloupců."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Aktuální soubor byl změněn.\n"
+"Chcete ho uložit?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Neuložené změny"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Vyberte vypůjčitele"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Nastavit Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Obecné volby"
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr "&Znovu otevřít soubor při spuštění"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Je-li zaškrtnuto, naposledy otevřený soubor bude otevřen při dalším "
+"spuštěním."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "Při &spuštění zobrazit \"Tip dne\""
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr ""
+"Je-li zaškrtnuto, bude při spuštění programu zobrazen \"Tip dne\"."
+
+#: configdialog.cpp:213
+#, fuzzy
+msgid "Image Storage Options"
+msgstr "Možnosti obrázku"
+
+#: configdialog.cpp:214
+#, fuzzy
+msgid "Store images in data file"
+msgstr "&Začlenit obrázky do datového souboru"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr ""
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr ""
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Možnosti formátování"
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr "Názvy a jména automaticky s &velkými písmeny"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Je-li zaškrtnuto, názvy a jména budou mít automaticky změněna první "
+"písmena na velká."
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr "Automaticky &formátovat názvy a jména"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr "Je-li zaškrtnuto, názvy a jména budou automaticky formátována."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr "Nepřevádět na velká &písmena:"
+
+#: configdialog.cpp:243
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Seznam slov, která nemají být převedena na velká písmena. "
+"Oddělovat středníkem.</qt>"
+
+#: configdialog.cpp:249
+msgid "Artic&les:"
+msgstr "Č&leny:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>Seznam slov, která mají být považována za členy, jsou-li prvním "
+"slovem v názvu. Oddělovat středníkem.</qt>"
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr "Osobní přípon&y:"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Seznam přípon, která mohou být použita ve jménech osob. Oddělovat "
+"středníkem.</qt>"
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr "Přípony &příjmení:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Seznam předpon, které mohou být použit v příjmeních. Oddělovat "
+"středníkem.</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Tisk"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Možnosti tisku"
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr "&Formátovat názvy a jména"
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr "&Tisk hlaviček polí"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Možnosti seskupování"
+
+#: configdialog.cpp:313
+msgid "&Group the entries"
+msgstr "&Seskupit záznamy"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Možnosti obrázku"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr "Maximální &šířka obrázků:"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Maximální šířka tištěných obrázků. Poměr stran je zachován."
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr "Maximální &výška obrázků:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr "Maximální výška tištěných obrázků. Poměr stran je zachován."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Šablony"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Možnosti šablon"
+
+#: configdialog.cpp:369
+msgid "Template:"
+msgstr "Šablona:"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+"Zvolte šablonu pro aktuální druh sbírky. Ne všechny šablony využijí "
+"nastavení písma a barev."
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr "&Náhled..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr "Zobrazit náhled šablony"
+
+#: configdialog.cpp:398
+msgid "Font Options"
+msgstr "Nastavení písma"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr "Písmo:"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr ""
+"Toto písmo se předává šabloně použité při zobrazení záznamu."
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr "Velikost:"
+
+#: configdialog.cpp:425
+msgid "Color Options"
+msgstr "Nastavení barev"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr "Barva pozadí:"
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr "Tato barva se předává šabloně použité při zobrazení záznamu."
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr "Barva textu:"
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr "Barva zvýraznění:"
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr "Barva zvýrazněného textu:"
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr "Správa šablon"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr "Instalace..."
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr "Kliknutím nainstalujete novou šablonu."
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr "Stažení..."
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr "Kliknutím stáhnete z internetu další šablony."
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr "Vymazat..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr "Kliknutím vyberete a odstraníte nainstalované šablony."
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Datové zdroje"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Možnosti datových zdrojů"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Zdroj"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr "Posunout &nahoru"
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+"Pořadí datových zdrojů určuje pořadí, kterého se Tellico drží při "
+"automatické aktualizaci záznamů."
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr "Posunout &dolu"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "&Nový..."
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr "Kliknutím přidáte nový datový zdroj."
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Upravit..."
+
+#: configdialog.cpp:533
+msgid "Click to modify the selected data source."
+msgstr "Kliknutím upravíte vybraný datový zdroj."
+
+#: configdialog.cpp:536
+msgid "Click to delete the selected data source."
+msgstr "Kliknutím vymažete vybraný datový zdroj."
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr "Kliknutím stáhnete z internetu další datové zdroje."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr "*.tar.gz *.tgz|balíček se šablonami (*.tar.gz)"
+
+#: configdialog.cpp:1049
+msgid "Delete Template"
+msgstr "Smazat šablonu"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr "Vyberte šablonu k vymazání:"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "Vypůjčitel"
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Vrácení"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Upravit půjčku..."
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "Vypůjčitel (seřadit podle počtu)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "Moje sbírka"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Sbírka knih"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Sbírka komiksů"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Video sbírka"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Sbírka hudby"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Sbírka mincí"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Sbírka známek"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Sbírka vín"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Sbírka karet"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Sbírka her"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr "Katalog souborů"
+
+#: collectionfactory.cpp:135
+#, fuzzy
+msgid "Board Game Collection"
+msgstr "Sbírka her"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Vlastní sbírka"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+"<qt><i>Pohled na záznam</i> ukazuje formátovaný pohled na obsah "
+"záznamu.</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt><i>Ikonový pohled</i> ukazuje všechny záznamy ve sbírce nebo "
+"skupině pomocí ikon, které mohou být obrázky v záznamech.</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Možnosti exportu"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Formátování"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Formátovat všechna pole"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Je-li zaškrtnuto, budou hodnoty všech polí automaticky formátovány "
+"podle svého druhu formátování."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Exportovat pouze označené záznamy"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr ""
+"Je-li zaškrtnuto, budou exportovány pouze aktuálně označené záznamy."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Kódování"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Kódovat v Unicode (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Kódovat exportovaný soubor v Unicode (UTF-8)."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Kódovat podle uživatelského nastavení (%1)"
+
+#: exportdialog.cpp:72
+#, fuzzy
+msgid "Encode the exported file in the local encoding."
+msgstr "Kódovat exportovaný soubor v místním formátu."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "&Hledat"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "&Stop"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Internetové hledání"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Dotaz pro vyhledávání"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr "Vyhl&edávání:"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+"Zadejte hodnotu k vyhledání. Hledání ISBN musí obsahovat celé ISBN."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Vyberte druh vyhledávání"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Kliknutím spustíte nebo zastavíte vyhledávání"
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr "&Vícenásobné hledání ISBN/UPC"
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr ""
+"Zaškrtněte přepínač, chcete-li vyhledávat více ISBN nebo UPC hodnot."
+
+#: fetchdialog.cpp:138
+msgid "Edit List..."
+msgstr "Upravit seznam..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr "Kliknutím otevřete okno pro zadání nebo úpravu více ISBN hodnot."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "Hledat &v:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Vyberte databázi, která bude prohledávána"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"V průběhu vyhledávání budou do seznamu přidávány výsledky. "
+"Vyberete-li nějaký, bude stažen kompletní záznam a zobrazen v pohledu "
+"níže."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"Vybráním ze seznamu výše můžete na tomto místě zobrazit záznam "
+"před přidáním do aktuální sbírky."
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "Přid&at záznam"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Přidat označený záznam do aktuální sbírky"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr "Další výsledky"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr "Stáhnout další výsledky z aktuálního datového zdroje"
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Vyprázdnit všechna vyhledávací pole a výsledky"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Ruším vyhledávání..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Hledám..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "Vyhledávání nevrátilo žádné výsledky."
+
+#: fetchdialog.cpp:372
+#, fuzzy, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr "Výsledků vyhledávání: %n."
+
+#: fetchdialog.cpp:412
+#, fuzzy
+msgid "No results were found for the following ISBN values:"
+msgstr ""
+"<qt>Pro následující kódy ISBN nebyly nalezeny žádné záznamy:</qt>"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Stahuji %1..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr ""
+"Pro druh aktuální sbírky nejsou k dispozici žádné internetové zdroje."
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr "Upravit hodnoty ISBN/UPC"
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Zadejte hodnoty ISBN nebo UPC, jednu na řádek.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "&Načíst ze souboru..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Načíst seznam z textového souboru.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>Vyhledávání ISBN může obsahovat maximálně 100 ISBN hodnot. Bude "
+"použito pouze prvních 100 hodnot vašeho seznamu.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Upravit záznam"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Nový záznam"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "&Uložit záznam"
+
+#: entryeditdialog.cpp:77
+msgid "Go to the previous entry in the collection"
+msgstr "Jít na předchozí záznam ve sbírce"
+
+#: entryeditdialog.cpp:82
+msgid "Go to the next entry in the collection"
+msgstr "Jít na následující záznam ve sbírce"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Opravdu chcete upravit tyto záznamy?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Upravit více záznamů?"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr ""
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Upravit záznamy"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "&Uložit záznamy"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"Aktuální záznam byl změněn.\n"
+"Chcete zadat změny?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Uložit záznam"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Zpráva o sbírce"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "Ša&blona zprávy:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "&Generovat"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr "Vyberte šablonu a klikněte na <em>Generovat</em>."
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+"Některé zprávy mohou být v případě velkých sbírek generovány "
+"několik vteřin."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Opravdu chcete smazat tento filtr?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Smazat filtr?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Nový název sbírky:"
+
+#: tellico_kernel.cpp:377
+#, fuzzy
+msgid "Entry 1"
+msgstr "Druh záznamu"
+
+#: tellico_kernel.cpp:378
+#, fuzzy
+msgid "Entry 2"
+msgstr "Druh záznamu"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr ""
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+#, fuzzy
+msgid "Merge Entries"
+msgstr "Smazat záznamy"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr ""
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico nemůže najít výchozí styl pro záznamy."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Nový"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Sbírka"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Nástrojová lišta sbírky"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Robert Krátký"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "kratky@rob.cz"
+
+#: entrymerger.cpp:35
+#, fuzzy
+msgid "Merging entries..."
+msgstr "Aktualizuji záznamy..."
+
+#: entrymerger.cpp:49
+#, fuzzy
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Celkem záznamů: %1"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>...že má-li kniha více než jednoho autora, měli byste jejich jména\n"
+"oddělit středníkem, aby Tellico věděl, že mají být rozdělena a "
+"použita\n"
+"samostatně.</p>\n"
+"<p>Všechna další pole umožňující více hodnot by měla být zadána "
+"stejným\n"
+"způsobem - se středníkem (;) oddělujícím jednotlivé hodnoty.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>...že můžete změnit, která pole budou zobrazována v pohledu na "
+"seznam,\n"
+"kliknutím pravým tlačítkem myši na hlavičku sloupce.\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>...že pomocí Editoru polí můžete přidat, upravit a změnit pole ve "
+"sbírce.\n"
+"Tlačítka se šipkami pod seznamem polí mohou být použita ke změně "
+"umístění\n"
+"pole v seznamu, což ovlivňuje umístění v Editoru záznamů.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>...že pokud chcete filtrovat podle pole se zaškrtávacím políčkem,\n"
+"měla by být použita hodnota \"pravda\". Pokud byste například chtěli, "
+"aby filtr\n"
+"zobrazil pouze vědeckofantastické knížky, které jste nečetli, "
+"zaškrtněte\n"
+"tlačítko <em>Odpovídá všemu, co následuje</em>, nastavte první\n"
+"pravidlo na \"Žánr\" \"obsahuje\" \"Vědeckofantastický\" (bez uvozovek)\n"
+"a druhé pravidlo na \"Přečteno\" \"neobsahuje\" \"pravda\" (bez\n"
+" uvozovek).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>...že pokud je v Rychlém filtru použit nepísmenný znak, bude text\n"
+"interpretován jako regulární výraz.</p>\n"
+"<p>Například knihy pouze od Webera nebo Bujolda zobrazíte\n"
+"zadáním \"weber|bujold\" (bez uvozovek) do pole filtru.</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>...že můžete upravovat více než jeden záznam najednou, když "
+"stisknete\n"
+"klávesu Shift nebo Ctrl a označíte více záznamů.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>...že můžete převést existující sbírku knih na bibliografii, "
+"kterou lze\n"
+"exportovat do formátu Bibtex nebo Bibtexml.</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>...že můžete přidat, upravit nebo smazat řetězcová makra\n"
+"pro bibliografie.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>...že pokud je více než jedno pole formátováno jako název,\n"
+"bude do sbírky přidána další skupina nazvaná \"Lidé\", která "
+"umožní\n"
+"například řadit nebo tisknout autory dohromady.</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>...že můžete změnit vzhled tištěného výstupu úpravou\n"
+"souboru <tt>tellico-printing.xsl</tt>. Tento soubor generuje HTML\n"
+"a CSS v stylesheetu určuje věci jako font, okraje, atd.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>...že můžete importovat s pomocí jakéhokoliv obecného XSL "
+"stylesheetu,\n"
+"jehož výstupem je platný Tellico XML soubor.</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+"<p>...že dvojím kliknutím na záznam otevřete Editor záznamu.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>...že můžete do kteréhokoliv pole Odstavec přidat HTML značky jako "
+"například\n"
+"&lt;b&gt;tučně&lt;/b&gt; nebo &lt;i&gt;kurzíva&lt;/i&gt;.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>...že v Detailním pohledu můžete stisknout písmeno na klávesnici,\n"
+"a skočit tak na záznam začínající tímto písmenem.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Album"
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr "Tato šablona je určena pouze pro hudební sbírky."
+
+#: xslt.cpp:5
+msgid "Total:"
+msgstr "Celkem:"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr "Zdobná"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "Výchozí"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Kompaktní"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Video"
+
+#: xslt.cpp:14 xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr "Tato šablona je určena pouze pro video sbírky."
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Skupinové shrnutí"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Skupinové shrnutí"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Celkový počet polí:"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Celkový počet záznamů:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+msgid "Generated by Tellico"
+msgstr "Generováno programem Tellico"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Rozdílné hodnoty: "
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Seznam obrázků"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Půjčkový pohled"
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Datum zápůjčky"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Poznámka"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Datum vrácení"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Skupinový pohled"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Výpis názvů (vodorovný)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Výpis názvů (svislý)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Sloupcový pohled"
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "Tři sloupce"
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr "Hledat"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr "Britská knihovna"
+
+#: z3950.cpp:6
+msgid "Sudoc (France)"
+msgstr "Sudoc (Francie)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr "BIBSYS (Norsko)"
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr "Italská národní knihovna"
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr "Portugalská národní knihovna"
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr "Polská národní knihovna"
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr "Kanadská národní knihovna"
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr "Sdružený seznam izraelských knihoven"
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr "Australská národní knihovna"
+
+#: z3950.cpp:22
+#, fuzzy
+msgid "National Library of Lithuania"
+msgstr "Kanadská národní knihovna"
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr ""
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr ""
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr "Dark Horse Comics"
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr "Allocine.fr"
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr "Španělské ministerstvo kultury"
+
+#, fuzzy
+#~ msgid "CrossRef"
+#~ msgstr "Křížový odkaz"
+
+#~ msgid "MODS"
+#~ msgstr "MODS"
+
+#~ msgid "RIS"
+#~ msgstr "RIS"
+
+#~ msgid "GCstar"
+#~ msgstr "GCstar"
+
+#~ msgid "AMC"
+#~ msgstr "AMC"
+
+#, fuzzy
+#~ msgid "Griffith"
+#~ msgstr "Dárek"
+
+#, fuzzy
+#~ msgid "Referencer"
+#~ msgstr "Křížový odkaz"
+
+#~ msgid "Comics"
+#~ msgstr "Komiks"
+
+#~ msgid "Stamps"
+#~ msgstr "Známky"
+
+#~ msgid "Coins"
+#~ msgstr "Mince"
+
+#~ msgid "Books"
+#~ msgstr "Knihy"
+
+#~ msgid "Wines"
+#~ msgstr "Vína"
+
+#~ msgid "Videos"
+#~ msgstr "Videa"
+
+#~ msgid "Games"
+#~ msgstr "Hry"
+
+#~ msgid "Cards"
+#~ msgstr "Karty"
+
+#~ msgid "Entries"
+#~ msgstr "Záznamy"
+
+#~ msgid "Albums"
+#~ msgstr "Alba"
+
+#~ msgid ""
+#~ "If checked, all images will be included in the data file, rather than saved "
+#~ "separately in the Tellico data directory. Saving a lot of images in the data "
+#~ "file cause Tellico to run more slowly."
+#~ msgstr ""
+#~ "Je-li zaškrtnuto, budou všechny obrázky vkládány do datového souboru, "
+#~ "místo aby byly ukládány samostatně v datovém adresáři Tellico. "
+#~ "Vložení velkého počtu obrázků do datového souboru může způsobit "
+#~ "zpomalení programu."
+
+#, fuzzy
+#~ msgid "Copac"
+#~ msgstr "Čárka"
diff --git a/po/de.po b/po/de.po
new file mode 100644
index 0000000..e7264ef
--- /dev/null
+++ b/po/de.po
@@ -0,0 +1,5450 @@
+# translation of de.po to German
+# tellico - A book collection manager for KDE3
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+# This file is distributed under the same license as the tellico package.
+#
+#
+# Robby Stephenson <robby@periapsis.org>, 2003.
+# Gerrit M. Albrecht <mail@gerrit-albrecht.de>, 2003, 2004, 2005, 2006.
+# Tobias Gruetzmacher <tobias@portfolio16.de>, 2006.
+# Jens Seidel <jensseidel@users.sf.net>, 2007, 2008.
+#
+# See http://www.mcphilatelics.com/education/stampterms/stampterms.html
+# for terms related to stamps.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: de\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2008-01-25 10:34+0100\n"
+"Last-Translator: Jens Seidel <jensseidel@users.sf.net>\n"
+"Language-Team: german <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Report-Msgid-Bugs-To: \n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr ""
+"<qt>Tellico kann nicht schreibend auf die Server-Pipe in <b>%1</b> "
+"zugreifen.</qt> "
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr "Verbindung zu OpenOffice.org wird aufgebaut ..."
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr "OpenOffice.org-Verbindung"
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+"Tellico konnte keine Verbindung zu OpenOffice.org herstellen.\n"
+"Bitte überprüfen Sie die Einstellungen weiter unten und\n"
+"stellen Sie sicher, dass OpenOffice.org Writer läuft."
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr "Pipe"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr "TCP/IP"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr "Benenne Spalte um"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr "Neuer Name für die Spalte:"
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr "Spalte %1"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr "Benenne Spalte um ..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr "Zeile einfügen"
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr "Zeile entfernen"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr "Zeile nach oben bewegen"
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr "Zeile nach unten bewegen"
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr "Lösche Tabelle"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr "Vorlagen-Vorschau"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Setze"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr "%1:"
+
+# ???
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Mehr"
+
+# ???
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Weniger"
+
+# Das hier klappt irgendwie nicht so richtig, ich sehe die komplette Übersetzung als Button-Text! Oder darf ich da nur einen Wert eintragen?
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Löschen"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Bild auswählen ..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr "Nur den Link speichern"
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr "Speichern eines Links ist nur für neu hinzugefügte Bilder möglich."
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Ändere %1"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Anhängen an Sammlung"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Verschmelze mit Sammlung"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Ersetze Sammlung"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr "Ändere Einträge"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "Füge %1 Feld hinzu"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Ändere %1 Feld "
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Lösche %1 Feld"
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr "Füge Einträge hinzu"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Hinzufügen %1"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Benenne Sammlung um"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Ändere Leihgebühr"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Füge Filter hinzu"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Ändere Filter"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Lösche Filter"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Einträge ausleihen"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Ausleihen %1"
+
+# Einfach mal das L als Kürzel ausgewählt. Testen.
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Lösche Einträge"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Lösche %1"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Felder neu ordnen"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Einträge zurückgeben"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Zurückgeben %1"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Allgemein"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Zustand"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Privat"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Meine Briefmarken"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Titel"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Beschreibung"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Nennwert"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "Land"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Ausgabejahr"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Farbe"
+
+# Laut http://www.mcphilatelics.com/education/stampterms/stampterms.html
+# ist dies ein Katalognummernsystem in den USA. In Deutschland dominiert
+# Michel. Dumm: Die Michel-Nummerierung ist durch Copyright geschützt :-(
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Katalognr."
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr "Ausgezeichnet,Extrem Gut,Sehr Gut,Gut,Durchschnitt,Schlecht"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Bewertung"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Gestempelt"
+
+# Falz (Michel-Katalog) ist eine Art Klebestreifen
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Falz"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Zentrierung"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Gummiert"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Kaufdatum"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Kaufpreis"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Ort"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Verschenkt"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Bild"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Kommentare"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Ausgabe"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Zuordnung"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Meine Comic-Bücher"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Untertitel"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Schreiber"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr "Künstler"
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Serie"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Ausgabe"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Verlag"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Auflage"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Veröffentlichungsjahr"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Seiten"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Sprache"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Gattung"
+
+# XXX: IMHO "Genre"
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Schlüsselwörter"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr ""
+"Ausgezeichnet,Fast Ausgezeichnet,Super Toll,Toll,Sehr "
+"Gut,Gut,Durchschnitt,Schlecht"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Signiert"
+
+# XXX: IMHO "Geschenk"
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Verliehen"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Vorderseite der Hülle"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Meine Münzen"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Typ"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Jahr"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Markierung"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Münzen-Satz"
+
+# soll/darf man das übersetzen?
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr "PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Bewertungs-Dienstleister"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Vorderseite"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Rückseite"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Meine Bücher"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Autor"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Gebundene Ausgabe"
+
+# http://www.answers.com/topic/trade-paperback
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Taschenbuch"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "TPB-Taschenbuch"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "E-Buch"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Zeitung"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Zeitschrift"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Einband"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Copyright-Jahr"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Internationale Standardbuchnummer"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Kongressbibliotheks-Katalognummer"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr "Übersetzer"
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Seriennummer"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Neu"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Gebraucht"
+
+# wo? lesen oder gelesen?
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Gelesen"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Bewertung"
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr "Meine Dateien"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "Name"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+# Buch, Jahrgang?
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Band"
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr "Ordner"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr "Dateityp"
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr "Größe"
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr "Rechte"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr "Besitzer"
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr "Gruppe"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr "Erstellt"
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr "Geändert"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr "Meta-Information"
+
+# Produzent?
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Eigenschaft"
+
+# Buch, Jahrgang?
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Wert"
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr "Icon"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Meine Weine"
+
+# Produzent?
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Produzent"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Benennung"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Mannigfaltigkeit"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Jahrgang"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Rotwein"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Weißwein"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Schaumwein"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Menge"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Trinken zu"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Etikett"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Weitere Personen"
+
+# Fähigkeiten?
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Funktionen"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Meine Videos"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr "Blu-ray"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+msgid "HD DVD"
+msgstr "HD DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Medium"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Produktionsjahr"
+
+# http://de.wikipedia.org/wiki/Freiwillige_Selbstkontrolle_der_Filmwirtschaft
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "FSK 0,FSK 6,FSK 12,FSK 16,FSK 18"
+
+# Ich weiß, es ist nicht 100% korrekt, aber das wird auch nicht zertifiziert,
+# sondern freiwillig in Klassen eingeteilt. Zumindest bei unserer FSK.
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Klassifizierung"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Regionalbereich 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Regionalbereich 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Regionalbereich 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Regionalbereich 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Regionalbereich 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Regionalbereich 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Regionalbereich 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Regionalbereich 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Regionalbereich"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Nationalität"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Format"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Besetzung"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr "Schauspieler/Schauspielerin"
+
+# Buch, Jahrgang?
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr "Rolle"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr ""
+"Eine Tabelle für die Schauspieler zusammen mit den Rollen, welche sie "
+"spielen"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Regisseur"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Komponist"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Studio"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Sprach-Spuren"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Untertitel-Sprachen"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Ton-Spuren"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Laufzeit"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "Die Laufzeit des Videos (in Minuten)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Bildseitenformat"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Breitwand"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Schwarz-Weiß"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Farbmodus"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Director's Cut"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Zusammenfassung der Handlung"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Persönliche Beurteilung"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Hülle"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "Meine Spiele"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr "Xbox 360"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr "PlayStation3"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr "Nintendo Wii"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr "Linux"
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Plattform"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Jahr der Veröffentlichung"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Herausgeber"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Entwickler"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+"Nicht bewertet, Nur für die Eltern, Jugendliche, Kinder, Alle, Kleinkinder, "
+"Kommt noch"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "Einstufung des Spiels"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Vollständig"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Meine Karten"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Spieler"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Team"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Marke"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Karten-Nummer"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Karten-Typ"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Bild der Vorderseite"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Bild der Rückseite"
+
+#: collections/boardgamecollection.cpp:26
+msgid "My Board Games"
+msgstr "Meine Brettspiele"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr "Mechanismus"
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr "Anzahl der Spieler"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Literaturverzeichnis"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Art des Eintrags"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+"Diese Einträge sind Bibtex-spezifisch. Bitte schauen Sie in der "
+"Bibtex-Dokumentation nach."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Bibtex-Schlüssel"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Buch-Titel"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Herausgeber"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organisation"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Adresse"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr "DOI"
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr "Digitaler Objektidentifikator"
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Monat"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Nummer"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Art der Veröffentlichung"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Kapitel"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Querverweis"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Kurzfassung"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Notizen"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Meine Musik"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Album"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "Compact Disc"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Kassette"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Schallplatte"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Künstler"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Herausgeber"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Titel"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr "Länge"
+
+# Noch gucken, wofür man die Wörter benötigt.
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr ""
+"ein,eine,einer,und,in,von,der,die,das,zu,an,nach,mit,als,über,für,ins,aus,a"
+"uf,bis"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "der,die,das"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr.,jr,iii,iv"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,van,der,van der,von"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr "ISBNdb.com"
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 erlaubt kein Suchen für diese Sammlungsart."
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Ergebnisse von %1: %2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "Diese Quelle besitzt keine Optionen."
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "Entrez-Datenbank"
+
+#: fetch/entrezfetcher.cpp:485
+msgid "Institution"
+msgstr "Institution"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Anfrage-Fehler!"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Fehler bei der Verbindungssuche %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Syntaxfehler aufzeichnen"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Verbindungsfehler %1: %2"
+
+# was ist denn das?
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr "SRU-Server"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Kongressbibliothek (USA)"
+
+# R noch frei?
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr "&Rechner: "
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr "Geben Sie den Rechner-Namen des Servers ein."
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Port: "
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Geben Sie die Port-Nummer des Servers ein. Der Vorgabewert ist %1."
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr "Pfad: "
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr "Geben Sie den Pfad zur Datenbank ein, die vom Server benutzt wird."
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr "Format: "
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr "Geben Sie das Ergebnisformat ein, das vom Server benutzt wird."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr "Yahoo! Audio-Suche"
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "Das Umschlagbild konnte nicht geladen werden."
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr "Amazon-Verweis"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (USA)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (GB)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Deutschland)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japan)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (Frankreich)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Kanada)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Amazon.com-Web-Dienste"
+
+# Einfach mal das L als Kürzel genommen. Noch testen.
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "&Land: "
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "Vereinigte Staaten von Amerika"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Großbritannien und Nordirland"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Deutschland"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Japan"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "Frankreich"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Kanada"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon.com stellt Daten von verschiedenen lokalisierten Sites zur "
+"Verfügung. Wählen Sie diejenige, welche Sie als Datenquelle benutzen "
+"möchten."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "B&ildgröße:"
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Kleines Bild"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Mittleres Bild"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Großes Bild"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Kein Bild"
+
+# Ich weiß, Performanz, aber so sieht's besser aus, oder?
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"Das Umschlagbild kann ebenfalls heruntergeladen werden, allerdings können "
+"zu viele große Bilder in der Sammlung die Performance beeinträchtigen."
+
+# Ist der Buchstabe M noch frei?
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "&Mitglieds-ID: "
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+"Die Mitglieds-ID identifiziert die Person, welche auf die Web-Dienste von "
+"Amazon.com zugreift. Sie ist Bestandteil von allen Links zur "
+"Amazon.com-Website."
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr "z39.50-Server"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr "Benutze voreingestellten &Server:"
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "&Datenbank: "
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr "Geben Sie den Datenbank-Namen zur Nutzung durch den Server ein."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "&Zeichensatz:"
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Geben Sie die Zeichensatz-Kodierung für den z39.50-Server ein. Die "
+"wahrscheinlichste Wahl ist MARC-8, aber auch ISO-8859-1 ist gebräuchlich."
+
+#: fetch/z3950fetcher.cpp:550
+msgid "&Format: "
+msgstr "&Format: "
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr "Automatisch erkennen"
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+"Geben Sie das Datenformat ein, dass der z39.50-Server benutzt. Tellico wird "
+"versuchen, dieses automatisch zu erkennen, wenn <i>Automatisch erkennen</i> "
+"ausgewählt ist."
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "&Benutzer: "
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Optional"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Geben Sie den Benutzernamen zur Authentifizierung ein, den die "
+"z39.50-Datenbank benutzen soll. Die meisten Server benötigen keinen."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "Pass&wort:"
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Geben Sie das Authentifizierungs-Passwort für die z39.50-Datenbank ein. Die "
+"meisten Server benötigen keins. Das Passwort wird im Klartext in der "
+"Tellico-Konfigurationsdatei abgelegt."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr "Illustrator"
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Externe Anwendung"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "Art der Sammlung:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+"Setzt die Art der Sammlung für die Daten, die von der externen Anwendung "
+"zurückgegeben werden."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr "&Ergebnis-Typ: "
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr ""
+"Setzt den Ergebnis-Typ für die Daten, die von der externen Anwendung "
+"zurückgegeben werden."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "Anwendungs-&Pfad: "
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+"Setzt den Pfad zur Anwendung, welche gestartet werden und eine gültige "
+"Tellico-Datendatei ausgeben soll."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr ""
+"Wählt die Such-Schlüssel, welche von der Datenquelle unterstützt werden."
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+"Füge alle Argumente welche benötigt werden könnten hinzu. <b>%1</b> wird "
+"durch den Suchbegriff ersetzt."
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr "Argumente"
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+msgid "Update"
+msgstr "Aktualisierung"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+"<p>Geben Sie die Argumente an, die bei der Suche nach verfügbaren "
+"Aktualisierungen für einen Eintrag benutzt werden sollen.</p><p>Das Format "
+"ist dasselbe wie für <i>Abhängige</i> Felder, wo die Feldwerte in Klammern "
+"stehen, wie in <i>%{author}</i>. Mehr Details stehen in der "
+"Dokumentation.</p>"
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Quellen-Optionen"
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr "Verfügbare Felder"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "Internet Film-Datenbank (IMDB)"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Wählen Sie das IMDB-Ergebnis aus"
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+"<qt>Ihre Suche lieferte mehrere Treffer zurück. Bitte wählen Sie einen "
+"weiter unten aus.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Wählen Sie ein Suchergebnis aus.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr "IMDB-Verweis"
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Alternative Titel"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+msgid "IMDB Rating"
+msgstr "IMDB-Bewertung"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Zertifikate"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"Die Internet Film-Datenbank (IMDB) benutzt verschiedene Server. Wählen Sie "
+"einen aus."
+
+# Hoffe das hat auch was mit Theater zu tun ...
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr "&Maximale Besetzung: "
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+"Die Liste der Besetzungs-Mitglieder kann viele Leute enthalten. Setzen Sie "
+"die maximale Anzahl,die die Suche zurückgeben darf."
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr "Umschlagb&ild herunterladen"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr "Internet-Buchhandlung (ibs.it)"
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Person"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr "UPC/EAN"
+
+# XXX: IMHO "Genre"
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Schlüsselwort"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr "arXiv-ID"
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr "Pubmed-ID"
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Direkte Anfrage"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr "Original-Titel"
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr "Verteiler"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr "Episoden"
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr "arXiv.org"
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr "%1 benötigt einen Benutzernamen und Passwort."
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+"CrossRef benötigt ein Benutzerkonto zum Zugriff. Bitte lesen Sie die "
+"allgemeinen Geschäftsbedingungen und <a "
+"href='http://www.crossref.org/requestaccount/'>fordern Sie ein Benutzerkonto "
+"an</a>. Geben Sie Ihre OpenURL-Kontoinformationen unten an."
+
+#: fetch/crossreffetcher.cpp:343
+msgid "&Username: "
+msgstr "&Benutzer: "
+
+#: fetch/crossreffetcher.cpp:348
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+"Ein Benutzername und ein Passwort wird benötigt, um auf den CrossRef-Dienst "
+"zuzugreifen. Das Passwort wird im Klartext in der "
+"Tellico-Konfigurationsdatei abgelegt."
+
+#: fetch/crossreffetcher.cpp:354
+msgid "&Password: "
+msgstr "Pass&wort: "
+
+#: fetch/gcstarpluginfetcher.cpp:190
+msgid "GCstar Plugin"
+msgstr "GCstar-Plugin"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr ""
+"Setzt die Art der Sammlung für die Daten, die vom Plugin zurückgegeben "
+"werden."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr "&Plugin: "
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr ""
+"Wählen Sie das GCstar-Plugin, welches für die Datenquelle verwendet wird."
+
+#: fetch/gcstarpluginfetcher.cpp:420
+msgid "Author: "
+msgstr "Autor: "
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr "Discogs-Audio-Suche"
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr "API-&Schlüssel: "
+
+# FIXME: s/See/see/
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+"Mit Ihrem discogs.com-Benutzerkonto erhalten Sie einen API-Schlüssel für "
+"die Verwendung derer XML-basierten Schnittstelle (siehe "
+"http://www.discogs.com/help/api)."
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr ""
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr "\"Neue Sachen\" abholen"
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr "Version"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr "Downloads"
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr "Veröffentlichungsdatum"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+"Dies ist eine Liste aller zum Download verfügbaren Dinge. Bereits "
+"installierte Dinge haben ein Häkchen-Icon und Dinge, die in einer neuen "
+"Version vorliegen, haben ein Update-Icon."
+
+#: newstuff/dialog.cpp:137
+msgid "The name and license of the selected item"
+msgstr "Der Name und die Lizenz des ausgewählten Elements"
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr "Der Autor des ausgewählten Eintrags"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr "I&nstallieren"
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr "Ausgewählte Vorlage herunterladen und installieren."
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+"Das ausgewählte Script herunterladen und installieren. Einige Scripts "
+"müssen nach der Installation konfiguriert werden."
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr "Eine Beschreibung des ausgewählten Eintrags wird hier angezeigt."
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr "Informationen werden heruntergeladen ..."
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Bereit."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr "Aktualisiere"
+
+#: newstuff/dialog.cpp:413
+msgid "Installing item..."
+msgstr "Installiere Eintrag ..."
+
+#: translators/bibteximporter.cpp:79
+msgid "No valid bibtex entries were found"
+msgstr "Es wurden keine gültigen Bibtex-Einträge gefunden"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "Es wurden keine gültigen Bibtex-Einträge in der Datei gefunden - %1"
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Bibtex-Optionen"
+
+#: translators/bibteximporter.cpp:287
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Verwende Unicode-(UTF-8)-Kodierung"
+
+#: translators/bibteximporter.cpp:288
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Lese die importierte Datei in Unicode (UTF-8)."
+
+#: translators/bibteximporter.cpp:289
+msgid "Use user locale (%1) encoding"
+msgstr "Verwende die Kodierung der Benutzer-Locale (%1)"
+
+#: translators/bibteximporter.cpp:293
+msgid "Read the imported file in the local encoding."
+msgstr "Lese die importierte Datei in der lokalen Kodierung."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "Tellico-ZIP-Datei"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Tellico-Dateien (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Alle Dateien"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>Eine Alexandria-Bibliothek namens <i>%1</i> existiert bereits. Alle "
+"existierenden Bücher in dieser Bibliothek werden überschrieben.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "XML-Parser-Fehler in Zeile %1, Spalte %2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "Die Qt-Fehlermeldung lautet:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Es ist von einer neueren Tellico-Version."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Tellico konvertiert die Datei in ein aktuelleres Datenformat. Es kann zu "
+"einem Informationsverlust kommen, falls eine ältere Tellico-Version benutzt "
+"wird, um die neue Datei einzulesen."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Unbekannt"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "Die Datei ist leer."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "Die Datei enthält keine Sammlungsdaten."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Ungelesene Bücher"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Alte Filme"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "80er Musik"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Favoriten"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Taste Audio-Dateien ab ..."
+
+#: translators/audiofileimporter.cpp:129
+#, fuzzy
+msgid "Bitrate"
+msgstr "Bibtex"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr "Tracks (Disc %1)"
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(Verschiedene)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Audio-Datei-Optionen"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Rekursive Verzeichnissuche"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+"Wenn markiert, werden Verzeichnisse rekursiv nach Audio-Dateien abgesucht."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr "Ort der Datei einb&inden"
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr ""
+"Wenn markiert, werden die Datei-Namen für jede Spur zu den Einträgen "
+"hinzugefügt."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:353
+#, fuzzy
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr ""
+"Wenn markiert, werden die Datei-Namen für jede Spur zu den Einträgen "
+"hinzugefügt."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|CSV-Dateien (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "CSV-Optionen"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Füge Feldtitel als Spaltenüberschrift ein"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr "Wenn markiert, wird eine Kopfzeile mit den Feldtiteln eingefügt."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Feldtrennzeichen"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"Zusätzlich zum Komma können andere Zeichen als Trennzeichen, welche jeden "
+"Wert in der Datei begrenzen, genutzt werden."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Komma"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Benutze ein Komma als Trennzeichen."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Semikolon"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Benutze ein Semikolon als Trennzeichen."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Tabulator"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Benutze einen Tabulator als Trennzeichen."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Anderes"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Benutze ein benutzerdefiniertes Zeichen als Trennzeichen."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr ""
+"Ein benutzerdefiniertes Zeichen, wie beispielsweise ein Doppelpunkt, kann "
+"als Trennzeichen benutzt werden."
+
+#: translators/filelistingimporter.cpp:63
+msgid "Scanning files..."
+msgstr "Lese Dateien ein ..."
+
+#: translators/filelistingimporter.cpp:191
+msgid "File Listing Options"
+msgstr "Dateilisten-Optionen"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr "Rekursive Verzeichnissuche"
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+"Wenn markiert, werden Verzeichnisse rekursiv nach allen Dateien abgesucht."
+
+#: translators/filelistingimporter.cpp:198
+msgid "Generate file previews"
+msgstr "Erzeuge Datei-Voransichten"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+"Wenn markiert, werden Voransichten des Dateiinhalts erzeugt, welche das "
+"Anzeigen des Verzeichnisses verlangsamen können."
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "ONIX-Archiv"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.zip|Zip-Dateien (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "ONIX-Archiv-Optionen"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Füge Bilder in das Archiv ein"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Wenn markiert, werden die Bilder des Dokuments zum gezippten ONIX-Archiv "
+"hinzugefügt."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr ""
+"<qt>Tellico konnte nicht auf das CD-Laufwerk zugreifen - <i>%1</i>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+msgid "Select CDDB Entry"
+msgstr "Wähle CDDB-Eintrag"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr "Wählen Sie einen CDDB-Eintrag aus:"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>Es wurden keine zur CD passende Aufzeichnungen gefunden.</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr ""
+"<qt>Tellico war nicht in der Lage, das Nachschlagen der CD "
+"abzuschließen.</qt> "
+
+#: translators/freedbimporter.cpp:470
+msgid "Various"
+msgstr "Verschiedene"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Audio-CD-Optionen"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Lese Daten vom CD-Laufwerk"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Wählen Sie das CD-Laufwerk aus oder geben Sie die Position ein."
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Nur die Dateien aus dem CDDB-Cache lesen"
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+"Lese Daten rekursiv von allen CDDB-Cache-Dateien, welche in den "
+"Vorgabe-Cache-Verzeichnissen enthalten sind."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr "GCfilms"
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.gcf|GCfilms-Datendateien (*.gcf)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.gcs|GCstar-Datendateien (*.gcs)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "XSLT-Optionen"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "XSLT-Datei:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr ""
+"Wählen Sie die XSLT-Datei aus, welche zum Transformieren der Tellico "
+"XML-Daten benutzt werden soll."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Alexandria-Optionen"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr "Bib&liothek:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "Bibtexml"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Bibtexml-Dateien (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|XML-Dateien (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Tellico-XML-Optionen"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Füge Bilder in das XML-Dokument ein"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Wenn markiert, werden die Bilder des Dokuments in den XML-Datenstrom in Form "
+"von base64-kodierten Daten eingefügt."
+
+#: translators/importer.h:100
+msgid "Loading data..."
+msgstr "Lade Daten ..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr "Lade %1 ..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "Bibtex"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Bibtex-Dateien (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Expandiere Zeichenketten-Makros"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Wenn markiert, werden Zeichenketten-Makros erweitert und es werden keine "
+"@string{}-Einträge geschrieben."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Benutze URL-Paket"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr ""
+"Wenn markiert, werden alle URL-Felder in eine \\url-Deklaration gepackt."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Überspringe Einträge mit leeren Zitat-Schlüsseln"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr ""
+"Wenn markiert, werden Einträge ohne einen Bibtex-Zitat-Schlüssel "
+"übersprungen."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Bibtex-Zitatstil:"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Geschweifte Klammern"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Anführungszeichen"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"<qt>Der Zitierstil, welcher beim Export nach Bibtex benutzt wird. Alle "
+"Feld-Werte werden entweder durch geschweifte Klammern oder mit "
+"Anführungszeichen markiert.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Wählen Sie die Art der zu importierenden Sammlung aus."
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr "&Erste Zeile enthält Feld-Titel"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr ""
+"Wenn markiert, werden die Daten der ersten Zeile als Feld-Titel angesehen."
+
+#: translators/csvimporter.cpp:248
+msgid "&Comma"
+msgstr "&Komma"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr "&Semikolon"
+
+#: translators/csvimporter.cpp:259
+msgid "Ta&b"
+msgstr "Ta&bulator"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr "&Anderes:"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "Die Tabelle zeigt die ersten fünf Zeilen der CSV-Datei."
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt>Verbinden Sie jede Spalte mit einem Feld in der Sammlung, indem Sie eine "
+"Spalte auswählen, das Feld auswählen und dann die <i>Feld "
+"zuweisen</i>-Schaltfläche anklicken.</qt>"
+
+#: translators/csvimporter.cpp:298
+msgid "Co&lumn:"
+msgstr "Spa&lte:"
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr "&Datenfeld in dieser Spalte:"
+
+#: translators/csvimporter.cpp:315
+msgid "&Assign Field"
+msgstr "Feld &zuweisen"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+"Mindestens einer Spalte muss ein Feld zugeordnet werden. Nur zugewiesene "
+"Spalten werden importiert."
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Neues Feld"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|Pilot-Datenbank-Dateien (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Zeige Spalten"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "PilotDB-Optionen"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Setze das PDA-Backup-Flag für die Datenbank"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>Die Datei ist keine gültige GCstar-Datei</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Tellico bemerkte einen Fehler bei einer XSLT-Transformation."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "Um die Datei zu importieren, wird eine gültige XSLT-Datei benötigt."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|XSL-Dateien (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|HTML-Dateien (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Personen"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(gruppiert nach %1)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "HTML-Optionen"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Drucke Feld-Kopfzeilen"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr "Wenn markiert, werden die Feld-Namen als Tabellenkopf gedruckt."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Gruppiere die Einträge"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr ""
+"Wenn markiert, werden die Einträge anhand des markierten Feldes gruppiert."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Exportiere individuelle Eintragsdateien"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr ""
+"Wenn markiert, werden für jeden Eintrag individuelle Dateien erstellt."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico konnte keine Metadaten aus der PDF-Datei lesen."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+"Tellico kann Informationen über Einträge mit einer DOI von CrossRef.org "
+"herunterladen. Sie müssen jedoch ein CrossRef-Benutzerkonto anlegen und "
+"eine neue Datenquelle mit Ihren Konto-Informationen hinzufügen."
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Datenquellen-Eigenschaften"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "Name der &Quelle: "
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr ""
+"Der Name identifiziert die Datenquelle und sollte einmalig und informativ "
+"sein."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "Art der Quelle: "
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr "Tellico unterstützt mehrere, verschiedene Datenquellen."
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr ""
+"Aktualisierungen von der Datenquelle sollen Benutzerdaten überschreiben"
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Wenn markiert, werden aktualisierende Einträge bestehende Informationen "
+"überschreiben."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Irgendein Feld"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "enthält"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "enthält nicht"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "ist gleich"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "ist ungleich"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "passt auf regexp"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "passt nicht auf regexp"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Bearbeite ..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Erweiterter Filter"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Filterkriterien"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Trifft auf a&lle der folgenden zu"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Trifft auf &eines der folgenden zu"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Filtername:"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "&Speichere Filter"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Einfacher Text"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Absatz"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Auswahl"
+
+# Markierbox?
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Checkbox"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Tabelle"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Abhängig"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Datum"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr "Aktualisiere %1 ..."
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr "Aktualisiere Einträge ..."
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr "Akt&ualisiere Einträge"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr "Aktualisiere <b>%1</b> ..."
+
+# hab keine ahnung, in welchem zusammenhang das benutzt wird.
+# erstmal was unverfängliches hier eingeben. passt vielleicht auch ;-)
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr "Passendes auswählen"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+"<qt><b>%1</b> gab mehrere Ergebnisse zurück, welche auf <b>%2</b>, den "
+"aktuellen Eintrag in der Sammlung, passen könnten.</qt>"
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Expandiere alle Gruppen"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Kollabiere alle Gruppen"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Filtere nach Gruppe"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (nach Anzahl sortiert)"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Gruppe"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Import-Optionen"
+
+#: importdialog.cpp:62
+msgid "&Replace current collection"
+msgstr "E&rsetze die aktuelle Sammlung"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr "Ersetze die aktuelle Sammlung mit dem Inhalt der importierten Datei."
+
+#: importdialog.cpp:65
+msgid "A&ppend to current collection"
+msgstr "&Hinzufügen zur aktuellen Sammlung"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Fügt den Inhalt der importierten Datei zur aktuellen Sammlung hinzu. Das "
+"ist nur möglich, wenn die Sammlungs-Typen zusammenpassen."
+
+#: importdialog.cpp:69
+msgid "&Merge with current collection"
+msgstr "&Mit der aktuellen Sammlung verschmelzen"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Vermengt den Inhalt der importierten Datei mit der aktuellen Sammlung. Das "
+"ist nur möglich, wenn die Sammlungs-Typen übereinstimmen. Die Datensätze "
+"müssen exakt passen, um eingefügt werden zu können."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Importiere"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|RIS-Dateien (*.ris)"
+
+#: importdialog.cpp:277
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.amc|AMC-Datendateien (*.amc)"
+
+#: importdialog.cpp:281
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdf|PDF-Dateien (*.pdf)"
+
+#: importdialog.cpp:285
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.reflib|Referencer-Dateien (*.reflib)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico kann die Datei nicht laden - %1."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico kann die Datei nicht speichern - %1."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico kann die Datei nicht hochladen - %1."
+
+# Satzzeichen hinzugefügt. Hoffe das wird nicht nochmal
+# automatisch angehangen.
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Nur Sammlungen mit den selben Eintragsarten wie der der aktuellen Sammlung "
+"können hinzugefügt werden. Es werden keine Änderungen an der aktuellen "
+"Sammlung vorgenommen."
+
+# Satzzeichen hinzugefügt. Hoffe das wird nicht nochmal
+# automatisch angehangen.
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Nur Sammlungen mit den selben Eintragsarten wie der der aktuellen Sammlung "
+"können verschmolzen werden. Es werden keine Änderungen an der aktuellen "
+"Sammlung vorgenommen."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico kann kein Bild aus der Datei einladen - %1."
+
+#: entryiconview.cpp:287
+msgid "&Sort By"
+msgstr "&Sortieren nach"
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Leihdialog"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "Die folgenden Elemente werden gerade ausgecheckt:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "Das folgende Element ist verliehen:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "&Verliehen an:"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Geben Sie den Namen der Person ein, welche sich die Gegenstände von Ihnen "
+"ausborgt. Mit dem Anklicken der Schaltfläche können Sie aus Ihrem "
+"Adressbuch auswählen."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "&Leihdatum:"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+"Das Ausleihdatum ist das Datum, an welchem Sie die Gegenstände verliehen "
+"haben. Als Vorgabe wird das aktuelle Datum benutzt."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "&Fälligkeitsdatum:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"Das Fälligkeitsdatum ist das Datum, zu welchem die Gegenstände "
+"zurückerwartet werden. Das Fälligkeitsdatum ist keine Pflichtangabe, es "
+"sei denn, Sie wollen den Leihvorgang zu Ihrem aktiven Kalender hinzufügen."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Notiz:"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "Sie können auch Notizen betreffend den Leihvorgang anlegen."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "&Füge eine Erinnerung zum aktiven Kalender hinzu."
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"<qt>Markieren der Box fügt einen <em>Zu Erledigen</em>-Eintrag zu Ihrem "
+"aktiven Kalender hinzu. Dieser kann mit dem KOrganizer angesehen werden. "
+"Diese Box ist nur aktiv, wenn Sie ein Fälligkeitsdatum gesetzt haben."
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Erstelle eine neue Sammlung"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Neue &Bücher-Sammlung"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Erstelle eine neue Bücher-Sammlung"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Neues L&iteraturverzeichnis"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Erstelle ein neues Bibtex-Literaturverzeichnis"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Neue &Comic-Bücher-Sammlung"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Erstelle eine neue Comic-Bücher-Sammlung"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Neue &Video-Sammlung"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Erstelle eine neue Video-Sammlung"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Neue &Musik-Sammlung"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Erstelle eine neue Musik-Sammlung"
+
+# Münzsammlung ist zwar populärer, aber die Begriffe enden hier alle
+# auf -Sammlung, also schreibe ich es mit Bindestrich.
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Neue Mün&z-Sammlung"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Erstelle eine neue Münz-Sammlung"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Neue &Briefmarken-Sammlung"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Erstelle eine neue Briefmarken-Sammlung"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Neue K&arten-Sammlung"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Erstelle eine neue Sammelkarten-Sammlung"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Neue &Wein-Sammlung"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Erstelle eine neue Wein-Sammlung"
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Neue &Spiele-Sammlung"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Erstelle eine neue Spiele-Sammlung"
+
+#: mainwindow.cpp:272
+msgid "New Boa&rd Game Collection"
+msgstr "Neue B&rettspiele-Sammlung"
+
+#: mainwindow.cpp:274
+msgid "Create a new board game collection"
+msgstr "Erstelle eine neue Brettspiele-Sammlung"
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr "Neue &Dateiliste"
+
+#: mainwindow.cpp:282
+msgid "Create a new file catalog"
+msgstr "Erstelle eine neuen Datei-Katalog"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Neue ben&utzerdefinierte Sammlung"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Erstelle eine neue benutzerdefinierte Sammlung"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Öffne ein existierendes Dokument"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Öffne eine kürzlich benutzte Datei"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Speichere das Dokument"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Speichere das Dokument in einer anderen Datei ..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Drucke den Inhalt des Dokuments ..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Beende die Anwendung"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Importiere die Daten einer Sammlung aus anderen Formaten"
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Importiere Tellico-Daten ..."
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Importiere eine andere Tellico-Datei"
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "Importiere CSV-Daten ..."
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Importiere eine CSV-Datei"
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "Importiere MODS-Daten ..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Importiere eine MODS-Datei"
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Importiere Alexandria-Daten ..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Importiere Daten von der Alexandria-Bücherverwaltung"
+
+#: mainwindow.cpp:352
+msgid "Import Delicious Library Data..."
+msgstr "Importiere Delicious-Bibliotheks-Daten ..."
+
+#: mainwindow.cpp:353
+msgid "Import data from Delicious Library"
+msgstr "Importiere Daten von Delicious-Bibliothek"
+
+#: mainwindow.cpp:359
+msgid "Import Referencer Data..."
+msgstr "Importiere Referencer-Daten ..."
+
+#: mainwindow.cpp:360
+msgid "Import data from Referencer"
+msgstr "Importiere Daten von Referencer"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Importiere Bibtex-Daten ..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Importiere Literaturverzeichnis aus einer Bibtex-Datei"
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Importiere Bibtexml-Daten ..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Importiere ein Literaturverzeichnis aus einer Bibtexml-Datei"
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "Importiere RIS-Daten ..."
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Importiere eine RIS-Referenz-Datei"
+
+#: mainwindow.cpp:387
+msgid "Import PDF File..."
+msgstr "Importiere PDF-Datei ..."
+
+#: mainwindow.cpp:388
+msgid "Import a PDF file"
+msgstr "Importiere eine PDF-Datei"
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Importiere Audio-Datei-Meta-Daten ..."
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Importiere Meta-Daten von Audio-Dateien"
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Importiere Audio-CD-Daten ..."
+
+#: mainwindow.cpp:405
+msgid "Import audio CD information"
+msgstr "Importiere Audio-CD-Informationen"
+
+#: mainwindow.cpp:414
+msgid "Import GCstar Data..."
+msgstr "Importiere GCstar-Daten ..."
+
+#: mainwindow.cpp:415
+msgid "Import a GCstar data file"
+msgstr "Importiere eine GCstar-Datendatei"
+
+#: mainwindow.cpp:421
+msgid "Import Griffith Data..."
+msgstr "Importiere Griffith-Daten ..."
+
+#: mainwindow.cpp:422
+msgid "Import a Griffith database"
+msgstr "Importiere eine Griffith-Datenbank"
+
+#: mainwindow.cpp:428
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Importiere \"Ant Movie Catalog\"-Daten ..."
+
+#: mainwindow.cpp:429
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Importiere eine \"Ant Movie Catalog\"-Datendatei"
+
+#: mainwindow.cpp:435
+msgid "Import File Listing..."
+msgstr "Importiere Dateiliste ..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr "Importiere Informationen über Dateien in einem Verzeichnis"
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "Importiere XSL-Transformation ..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Importiere mit Hilfe einer XSL-Transformation"
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Exportiere"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Exportiere die Sammlungsdaten in andere Formate"
+
+#: mainwindow.cpp:461
+msgid "Export to XML..."
+msgstr "Exportiere nach XML ..."
+
+#: mainwindow.cpp:462
+msgid "Export to a Tellico XML file"
+msgstr "Exportiere in eine Tellico-XML-Datei"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Exportiere nach Zip"
+
+#: mainwindow.cpp:469
+msgid "Export to a Tellico Zip file"
+msgstr "Exportiere in eine Tellico-Zip-Datei"
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "Exportiere nach HTML ..."
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Exportiere in eine HTML-Datei"
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "Exportiere nach CSV ..."
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Exportiere in eine CSV-Datei"
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "Exportiere nach PilotDB ..."
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Exportiere in eine PilotDB-Datenbank"
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Exportiere nach Alexandria ..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Exportiere in eine Alexandria-Bibliothek"
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Exportiere nach Bibtex ..."
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Exportiere in eine Bibtex-Datei"
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Exportiere nach Bibtexml ..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Exportiere in eine Bibtexml-Datei"
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "Exportiere nach ONIX ..."
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Exportiere in eine ONIX-Datei"
+
+#: mainwindow.cpp:524
+msgid "Export to GCfilms..."
+msgstr "Exportiere nach GCfilms ..."
+
+#: mainwindow.cpp:525
+msgid "Export to a GCfilms data file"
+msgstr "Exportiere in eine GCfilms-Datendatei"
+
+#: mainwindow.cpp:531
+msgid "Export to GCstar..."
+msgstr "Exportiere nach GCstar ..."
+
+#: mainwindow.cpp:532
+msgid "Export to a GCstar data file"
+msgstr "Exportiere in eine GCstar-Datendatei"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "Exportiere XSL-Transformation ..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Exportiere unter Verwendung einer XSL-Transformation"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Schneide den markierten Text aus und lege ihn in der Zwischenablage ab"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Kopiere den markierten Text in die Zwischenablage"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Füge den Inhalt der Zwischenablage ein"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Wähle alle Datensätze der Sammlung aus"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Wähle keine Datensätze der Sammlung aus"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Internet-Suche ..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Durchsuche das Internet ..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "Erweiterter &Filter ..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Filtere die Sammlung"
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&Neuer Eintrag ..."
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Erstelle einen neuen Eintrag"
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "B&earbeite Eintrag ..."
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Bearbeite die ausgewählten Einträge"
+
+#: controller.cpp:621 mainwindow.cpp:577
+msgid "D&uplicate Entry"
+msgstr "D&upliziere Eintrag"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Kopiere die ausgewählten Einträge"
+
+# Einfach mal das L als Kürzel ausgewählt. Testen.
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "&Lösche Eintrag"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Lösche die ausgewählten Einträge"
+
+#: mainwindow.cpp:585
+msgid "&Merge Entries"
+msgstr "Einträge &zusammenfügen"
+
+#: mainwindow.cpp:588
+msgid "Merge the selected entries"
+msgstr "Die ausgewählten Einträge zusammenführen"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "Erzeu&ge Berichte ..."
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Erzeuge Sammlungsberichte"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "&Ausleihen ..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Die ausgewählten Einträge ausleihen"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "&Zurückgeben"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Die ausgewählten Einträge zurückgeben"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "Benenne Sammlung &um ..."
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Benenne Sammlung um"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "Daten&felder der Sammlung ..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Sammlungsfelder modifizieren"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "Konvertiere in &Literaturverzeichnis"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Konvertiere eine Bücher-Sammlung in ein Literaturverzeichnis"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "Zeichenketten-&Makros ..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Bearbeite die Bibtex Zeichenketten-Makros"
+
+#: mainwindow.cpp:626
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Ko&piere Bibtex in die Zwischenablage"
+
+#: mainwindow.cpp:627
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Kopiere Bibtex-Zitate in die Zwischenablage"
+
+#: mainwindow.cpp:632
+msgid "Cite Entry in &LyX"
+msgstr "Zitiere Eintrag in &LyX"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Zitiere die ausgewählten Einträge in LyX"
+
+#: mainwindow.cpp:638
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Zi&tiere Eintrag in OpenOffice.org"
+
+#: mainwindow.cpp:639
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Zitiere die ausgewählten Einträge in OpenOffice.org"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, no-c-format
+msgid "&Update Entry"
+msgstr "&Aktualisiere Eintrag"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr "Alle Quellen"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr "Aktualisiere Eintragsdaten von allen verfügbaren Quellen."
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Zeige Gru&ppen-Ansicht"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Aktiviere/Deaktiviere die Gruppen-Ansicht"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Verberge Gru&ppen-Ansicht"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Zeige Eintrags-&Editor"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Aktiviere/Deaktiviere den Editor"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "Verberge Eintrags-&Editor"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Zeige Eintrags-&Ansicht"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Aktiviere/Deaktiviere die Eintrags-Ansicht"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "Verberge Eintrags-&Ansicht"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Ändere Gruppierung"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "&Gruppen-Auswahl"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Ändere die Gruppierung der Sammlung"
+
+# oder "Filtere"?
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Filter"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Lösche Filter"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Filtere hier ..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Gruppen"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt>Die <i>Gruppen-Ansicht</i> sortiert die Einträge in Gruppen basierend "
+"auf einem ausgewählten Feld.</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt>Die <i>Spalten-Ansicht</i> zeigt den Wert von mehreren Feldern für "
+"jeden Eintrag.</qt>"
+
+#: mainwindow.cpp:831
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Willkommen zur Tellico-Sammlungsverwaltung"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+"<h3>Tellico ist ein Werkzeug für die Verwaltung von Büchern, Videos, Musik "
+"und was immer sonst Sie katalogisieren möchten.</h3><h3>Neue Einträge "
+"können zu Ihrer Sammlung durch <a href=\"tc:///coll_new_entry\">Manuelle "
+"Eingabe</a> oder <a href=\"tc:///edit_search_internet\">Herunterladen der "
+"Daten</a> von verschiedenen Quellen im Internet hinzugefügt werden.</h3>"
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Erstelle ein neues Dokument ..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Öffne Datei ..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Öffne Datei"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Speichere Datei ..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+"<qt><p>Sie speichern eine Datei mit vielen Grafiken, was Tellico wesentlich "
+"langsamer werden lässt. Möchten Sie die Grafiken separat in Tellicos "
+"Datenverzeichnis speichern, um die Leistung zu verbessern?</p><p>Ihre Wahl "
+"kann jederzeit im Konfigurationsdialog geändert werden.</p></qt>"
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr "Speichere Grafiken separat"
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr "Speichere Grafiken in der Datei"
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Speichere Datei unter einem neuen Dateinamen ..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Drucke ..."
+
+# ausgeben evtl. in drucken ändern. Erst mal schauen, wo der
+# Text gebraucht wird
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"Die Sammlung wird gerade gefiltert, um eine begrenzte Untermenge der "
+"Einträge anzuzeigen. Nur die sichtbaren Einträge werden ausgegeben. Weiter?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Bearbeite Dokument ..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Beende ..."
+
+# Kürzel testen
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Einträge insgesamt: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 ausgefiltert; %2 ausgewählt)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 ausgefiltert)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 ausgewählt)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Drucke %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Seite %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Bitte überprüfen Sie Ihre Installation."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Importiere Daten ..."
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Importiere Datei"
+
+#: mainwindow.cpp:1864
+msgid "Import Directory"
+msgstr "Importiere Verzeichnis"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Exportiere Daten ..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Exportiere als"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Zeichenketten-Makros"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Makro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Zeichenkette"
+
+#: mainwindow.cpp:1999
+msgid "Creating citations..."
+msgstr "Erstelle Zitate ..."
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Filter"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt>Die <i>Filter-Ansicht</i> zeigt die Einträge, welche auf bestimmte "
+"Filter-Regeln zutreffen.</qt>"
+
+# XXX: IMHO "Geschenk"
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Verliehenes"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt>Die <i>Verleih-Ansicht</i> zeigt eine Liste aller Leute, die etwas aus "
+"der Sammlung ausgeliehen haben.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr "Aktualisiere Eintrags-Daten von %1"
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+"Tellico kann nur eine Datei dieses Typs pro Durchgang importieren. Nur %1 "
+"wird importiert."
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico kann das Bild nicht laden - %1."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+"Eine Datei mit dem Namen \"%1\" existiert bereits. Soll sie wirklich "
+"überschrieben werden?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Datei überschreiben?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Überschreiben"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Filter (Nach Anzahl sortiert)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Wollen Sie diesen Eintrag wirklich löschen?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Lösche Eintrag"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Wollen Sie diese Einträge wirklich löschen?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Lösche mehrere Einträge"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "B&earbeite Einträge ..."
+
+#: controller.cpp:627
+msgid "D&uplicate Entries"
+msgstr "D&upliziere Einträge"
+
+#: controller.cpp:628
+msgid "&Update Entries"
+msgstr "Akt&ualisiere Einträge"
+
+# Einfach mal das L als Kürzel ausgewählt. Testen.
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "&Lösche Einträge"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+"Die folgenden Gegenstände sind bereits verliehen worden, aber Tellico "
+"unterstützt es zurzeit noch nicht, einen Gegenstand mehrfach zu verleihen. "
+"Sie werden von der Liste der zu verleihenden Gegenstände entfernt."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Standard Kalender"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"Tellico unterstützt zurzeit nur lokale Kalender-Ressourcen. Der aktive "
+"Kalender ist entfernt positioniert, so dass Ihre Leihen nicht hinzugefügt "
+"werden können."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Aktiver Kalender"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 ist zur Rückgabe fällig am \"%2\""
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(Leer)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - ein Sammlungs-Manager für KDE"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Die letzte offene Datei nicht erneut öffnen"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Importiere <Dateiname> als eine Bibtex-Datei"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Importiere <Dateiname> als eine MODS-Datei"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Importiere <Dateiname> als eine RIS-Datei"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Zu öffnende Datei"
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr "Datenquellen-Scripte"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Icons"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Autor der btparse-Bibliothek"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr "Quelltext-Beispiele und allgemeine Inspiration"
+
+#: main.cpp:50
+msgid "Author of libcsv library"
+msgstr "Autor der libcsv-Bibliothek"
+
+#: main.cpp:52
+msgid "Author of rtf2html library"
+msgstr "Autor der rtf2html-Bibliothek"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Sammlungsfelder"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Aktuelle Felder"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "&Neu"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Füge ein neues Feld zur Sammlung hinzu"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "&Löschen"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Entferne ein Feld aus der Sammlung"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Bewege das Feld in der Liste nach oben. Die Reihenfolge der Liste ist für "
+"das Aussehen des Datensatz-Editors wichtig."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Bewege das Feld in der Liste nach unten. Die Reihenfolge der Liste ist für "
+"das Aussehen des Datensatz-Editors wichtig."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Feld-Eigenschaften"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "&Titel:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "Der Titel des Feldes:"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "T&yp:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "Der Feldtyp bestimmt, welche Werte benutzt werden können. "
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "<i>Einfacher Text</i> wird für die meisten Felder benutzt. "
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "<i>Absatz</i> ist für größere Textblöcke. "
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Auswahl</i> limitiert ein Feld auf bestimmte Werte. "
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "Das <i>Ankreuzfeld</i> ist für einfache Ja/Nein-Werte. "
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr ""
+"Eine <i>Nummer</i> bedeutet, dass das Feld einen numerischen Wert "
+"beinhaltet. "
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+"<i>URL</i> ist für Felder, welche auf eine URL oder auf andere Dateien "
+"verweisen. "
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr ""
+"Eine <i>Tabelle</i>n kann eine oder mehrere Spalten mit Werten aufnehmen. "
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "Ein <i>Bild</i>-Feld enthält eine Grafik. "
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+"Ein <i>Datum</i>-Feld kann für Werte bestehend aus Tag, Monat und Jahr "
+"benutzt werden. "
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+"Ein <i>Bewertungs</i>-Feld benutzt Sternchen, um eine Wertungsnummer "
+"anzuzeigen. "
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"Ein <i>Abhängig</i>-Feld hängt von den Werten anderer Felder ab und wird "
+"anhand der Feld-Beschreibung formatiert. "
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"<i>Nur Lesen</i> ist für interne Werte gedacht und ist wahrscheinlich beim "
+"Im- und Export nützlich. "
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "Kate&gorie:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr "Die Feld-Kategorie bestimmt, wo das Feld im Editor platziert wird."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "Beschre&ibung:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"Die Beschreibung ist eine nützliche Erinnerungshilfe dafür, welche "
+"Information in dem Feld enthalten ist. Für <i>Abhängig</i>e Felder ist die "
+"Beschreibung eine Formatier-Zeichenkette wie z.B. \"%{year} %{title}\", bei "
+"welcher die angegebenen Felder in der Zeichenkette ersetzt werden."
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr "Stan&dardwert:"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr "<qt>Ein Standardwert für neue Einträge gesetzt werden.</qt>"
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr "Er&laubte Werte:"
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>Für <i>Auswahl</i>-artige Felder sind das die einzig erlaubten Werte. "
+"Sie sind in einer Auswahl-Box angeordnet. Die möglichen Werte müssen durch "
+"ein Semikolon getrennt werden. Zum Beispiel: \"Hund; Katze; Maus\"</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "Erweiterte &Eigenschaften:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "&Setze ..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"Erweiterte Feld-Eigenschaften werden benutzt, um Dinge wie das "
+"korrespondierende Bibtex-Feld anzugeben."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Formatieroptionen"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Keine Formatierung"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+"Diese Option verhindert, dass das Feld automatisch formatiert oder groß "
+"geschrieben wird."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Erlaube nur die automatische Großschreibung"
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+"Diese Option erlaubt es, dass das Feld groß geschrieben, aber nicht "
+"speziell formatiert wird."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Als Titel formatieren"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Diese Option schreibt das Feld groß und formatiert es als einen Titel, aber "
+"nur, wenn diese Optionen global gesetzt sind."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Als Namen formatieren"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Diese Option schreibt das Feld groß und formatiert es als einen Namen, aber "
+"nur, wenn diese Optionen global gesetzt sind."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Feld-Optionen"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Mit automatischer Vervollständigung"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Wenn markiert, wird die KDE-eigene automatische Textvervollständigung in "
+"der Textbearbeitungsbox dieses Feldes aktiviert."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Mehrere Einträge erlauben"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Wenn markiert, durchsucht Tellico die Werte in dem Feld nach mehreren, durch "
+"ein Semikolon getrennten Werten."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Erlaube Gruppierung"
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Wenn markiert, kann dieses Feld benutzt werden, um die Einträge in der "
+"Gruppenansicht zu gruppieren."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr ""
+"Die Eigenschaften der ausgewählten Felder auf die voreingestellten Werte "
+"zurücksetzen."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Ändere Felder"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Das Entfernen von erlaubten Werten des <i>%1</i>-Feldes, welches zurzeit "
+"in der Sammlung existiert, könnte Datenfehler erzeugen. Möchten Sie Ihre "
+"veränderten Werte erhalten oder Abbrechen und zu den aktuellen Werten "
+"zurückkehren?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Veränderte Werte übernehmen"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Feld-Eigenschaften rückgängig machen"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Wollen Sie wirklich die Eigenschaften des <em>%1</em>-Feldes auf ihre "
+"Vorgabewerte zurücksetzen?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Rückgängig machen"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Erweiterte Feld-Eigenschaften"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr ""
+"Ein Feld mit diesem Titel existiert bereits. Bitte geben Sie einen anderen "
+"Titel ein."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr ""
+"<qt>Die Kategorie darf nicht leer sein. Bitte geben Sie eine Kategorie "
+"ein.</qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>Ein Feld darf sich nicht in der gleichen Kategorie wie ein "
+"<em>Absatz</em>-, ein <em>Tabelle</em>n- oder ein <em>Bild</em>-Feld "
+"befinden. Bitte geben Sie eine andere Kategorie ein.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"Der Titel eines Feldes darf nicht mit dem Namen einer existierenden "
+"Kategorie übereinstimmen. Bitte geben Sie einen anderen Titel ein."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+"Der Bereich für ein Bewertungs-Feld muss zwischen 1 und 10 liegen und die "
+"niedrige Grenze muss kleiner sein als die höhere Grenze. Bitte geben Sie "
+"andere Werte für die niedrige und die hohe Grenze vor."
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "Tabellen sind auf maximal 10 Spalten begrenzt."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Die aktuelle Datei wurde verändert.\n"
+"Soll sie gespeichert werden?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Ungesicherte Änderungen"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Ausleiher auswählen"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Einrichten von Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Allgemeine Optionen"
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr "&Öffne Datei beim Programmstart erneut"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Wenn markiert, wird die zuletzt geöffnete Datei beim nächsten "
+"Programmstart erneut geöffnet."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "&Zeige den \"Tipp des Tages\" beim Starten"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr ""
+"Wenn markiert, wird der \"Tipp des Tages\" beim Starten des Programms "
+"gezeigt."
+
+#: configdialog.cpp:213
+msgid "Image Storage Options"
+msgstr "Bildspeicheroptionen"
+
+#: configdialog.cpp:214
+msgid "Store images in data file"
+msgstr "Bilder in Datendatei speichern"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr "Bilder im gemeinsam genutzten Anwendungsverzeichnis speichern"
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr "Bilder in einem Verzeichnis relativ zur Datendatei speichern"
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+"Bilder können in der Datendatei gespeichert werden, was Tellico "
+"verlangsamen kann, in das Tellico-Anwendungsverzeichnis und in ein "
+"Verzeichnis an der selben Stelle wie die Datendatei."
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Formatieroptionen"
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr "Automatische Großschreibung von &Titeln und Namen"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Wenn markiert, werden die Anfangsbuchstaben von Titeln und Namen automatisch "
+"groß geschrieben."
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr "&Formatiere Titel und Namen automatisch"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr "Wenn markiert, werden Titel und Namen automatisch formatiert."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr "&Keine automatische Großschreibung:"
+
+#: configdialog.cpp:243
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Eine Liste von Wörtern, welche nicht automatisch großgeschrieben "
+"werden sollen. Mehrere Werte müssen durch ein Semikolon voneinander "
+"getrennt werden.</qt>"
+
+#: configdialog.cpp:249
+msgid "Artic&les:"
+msgstr "Artike&l:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>Eine Liste von Wörtern, welche als Artikel betrachtet werden sollen, "
+"wenn diese als erstes Wort in einem Titel vorkommen. Mehrere Werte müssen "
+"mit einem Semikolon voneinander getrennt werden.</qt>"
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr "&Nachsilben von Personen:"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Eine Liste mit Endungen, welche in Personen-Namen benutzt werden "
+"können. Mehrere Werte müssen durch ein Semikolon voneinander getrennt "
+"werden.</qt>"
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr "&Vorsilben des Nachnamens:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Eine Liste von Vorsilben, welche in Familiennamen benutzt werden "
+"können. Mehrere Werte müssen durch ein Semikolon voneinander getrennt "
+"werden.</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Drucke"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Druckoptionen"
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr "&Formatiere Titel und Namen"
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr "&Drucke Feld-Kopfzeilen"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Gruppierungsoptionen"
+
+#: configdialog.cpp:313
+msgid "&Group the entries"
+msgstr "&Gruppiere die Einträge"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Bild-Optionen"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr "Maximale Bild-&Breite:"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Die maximale Breite von Bildern im Ausdruck. Das Breite/Höhe-Verhältnis "
+"wird beibehalten."
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr "Maximale Bild-&Höhe:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Die maximale Höhe von Bildern im Ausdruck. Das Breite/Höhe-Verhältnis "
+"wird beibehalten."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Vorlagen"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Vorlage-Optionen"
+
+#: configdialog.cpp:369
+msgid "Template:"
+msgstr "Vorlage:"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+"Wählen Sie eine Vorlage, die für den aktuellen Typ von Sammlung benutzt "
+"werden soll. Nicht alle Vorlagen benutzen die Schriftart- und "
+"Farbeinstellungen."
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr "&Vorschau ..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr "Zeige eine Vorschau der Vorlage"
+
+#: configdialog.cpp:398
+msgid "Font Options"
+msgstr "Schriftartoptionen"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr "Schriftart:"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr ""
+"Diese Schriftart wird an die Vorlage übergeben, die in der Eintragsansicht "
+"benutzt wird."
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr "Größe:"
+
+#: configdialog.cpp:425
+msgid "Color Options"
+msgstr "Farboptionen"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr "Hintergrundfarbe:"
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr ""
+"Diese Farbe wird an die Vorlage übergeben, die in der Eintragsansicht "
+"benutzt wird."
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr "Textfarbe:"
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr "Hervorhebungsfarbe:"
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr "Hervorhebungstextfarbe:"
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr "Vorlagen verwalten"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr "Installieren ..."
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr "Klicken Sie hier, um eine neue Vorlage direkt zu installieren."
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr "Herunterladen ..."
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr ""
+"Klicken Sie hier, um zusätzliche Vorlagen aus dem Internet herunterzuladen."
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr "Löschen ..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr ""
+"Klicken Sie hier, um installierte Vorlagen auszuwählen und zu entfernen."
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Datenquellen"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Datenquellen-Optionen"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Quelle"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr "&Hoch"
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+"Die Reihenfolge der Datenquellen bestimmt die Reihenfolge, die Tellico "
+"benutzt, um Einträge automatisch zu aktualisieren."
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr "&Runter"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "&Neu ..."
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr "Klicken Sie hier, um eine neue Datenquelle hinzuzufügen."
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Ändern ..."
+
+#: configdialog.cpp:533
+msgid "Click to modify the selected data source."
+msgstr "Klicken Sie hier, um die ausgewählte Datenquelle zu ändern."
+
+#: configdialog.cpp:536
+msgid "Click to delete the selected data source."
+msgstr "Klicken Sie hier, um die ausgewählte Datenquelle zu löschen."
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr ""
+"Klicken Sie hier, um zusätzliche Datenquellen aus dem Internet "
+"herunterzuladen."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr "*.tar.gz *.tgz|Vorlagen-Paket (*.tar.gz)"
+
+#: configdialog.cpp:1049
+msgid "Delete Template"
+msgstr "Lösche Vorlage"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr "Wählen Sie die zu löschende Vorlage aus:"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "Ausleiher"
+
+# Markierbox?
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Rückgabe"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Ändere Leihe ..."
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "Ausleiher (nach Anzahl sortiert)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "Meine Sammlung"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Bücher-Sammlung"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Comic-Bücher-Sammlung"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Video-Sammlung"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Musik-Sammlung"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Münzen-Sammlung"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Briefmarken-Sammlung"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Wein-Sammlung"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Karten-Sammlung"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Spiele-Sammlung"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr "Dateiliste"
+
+#: collectionfactory.cpp:135
+msgid "Board Game Collection"
+msgstr "Brettspiele-Sammlung"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Benutzerdefinierte Sammlung"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+"<qt>Die <i>Datensatz-Ansicht</i> zeigt eine formatierte Ansicht des Inhalts "
+"des Datensatzes.</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt>Die <i>Piktogramm-Ansicht</i> zeigt jeden Datensatz der Sammlung oder "
+"Gruppe mit einem Symbol an. Dieses kann auch ein Bild des Datensatzes "
+"sein.</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Exportoptionen"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Formatierung"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Alle Felder formatieren"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Wenn markiert, werden die Werte der Felder in Abhängigkeit vom Feld-Typ "
+"automatisch formatiert."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Exportiere nur die ausgewählten Einträge"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr "Wenn markiert, werden nur die ausgewählten Einträge exportiert."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Kodierung"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Kodiere in Unicode (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Kodiere die exportierte Datei in Unicode (UTF-8)."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Kodiere in Benutzer-Locale (%1)"
+
+#: exportdialog.cpp:72
+msgid "Encode the exported file in the local encoding."
+msgstr "Kodiere die exportierte Datei in die lokale Kodierung."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "&Suchen"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "&Stopp"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Internet-Suche"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Such-Anfrage"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr "Such&en:"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+"Geben Sie einen Suchwert ein. Eine Suche nach einer ISBN muss die komplette "
+"ISBN enthalten."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Wählen Sie die Art der Suche"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Klicken Sie, um die Suche zu beginnen oder zu beenden"
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr "&Mehrfache ISBN/UPC-Suche"
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr ""
+"Markieren Sie dieses Feld, um nach mehreren ISBN- oder UPC-Werten zu suchen."
+
+#: fetchdialog.cpp:138
+msgid "Edit List..."
+msgstr "Bearbeite Liste ..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+"Klicken Sie hier, um einen Text-Editor zu öffnen, um mehrere ISBN-Werte zu "
+"bearbeiten oder einzugeben."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "Such-Quelle:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Wählen Sie die zu durchsuchende Datenbank aus"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"Gefundene Ergebnisse werden in dieser Liste angezeigt. Auswählen eines "
+"solchen holt den kompletten Datensatz ab und zeigt ihn in der unteren "
+"Ansicht an."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"Ein Datensatz kann hier angezeigt werden, bevor er zur aktuellen Sammlung "
+"hinzugefügt wird, indem er in der obigen Liste markiert wird."
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "Eintr&ag hinzufügen"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Fügt den ausgewählten Eintrag zur aktuellen Sammlung hinzu"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr "Weitere Ergebnisse holen"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr "Hole mehr Ergebnisse von der aktuellen Datenquelle"
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Lösche alle Suchfelder und Ergebnisse"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Abbrechen der Suche ..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Suchen ..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "Die Suche lieferte keine Treffer."
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+"Die Suche lieferte einen Treffer.\n"
+"Die Suche lieferte %n Treffer."
+
+#: fetchdialog.cpp:412
+msgid "No results were found for the following ISBN values:"
+msgstr "Für die folgenden ISBN-Werte konnten keine Einträge gefunden werden:"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Hole %1 ..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr ""
+"Für Ihre aktuelle Art der Sammlung sind keine Internet-Quellen verfügbar."
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr "Bearbeite ISBN/UPC-Werte"
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Geben Sie die ISBN- oder UPC-Werte (einen pro Zeile) ein.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "&Lade aus Datei ..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Lade die Liste aus einer Text-Datei.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>Eine ISBN-Suche kann maximal 100 ISBN-Nummern enthalten. Nur die ersten "
+"100 Werte Ihrer Liste werden benutzt.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Bearbeite Eintrag"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Neuer Eintrag"
+
+# Einfach mal das P als Kürzel ausgewählt. Testen.
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "S&peichere Eintrag"
+
+#: entryeditdialog.cpp:77
+msgid "Go to the previous entry in the collection"
+msgstr "Gehe zum vorherigen Eintrag der Sammlung"
+
+#: entryeditdialog.cpp:82
+msgid "Go to the next entry in the collection"
+msgstr "Gehe zum nächsten Eintrag der Sammlung"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Wollen Sie diese Einträge wirklich ändern?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Mehrere Einträge ändern"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr ""
+"Ein Wert wird für die folgenden Felder benötigt. Möchten Sie fortfahren?"
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Bearbeite Einträge"
+
+# Kürzel testen
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "S&peichere Einträge"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"Der aktuelle Eintrag wurde verändert.\n"
+"Sollen die Änderungen eingefügt werden?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Speichere Eintrag"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Sammlungsbericht"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "Be&richtsvorlage:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "&Generieren"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr ""
+"Wählen Sie eine Berichtsvorlage aus und klicken Sie <em>Generieren</em>."
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+"Bei großen Sammlungen kann es mehrere Sekunden dauern, bis der Bericht "
+"erzeugt wurde."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Wollen Sie diesen Filter wirklich löschen?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Lösche Filter?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Neuer Name für die Sammlung:"
+
+#: tellico_kernel.cpp:377
+msgid "Entry 1"
+msgstr "Eintrag 1"
+
+#: tellico_kernel.cpp:378
+msgid "Entry 2"
+msgstr "Eintrag 2"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+"In Konflikt stehende Werte für %1 wurden beim Zusammenfügen von Einträgen "
+"gefunden."
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr "Bitte wählen Sie den Wert aus, der behalten werden soll."
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+msgid "Merge Entries"
+msgstr "Einträge zusammenfügen"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr "Eintrag aus %1 auswählen"
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico kann den Stylesheet für den Vorgabe-Datensatz nicht finden."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Neu"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Sammlung"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Sammlungs-Werkzeugleiste"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Jens Seidel"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "jensseidel@users.sf.net"
+
+#: entrymerger.cpp:35
+msgid "Merging entries..."
+msgstr "Füge Einträge zusammen ..."
+
+# Kürzel testen
+#: entrymerger.cpp:49
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Zusammengefügte/gescannte Einträge: %1/%2"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>... dass Sie, falls ein Buch mehr als einen Autor hat, deren Namen\n"
+"mit einem Semikolon trennen sollten, so dass Tellico weiß,\n"
+"wie sie getrennt und separat benutzt werden können?</p>\n"
+"<p>Jedes andere Feld, welches mehrere Werte erlaubt, sollte\n"
+"in der gleichen Art und Weise mit einem die Werte trennenden\n"
+"Semikolon (;) eingegeben werden.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>... dass Sie die Felder, welche in der Listenansicht angezeigt\n"
+"werden sollen, durch Anklicken der Spalten-Titel mit der rechten\n"
+"Maustaste ändern können?</p>\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>... dass Sie die Felder der Sammlung im Feld-Editor bearbeiten\n"
+"können? Die Pfeil-Schaltflächen unter der Feldliste können dazu\n"
+"benutzt werden, die Position der Felder in der Liste zu verändern.\n"
+"Das beeinflusst die Positionierung im Datensatz-Editor.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>... dass, falls Sie nach einer Checkbox filtern wollen, der Wert\n"
+"\"true\" benutzt werden sollte? Falls Sie beispielsweise nur die\n"
+"noch ungelesenen Science-Fiction-Bücher anzeigen möchten,\n"
+"markieren Sie die <em>Trifft auf alle der folgenden zu</em>-Schaltfläche,\n"
+"stellen für die erste Regel Folgendes ein: \"Gattung\" \"enthält\"\n"
+"\"Science Fiction\" (ohne Anführungszeichen) und die zweite Regel\n"
+"lautet: \"Gelesen\" \"enthält nicht\" \"true\" (ohne "
+"Anführungszeichen).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>... dass, wenn ein Nicht-Textzeichen im Schnell-Filter benutzt wird,\n"
+"der Text als ein regulärer Ausdruck interpretiert wird?</p>\n"
+"<p>Um zum Beispiel nur Bücher anzuzeigen, welche von Weber\n"
+"oder Bujold geschrieben wurden, tippen Sie \"weber|bujold\"\n"
+"(ohne Anführungszeichen) in das Filter-Eingabefeld.</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>... dass Sie mehr als einen Datensatz auf einmal bearbeiten können,\n"
+"indem Sie die Shift- oder Strg-Taste gedrückt halten und mehrere Einträge "
+"auswählen?</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>... dass Sie eine existierende Bücher-Sammlung in ein\n"
+"Literaturverzeichnis konvertieren können, welches anschließend\n"
+"ins Bibtex- oder Bibtexml-Format exportiert werden kann?</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>... dass Sie Zeichenketten-Makros zu Literaturverzeichnissen "
+"hinzufügen,\n"
+"bearbeiten und löschen können?</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>... dass, wenn mehr als ein Feld als ein Name formatiert wird, eine\n"
+"zusätzliche Gruppe mit dem Namen \"Leute\" zur Sammlung hinzugefügt\n"
+"wird, welche es beispielsweise erlaubt, Autoren und Verfasser\n"
+"zusammen zu sortieren und auszudrucken?</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>... dass Sie das Aussehen der gedruckten Ausgabe verändern können,\n"
+"indem Sie die Datei <tt>tellico-printing.xsl</tt> anpassen? Die Datei\n"
+"erzeugt HTML und die CSS-Anweisungen im Stylesheet sind für Dinge\n"
+"wie Schriftart und Ränder usw. verantwortlich.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>... dass Sie mit einem beliebigen XSL-Stylesheet, welches eine gültige\n"
+"Tellico XML-Datei ausgibt, importieren können?</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+"<p>... dass ein Doppelklick auf einen Eintrag den Eintrags-Editor "
+"öffnet?</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>... dass Sie zu Formatierzwecken HTML-Tags zu jedem Absatz-Feld "
+"hinzufügen können? Zum Beispiel:\n"
+"&lt;b&gt;fett&lt;/b&gt; oder &lt;i&gt;kursiv&lt;/i&gt;.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>... dass Sie in der Detail-Ansicht einen Buchstaben auf der\n"
+"Tastatur drücken können, um zum nächsten Eintrag zu springen,\n"
+"der mit diesem Buchstaben beginnt?</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+"<p>... dass Abhängig-Felder mehrere separate Felder in einem einzelnen "
+"Feld\n"
+"kombinieren können? Wählen Sie einfach den Typ Abhängig und eine "
+"Beschreibung\n"
+"ähnlich zu \"Wert: %{Feld1}%{Feld2}\" wobei %{...} durch den "
+"entsprechenden\n"
+"Feldwert ersetzt wird. Dies ist sinnvoll zum Sammeln von mehreren Werten in\n"
+"einem einzelnen Feld, z.B. für bessere Gruppierung und zum Zusammenfassen\n"
+"von Feldern verschiedener Typen unter gleichzeitiger Berücksichtigung\n"
+"korrekter Sortierung. Eine Anwendung ist zum Beispiel ein Nummern-Feld\n"
+"gefolgt von einem Textunterfeld mit Einträgen wie 3b, 14a.</p>\n"
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Album"
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr "Diese Vorlage ist nur für Musik-Sammlungen gedacht."
+
+#: xslt.cpp:5
+msgid "Total:"
+msgstr "Gesamt:"
+
+# wo wird das benutzt?
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr "Extravagant"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "Standard"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Kompakt"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Video"
+
+#: xslt.cpp:14 xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr "Diese Vorlage ist nur für Video-Sammlungen gedacht."
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Gruppen-Zusammenfassung"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Gruppen-Zusammenfassung"
+
+# Kürzel testen
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Gesamte Anzahl von Feldern:"
+
+# Kürzel testen
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Gesamte Anzahl von Einträgen:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+msgid "Generated by Tellico"
+msgstr "Erzeugt von Tellico"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Verschiedene Werte:"
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Bilderliste"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Ausleih-Ansicht"
+
+# XXX: IMHO "Geschenk"
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Leihdatum"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Notiz"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Fälligkeitsdatum"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Gruppen-Ansicht"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Titelliste (Horizontal)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Titelliste (Vertikal)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Spalten-Ansicht"
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "Dreispaltig"
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr "Suchen"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr "Nationalbibliothek Großbritannien"
+
+#: z3950.cpp:6
+msgid "Sudoc (France)"
+msgstr "Sudoc (Frankreich)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr "BIBSYS (Norwegen)"
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr "Italienische Nationalbibliothek"
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr "Portugiesische Nationalbibliothek"
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr "Nationalbibliothek von Polen"
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr "Nationalbibliothek von Kanada"
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr "Israel Union List"
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr "Nationalbibliothek von Australien"
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr "Nationalbibliothek von Litauen"
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr "Copac (Großbritannien und Irland)"
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr ""
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr "Dark-Horse-Comics"
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr "Allocine.fr"
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr "Spanisches Kultusministerium"
+
+#~ msgid "CrossRef"
+#~ msgstr "CrossRef"
+
+#~ msgid "Citebase"
+#~ msgstr "Citebase"
+
+#~ msgid "Bibsonomy"
+#~ msgstr "Bibsonomy"
+
+#~ msgid "MODS"
+#~ msgstr "MODS"
+
+#~ msgid "RIS"
+#~ msgstr "RIS"
+
+#~ msgid "GCstar"
+#~ msgstr "GCstar"
+
+#~ msgid "AMC"
+#~ msgstr "AMC"
+
+#~ msgid "Griffith"
+#~ msgstr "Griffith"
+
+#~ msgid "Referencer"
+#~ msgstr "Referencer"
+
+#~ msgid "Comics"
+#~ msgstr "Comics"
+
+#~ msgid "Stamps"
+#~ msgstr "Briefmarken"
+
+#~ msgid "Coins"
+#~ msgstr "Münzen"
+
+#~ msgid "Books"
+#~ msgstr "Bücher"
+
+#~ msgid "Wines"
+#~ msgstr "Weine"
+
+#~ msgid "Videos"
+#~ msgstr "Videos"
+
+#~ msgid "Games"
+#~ msgstr "Spiele"
+
+#~ msgid "Cards"
+#~ msgstr "Karten"
+
+#~ msgid "Entries"
+#~ msgstr "Einträge"
+
+#~ msgid "Albums"
+#~ msgstr "Alben"
+
+#~ msgid ""
+#~ "If checked, all images will be included in the data file, rather than saved "
+#~ "separately in the Tellico data directory. Saving a lot of images in the data "
+#~ "file cause Tellico to run more slowly."
+#~ msgstr ""
+#~ "Wenn markiert, werden alle Grafiken in die Datei eingefügt und nicht im "
+#~ "separaten Tellico-Datenverzeichnis gespeichert. Das Speichern einer großen "
+#~ "Menge von Bildern in der Datei kann die Ausführung von Tellico verlangsamen."
diff --git a/po/ee.po b/po/ee.po
new file mode 100644
index 0000000..310f2dc
--- /dev/null
+++ b/po/ee.po
@@ -0,0 +1,6000 @@
+# translation of ee.po to Estonian
+# This file is distributed under the same license as the tellico package.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER.
+# Toomas Nigola,25,+3727416388,+3725296049,+3727500970 <toomas.nigola@eelk.ee>, 2003, 2004.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ee\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2004-02-13 16:58+0200\n"
+"Last-Translator: Toomas Nigola <toomas.nigola@eelk.ee>\n"
+"Language-Team: Estonian <et@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Report-Msgid-Bugs-To: \n"
+"<toomas.nigola@eelk.ee>\n"
+"X-Generator: KBabel 1.0.2\n"
+
+#: cite/lyxpipe.cpp:50
+#, fuzzy
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "Tellico-l ei õnnestu kirjutada faili '%1'."
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr ""
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr ""
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+
+#: cite/openoffice.cpp:191
+#, fuzzy
+msgid "Pipe"
+msgstr "Inimesed"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:181
+#, fuzzy
+msgid "Rename Column"
+msgstr "Kogu nime muutmine"
+
+#: gui/tablefieldwidget.cpp:181
+#, fuzzy
+msgid "New column name:"
+msgstr "Uue kogu nimi"
+
+#: gui/tablefieldwidget.cpp:206
+#, fuzzy, c-format
+msgid "Column %1"
+msgstr "Tulp:"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+#, fuzzy
+msgid "Rename Column..."
+msgstr "Kogu nime muutmine"
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:295
+#, fuzzy
+msgid "Clear Table"
+msgstr "Kustutada väli?"
+
+#: gui/previewdialog.cpp:27
+#, fuzzy
+msgid "Template Preview"
+msgstr "Valikute importimine"
+
+#: gui/stringmapdialog.cpp:57
+#, fuzzy
+msgid "&Set"
+msgstr "Sea"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr ""
+
+#: gui/kwidgetlister.cpp:58
+#, fuzzy
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "rohkem vidinaid"
+
+#: gui/kwidgetlister.cpp:62
+#, fuzzy
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "vähem vidinaid"
+
+#: gui/kwidgetlister.cpp:69
+#, fuzzy
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "puhasta vidinad"
+
+#: gui/imagewidget.cpp:57
+#, fuzzy
+msgid "Select Image..."
+msgstr "XSLT fail valimine"
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr ""
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr ""
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, fuzzy, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Välja kustutamine"
+
+#: commands/collectioncommand.cpp:110
+#, fuzzy
+msgid "Append Collection"
+msgstr "Kogu nime muutmine"
+
+#: commands/collectioncommand.cpp:112
+#, fuzzy
+msgid "Merge Collection"
+msgstr "Muusikakogu"
+
+#: commands/collectioncommand.cpp:114
+#, fuzzy
+msgid "Replace Collection"
+msgstr "Kogu nime muutmine"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+#, fuzzy
+msgid "Modify Entries"
+msgstr "Kirje kustutamine"
+
+#: commands/fieldcommand.cpp:104
+#, fuzzy
+msgid "Add %1 Field"
+msgstr "Suvaline väli"
+
+#: commands/fieldcommand.cpp:106
+#, fuzzy
+msgid "Modify %1 Field"
+msgstr "Kiirfilter"
+
+#: commands/fieldcommand.cpp:108
+#, fuzzy
+msgid "Delete %1 Field"
+msgstr "Kustutada väli?"
+
+#: commands/addentries.cpp:50
+#, fuzzy
+msgid "Add Entries"
+msgstr "Kirje kustutamine"
+
+#: commands/addentries.cpp:51
+#, fuzzy, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Välja kustutamine"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Kogu nime muutmine"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+#, fuzzy
+msgid "Modify Loan"
+msgstr "Raamatu kirje muutmine"
+
+#: commands/filtercommand.cpp:98
+#, fuzzy
+msgid "Add Filter"
+msgstr "Erifilter"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+#, fuzzy
+msgid "Modify Filter"
+msgstr "Kiirfilter"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+#, fuzzy
+msgid "Delete Filter"
+msgstr "Kustutada väli?"
+
+#: commands/addloans.cpp:108
+#, fuzzy
+msgid "Check-out Items"
+msgstr "Kustutada valitud kirjed?"
+
+#: commands/addloans.cpp:109
+#, fuzzy, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Välja kustutamine"
+
+#: commands/removeentries.cpp:48
+#, fuzzy
+msgid "Delete Entries"
+msgstr "Välja kustutamine"
+
+#: commands/removeentries.cpp:49
+#, fuzzy, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Välja kustutamine"
+
+#: commands/reorderfields.cpp:54
+#, fuzzy
+msgid "Reorder Fields"
+msgstr "Käesolevad väljad"
+
+#: commands/removeloans.cpp:79
+#, fuzzy
+msgid "Check-in Entries"
+msgstr "Märkeruut"
+
+#: commands/removeloans.cpp:80
+#, fuzzy, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Välja kustutamine"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Üldine"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Seisukord"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Isiklik"
+
+#: collections/stampcollection.cpp:27
+#, fuzzy
+msgid "My Stamps"
+msgstr "Minu Videod"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Pealkiri"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+#, fuzzy
+msgid "Description"
+msgstr "Kirjeldus:"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+#, fuzzy
+msgid "Denomination"
+msgstr "Kirjeldus:"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+#, fuzzy
+msgid "Country"
+msgstr "Kirje tüüp"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr ""
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Värviline"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr ""
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr ""
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+#, fuzzy
+msgid "Grade"
+msgstr "Žanr"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr ""
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+#, fuzzy
+msgid "Hinged"
+msgstr "Pühendusega"
+
+#: collections/stampcollection.cpp:95
+#, fuzzy
+msgid "Centering"
+msgstr "String"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Ostmise aeg"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Ostuhind"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+#, fuzzy
+msgid "Location"
+msgstr "BCKollektsioon"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Kingitus"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+#, fuzzy
+msgid "Image"
+msgstr "Lehekülgede arv"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Märkused"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Kirjastamine"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Klassifitseerimine"
+
+#: collections/comicbookcollection.cpp:28
+#, fuzzy
+msgid "My Comic Books"
+msgstr "Minu raamatud"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Alapealkiri"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Autor"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Seeriad"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Kirjastaja"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Väljaanne"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Väljaandmisaasta"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Lehekülgede arv"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Keel"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Žanr"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Märksõnad"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr ""
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Pühendusega"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Laenatud"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+#, fuzzy
+msgid "Front Cover"
+msgstr "Helilooja"
+
+#: collections/coincollection.cpp:26
+#, fuzzy
+msgid "My Coins"
+msgstr "Minu Laulud"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+#, fuzzy
+msgid "Type"
+msgstr "Tüüp:"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Aasta"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr ""
+
+#: collections/coincollection.cpp:73
+#, fuzzy
+msgid "Coin Set"
+msgstr "sisaldab"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr ""
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr ""
+
+#: collections/coincollection.cpp:122
+#, fuzzy
+msgid "Obverse"
+msgstr "Üle kirjutamine"
+
+#: collections/coincollection.cpp:125
+#, fuzzy
+msgid "Reverse"
+msgstr "Tagasimuutmine"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Minu raamatud"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Autor"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Kõvakaaneline"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Pehmeköiteline"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Trade Paperpack"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "E-raamat"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Ajakiri"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Žurnaal"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Köide"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Valmimisaasta"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN nr"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "International Standard Book Number"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN nr"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Library of Congress Control Number"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr ""
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Seeria nr"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Uus"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Kasutatud"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Loetud"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Hinnang"
+
+#: collections/filecatalog.cpp:25
+#, fuzzy
+msgid "My Files"
+msgstr "Minu Videod"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+#, fuzzy
+msgid "Name"
+msgstr "Number"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Köide"
+
+#: collections/filecatalog.cpp:55
+#, fuzzy
+msgid "Folder"
+msgstr "Kirje kustutamine"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr ""
+
+#: collections/filecatalog.cpp:65
+#, fuzzy
+msgid "Size"
+msgstr "Pühendusega"
+
+#: collections/filecatalog.cpp:69
+#, fuzzy
+msgid "Permissions"
+msgstr "Isiklik"
+
+#: collections/filecatalog.cpp:74
+#, fuzzy
+msgid "Owner"
+msgstr "Muu"
+
+#: collections/filecatalog.cpp:79
+#, fuzzy
+msgid "Group"
+msgstr "Grupeerimise alus:"
+
+#: collections/filecatalog.cpp:85
+#, fuzzy
+msgid "Created"
+msgstr "CD"
+
+#: collections/filecatalog.cpp:89
+#, fuzzy
+msgid "Modified"
+msgstr "Kiirfilter"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+#, fuzzy
+msgid "Property"
+msgstr "Produtsent"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+#, fuzzy
+msgid "Value"
+msgstr "Köide"
+
+#: collections/filecatalog.cpp:99
+#, fuzzy
+msgid "Icon"
+msgstr "sisaldab"
+
+#: collections/winecollection.cpp:26
+#, fuzzy
+msgid "My Wines"
+msgstr "Minu Videod"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Produtsent"
+
+#: collections/winecollection.cpp:49
+#, fuzzy
+msgid "Appellation"
+msgstr "Suurus"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr ""
+
+#: collections/winecollection.cpp:61
+#, fuzzy
+msgid "Vintage"
+msgstr "Pühendusega"
+
+#: collections/winecollection.cpp:67
+#, fuzzy
+msgid "Red Wine"
+msgstr "Minu Videod"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr ""
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr ""
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr ""
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr ""
+
+#: collections/winecollection.cpp:111
+#, fuzzy
+msgid "Label Image"
+msgstr "Pealkiri"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Teised inimesed"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Omadused"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Minu Videod"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr ""
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+#, fuzzy
+msgid "HD DVD"
+msgstr "DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Meedia"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Väljalaskeaasta"
+
+#: collections/videocollection.cpp:60
+#, fuzzy
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "G (USA),PG (USA),PG-13 (USA),R (USA)"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Sertifitseerimine"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "1. regioon"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "2. regioon"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "3. regioon"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "4. regioon"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "5. regioon"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "6. regioon"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "7. regioon"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "8. regioon"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Regioon"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Rahvus"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Vorming"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Osatäitjad"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr ""
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+#, fuzzy
+msgid "Role"
+msgstr "Köide"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr "Tabel osatäitjate nimede ning nendepoolt mängitud rollidega"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Režissöör"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Helilooja"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Stuudio"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Keeled"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Subtiitrite keeled"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Audiorajad"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Kestvus"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "Video kestvus (minutites)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Suurus"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Täisekraan"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Mustvalge"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Värviline"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+#, fuzzy
+msgid "Director's Cut"
+msgstr "Režissöör"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr ""
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Isiklik hinnang"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+#, fuzzy
+msgid "Cover"
+msgstr "Helilooja"
+
+#: collections/gamecollection.cpp:26
+#, fuzzy
+msgid "My Games"
+msgstr "Minu Videod"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr ""
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+#, fuzzy
+msgid "Nintendo Wii"
+msgstr "Regioon"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+#, fuzzy
+msgid "GameCube"
+msgstr "Number"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr ""
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr ""
+
+#: collections/gamecollection.cpp:47
+#, fuzzy
+msgid "Game Boy Color"
+msgstr "Kogu nime muutmine"
+
+#: collections/gamecollection.cpp:47
+#, fuzzy
+msgid "Game Boy"
+msgstr "Number"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr ""
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr ""
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr ""
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr ""
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Kirjastaja"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr ""
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+
+#: collections/gamecollection.cpp:82
+#, fuzzy
+msgid "ESRB Rating"
+msgstr "Hinnang"
+
+#: collections/gamecollection.cpp:95
+#, fuzzy
+msgid "Completed"
+msgstr "CD"
+
+#: collections/cardcollection.cpp:26
+#, fuzzy
+msgid "My Cards"
+msgstr "Osatäitjad"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr ""
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr ""
+
+#: collections/cardcollection.cpp:55
+#, fuzzy
+msgid "Brand"
+msgstr "Žanr"
+
+#: collections/cardcollection.cpp:62
+#, fuzzy
+msgid "Card Number"
+msgstr "Number"
+
+#: collections/cardcollection.cpp:77
+#, fuzzy
+msgid "Card Type"
+msgstr "Kirje tüüp"
+
+#: collections/cardcollection.cpp:109
+#, fuzzy
+msgid "Front Image"
+msgstr "Lehekülgede arv"
+
+#: collections/cardcollection.cpp:112
+#, fuzzy
+msgid "Back Image"
+msgstr "Lehekülgede arv"
+
+#: collections/boardgamecollection.cpp:26
+#, fuzzy
+msgid "My Board Games"
+msgstr "Minu Videod"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:72
+#, fuzzy
+msgid "Number of Players"
+msgstr "Kirjete sal&vestamine"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Bibliograafia"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Kirje tüüp"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Bibtex võti"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Raamatu pealkiri"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Redaktor"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organisatsioon"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Kuu"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Number"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Väljaandmise viis"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Peatükk"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Ristviide"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Märkused"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Minu muusika"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Album"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "CD"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Kassett"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Vinüülplaat"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Esitaja"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Pealkiri"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Rajad"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr ""
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "see"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr.,jr,iii,iv"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,van,der,van der,von"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr ""
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr ""
+
+#: fetch/entrezfetcher.cpp:485
+#, fuzzy
+msgid "Institution"
+msgstr "Seisukord"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr ""
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr ""
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr ""
+
+#: fetch/z3950connection.cpp:345
+#, fuzzy
+msgid "Connection error %1: %2"
+msgstr "Kollektsiooni tööriistariba"
+
+#: fetch/srufetcher.cpp:72
+#, fuzzy
+msgid "SRU Server"
+msgstr "Tagasimuutmine"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+#, fuzzy
+msgid "Library of Congress (US)"
+msgstr "Library of Congress Control Number"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+#, fuzzy
+msgid "Hos&t: "
+msgstr "Märkused"
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr ""
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+#, fuzzy
+msgid "&Port: "
+msgstr "Märkused"
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr ""
+
+#: fetch/srufetcher.cpp:450
+#, fuzzy
+msgid "Path: "
+msgstr "Märkused"
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr ""
+
+#: fetch/srufetcher.cpp:460
+#, fuzzy
+msgid "Format: "
+msgstr "Vorming"
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr ""
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:855
+#, fuzzy
+msgid "France"
+msgstr "Rajad"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:866
+#, fuzzy
+msgid "&Image size: "
+msgstr "Režissöör"
+
+#: fetch/amazonfetcher.cpp:869
+#, fuzzy
+msgid "Small Image"
+msgstr "Pealkiri"
+
+#: fetch/amazonfetcher.cpp:870
+#, fuzzy
+msgid "Medium Image"
+msgstr "Meedia"
+
+#: fetch/amazonfetcher.cpp:871
+#, fuzzy
+msgid "Large Image"
+msgstr "Pealkiri"
+
+#: fetch/amazonfetcher.cpp:872
+#, fuzzy
+msgid "No Image"
+msgstr "Lehekülgede arv"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+#, fuzzy
+msgid "z39.50 Server"
+msgstr "Tagasimuutmine"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:550
+#, fuzzy
+msgid "&Format: "
+msgstr "Vorming"
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+#, fuzzy
+msgid "Optional"
+msgstr "CSV valikud"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:82
+#, fuzzy
+msgid "External Application"
+msgstr "Rakendusest lahkumine"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "Kogu tüüp:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:370
+#, fuzzy
+msgid "Application &path: "
+msgstr "Suurus"
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+#, fuzzy
+msgid "Update"
+msgstr "Kirje kustutamine"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+
+#: fetch/configwidget.cpp:29
+#, fuzzy
+msgid "Source Options"
+msgstr "CSV valikud"
+
+#: fetch/configwidget.cpp:40
+#, fuzzy
+msgid "Available Fields"
+msgstr "Saadavalolevad väljad"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+#, fuzzy
+msgid "IMDB Rating"
+msgstr "Hinnang"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+#, fuzzy
+msgid "Certifications"
+msgstr "Sertifitseerimine"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr ""
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:69
+#, fuzzy
+msgid "Person"
+msgstr "Isiklik"
+
+#: fetch/fetchmanager.cpp:70
+#, fuzzy
+msgid "ISBN"
+msgstr "ISBN nr"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:72
+#, fuzzy
+msgid "Keyword"
+msgstr "Märksõnad"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:76
+#, fuzzy
+msgid "Raw Query"
+msgstr "Otsingukoht:"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:264
+#, fuzzy
+msgid "Distributor"
+msgstr "Režissöör"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr ""
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:343
+#, fuzzy
+msgid "&Username: "
+msgstr "Kirje kustutamine"
+
+#: fetch/crossreffetcher.cpp:348
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:354
+#, fuzzy
+msgid "&Password: "
+msgstr "Märkused"
+
+#: fetch/gcstarpluginfetcher.cpp:190
+#, fuzzy
+msgid "GCstar Plugin"
+msgstr "Osatäitjad"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:420
+#, fuzzy
+msgid "Author: "
+msgstr "Autor"
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr ""
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr ""
+
+#: newstuff/dialog.cpp:114
+#, fuzzy
+msgid "Version"
+msgstr "Isiklik"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr ""
+
+#: newstuff/dialog.cpp:117
+#, fuzzy
+msgid "Release Date"
+msgstr "Ostmise aeg"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+
+#: newstuff/dialog.cpp:137
+#, fuzzy
+msgid "The name and license of the selected item"
+msgstr "Kustutada valitud kirjed?"
+
+#: newstuff/dialog.cpp:140
+#, fuzzy
+msgid "The author of the selected item"
+msgstr "Kustutada valitud kirjed?"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr ""
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr ""
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+
+#: newstuff/dialog.cpp:194
+#, fuzzy
+msgid "A description of the selected item is shown here."
+msgstr "Kustutada valitud kirjed?"
+
+#: newstuff/dialog.cpp:224
+#, fuzzy
+msgid "Downloading information..."
+msgstr "CSV andmete importimine"
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Valmis."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr ""
+
+#: newstuff/dialog.cpp:413
+#, fuzzy
+msgid "Installing item..."
+msgstr "Faili salvestamine..."
+
+#: translators/bibteximporter.cpp:79
+#, fuzzy
+msgid "No valid bibtex entries were found"
+msgstr "Failist %1 ei leitud ühtki õiget Bibtex kirjet."
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "Failist %1 ei leitud ühtki õiget Bibtex kirjet."
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Bibtex'i valikud"
+
+#: translators/bibteximporter.cpp:287
+#, fuzzy
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Unicode's kodeerimine (UTF-8)"
+
+#: translators/bibteximporter.cpp:288
+#, fuzzy
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Eksporditava faili kodeerimine Unicode's (UTF-8)."
+
+#: translators/bibteximporter.cpp:289
+#, fuzzy
+msgid "Use user locale (%1) encoding"
+msgstr "Kasutaja lokaadis (%1) kodeerimine"
+
+#: translators/bibteximporter.cpp:293
+#, fuzzy
+msgid "Read the imported file in the local encoding."
+msgstr "Eksporditava faili kodeerimine kohalikus vormingus."
+
+#: translators/tellicozipexporter.cpp:35
+#, fuzzy
+msgid "Tellico Zip File"
+msgstr "Tellico"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+#, fuzzy
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Tellico failid (*.bc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+#, fuzzy
+msgid "*|All Files"
+msgstr "*|Kõik failid"
+
+#: translators/alexandriaexporter.cpp:43
+#, fuzzy
+msgid "Alexandria"
+msgstr "Üldised valikud"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "XML sõelumisel on viga real %1, veerus %2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "Qt veateade:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "See on pärit Tellico tulevikuversioonist."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Tellico konverteerib faili veidi uuemasse vormingusse. Selle faili "
+"edaspidisel kasutamisel Tellico mõne vanema versiooniga võib esineda "
+"andmekadu."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Tundmatu"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr ""
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr ""
+
+#: translators/tellicoimporter.cpp:940
+#, fuzzy
+msgid "Unread Books"
+msgstr "Raamatu sisestamine"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr ""
+
+#: translators/tellicoimporter.cpp:968
+#, fuzzy
+msgid "80's Music"
+msgstr "Minu muusika"
+
+#: translators/tellicoimporter.cpp:980
+#, fuzzy
+msgid "Favorites"
+msgstr "Kirje kustutamine"
+
+#: translators/audiofileimporter.cpp:69
+#, fuzzy
+msgid "Scanning audio files..."
+msgstr "Faili salvestamine..."
+
+#: translators/audiofileimporter.cpp:129
+#, fuzzy
+msgid "Bitrate"
+msgstr "Bibtex"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:340
+#, fuzzy
+msgid "Audio File Options"
+msgstr "Välja valikud"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:348
+#, fuzzy
+msgid "If checked, the file names for each track are added to the entries."
+msgstr "Selle ruudu märkimisel väljade nimed prinditakse tabeli päistena."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:353
+#, fuzzy
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr "Selle ruudu märkimisel väljade nimed prinditakse tabeli päistena."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+#, fuzzy
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|CSV failid (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "CSV valikud"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Kaasa väljade nimed tulpade pealdistena"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr "Selle ruudu märkimisel lisatakse pealdisrida väljanimedega."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Piiritleja"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"Lisaks komale võib ka muid märke kasutada failis sisalduvate väärtuste "
+"üksteisest eristamiseks."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Koma"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Koma kasutamine piiritlejana."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Semikoolon"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Semikooloni kasutamine piiritlejana."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Tabulaator"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Tabulaatori kasutamine piiritlejana."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Muu"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Kasutaja poolt valitud märgi kasutamine piiritlejana."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr ""
+"Kasutaja poolt valitud märk, nt koolon, võib olla kasutuses väärtuste "
+"üksteisest eristamiseks (nt \"esimene,teine,kolmas,jne\")."
+
+#: translators/filelistingimporter.cpp:63
+#, fuzzy
+msgid "Scanning files..."
+msgstr "Faili salvestamine..."
+
+#: translators/filelistingimporter.cpp:191
+#, fuzzy
+msgid "File Listing Options"
+msgstr "Printimise valikud"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr ""
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+
+#: translators/filelistingimporter.cpp:198
+#, fuzzy
+msgid "Generate file previews"
+msgstr "Uue dokumendi loomine"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+
+#: translators/onixexporter.cpp:63
+#, fuzzy
+msgid "ONIX Archive"
+msgstr "CSV valikud"
+
+#: translators/onixexporter.cpp:67
+#, fuzzy
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.bib|Bibtexi failid (*.bib)"
+
+#: translators/onixexporter.cpp:176
+#, fuzzy
+msgid "ONIX Archive Options"
+msgstr "CSV valikud"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr ""
+
+#: translators/onixexporter.cpp:181
+#, fuzzy
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Selle ruudu märkimisel lisatakse grupis olevate nimetuste arv grupi nimele"
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+#, fuzzy
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr "Tellico-l ei õnnestu kirjutada faili '%1'."
+
+#: translators/freedbimporter.cpp:196
+#, fuzzy
+msgid "Select CDDB Entry"
+msgstr "V&älja kustutamine"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr ""
+
+#: translators/freedbimporter.cpp:220
+#, fuzzy
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "Tellico-l ei õnnestu avada faili '%1'."
+
+#: translators/freedbimporter.cpp:238
+#, fuzzy
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "Tellico-l ei õnnestu avada faili '%1'."
+
+#: translators/freedbimporter.cpp:470
+#, fuzzy
+msgid "Various"
+msgstr "Grupeerimise alus:"
+
+#: translators/freedbimporter.cpp:489
+#, fuzzy
+msgid "Audio CD Options"
+msgstr "Välja valikud"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr ""
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr ""
+
+#: translators/freedbimporter.cpp:502
+#, fuzzy
+msgid "Read all CDDB cache files only"
+msgstr "Faili salvestamine..."
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr ""
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+#, fuzzy
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.csv|CSV failid (*.csv)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+#, fuzzy
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.csv|CSV failid (*.csv)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "XSLT eelistused"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+#, fuzzy
+msgid "XSLT file:"
+msgstr "XSLT fail:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr "Vali palun XSLT fail, mida kasutada Tellico XML andmete muutmiseks."
+
+#: translators/alexandriaimporter.cpp:194
+#, fuzzy
+msgid "Alexandria Options"
+msgstr "Üldised valikud"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr ""
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "Bibtexml"
+
+#: translators/bibtexmlexporter.cpp:40
+#, fuzzy
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Bibtexml failid (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr ""
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+#, fuzzy
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|XML failid (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+#, fuzzy
+msgid "Tellico XML Options"
+msgstr "TellicoXMLImporter"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr ""
+
+#: translators/tellicoxmlexporter.cpp:485
+#, fuzzy
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Selle ruudu märkimisel lisatakse grupis olevate nimetuste arv grupi nimele"
+
+#: translators/importer.h:100
+#, fuzzy
+msgid "Loading data..."
+msgstr "Andmete importimine..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "Bibtex"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+#, fuzzy
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Bibtexi failid (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Stringimakrote laiendamine"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Selle ruudu märkimisel laiendatakse stringimakrod ning ühtegi @string{} "
+"kirjet ei kirjutata."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "URL paki kasutamine"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr "Selle ruudu märkimisel mähitakse kõik URL väljad \\url avaldisse."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:219
+#, fuzzy
+msgid "Bibtex quotation style:"
+msgstr "Bibtex'i valikud"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+#, fuzzy
+msgid "Braces"
+msgstr "Rajad"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+#, fuzzy
+msgid "Quotes"
+msgstr "Märkused"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Imporditava kogu tüübi valimine."
+
+#: translators/csvimporter.cpp:235
+#, fuzzy
+msgid "&First row contains field titles"
+msgstr "Esimene rida sisaldab väljade pealkirju"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr ""
+"Selle ruudu märkimisel kasutatakse esimese rea kirjeid väljade "
+"pealkirjadena."
+
+#: translators/csvimporter.cpp:248
+#, fuzzy
+msgid "&Comma"
+msgstr "Koma"
+
+#: translators/csvimporter.cpp:254
+#, fuzzy
+msgid "&Semicolon"
+msgstr "Semikoolon"
+
+#: translators/csvimporter.cpp:259
+#, fuzzy
+msgid "Ta&b"
+msgstr "Tabulaator"
+
+#: translators/csvimporter.cpp:264
+#, fuzzy
+msgid "Ot&her:"
+msgstr "Muu"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "See tabel kuvab kuni viis esimest rida CSV failist"
+
+#: translators/csvimporter.cpp:296
+#, fuzzy
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt>Igat tulpa saab panna vastama kollektsiooni väljale valides tulba, siis "
+"välja ning viimaks klõpsates nupule <i>Sea</i>.</qt>"
+
+#: translators/csvimporter.cpp:298
+#, fuzzy
+msgid "Co&lumn:"
+msgstr "Tulp:"
+
+#: translators/csvimporter.cpp:307
+#, fuzzy
+msgid "&Data field in this column:"
+msgstr "Kollektsiooni väli selles tulbas:"
+
+#: translators/csvimporter.cpp:315
+#, fuzzy
+msgid "&Assign Field"
+msgstr "Suvaline väli"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Uus väli"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr ""
+
+#: translators/pilotdbexporter.cpp:43
+#, fuzzy
+msgid "PilotDB"
+msgstr "Välja valikud"
+
+#: translators/pilotdbexporter.cpp:47
+#, fuzzy
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.bc|Tellico failid (*.bc)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Tulpadena vaatamine"
+
+#: translators/pilotdbexporter.cpp:210
+#, fuzzy
+msgid "PilotDB Options"
+msgstr "Välja valikud"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr ""
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+#, fuzzy
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Tellico sattus veale XSLT töötluses.\n"
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "Korralikku XSLT faili on tarvis selle faili importimiseks."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+#, fuzzy
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xml|XML failid (*.xml)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+#, fuzzy
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|HTML failid (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Inimesed"
+
+#: translators/htmlexporter.cpp:320
+#, fuzzy
+msgid "(grouped by %1)"
+msgstr "(sorteeritud %1 järgi)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "HTML eelistused"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Välja päiste printimine"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr "Selle ruudu märkimisel väljade nimed prinditakse tabeli päistena."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Kirjete grupeerimine"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr "Selle ruudu märkimisel grupeeritakse kirjed valitud välja järgi."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr ""
+
+#: translators/htmlexporter.cpp:479
+#, fuzzy
+msgid "If checked, individual files will be created for each entry."
+msgstr "Selle ruudu märkimisel väljade nimed prinditakse tabeli päistena."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+#, fuzzy
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico-l ei õnnestu laadida faili '%1'."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+#, fuzzy
+msgid "Data Source Properties"
+msgstr "Välja omadused"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr ""
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr ""
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr ""
+
+#: fetcherconfigdialog.cpp:114
+#, fuzzy
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr "Selle ruudu märkimisel grupeeritakse kirjed valitud välja järgi."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Suvaline väli"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "sisaldab"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "ei sisalda"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "võrdub"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "ei võrdu"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "vastab regulaaravaldisele"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "ei vasta regulaaravaldisele"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Muutmine"
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Erifilter"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Filtreerimise kriteeriumid"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Vasta kõige&le järgnevale"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Vasta millelegi j&ärgnevast"
+
+#: filterdialog.cpp:311
+#, fuzzy
+msgid "Filter name:"
+msgstr "Kirje kustutamine"
+
+#: filterdialog.cpp:319
+#, fuzzy
+msgid "&Save Filter"
+msgstr "Erifilter"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Tavaline tekst"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Lõik"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr ""
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Märkeruut"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Tabel"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr ""
+
+#: field.cpp:500
+msgid "Date"
+msgstr ""
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr ""
+
+#: entryupdater.cpp:83
+#, fuzzy
+msgid "Updating entries..."
+msgstr "Kirje kustutamine"
+
+#: entryupdater.cpp:85
+#, fuzzy
+msgid "Update Entries"
+msgstr "Kirje kustutamine"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr ""
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr ""
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Gruppide vaate laiendamine"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Gruppide vaate ahendamine"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr ""
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr ""
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr ""
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Valikute importimine"
+
+#: importdialog.cpp:62
+#, fuzzy
+msgid "&Replace current collection"
+msgstr "Käesoleva kogu asendamine"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr "Käesoleva kogu asendamine imporditud faili sisuga."
+
+#: importdialog.cpp:65
+#, fuzzy
+msgid "A&ppend to current collection"
+msgstr "Käesolevale kogule lisamine"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Imporditava faili sisu lisatakse käesolevale kogule. See on võimalik "
+"siiski vaid juhul, kui kogu kirjete tüübid kogudes ühtivad."
+
+#: importdialog.cpp:69
+#, fuzzy
+msgid "&Merge with current collection"
+msgstr "Käesolevale kogule lisamine"
+
+#: importdialog.cpp:70
+#, fuzzy
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Imporditava faili sisu lisatakse käesolevale kogule. See on võimalik "
+"siiski vaid juhul, kui kogu kirjete tüübid kogudes ühtivad."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Importimine"
+
+#: importdialog.cpp:268
+#, fuzzy
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.xml|XML failid (*.xml)"
+
+#: importdialog.cpp:277
+#, fuzzy
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.csv|CSV failid (*.csv)"
+
+#: importdialog.cpp:281
+#, fuzzy
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.bc|Tellico failid (*.bc)"
+
+#: importdialog.cpp:285
+#, fuzzy
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.xml|XML failid (*.xml)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico-l ei õnnestu laadida faili '%1'."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico-l ei õnnestu kirjutada faili '%1'."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico-l ei õnnestu üles laadida faili '%1'."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Lisada saab ainult käesolevaga sama tüüpi kirjeid sisaldavaid kogusid. "
+"Käesolevas kogus muudatusi ei tehta."
+
+#: tellico_strings.cpp:24
+#, fuzzy
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Lisada saab ainult käesolevaga sama tüüpi kirjeid sisaldavaid kogusid. "
+"Käesolevas kogus muudatusi ei tehta."
+
+#: tellico_strings.cpp:27
+#, fuzzy, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico-l ei õnnestu laadida faili '%1'."
+
+#: entryiconview.cpp:287
+#, fuzzy
+msgid "&Sort By"
+msgstr "Märkused"
+
+#: loandialog.cpp:40
+#, fuzzy
+msgid "Loan Dialog"
+msgstr "Valikudialoog"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr ""
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr ""
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr ""
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr ""
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr ""
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+
+#: loandialog.cpp:144
+#, fuzzy
+msgid "&Note:"
+msgstr "Märkused"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr ""
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr ""
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+
+#: mainwindow.cpp:188
+#, fuzzy
+msgid "Create a new collection"
+msgstr "Uue dokumendi loomine"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Uus raamatukog&u"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Uue raamatukogu loomine"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Uus b&ibliograafia"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Uue bibtexml bibliograafia loomine"
+
+#: mainwindow.cpp:208
+#, fuzzy
+msgid "New &Comic Book Collection"
+msgstr "Uus raamatukog&u"
+
+#: mainwindow.cpp:210
+#, fuzzy
+msgid "Create a new comic book collection"
+msgstr "Uue raamatukogu loomine"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Uus &videokogu"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Uue videokogu loomine"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Uus &muusikakogu"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Uue muusikakogu loomine"
+
+#: mainwindow.cpp:232
+#, fuzzy
+msgid "New C&oin Collection"
+msgstr "Uue kogu nimi"
+
+#: mainwindow.cpp:234
+#, fuzzy
+msgid "Create a new coin collection"
+msgstr "Uue dokumendi loomine"
+
+#: mainwindow.cpp:240
+#, fuzzy
+msgid "New &Stamp Collection"
+msgstr "Uue kogu nimi"
+
+#: mainwindow.cpp:242
+#, fuzzy
+msgid "Create a new stamp collection"
+msgstr "Uue dokumendi loomine"
+
+#: mainwindow.cpp:248
+#, fuzzy
+msgid "New C&ard Collection"
+msgstr "Uus &videokogu"
+
+#: mainwindow.cpp:250
+#, fuzzy
+msgid "Create a new trading card collection"
+msgstr "Uue videokogu loomine"
+
+#: mainwindow.cpp:256
+#, fuzzy
+msgid "New &Wine Collection"
+msgstr "Uus &videokogu"
+
+#: mainwindow.cpp:258
+#, fuzzy
+msgid "Create a new wine collection"
+msgstr "Uue videokogu loomine"
+
+#: mainwindow.cpp:264
+#, fuzzy
+msgid "New &Game Collection"
+msgstr "Uue kogu nimi"
+
+#: mainwindow.cpp:266
+#, fuzzy
+msgid "Create a new game collection"
+msgstr "Uue dokumendi loomine"
+
+#: mainwindow.cpp:272
+#, fuzzy
+msgid "New Boa&rd Game Collection"
+msgstr "Uue kogu nimi"
+
+#: mainwindow.cpp:274
+#, fuzzy
+msgid "Create a new board game collection"
+msgstr "Uue dokumendi loomine"
+
+#: mainwindow.cpp:280
+#, fuzzy
+msgid "New &File Catalog"
+msgstr "Uus väli"
+
+#: mainwindow.cpp:282
+#, fuzzy
+msgid "Create a new file catalog"
+msgstr "Uue dokumendi loomine"
+
+#: mainwindow.cpp:288
+#, fuzzy
+msgid "New C&ustom Collection"
+msgstr "Uue kogu nimi"
+
+#: mainwindow.cpp:290
+#, fuzzy
+msgid "Create a new custom collection"
+msgstr "Uue muusikakogu loomine"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Olemasoleva dokumendi avamine"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Hiljuti kasutatud faili avamine"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Käesoleva dokumendi salvestamine"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Dokumendi uue failinimega salvestamine"
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Dokumendi sisu printimine"
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Rakendusest lahkumine"
+
+#: mainwindow.cpp:320
+#, fuzzy
+msgid "Import collection data from other formats"
+msgstr "Kogu andmete importimine teistest vormingutest..."
+
+#: mainwindow.cpp:324
+#, fuzzy
+msgid "Import Tellico Data..."
+msgstr "Tellico andmete importimine"
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Tellico andmefaili importimine"
+
+#: mainwindow.cpp:331
+#, fuzzy
+msgid "Import CSV Data..."
+msgstr "CSV andmete importimine"
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "CSV faili importimine"
+
+#: mainwindow.cpp:338
+#, fuzzy
+msgid "Import MODS Data..."
+msgstr "CSV andmete importimine"
+
+#: mainwindow.cpp:339
+#, fuzzy
+msgid "Import a MODS data file"
+msgstr "CSV faili importimine"
+
+#: mainwindow.cpp:345
+#, fuzzy
+msgid "Import Alexandria Data..."
+msgstr "Bibtex'i andmete importimine"
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr ""
+
+#: mainwindow.cpp:352
+#, fuzzy
+msgid "Import Delicious Library Data..."
+msgstr "Tellico andmete importimine"
+
+#: mainwindow.cpp:353
+#, fuzzy
+msgid "Import data from Delicious Library"
+msgstr "Bibtexmlist importimine"
+
+#: mainwindow.cpp:359
+#, fuzzy
+msgid "Import Referencer Data..."
+msgstr "CSV andmete importimine"
+
+#: mainwindow.cpp:360
+#, fuzzy
+msgid "Import data from Referencer"
+msgstr "CSV faili importimine"
+
+#: mainwindow.cpp:366
+#, fuzzy
+msgid "Import Bibtex Data..."
+msgstr "Bibtex'i andmete importimine"
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Bibtex bibliograafiafaili importimine"
+
+#: mainwindow.cpp:373
+#, fuzzy
+msgid "Import Bibtexml Data..."
+msgstr "Bibtexml andmete importimine"
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Bibtex bibliograafiafaili importimine"
+
+#: mainwindow.cpp:380
+#, fuzzy
+msgid "Import RIS Data..."
+msgstr "CSV andmete importimine"
+
+#: mainwindow.cpp:381
+#, fuzzy
+msgid "Import an RIS reference file"
+msgstr "CSV faili importimine"
+
+#: mainwindow.cpp:387
+#, fuzzy
+msgid "Import PDF File..."
+msgstr "Faili importimine..."
+
+#: mainwindow.cpp:388
+#, fuzzy
+msgid "Import a PDF file"
+msgstr "CSV faili importimine"
+
+#: mainwindow.cpp:394
+#, fuzzy
+msgid "Import Audio File Metadata..."
+msgstr "CSV andmete importimine"
+
+#: mainwindow.cpp:395
+#, fuzzy
+msgid "Import meta-data from audio files"
+msgstr "Bibtexmlist importimine"
+
+#: mainwindow.cpp:404
+#, fuzzy
+msgid "Import Audio CD Data..."
+msgstr "CSV andmete importimine"
+
+#: mainwindow.cpp:405
+#, fuzzy
+msgid "Import audio CD information"
+msgstr "CSV andmete importimine"
+
+#: mainwindow.cpp:414
+#, fuzzy
+msgid "Import GCstar Data..."
+msgstr "CSV andmete importimine"
+
+#: mainwindow.cpp:415
+#, fuzzy
+msgid "Import a GCstar data file"
+msgstr "CSV faili importimine"
+
+#: mainwindow.cpp:421
+#, fuzzy
+msgid "Import Griffith Data..."
+msgstr "CSV andmete importimine"
+
+#: mainwindow.cpp:422
+#, fuzzy
+msgid "Import a Griffith database"
+msgstr "Bibtex faili eksportimine"
+
+#: mainwindow.cpp:428
+#, fuzzy
+msgid "Import Ant Movie Catalog Data..."
+msgstr "CSV andmete importimine"
+
+#: mainwindow.cpp:429
+#, fuzzy
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Tellico andmefaili importimine"
+
+#: mainwindow.cpp:435
+#, fuzzy
+msgid "Import File Listing..."
+msgstr "Faili importimine..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr ""
+
+#: mainwindow.cpp:442
+#, fuzzy
+msgid "Import XSL Transform..."
+msgstr "XSL muudatustega importimine"
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "XSL muudatusi kasutav importimine"
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Eksportimine"
+
+#: mainwindow.cpp:457
+#, fuzzy
+msgid "Export the collection data to other formats"
+msgstr "Andmete eksportimine teistesse vormingutesse..."
+
+#: mainwindow.cpp:461
+#, fuzzy
+msgid "Export to XML..."
+msgstr "Eksport HTML vormingusse"
+
+#: mainwindow.cpp:462
+#, fuzzy
+msgid "Export to a Tellico XML file"
+msgstr "Eksport HTML faili"
+
+#: mainwindow.cpp:468
+#, fuzzy
+msgid "Export to Zip..."
+msgstr "Eksport HTML vormingusse"
+
+#: mainwindow.cpp:469
+#, fuzzy
+msgid "Export to a Tellico Zip file"
+msgstr "Eksport HTML faili"
+
+#: mainwindow.cpp:475
+#, fuzzy
+msgid "Export to HTML..."
+msgstr "Eksport HTML vormingusse"
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Eksport HTML faili"
+
+#: mainwindow.cpp:482
+#, fuzzy
+msgid "Export to CSV..."
+msgstr "Eksport CSV faili"
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Komaga-eraldatud-väärtuste faili eksportimine"
+
+#: mainwindow.cpp:489
+#, fuzzy
+msgid "Export to PilotDB..."
+msgstr "Bibtexi eksportimine"
+
+#: mainwindow.cpp:490
+#, fuzzy
+msgid "Export to a PilotDB database"
+msgstr "Bibtex faili eksportimine"
+
+#: mainwindow.cpp:496
+#, fuzzy
+msgid "Export to Alexandria..."
+msgstr "Bibtex'i andmete importimine"
+
+#: mainwindow.cpp:497
+#, fuzzy
+msgid "Export to an Alexandria library"
+msgstr "Bibtex'i andmete importimine"
+
+#: mainwindow.cpp:503
+#, fuzzy
+msgid "Export to Bibtex..."
+msgstr "Bibtexi eksportimine"
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Bibtex faili eksportimine"
+
+#: mainwindow.cpp:510
+#, fuzzy
+msgid "Export to Bibtexml..."
+msgstr "Bibtexmli eksportimine"
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Bibtexml faili eksportimine"
+
+#: mainwindow.cpp:517
+#, fuzzy
+msgid "Export to ONIX..."
+msgstr "Eksport HTML vormingusse"
+
+#: mainwindow.cpp:518
+#, fuzzy
+msgid "Export to an ONIX file"
+msgstr "Eksport HTML faili"
+
+#: mainwindow.cpp:524
+#, fuzzy
+msgid "Export to GCfilms..."
+msgstr "Eksport CSV faili"
+
+#: mainwindow.cpp:525
+#, fuzzy
+msgid "Export to a GCfilms data file"
+msgstr "Bibtex faili eksportimine"
+
+#: mainwindow.cpp:531
+#, fuzzy
+msgid "Export to GCstar..."
+msgstr "Eksport CSV faili"
+
+#: mainwindow.cpp:532
+#, fuzzy
+msgid "Export to a GCstar data file"
+msgstr "Bibtex faili eksportimine"
+
+#: mainwindow.cpp:536
+#, fuzzy
+msgid "Export XSL Transform..."
+msgstr "XSL muudatustega eksportimine"
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "XSL muudatusi kasutav eksportimine"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr ""
+
+#: mainwindow.cpp:548
+#, fuzzy
+msgid "Copy the selected text to the clipboard"
+msgstr "Valitu lõikelauale kopeerimine"
+
+#: mainwindow.cpp:550
+#, fuzzy
+msgid "Paste the clipboard contents"
+msgstr "Lõikelaua sisu lisamine"
+
+#: mainwindow.cpp:552
+#, fuzzy
+msgid "Select all the entries in the collection"
+msgstr "Need on selle kogu valitud väljad."
+
+#: mainwindow.cpp:554
+#, fuzzy
+msgid "Deselect all the entries in the collection"
+msgstr "Need on selle kogu valitud väljad."
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr ""
+
+#: mainwindow.cpp:559
+#, fuzzy
+msgid "Search the internet..."
+msgstr "Dokumendist otsimine"
+
+#: mainwindow.cpp:561
+#, fuzzy
+msgid "Advanced &Filter..."
+msgstr "Erifilter"
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Kogu väljade filtreerimine"
+
+#: mainwindow.cpp:569
+#, fuzzy
+msgid "&New Entry..."
+msgstr "Uus kirje"
+
+#: mainwindow.cpp:572
+#, fuzzy
+msgid "Create a new entry"
+msgstr "Uue dokumendi loomine"
+
+#: controller.cpp:620 mainwindow.cpp:573
+#, fuzzy
+msgid "&Edit Entry..."
+msgstr "Kirje kustutamine"
+
+#: mainwindow.cpp:576
+#, fuzzy
+msgid "Edit the selected entries"
+msgstr "Kustutada valitud kirjed?"
+
+#: controller.cpp:621 mainwindow.cpp:577
+#, fuzzy
+msgid "D&uplicate Entry"
+msgstr "Kirjest dublikaadi tegemine"
+
+#: mainwindow.cpp:580
+#, fuzzy
+msgid "Copy the selected entries"
+msgstr "Kustutada valitud kirjed?"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "V&älja kustutamine"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Kustutada valitud kirjed?"
+
+#: mainwindow.cpp:585
+#, fuzzy
+msgid "&Merge Entries"
+msgstr "Väljade kustutamine"
+
+#: mainwindow.cpp:588
+#, fuzzy
+msgid "Merge the selected entries"
+msgstr "Kustutada valitud kirjed?"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr ""
+
+#: mainwindow.cpp:594
+#, fuzzy
+msgid "Generate collection reports"
+msgstr "Uue dokumendi loomine"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr ""
+
+#: mainwindow.cpp:598
+#, fuzzy
+msgid "Check-out the selected items"
+msgstr "Kustutada valitud kirjed?"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr ""
+
+#: mainwindow.cpp:602
+#, fuzzy
+msgid "Check-in the selected items"
+msgstr "Kustutada valitud kirjed?"
+
+#: mainwindow.cpp:604
+#, fuzzy
+msgid "&Rename Collection..."
+msgstr "Kogu nime muutmine"
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Kollektsiooni nime muutmine"
+
+#: mainwindow.cpp:608
+#, fuzzy
+msgid "Collection &Fields..."
+msgstr "Kogu kirjed"
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Kogu väljade muutmine"
+
+#: mainwindow.cpp:612
+#, fuzzy
+msgid "Convert to &Bibliography"
+msgstr "Bibliograafiaks konverteerimine"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Raamatukogu bibliograafiaks konverteerimine"
+
+#: mainwindow.cpp:616
+#, fuzzy
+msgid "String &Macros..."
+msgstr "Makrod..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Bibtex'i makrote muutmine"
+
+#: mainwindow.cpp:626
+#, fuzzy
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Valitu lõikelauale kopeerimine"
+
+#: mainwindow.cpp:627
+#, fuzzy
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Valitu lõikelauale kopeerimine"
+
+#: mainwindow.cpp:632
+#, fuzzy
+msgid "Cite Entry in &LyX"
+msgstr "Kirje kustutamine"
+
+#: mainwindow.cpp:633
+#, fuzzy
+msgid "Cite the selected entries in LyX"
+msgstr "Kustutada valitud kirjed?"
+
+#: mainwindow.cpp:638
+#, fuzzy
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Kirje kustutamine"
+
+#: mainwindow.cpp:639
+#, fuzzy
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Kustutada valitud kirjed?"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, fuzzy, no-c-format
+msgid "&Update Entry"
+msgstr "Kirje kustutamine"
+
+#: mainwindow.cpp:652
+#, fuzzy
+msgid "All Sources"
+msgstr "Otsingukoht:"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr ""
+
+#: mainwindow.cpp:665
+#, fuzzy
+msgid "Show Grou&p View"
+msgstr "&Grupivaate näitamine"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Grupivaate lubamine/keelamine"
+
+#: mainwindow.cpp:669
+#, fuzzy
+msgid "Hide Grou&p View"
+msgstr "&Grupivaate näitamine"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Kirj&eredaktori näitamine"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Redaktori lubamine/keelamine"
+
+#: mainwindow.cpp:675
+#, fuzzy
+msgid "Hide Entry &Editor"
+msgstr "Kirj&eredaktori näitamine"
+
+#: mainwindow.cpp:677
+#, fuzzy
+msgid "Show Entry &View"
+msgstr "Kirj&eredaktori näitamine"
+
+#: mainwindow.cpp:680
+#, fuzzy
+msgid "Enable/disable the entry view"
+msgstr "Grupivaate lubamine/keelamine"
+
+#: mainwindow.cpp:681
+#, fuzzy
+msgid "Hide Entry &View"
+msgstr "Kirj&eredaktori näitamine"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr ""
+
+#: mainwindow.cpp:697
+#, fuzzy
+msgid "&Group Selection"
+msgstr "Grupeerimise valikud"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Kogu grupeerimise muutmine"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+#, fuzzy
+msgid "Filter"
+msgstr "Kirje kustutamine"
+
+#: mainwindow.cpp:705
+#, fuzzy
+msgid "Clear Filter"
+msgstr "Kustutada väli?"
+
+#: mainwindow.cpp:710
+#, fuzzy
+msgid "Filter here..."
+msgstr "Filtreerimise kriteeriumid"
+
+#: mainwindow.cpp:768
+#, fuzzy
+msgid "Groups"
+msgstr "Grupeerimise alus:"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:831
+#, fuzzy
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Tellico - rakendus raamatute kogu haldamiseks KDE-s"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Uue dokumendi loomine..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Faili avamine..."
+
+#: mainwindow.cpp:1108
+#, fuzzy
+msgid "Open File"
+msgstr "Faili avamine..."
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Faili salvestamine..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr ""
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr ""
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Faili uue nimega salvestamine..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Printimine..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"Kogu filtreeritakse näitamaks ainult piiratud hulka kirjeid. Prinditakse "
+"ainult nähtavad kirjed. Jätkata?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Dokumendi töötlemine..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Väljumine..."
+
+#: mainwindow.cpp:1498
+#, fuzzy, c-format
+msgid "Total entries: %1"
+msgstr "Kirjete sal&vestamine"
+
+#: mainwindow.cpp:1505
+#, fuzzy
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 on valitud)"
+
+#: mainwindow.cpp:1508
+#, fuzzy
+msgid "(%1 filtered)"
+msgstr "(%1 on valitud)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 on valitud)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "%1 printimine"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Lehekülg nr %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Palun kontrolli oma installatsiooni."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Andmete importimine..."
+
+#: mainwindow.cpp:1858
+#, fuzzy
+msgid "Import File"
+msgstr "Faili importimine..."
+
+#: mainwindow.cpp:1864
+#, fuzzy
+msgid "Import Directory"
+msgstr "Importija"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Andmete eksportimine..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Eksport "
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Stringimakrod"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Makro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "String"
+
+#: mainwindow.cpp:1999
+#, fuzzy
+msgid "Creating citations..."
+msgstr "Märgistatu lõikamine"
+
+#: mainwindow.cpp:2104
+#, fuzzy
+msgid "Filters"
+msgstr "Kirje kustutamine"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:2121
+#, fuzzy
+msgid "Loans"
+msgstr "Laenatud"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr ""
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+
+#: filehandler.cpp:193
+#, fuzzy, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico-l ei õnnestu laadida faili '%1'."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+"Fail nimega \"%1\" on juba olemas. Kas oled kindel, et soovid selle üle "
+"kirjutada?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Fail üle kirjutada?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Üle kirjutamine"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr ""
+
+#: controller.cpp:427
+#, fuzzy
+msgid "Do you really want to delete this entry?"
+msgstr "Kas oled kindel oma soovis kustutada need kirjed?"
+
+#: controller.cpp:429
+#, fuzzy
+msgid "Delete Entry"
+msgstr "V&älja kustutamine"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Kas oled kindel oma soovis kustutada need kirjed?"
+
+#: controller.cpp:443
+#, fuzzy
+msgid "Delete Multiple Entries"
+msgstr "Kustutada need kirjed?"
+
+#: controller.cpp:626
+#, fuzzy
+msgid "&Edit Entries..."
+msgstr "Kirje kustutamine"
+
+#: controller.cpp:627
+#, fuzzy
+msgid "D&uplicate Entries"
+msgstr "Kirjest dublikaadi tegemine"
+
+#: controller.cpp:628
+#, fuzzy
+msgid "&Update Entries"
+msgstr "Kirje kustutamine"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "Väljade kustutamine"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr ""
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr ""
+
+#: calendarhandler.cpp:203
+#, fuzzy
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico-l ei õnnestu lugeda faili '%1'."
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(tühi)"
+
+#: main.cpp:23
+#, fuzzy
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - rakendus raamatute kogu haldamiseks KDE-s"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Ärgu avatagu viimati avatud faili"
+
+#: main.cpp:28
+#, fuzzy
+msgid "Import <filename> as a bibtex file"
+msgstr "Bibtex faili eksportimine"
+
+#: main.cpp:29
+#, fuzzy
+msgid "Import <filename> as a MODS file"
+msgstr "CSV faili importimine"
+
+#: main.cpp:30
+#, fuzzy
+msgid "Import <filename> as a RIS file"
+msgstr "CSV faili importimine"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Fail, mida avada"
+
+#: main.cpp:42
+#, fuzzy
+msgid "Data source scripts"
+msgstr "Valikute importimine"
+
+#: main.cpp:44
+#, fuzzy
+msgid "Icons"
+msgstr "sisaldab"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "'Btparse library' autor"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr ""
+
+#: main.cpp:50
+#, fuzzy
+msgid "Author of libcsv library"
+msgstr "'Btparse library' autor"
+
+#: main.cpp:52
+#, fuzzy
+msgid "Author of rtf2html library"
+msgstr "'Btparse library' autor"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Kollektsiooni kirjed"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Käesolevad väljad"
+
+#: collectionfieldsdialog.cpp:84
+#, fuzzy
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "Uus väli"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Kogusse uue välja lisamine"
+
+#: collectionfieldsdialog.cpp:87
+#, fuzzy
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "Välja kustutamine"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Välja eemaldamine kogust"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Selle välja nimekirjas ülespoole liigutamine. Nimekirja järjestus on "
+"oluline kirjeredaktori väljanägemise seisukohalt."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Selle välja nimekirjas allapoole liigutamine. Nimekirja järjestus on "
+"oluline kirjeredaktori väljanägemise seisukohalt."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Välja omadused"
+
+#: collectionfieldsdialog.cpp:119
+#, fuzzy
+msgid "&Title:"
+msgstr "Pealkiri:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "Välja pealkiri"
+
+#: collectionfieldsdialog.cpp:129
+#, fuzzy
+msgid "T&ype:"
+msgstr "Tüüp:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:157
+#, fuzzy
+msgid "Cate&gory:"
+msgstr "Liigitus:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr "Välja liigitus määrab ära tema asukoha redaktoris."
+
+#: collectionfieldsdialog.cpp:179
+#, fuzzy
+msgid "Descr&iption:"
+msgstr "Kirjeldus:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:203
+#, fuzzy
+msgid "A&llowed values:"
+msgstr "Lubatud:"
+
+#: collectionfieldsdialog.cpp:208
+#, fuzzy
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt><i>Nimekiri</i> tüüpi väljade jaoks on need ainsad lubatud "
+"väärtused. Leiduvad liitboksis.</qt>"
+
+#: collectionfieldsdialog.cpp:215
+#, fuzzy
+msgid "Extended &properties:"
+msgstr "Välja omadused"
+
+#: collectionfieldsdialog.cpp:217
+#, fuzzy
+msgid "&Set..."
+msgstr "Sea"
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Vormingu eelistused"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Vormistuseta"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+"See suvand keelab välja automaatse vormistamise (nt automaatne "
+"suurtähtesitus)."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Luba ainult automaatsed suurtähtesitused."
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+"See suvand lubab välja teksti teisendamise suurtähtedeks ilma muu erilise "
+"vormistamiseta."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Pealkirjana vormistamine"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"See suvand teisendab välja teksti suurtähtedeks ning vormistab selle "
+"pealkirjana. Seda siiski vaid juhul, kui need eelistused on seatud "
+"globaalselt."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Nimena vormistamine"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"See suvand teisendab välja teksti suurtähtedeks ja vormistab välja "
+"nimena. Seda siiski vaid juhul, kui need eelistused on seatud globaalselt."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Välja valikud"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Automaatse sõnalõpetuse lubamine"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Selle ruudu märkimisel lubatakse KDE automaatne sõnalõpetus (arvuti "
+"üritab mõistatada, mis sõna sa parasjagu soovid kirjutada ning pakub "
+"lahkesti oma abi sinu sõrmede vaeva vähendamiseks) selle välja "
+"tekstisisestuse boksi tarvis."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Enam kui ühe väärtuse lubamine"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Selle ruudu märkimisel mõistab Tellico, et väljal on mitu üskteisest "
+"semikooloniga eraldatud väärtust."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Grupeerimise lubamine"
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Selle ruudu märkimisel saab seda välja kasutada grupivaate kirjete "
+"grupeerimiseks."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr "Valitud välja eelistuste asendamine vaikeväärtustega."
+
+#: collectionfieldsdialog.cpp:306
+#, fuzzy
+msgid "Modify Fields"
+msgstr "Kiirfilter"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:745
+#, fuzzy
+msgid "Revert Field Properties"
+msgstr "Muuta välja omadused?"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Kas oled kindel oma otsuses asendada välja <em>%1</em> omadused "
+"vaikeväärtustega?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Tagasimuutmine"
+
+#: collectionfieldsdialog.cpp:872
+#, fuzzy
+msgid "Extended Field Properties"
+msgstr "Välja omadused"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr ""
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Käesolevat faili on muudetud.\n"
+"Soovid sa selle salvestada?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr ""
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr ""
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Eelistused"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Üldised valikud"
+
+#: configdialog.cpp:201
+#, fuzzy
+msgid "&Reopen file at startup"
+msgstr "Faili taasavamine programmi käivitamisel"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Selle ruudu märkimisel avatakse viimati kasutatud fail programmi "
+"taaskäivitamisel"
+
+#: configdialog.cpp:207
+#, fuzzy
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "\"Päeva nipi\" näitamine programmi käivitamisel"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr ""
+"Selle ruudu märkimisel näidatakse programmi käivitamisel õpetliku sisuga "
+"\"Päeva nippi\" - nõuandeid programmi efektiivsemaks kasutamiseks."
+
+#: configdialog.cpp:213
+#, fuzzy
+msgid "Image Storage Options"
+msgstr "Valikute importimine"
+
+#: configdialog.cpp:214
+#, fuzzy
+msgid "Store images in data file"
+msgstr "CSV faili importimine"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr ""
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr ""
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Kujundamise valikud"
+
+#: configdialog.cpp:227
+#, fuzzy
+msgid "Auto capitalize &titles and names"
+msgstr "Pealkirjadele ja nimedele automaatselt suure algustähe andmine"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Selle ruudu märkimisel antakse raamatute pealkirjadele ja autorite nimedele "
+"automaatselt suured algustähed."
+
+#: configdialog.cpp:232
+#, fuzzy
+msgid "Auto &format titles and names"
+msgstr "Pealkirjade ja nimede automaatvormindus"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr ""
+"Selle ruudu märkimisel vormistatakse raamatute pealkirjad ja autorite nimed "
+"automaatselt."
+
+#: configdialog.cpp:240
+#, fuzzy
+msgid "No capitali&zation:"
+msgstr "Luba ainult automaatsed suurtähtesitused."
+
+#: configdialog.cpp:243
+#, fuzzy
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"Komadega eraldatud nimekiri sõnadest, mida tuleks kohelda artiklitena, kui "
+"nad esinevad pealkirja esimese sõnana."
+
+#: configdialog.cpp:249
+#, fuzzy
+msgid "Artic&les:"
+msgstr "Artiklid:"
+
+#: configdialog.cpp:252
+#, fuzzy
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"Komadega eraldatud nimekiri sõnadest, mida tuleks kohelda artiklitena, kui "
+"nad esinevad pealkirja esimese sõnana."
+
+#: configdialog.cpp:259
+#, fuzzy
+msgid "Personal suffi&xes:"
+msgstr "Isiklikud sufiksid"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+
+#: configdialog.cpp:268
+#, fuzzy
+msgid "Surname &prefixes:"
+msgstr "Perekonnanime prefiksid:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Printimine"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Printimise valikud"
+
+#: configdialog.cpp:302
+#, fuzzy
+msgid "&Format titles and names"
+msgstr "Pealkirjade ja nimede vormindamine"
+
+#: configdialog.cpp:306
+#, fuzzy
+msgid "&Print field headers"
+msgstr "Välja päiste printimine"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Grupeerimise valikud"
+
+#: configdialog.cpp:313
+#, fuzzy
+msgid "&Group the entries"
+msgstr "Kirjete grupeerimine"
+
+#: configdialog.cpp:317
+#, fuzzy
+msgid "Image Options"
+msgstr "Valikute importimine"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr ""
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr ""
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr ""
+
+#: configdialog.cpp:355
+#, fuzzy
+msgid "Template Options"
+msgstr "Valikute importimine"
+
+#: configdialog.cpp:369
+#, fuzzy
+msgid "Template:"
+msgstr "Valikute importimine"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+
+#: configdialog.cpp:380
+#, fuzzy
+msgid "&Preview..."
+msgstr "&Uus"
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr ""
+
+#: configdialog.cpp:398
+#, fuzzy
+msgid "Font Options"
+msgstr "Vormingu eelistused"
+
+#: configdialog.cpp:405
+#, fuzzy
+msgid "Font:"
+msgstr "Kuu"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:415
+#, fuzzy
+msgid "Size:"
+msgstr "Pühendusega"
+
+#: configdialog.cpp:425
+#, fuzzy
+msgid "Color Options"
+msgstr "CSV valikud"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr ""
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr ""
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr ""
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr ""
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr ""
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr ""
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr ""
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr ""
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr ""
+
+#: configdialog.cpp:487
+#, fuzzy
+msgid "Delete..."
+msgstr "XSLT fail valimine"
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr ""
+
+#: configdialog.cpp:501
+#, fuzzy
+msgid "Data Sources"
+msgstr "Otsingukoht:"
+
+#: configdialog.cpp:501
+#, fuzzy
+msgid "Data Source Options"
+msgstr "Valikute importimine"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr ""
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr ""
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr ""
+
+#: configdialog.cpp:528
+#, fuzzy
+msgid "&New..."
+msgstr "&Uus"
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr ""
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr ""
+
+#: configdialog.cpp:533
+#, fuzzy
+msgid "Click to modify the selected data source."
+msgstr "Kustutada valitud kirjed?"
+
+#: configdialog.cpp:536
+#, fuzzy
+msgid "Click to delete the selected data source."
+msgstr "Kustutada valitud kirjed?"
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr ""
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr ""
+
+#: configdialog.cpp:1049
+#, fuzzy
+msgid "Delete Template"
+msgstr "Kustutada väli?"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr ""
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr ""
+
+#: loanview.cpp:74
+#, fuzzy
+msgid "Check-in"
+msgstr "Märkeruut"
+
+#: loanview.cpp:76
+#, fuzzy
+msgid "Modify Loan..."
+msgstr "Raamatu kirje muutmine"
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr ""
+
+#: collectionfactory.cpp:81
+#, fuzzy
+msgid "My Collection"
+msgstr "Muusikakogu"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Raamatukogu"
+
+#: collectionfactory.cpp:126
+#, fuzzy
+msgid "Comic Book Collection"
+msgstr "Raamatukogu"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Videokogu"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Muusikakogu"
+
+#: collectionfactory.cpp:129
+#, fuzzy
+msgid "Coin Collection"
+msgstr "Muusikakogu"
+
+#: collectionfactory.cpp:130
+#, fuzzy
+msgid "Stamp Collection"
+msgstr "Kogu nime muutmine"
+
+#: collectionfactory.cpp:131
+#, fuzzy
+msgid "Wine Collection"
+msgstr "Videokogu"
+
+#: collectionfactory.cpp:132
+#, fuzzy
+msgid "Card Collection"
+msgstr "BCKollektsioon"
+
+#: collectionfactory.cpp:133
+#, fuzzy
+msgid "Game Collection"
+msgstr "Kogu nime muutmine"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr ""
+
+#: collectionfactory.cpp:135
+#, fuzzy
+msgid "Board Game Collection"
+msgstr "Kogu nime muutmine"
+
+#: collectionfactory.cpp:136
+#, fuzzy
+msgid "Custom Collection"
+msgstr "Uue kogu nimi"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Valikute eksportimine"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Vormistamine"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Kõigi väljade vormistamine"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Selle ruudu märkimisel vormistatakse väljade väärtused automaatselt "
+"vastavalt nende vormingutüübile."
+
+#: exportdialog.cpp:59
+#, fuzzy
+msgid "Export selected entries only"
+msgstr "Kustutada valitud kirjed?"
+
+#: exportdialog.cpp:61
+#, fuzzy
+msgid "If checked, only the currently selected entries will be exported."
+msgstr "Selle ruudu märkimisel väljade nimed prinditakse tabeli päistena."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Kodeerimine"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Unicode's kodeerimine (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Eksporditava faili kodeerimine Unicode's (UTF-8)."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Kasutaja lokaadis (%1) kodeerimine"
+
+#: exportdialog.cpp:72
+#, fuzzy
+msgid "Encode the exported file in the local encoding."
+msgstr "Eksporditava faili kodeerimine kohalikus vormingus."
+
+#: fetchdialog.cpp:65
+#, fuzzy
+msgid "&Search"
+msgstr "Otsingukoht:"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr ""
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr ""
+
+#: fetchdialog.cpp:94
+#, fuzzy
+msgid "Search Query"
+msgstr "Otsingukoht:"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr ""
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr ""
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr ""
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr ""
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr ""
+
+#: fetchdialog.cpp:138
+#, fuzzy
+msgid "Edit List..."
+msgstr "Muutmine"
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+
+#: fetchdialog.cpp:146
+#, fuzzy
+msgid "Search s&ource:"
+msgstr "Otsingukoht:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr ""
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+
+#: fetchdialog.cpp:192
+#, fuzzy
+msgid "&Add Entry"
+msgstr "Kirje kustutamine"
+
+#: fetchdialog.cpp:196
+#, fuzzy
+msgid "Add the selected entry to the current collection"
+msgstr "Kogusse uue välja lisamine"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr ""
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr ""
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr ""
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr ""
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+#, fuzzy
+msgid "Searching..."
+msgstr "Otsingukoht:"
+
+#: fetchdialog.cpp:368
+#, fuzzy
+msgid "The search returned no items."
+msgstr "Otsitav string"
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+
+#: fetchdialog.cpp:412
+msgid "No results were found for the following ISBN values:"
+msgstr ""
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr ""
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr ""
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr ""
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr ""
+
+#: fetchdialog.cpp:604
+#, fuzzy
+msgid "&Load From File..."
+msgstr "Faili importimine..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr ""
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+#, fuzzy
+msgid "Edit Entry"
+msgstr "Kirje kustutamine"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "Uus kirje"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "Kirje sal&vestamine"
+
+#: entryeditdialog.cpp:77
+#, fuzzy
+msgid "Go to the previous entry in the collection"
+msgstr "Järgmise kattuvuse otsimine kogus"
+
+#: entryeditdialog.cpp:82
+#, fuzzy
+msgid "Go to the next entry in the collection"
+msgstr "Need on selle kogu valitud väljad."
+
+#: entryeditdialog.cpp:315
+#, fuzzy
+msgid "Do you really want to modify these entries?"
+msgstr "Kas oled kindel oma soovis kustutada need kirjed?"
+
+#: entryeditdialog.cpp:317
+#, fuzzy
+msgid "Modify Multiple Entries"
+msgstr "Muuta mitme raamatu kirjeid?"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr ""
+
+#: entryeditdialog.cpp:456
+#, fuzzy
+msgid "Edit Entries"
+msgstr "Kirje kustutamine"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "Kirjete sal&vestamine"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"Kõnealust kirjet on muudetud.\n"
+"Kas soovid tehtud muudatused sisestada?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Kirje salvestamine"
+
+#: reportdialog.cpp:53
+#, fuzzy
+msgid "Collection Report"
+msgstr "Kollektsiooni tööriistariba"
+
+#: reportdialog.cpp:60
+#, fuzzy
+msgid "&Report template:"
+msgstr "Bibtexml andmete importimine"
+
+#: reportdialog.cpp:83
+#, fuzzy
+msgid "&Generate"
+msgstr "Üldine"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr ""
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+
+#: tellico_kernel.cpp:285
+#, fuzzy
+msgid "Do you really want to delete this filter?"
+msgstr "Kas oled kindel oma soovis kustutada need kirjed?"
+
+#: tellico_kernel.cpp:287
+#, fuzzy
+msgid "Delete Filter?"
+msgstr "Kustutada väli?"
+
+#: tellico_kernel.cpp:323
+#, fuzzy
+msgid "New collection name:"
+msgstr "Uue kogu nimi"
+
+#: tellico_kernel.cpp:377
+#, fuzzy
+msgid "Entry 1"
+msgstr "Kirje tüüp"
+
+#: tellico_kernel.cpp:378
+#, fuzzy
+msgid "Entry 2"
+msgstr "Kirje tüüp"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr ""
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+#, fuzzy
+msgid "Merge Entries"
+msgstr "Välja kustutamine"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr ""
+
+#: entryview.cpp:186
+#, fuzzy
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico-l ei õnnestu laadida faili '%1'."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Uus"
+
+#: rc.cpp:15
+#, fuzzy, no-c-format
+msgid "&Collection"
+msgstr "&Uus kollektsioon"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Kollektsiooni tööriistariba"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr ""
+"_: NAME OF TRANSLATORS\n"
+"Teele & Toomas Nigola "
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr ""
+"_: EMAIL OF TRANSLATORS\n"
+"tnigola@eelk.ee"
+
+#: entrymerger.cpp:35
+#, fuzzy
+msgid "Merging entries..."
+msgstr "Kirje kustutamine"
+
+#: entrymerger.cpp:49
+#, fuzzy
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Kirjete sal&vestamine"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>... et kui raamatul on rohkem kui üks autor, tuleks nende\n"
+"nimed üksteisest eraldada semikooloniga, nii et Tellico\n"
+"teaks neid eraldada ja kasutada erinevate nimedena?</p>\n"
+"<p>Iga muu mitut väärtust võimaldava väljaga tuleks\n"
+"käituda täpselt samuti.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>...et saad muuta nimekirjas näidatavaid välju tehes hiire\n"
+"parema klahviga klõpsu tulba pealdisel?\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>... et saad lisada ja muuta kollektsioon välju kasutades\n"
+"väljaredaktorit? Nooltega nupud väljade nimekirja all võimaldavad\n"
+"muuta väljade asetust nimekirjas, mis omakorda mõjutab kirje\n"
+"paiknemist redaktoris.</p>\n"
+
+#: tips.cpp:23
+#, fuzzy
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>... et kui soovid filtreerida märkeruudu välja järgi,\n"
+"tuleks kasutada väärtust \"tõene\". Kui soovid näiteks kuvada\n"
+"ainult veel lugemata ulmeraamatud, märgi <em>\"Vasta kõigele\n"
+"järgnevale\"</em> nupp, vali esimeseks reegliks \"žanr\" \"sisaldab\"\n"
+"\"Ulme\" (jutumärkideta) ja teiseks reegliks \"Loetud\" \"ei sisalda\"\n"
+" \"tõene\" (jutumärkideta).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>... et kui kiirfiltris kasutada mitte sõna, vaid suvalist tähemärki,\n"
+"koheldakse seda kui regulaaravaldist.</p>\n"
+"<p>Kuvamaks näiteks ainult Weber'i või Bujold'i raamatuid, trüki "
+"\"weber|bujold\"\n"
+"(jutumärkideta) filtriboksi.</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>... et saad redigeerida korraga rohkem kui ühte kirjet. Selleks\n"
+"hoia all Shift või Ctrl klahvi ning vali kirjed, mida soovid muuta.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>... et saad teisendada olemasoleva raamatukollektsiooni bibliograafiaks,\n"
+"mida omakorda on võimalik eksportida Bibtex või Bibtexml vormingusse.</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>... et saad lisada, redigeerida ja kustutada bibliograafiate "
+"srtingimakrosid.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>... et juhul, kui rohkem kui üks väli on vormindatud kui \"nimi\", "
+"lisatakse kogusse\n"
+"uus grupp nimega \"Inimesed\". Seeläbi on võimalik näiteks autoreid ja "
+"redigeerijaid\n"
+"sorteerida või printida koos jne.</p>\n"
+
+#: tips.cpp:60
+#, fuzzy
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>... et saad muuta prinditu väljanägemist , muutes faili "
+"<tt>tellico-printing.xsl</tt>.\n"
+"</p>\n"
+
+#: tips.cpp:66
+#, fuzzy
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>... et saad importida ja eksportida kasutades tavalist XSL stiililehte, "
+"mille väljundiks\n"
+"on tavaline Tellico XML fail.</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr ""
+
+#: xslt.cpp:3
+#, fuzzy
+msgid "This template is meant for music collections only."
+msgstr "Uue muusikakogu loomine"
+
+#: xslt.cpp:5
+#, fuzzy
+msgid "Total:"
+msgstr "%1 kokku"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr ""
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr ""
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr ""
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr ""
+
+#: xslt.cpp:14 xslt.cpp:43
+#, fuzzy
+msgid "This template is meant for video collections only."
+msgstr "Uue videokogu loomine"
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr ""
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ""
+
+#: xslt.cpp:18
+#, fuzzy
+msgid "Total number of fields:"
+msgstr "Kirjete sal&vestamine"
+
+#: xslt.cpp:19
+#, fuzzy
+msgid "Total number of entries:"
+msgstr "Kirjete sal&vestamine"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+#, fuzzy
+msgid "Generated by Tellico"
+msgstr "Üldine"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr ""
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr ""
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr ""
+
+#: xslt.cpp:27 xslt.cpp:29
+#, fuzzy
+msgid "Loan Date"
+msgstr "Valikudialoog"
+
+#: xslt.cpp:28 xslt.cpp:31
+#, fuzzy
+msgid "Note"
+msgstr "Märkused"
+
+#: xslt.cpp:30
+#, fuzzy
+msgid "Due Date"
+msgstr "Ostmise aeg"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr ""
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr ""
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr ""
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr ""
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr ""
+
+#: xslt.cpp:44
+#, fuzzy
+msgid "Search"
+msgstr "Otsingukoht:"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr ""
+
+#: z3950.cpp:6
+#, fuzzy
+msgid "Sudoc (France)"
+msgstr "Rajad"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr ""
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr ""
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr ""
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr ""
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr ""
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr ""
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr ""
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr ""
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr ""
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr ""
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr ""
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr ""
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr ""
+
+#, fuzzy
+#~ msgid "CrossRef"
+#~ msgstr "Ristviide"
+
+#, fuzzy
+#~ msgid "GCstar"
+#~ msgstr "Osatäitjad"
+
+#, fuzzy
+#~ msgid "Griffith"
+#~ msgstr "Kingitus"
+
+#, fuzzy
+#~ msgid "Referencer"
+#~ msgstr "Ristviide"
+
+#, fuzzy
+#~ msgid "Comics"
+#~ msgstr "sisaldab"
+
+#, fuzzy
+#~ msgid "Coins"
+#~ msgstr "sisaldab"
+
+#~ msgid "Books"
+#~ msgstr "Raamatud"
+
+#, fuzzy
+#~ msgid "Wines"
+#~ msgstr "Minu Videod"
+
+#~ msgid "Videos"
+#~ msgstr "Videod"
+
+#, fuzzy
+#~ msgid "Games"
+#~ msgstr "Number"
+
+#, fuzzy
+#~ msgid "Cards"
+#~ msgstr "Osatäitjad"
+
+#~ msgid "Entries"
+#~ msgstr "Kirjed"
+
+#~ msgid "Albums"
+#~ msgstr "Albumid"
+
+#, fuzzy
+#~ msgid "Copac"
+#~ msgstr "Koma"
+
+#~ msgid "Tellico"
+#~ msgstr "Tellico"
+
+#, fuzzy
+#~ msgid "&Copy Entry"
+#~ msgstr "Uus kirje"
+
+#, fuzzy
+#~ msgid "&Copy Entries"
+#~ msgstr "Uus kirje"
+
+#, fuzzy
+#~ msgid "Scanning CDDB cache files..."
+#~ msgstr "Faili salvestamine..."
+
+#, fuzzy
+#~ msgid "Collection &type: "
+#~ msgstr "Kogu tüüp:"
+
+#, fuzzy
+#~ msgid "Save Entries"
+#~ msgstr "Kirjete sal&vestamine"
+
+#, fuzzy
+#~ msgid ""
+#~ "_: Save (Entry Title)\n"
+#~ "Save %1"
+#~ msgstr "Välja kustutamine"
+
+#~ msgid "Enable/disable the statusbar"
+#~ msgstr "Olekuriba lubamine/keelamine"
+
+#, fuzzy
+#~ msgid "Reading files..."
+#~ msgstr "Faili salvestamine..."
+
+#~ msgid ""
+#~ "<p>...that you can rename a collection by right-clicking on\n"
+#~ "the top collection item in the left column.</p>\n"
+#~ msgstr ""
+#~ "<p>... et saad kollektsiooni nime muuta tehes\n"
+#~ "hiire parema klahviga klõpsu kollektsiooni ülemise nimetuse vasakul "
+#~ "tulbal?</p>\n"
+
+#, fuzzy
+#~ msgid "S&earch:"
+#~ msgstr "Otsingukoht:"
+
+#, fuzzy
+#~ msgid "Group by:"
+#~ msgstr "Grupeerimise alus:"
+
+#, fuzzy
+#~ msgid "Quick filter:"
+#~ msgstr "Kiirfilter"
+
+#~ msgid "Filter Entry"
+#~ msgstr "Kirje kustutamine"
+
+#, fuzzy
+#~ msgid "Tellico: %1 is due to return %2"
+#~ msgstr "Tellico-l ei õnnestu lugeda faili '%1'."
+
+#~ msgid "Find Text"
+#~ msgstr "Teksti leidmine"
+
+#~ msgid "&Find"
+#~ msgstr "Otsimine"
+
+#, fuzzy
+#~ msgid "Find"
+#~ msgstr "Otsimine"
+
+#, fuzzy
+#~ msgid "&Text to find:"
+#~ msgstr "Otsitav tekst:"
+
+#~ msgid "The search string"
+#~ msgstr "Otsitav string"
+
+#, fuzzy
+#~ msgid "As regular e&xpression"
+#~ msgstr "Regulaaravaldisena"
+
+#~ msgid "If checked, the search string is used as a regular expression."
+#~ msgstr ""
+#~ "Selle ruudu märkimisel vaadeldakse otsitavat stringi regulaaravaldisena."
+
+#, fuzzy
+#~ msgid "&Edit Regular Expression..."
+#~ msgstr "Regulaaravaldise muutmine"
+
+#, fuzzy
+#~ msgid "Field"
+#~ msgstr "Väljad"
+
+#, fuzzy
+#~ msgid "Search in:"
+#~ msgstr "Otsingukoht:"
+
+#~ msgid "Select which field should be searched."
+#~ msgstr "Otsitakse järgnevast väljast:"
+
+#, fuzzy
+#~ msgid "C&ase sensitive"
+#~ msgstr "Tõ&stutundlik"
+
+#~ msgid "If checked, the search is case-sensitive."
+#~ msgstr ""
+#~ "Selle ruudu märkimisel omavad otsingul tähtsust suur- ja väiketähtede "
+#~ "erinevused."
+
+#, fuzzy
+#~ msgid "Find &backwards"
+#~ msgstr "&Tagurpidiotsing"
+
+#~ msgid "If checked, the document is searched in reverse."
+#~ msgstr ""
+#~ "Selle ruudu märkimisel otsitakse dokumendist kirjeid tagant ettepoole."
+
+#, fuzzy
+#~ msgid "&Whole words only"
+#~ msgstr "Ainult terved sõnad"
+
+#~ msgid "If checked, the search is limited to whole words."
+#~ msgstr ""
+#~ "Selle ruudu märkimisel otsitakse ainult täissõnu (mitte lihtsalt "
+#~ "tähemärkide järgnevust)."
+
+#~ msgid "All Fields"
+#~ msgstr "Kõik väljad"
+
+#~ msgid "Invalid regular expression."
+#~ msgstr "Vigane regulaaravaldis"
+
+#~ msgid "5 - Best"
+#~ msgstr "5 - Parim"
+
+#~ msgid "4 - Good"
+#~ msgstr "4 - Hea"
+
+#~ msgid "3 - Neutral"
+#~ msgstr "3 - Neutraalne"
+
+#~ msgid "2 - Bad"
+#~ msgstr "2 - Vilets"
+
+#~ msgid "1 - Worst"
+#~ msgstr "1 - Viletsaim"
+
+#~ msgid "Table (2 Columns)"
+#~ msgstr "Tabel (kaks tulpa)"
+
+#, fuzzy
+#~ msgid "Delete Entry?"
+#~ msgstr "V&älja kustutamine"
+
+#~ msgid "Warning!"
+#~ msgstr "Tähelepanu!"
+
+#~ msgid "(grouped by %1; sorted by %2)"
+#~ msgstr "(grupeeritud %1 järgi; sorteeritud %2 järgi)"
+
+#~ msgid "(sorted by %1)"
+#~ msgstr "(sorteeritud %1 järgi)"
+
+#~ msgid ""
+#~ "<qt><p>Do you really want to delete the <em>%1</em> field? This action "
+#~ "occurs immediately and can not be undone!</p></qt>"
+#~ msgstr ""
+#~ "<qt><p>Kas oled kindel oma otsuses kustutada väli nimega <em>%1</em>? Selle "
+#~ "teo tulemused avalduvad otsekohe ja neid pole enam võimalik olematuks "
+#~ "teha!</p></qt>"
+
+#~ msgid "Search the collection"
+#~ msgstr "Kogu otsing"
+
+#~ msgid "Find next match in the collection"
+#~ msgstr "Järgmise kattuvuse otsimine kogus"
+
+#, fuzzy
+#~ msgid "Reports"
+#~ msgstr "&Eksportimine"
+
+#~ msgid "Show number of items in group"
+#~ msgstr "Gruppi kuuluvate nimetuste arvu näitamine"
+
+#~ msgid "Search string '%1' not found."
+#~ msgstr "Otsitavat sõna (\"%1\") ei leidunud."
+
+#, fuzzy
+#~ msgid "Video"
+#~ msgstr "Videod"
+
+#~ msgid "&From Beginning"
+#~ msgstr "&Algusest"
+
+#~ msgid "If checked, the document is searched from the beginning."
+#~ msgstr ""
+#~ "Selle ruudu märkimisel otsitakse dokumendist kirjeid eest tahapoole."
+
+#~ msgid "Do you really want to modify these books?"
+#~ msgstr "Kas oled kindel oma soovis muuta nende raamatute kirjeid?"
+
+#, fuzzy
+#~ msgid "<qt>Tellico was unable to open the CD-ROM device - <i>%1</i>.</qt>"
+#~ msgstr "Tellico-l ei õnnestu kirjutada faili '%1'."
+
+#, fuzzy
+#~ msgid "*.ogg|Ogg files (*.ogg)"
+#~ msgstr "*.xml|XML failid (*.xml)"
+
+#, fuzzy
+#~ msgid ""
+#~ "<qt>The type of the field determines what values may be used. <i>Simple "
+#~ "Text</i> is used for most fields. <i>Paragraph</i> is for large text blocks. "
+#~ "<i>Choice</i> limits the field to certain values. <i>Checkbox</i> is for a "
+#~ "simple yes/no value. <i>Number</i> indicates that the field contains a "
+#~ "numerical value. <i>URL</i> is for fields which refer to URLs, including "
+#~ "references to other files. <i>Table</i>s may be a single or double column of "
+#~ "values, while <i>Read Only</i> is for internal values, possibly useful for "
+#~ "import and export. A <i>Dependent</i> field depends on the values of other "
+#~ "fields, and is formatted according to the field description. An <i>Image</i> "
+#~ "holds a picture.</qt>"
+#~ msgstr ""
+#~ "<qt>Välja tüübist sõltub, milliseid väärtusi on võimalik "
+#~ "kasutada.<i>Tavaline tekst</i> on sobilik enamiku väljade jaoks. "
+#~ "<i>Lõik</i> on suuremate tekstilõikude tarvis. <i>Nimekiri</i> lubab "
+#~ "väljale omistada vaid teatud väärtusi. </i>Märkeruut</i> on "
+#~ "tarvitamiseks lihtsa 'jah/ei' valiku puhul. </i>Number</i> näitab, et väli "
+#~ "sisaldab numbrilist väärtust. <i>URL</i> on URL-idele (sh teistele "
+#~ "failidele) viitavate väljade tarbeks. <i>Tabel</i>id võivad koosneda "
+#~ "ühest või kahest väärtustetulbast. </i>Ainult lugemiseks</i> on hea "
+#~ "tüüp väljale, mida tahetakse kasutada muutumatute väärtuste "
+#~ "märkimiseks (kasulik ehk andmete importimisel-eksportimisel).</qt>"
+
+#, fuzzy
+#~ msgid "Data Type:"
+#~ msgstr "Tüüp:"
+
+#, fuzzy
+#~ msgid "Export images"
+#~ msgstr "Eksport "
+
+#~ msgid ""
+#~ "The description is useful reminder of what information is contained in the "
+#~ "field."
+#~ msgstr "Kirjeldus on kasulik meenutamaks, mis infot väli õieti sisaldab."
+
+#~ msgid "Bibtex Field Name:"
+#~ msgstr "Bibtex-i väljanimi:"
+
+#~ msgid ""
+#~ "The Bibtex field name determines the entry name for exporting to "
+#~ "bibliogrgaphy files."
+#~ msgstr ""
+#~ "Bibtex-i väljanimi määrab sisestise nime eksportimiseks "
+#~ "bibliograafiafailidesse."
+
+#~ msgid "List"
+#~ msgstr "Nimekiri"
+
+#~ msgid "(Requires restart)"
+#~ msgstr "(Nõuab taaskäivitamist)"
+
+#~ msgid ""
+#~ "A comma-separated list of suffixes which might be used in personal names."
+#~ msgstr ""
+#~ "Komadega eraldatud nimekiri sufiksitest, mida võidakse kasutada "
+#~ "isikunimedes."
+
+#~ msgid "A comma-separated list of prefixes which might be used in surnames."
+#~ msgstr ""
+#~ "Komadega eraldatud nimekiri prefiksitest, mida võidakse kasutada "
+#~ "perekonnanimedes."
+
+#~ msgid "Enable/disable the toolbar"
+#~ msgstr "Tööriistariba lubamine/keelamine"
+
+#~ msgid "Show Co&llection ToolBar"
+#~ msgstr "Kogu t&ööriistariba näitamine"
+
+#~ msgid "Enable/disable the collection toolbar"
+#~ msgstr "Kogu tööriistariba lubamine/keelamine"
+
+#~ msgid "Tip of the &Day"
+#~ msgstr "P&äeva nipp"
+
+#~ msgid "Show the \"Tip of the Day\" dialog..."
+#~ msgstr "\"Päeva nipi\" näitamine..."
+
+#~ msgid "Toggling toolbar..."
+#~ msgstr "Tööriistariba lülitamine"
+
+#~ msgid "Toggling collection toolbar..."
+#~ msgstr "Kogu tööriistariba lülitamine"
+
+#~ msgid "Toggle the statusbar..."
+#~ msgstr "Olekuriba lülitamine"
+
+#~ msgid "Tellico is unable to find a required file - %1.\n"
+#~ msgstr "Tellico ei suuda leida vajalikku faili - %1.\n"
+
+#~ msgid "Editing string macros..."
+#~ msgstr "Makrote muutmine..."
+
+#~ msgid ""
+#~ "Both the macro and the string can be edited by triple-clicking the item."
+#~ msgstr ""
+#~ "Nii makrot kui stringi saab muuta tehes selle peal kolmekordse hiireklõpsu."
+
+#~ msgid "XSLTImporter"
+#~ msgstr "XSLTImporter"
+
+#~ msgid "CSVImporter"
+#~ msgstr "CSVImporter"
+
+#~ msgid "TextImporter"
+#~ msgstr "Importija"
+
+#~ msgid "BibtexImporter"
+#~ msgstr "BibtexImporter"
+
+#~ msgid "BibtexmlImporter"
+#~ msgstr "BibtexmlImporter"
+
+#~ msgid ""
+#~ "An article is from a journal or magazine. A book has an explicit publisher, "
+#~ "while a booklet does not."
+#~ msgstr ""
+#~ "Artikkel pärineb žurnaalist või ajakirjast. Raamatul on konkreetne "
+#~ "kirjastaja, bukletil ei pruugi olla."
+
+#~ msgid "MusicCollection"
+#~ msgstr "Muusikakogu"
+
+#~ msgid "BibtexCollection"
+#~ msgstr "BibtexCollection"
+
+#~ msgid "BookCollection"
+#~ msgstr "Raamatukogu"
+
+#~ msgid "VideoCollection"
+#~ msgstr "Videokogu"
+
+#~ msgid "BCLabelAction"
+#~ msgstr "BCLabelAction"
+
+#~ msgid "TellicoDoc"
+#~ msgstr "TellicoDoc"
+
+#~ msgid "FindDialog"
+#~ msgstr "Otsingudialoog"
+
+#~ msgid "BCImportDialog"
+#~ msgstr "BCImpordidialoog"
+
+#~ msgid "StringMacroDialog"
+#~ msgstr "StringiMakroDialoog"
+
+#, fuzzy
+#~ msgid "Processing new entries..."
+#~ msgstr "Dokumendi töötlemine..."
+
+#, fuzzy
+#~ msgid "If checked, the first row is used as field headers."
+#~ msgstr ""
+#~ "Selle ruudu märkimisel väljade nimed prinditakse tabeli päistena."
+
+#, fuzzy
+#~ msgid "Collection Field in this Column:"
+#~ msgstr "Kogu kirjed"
+
+#~ msgid "Tellico is unable to find the file - %1."
+#~ msgstr "Tellico-l ei õnnestu leida faili %1."
+
+#~ msgid "Tellico is unable to download the file - %1."
+#~ msgstr "Tellico-l ei õnnestu alla laadida faili %1."
+
+#~ msgid "Edit Collection Fields"
+#~ msgstr "Kogu väljade muutmine"
+
+#~ msgid "The fields are grouped by common categories for editing."
+#~ msgstr "Väljad grupeeritakse muutmiseks ühiste kategooriatena."
+
+#~ msgid "The collection is grouped by this field."
+#~ msgstr "Kogu grupeeritakse selle välja järgi."
+
+#~ msgid "These are the available fields in the collection."
+#~ msgstr "Need on selles kogus saadavalolevad väljad."
+
+#~ msgid "Selected Fields"
+#~ msgstr "Valitud väljad"
+
+#, fuzzy
+#~ msgid "Import..."
+#~ msgstr "Eksportimine"
+
+#, fuzzy
+#~ msgid "Read Only"
+#~ msgstr "Valmis!"
+
+#, fuzzy
+#~ msgid "Text"
+#~ msgstr "Teksti leidmine"
+
+#, fuzzy
+#~ msgid "Enoding Options"
+#~ msgstr "Grupeerimise valikud"
+
+#~ msgid "Edit Collection Fields..."
+#~ msgstr "Kogu väljade redigeerimine"
+
+#, fuzzy
+#~ msgid "&Create new collection"
+#~ msgstr "Uue dokumendi loomine"
+
+#, fuzzy
+#~ msgid "*.txt|Text files (*.txt)"
+#~ msgstr "*.xsl|XSLT failid (*.xsl)"
+
+#~ msgid "New Book"
+#~ msgstr "Uus raamat"
+
+#~ msgid "Modify Books"
+#~ msgstr "Raamatute kirjete muutmine"
+
+#~ msgid "Delete Books"
+#~ msgstr "Raamatute kustutamine"
+
+#~ msgid "Lookup book..."
+#~ msgstr "Raamatu otsimine"
+
+#~ msgid "Group Books By"
+#~ msgstr "Raamatute grupeerimise alus:"
+
+#~ msgid "Configure the options for the application..."
+#~ msgstr "Rakenduse suvandite määramine"
+
+#~ msgid "Save as..."
+#~ msgstr "Salvesta nimega..."
+
+#~ msgid "Importing from Bibtex..."
+#~ msgstr "Bibtexist importimine..."
+
+#~ msgid "Import from Bibtex..."
+#~ msgstr "Bibtexist importimine"
+
+#~ msgid "Importing from Bibtexml..."
+#~ msgstr "Bibtexmlist importimine..."
+
+#~ msgid "Song"
+#~ msgstr "Laul"
+
+#~ msgid "CD"
+#~ msgstr "CD"
diff --git a/po/en_GB.po b/po/en_GB.po
new file mode 100644
index 0000000..8ae1aeb
--- /dev/null
+++ b/po/en_GB.po
@@ -0,0 +1,5243 @@
+# English (British) translation.
+# Abigail Brady <morwen@evilmagic.org>, Bastien Nocera <hadess@hadess.net>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2008-05-24 08:15-0700\n"
+"Last-Translator: Abigail Brady <morwen@evilmagic.org>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr "Connecting to OpenOffice.org..."
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr "OpenOffice.org Connection"
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr "Pipe"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr "TCP/IP"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr "Rename Column"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr "New column name:"
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr "Column %1"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr "Rename Column..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr "Insert Row"
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr "Remove Row"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr "Move Row Up"
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr "Move Row Down"
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr "Clear Table"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr "Template Preview"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Set"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr ""
+"%1:"
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr ""
+"More"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr ""
+"Fewer"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr ""
+"Clear"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Select Image..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr "Save link only"
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr "Saving a link is only possible for newly added images."
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr ""
+"Modify %1"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Append Collection"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Merge Collection"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Replace Collection"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr "Modify Entries"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "Add %1 Field"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Modify %1 Field"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Delete %1 Field"
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr "Add Entries"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr ""
+"Add %1"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Rename Collection"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Modify Loan"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Add Filter"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Modify Filter"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Delete Filter"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Check-out Items"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr ""
+"Check-out %1"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Delete Entries"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr ""
+"Delete %1"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Reorder Fields"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Check-in Entries"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr ""
+"Check-in %1"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "General"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Condition"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Personal"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "My Stamps"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Title"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Description"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Denomination"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "Country"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Issue Year"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Colour"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Scott#"
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr ""
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Grade"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Cancelled"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Hinged"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Centreing"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Gummed"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Purchase Date"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Purchase Price"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Location"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Gift"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Image"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Comments"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Publishing"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Classification"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "My Comic Books"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Subtitle"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Writer"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr ""
+"Artist"
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Series"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Issue"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Publisher"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Edition"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Publication Year"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Pages"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Language"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Genre"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Keywords"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr ""
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Signed"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Loaned"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Front Cover"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "My Coins"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Type"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Year"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Mint Mark"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Coin Set"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr ""
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Grading Service"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Obverse"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Reverse"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "My Books"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Author"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Hardback"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Paperback"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Trade Paperback"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "E-Book"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Magazine"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Journal"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Binding"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Copyright Year"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN#"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "International Standard Book Number"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN#"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Library of Congress Control Number"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr "Translator"
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Series Number"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "New"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Used"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Read"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Rating"
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr "My Files"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "Name"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Volume"
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr "Folder"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr "Mimetype"
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr "Size"
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr "Permissions"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr "Owner"
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr "Group"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr "Created"
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr "Modified"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr "Meta Info"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Property"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Value"
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr "Icon"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "My Wines"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Producer"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Appellation"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Varietal"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Vintage"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Red Wine"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "White Wine"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Sparkling Wine"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Quantity"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Drink By"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Label Image"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Other People"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Features"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "My Videos"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr "Blu-ray"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+msgid "HD DVD"
+msgstr "HD DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Medium"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Production Year"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr ""
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Certification"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Region 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Region 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Region 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Region 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Region 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Region 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Region 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Region 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Region"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Nationality"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Format"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Cast"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr "Actor/Actress"
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr "Role"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr "A table for the cast members, along with the roles they play"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Director"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Composer"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Studio"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Language Tracks"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Subtitle Languages"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Audio Tracks"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Running Time"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "The running time of the video (in minutes)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Aspect Ratio"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Widescreen"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Black & White"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Colour Mode"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Director's Cut"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Plot Summary"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Personal Rating"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Cover"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "My Games"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr "Xbox 360"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr "PlayStation3"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr ""
+"PSP"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr "Nintendo Wii"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Colour"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr ""
+"Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr "Linux"
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Platform"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Release Year"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr ""
+"Publisher"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Developer"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "ESRB Rating"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Completed"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "My Cards"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Player"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Team"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Brand"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Card Number"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Card Type"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Front Image"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Back Image"
+
+#: collections/boardgamecollection.cpp:26
+msgid "My Board Games"
+msgstr "My Board Games"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr "Mechanism"
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr "Designer"
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr "Number of Players"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Bibliography"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Entry Type"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr "These entry types are specific to bibtex. See the bibtex documentation."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Bibtex Key"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Book Title"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Editor"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organization"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Address"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr "DOI"
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr "Digital Object Identifier"
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Month"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Number"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "How Published"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Chapter"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Cross-Reference"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Abstract"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Notes"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "My Music"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Album"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "Compact Disc"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Cassette"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Vinyl"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Artist"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Label"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Tracks"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr "Length"
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "the"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr.,jr,iii,iv"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,van,der,van der,von"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr "ISBNdb.com"
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 does not allow searching for this collection type."
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Results from %1: %2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "This source has no options."
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "Entrez Database"
+
+#: fetch/entrezfetcher.cpp:485
+msgid "Institution"
+msgstr "Institution"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Query error!"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Connection search error %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Record syntax error"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Connection error %1: %2"
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr "SRU Server"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Library of Congress (US)"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr "Hos&t: "
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr "Enter the host name of the server."
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Port: "
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Enter the port number of the server. The default is %1."
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr "Path: "
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr "Enter the path to the database used by the server."
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr "Format: "
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr "Enter the result format used by the server."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr "Yahoo! Audio Search"
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "The cover image could not be loaded."
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr "Amazon Link"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (US)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (UK)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Germany)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japan)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (France)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Canada)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Amazon.com Web Services"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "Co&untry: "
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "United States"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "United Kingdom"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Germany"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Japan"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "France"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Canada"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "&Image size: "
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Small Image"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Medium Image"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Large Image"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "No Image"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "&Associate's ID: "
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr "z39.50 Server"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr "Use preset &server:"
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "&Database: "
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr "Enter the database name used by the server."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "Ch&aracter set: "
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+
+#: fetch/z3950fetcher.cpp:550
+msgid "&Format: "
+msgstr "&Format: "
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr "Auto-detect"
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "&User: "
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Optional"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "Pass&word: "
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr "Illustrator"
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "External Application"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "Collection &type:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+"Set the collection type of the data returned from the external application."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr "&Result type: "
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr "Set the result type of the data returned from the external application."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "Application &path: "
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr "Select the search keys supported by the data source."
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr "Arguments"
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+msgid "Update"
+msgstr "Update"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Source Options"
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr "Available Fields"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "Internet Movie Database"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Select IMDB Result"
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Select a search result.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr "IMDB Link"
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Alternative Titles"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+msgid "IMDB Rating"
+msgstr "IMDB Rating"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Certifications"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr "&Maximum cast: "
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr "Download cover &image"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr "Internet Bookshop (ibs.it)"
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Person"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr "UPC/EAN"
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Keyword"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr "arXiv ID"
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr "Pubmed ID"
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Raw Query"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr "Original Title"
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr "Distributor"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr "Episodes"
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr "arXiv.org"
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr "%1 requires a username and password."
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+
+#: fetch/crossreffetcher.cpp:343
+msgid "&Username: "
+msgstr "&Username: "
+
+#: fetch/crossreffetcher.cpp:348
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+
+#: fetch/crossreffetcher.cpp:354
+msgid "&Password: "
+msgstr "&Password: "
+
+#: fetch/gcstarpluginfetcher.cpp:190
+msgid "GCstar Plugin"
+msgstr "GCstar Plugin"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr "Set the collection type of the data returned from the plugin."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr "&Plugin: "
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr "Select the GCstar plugin used for the data source."
+
+#: fetch/gcstarpluginfetcher.cpp:420
+msgid "Author: "
+msgstr "Author: "
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr "Discogs Audio Search"
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr "API &key: "
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr "Discogs Link"
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr "Get Hot New Stuff"
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr "Version"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr "Downloads"
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr "Release Date"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+
+#: newstuff/dialog.cpp:137
+msgid "The name and license of the selected item"
+msgstr "The name and licence of the selected item"
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr "The author of the selected item"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr "Install"
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr "Download and install the selected template."
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr "A description of the selected item is shown here."
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr "Downloading information..."
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Ready."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr ""
+"Update"
+
+#: newstuff/dialog.cpp:413
+msgid "Installing item..."
+msgstr "Installing item..."
+
+#: translators/bibteximporter.cpp:79
+msgid "No valid bibtex entries were found"
+msgstr "No valid bibtex entries were found"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "No valid bibtex entries were found in file - %1"
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Bibtex Options"
+
+#: translators/bibteximporter.cpp:287
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Use Unicode (UTF-8) encoding"
+
+#: translators/bibteximporter.cpp:288
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Read the imported file in Unicode (UTF-8)."
+
+#: translators/bibteximporter.cpp:289
+msgid "Use user locale (%1) encoding"
+msgstr "Use user locale (%1) encoding"
+
+#: translators/bibteximporter.cpp:293
+msgid "Read the imported file in the local encoding."
+msgstr "Read the imported file in the local encoding."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "Tellico Zip File"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "Tellico Files (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "All Files"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "There is an XML parsing error in line %1, column %2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "The error message from Qt is:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "It is from a future version of Tellico."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Unknown"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "The file is empty."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "The file contains no collection data."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Unread Books"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Old Movies"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "80's Music"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Favourites"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Scanning audio files..."
+
+#: translators/audiofileimporter.cpp:129
+msgid "Bitrate"
+msgstr "Bitrate"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr "Tracks (Disc %1)"
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(Various)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Audio File Options"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Recursive &folder search"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr "If checked, folders are recursively searched for audio files."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr "Include file &location"
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr "If checked, the file names for each track are added to the entries."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr "Include &bitrate"
+
+#: translators/audiofileimporter.cpp:353
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr "If checked, the bitrate for each track is added to the entries."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "CSV Files (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "CSV Options"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Include field titles as column headers"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr "If checked, a header row will be added with the field titles."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Delimiter"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Comma"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Use a comma as the delimiter."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Semicolon"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Use a semi-colon as the delimiter."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Tab"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Use a tab as the delimiter."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Other"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Use a custom string as the delimiter."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr "A custom string, such as a colon, may be used as a delimiter."
+
+#: translators/filelistingimporter.cpp:63
+msgid "Scanning files..."
+msgstr "Scanning files..."
+
+#: translators/filelistingimporter.cpp:191
+msgid "File Listing Options"
+msgstr "File Listing Options"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr "Recursive folder search"
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr "If checked, folders are recursively searched for all files."
+
+#: translators/filelistingimporter.cpp:198
+msgid "Generate file previews"
+msgstr "Generate file previews"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "ONIX Archive"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "Zip Files (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "ONIX Archive Options"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Include images in archive"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+msgid "Select CDDB Entry"
+msgstr "Select CDDB Entry"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr "Select a CDDB entry:"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>No records were found to match the CD.</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "<qt>Tellico was unable to complete the CD lookup.</qt>"
+
+#: translators/freedbimporter.cpp:470
+msgid "Various"
+msgstr "Various"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Audio CD Options"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Read data from CD-ROM device"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Select or input the CD-ROM device location."
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Read all CDDB cache files only"
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr "GCfilms"
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "GCfilms Data Files (*.gcf)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "GCstar Data Files (*.gcs)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "XSLT Options"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "XSLT file:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr "Choose the XSLT file used to transform the Tellico XML data."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Alexandria Options"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr "&Library:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "Bibtexml"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "Bibtexml Files (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "XML Files (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Tellico XML Options"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Include images in XML document"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+
+#: translators/importer.h:100
+msgid "Loading data..."
+msgstr "Loading data..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr "Loading %1..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "Bibtex"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "Bibtex Files (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Expand string macros"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Use URL package"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr "If checked, any URL fields will be wrapped in a \\url declaration."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Skip entries with empty citation keys"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr "If checked, any entries without a bibtex citation key will be skipped."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Bibtex quotation style:"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Braces"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Quotes"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Select the type of collection being imported."
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr "&First row contains field titles"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr "If checked, the first row is used as field titles."
+
+#: translators/csvimporter.cpp:248
+msgid "&Comma"
+msgstr "&Comma"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr "&Semicolon"
+
+#: translators/csvimporter.cpp:259
+msgid "Ta&b"
+msgstr "Ta&b"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr "Ot&her:"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "The table shows up to the first five lines of the CSV file."
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+
+#: translators/csvimporter.cpp:298
+msgid "Co&lumn:"
+msgstr "Co&lumn:"
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr "&Data field in this column:"
+
+#: translators/csvimporter.cpp:315
+msgid "&Assign Field"
+msgstr "&Assign Field"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "New Field"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "Pilot Database Files (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "View Columns"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "PilotDB Options"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Set PDA backup flag for database"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>The file is not a valid GCstar data file.</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Tellico encountered an error in XSLT processing."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "A valid XSLT file is needed to import the file."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "XSL Files (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "HTML Files (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "People"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(grouped by %1)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "HTML Options"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Print field headers"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr "If checked, the field names will be printed as table headers."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Group the entries"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr "If checked, the entries will be grouped by the selected field."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Export individual entry files"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr "If checked, individual files will be created for each entry."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico was unable to read any metadata from the PDF file."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Data Source Properties"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "&Source name: "
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr ""
+"The name identifies the data source and should be unique and informative."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "Source &type: "
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr "Tellico supports several different data sources."
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr "Updating from source should overwrite user data"
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr "If checked, updating entries will overwrite any existing information."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Any Field"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "contains"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "does not contain"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "equals"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "does not equal"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "matches regexp"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "does not match regexp"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Edit..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Advanced Filter"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Filter Criteria"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Match a&ll of the following"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Match an&y of the following"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Filter name:"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "&Save Filter"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Simple Text"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Paragraph"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Choice"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Checkbox"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Table"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Dependent"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Date"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr "Updating %1..."
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr "Updating entries..."
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr "Update Entries"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr "Updating <b>%1</b>..."
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr "Select Match"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Expand All Groups"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Collapse All Groups"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Filter by Group"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (Sort by Count)"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr ""
+"Group"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Import Options"
+
+#: importdialog.cpp:62
+msgid "&Replace current collection"
+msgstr "&Replace current collection"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr "Replace the current collection with the contents of the imported file."
+
+#: importdialog.cpp:65
+msgid "A&ppend to current collection"
+msgstr "A&ppend to current collection"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+
+#: importdialog.cpp:69
+msgid "&Merge with current collection"
+msgstr "&Merge with current collection"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Import"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "RIS Files (*.ris)"
+
+#: importdialog.cpp:277
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "AMC Data Files (*.amc)"
+
+#: importdialog.cpp:281
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "PDF Files (*.pdf)"
+
+#: importdialog.cpp:285
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "Referencer Files (*.reflib)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico is unable to load the file - %1."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico is unable to write the file - %1."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico is unable to upload the file - %1."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico is unable to load an image from the file - %1."
+
+#: entryiconview.cpp:287
+msgid "&Sort By"
+msgstr "&Sort By"
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Loan Dialogue"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "The following items are being checked out:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "The following item is on-loan:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "&Lend to:"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "&Loan date:"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "D&ue date:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Note:"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "You can add notes about the loan, as well."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "&Add a reminder to the active calendar"
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Create a new collection"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "New &Book Collection"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Create a new book collection"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "New B&ibliography"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Create a new bibtex bibliography"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "New &Comic Book Collection"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Create a new comic book collection"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "New &Video Collection"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Create a new video collection"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "New &Music Collection"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Create a new music collection"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "New C&oin Collection"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Create a new coin collection"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "New &Stamp Collection"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Create a new stamp collection"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "New C&ard Collection"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Create a new trading card collection"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "New &Wine Collection"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Create a new wine collection"
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "New &Game Collection"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Create a new game collection"
+
+#: mainwindow.cpp:272
+msgid "New Boa&rd Game Collection"
+msgstr "New Boa&rd Game Collection"
+
+#: mainwindow.cpp:274
+msgid "Create a new board game collection"
+msgstr "Create a new board game collection"
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr "New &File Catalogue"
+
+#: mainwindow.cpp:282
+msgid "Create a new file catalog"
+msgstr "Create a new file catalogue"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "New C&ustom Collection"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Create a new custom collection"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Open an existing document"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Open a recently used file"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Save the document"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Save the document as a different file..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Print the contents of the document..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Quit the application"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Import collection data from other formats"
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Import Tellico Data..."
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Import another Tellico data file"
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "Import CSV Data..."
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Import a CSV file"
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "Import MODS Data..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Import a MODS data file"
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Import Alexandria Data..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Import data from the Alexandria book collection manager"
+
+#: mainwindow.cpp:352
+msgid "Import Delicious Library Data..."
+msgstr "Import Delicious Library Data..."
+
+#: mainwindow.cpp:353
+msgid "Import data from Delicious Library"
+msgstr "Import data from Delicious Library"
+
+#: mainwindow.cpp:359
+msgid "Import Referencer Data..."
+msgstr "Import Referencer Data..."
+
+#: mainwindow.cpp:360
+msgid "Import data from Referencer"
+msgstr "Import data from Referencer"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Import Bibtex Data..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Import a bibtex bibliography file"
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Import Bibtexml Data..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Import a Bibtexml bibliography file"
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "Import RIS Data..."
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Import an RIS reference file"
+
+#: mainwindow.cpp:387
+msgid "Import PDF File..."
+msgstr "Import PDF File..."
+
+#: mainwindow.cpp:388
+msgid "Import a PDF file"
+msgstr "Import a PDF file"
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Import Audio File Metadata..."
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Import meta-data from audio files"
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Import Audio CD Data..."
+
+#: mainwindow.cpp:405
+msgid "Import audio CD information"
+msgstr "Import audio CD information"
+
+#: mainwindow.cpp:414
+msgid "Import GCstar Data..."
+msgstr "Import GCstar Data..."
+
+#: mainwindow.cpp:415
+msgid "Import a GCstar data file"
+msgstr "Import a GCstar data file"
+
+#: mainwindow.cpp:421
+msgid "Import Griffith Data..."
+msgstr "Import Griffith Data..."
+
+#: mainwindow.cpp:422
+msgid "Import a Griffith database"
+msgstr "Import a Griffith database"
+
+#: mainwindow.cpp:428
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Import Ant Movie Catalogue Data..."
+
+#: mainwindow.cpp:429
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Import an Ant Movie Catalogue data file"
+
+#: mainwindow.cpp:435
+msgid "Import File Listing..."
+msgstr "Import File Listing..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr "Import information about files in a folder"
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "Import XSL Transform..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Import using an XSL Transform"
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Export"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Export the collection data to other formats"
+
+#: mainwindow.cpp:461
+msgid "Export to XML..."
+msgstr "Export to XML..."
+
+#: mainwindow.cpp:462
+msgid "Export to a Tellico XML file"
+msgstr "Export to a Tellico XML file"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Export to Zip..."
+
+#: mainwindow.cpp:469
+msgid "Export to a Tellico Zip file"
+msgstr "Export to a Tellico Zip file"
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "Export to HTML..."
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Export to an HTML file"
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "Export to CSV..."
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Export to a comma-separated values file"
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "Export to PilotDB..."
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Export to a PilotDB database"
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Export to Alexandria..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Export to an Alexandria library"
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Export to Bibtex..."
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Export to a bibtex file"
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Export to Bibtexml..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Export to a Bibtexml file"
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "Export to ONIX..."
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Export to an ONIX file"
+
+#: mainwindow.cpp:524
+msgid "Export to GCfilms..."
+msgstr "Export to GCfilms..."
+
+#: mainwindow.cpp:525
+msgid "Export to a GCfilms data file"
+msgstr "Export to a GCfilms data file"
+
+#: mainwindow.cpp:531
+msgid "Export to GCstar..."
+msgstr "Export to GCstar..."
+
+#: mainwindow.cpp:532
+msgid "Export to a GCstar data file"
+msgstr "Export to a GCstar data file"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "Export XSL Transform..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Export using an XSL Transform"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Cut the selected text and puts it in the clipboard"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Copy the selected text to the clipboard"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Paste the clipboard contents"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Select all the entries in the collection"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Deselect all the entries in the collection"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Internet Search..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Search the internet..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "Advanced &Filter..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Filter the collection"
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&New Entry..."
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Create a new entry"
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "&Edit Entry..."
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Edit the selected entries"
+
+#: controller.cpp:621 mainwindow.cpp:577
+msgid "D&uplicate Entry"
+msgstr "D&uplicate Entry"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Copy the selected entries"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "&Delete Entry"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Delete the selected entries"
+
+#: mainwindow.cpp:585
+msgid "&Merge Entries"
+msgstr "&Merge Entries"
+
+#: mainwindow.cpp:588
+msgid "Merge the selected entries"
+msgstr "Merge the selected entries"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "&Generate Reports..."
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Generate collection reports"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "Check-&out..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Check-out the selected items"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "Check-&in"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Check-in the selected items"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "&Rename Collection..."
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Rename the collection"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "Collection &Fields..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Modify the collection fields"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "Convert to &Bibliography"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Convert a book collection to a bibliography"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "String &Macros..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Edit the bibtex string macros"
+
+#: mainwindow.cpp:626
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Copy Bibtex to Cli&pboard"
+
+#: mainwindow.cpp:627
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Copy bibtex citations to the clipboard"
+
+#: mainwindow.cpp:632
+msgid "Cite Entry in &LyX"
+msgstr "Cite Entry in &LyX"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Cite the selected entries in LyX"
+
+#: mainwindow.cpp:638
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Ci&te Entry in OpenOffice.org"
+
+#: mainwindow.cpp:639
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Cite the selected entries in OpenOffice.org"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, no-c-format
+msgid "&Update Entry"
+msgstr "&Update Entry"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr "All Sources"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr "Update entry data from all available sources"
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Show Grou&p View"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Enable/disable the group view"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Hide Grou&p View"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Show Entry &Editor"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Enable/disable the editor"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "Hide Entry &Editor"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Show Entry &View"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Enable/disable the entry view"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "Hide Entry &View"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Change Grouping"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "&Group Selection"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Change the grouping of the collection"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Filter"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Clear Filter"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Filter here..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Groups"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+
+#: mainwindow.cpp:831
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Welcome to the Tellico Collection Manager"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalogue.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Creating new document..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Opening file..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Open File"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Saving file..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialogue.</p></qt>"
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr "Save Images Separately"
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr "Save Images in File"
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Saving file with a new filename..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Printing..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Processing document..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Exiting..."
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Total entries: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 filtered; %2 selected)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 filtered)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 selected)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Print %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Page %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Please check your installation."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Importing data..."
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Import File"
+
+#: mainwindow.cpp:1864
+msgid "Import Directory"
+msgstr "Import Directory"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Exporting data..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Export As"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "String Macros"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Macro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "String"
+
+#: mainwindow.cpp:1999
+msgid "Creating citations..."
+msgstr "Creating citations..."
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Filters"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Loans"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr "Update entry data from %1"
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico is unable to load the image - %1."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Overwrite File?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Overwrite"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Filter (Sort by Count)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Do you really want to delete this entry?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Delete Entry"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Do you really want to delete these entries?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Delete Multiple Entries"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "&Edit Entries..."
+
+#: controller.cpp:627
+msgid "D&uplicate Entries"
+msgstr "D&uplicate Entries"
+
+#: controller.cpp:628
+msgid "&Update Entries"
+msgstr "&Update Entries"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "&Delete Entries"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Default Calendar"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Active Calendar"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 is due to return \"%2\""
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(Empty)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - a collection manager for KDE"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Do not reopen the last open file"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Import <filename> as a bibtex file"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Import <filename> as a MODS file"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Import <filename> as a RIS file"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "File to open"
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr "Data source scripts"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Icons"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Author of btparse library"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr "Code examples and general inspiration"
+
+#: main.cpp:50
+msgid "Author of libcsv library"
+msgstr "Author of libcsv library"
+
+#: main.cpp:52
+msgid "Author of rtf2html library"
+msgstr "Author of rtf2html library"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Collection Fields"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Current Fields"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr ""
+"&New"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Add a new field to the collection"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr ""
+"&Delete"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Remove a field from the collection"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Field Properties"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "&Title:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "The title of the field"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "T&ype:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "The type of the field determines what values may be used. "
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "<i>Simple Text</i> is used for most fields. "
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "<i>Paragraph</i> is for large text blocks. "
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Choice</i> limits the field to certain values. "
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "<i>Checkbox</i> is for a simple yes/no value. "
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr "<i>Number</i> indicates that the field contains a numerical value. "
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr "A <i>Table</i> may hold one or more columns of values. "
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "An <i>Image</i> field holds a picture. "
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr "A <i>Rating</i> field uses stars to show a rating number. "
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "Cate&gory:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr "The field category determines where the field is placed in the editor."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "Descr&iption:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr "&Default value:"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr "<qt>A default value can be set for new entries.</qt>"
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr "A&llowed values:"
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "Extended &properties:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "&Set..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Format Options"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "No formatting"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalised."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Allow auto-capitalization only"
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+"This option allows the field to be capitalised, but not specially formatted."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Format as a title"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"This option capitalises and formats the field as a title, but only if those "
+"options are globally set."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Format as a name"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"This option capitalises and formats the field as a name, but only if those "
+"options are globally set."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Field Options"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Enable auto-completion"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Allow multiple values"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Allow grouping"
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"If checked, this field may be used to group the entries in the group view."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr "Revert the selected field's properties to the default values."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Modify Fields"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Keep modified values"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Revert Field Properties"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Revert"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Extended Field Properties"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr "A field with this title already exists. Please enter a different title."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr "<qt>The category may not be empty. Please enter a category.</qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "Tables are limited to a maximum of ten columns."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Unsaved Changes"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Select Borrower"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Configure Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "General Options"
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr "&Reopen file at startup"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "&Show \"Tip of the Day\" at startup"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr "If checked, the \"Tip of the Day\" will be shown at program start-up."
+
+#: configdialog.cpp:213
+msgid "Image Storage Options"
+msgstr "Image Storage Options"
+
+#: configdialog.cpp:214
+msgid "Store images in data file"
+msgstr "Store images in data file"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr "Store images in common application directory"
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr "Store images in directory relative to data file"
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Formatting Options"
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr "Auto capitalise &titles and names"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr "If checked, titles and names will be automatically capitalised."
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr "Auto &format titles and names"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr "If checked, titles and names will be automatically formatted."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr "No capitali&zation:"
+
+#: configdialog.cpp:243
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>A list of words which should not be capitalised. Multiple values should "
+"be separated by a semi-colon.</qt>"
+
+#: configdialog.cpp:249
+msgid "Artic&les:"
+msgstr "Artic&les:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr "Personal suffi&xes:"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr "Surname &prefixes:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Printing"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Printing Options"
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr "&Format titles and names"
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr "&Print field headers"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Grouping Options"
+
+#: configdialog.cpp:313
+msgid "&Group the entries"
+msgstr "&Group the entries"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Image Options"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr "Maximum image &width:"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr "&Maximum image height:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Templates"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Template Options"
+
+#: configdialog.cpp:369
+msgid "Template:"
+msgstr "Template:"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and colour settings."
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr "&Preview..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr "Show a preview of the template"
+
+#: configdialog.cpp:398
+msgid "Font Options"
+msgstr "Font Options"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr "Font:"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr "This font is passed to the template used in the Entry View."
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr "Size:"
+
+#: configdialog.cpp:425
+msgid "Color Options"
+msgstr "Colour Options"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr "Background colour:"
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr "This colour is passed to the template used in the Entry View."
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr "Text colour:"
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr "Highlight colour:"
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr "Highlighted text colour:"
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr "Manage Templates"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr "Install..."
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr "Click to install a new template directly."
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr "Download..."
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr "Click to download additional templates via the Internet."
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr "Delete..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr "Click to select and remove installed templates."
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Data Sources"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Data Source Options"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Source"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr "Move &Up"
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr "Move &Down"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "&New..."
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr "Click to add a new data source."
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Modify..."
+
+#: configdialog.cpp:533
+msgid "Click to modify the selected data source."
+msgstr "Click to modify the selected data source."
+
+#: configdialog.cpp:536
+msgid "Click to delete the selected data source."
+msgstr "Click to delete the selected data source."
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr "Click to download additional data sources via the Internet."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr "Template Packages (*.tar.gz)"
+
+#: configdialog.cpp:1049
+msgid "Delete Template"
+msgstr "Delete Template"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr "Select template to delete:"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "Borrower"
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Check-in"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Modify Loan..."
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "Borrower (Sort by Count)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "My Collection"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Book Collection"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Comic Book Collection"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Video Collection"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Music Collection"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Coin Collection"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Stamp Collection"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Wine Collection"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Card Collection"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Game Collection"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr "File Catalogue"
+
+#: collectionfactory.cpp:135
+msgid "Board Game Collection"
+msgstr "Board Game Collection"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Custom Collection"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Export Options"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Formatting"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Format all fields"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Export selected entries only"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr "If checked, only the currently selected entries will be exported."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Encoding"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Encode in Unicode (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Encode the exported file in Unicode (UTF-8)."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Encode in user locale (%1)"
+
+#: exportdialog.cpp:72
+msgid "Encode the exported file in the local encoding."
+msgstr "Encode the exported file in the local encoding."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "&Search"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "&Stop"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Internet Search"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Search Query"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr ""
+"S&earch:"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr "Enter a search value. An ISBN search must include the full ISBN."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Choose the type of search"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Click to start or stop the search"
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr "&Multiple ISBN/UPC search"
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr "Check this box to search for multiple ISBN or UPC values."
+
+#: fetchdialog.cpp:138
+msgid "Edit List..."
+msgstr "Edit List..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "Search s&ource:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Select the database to search"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "&Add Entry"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Add the selected entry to the current collection"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr "Get More Results"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr "Fetch more results from the current data source"
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Clear all search fields and results"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Cancelling the search..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Searching..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "The search returned no items."
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+
+#: fetchdialog.cpp:412
+msgid "No results were found for the following ISBN values:"
+msgstr "No results were found for the following ISBN values:"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Fetching %1..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr "No Internet sources are available for your current collection type."
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr "Edit ISBN/UPC Values"
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "&Load From File..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Load the list from a text file.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Edit Entry"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&New Entry"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "Sa&ve Entry"
+
+#: entryeditdialog.cpp:77
+msgid "Go to the previous entry in the collection"
+msgstr "Go to the previous entry in the collection"
+
+#: entryeditdialog.cpp:82
+msgid "Go to the next entry in the collection"
+msgstr "Go to the next entry in the collection"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Do you really want to modify these entries?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Modify Multiple Entries"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr "A value is required for the following fields. Do you want to continue?"
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Edit Entries"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "Sa&ve Entries"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Save Entry"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Collection Report"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "&Report template:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "&Generate"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr "Select a report template and click <em>Generate</em>."
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+"Some reports may take several seconds to generate for large collections."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Do you really want to delete this filter?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Delete Filter?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "New collection name:"
+
+#: tellico_kernel.cpp:377
+msgid "Entry 1"
+msgstr "Entry 1"
+
+#: tellico_kernel.cpp:378
+msgid "Entry 2"
+msgstr "Entry 2"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr "Conflicting values for %1 were found while merging entries."
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr "Please choose which value to keep."
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+msgid "Merge Entries"
+msgstr "Merge Entries"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr "Select value from %1"
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico is unable to locate the default entry stylesheet."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&New"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Collection"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Collection Toolbar"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr ""
+"Your names"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr ""
+"Your emails"
+
+#: entrymerger.cpp:35
+msgid "Merging entries..."
+msgstr "Merging entries..."
+
+#: entrymerger.cpp:49
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Total merged/scanned entries: %1/%2"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr ""
+"Album"
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr "This template is meant for music collections only."
+
+#: xslt.cpp:5
+msgid "Total:"
+msgstr "Total:"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr ""
+"Fancy"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr ""
+"Default"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr ""
+"Compact"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr ""
+"Video"
+
+#: xslt.cpp:14 xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr "This template is meant for video collections only."
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr ""
+"Group Summary"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Group Summary"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Total number of fields:"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Total number of entries:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+msgid "Generated by Tellico"
+msgstr "Generated by Tellico"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Distinct values: "
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr ""
+"Image List"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr ""
+"Loan View"
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Loan Date"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Note"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Due Date"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr ""
+"Group View"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr ""
+"Title Listing (Horizontal)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr ""
+"Title Listing (Vertical)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr ""
+"Column View"
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr ""
+"Tri-Column"
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr "Search"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr "The British Library"
+
+#: z3950.cpp:6
+msgid "Sudoc (France)"
+msgstr "Sudoc (France)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr "BIBSYS (Norway)"
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr "Italian National Library"
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr "Portuguese National Library"
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr "National Library of Poland"
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr "National Library of Canada"
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr "Israel Union List"
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr "National Library of Australia"
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr "National Library of Lithuania"
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr "Copac (UK and Ireland)"
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr "BoardGameGeek"
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr "Dark Horse Comics"
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr "Allocine.fr"
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr "Spanish Ministry of Culture"
diff --git a/po/es.po b/po/es.po
new file mode 100644
index 0000000..30950c2
--- /dev/null
+++ b/po/es.po
@@ -0,0 +1,5294 @@
+# translation of es.po to Español
+# Translation of es to Spanish
+# This file is distributed under the same license as the Tellico package.
+# Copyright (C) 2003 Robby Stephenson <robby@periapsis.org>.
+#
+# Enrique Matias Sanchez (aka Quique) <cronopios@gmail.com>, 2003, 2004, 2005, 2006, 2007.
+# Ale Hamann <amadeus@bbs.frc.utn.edu.ar>, 2006, 2007, 2008.
+msgid ""
+msgstr ""
+"Project-Id-Version: es\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2008-02-17 06:21-0200\n"
+"Last-Translator: Ale Hamann <amadeus@bbs.frc.utn.edu.ar>\n"
+"Language-Team: Español <es@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Report-Msgid-Bugs-To: \n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "<qt>Tellico no puede redireccionar al servidor en <b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr "Conectando con OpenOffice.org..."
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr "Conexión a OpenOffice.org"
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+"Tellico no pudo conectarse a OpenOffice.org. Por favor, verifique las "
+"opciones de conexión inferiores, y asegúrese de que OpenOffice.org Writer "
+"esté actualmente en ejecución."
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr "Redirección"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr "TCP/IP"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr "Cambiar el nombre de la columna"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr "Nuevo nombre para la columna:"
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr "Columna %1"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr "Cambiar el nombre de la columna..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr "Insertar fila"
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr "Eliminar fila"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr "Subir la fila"
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr "Bajar la fila"
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr "Limpiar la tabla"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr "Previsualización de la plantilla"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "Configuración (&s)"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr "%1:"
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Más"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Menos"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Limpiar"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Seleccionar la imagen..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr "Guardar enlace solamente"
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr "Guardar un enlace solo es posible para las imágenes nuevas."
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Modificar %1"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Agregar una colección"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Fusionar una colección"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Reemplazar la colección"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr "Modificar las entradas"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "Añadir el campo %1"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Modificar el campo %1"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Borrar el campo %1"
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr "Añadir entradas"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Añadir %1"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Darle un nuevo nombre a la colección"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Modificar préstamo"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Añadir un filtro"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Modificar el filtro"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Borrar el filtro"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Artículos prestados"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Préstamos %1"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Borrar las entradas"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Borrar %1"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Reordenar los campos"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Entradas devueltas"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Devolución %1"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "General"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Condición"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Personal"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Mis sellos"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Título"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Descripción"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Denominación"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "País"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Año de publicación"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Color"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Scott#"
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr "Soberbio,excelente,muy bueno,bueno,normal,pobre"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Calidad"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Cancelado"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Articulado"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Centrado"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Engomado"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Fecha de compra"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Precio de compra"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Ubicación"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Regalo"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Imagen"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Comentarios"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Publicación"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Clasificación"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Mis libros de cómics"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Subtítulo"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Escritor"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr "Artista"
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Serie"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Número"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Editorial"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Edición"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Año de publicación"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Páginas"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Idioma"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Género"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Palabras clave"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr ""
+"Perfecto,casi perfecto,excelente,francamente bueno,muy "
+"bueno,bueno,mediocre,malo"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Firmado"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Prestado"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Carátula Frontal"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Mis monedas"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Tipo"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Año"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Marca de acuñación"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Juego de monedas"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+"Prueba-65,prueba-60,perfecto estado-65,perfecto estado-60,casi sin "
+"circular-55,casi sin circular-50,extremadamente bueno-40, "
+"excelente-30,excelente-20,muy bueno-12,muy bueno-8,bueno-4,mediocre"
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr "PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Servicio de calificación"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Cara"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Cruz"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Mis libros"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Autor"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Tapa dura"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Rústica"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Rústica económica"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "Libro electrónico"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Revista"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Periódico"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Encuadernación"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Año de copyright"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN#"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Número Internacional Estándar del Libro"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN#"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Número de control de la Biblioteca del Congreso"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr "Traductor"
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Número en la serie"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Nuevo"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Usado"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Leído"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Clasificación"
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr "Mis archivos"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "Nombre"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Volumen"
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr "Carpeta"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr "Tipo MIME"
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr "Tamaño"
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr "Permisos"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr "Propietario"
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr "Grupo"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr "Creado"
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr "Modificado"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr "Metainformación"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Propiedad"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Valor"
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr "Icono"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Mis vinos"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Productor"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Denominación"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Variedad"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Cosecha"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Vino tinto"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Vino blanco"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Vino espumoso"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Cantidad"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Bebido por"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Imagen de la etiqueta"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Otras personas"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Características"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Mis vídeos"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr "Blu-ray"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+msgid "HD DVD"
+msgstr "HD DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Medio"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Año de producción"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Certificación"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Región 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Región 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Región 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Región 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Región 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Región 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Región 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Región 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Región"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Nacionalidad"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Formato"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Reparto"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr "Actor/actriz"
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr "Papel"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr ""
+"Una tabla para los miembros del reparto, junto a los papeles que interpretan"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Director"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Compositor"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Estudio"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Pistas de idioma"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Idiomas de los subtítulos"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Pistas de audio"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Duración"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "La duración del vídeo (en minutos)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Proporciones"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Pantalla ancha"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Blanco y Negro"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Modo de color"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Versión del director"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Sinopsis"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Valoración personal"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Carátula"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "Mis juegos"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr "Xbox 360"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr "PlayStation3"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr "Nintendo Wii"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr "Linux"
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Plataforma"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Año de publicación"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Editorial"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Desarrollador"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+"Sin calificar, sólo para adultos, mayores, adolescentes, todos, niños, "
+"pendiente"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "Clasificación ESRB"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Finalizado"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Mis naipes"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Jugador"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Equipo"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Marca"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Número de naipe"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Tipo de naipe"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Imagen frontal"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Imagen trasera"
+
+#: collections/boardgamecollection.cpp:26
+msgid "My Board Games"
+msgstr "Mis juegos de mesa"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr "Mecanismo"
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr "Diseñador"
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr "Número de Jugadores"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Bibliografía"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Tipo de entrada"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+"Estos tipos de entrada son específicos de BibTeX. Consulte la "
+"documentación de BibTeX."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Clave de BibTeX"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Título del libro"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Editor"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organización"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Dirección"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr "DOI"
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr "Identificador Digital de Objeto"
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Mes"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Número"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Modo de publicación"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Capítulo"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Referencia cruzada"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Resumen"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Notas"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Mi música"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Álbum"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "CD (Disco Compacto)"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Casete"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Vinilo"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Artista"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Discográfica"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Pistas"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr "Duración"
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with,un,una,y,pero,por,para,desde,en,entre,no,ni,de,fuera,sobre,o,sobre,el"
+",ella,eso,la,lo,le,con"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "el,la,los,las"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr.,jr,iii,iv,h,hijo"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,del,van,der,van der,von"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr "ISBNdb.com"
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 no permite buscar por este tipo de colección."
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Resultados de %1:%2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "Esta fuente no tiene opciones."
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "Base de datos Entrez"
+
+#: fetch/entrezfetcher.cpp:485
+msgid "Institution"
+msgstr "Institución"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Error en la consulta"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Error de búsqueda de conexión %1:%2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Error en sintaxis de registro"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Error de conexión %1:%2"
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr "Servidor SRU"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Biblioteca del Congreso (EEUU)"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr "Servidor (&t): "
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr "Introduzca el nombre del servidor."
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Puerto: "
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Introduzca el número de puerto del servidor. El predefinido es %1."
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr "Ruta: "
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr "Introduzca la ruta a la base de datos que usa el servidor."
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr "Formato: "
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr "Introduzca el formato del resultado que usa el servidor."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr "Yahoo! Audio Search"
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "La imagen de la carátula no pudo ser cargada."
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr "Enlace a Amazon"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (Estados Unidos)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (Reino Unido)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Alemania)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japón)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (Francia)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Canadá)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Servicios Web de Amazon.com"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "País (&u):"
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "Estados Unidos"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Reino Unido"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Alemania"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Japón"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "Francia"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Canadá"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon.com proporciona datos desde diferentes servidores locales. Elija el "
+"que desee utilizar como fuente de datos."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "Tamaño de &imagen: "
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Imagen pequeña"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Imagen mediana"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Imagen grande"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Sin imagen"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"La imagen de la carátula puede ser descargada sin problemas. Sin embargo, "
+"si hay demasiadas imágenes grandes en la colección, el rendimiento puede "
+"degradarse."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "ID &Asociada: "
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+"El ID del asociado identifica a la persona que accede a los servicios web de "
+"Amazon.com, y se incluye en todos los enlaces al servidor Amazon.com."
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr "Servidor z39.50"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr "Usar &servidor preconfigurado:"
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "Base de &datos: "
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr "Introduzca el nombre de la base de datos que usa el servidor."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "Juego de c&aracteres: "
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Introduzca la codificación del juego de caracteres utilizada por el "
+"servidor z39.50. La opción más probable es MARC-8, aunque ISO-8859-1 "
+"también es común."
+
+#: fetch/z3950fetcher.cpp:550
+msgid "&Format: "
+msgstr "&Formato: "
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr "Detectar automáticamente"
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+"Introduzca el formato de datos que utiliza el servidor z39.50. Si "
+"<i>detectar automáticamente</i> está marcado, Tellico intentará detectar "
+"automáticamente la mejor configuración."
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "&Usuario: "
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Opcional"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Introduzca el nombre del usuario para la autenticación que usa la base de "
+"datos z39.50. La mayoría de los servidores no necesitan ninguno."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "Contraseña (&w):"
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Introduzca la contraseña de autenticación que utiliza la base de datos "
+"z39.50. La mayoría de los servidores no necesitan ninguna. La contraseña "
+"se guardará en texto plano en el archivo de configuración de Tellico."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr "Ilustrador"
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Aplicación externa"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "&Tipo de colección:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+"Configura el tipo de colección de los datos devueltos por la aplicación "
+"externa."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr "Tipo de &resultado: "
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr ""
+"Configura el tipo de resultados de los datos devueltos por la aplicación "
+"externa."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "Ruta de la a&plicación: "
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+"Configura la ruta de la aplicación a ejecutar que debería producir un "
+"archivo de datos de Tellico válido."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr "Seleccione las claves de búsqueda que admite la fuente de datos."
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+"Añada cualquier argumento que se pueda necesitar. <b>%1</b> será "
+"reemplazado por el término de búsqueda."
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr "Argumentos"
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+msgid "Update"
+msgstr "Actualizar"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+"<p>Introduzca los argumentos que deberían utilizarse para buscar las "
+"actualizaciones disponibles para una entrada.</p><p>El formato es el mismo "
+"que el de los campos <i>Dependiente</i>, en donde los valores del campo "
+"están contenidos entre llaves, como <i>%{author}</i>. Consulte más "
+"detalles en la documentación.</p>"
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Opciones de fuente"
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr "Campos disponibles"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "Base de datos de películas de Internet"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Seleccione el resultado de IMDB"
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+"<qt>Su búsqueda produjo varios resultados. Por favor, seleccione uno de los "
+"siguientes.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Seleccione un resultado de la búsqueda.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr "Enlace IMDB"
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Títulos alternativos"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+msgid "IMDB Rating"
+msgstr "Valoración IMDB"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Certificaciones"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"La Base de datos de películas de Internet usa varios servidores. Escoja el "
+"que desee utilizar."
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr "Reparto &máximo: "
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+"La lista de miembros del reparto puede incluir mucha gente. Establezca el "
+"número máximo que devolverá la búsqueda."
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr "Descargar &imagen de la carátula"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr "Internet Bookshop (ibs.it)"
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Persona"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr "UPC/EAN"
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Palabra clave"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr "ID de arXiv"
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr "ID de Pubmed"
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Búsqueda sin formato"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr "Título original"
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr "Distribuidor"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr "Episodios"
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr "arXiv.org"
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr "%1 requiere un nombre de usuario y una contraseña."
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+"CrossRef requiere de una cuenta para acceder. Por favor, lea los términos y "
+"condiciones <a href='http://www.crossref.org/requestaccount/'>y solicite una "
+"cuenta</a>. Ingrese la información de su cuenta OpenURL a continuación."
+
+#: fetch/crossreffetcher.cpp:343
+msgid "&Username: "
+msgstr "Nombre de &usuario: "
+
+#: fetch/crossreffetcher.cpp:348
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+"Se requiere un nombre de usuario y contraseña para acceder al servicio "
+"CrossRef. La contraseña es almacenada como texto plano en el archivo de "
+"configuración de Tellico."
+
+#: fetch/crossreffetcher.cpp:354
+msgid "&Password: "
+msgstr "Contraseña (&p):"
+
+#: fetch/gcstarpluginfetcher.cpp:190
+msgid "GCstar Plugin"
+msgstr "Complemento GCstar"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr ""
+"Configura el tipo de colección de los datos devueltos por el complemento."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr "Com&plemento: "
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr "Seleccione el complemento GCstar utilizado para la fuente de datos."
+
+#: fetch/gcstarpluginfetcher.cpp:420
+msgid "Author: "
+msgstr "Autor: "
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr "Búsqueda de audio Discog"
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr "Llave API (&k):"
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+"Con su cuenta discogs.com, usted recibe una llave API para el uso de su "
+"interfaz basada en XML (Vea http://www.discogs.com/help/api)."
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr "Enlace Discogs"
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr "Obtener novedades"
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr "Versión"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr "Descargas"
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr "Fecha de publicación"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+"Ésta es una lista de todos los elementos disponibles para descarga. Los "
+"elementos instalados previamente tienen un icono de marca de comprobación, "
+"mientras que los elementos que tienen una nueva versión disponible tienen "
+"un icono de actualización"
+
+#: newstuff/dialog.cpp:137
+msgid "The name and license of the selected item"
+msgstr "El nombre y licencia del elemento seleccionado"
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr "El autor del elemento seleccionado"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr "Instalar"
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr "Descargar e instalar la plantilla seleccionada."
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+"Descargar e instalar el script seleccionado. Algunos scripts puede que "
+"necesiten ser configurados tras su instalación."
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr "Se muestra aquí una descripción del elemento seleccionado."
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr "Descargando información..."
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Preparado."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr "Actualizar"
+
+#: newstuff/dialog.cpp:413
+msgid "Installing item..."
+msgstr "Instalando el elemento..."
+
+#: translators/bibteximporter.cpp:79
+msgid "No valid bibtex entries were found"
+msgstr "No se encontraron entradas válidas de BibTeX"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "No se encontraron entradas de BibTeX válidas en el archivo - %1"
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Opciones de BibTeX"
+
+#: translators/bibteximporter.cpp:287
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Usar codificación Unicode (UTF-8)"
+
+#: translators/bibteximporter.cpp:288
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Codificar el archivo exportado en Unicode (UTF-8)."
+
+#: translators/bibteximporter.cpp:289
+msgid "Use user locale (%1) encoding"
+msgstr "Usar codificación local del usuario (%1)"
+
+#: translators/bibteximporter.cpp:293
+msgid "Read the imported file in the local encoding."
+msgstr "Leer el archivo importado utilizando la codificación local."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "Archivo ZIP de Tellico"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Archivos de Tellico (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Todos los archivos"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>Ya existe una biblioteca de Alexandria llamada<i>%1</i>. Cualquier libro "
+"existente en esa biblioteca podría ser sobreescrito.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr ""
+"Hay un error de análisis sintáctico de XML en la línea %1, columna %2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "El mensaje de error de Qt es:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Es de una versión futura de Tellico."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Tellico está convirtiendo el archivo a un formato de documento más "
+"reciente. Se puede producir una pérdida de información si en el futuro se "
+"usa una versión más antigua de Tellico para leer este archivo."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Desconocido"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "El archivo está vacío."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "El archivo no contiene datos de una colección."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Libros no leídos"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Películas viejas"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "Música de los 80"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Favoritos"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Buscando archivos de audio..."
+
+#: translators/audiofileimporter.cpp:129
+msgid "Bitrate"
+msgstr "Tasa de bits"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr "Pistas (Disco %1)"
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(Varios)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Opciones para archivos de audio"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Búsqueda recursiva en carpetas (&f)"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+"Si se marca, las carpetas serán exploradas recursivamente durante la "
+"búsqueda de archivos de audio."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr "Inc&luir ubicación de archivo"
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr ""
+"Si se marca, se añadirán a las entradas el nombre de archivo de cada pista."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr "Incluir tasa de &bits"
+
+#: translators/audiofileimporter.cpp:353
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr ""
+"Si se marca, la tasa de bits para cada pista será agregada a la entradas"
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|Archivos CSV (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "Opciones CSV"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Incluir los títulos de los campos como cabeceras de columna"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr ""
+"Si se marca, se añadirá una fila de cabecera con los títulos de los "
+"campos."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Separador"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"Además de la coma, se pueden usar otros caracteres como delimitadores, "
+"separando cada valor del archivo."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Coma"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Usar una coma como separador."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Punto y coma"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Usar punto y coma como separador."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Tabulador"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Usar tabulaciones como separador."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Otro"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Usar una cadena personalizada como separador."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr ""
+"Puede usarse como delimitador una cadena personalizada, como un dos puntos."
+
+#: translators/filelistingimporter.cpp:63
+msgid "Scanning files..."
+msgstr "Explorando archivos..."
+
+#: translators/filelistingimporter.cpp:191
+msgid "File Listing Options"
+msgstr "Opciones para el listado de archivos"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr "Búsqueda recursiva en carpetas"
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+"Si se marca, las carpetas serán exploradas recursivamente durante la "
+"búsqueda para todos los archivos."
+
+#: translators/filelistingimporter.cpp:198
+msgid "Generate file previews"
+msgstr "Generar previsualizaciones de archivos"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+"Si se marca, se generarán previsualizaciones del contenido del archivo, lo "
+"cual puede enlentecer el listado de la carpeta."
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "Archivo ONIX"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.zip|Archivos Zip (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "Opciones de archivo ONIX"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Incluir imágenes en el archivo"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Si se marca, las imágenes del documento serán incluidas en el archivo ONIX "
+"comprimido con Zip."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr "<qt>Tellico no pudo acceder a la unidad de CD-ROM - <i>%1</i>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+msgid "Select CDDB Entry"
+msgstr "Seleccionar entrada CDDB"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr "Seleccione una entrada de CDDB:"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>No se encontró ningún registro que coincida con el CD</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "<qt>Tellico no pudo completar la búsqueda del CD.</qt>"
+
+#: translators/freedbimporter.cpp:470
+msgid "Various"
+msgstr "Varios"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Opciones de CD de audio"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Leer datos desde la unidad de CD-ROM"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Seleccione o introduzca la ubicación del dispositivo de CD-ROM."
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Leer solamente todos los archivos de la caché de CDDB"
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+"Leer recursivamente los datos de todos los archivos de la caché de CDDB "
+"contenidos en la carpeta de caché predeterminada."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr "GCfilms"
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.gcf|Archivos de datos GCfilms (*.gcf)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.gcs|Archivos de datos GCstar (*.gcs)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "Opciones de XSLT"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "Archivo XSLT:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr ""
+"Seleccione el archivo XSLT usado para transformar los datos XML de Tellico."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Opciones de Alexandria"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr "Bib&lioteca:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "BibTeXML"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Archivos BibTeXML (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|Archivos XML (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Opciones XML de Tellico"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Incluir las imágenes en el documento XML"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Si se marca, las imágenes del documento serán incluidas en el flujo XML "
+"como elementos codificados en base64."
+
+#: translators/importer.h:100
+msgid "Loading data..."
+msgstr "Cargando datos..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr "Cargando %1..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "BibTeX"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Archivos Bibtex (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Expandir macros de cadenas"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Si se marca, las macros de cadenas serán expandidas y no se escribirá "
+"ninguna entrada @cadena{}."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Usar paquete URL"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr ""
+"Si se marca, todos los campos URL aparecerán en una declaración \\url."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Omitir las entradas con claves de cita vacías"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr "Si se marca, se omitirán las entradas que no tengan una cita BibTeX."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Estilo de cita de BibTeX:"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Llaves"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Citas"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"<qt>El estilo de cita utilizado al exportar a BibTeX. Todos los valores de "
+"los campos serán «escapados» bien con llaves, bien con marcas de "
+"cita.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Seleccione el tipo de colección que se va a importar."
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr "La primera &fila contiene los títulos de campo"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr "Si se marca, se usa la primera fila como título de los campos."
+
+#: translators/csvimporter.cpp:248
+msgid "&Comma"
+msgstr "&Coma"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr "Punto y coma (&s)"
+
+#: translators/csvimporter.cpp:259
+msgid "Ta&b"
+msgstr "Ta&bulador"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr "Otro (&h):"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "La tabla muestra las primeras cinco lineas del archivo CSV."
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt>Asociar cada columna a un campo de la colección, seleccionando una "
+"columna, el campo, y luego pulsando el botón <i>Asignar campo</i></qt>"
+
+#: translators/csvimporter.cpp:298
+msgid "Co&lumn:"
+msgstr "Co&lumna:"
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr "Campo de &datos en esta columna:"
+
+#: translators/csvimporter.cpp:315
+msgid "&Assign Field"
+msgstr "&Asignar Campo"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+"Al menos una columna debe ser asignada a un campo. Solamente las columnas "
+"asignadas serán importadas."
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Nuevo campo"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|Base de datos de Pilot (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Ver las columnas"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "Opciones de PilotDB"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Establecer un indicador de respaldo PDA para la base de datos"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>El archivo no es un archivo de datos GCstar válido.</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Tellico se ha encontrado con un error en un proceso de XSLT."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "Para importar el archivo se necesita un archivo XSLT válido."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|Archivos XSL (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|Archivos HTML (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Gente"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(agrupado por %1)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "Opciones de HTML"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Imprimir los encabezados de campo"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr ""
+"Si se marca, los nombres de los campos se imprimirán como cabeceras de "
+"tabla."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Agrupar las entradas"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr "Si se marca, las entradas se agruparán por el campo seleccionado."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Exportar archivos de entradas individuales"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr "Si se marca, se crearán archivos independientes para cada entrada."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico fue incapaz de leer cualquier metadato del archivo PDF"
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+"Tellico es capaz de descargar información sobre las entradas con una DOI "
+"desde CrossRef.org. Sin embargo, usted deberá crear una cuenta CrossRef y "
+"añadir una nueva fuente de datos con la información de su cuenta."
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Propiedades de fuente de datos"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "Nombre de fuente (&s): "
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr ""
+"El nombre que identifica a la fuente de datos deber ser único e informativo."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "&Tipo de fuente: "
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr "Tellico admite varias fuentes de datos diferentes."
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr "Actualizar desde la fuente debería sobrescribir los datos de usuario"
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Si se marca, al actualizar las entradas se sobrescribirá la información "
+"existente."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Cualquier campo"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "contiene"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "no contiene"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "igual a"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "no es igual a"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "coincide con la expresión regular"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "no coincide con la expresión regular"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Editar..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Filtro avanzado"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Criterio del filtro"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Coincide con todos &los siguientes"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Coincide con cualquiera de los siguientes (&y)"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Nombre del filtro:"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "Guardar Filtro (&s)"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Texto simple"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Párrafo"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Selección"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Casilla"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Tabla"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Dependiente"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Fecha"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr "Actualizando %1..."
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr "Actualizando entradas..."
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr "Actualizar las entradas"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr "Actualizando <b>%1</b>..."
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr "Seleccione un resultado"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+"<qt><b>%1</b> devolvió varios resultados que podrían coincidir con "
+"<b>%2</b>, la entrada actual en la colección. Por favor, seleccione la "
+"coincidencia adecuada.</qt>"
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Expandir todos los grupos"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Contraer todos los grupos"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Filtrar por grupo"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (ordenar por número)"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Grupo"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Opciones de importación"
+
+#: importdialog.cpp:62
+msgid "&Replace current collection"
+msgstr "&Reemplazar colección actual"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr ""
+"Reemplazar la colección actual con el contenido del archivo importado."
+
+#: importdialog.cpp:65
+msgid "A&ppend to current collection"
+msgstr "Agregar a colección actual (&p)"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Añade el contenido del archivo importado a la colección actual. Esto "
+"solamente es posible si las colecciones son del mismo tipo."
+
+#: importdialog.cpp:69
+msgid "&Merge with current collection"
+msgstr "Fusionar con la colección actual (&m)"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Fusiona el contenido del archivo importado con la colección actual. Esto "
+"solamente es posible si las colecciones son del mismo tipo. Las entradas "
+"deben ser exactamente del mismo tipo para poder ser fusionadas."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Importar"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|Archivos RIS (*.ris)"
+
+#: importdialog.cpp:277
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.amc|Archivos de datos AMC (*.amc)"
+
+#: importdialog.cpp:281
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdf|Archivos PDF (*.pdf)"
+
+#: importdialog.cpp:285
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.reflib|Archivos de Referencer (*.reflib)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico no es capaz de cargar el archivo - %1."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico no es capaz de escribir el archivo - %1."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico no es capaz de cargar el archivo - %1."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Sólo se pueden agregar colecciones que tengan el mismo tipo de entradas que "
+"la actual. No se hace ningún cambio a la colección actual."
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Sólo se pueden fusionar colecciones que tengan el mismo tipo de entradas "
+"que la actual. No se hace ningún cambio a la colección actual."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico no es capaz de cargar alguna imagen del archivo - %1."
+
+#: entryiconview.cpp:287
+msgid "&Sort By"
+msgstr "Ordenado por (&s)"
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Ventana de préstamos"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "Se están prestando los siguientes elementos:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "El siguiente elemento está en préstamo:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "Prestado a (&l):"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Introduzca el nombre de la persona que ha tomado prestados los elementos. "
+"Pulsando el botón podrá seleccionarlo de la libreta de direcciones."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "Fecha de préstamo (&l):"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+"La fecha de préstamo es la fecha en que prestó los artículos. Por "
+"omisión, se usa la fecha de hoy."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "Fecha límite de devol&ución:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"La fecha de devolución es cuando se deben haber devuelto los artículos. La "
+"fecha de devolución no es obligatoria, salvo que quiera añadir el "
+"préstamo a su calendario activo."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Nota:"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "También puede añadir notas sobre el préstamo."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "&Añadir un recordatorio al calendario activo"
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"<qt>Marcar esta casilla añadirá un elemento <em>Por hacer</em> a su "
+"calendario activo, que se puede ver usando KOrganizer. Esta caja solamente "
+"se activa cuando se configura una fecha de devolución."
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Crear una nueva colección"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Nueva Colección de Li&bros"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Crear una nueva Colección de libros"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Nueva B&ibliografía"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Crear una nueva bibliografía BibTeX"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Nueva Colección de &Cómics"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Crear una nueva colección de cómics"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Nueva Colección de &Vídeos"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Crear una nueva colección de vídeos"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Nueva Colección de &Música"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Crear una nueva colección de música"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Nueva Colección de M&onedas"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Crear un nueva colección de monedas"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Nueva Colección de &Sellos"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Crear una nueva colección de sellos"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Nueva Colección de N&aipes"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Crear una nueva colección de naipes"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Nueva Colección de Vinos (&w)"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Crear una nueva colección de vinos"
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Nueva Colección de Jue&gos"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Crear una nueva colección de juegos"
+
+#: mainwindow.cpp:272
+msgid "New Boa&rd Game Collection"
+msgstr "Nueva Colección de Juegos de Mesa (&r)"
+
+#: mainwindow.cpp:274
+msgid "Create a new board game collection"
+msgstr "Crear una nueva colección de juegos de mesa"
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr "Nuevo Catálogo de Archivos (&f)"
+
+#: mainwindow.cpp:282
+msgid "Create a new file catalog"
+msgstr "Crear un nuevo catálogo de archivos"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "N&ueva Colección Personalizada"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Crear una nueva colección personalizada"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Abrir un documento ya existente"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Abrir un archivo usado recientemente"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Guardar el documento"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Guardar el documento actual como un archivo diferente..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Imprime el contenido del documento..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Salir de la aplicación"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Importar datos de la colección desde otros formatos"
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Importar datos de Tellico..."
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Importar otro archivo de datos de Tellico"
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "Importar datos CSV..."
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Importar un archivo CSV"
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "Importar datos MODS..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Importar un archivo de datos MODS"
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Importar datos de Alexandria..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Importar datos del gestor de colecciones de libros Alexandria"
+
+#: mainwindow.cpp:352
+msgid "Import Delicious Library Data..."
+msgstr "Importar datos de Delicious Library..."
+
+#: mainwindow.cpp:353
+msgid "Import data from Delicious Library"
+msgstr "Importar datos desde Delicious Library"
+
+#: mainwindow.cpp:359
+msgid "Import Referencer Data..."
+msgstr "Importar datos de Referencer..."
+
+#: mainwindow.cpp:360
+msgid "Import data from Referencer"
+msgstr "Importar datos desde Referencer"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Importar datos de BibTeX..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Importar un archivo de bibliografía BibTeX"
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Importar datos BibTeXML..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Importar un archivo de bibliografía BibTeXML"
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "Importar datos RIS..."
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Importar un archivo de referencia RIS"
+
+#: mainwindow.cpp:387
+msgid "Import PDF File..."
+msgstr "Importar archivo PDF..."
+
+#: mainwindow.cpp:388
+msgid "Import a PDF file"
+msgstr "Importar un archivo PDF"
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Importar metadatos de un archivo de sonido..."
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Importar metadatos desde archivos de sonido"
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Importar datos de un CD de audio..."
+
+#: mainwindow.cpp:405
+msgid "Import audio CD information"
+msgstr "Importar información de un CD de audio"
+
+#: mainwindow.cpp:414
+msgid "Import GCstar Data..."
+msgstr "Importar datos GCstar..."
+
+#: mainwindow.cpp:415
+msgid "Import a GCstar data file"
+msgstr "Importar un archivo de datos GCstar"
+
+#: mainwindow.cpp:421
+msgid "Import Griffith Data..."
+msgstr "Importar datos de Griffith..."
+
+#: mainwindow.cpp:422
+msgid "Import a Griffith database"
+msgstr "Importar una base de datos de Griffith"
+
+#: mainwindow.cpp:428
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Importar datos de Ant Movie Catalog..."
+
+#: mainwindow.cpp:429
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Importar un archivo de datos de Ant Movie Catalog"
+
+#: mainwindow.cpp:435
+msgid "Import File Listing..."
+msgstr "Importar un listado de archivos..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr "Importar información sobre los archivos de una carpeta"
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "Importar y transformar con XSL..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Importar un archivo utilizando una transformación XSL"
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Exportar"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Exportar los datos de la colección a otros formatos"
+
+#: mainwindow.cpp:461
+msgid "Export to XML..."
+msgstr "Exportar a XML..."
+
+#: mainwindow.cpp:462
+msgid "Export to a Tellico XML file"
+msgstr "Exportar a un archivo XML de Tellico"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Exportar a Zip..."
+
+#: mainwindow.cpp:469
+msgid "Export to a Tellico Zip file"
+msgstr "Exportar a un archivo Zip de Tellico"
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "Exportar a HTML..."
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Exportar a un archivo HTML"
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "Exportar a CSV..."
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Exportar a un archivo de valores separados por comas"
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "Exportar a PilotDB..."
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Exportar a una base de datos PilotDB"
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Exportar a Alexandria..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Exportar a una biblioteca de Alexandria"
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Exportar a BibTeX..."
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Exportar a un archivo BibTeX"
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Exportar a BibTeXML..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Exportar a un archivo BibTeXML"
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "Exportar a ONIX..."
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Exportar a un archivo ONIX"
+
+#: mainwindow.cpp:524
+msgid "Export to GCfilms..."
+msgstr "Exportar a GCfilms..."
+
+#: mainwindow.cpp:525
+msgid "Export to a GCfilms data file"
+msgstr "Exportar a un archivo de datos GCfilms"
+
+#: mainwindow.cpp:531
+msgid "Export to GCstar..."
+msgstr "Exportar a GCstar..."
+
+#: mainwindow.cpp:532
+msgid "Export to a GCstar data file"
+msgstr "Exportar a un archivo de datos de GCstar"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "Exportar y transformar con XSL..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Exportar utilizando una transformación XSL"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Cortar el texto seleccionado y colocarlo en el portapapeles"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Copiar el texto seleccionado al portapapeles"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Pegar el contenido del portapapeles"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Seleccionar todas las entradas de esta colección"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Deseleccionar todas las entradas de esta colección"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Búsqueda en Internet..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Buscar en Internet..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "&Filtro Avanzado..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Filtrar la colección"
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&Nueva Entrada..."
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Crear una nueva entrada"
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "&Editar Entrada..."
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Editar las entradas seleccionadas"
+
+#: controller.cpp:621 mainwindow.cpp:577
+msgid "D&uplicate Entry"
+msgstr "D&uplicar Entrada"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Copiar las entradas seleccionadas"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "&Borrar Entrada"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Borrar las entradas seleccionadas"
+
+#: mainwindow.cpp:585
+msgid "&Merge Entries"
+msgstr "Fusionar Entradas (&m)"
+
+#: mainwindow.cpp:588
+msgid "Merge the selected entries"
+msgstr "Fusionar las entradas seleccionadas"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "&Generar Informes..."
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Generar informes de la colección"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "Prestar (&o)..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Gestionar un préstamo de los artículos seleccionados"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "Devoluc&ión"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Ingresar (como devolución) los artículos seleccionados"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "&Renombrar Colección..."
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Cambiar el nombre de la colección"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "Campos de la Colección (&f)..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Modificar los campos de la colección"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "Convertir en &Bibliografía"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Convertir una colección de libros a una bibliografía"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "&Macros para Cadenas de texto..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Editar las macros para cadenas de texto de BibTeX"
+
+#: mainwindow.cpp:626
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Copiar BibTeX al &Portapapeles"
+
+#: mainwindow.cpp:627
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Copiar citas de BibTeX al portapapeles"
+
+#: mainwindow.cpp:632
+msgid "Cite Entry in &LyX"
+msgstr "Citar Entrada en &LyX"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Citar las entradas seleccionadas en LyX"
+
+#: mainwindow.cpp:638
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Ci&tar Entrada en OpenOffice.org"
+
+#: mainwindow.cpp:639
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Citar las entradas seleccionadas en OpenOffice.org"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, no-c-format
+msgid "&Update Entry"
+msgstr "Act&ualizar Entrada"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr "Todas las fuentes"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr ""
+"Actualizar los datos de la entrada usando todas las fuentes disponibles"
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Mostrar Vista de Gru&po"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Habilitar/deshabilitar la vista de grupo"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Ocultar Vista de Gru&po"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Mostrar &Editor de Entradas"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Habilitar/deshabilitar el editor"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "Ocultar &Editor de Entradas"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Mostrar &Vista de Entradas"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Habilitar/deshabilitar la vista de entradas"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "Ocultar &Vista de Entradas"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Cambiar el agrupamiento"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "Selección de &Grupos"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Cambiar el agrupamiento de la colección"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Filtro"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Limpiar el filtro"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Filtrar aquí..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Grupos"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt>La <i>vista de grupos</i> ordena las entradas por grupos basándose en "
+"un campo seleccionado.</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt>La <i>vista de columnas</i> muestra los valores de varios campos para "
+"cada entrada.</qt>"
+
+#: mainwindow.cpp:831
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Bienvenido al administrador de colecciones Tellico"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+"<h3>Tellico es una herramienta para gestionar colecciones de libros, "
+"vídeos,música, o cualquier otra cosa que Ud. desee "
+"catalogar.</h3><h3>Nuevasentradas pueden ser agregadas a su colección por "
+"<a href=\"tc:///coll_new_entry\">ingresando datos manualmente</a> o por <a "
+"href=\"tc:///edit_search_internet\">descargando datos</a> desde diversas "
+"fuentes en Internet.</h3>"
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Creando un nuevo documento..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Abriendo el archivo..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Abrir el archivo"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Guardando el archivo..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+"<qt><p>Está guardando un archivo con muchas imágenes, lo cual causa que "
+"Tellico se enlentezca considerablemente. ¿Desea guardar las imágenes por "
+"separado en la carpeta de datos de Tellico para mejorar el rendimiento?</p> "
+"<p>Siempre podrá modificar su elección desde la ventana de "
+"configuración</p></qt>"
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr "Guardar imágenes por separado"
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr "Guardar imágenes en archivo"
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Guardando el archivo con un nombre nuevo..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Imprimiendo..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"La colección está actualmente filtrada para que se muestre un subconjunto "
+"limitado de las entradas. Solo se imprimirán las entradas visibles. "
+"¿Continuar?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Procesando el documento..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Saliendo..."
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Total de entradas: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 filtrada(s);%2 seleccionada(s))"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 filtrada(s))"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 seleccionada(s))"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Imprimir %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Página %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Por favor, revise su instalación."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Importando datos..."
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Importación de un archivo"
+
+#: mainwindow.cpp:1864
+msgid "Import Directory"
+msgstr "Importación de un directorio"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Exportando datos..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Exportar como"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Macros de cadenas de texto"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Macro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Cadena de texto"
+
+#: mainwindow.cpp:1999
+msgid "Creating citations..."
+msgstr "Creando citas..."
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Filtros"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt>La <i>vista de filtros</i> muestra las entradas que cumplen ciertas "
+"reglas de filtrado.</qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Préstamos"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt>La <i>Vista de préstamos</i> muestra un listado de todas las personas "
+"que tienen prestados artículos de su colección.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr "Actualizar los datos de la entrada desde %1"
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+"Tellico solamente puede importar un archivo de este tipo a la vez.Solamente "
+"%1 será importado."
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico no es capaz de cargar la imagen - %1."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+"Ya existe un archivo llamado «%1». ¿Seguro qué desea sobrescribirlo?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "¿Sobrescribir el archivo?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Sobrescribir"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Filtro (ordenar por número)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "¿Realmente desea borrar esta entrada?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Borrar la entrada"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "¿Realmente desea borrar estas entradas?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Borrar varias entradas"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "&Editar Entradas..."
+
+#: controller.cpp:627
+msgid "D&uplicate Entries"
+msgstr "D&uplicar Entradas"
+
+#: controller.cpp:628
+msgid "&Update Entries"
+msgstr "Act&ualizar Entradas"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "Borrar Entra&das"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+"Los siguientes artículos ya están prestados, pero Tellico no acepta "
+"actualmente prestar un elemento varias veces. Serán eliminados de la lista "
+"de elementos a prestar."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Calendario predeterminado"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"De momento, Tellico sólo admite recursos de calendario local. El calendario "
+"activo está en una ubicación remota, así que no se añadirán sus "
+"préstamos."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Calendario activo"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 debe devolver «%2»"
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(Vacío)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - un gestor de colecciones para KDE"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "No reabrir el último archivo abierto"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Importar <filename> como un archivo de BibTeX"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Importar <filename> como un archivo MODS"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Importar <filename> como un archivo RIS"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Archivo a abrir"
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr "Guiones de fuentes de datos"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Iconos"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Autor de la biblioteca btparse"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr "Ejemplos de código e inspiración en general"
+
+#: main.cpp:50
+msgid "Author of libcsv library"
+msgstr "Autor de la biblioteca libcsv"
+
+#: main.cpp:52
+msgid "Author of rtf2html library"
+msgstr "Autor de la biblioteca rtf2html"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Campos de la colección"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Campos actuales"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "&Nuevo"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Añadir un nuevo campo a la colección"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "Borrar (&d)"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Eliminar un campo de la colección"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Mover este campo hacia arriba en la lista. El orden de la lista es muy "
+"importante para la disposición del editor de entradas."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Mover este campo hacia abajo en la lista. El orden de la lista es muy "
+"importante para la disposición del editor de entradas."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Propiedades del campo"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "&Título:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "El título del campo"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "Tipo (&y):"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "El tipo del campo determina que valores se pueden utilizar. "
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "Se usa <i>texto simple</i> para la mayoría de los campos. "
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "<i>Párrafo</i> es para bloques de textos largos. "
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Opción</i> limita el campo a ciertos valores. "
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "<i>Casilla de selección</i> es para valores simples de sí/no. "
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr "<i>Número</i> indica que el campo contiene un valor numérico. "
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+"<i>URL</i> es para los campos que hacen referencia a una URL, incluídas "
+"también referencias a otros archivos."
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr "Una <i>tabla</i> puede contener una o más columnas de valores. "
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "Un campo de <i>imagen</i> contiene una imagen. "
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+"Un campo de <i>fecha</i> se puede utilizar para valores con un día, mes y "
+"año. "
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+"Un campo de <i>valoración</i> usa estrellas para mostrar una calificación. "
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"Un campo <i>dependiente</i> depende de valores de otros campos y es "
+"formateado en función de la descripción del campo. "
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"Un campo de <i>sólo lectura</i> se usa para valores internos, que se pueden "
+"utilizar para importar y exportar. "
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "Cate&goría:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr "La categoría del campo determina la posición del campo en el editor."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "Descr&ipción:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"La descripción es útil para recordar qué información contiene el campo. "
+"Para los campos <i>dependientes</i>, la descripción es una cadena de "
+"formato como «%{year} %{title}» donde los campos nombrados son sustituidos "
+"en la cadena."
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr "Valor pre&determinado:"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr ""
+"<qt>Se puede establecer un valor predeterminado para las entradas "
+"nuevas.</qt>"
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr "Va&lores permitidos:"
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>Para los campos de tipo <i>elección</i>, éstos son los únicos valores "
+"permitidos. Son colocados en una lista desplegable. Los valores posibles "
+"tienen que estar separados por punto y coma, por ejemplo: «perro; gato; "
+"ratón».</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "&Propiedades extendidas:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "Configuración (&s)..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"Las propiedades extendidas de un campo se utilizan para definir cosas como "
+"el campo BibTeX correspondiente."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Opciones de formato"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Sin formato"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+"Esta opción impide que el campo sea formateado automáticamente o pasado a "
+"mayúsculas."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Permitir solamente el pase a mayúsculas automático"
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+"Esta opción permite pasar el campo a mayúsculas, pero sin formato especial."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Formato de título"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Esta opción pasa a mayúsculas y formatea el campo como un título, pero "
+"solamente si estas opciones están configuradas de forma global."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Formato de nombre"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Esta opción pasa a mayúsculas y formatea el campo como un nombre, pero "
+"solamente si estas opciones están configuradas de forma global."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Opciones de los campos"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Habilitar la terminación automática"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Si se marca, se habilitará la terminación automática de KDE en la caja de "
+"edición de texto de este campo."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Permitir varios valores"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Si se marca, Tellico analizará los valores del campo en busca de varios "
+"valores, separados por un punto y coma."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Permitir el agrupamiento"
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Si se marca, este campo se puede usar para agrupar las entradas en la vista "
+"de grupo."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr ""
+"Restaurar las propiedades de los campos seleccionados con los valores "
+"predefinidos."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Modificar los campos"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Eliminar los valores permitidos del campo <i>%1</i> que existe "
+"actualmente en la colección puede provocar corrupciones de datos. ¿Desea "
+"mantener los valores modificados o cancelar y volver a los actuales?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Conservar los valores modificados"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Restaurar las propiedades predefinidas del campo"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>¿Realmente desea devolver las propiedades del campo <em>%1</em> a "
+"sus valores predefinidos?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Devolver"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Propiedades extendidas del campo"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr ""
+"Ya existe un campo con este título. Por favor, introduzca un título "
+"diferente."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr ""
+"<qt>La categoría no puede estar vacía. Por favor, introduzca una "
+"categoría.</qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>Un campo no puede estar en la misma categoría que un campo "
+"<em>párrafo</em>, <em>tabla</em> o <em>imagen</em>. Por favor, introduzca "
+"otra categoría.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"El título de un campo no puede ser el mismo que el de una categoría "
+"existente. Por favor, introduzca otro título."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+"El intervalo de un campo de valoración debe ir entre 1 y 10, y el límite "
+"inferior debe ser menor que el límite superior. Por favor, introduzca otras "
+"propiedades inferior y superior."
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "Las tablas están limitadas a un máximo de diez columnas."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"El archivo actual ha sido modificado.\n"
+"¿Desea guardarlo?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Cambios sin guardar"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Seleccione un prestatario"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Configurar Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Opciones generales"
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr "&Reabrir el archivo al iniciar"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Si se marca, el último archivo abierto será cargado nuevamente cada vez "
+"que se inicie el programa."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "Mo&strar \"Consejo del día\" al iniciar"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr ""
+"Si se marca, se mostrará el «Consejo del día» al arrancar el programa."
+
+#: configdialog.cpp:213
+msgid "Image Storage Options"
+msgstr "Opciones de Almacenamiento de Imagen"
+
+#: configdialog.cpp:214
+msgid "Store images in data file"
+msgstr "Almacenar imágenes en archivo de datos"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr "Almacenar imágenes en carpeta común de la aplicación"
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr "Almacenar imágenes en una carpeta relativa a la del archivo de datos"
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+"Las imágenes deben ser guardadas dentro del archivo de datos, lo cual puede "
+"provocar que Tellico se ejecute lentamente; almacene las imágenes en la "
+"carpeta de Tellico o en una carpeta en la misma ubicación que el archivo de "
+"datos."
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Opciones de formato"
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr ""
+"Poner automáticamente en mayúsculas las iniciales de &títulos y nombres"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Si se marca, las iniciales de los títulos y nombres se escribirán "
+"automáticamente en mayúsculas."
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr "&Formatear automáticamente títulos y nombres"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr ""
+"Si se marca, los títulos y nombre serán formateados automáticamente."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr "No pasar a mayúsculas las iniciales (&z):"
+
+#: configdialog.cpp:243
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Una lista de palabras cuyas iniciales no deberían ponerse en "
+"mayúsculas. Los valores deben separarse con un punto y coma.</qt>"
+
+#: configdialog.cpp:249
+msgid "Artic&les:"
+msgstr "Artícu&los:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>Una lista de palabras que deberán considerarse como artículos si son "
+"la primera palabra de un título. Los valores deben separarse con un punto y "
+"coma.</qt>"
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr "Sufijos de nombre (&x):"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Una lista de sufijos que se pueden utilizar en nombres personales. Los "
+"valores deben separarse con un punto y coma.</qt>"
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr "&Prefijos de apellido:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Una lista de prefijos que suelen usarse en apellidos. Los valores deben "
+"separarse con un punto y coma.</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Impresión"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Opciones de impresión"
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr "&Formatear títulos y nombres"
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr "Im&primir las cabeceras de campo"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Opciones de agrupamiento"
+
+#: configdialog.cpp:313
+msgid "&Group the entries"
+msgstr "A&grupar las entradas"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Opciones de imagen"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr "Anchura máxima de imagen (&w):"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"La anchura máxima de las imágenes en la impresión. Se mantienen las "
+"proporciones."
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr "Altura &máxima de imagen:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"La altura máxima de las imágenes en la impresión. Se mantienen las "
+"proporciones."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Plantillas"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Opciones de las plantillas"
+
+#: configdialog.cpp:369
+msgid "Template:"
+msgstr "Plantilla:"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+"Seleccione la plantilla a utilizar para el tipo de colección actual. No "
+"todas las plantillas utilizaran los tipo de letra y color configurados."
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr "&Previsualizar..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr "Mostrar una previsualización de la plantilla"
+
+#: configdialog.cpp:398
+msgid "Font Options"
+msgstr "Opciones del tipo de letra"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr "Tipo de letra:"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr ""
+"Se pasa este tipo de letra a la plantilla usada en la Vista de entradas."
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr "Tamaño:"
+
+#: configdialog.cpp:425
+msgid "Color Options"
+msgstr "Opciones de color"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr "Color de fondo:"
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr "Se pasa este color a la plantilla usada en la Vista de entradas."
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr "Color del texto:"
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr "Color de realce:"
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr "Color del texto resaltado:"
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr "Gestionar las plantillas"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr "Instalar..."
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr "Pulse para instalar una nueva plantilla directamente."
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr "Descargar..."
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr ""
+"Pulse el botón para descargar plantillas adicionales a través de Internet."
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr "Borrar..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr "Pulse para seleccionar y eliminar las plantillas instaladas."
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Fuente de datos"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Opciones de fuente de datos"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Fuente"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr "Mover hacia arriba (&u)"
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+"El orden de las fuentes de datos define el orden que usa Tellico cuando se "
+"actualizan automáticamente las entradas."
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr "Mover hacia abajo (&d)"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "&Nuevo..."
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr "Pulse para añadir una nueva fuente de datos."
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Modificar..."
+
+#: configdialog.cpp:533
+msgid "Click to modify the selected data source."
+msgstr "Pulse para modificar la fuente de datos seleccionada."
+
+#: configdialog.cpp:536
+msgid "Click to delete the selected data source."
+msgstr "Pulse para borrar la fuente de datos seleccionada."
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr ""
+"Pulse para descargar fuentes de datos adicionales a través de Internet."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr "*.tar.gz *.tgz|Paquetes de plantillas (*.tar.gz)"
+
+#: configdialog.cpp:1049
+msgid "Delete Template"
+msgstr "Borrar la plantilla"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr "Seleccione la plantilla a borrar:"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "Prestatario"
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Devolución"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Modificar préstamo..."
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "Prestatarios (ordenados por número)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "Mi colección"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Colección de libros"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Colección de cómics"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Colección de vídeos"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Colección de música"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Colección de monedas"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Colección de sellos"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Colección de vinos"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Colección de cromos"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Colección de juegos"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr "Catálogo de archivos"
+
+#: collectionfactory.cpp:135
+msgid "Board Game Collection"
+msgstr "Colección de Juegos de Mesa"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Colección personalizada"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+"<qt>La <i>Vista de entradas</i> muestra una vista formateada del contenido "
+"de las entradas.</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt>La <i>Vista de iconos</i> muestra cada entrada de la colección o grupo "
+"usando un icono, que puede ser una imagen en la entrada.</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Opciones de exportación"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Formato"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Formatear todos los campos"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Si se marca, los valores de los campos se formatearán automáticamente "
+"según su tipo de formato."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Exportar solamente las entradas seleccionadas"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr ""
+"Si se marca, solamente se exportarán las entradas actualmente seleccionadas."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Codificación"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Codificar en Unicode (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Codificar el archivo exportado en Unicode (UTF-8)."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Codificar en la «locale» del usuario (%1)"
+
+#: exportdialog.cpp:72
+msgid "Encode the exported file in the local encoding."
+msgstr "Codificar el archivo exportado usando codificación local."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "Bu&scar"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "Detener (&s)"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Búsqueda en Internet"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Consulta de búsqueda"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr "Buscar (&e):"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+"Introducir un valor de búsqueda. Una búsqueda por ISBN debe contener el "
+"ISBN completo."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Escoja el tipo de búsqueda"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Pulse el botón para iniciar o detener la búsqueda"
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr "Búsqueda &múltiple de ISBN/UPC"
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr "Marque esta casilla para buscar múltiples valores de ISBN o UPC."
+
+#: fetchdialog.cpp:138
+msgid "Edit List..."
+msgstr "Editar lista..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+"Pulse el botón para abrir un cuadro de edición de texto para introducir o "
+"editar múltiples valores de ISBN."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "Fuente de búsqueda (&o):"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Seleccione la base de datos en la cual buscar"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"A medida que se van obteniendo resultados, se van agregando a la lista. "
+"Seleccionando uno de ellos, se obtendrá la entrada completa y se la "
+"mostrará en la vista de abajo."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"Antes de añadir una entrada a la colección actual, puede previsualizarse "
+"aquí seleccionándola en la lista superior"
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "&Agregar Entrada"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Añadir la entrada seleccionada a la colección actual"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr "Obtener más resultados"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr "Obtener más resultados de la fuente de datos actual"
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Limpiar todos los campos de búsqueda y los resultados"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Cancelando la búsqueda..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Buscando..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "La búsqueda no devolvió ningún resultado."
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+"La búsqueda devolvió 1 resultado.\n"
+"La búsqueda devolvió %n resultados."
+
+#: fetchdialog.cpp:412
+msgid "No results were found for the following ISBN values:"
+msgstr "No se encontraron resultados para los siguientes valores ISBN:"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Obteniendo %1..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr ""
+"No hay fuentes de Internet disponibles para su tipo de colección actual."
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr "Editar valores ISBN/UPC"
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Introduzca los valores ISBN o UPC, uno por linea.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "Cargar desde archivo (&l)..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Cargar la lista desde un archivo de texto.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>Una búsqueda ISBN puede contener un máximo de 100 valores ISBN. Sólo "
+"los se usarán los primeros 100 valores de la lista.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Editar la entrada"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Nueva Entrada"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "Guardar Entrada (&v)"
+
+#: entryeditdialog.cpp:77
+msgid "Go to the previous entry in the collection"
+msgstr "Ir a la anterior entrada de la colección"
+
+#: entryeditdialog.cpp:82
+msgid "Go to the next entry in the collection"
+msgstr "Ir a la siguiente entrada de la colección"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "¿Realmente quiere borrar estas entradas?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Modificar varias entradas"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr "Se requiere un valor para los siguientes campos. ¿Desea continuar?"
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Editar las entradas"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "Guardar Entradas (&v)"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"La entrada actual ha sido modificada.\n"
+"¿Quiere asentar los cambios?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Guardar la entrada"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Informe sobre la colección"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "Plantilla de info&rme:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "&Generar"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr "Seleccione una plantilla de informe y pulse <em>Generar</em>."
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+"Algunos informes pueden tomar varios segundos en generarse si la colección "
+"es muy grande."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "¿Realmente quiere borrar este filtro?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "¿Borrar el filtro?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Nuevo nombre de la colección:"
+
+#: tellico_kernel.cpp:377
+msgid "Entry 1"
+msgstr "Entrada 1"
+
+#: tellico_kernel.cpp:378
+msgid "Entry 2"
+msgstr "Entrada 2"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+"Se encontraron valores conflictivos para %1 mientras se fusionaban las "
+"entradas."
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr "Por favor, seleccione que valor mantener."
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+msgid "Merge Entries"
+msgstr "Fusionar entradas"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr "Seleccionar valor desde %1"
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico no puede localizar la hoja de estilo predeterminada."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Nuevo"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Colección"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Barra de colecciones"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Alejandro Hamann,Enrique Matías Sánchez (Quique),Jonathan Rivera"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "linkstat@gmail.com,cronopios@gmail.com,mdjinn31@yahoo.com"
+
+#: entrymerger.cpp:35
+msgid "Merging entries..."
+msgstr "Fusionando entradas..."
+
+#: entrymerger.cpp:49
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Totales de entradas fusionadas/exploradas: %1/%2"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>... qué si un libro tiene más de un autor, debería separar\n"
+"sus nombres por un punto y coma, para qué Tellico sepa cómo\n"
+"separarlos y usarlos por separado?</p>\n"
+"<p>Cualquier otro campo que permita valores múltiples\n"
+"deberá rellenarse de la misma manera,\n"
+"con un punto y coma (;) separando cada valor.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>... qué se pueden cambiar los campos qué se muestran\n"
+"en la «Vista de lista» pulsando con el botón derecho sobre las\n"
+"cabeceras de las columnas?\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>... qué se pueden añadir, editar o modificar los campos de la\n"
+"colección utilizando el «Editor de campos»?\n"
+"Los botones con flechitas que hay bajo la lista de campos se\n"
+"pueden usar para cambiar la posición del campo en dicha lista,\n"
+"lo que afectará el lugar donde se ubique dicho campo en el\n"
+"editor de entradas.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>... qué si se desea filtrar un campo consistente en una\n"
+"casilla de selección, se debe usar un valor de «verdadero»?</p>\n"
+"<p>Si se quisiera hacer un filtro para mostrar sólo, por ejemplo,\n"
+"los libros de Ciencia Ficción no leídos, marque la casilla\n"
+"<em>Coincide con todos los siguientes</em>, y configure la\n"
+"primera regla para que el «Género» «contenga» «Ciencia-Ficción»\n"
+"(todo sin comillas) y la segunda regla para que «Leído»\n"
+"«no contenga» «verdadero» (de nuevo sin comillas).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>... qué si se usa un carácter no alfanumérico en el «Filtro "
+"rápido»,\n"
+"el texto se interpretará como una expresión regular?</p>\n"
+"<p>Para mostrar sólo los libros que sean de Weber ó de Neruda,\n"
+"por ejemplo, escriba «weber|neruda» (sin comillas) en el campo "
+"Filtro.</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>... qué se puede editar a la vez más de una entrada, realizando\n"
+"una selección múltiple normal con las teclas Mayús ó Ctrl?</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>... qué se puede convertir una colección de libros en una "
+"bibliografía,\n"
+"con lo qué se podrá exportar a los formatos BibTeX o BibTeXML?</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>... qué puede añadir, editar y borrar macros de cadena para\n"
+"las bibliografías?</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>... qué si más de un campo tiene formato de nombre, se agrega a\n"
+"la colección un grupo adicional llamado «Gente», lo que permite qué,\n"
+"por ejemplo, los autores y editores sean ordenados y mostrados juntos?</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>... qué se puede cambiar la apariencia de la salida impresa\n"
+"modificando el archivo <tt>tellico-printing.xsl</tt>?\n"
+"El archivo genera HTML, y el código CSS de la hoja de estilos\n"
+"rige cosas como el tipo de letra, los márgenes, etc.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>... qué puede importar usando cualquier hoja de estilos XSL genérica\n"
+"qué produzca un archivo XML de Tellico válido?</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+"<p>... qué la doble pulsación sobre una entrada de la lista\n"
+"abre el «Editor de entradas»?</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>... qué puede añadir etiquetas HTML a cualquier campo del\n"
+"tipo «Párrafo» para formatear el texto, tales cómo "
+"&lt;b&gt;bold&lt;/b&gt; ó\n"
+"&lt;i&gt;italic&lt;/i&gt;?</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>... qué en la <i>Vista detallada</i> puede presionar\n"
+"una letra del teclado para saltar a la siguiente entrada\n"
+"qué comience con esa letra?</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+"<p>... qué puede usar campos dependientes para combinar varios campos\n"
+"separados en un único campo? Seleccione el tipo «Dependiente» y asígne\n"
+"una descripción similar a «Valor: %{campo-a}%{campo-b}» reemplazando\n"
+"%{...} por los valores adecuados del campo. Esto es útil para recoger "
+"varios\n"
+"campos en un único campo, por ejemplo para disponer de un mejor\n"
+"agrupamiento, y para combinar campos de diferentes tipos respetando la\n"
+"ordenación correcta al mismo tiempo. Considere por ejemplo un campo\n"
+" numérico seguido de un subcampo de texto con las entradas 3b y 14a.</p>\n"
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Álbum"
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr "Esta plantilla está pensada solamente para Colecciones de música."
+
+#: xslt.cpp:5
+msgid "Total:"
+msgstr "Total:"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr "Fantasía"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "Predeterminada"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Compacta"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Vídeo"
+
+#: xslt.cpp:14 xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr "Esta plantilla está pensada solamente para Colecciones de vídeo."
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Resumen de grupo"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Resumen de grupo"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Número total de campos:"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Número total de entradas:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+msgid "Generated by Tellico"
+msgstr "Generado por Tellico"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Valores distintos: "
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Lista de imágenes"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Vista de préstamos"
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Fecha de préstamo"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Nota"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Fecha de devolución"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Vista de grupo"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Listado de títulos (Horizontal)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Listado de títulos (Vertical)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Vista de columna"
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "Columna triple"
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr "Buscar"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr "La Biblioteca Británica"
+
+#: z3950.cpp:6
+msgid "Sudoc (France)"
+msgstr "Sudoc (Francia)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr "BIBSYS (Noruega)"
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr "Biblioteca Nacional de Italia"
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr "Biblioteca Nacional de Portugal"
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr "Biblioteca Nacional de Polonia"
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr "Biblioteca Nacional de Canadá"
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr "Israel Union List"
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr "Biblioteca Nacional de Australia"
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr "Biblioteca Nacional de Lituania"
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr "Copac (Reino Unido e Irlanda)"
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr "BoardGameGeek"
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr "Dark Horse Comics"
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr "Allocine.fr"
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr "Ministerio de Cultura de España"
diff --git a/po/fi.po b/po/fi.po
new file mode 100644
index 0000000..3d078b1
--- /dev/null
+++ b/po/fi.po
@@ -0,0 +1,5143 @@
+# translation of fi.po to Finnish
+# translation of tellico.po to Finnish
+# This file is distributed under the same license as the tellico package.
+# Teuvo Eloranta <teuvo -at- piketa.fi>, 2005.
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+# Teuvo Eloranta <teuvo -at- piketa.fi>, 2005.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: fi\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2008-03-04 15:25+0200\n"
+"Last-Translator: Teuvo Eloranta <not@valid.com>\n"
+"Language-Team: Finnish <fi@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Report-Msgid-Bugs-To: \n"
+"X-Generator: KBabel 1.10.2\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "<qt>Tellico ei pysty kirjoittamaan palvelimen putkeen: <b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr "Yhdistetään OpenOffice.org:iin..."
+
+#: cite/openoffice.cpp:165
+#: cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr "OpenOffice.org yhteys"
+
+#: cite/openoffice.cpp:179
+msgid "Tellico was unable to connect to OpenOffice.org. Please verify the connection settings below, and that OpenOffice.org Writer is currently running."
+msgstr "Tellico ei pystynyt ottamaan yhteyttä OpenOffice.org:iin. Ole hyvä ja varmista yhteyden asetukset alta. Varmista myös että OpenOffice.org Writer on käynnistetty."
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr "Putki"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr "TCP/IP"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr "Uudelleennimeä sarake"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr "Uusi sarakkeen nimi:"
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr "Sarake %1"
+
+#: gui/tablefieldwidget.cpp:241
+#: gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr "Uudelleennimeä sarake..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr "Lisää rivi"
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr "Poista rivi"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr "Siirrä rivi ylös"
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr "Siirrä rivi alas"
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr "Tyhjennä taulu"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr "Mallipohjan esikatselu"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Aseta"
+
+#: gui/fieldwidget.cpp:101
+#: gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr "%1:"
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Lisää"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Vähemmän"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Tyhjennä"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Valitse kuva..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr "Tallenna vain linkki"
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr "Linkin tallentaminen on mahdollista vain uusimmille lisätyille kuville."
+
+#: commands/modifyentries.cpp:73
+#: commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Muokkaa %1"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Lisää kokoelma perään"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Yhdistä kokoelma"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Korvaa kokoelma"
+
+#: commands/modifyentries.cpp:72
+#: entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr "Muokkaa tietueita"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "Lisää %1-kenttä"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Muokkaa %1-kenttää"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Tuhoa %1-kenttä"
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr "Lisää tietueita"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Lisää %1"
+
+#: commands/renamecollection.cpp:45
+#: tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Uudelleennimeä kokoelma"
+
+#: commands/modifyloans.cpp:75
+#: loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Muokkaa lainausta"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Lisää suodatin"
+
+#: commands/filtercommand.cpp:100
+#: filterdialog.cpp:282
+#: filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Muokkaa suodatinta"
+
+#: commands/filtercommand.cpp:102
+#: filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Tuhoa suodatin"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Lainaa nimikkeet"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Lainaa %1"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Tuhoa nimikkeet"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Tuhoa %1"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Uudelleenjärjestä kentät"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Palauta nimikkeet"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Palauta %1"
+
+#: collectionfactory.cpp:83
+#: collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58
+#: collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19
+#: collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40
+#: collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19
+#: collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19
+#: collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19
+#: collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19
+#: collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19
+#: configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689
+#: fetch/imdbfetcher.cpp:948
+#: field.cpp:40
+#: field.cpp:72
+#: translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Yleiset"
+
+#: collections/bookcollection.cpp:143
+#: collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Kunto"
+
+#: collections/boardgamecollection.cpp:20
+#: collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20
+#: collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22
+#: collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20
+#: collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22
+#: collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Henkilökohtainen"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Omat postimerkit"
+
+#: collectionfactory.cpp:82
+#: collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37
+#: collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37
+#: collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39
+#: collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76
+#: collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39
+#: collections/winecollection.cpp:37
+#: entryupdater.cpp:229
+#: fetch/fetchmanager.cpp:68
+#: fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164
+#: translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Nimeke"
+
+#: collections/boardgamecollection.cpp:77
+#: collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87
+#: collections/stampcollection.cpp:44
+#: entryupdater.cpp:230
+#: fetchdialog.cpp:170
+msgid "Description"
+msgstr "Kuvaus"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51
+#: collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Nimellisarvo"
+
+#: collections/coincollection.cpp:67
+#: collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55
+#: collections/winecollection.cpp:73
+msgid "Country"
+msgstr "Alkuperämaa"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Vuosiluku"
+
+#: collections/stampcollection.cpp:66
+#: collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Väri"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Scott-numero"
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr "Erinomainen,Erittäin hieno,Oikein hieno,Hieno,Keskiverto,Kehno"
+
+#: collections/coincollection.cpp:88
+#: collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Luokitus"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Leimattu"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Liimakkeella"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Keskitys"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Liimattu"
+
+#: collections/boardgamecollection.cpp:85
+#: collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82
+#: collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126
+#: collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86
+#: collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190
+#: collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Ostopäivämäärä"
+
+#: collections/boardgamecollection.cpp:94
+#: collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87
+#: collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131
+#: collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95
+#: collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199
+#: collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Ostohinta"
+
+#: collections/cardcollection.cpp:91
+#: collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114
+#: collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Sijainti"
+
+#: collections/boardgamecollection.cpp:90
+#: collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96
+#: collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139
+#: collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91
+#: collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195
+#: collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Lahja"
+
+#: collections/stampcollection.cpp:124
+#: field.cpp:497
+msgid "Image"
+msgstr "Kuva"
+
+#: collections/boardgamecollection.cpp:105
+#: collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115
+#: collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150
+#: collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111
+#: collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210
+#: collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Kommentit"
+
+#: collections/bibtexcollection.cpp:25
+#: collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20
+#: translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68
+#: translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Julkaisija"
+
+#: collections/bookcollection.cpp:21
+#: collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63
+#: translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Luokitus"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Omat sarjakuvat"
+
+#: collections/bookcollection.cpp:45
+#: collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Alaotsikko"
+
+#: collections/comicbookcollection.cpp:50
+#: collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Kirjoittaja"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr "Taiteilija"
+
+#: collections/bibtexcollection.cpp:200
+#: collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71
+#: collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Sarja"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Aihe"
+
+#: collections/bibtexcollection.cpp:120
+#: collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73
+#: collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Julkaisija"
+
+#: collections/bibtexcollection.cpp:133
+#: collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Versio"
+
+#: collections/bookcollection.cpp:90
+#: collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Julkaisuvuosi"
+
+#: collections/bibtexcollection.cpp:140
+#: collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Sivuja"
+
+#: collections/bookcollection.cpp:115
+#: collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Kieli"
+
+#: collections/boardgamecollection.cpp:43
+#: collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106
+#: collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67
+#: collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Tyylilaji"
+
+#: collections/bibtexcollection.cpp:222
+#: collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100
+#: collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103
+#: fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62
+#: translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Avainsanat"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr "Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+
+#: collections/bookcollection.cpp:147
+#: collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Signeerattu"
+
+#: collections/boardgamecollection.cpp:98
+#: collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143
+#: collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99
+#: collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Lainattu"
+
+#: collections/bookcollection.cpp:168
+#: collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216
+#: fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204
+#: translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Etukansi"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Omat kolikot"
+
+#: collections/coincollection.cpp:44
+#: collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Tyyppi"
+
+#: collections/bibtexcollection.cpp:145
+#: collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56
+#: collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Vuosiluku"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Rahapajan merkki"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Kolikkoryhmä"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very Good-8,Good-4,Fair"
+msgstr "Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very Good-8,Good-4,Fair"
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr "PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Luokituspalvelu"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Kuvapuoli"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Takapuoli"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Omat kirjat"
+
+#: collections/bibtexcollection.cpp:79
+#: collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Kirjailija"
+
+#: collections/bookcollection.cpp:57
+#: translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Kovakantinen"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Pehmeäkantinen"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Irtokantinen"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "E-kirja"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Lehti"
+
+#: collections/bibtexcollection.cpp:157
+#: collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Aikakauslehti"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Sidonta"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Tekijänoikeusvuosi"
+
+#: collections/bibtexcollection.cpp:151
+#: collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57
+#: translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN-numero"
+
+#: collections/bibtexcollection.cpp:154
+#: collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59
+#: translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Kansainvälinen ISBN-kirjanumero"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN-numero"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "LCCN, Hallintanumerokirjasto"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr "Kääntäjä"
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Sarjanumero"
+
+#: collections/bookcollection.cpp:142
+#: mainwindow.cpp:185
+msgid "New"
+msgstr "Uusi"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Käytetty"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Luettu"
+
+#: collections/boardgamecollection.cpp:80
+#: collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81
+#: collections/winecollection.cpp:102
+#: field.cpp:501
+#: newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Arvosana"
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr "Omat tiedostot"
+
+#: borrowerdialog.cpp:49
+#: collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "Nimi"
+
+#: collections/bibtexcollection.cpp:227
+#: collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400
+#: fetch/entrezfetcher.cpp:487
+#: field.cpp:495
+#: translators/gcfilmsimporter.cpp:77
+#: translators/risimporter.cpp:284
+msgid "URL"
+msgstr "Verkko-osoite (URL)"
+
+#: collections/bibtexcollection.cpp:207
+#: collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Osa"
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr "Kansio"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr "Mime-tyyppi"
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr "Koko"
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr "Oikeudet"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr "Omistaja"
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr "Ryhmä"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr "Luotu"
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr "Muokkattu"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr "Metatieto"
+
+#: collectionfieldsdialog.cpp:873
+#: collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Ominaisuus"
+
+#: collectionfieldsdialog.cpp:873
+#: collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Arvo"
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr "Kuvake"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Omat viinit"
+
+#: collections/videocollection.cpp:115
+#: collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Tuottaja"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Luokitus"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Päälajike"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Vuosikerta"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Punaviini"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Valkoviini"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Kuohoviini"
+
+#: collections/cardcollection.cpp:105
+#: collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Määrä"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Viimeinen juontipäivä"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Etiketin kuva"
+
+#: collections/videocollection.cpp:20
+#: fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Muut ihmiset"
+
+#: collections/videocollection.cpp:21
+#: fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Ominaisuudet"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Omat elokuvat"
+
+#: collections/musiccollection.cpp:44
+#: collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46
+#: fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr "Blu-ray"
+
+#: collections/videocollection.cpp:46
+#: fetch/amazonfetcher.cpp:826
+msgid "HD DVD"
+msgstr "HD DVD"
+
+#: collections/musiccollection.cpp:45
+#: collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Media"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Tuotantovuosi"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "7 vuotta,11 vuotta,12 vuotta, 15 vuotta,16 vuotta,18 vuotta"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Ikäraja"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Alue 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Alue 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Alue 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Alue 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Alue 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Alue 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Alue 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Alue 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Alue"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Kansallisuus"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Formaatti"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Roolit"
+
+#: collections/videocollection.cpp:102
+#: translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr "Näyttelijä/Näyttelijätär"
+
+#: collections/videocollection.cpp:103
+#: translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr "Rooli"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr "Taulukko näyttelijöistä rooleineen"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Ohjaaja"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Säveltäjä"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Studio"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Kieliraidat"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Tekstityskielet"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Ãäniraidat"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Kesto"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "Elokuvan kesto (minuutteina)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Kuvasuhde"
+
+#: collections/videocollection.cpp:167
+#: fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Laajakuva"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Mustavalkoinen"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Väritila"
+
+#: collections/videocollection.cpp:178
+#: fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Ohjaajan leikkaus"
+
+#: collections/videocollection.cpp:182
+#: fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Juonen yhteenveto"
+
+#: collections/gamecollection.cpp:90
+#: collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Oma arvosana"
+
+#: collections/boardgamecollection.cpp:102
+#: collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108
+#: collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Kansi"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "Omat pelit"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr "Xbox 360"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr "PlayStation3"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr "Nintendo Wii"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr "Linux"
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Alusta"
+
+#: collections/boardgamecollection.cpp:55
+#: collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Julkaisuvuosi"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Julkaisija"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Kehittäjä"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr "K-18, K-15, K-11, K-7, K-3"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "ESRB-määritys"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Loppuun pelattu"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Omat kortit"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Pelaaja"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Joukkue"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Merkki"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Kortin numero"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Kortin tyyppi"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Etupuolen kuva"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Takapuolen kuva"
+
+#: collections/boardgamecollection.cpp:26
+msgid "My Board Games"
+msgstr "Omat lautapelit"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr "Mekanismi"
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr "Suunnittelija"
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr "Pelaajien lukumäärä"
+
+#: collectionfactory.cpp:125
+#: collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Bibliografia"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Tietueen tyyppi"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr "Nämä tietuetyypit ovat erikoisia bibtex:lle. Katso bibtex:in dokumentaatio."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Bibtex-avain"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Kirjan nimi"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Kirjoittaja"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organisaatio"
+
+#: collections/bibtexcollection.cpp:127
+#: fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Osoite"
+
+#: collections/bibtexcollection.cpp:164
+#: fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr "DOI"
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr "Digital Object Identifier"
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Kuukausi"
+
+#: collections/bibtexcollection.cpp:178
+#: field.cpp:494
+msgid "Number"
+msgstr "Numero"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Julkaisutapa"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Kappale"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Ristiviite"
+
+#: collections/bibtexcollection.cpp:232
+#: fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413
+#: fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Tiivistelmä"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Muistiinpanot"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Oma musiikki"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Albumi"
+
+#: collections/musiccollection.cpp:44
+#: translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375
+#: translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "CD-levy"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Kasetti"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "LP-levy"
+
+#: collections/musiccollection.cpp:50
+#: collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165
+#: translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Taiteilija"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Levymerkki"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Ääniraidat"
+
+#: collections/musiccollection.cpp:78
+#: translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr "Pituus"
+
+#: core/tellico_config.cpp:134
+msgid "a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,up,with"
+msgstr "a,an,i,in,och,of,the,till,to"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "the"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr.,jr,iii,iv"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,van,der,van der,von"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr "ISBNdb.com"
+
+#: fetch/amazonfetcher.cpp:192
+#: fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83
+#: fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67
+#: fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102
+#: fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79
+#: fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 ei salli etsimistä tälle kokoelmatyypille."
+
+#: fetch/amazonfetcher.cpp:562
+#: fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Tulokset: %1: %2/%3"
+
+#: fetch/animenfofetcher.cpp:370
+#: fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198
+#: fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466
+#: fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342
+#: fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "Tällä lähteellä ei ole valintoja."
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "Entrez-tietokanta"
+
+#: fetch/entrezfetcher.cpp:485
+msgid "Institution"
+msgstr "Instituutio"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Kysely-virhe!"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Hakuvirhe yhteydessä %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Syntaksivirhe"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Yhteysvirhe %1: %2"
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr "SRU-palvelin"
+
+#: fetch/srufetcher.cpp:405
+#: z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Library of Congress (Yhdysvallat)"
+
+#: fetch/imdbfetcher.cpp:1121
+#: fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr "&Isäntä: "
+
+#: fetch/srufetcher.cpp:435
+#: fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr "Anna palvelimen isäntänimi."
+
+#: fetch/srufetcher.cpp:440
+#: fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Portti: "
+
+#: fetch/srufetcher.cpp:445
+#: fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Anna palvelimen porttinumero. Oletusnumero on %1."
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr "&Polku:"
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr "Anna polku palvelimen käyttämään tietokantaan."
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr "Formaatti:"
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr "Anna palvelimen palauttaman vastauksen muoto"
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr "Yahoo! Äänihaku"
+
+#: fetch/amazonfetcher.cpp:730
+#: fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "Kansikuvaa ei voitu ladata."
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr "Amazon-linkki"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (Yhdysvallat)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (Iso-Britannia)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Saksa)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japani)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (Ranska)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Kanada)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Amazon.com"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "Alkup&erämaa"
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "Yhdysvallat"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Iso-Britannia"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Saksa"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Japani"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "Ranska"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Kanada"
+
+#: fetch/amazonfetcher.cpp:860
+msgid "Amazon.com provides data from several different localized sites. Choose the one you wish to use for this data source."
+msgstr "Amazon.com tarjoaa tietoa monista lokalisoiduista lähteistä. Valitse käytettävä lähde."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "&Kuvan koko: "
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Pieni kuva"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Keskikokoinen kuva"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Iso kuva"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Ei kuvaa"
+
+#: fetch/amazonfetcher.cpp:875
+#: fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid "The cover image may be downloaded as well. However, too many large images in the collection may degrade performance."
+msgstr "Myös kansikuva voidaan hakea. Huomaa kuitenkin että kokoelman sisältäessä monia isoja kuvia, sen käyttönopeus voi hidastua."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "Käyttäjän tunnus:"
+
+#: fetch/amazonfetcher.cpp:886
+msgid "The associate's id identifies the person accessing the Amazon.com Web Services, and is included in any links to the Amazon.com site."
+msgstr "Käyttäjän tunnusta (ID) käytetään Amazon.com:in web-palvelussa tunnistautumiseen. Se sisältyy myös jokaiseen Amazon.com:iin viittaavaan linkkiin."
+
+#: fetch/z3950fetcher.cpp:79
+#: fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr "z39.50-palvelin"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr "Käytä &esiasetettua palvelinta:"
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "&Tietokanta: "
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr "Anna palvelimen käyttämän tietokannan nimi."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "Ki&rjainmerkistö:"
+
+#: fetch/z3950fetcher.cpp:544
+msgid "Enter the character set encoding used by the z39.50 server. The most likely choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr "Anna z39.50-palvelimen kirjainmerkistön koodaustapa. Todennäköisin vaihtoehto on MARC-8, tosin myös ISO-8859-1 on yleinen."
+
+#: fetch/z3950fetcher.cpp:550
+msgid "&Format: "
+msgstr "&Formaatti:"
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr "Automaattinen tunnistaminen"
+
+#: fetch/z3950fetcher.cpp:561
+msgid "Enter the data format used by the z39.50 server. Tellico will attempt to automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr "Anna z39.50-palvelimen käyttämä tietomuoto. Tellico yrittää automaattisesti tunnistaa parhaan asetuksen jos <i>Automaattinen tunnistaminen</i> on valittu."
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "&Käyttäjä: "
+
+#: fetch/z3950fetcher.cpp:570
+#: fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Valinnainen"
+
+#: fetch/z3950fetcher.cpp:573
+msgid "Enter the authentication user name used by the z39.50 database. Most servers do not need one."
+msgstr "Anna z39.50-tietokannan käyttämä sisäänkirjautumistunnus. Useimmat palvelimet eivät tarvitse tunnusta ollenkaan."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "&Salasana: "
+
+#: fetch/z3950fetcher.cpp:586
+msgid "Enter the authentication password used by the z39.50 database. Most servers do not need one. The password will be saved in plain text in the Tellico configuration file."
+msgstr "Anna z39.50-tietokannan käyttämä sisäänkirjautumissalasana. Useimmat palvelimet eivät tarvitse salasanaa ollenkaan. Salasana tallennetaan normaalina näkyvänä tekstinä Tellicon asetustiedostoon."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr "Kuvittaja"
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Ulkoinen ohjelma"
+
+#: configdialog.cpp:363
+#: fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398
+#: translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "Kokoelman tyyppi:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid "Set the collection type of the data returned from the external application."
+msgstr "Aseta ulkoisen sovelluksen palauttaman kokoelman tyyppi."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr "&Tuloksen tyyppi:"
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr "Aseta ulkoisen sovelluksen palauttaman tiedon tyyppi."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "&Polku sovellukseen:"
+
+#: fetch/execexternalfetcher.cpp:375
+msgid "Set the path of the application to run that should output a valid Tellico data file."
+msgstr "Aseta polku ajettavaan sovellukseen joka tekee validin Tellico-tietoa sisältävän tiedoston."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr "Valitse tietolähteen tukemat hakuavaimet"
+
+#: fetch/execexternalfetcher.cpp:381
+msgid "Add any arguments that may be needed. <b>%1</b> will be replaced by the search term."
+msgstr "Lisää tarvittavat argumentit. <b>%1</b> korvataan hakutermeillä."
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr "Argumentit"
+
+#: fetch/execexternalfetcher.cpp:415
+#: newstuff/dialog.cpp:152
+msgid "Update"
+msgstr "Päivitä"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid "<p>Enter the arguments which should be used to search for available updates to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, where field values are contained inside braces, such as <i>%{author}</i>. See the documentation for details.</p>"
+msgstr "<p>Anna saatavilla olevien päivitysten etsimiseen käytettävät argumentit.</p><p>Muoto on sama kuin <i>Riippuvainen</i> -kentille, missä kenttien arvot annetaan sulkeiden sisällä, kuten esim: <i>%{author}</i> Katso Tellicon dokumentoinnista lisätietoja.</p>"
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Tietolähteen asetukset"
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr "Saatavilla olevat kentät"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "Internet Movie Database"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Valitse IMDB-hakutulos"
+
+#: fetch/imdbfetcher.cpp:581
+msgid "<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr "<qt>Hakusi tuotti useita tuloksia. Valitse niistä yksi alta.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Valitse hakutulos.</qt>"
+
+#: fetch/imdbfetcher.cpp:688
+#: fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr "IMDB-linkki"
+
+#: fetch/animenfofetcher.cpp:260
+#: fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Vaihtoehtoiset otsikot"
+
+#: fetch/imdbfetcher.cpp:947
+#: fetch/imdbfetcher.cpp:1186
+msgid "IMDB Rating"
+msgstr "IMDB-arvosana"
+
+#: fetch/imdbfetcher.cpp:1065
+#: fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Ikärajat"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid "The Internet Movie Database uses several different servers. Choose the one you wish to use."
+msgstr "Interned Movie Database käyttää useita palvelimia. Valitse mitä niistä haluat käyttää."
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr "&Näyttelijöiden maksimimäärä:"
+
+#: fetch/imdbfetcher.cpp:1137
+msgid "The list of cast members may include many people. Set the maximum number returned from the search."
+msgstr "Lista näyttelijöistä voi sisältää varsin monta nimeä. Aseta haun palauttama suurin näyttelijämäärä."
+
+#: fetch/discogsfetcher.cpp:679
+#: fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr "Lataa &kansikuva"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr "Internet Bookshop (ibs.it)"
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Henkilö"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN-numero"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr "UPC/EAN"
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Avainsana"
+
+#: fetch/fetchmanager.cpp:74
+#: translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr "arXiv ID"
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr "Pubmed ID"
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Raakahaku"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr "Alkuperäinen otsikko"
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr "Jakelija"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr "Episodit"
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr "arXiv.org"
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr "%1 vaatii käyttäjänimen ja salasanan."
+
+#: fetch/crossreffetcher.cpp:332
+msgid "CrossRef requires an account for access. Please read the terms and conditions and <a href='http://www.crossref.org/requestaccount/'>request an account</a>. Enter your OpenURL account information below."
+msgstr "CrossRef vaatii käyttäjätilin luonnin. Ole hyvä ja lue paljvelun ehdot ja <a href='http://www.crossref.org/requestaccount/'>pyydä käyttäjätiliä</a>. Kirjoita OpenURL osoitteesi alle."
+
+#: fetch/crossreffetcher.cpp:343
+msgid "&Username: "
+msgstr "&Käyttäjänimi:"
+
+#: fetch/crossreffetcher.cpp:348
+msgid "A username and password is required to access the CrossRef service. The password is stored as plain text in the Tellico configuration file."
+msgstr "Käyttäjänimi ja salasana vaaditaan CrossRef-palvelun käyttöön. Salasana on talletettu tekstimuodossa Tellicon asetukset-tiedostossa."
+
+#: fetch/crossreffetcher.cpp:354
+msgid "&Password: "
+msgstr "&Salasana:"
+
+#: fetch/gcstarpluginfetcher.cpp:190
+msgid "GCstar Plugin"
+msgstr "GCstar Liitännäinen"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr "Aseta liitännäisen palauttamalle tiedolle kokoelman tyyppi."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr "&Liitännäinen:"
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr "Valitse GCstar-liitännäinen tiedon lähteeksi."
+
+#: fetch/gcstarpluginfetcher.cpp:420
+#, fuzzy
+msgid "Author: "
+msgstr "Tekijä: "
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr "Discogs äänihaku"
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr "API &Avain: "
+
+#: fetch/discogsfetcher.cpp:674
+msgid "With your discogs.com account you receive an API key for the usage of their XML-based interface (See http://www.discogs.com/help/api)."
+msgstr "discogs.com tilisi avulla vastaanotat API avaimen jolla voit käyttää palvelun XML-pohjaista käyttöliittymää (ks. http://www.discogs.com/help/api)."
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr "Discogs linkki"
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr "Hae uusia kuumia juttuja"
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr "Versio"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr "Lataukset"
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr "Julkaisupäivä"
+
+#: newstuff/dialog.cpp:121
+msgid "This is a list of all the items available for download. Previously installed items have a checkmark icon, while items with new version available have an update icon"
+msgstr "Tässä on lista kaikista ladattavissa olevista nimikkeistä. Jo aiemmin asennettujen kohdalla näytetään valintarasti ja niissä asennetuista joista on tarjolla uudempi versio näytetään päivityskuvake."
+
+#: newstuff/dialog.cpp:137
+msgid "The name and license of the selected item"
+msgstr "Valitun nimikkeen nimi ja lisenssi"
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr "Valitun nimikkeen tekijä"
+
+#: newstuff/dialog.cpp:142
+#: newstuff/dialog.cpp:396
+msgid "Install"
+msgstr "Asenna"
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr "Lataa ja asenna valittu mallipohja"
+
+#: newstuff/dialog.cpp:164
+msgid "Download and install the selected script. Some scripts may need to be configured after being installed."
+msgstr "Lataa ja asenna valittu skripti. Joitain skriptejä saattaa joutua konfiguroimaan asennuksen jälkeen."
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr "Tässä näytetään valitun nimikkeen kuvaus"
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr "Ladataan tietoa..."
+
+#: controller.cpp:135
+#: fetchdialog.cpp:226
+#: fetchdialog.cpp:333
+#: fetchdialog.cpp:451
+#: fetchdialog.cpp:506
+#: newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324
+#: newstuff/dialog.cpp:434
+#: statusbar.cpp:83
+msgid "Ready."
+msgstr "Valmis."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr "Päivitä"
+
+#: newstuff/dialog.cpp:413
+msgid "Installing item..."
+msgstr "Asennetaan nimikettä..."
+
+#: translators/bibteximporter.cpp:79
+msgid "No valid bibtex entries were found"
+msgstr "Valideja bibtex-tietueita ei löytynyt"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "Säännönmukaisia Bibtex-tietueita ei löytynyt tiedostosta - %1"
+
+#: translators/bibtexexporter.cpp:200
+#: translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Bibtex asetukset"
+
+#: translators/bibteximporter.cpp:287
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Käytä Unicode-muotoa (UTF-8)"
+
+#: translators/bibteximporter.cpp:288
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Lue tuotu tiedosto Unicodena (UTF-8)."
+
+#: translators/bibteximporter.cpp:289
+msgid "Use user locale (%1) encoding"
+msgstr "Käytä käyttäjän omaa muotoa (%1) enkoodauksessa"
+
+#: translators/bibteximporter.cpp:293
+msgid "Read the imported file in the local encoding."
+msgstr "Lue tuotu tiedosto paikallisella enkoodauksella."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "Tellico ZIP-tiedosto"
+
+#: importdialog.cpp:245
+#: mainwindow.cpp:1101
+#: mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Tellico-tiedostot (*.tc)"
+
+#: configdialog.cpp:1017
+#: importdialog.cpp:297
+#: mainwindow.cpp:1105
+#: mainwindow.cpp:1269
+#: reportdialog.cpp:195
+#: translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40
+#: translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41
+#: translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67
+#: translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60
+#: translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41
+#: translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Kaikki tiedostot"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid "<qt>An Alexandria library called <i>%1</i> already exists. Any existing books in that library could be overwritten.</qt>"
+msgstr "<qt><i>%1</i>-niminen Alexandria-kirjasto on jo olemassa. Kaikki siinä olevat kirjat voidaan ylikirjoittaa.</qt>"
+
+#: filehandler.cpp:141
+#: translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43
+#: translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "Virhe XML:n tulkkauksessa. Virhe rivillä %1, sarakkeessa %2."
+
+#: filehandler.cpp:143
+#: translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45
+#: translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "Qt:n virheilmoitus:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Tämä on Boocasen tulevia versioita varten."
+
+#: translators/tellicoimporter.cpp:162
+msgid "Tellico is converting the file to a more recent document format. Information loss may occur if an older version of Tellico is used to read this file in the future."
+msgstr "Tellico muuttaa tiedostoa uudempaan muotoon. Tietoja saattaa hävitä jos jatkossa vanhempaa Tellico-ohjelmaa käytetää tämän tiedoston lukemiseen."
+
+#: translators/bibtexhandler.cpp:245
+#: translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290
+#: translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Tuntematon"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "Tiedosto on tyhjä"
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "Tiedosto ei sisällä kokoelma-tietoa."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Lukemattomat kirjat"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Vanhat elokuvat"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "80-luvun musiikki"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Suosikit"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Selataan äänitiedostoja..."
+
+#: translators/audiofileimporter.cpp:129
+msgid "Bitrate"
+msgstr "Bittinopeus"
+
+#: translators/audiofileimporter.cpp:160
+#: translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr "Raidat (Disc %1)"
+
+#: translators/audiofileimporter.cpp:189
+#: xslt.cpp:4
+msgid "(Various)"
+msgstr "(Sekalaisia)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Äänitiedoston asetukset"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Rekursiivinen hakemistoetsintä"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr "Jos valittu, äänitiedostoja etsitään hakemistorakenteesta rekursiivisesti."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr "&Sisällytä tiedoston sijainti"
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr "Jos valittu, jokaisen kappaleen tiedostonimi lisätään tietueisiin."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr "Sisällytä &bittinopeus"
+
+#: translators/audiofileimporter.cpp:353
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr "Jos valittu, jokaisen raidan bittinopeus lisätään tietueisiin."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254
+#: translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|CSV-tiedostot (*.csv)"
+
+#: translators/csvexporter.cpp:109
+#: translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "CSV-asetukset"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Sisällytä kenttien nimet sarakkeiden otsikkoina."
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr "Jos valittu, otsikokkorivi lisätään kenttien nimien kanssa."
+
+#: translators/csvexporter.cpp:117
+#: translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Erotin"
+
+#: translators/csvexporter.cpp:120
+#: translators/csvimporter.cpp:243
+msgid "In addition to a comma, other characters may be used as a delimiter, separating each value in the file."
+msgstr "Pilkun lisäksi muitakin merkkejä voidaan käyttää erottimina jotka erottavat kentän arvot toisistaan."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Pilkku"
+
+#: translators/csvexporter.cpp:126
+#: translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Käytä pilkkua erottimena."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Puolipiste"
+
+#: translators/csvexporter.cpp:131
+#: translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Käytä puolipistettä erottimena."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Sarkain"
+
+#: translators/csvexporter.cpp:136
+#: translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Käytä sarkainta erottimena."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Muu"
+
+#: translators/csvexporter.cpp:141
+#: translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Käytä muuta merkkijonoa erottimena."
+
+#: translators/csvexporter.cpp:146
+#: translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr "Muuta merkkijonoa, kuten välilyöntiä, voidaan käyttää erottimena."
+
+#: translators/filelistingimporter.cpp:63
+msgid "Scanning files..."
+msgstr "Selataan tiedostoja..."
+
+#: translators/filelistingimporter.cpp:191
+msgid "File Listing Options"
+msgstr "Tiedostojen listausasetukset"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr "Rekursiivinen hakemistoetsintä"
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr "Jos valittu, tiedostoja etsitään kansioista rekursiivisesti"
+
+#: translators/filelistingimporter.cpp:198
+msgid "Generate file previews"
+msgstr "Luo tiedostoille esikatselut"
+
+#: translators/filelistingimporter.cpp:199
+msgid "If checked, previews of the file contents are generated, which can slow down the folder listing."
+msgstr "Jos valittu, tiedostojen sisällöistä luodaan esikatselut. Tämä saattaa hidastaa hakemiston listausta."
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "ONIX-paketti"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.zip|Zip-tiedostot (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "ONIX-paketin asetukset"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Sisällytä kuvat pakettiin"
+
+#: translators/onixexporter.cpp:181
+msgid "If checked, the images in the document will be included in the zipped ONIX archive."
+msgstr "Jos valittu, dokumentin kuvat sisällytetään zipattuun ONIX-pakettiin."
+
+#: translators/freedbimporter.cpp:84
+#: translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr "<qt>Tellico ei pystynyt käyttämään CD-ROM-laitetta: <b>%1</b>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+msgid "Select CDDB Entry"
+msgstr "Valitse CDDB-tietue"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr "Valitse CDDB-tietue"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>CD-levyä vastaavia hakutuloksia ei löytynyt.</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "<qt>Tellico ei pystynyt suorittamaan CD-hakua loppuun.</qt>"
+
+#: translators/freedbimporter.cpp:470
+msgid "Various"
+msgstr "Sekalaisia"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Ääni-CD:n asetukset"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Lue tietoa CD-ROM:lta"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Valitse tai syötä CD-ROM-laitteen sijainti."
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Lue vain kaikki CDDB-välimuistitiedostot"
+
+#: translators/freedbimporter.cpp:503
+msgid "Read data recursively from all the CDDB cache files contained in the default cache folders."
+msgstr "Lue rekursiivisesti tietoa kaikista CDDB-välimuistitiedostoista oletusvälimuistihakemistosta."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr "GCfilms"
+
+#: importdialog.cpp:273
+#: translators/gcfilmsexporter.cpp:41
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.gcf|GCF-tiedostot (*.gcf)"
+
+#: importdialog.cpp:272
+#: translators/gcfilmsexporter.cpp:43
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.gcs|GCstar-tiedostot (*.gcs) "
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69
+#: translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "XSLT-asetukset"
+
+#: translators/xsltexporter.cpp:74
+#: translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "XSLT-tiedosto:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr "Valitse Tellico XML-tiedon muuttamiseen käytettävä XSLT-tiedosto."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Alexandria-asetukset"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr "&Kirjasto:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "Bibtexml"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Bibtexml-tiedostot (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246
+#: importdialog.cpp:259
+#: importdialog.cpp:264
+#: mainwindow.cpp:1103
+#: translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|XML-tiedostot (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Tellico XML-asetukset"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Sisällytä kuvat XML-dokumenttiin"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid "If checked, the images in the document will be included in the XML stream as base64 encoded elements."
+msgstr "Jos valittu, dokumentin kuvat sisällytetään XML:ään base64-koodattuina elementteinä."
+
+#: translators/importer.h:100
+msgid "Loading data..."
+msgstr "Ladataan tietoja..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr "Ladataan %1..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "Bibtex"
+
+#: importdialog.cpp:250
+#: translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Bibtex-tiedostot (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Laajenna merkkijonomakrot"
+
+#: translators/bibtexexporter.cpp:205
+msgid "If checked, the string macros will be expanded and no @string{} entries will be written."
+msgstr "Jos valittu, merkkijonomakrot laajennetaan eikä @sring{} -esiintymiä kirjoiteta."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Käytä verkko-osoite (URL) -pakettia"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr "Jos valittu, kaikki verkko-osoite -kentät sijoitetaan \\url määritykseen."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Ohita tietueet joissa on tyhjä sitaattiavain"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr "Jos valittu, kaikki tietueet joissa ei ole bibtex-sitaattiavainta ohitetaan."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Bibtex:in sitaatin tyyli:"
+
+#: translators/bibtexexporter.cpp:221
+#: translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Sulkumerkit"
+
+#: translators/bibtexexporter.cpp:222
+#: translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Lainausmerkit"
+
+#: translators/bibtexexporter.cpp:223
+msgid "<qt>The quotation style used when exporting bibtex. All field values will be escaped with either braces or quotation marks.</qt>"
+msgstr "<qt>Sitaatin tyyli vietäessä bibtex:nä. Kaikki kenttien arvot laitetaan joko sulkeiden tai lainausmerkkien sisään.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Valitse tuotavan kokoelman tyyppi."
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr "&Kenttien nimet ensimmäisessä rivissä"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr "Jos valittu, ensimmäistä riviä käytetään kenttien niminä."
+
+#: translators/csvimporter.cpp:248
+msgid "&Comma"
+msgstr "Pil&kku"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr "&Puolipiste"
+
+#: translators/csvimporter.cpp:259
+msgid "Ta&b"
+msgstr "Sa&rkain"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr "&Muu:"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "Taulukossa näkyy ensimmäiset viisi riviä CSV-tiedostosta."
+
+#: translators/csvimporter.cpp:296
+msgid "<qt>Set each column to correspond to a field in the collection by choosing a column, selecting the field, then clicking the <i>Assign Field</i> button.</qt>"
+msgstr "<qt>Määritä jokainen sarake vastaamaan kokoelman kenttää valitsemalla ensin sarake, sitten kenttä ja klikkaamalla lopuksi<i>Määritä kenttä</i>-nappulaa.</qt>"
+
+#: translators/csvimporter.cpp:298
+msgid "Co&lumn:"
+msgstr "&Sarake:"
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr "&Tietokenttä tässä sarakkeessa:"
+
+#: translators/csvimporter.cpp:315
+msgid "&Assign Field"
+msgstr "&Määritä kenttä"
+
+#: translators/csvimporter.cpp:347
+msgid "At least one column must be assigned to a field. Only assigned columns will be imported."
+msgstr "Ainakin yksi sarake pitää olla määritetty johonkin kenttään. Vain määritetyt sarakkeet voidaan tuoda."
+
+#: collectionfieldsdialog.cpp:409
+#: collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396
+#: translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Uusi kenttä"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|Pilot-tietokantatiedostot (*.pdb)"
+
+#: detailedlistview.cpp:67
+#: detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Näytä sarakkeet"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "PilotDB-asetukset"
+
+#: translators/pilotdbexporter.cpp:213
+#: translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Aseta PDA varmuuskopio-asetus tietokannalle"
+
+#: translators/gcfilmsimporter.cpp:110
+#: translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>Tiedosto ei ole validi GCstar-tiedosto</qt>"
+
+#: mainwindow.cpp:1738
+#: translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "XSLT:n käsittelyssä tapahtui virhe."
+
+#: translators/xsltimporter.cpp:64
+#: translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "Tiedoston tuomiseen tarvitaan säännönmukainen XSLT-tiedosto."
+
+#: configdialog.cpp:1015
+#: translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|XSL-tiedostot (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195
+#: translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|HTML-tiedostot (*.html)"
+
+#: groupview.cpp:479
+#: mainwindow.cpp:1591
+#: mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Ihmiset"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(lajiteltu %1 mukaan)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "HTML-asetukset"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Tulosta kenttien otsikot"
+
+#: configdialog.cpp:307
+#: translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr "Jos valittu, kentän nimet tulostetaan taulun otsikkotietoina."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Ryhmittele tietueet"
+
+#: configdialog.cpp:314
+#: translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr "Jos valittu, tietueet ryhmitellään valitun kentän perusteella."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Vie yksittäisiä tietue-tiedostoja"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr "Jos valittu, jokaiselle tietueelle luodaan yksittäiset tiedostot."
+
+#: translators/pdfimporter.cpp:92
+#: translators/pdfimporter.cpp:100
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico ei pystynyt lukemaan metadataa PDF-tiedostosta."
+
+#: translators/pdfimporter.cpp:231
+msgid "Tellico is able to download information about entries with a DOI from CrossRef.org. However, you must create an CrossRef account and add a new data source with your account information."
+msgstr "Tellico voi ladata tietoa tietueista DOI:n avulla CrossRef.org:sta. Huomaa kuitenkin, että sinun pitää luota CrossRef-tili ja lisätä uusi tietolähde tilisi tiedoilla."
+
+#: fetcherconfigdialog.cpp:39
+#: fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Tietolähteen ominaisuudet"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "Tietolähteen &nimi: "
+
+#: fetcherconfigdialog.cpp:79
+msgid "The name identifies the data source and should be unique and informative."
+msgstr "Nimi määrittää tietolähteen nimen. Sen tulisi olla yksilöllinen ja informatiivinen."
+
+#: fetcherconfigdialog.cpp:90
+#: fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "Tietolähteen tyyppi: "
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr "Tellico tukee useita eri tietolähteitä"
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr "Tietolähteestä päivittäminen ylikirjoittaa aiemman tiedon"
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr "Jos valittu, tietueiden päivitys ylikirjoittaa kaiken olemassa olevan tiedon"
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Mikä tahansa kenttä"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "sisältää"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "ei sisällä"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "yhtä suuri kuin"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "erisuuri kuin"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "säännönmuk. lauseke sopii"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "säännönmuk. lauseke ei sovi"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Muokkaa..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Tarkempi suodatin"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Suodattimen arvo"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Sopii kaikkiin &seuraaviin"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Sopii mi&hin tahansa seuraavista"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Suodattimen nimi:"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "Tallenna &suodatin"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Tavallinen teksti"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Kappale"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Vaihtoehto"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Valintaruutu"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Taulu"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Riippuvainen"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Päivämäärä"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr "Päivitetään %1..."
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr "Päivitetään tietueita..."
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr "Päivitä tietueet"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr "Päivitetään <b>%1</b>..."
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr "Valitse osuma"
+
+#: entryupdater.cpp:217
+msgid "<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the entry currently in the collection. Please select the correct match.</qt>"
+msgstr "<qt><b>%1</b> palautti useita tuloksia jotka vastaavat <b>%2</b>, eli nykyistä kokoelman tietuetta. Ole hyvä ja valitse oikea tulos.</qt>"
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Laajenna kaikki ryhmät"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Supista kaikki ryhmät"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Suodata ryhmän mukaan"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (Järjestetty lukumäärän mukaan)"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Ryhmä"
+
+#: importdialog.cpp:54
+#: importdialog.cpp:60
+msgid "Import Options"
+msgstr "Tuonnin asetukset"
+
+#: importdialog.cpp:62
+msgid "&Replace current collection"
+msgstr "&Korvaa nykyinen kokoelma"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr "Korvaa nykyinen kokoelma tuodun tiedoston sisällöllä."
+
+#: importdialog.cpp:65
+msgid "A&ppend to current collection"
+msgstr "&Lisää nykyiseen kokoelmaan"
+
+#: importdialog.cpp:66
+msgid "Append the contents of the imported file to the current collection. This is only possible when the collection types match."
+msgstr "Lisää tuodun tiedoston nykyiseen kokoelmaan. Tämä on mahdollista vain kun kokoelmien tietuerakenteet ovat identtisiä."
+
+#: importdialog.cpp:69
+msgid "&Merge with current collection"
+msgstr "&Yhdistä nykyiseen kokoelmaan"
+
+#: importdialog.cpp:70
+msgid "Merge the contents of the imported file to the current collection. This is only possible when the collection types match. Entries must match exactly in order to be merged."
+msgstr "Yhdistää tuodun kokoelman nykyiseen kokoelmaan. Tämä on mahdollista vain mikäli kokoelmien tietuerakenteet ovat identtisiä. Tietueiden on oltava tarkalleen toistensa kaltaiset."
+
+#: importdialog.cpp:95
+#: mainwindow.cpp:318
+#: rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "T&uo"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|RIS-tiedostot (*.ris)"
+
+#: importdialog.cpp:277
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.amc|AMC-tiedostot (*.amc)"
+
+#: importdialog.cpp:281
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdf|PDF-tiedostot (*.pdf)"
+
+#: importdialog.cpp:285
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.reflib|Referencer-tiedostot (*.reflib)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico ei pysty lataamaan tiedostoa - %1."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico ei pysty kirjoittamaan tiedostoa - %1."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico ei pysty siirtämään tiedostoa - %1."
+
+#: tellico_strings.cpp:21
+msgid "Only collections with the same type of entries as the current one can be appended. No changes are being made to the current collection."
+msgstr "Vain aktiivisen kokoelman kanssa samanlaisen tietuerakenteen omaavia kokoelmia voidaan lisätä. Muutoksia ei tehdä nykyiseen kokoelmaan. "
+
+#: tellico_strings.cpp:24
+msgid "Only collections with the same type of entries as the current one can be merged. No changes are being made to the current collection."
+msgstr "Vain aktiivisen kokoelman kanssa samanlaisen tietuerakenteen omaavia kokoelmia voidaan yhdistää. Muutoksia ei tehdä nykyiseen kokoelmaan. "
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico ei pysty lataamaan kuvaa tiedostosta - %1."
+
+#: entryiconview.cpp:287
+msgid "&Sort By"
+msgstr "&Järjestä tämän mukaan:"
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Lainausikkuna"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "Lainatut nimikkeet:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "Lainassa olevat nimikkeet"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "&Lainaa henkilölle:"
+
+#: loandialog.cpp:107
+msgid "Enter the name of the person borrowing the items from you. Clicking the button allows you to select from your address book."
+msgstr "Syötä lainaajan nimi. Painamalla nappulaa voit valita nimen osoitekirjastasi."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "&Lainauspäivämäärä:"
+
+#: loandialog.cpp:123
+msgid "The check-out date is the date that you lent the items. By default, today's date is used."
+msgstr "Lainauspvm on päivä jolloin lainasit nimikkeet. Oletuksena käytetään tätä päivää."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "&Palautuspvm:"
+
+#: loandialog.cpp:139
+msgid "The due date is when the items are due to be returned. The due date is not required, unless you want to add the loan to your active calendar."
+msgstr "Palautuspvm on päivämäärä jolloin lainaukset pitäisi palauttaa. Palautuspäivämäärää ei vaadita, paitsi jos haluat lisätä lainan kelenteriisi."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Muistiinpano"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "Voit myös lisätä lainasta koskevia muistiinpanoja."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "Lisää &muistutus kalenteriin"
+
+#: loandialog.cpp:157
+msgid "<qt>Checking this box will add a <em>To-do</em> item to your active calendar, which can be viewed using KOrganizer. The box is only active if you set a due date."
+msgstr "<qt>Valitsemalla tämän valinnan uusi <em>tehtävä</em> lisätään kalenteriisi, se voidaan näyttää KOrganizerilla. Valinta on aktiivinen vain jos asetat lainaukselle palautuspäivämäärän."
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Luo uusi kokoelma"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Uusi &Kirjakokoelma"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Luo uusi kirjakokoelma"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Uusi B&ibliografia"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Luo uusi bibtex-bibliografia"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Uusi &Sarjakuvakokoelma"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Luo uusi sarjakuvakokoelma"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Uusi &Elokuvakokoelma"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Luo uusi elokuvakokoelma"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Uusi &Musiikkikokoelma"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Luo uusi musiikkikokoelma"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Uusi k&olikkokokoelma"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Luo uusi kolikkokokoelma"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Uusi &Postimerkkikokoelma"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Luo uusi postimerkkikokoelma"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Uusi Kor&ttikokoelma"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Luo uusi korttikokoelma"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Uusi &Viinikokoelma"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Luo uusi viinikokoelma"
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Uusi &Pelikokoelma"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Luo uusi pelikokoelma"
+
+#: mainwindow.cpp:272
+msgid "New Boa&rd Game Collection"
+msgstr "Uusi &Lautapelikokoelma"
+
+#: mainwindow.cpp:274
+msgid "Create a new board game collection"
+msgstr "Luo uusi lautapelikokoelma"
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr "Uusi tiedosto&katalogi"
+
+#: mainwindow.cpp:282
+msgid "Create a new file catalog"
+msgstr "Luo uusi tiedostokatalogi"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Uusi M&uokattu kokoelma"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Luo uusi muokattu kokoelma"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Avaa olemassa oleva dokumentti"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Avaa viimeisimmistä käytetyistä tiedostoista"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Tallenna dokumentti"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Tallenna dokumentti eri tiedostoon..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Tulosta dokumetin sisältö..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Lopeta ohjelma"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Tuo kokoelmatietoa muista formaateista..."
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Tuo Tellico-tietoa..."
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Tuo toinen Tellico tiedosto"
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "Tuo CSV-tietoa..."
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Tuo CSV-tiedosto"
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "Tuo MODS-tietoa..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Tuo MODS-tiedosto"
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Tuo Alexandria-tietoa..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Tuo tietoa Alexandria-ohjelmasta"
+
+#: mainwindow.cpp:352
+msgid "Import Delicious Library Data..."
+msgstr "Tuo Delicious Library-tietoa..."
+
+#: mainwindow.cpp:353
+msgid "Import data from Delicious Library"
+msgstr "Tuo tietoa Delicious Library:stä"
+
+#: mainwindow.cpp:359
+msgid "Import Referencer Data..."
+msgstr "Tuo Referencer-tietoa..."
+
+#: mainwindow.cpp:360
+msgid "Import data from Referencer"
+msgstr "Tuo tietoa Referencer:stä"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Tuo Bibtex-tietoa..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Tuo Bibtex bibliografiatiedosto"
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Tuo Bibtexml-tietoa..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Tuo Bibtexml bibliografiatiedosto"
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "Tuo RIS-tietoa..."
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Tuo RIS-referenssitiedosto"
+
+#: mainwindow.cpp:387
+msgid "Import PDF File..."
+msgstr "Tuo PDF-tiedosto..."
+
+#: mainwindow.cpp:388
+msgid "Import a PDF file"
+msgstr "Tuo PDF-tiedosto"
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Tuo Äänitiedoston metatietoa..."
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Tuo metatietoa äänittiedostoista"
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Tuo äänitiedoston tietoa..."
+
+#: mainwindow.cpp:405
+msgid "Import audio CD information"
+msgstr "Tuo ääni-cd:n tietoa"
+
+#: mainwindow.cpp:414
+msgid "Import GCstar Data..."
+msgstr "Tuo GCstar-tietoa..."
+
+#: mainwindow.cpp:415
+msgid "Import a GCstar data file"
+msgstr "Tuo GCstar tiedosto"
+
+#: mainwindow.cpp:421
+msgid "Import Griffith Data..."
+msgstr "Tuo Griffith-tietoa..."
+
+#: mainwindow.cpp:422
+msgid "Import a Griffith database"
+msgstr "Tuo Griffith-tietokanta"
+
+#: mainwindow.cpp:428
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Tuo Ant Movie Catalog -tietoa..."
+
+#: mainwindow.cpp:429
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Tuo Ant Movie Catalog -tiedosto"
+
+#: mainwindow.cpp:435
+msgid "Import File Listing..."
+msgstr "Tuo tiedostolistaus..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr "Tuo tietoa hakemiston tiedostoista"
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "Tuo XSL-muunnos..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Tuo käyttäen XSL-muunnosta"
+
+#: mainwindow.cpp:455
+#: rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Vie"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Vie kokoelman tiedot toiseen formaattiin"
+
+#: mainwindow.cpp:461
+msgid "Export to XML..."
+msgstr "Vie XML:nä..."
+
+#: mainwindow.cpp:462
+msgid "Export to a Tellico XML file"
+msgstr "Vie Tellico XML-tiedostoon"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Vie Zip:nä..."
+
+#: mainwindow.cpp:469
+msgid "Export to a Tellico Zip file"
+msgstr "Vie Tellico ZIP-tiedostoon"
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "Vie HTML:nä..."
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Vie HTML-tiedostoon"
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "Vie CSV:nä..."
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Vie CSV-tiedostoon (arvot pilkuilla erotettu)"
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "Vie PilotDB:nä..."
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Vie PilotDB-tiedostoon"
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Vie Alexandriaan..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Vie Alexandria-kirjastoon"
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Vie Bibtex:nä..."
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Vie Bibtex-tiedostoon"
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Vie Bibtexml:nä..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Vie Bibtexml-tiedostoon"
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "Vie ONIX:na..."
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Vie ONIX-tiedostoon"
+
+#: mainwindow.cpp:524
+msgid "Export to GCfilms..."
+msgstr "Vie GCfilms:nä..."
+
+#: mainwindow.cpp:525
+msgid "Export to a GCfilms data file"
+msgstr "Vie GCFilms-tiedostoon"
+
+#: mainwindow.cpp:531
+msgid "Export to GCstar..."
+msgstr "Vie GCstar:na..."
+
+#: mainwindow.cpp:532
+msgid "Export to a GCstar data file"
+msgstr "Vie GCstar-tiedostoon"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "Vie XSL-muunnoksella..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Vie käyttäen XSL-muunnosta"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Leikkaa valittu teksti leikepöydälle"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Kopioi valittu teksti leikepöydälle"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Liitä leikepöydän sisältö"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Valitse kaikki kokoelman tietueet"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Poista kokoelman kaikkien tietueiden valinta"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Internethaku..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Etsi Internetistä..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "&Tarkempi suodatin..."
+
+#: mainwindow.cpp:564
+#: mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Suodata kokoelmaa"
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&Uusi tietue..."
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Luo uusi tietue"
+
+#: controller.cpp:620
+#: mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "&Muokkaa tietuetta..."
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Muokkaa valittuja tietueita"
+
+#: controller.cpp:621
+#: mainwindow.cpp:577
+msgid "D&uplicate Entry"
+msgstr "&Monista tietue"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Kopioi valitut tietueet"
+
+#: controller.cpp:623
+#: mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "&Tuhoa tietue"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Tuhoa valitut tietueet"
+
+#: mainwindow.cpp:585
+msgid "&Merge Entries"
+msgstr "&Yhdistä tietueet"
+
+#: mainwindow.cpp:588
+msgid "Merge the selected entries"
+msgstr "Yhdistä valitut tietueet"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "&Luo raportteja..."
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Tee kokoelmaraportteja"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "&Lainaa..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Lainaa valitut nimikkeet"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "&Palautus"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Palauta valitut nimikkeet"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "&Uudelleennimeä kokoelma..."
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Uudelleennimeä kokoelma"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "&Kokoelman kentät..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Muuta kokoelman kenttiä"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "Muunna &bibliografiaksi"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Muuta kirjakokoelma bibliografiaksi"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "&Merkkijonomakrot..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Muokkaa Bibtex-merkkijonomakroja"
+
+#: mainwindow.cpp:626
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Kopioi Bibtex leikepöydälle"
+
+#: mainwindow.cpp:627
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Kopioi bibtex-sitaatit leikepöydälle"
+
+#: mainwindow.cpp:632
+msgid "Cite Entry in &LyX"
+msgstr "&Siteeraa tietue LyX:ssä"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Lähetä valitut sitaatit LyX:iin"
+
+#: mainwindow.cpp:638
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "&Siteeraa tietue OpenOffice.org:ssa"
+
+#: mainwindow.cpp:639
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Siteeraa OpenOffice.org:ssa valittuja tietueita"
+
+#: controller.cpp:622
+#: mainwindow.cpp:647
+#: rc.cpp:18
+#, no-c-format
+msgid "&Update Entry"
+msgstr "&Päivitä tietue"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr "Kaikki lähteet"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr "Päivitä tietueet kaikista saatavilla olevista lähteistä"
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Näytä &ryhmänäkymä"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Näytä/älä näytä ryhmänäkymä"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "&Piilota ryhmänäkymä"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Näytä tietue-&editori"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Näytä/älä näytä editori"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "&Piilota tietue-editori"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Näytä tietue-&näkymä"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Näytä/älä näytä tietuenäkymä"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "&Piilota tietue-näkymä"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Muuta ryhmittelyä"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "&Ryhmävalinta"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Muuta kokoelman ryhmittelyä"
+
+#: filterview.cpp:33
+#: filterview.cpp:85
+#: mainwindow.cpp:702
+#: mainwindow.cpp:717
+msgid "Filter"
+msgstr "Suodatin"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Tyhjennä suodatin"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Suodata tässä..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Ryhmät"
+
+#: mainwindow.cpp:769
+msgid "<qt>The <i>Group View</i> sorts the entries into groupings based on a selected field.</qt>"
+msgstr "<qt><i>Ryhmänäkymä</i> järjestää tietueet ryhmiin valitun kentän perusteella</qt>"
+
+#: mainwindow.cpp:776
+msgid "<qt>The <i>Column View</i> shows the value of multiple fields for each entry.</qt>"
+msgstr "<qt><i>Sarakenäkymä</i> näyttää jokaiselle tietueelle kuuluvat kentät.</qt>"
+
+#: mainwindow.cpp:831
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Tervetuloa Tellicoon, kokoelmien hallintaohjelmaan."
+
+#: mainwindow.cpp:833
+msgid "<h3>Tellico is a tool for managing collections of books, videos, music, and whatever else you want to catalog.</h3><h3>New entries can be added to your collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or by <a href=\"tc:///edit_search_internet\">downloading data</a> from various Internet sources.</h3>"
+msgstr "<h3>Tellico on työkalu jolla voi hallita erityyppisiä kokoelmia, kuten kirjat, videot, musiikki tai mitä tietoa ikinä haluat hallitakaan. </h3><h3>Uusia tietueita voit lisätä kokoelmaasi <a href=\"tc:///coll_new_entry\">syöttämällä tietoa käsin</a> tai <a href=\"tc:///edit_search_internet\">lataamalla valmista tietoa /a> erilaisista internet-lähteistä</h3>"
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Luodaan uutta dokumenttia..."
+
+#: mainwindow.cpp:1098
+#: mainwindow.cpp:1117
+#: mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Avataan tiedostoa..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Avaa tiedosto"
+
+#: document.cpp:192
+#: mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Talletetaan tiedostoa..."
+
+#: mainwindow.cpp:1226
+msgid "<qt><p>You are saving a file with many images, which causes Tellico to slow down significantly. Do you want to save the images separately in Tellico's data directory to improve performance?</p><p>Your choice can always be changed in the configuration dialog.</p></qt>"
+msgstr "<qt><p>Talletat tiedostoa joka sisältää paljon kuvia. Tämän takia Tellicon toiminta hidastuu merkittävästi. Haluatko tallettaa kuvat tellicon data-hakemistoon parantaaksesi ohjelman suorituskykyä?</p><p>Valintasi voidaan aina vaihtaa myöhemmin asetukset-dialogista.</p></qt>"
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr "Tallenna kuvat erikseen"
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr "Tallenna kuvat tiedostoon"
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Talletetaan tiedostoa uudella nimellä..."
+
+#: mainwindow.cpp:1303
+#: mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Tulostetaan..."
+
+#: mainwindow.cpp:1312
+msgid "The collection is currently being filtered to show a limited subset of the entries. Only the visible entries will be printed. Continue?"
+msgstr "Kokoelmasta on esillä suodatettu näkymä. Vain näkyvät tietueet tulostetaan, jatketaanko?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Käsitellään dokumenttia..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Suljetaan..."
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Tietueita yhteensä: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 suodatettu; %2 valittu)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 suodatettu)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 valittu)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Tulosta %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Sivu %1"
+
+#: entryview.cpp:188
+#: mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Tarkista asennuksesi."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Tuodaan tietoja..."
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Tuo tiedosto"
+
+#: mainwindow.cpp:1864
+msgid "Import Directory"
+msgstr "Tuo hakemisto"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Viedään tietoja..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Vie muodossa"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Merkkijonomakrot"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Makro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Merkkijono"
+
+#: mainwindow.cpp:1999
+msgid "Creating citations..."
+msgstr "Luodaan sitaatteja..."
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Suodattimet"
+
+#: mainwindow.cpp:2105
+msgid "<qt>The <i>Filter View</i> shows the entries which meet certain filter rules.</qt>"
+msgstr "<qt><i>Suodatinnäkymä</i>näyttää tietueet jotka sopivat suodatussääntöön.</qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Lainaukset"
+
+#: mainwindow.cpp:2122
+msgid "<qt>The <i>Loan View</i> shows a list of all the people who have borrowed items from your collection.</qt>"
+msgstr "<qt><i>Lainausnäkymä</i> näyttää listan ihmisistä jotka ovat lainanneet kokoelmastasi.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr "Päivitä tietue täältä: %1"
+
+#: mainwindow.cpp:2274
+msgid "Tellico can only import one file of this type at a time. Only %1 will be imported."
+msgstr "Tellico voi tuoda tämäntyyppisiä tiedostoja vain yhden kerrallaan. Vain %1 tuodaan."
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico ei pysty lataamaan kuvatiedostoa - %1."
+
+#: filehandler.cpp:207
+msgid "A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr "Tiedosto \"%1\" on jo olemassa. Haluatko varmasti ylikirjoittaa sen?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Ylikirjoita tiedosto?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Ylikirjoita"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Suodata (Järjestetty lukumäärän mukaan)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Haluatko todella tuhota tämän tietueen?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Tuhoa nimike"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Haluatko todella tuhota valitut tietueet?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Tuhoa useampia nimikkeitä"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "&Muokkaa tietueita..."
+
+#: controller.cpp:627
+msgid "D&uplicate Entries"
+msgstr "Monista tietueet (x2)"
+
+#: controller.cpp:628
+msgid "&Update Entries"
+msgstr "&Päivitä tietueet"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "Tuh&oa tietueet"
+
+#: controller.cpp:684
+msgid "The following items are already loaned, but Tellico does not currently support lending an item multiple times. They will be removed from the list of items to lend."
+msgstr "Seuraavat tietueet ovat jo lainattu. Nykyisellään Tellico ei tue nimikkeen lainausta useampaan kertaa. Nämä nimikkeet poistetaan lainattavien listalta."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Oletuskalenteri"
+
+#: calendarhandler.cpp:175
+msgid "At the moment, Tellico only supports local calendar resources. The active calendar is remotely located, so your loans will not be added."
+msgstr "Nykyisellään Tellico tukee vai paikallisia kalentereita. Aktiivinen kalenterisi ei ole paikallinen, joten lainauksiasi ei lisätä."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Aktiivinen kalenteri"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 -nimikkeen viimeinen palautuspäivämäärä on \"%2\""
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(Tyhjä)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - kokoelmienhallintaohjelmisto KDE:lle"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Alä uudelleenavaa viimeksiaukaistua tiedostoa"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Tuo<filename> bibtex-tiedostona"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Tuo <filename> MODS-tiedostona"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Tuo <filename> RIS-tiedostona"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Avattava tiedosto"
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr "Tietolähteiden skriptit"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Kuvakkeet"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Btparse-kirjaston tekijä"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr "Koodiesimerkkejä ja yleiseksi inspiraatioksi..."
+
+#: main.cpp:50
+msgid "Author of libcsv library"
+msgstr "Libcvs-kirjaston tekijä"
+
+#: main.cpp:52
+msgid "Author of rtf2html library"
+msgstr "rtf2html-kirjaston tekijä"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Kokoelman kentät"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Nykyiset kentät"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "&Uusi"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Lisää uusi kenttä kokoelmaan"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "&Tuhoa"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Poista kenttä kokoelmasta"
+
+#: collectionfieldsdialog.cpp:98
+msgid "Move this field up in the list. The list order is important for the layout of the entry editor."
+msgstr "Siirrä tämä kenttä ylös listassa. Listan järjestys vaikuttaa tietue-editorin kenttien asetteluun."
+
+#: collectionfieldsdialog.cpp:102
+msgid "Move this field down in the list. The list order is important for the layout of the entry editor."
+msgstr "Siirrä tämä kenttä alas listassa. Listan järjestys vaikuttaa tietue-editorin kenttien asetteluun."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Kentän ominaisuudet"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "&Otsikko:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "Kentän otsikko"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "&Tyyppi:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "Kentän tyyppi määrittää millaisia arvoja siinä voidaan käyttää. "
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "<i>Yksinkertaista tekstiä</i> käytetään useimmissa kentissä. "
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "<i>Kappale</i> on isoille tekstilohkoille. "
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Valinta</i> rajaa kentän arvot tiettyihin arvoihin. "
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "<i>Valintaruutu</i> on yksinkertaisille kyllä/ei -arvoille. "
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr "<i>Numero</i> kertoo että kenttä sisältää numeerison arvon. "
+
+#: collectionfieldsdialog.cpp:141
+msgid "<i>URL</i> is for fields which refer to URLs, including references to other files. "
+msgstr "<i>URL</i> on kentille jotka viittaavat verkko-osoitteisiin, mukaanlukien viitteet toisiin tiedostoihin. "
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr "<i>Taulu</i> voi sisältää yhden tai useampia arvosarakkeita. "
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "<i>Kuva</i>-kenttä sisältää kuvan. "
+
+#: collectionfieldsdialog.cpp:144
+msgid "A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr "<i>Päivämäärä</i>-kenttää voidaan käyttää ilmaistaessa päivää, kuukautta ja vuotta. "
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr "A <i>Arvosana</i>-kenttä käyttää tähtiä kertomaan arvosanan. "
+
+#: collectionfieldsdialog.cpp:146
+msgid "A <i>Dependent</i> field depends on the values of other fields, and is formatted according to the field description. "
+msgstr "A <i>Riippuvainen</i>-kentän muoto riippuu muista kentistä ja se muotoillaan kentän kuvauksen mukaan. "
+
+#: collectionfieldsdialog.cpp:148
+msgid "A <i>Read Only</i> is for internal values, possibly useful for import and export. "
+msgstr "<i>Vain lulu</i> on sisäisille arvoille, se on mahdollisesti hyödyllinen tiedon tuomisessa ja viemisessä. "
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "&Kategoria:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr "Kategoria-kenttä määrittää kentän välilehden tietue-editorissa."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "K&uvaus:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid "The description is a useful reminder of what information is contained in the field. For <i>Dependent</i> fields, the description is a format string such as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr "Kuvaus on käytännöllinen muistutus siitä millaista tietoa kenttä sisältää. <i>Riippuvainen</i>-kentille kuvaus on muotoilumerkkijono, kuten \"%{year} %{title}\" missä nimetyt kentät korvautuvat merkkijonolla."
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr "&Oletusarvo:"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr "<qt>Uusille tietueille voidaan asettaa oletusarvo</qt>"
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr "&Sallitut arvot:"
+
+#: collectionfieldsdialog.cpp:208
+msgid "<qt>For <i>Choice</i>-type fields, these are the only values allowed. They are placed in a combo box. The possible values have to be separated by a semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr "<qt>Vain nämä arvot ovat sallittuja <i>Vaihtoehto</i>-tyyppisille kentille. Ne sijoitetaan yhdistelmäruutuun. Arvot pitää erotella puolipoisteella, tähän tyyliin: \"koira; kissa; hiiri\"</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "&Laajennetut ominaisuudet:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "&Aseta..."
+
+#: collectionfieldsdialog.cpp:221
+msgid "Extended field properties are used to specify things such as the corresponding bibtex field."
+msgstr "Laajennennettuja kentän ominaisuuksia käytetään määrittämään asioita kuten kentän vastaavuus bibtex-tietueessa."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Muotoiluasetukset"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Ei muotoilua"
+
+#: collectionfieldsdialog.cpp:228
+msgid "This option prevents the field from ever being automatically formatted or capitalized."
+msgstr "Tämä valinta estää kentän automaattisen muotoilun."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Salli vain automaattinen isojen kirjainten käyttö"
+
+#: collectionfieldsdialog.cpp:231
+msgid "This option allows the field to be capitalized, but not specially formatted."
+msgstr "Tämä valinta sallii kentässä isojen kirjainten käytön mutta ei sen erillistä muotoilua."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Muotoile kuten otsikko"
+
+#: collectionfieldsdialog.cpp:234
+msgid "This option capitalizes and formats the field as a title, but only if those options are globally set."
+msgstr "Tämä valinta asettaa isot kirjaimet ja muotoilun kuten otsikossa mutta vain jos nämä asetukset ovat globaalisti asetettu."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Muotoile kuten nimi"
+
+#: collectionfieldsdialog.cpp:237
+msgid "This option capitalizes and formats the field as a name, but only if those options are globally set."
+msgstr "Tämä valinta asettaa kenttän käyttämään isoja kirjaimia ja muotoilee sen kuten nimen, mutta vain jos nämä asetukset on globaalisti asetettu."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Kentän asetukset"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Aktivoi automaattinen tekstintäydennys"
+
+#: collectionfieldsdialog.cpp:243
+msgid "If checked, KDE auto-completion will be enabled in the text edit box for this field."
+msgstr "Jos valittu, tässä kentässä käytetään KDE:n automaattista tekstintäydennystä."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Salli monta arvoa"
+
+#: collectionfieldsdialog.cpp:246
+msgid "If checked, Tellico will parse the values in the field for multiple values, separated by a semi-colon."
+msgstr "Jos valittu, Tellico luetteloi kentän kaikki puolipisteellä erotellut arvot omina arvoinaan."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Salli ryhmittely"
+
+#: collectionfieldsdialog.cpp:249
+msgid "If checked, this field may be used to group the entries in the group view."
+msgstr "Jos valittu, kenttää voidaan käyttää ryhmittelemään ryhmänäkymän tietueet."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr "Palauta valittujen kenttien ominaisuudet oletusarvoihin."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Muokkaa kenttiä"
+
+#: collectionfieldsdialog.cpp:320
+msgid "<qt>Removing allowed values from the <i>%1</i> field which currently exist in the collection may cause data corruption. Do you want to keep your modified values or cancel and revert to the current ones?</qt>"
+msgstr "<qt>Sallittujen arvojen poistaminen nykyiseen kokoelmaan sisältyvästä <i>%1</i>-kentästä voi aiheuttaa tiedon korruptoitumista. Haluatko varmuuskopioida muokatut arvot vai keskeyttää toiminnon ja palata takaisiin nykyisiin arvoihin?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Pidä muokatut arvot"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Palauta kentän asetukset"
+
+#: collectionfieldsdialog.cpp:746
+msgid "<qt><p>Do you really want to revert the properties for the <em>%1</em> field back to their default values?</p></qt>"
+msgstr "<qt><p>Haluatko todella palauttaa kentän <em>%1</em> asetukset oletusarvoihin?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Palauta"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Kentän laajennetut ominaisuudet"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr "Tämän niminen kenttä on jo olemassa. Anna joku muu nimi."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr "<qt>Kategoria ei voi olla tyhjä. Anna kategorian nimi.</qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid "<qt>A field may not be in the same category as a <em>Paragraph</em>, <em>Table</em> or <em>Image</em> field. Please enter a different category.</qt>"
+msgstr "<qt>Kenttä ei voi olla samassa kategoriassa kuin <em>Kappale-</em>, <em>Taulu-</em> tai <em>Kuva</em>-kenttä. Anna joku muu kategoria."
+
+#: collectionfieldsdialog.cpp:925
+msgid "A field's title may not be the same as an existing category. Please enter a different title."
+msgstr "Kentän otsikko ei voi olla sama kuin joku jo olemassa oleva kategoria. Anna joku muu otsikko "
+
+#: collectionfieldsdialog.cpp:937
+msgid "The range for a rating field must be between 1 and 10, and the lower bound must be less than the higher bound. Please enter different low and high properties."
+msgstr "Arvosanan arvoalue täytyy olla väliltä 1-10.Alempi raja pitää olla ylempää pienempi. Syötä uudet ala- ja yläraja-arvot."
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "Tauluissa on kymmenen sarakkeen maksimirajoitus."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Aktiivista tiedostoa on muokattu\n"
+"haluetko tallentaa muutoksen?"
+
+#: document.cpp:160
+#: entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Tallentamattomat muutokset"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Valitse lainaaja"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Muokkaa Tellico:n asetuksia"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Yleiset asetukset"
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr "&Uudelleenavaa tiedosto käynnistyessä"
+
+#: configdialog.cpp:202
+msgid "If checked, the file that was last open will be re-opened at program start-up."
+msgstr "Jos valittu, viimeksi muokattu tiedosto avataan ohjelman käynnistyessä."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "&Näytä \"päivän vinkki\" käynnistettäessä ohjelma"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr "Jos valittu, \"päivän vinkki\" näytetään ohjelman käynnistyessä."
+
+#: configdialog.cpp:213
+msgid "Image Storage Options"
+msgstr "Kuvien tallennusasetukset"
+
+#: configdialog.cpp:214
+msgid "Store images in data file"
+msgstr "Talleta kuvat tiedoston sisään"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr "Tallenna kuvat ohjelman hakemistoon."
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr "Tallenna kuvat hakemistoon (suhteessa kokoelman tiedot sisältävään tiedostoon)."
+
+#: configdialog.cpp:217
+msgid "Images may be saved in the data file itself, which can cause Tellico to run slowly, stored in the Tellico application directory, or stored in a directory in the same location as the data file."
+msgstr "Kuvat voidaan tallettaa itse tiedoston sisään jossa muukin tieto on (tämä tosin saattaa hidastaa Tellicoa) tai erilliseen hakemistoon, joka sijaitsee samassa paikassa kuin em. tiedosto."
+
+#: configdialog.cpp:224
+#: configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Muotoiluasetukset"
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr "Automaattiset isotkirjaimet otsikoissa ja nimissä"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr "Jos valittu, otsikkojen ja nimien alkukirjaimet muutetaan isoiksi kirjaimiksi automaattisesti."
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr "Otsikoiden ja kenttien automaattinen muotoilu"
+
+#: configdialog.cpp:233
+#: configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr "Jos valittu, otsikot ja nimet muotoillaan automaattisesti."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr "Ei &kapitalosointia"
+
+#: configdialog.cpp:243
+msgid "<qt>A list of words which should not be capitalized. Multiple values should be separated by a semi-colon.</qt>"
+msgstr "<qt>Lista sanoista joiden ei pitäisi alkaa isolla alkukirjaimella. Useampi arvo tulee erottaa toisistaan puolipisteellä .</qt>"
+
+#: configdialog.cpp:249
+msgid "Artic&les:"
+msgstr "Ar&tikkelit:"
+
+#: configdialog.cpp:252
+msgid "<qt>A list of words which should be considered as articles if they are the first word in a title. Multiple values should be separated by a semi-colon.</qt>"
+msgstr "<qt>Pilkuilla erotettu lista sanoista joita käsitellään artikkeleina jos ne esiintyvät otsikon ensimmäisenä sanana. Useampi arvo tulee erottaa toisistaan puolipisteellä.<qt>"
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr "Henkilökohtaiset &jälkiliitteet:"
+
+#: configdialog.cpp:262
+msgid "<qt>A list of suffixes which might be used in personal names. Multiple values should be separated by a semi-colon.</qt>"
+msgstr "<qt>Lista jälkiliitteistä joita voidaan käyttää henkilöiden nimissä. Useampi arvo tulee erottaa toisistaan puolipisteellä.<qt>"
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr "Sukunimen &alkuliitteet:"
+
+#: configdialog.cpp:271
+msgid "<qt>A list of prefixes which might be used in surnames. Multiple values should be separated by a semi-colon.</qt>"
+msgstr "<qt>Lista etuliitteistä joita saatetaan käyttää sukunimessä. Useampi arvo tulee erottaa toisistaan puolipisteellä .</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Tulostus"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Tulostuksen asetukset"
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr "&Muotoile otsikkoja ja nimiä"
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr "&Tulosta kenttien otsikot"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Ryhmittelyn asetukset"
+
+#: configdialog.cpp:313
+msgid "&Group the entries"
+msgstr "&Ryhmittele tietueet"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Kuvan asetukset"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr "Kuvan enimmäisl&eveys:"
+
+#: configdialog.cpp:328
+msgid "The maximum width of the images in the printout. The aspect ration is preserved."
+msgstr "Tulosteessa olevan kuvan enimmäisleveys. Kuvasuhde on vakio."
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr "&Kuvan enimmäiskorkeus:"
+
+#: configdialog.cpp:341
+msgid "The maximum height of the images in the printout. The aspect ration is preserved."
+msgstr "Tulosteessa olevan kuvan enimmäiskorkeus. Kuvasuhde on vakio."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Mallipohjat"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Mallipohjien asetukset"
+
+#: configdialog.cpp:369
+msgid "Template:"
+msgstr "Mallipohja:"
+
+#: configdialog.cpp:373
+msgid "Select the template to use for the current type of collections. Not all templates will use the font and color settings."
+msgstr "Valitse aktiivisena olevan tyyppiseen kokoelmaan käytettävä mallipohja. Kaikki mallipohjat eivät käytät kirjasin- ja väriasetuksia."
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr "&Esikatselu..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr "Näytä esikatselu mallipohjasta"
+
+#: configdialog.cpp:398
+msgid "Font Options"
+msgstr "Kirjasinasetukset"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr "Kirjasin:"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr "Tämä kirjasin viedään tietuenäkymän käyttämään mallipohjaan."
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr "Koko:"
+
+#: configdialog.cpp:425
+msgid "Color Options"
+msgstr "Väriasetukset"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr "Taustaväri:"
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr "Tämä väri viedään tietuenäkymän käyttämään mallipohjaan."
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr "Tekstin väri:"
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr "Korostusväri:"
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr "Korostetun tekstin väri:"
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr "Hallitse mallipohjia"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr "Asenna..."
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr "Paina asentaaksesi suoraan uuden mallipohjan"
+
+#: configdialog.cpp:481
+#: configdialog.cpp:537
+msgid "Download..."
+msgstr "Lataa..."
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr "Paina ladataksesi mallipohjia lisää internetistä"
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr "Tuhoa..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr "Paina valitaksesi ja poistaaksesi asennetut mallipohjat"
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Tietolähteet"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Tietolähteiden asetukset"
+
+#: configdialog.cpp:506
+#: fetchdialog.cpp:171
+msgid "Source"
+msgstr "Lähde"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr "Siirrä &Ylös"
+
+#: configdialog.cpp:519
+#: configdialog.cpp:523
+msgid "The order of the data sources sets the order that Tellico uses when entries are automatically updated."
+msgstr "Tietolähteiden järjestys määrää järjestyksen mitä Tellico käyttää tietueiden automaattisessa päivityksessä."
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr "Siirrä &Alas"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "&Uusi..."
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr "Paina lisätäksesi uuden tietolähteen."
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Muokkaa..."
+
+#: configdialog.cpp:533
+msgid "Click to modify the selected data source."
+msgstr "Paina muokataksesi valittua tietolähdettä"
+
+#: configdialog.cpp:536
+msgid "Click to delete the selected data source."
+msgstr "Paina tuhotaksesi valitun tietolähteen"
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr "Paina ladataksesi lisää tietolähteitä internetistä"
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr "*.tar.gz *.tgz|Mallipohjapaketit (*.tar.gz)"
+
+#: configdialog.cpp:1049
+msgid "Delete Template"
+msgstr "Tuhoa mallipohja"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr "Valitse tuhottava mallipohja"
+
+#: loanview.cpp:33
+#: loanview.cpp:91
+#: xslt.cpp:26
+msgid "Borrower"
+msgstr "Lainaaja"
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Palautus"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Muokkaa lainausta..."
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "Lainaaja (Järjestetty lukumäärän mukaan)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "Oma Kokoelma"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Kirjakokoelma"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Sarjakuvakokoelma"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Elokuvakokoelma"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Musiikkikokoelma"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Kolikkokokoelma"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Postimerkkikokoelma"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Viinikokoelma"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Korttikokoelma"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Pelikokoelma"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr "Tiedostokatalogi"
+
+#: collectionfactory.cpp:135
+msgid "Board Game Collection"
+msgstr "Lautapelikokoelma"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Muokattu kokoelma"
+
+#: viewstack.cpp:29
+msgid "<qt>The <i>Entry View</i> shows a formatted view of the entry's contents.</qt>"
+msgstr "<qt><i>Tietuenäkymä</i> näyttää tietueen sisällön muotoillusti.</qt>"
+
+#: viewstack.cpp:31
+msgid "<qt>The <i>Icon View</i> shows each entry in the collection or group using an icon, which may be an image in the entry.</qt>"
+msgstr "<qt><i>Kuvakenäkymä</i> näyttää jokaisen kokoelmassa olevan tietueen tai ryhmän käyttäen kuvakkeita. Kuvake voi olla tietueenssa oleva kuva.</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Viennin asetukset"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Muotoilu"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Muotoile kaikkia kenttiä"
+
+#: exportdialog.cpp:57
+msgid "If checked, the values of the fields will be automatically formatted according to their format type."
+msgstr "Jos valittu, kenttien arvot muotoillaan automaattisesti niiden muotoilutyypin mukaan."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Vie vain valitut tietueet"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr "Jos valittu, vain tällä hetkellä valittuna olevat tietueet viedään."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Koodaus"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Koodaa Unicode-muotoon (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Koodaa viety tiedosto Unicode-muotoon (UTF-8)."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Koodaa käyttäjän paikallisella muotoon (%1)"
+
+#: exportdialog.cpp:72
+#, fuzzy
+msgid "Encode the exported file in the local encoding."
+msgstr "Koodaa viety tiedosto paikalliseen muotoon."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "&Hae"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "&Lopeta"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Internet-haku"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Hakuehto"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr "&Hae:"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr "Anna hakuehto. ISBN-haun pitää sisältää koko ISBN-numero."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Valitse haun tyyppi"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Paina aloittaaksesi tai lopettaaksesi haun"
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr "ISBN/UPC-&monihaku"
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr "Valitse tämä ruutu etsiäksesi monia ISBN- tai UP-arvoja"
+
+#: fetchdialog.cpp:138
+msgid "Edit List..."
+msgstr "Muokkaa listaa..."
+
+#: fetchdialog.cpp:140
+msgid "Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr "Paina avataksesi tekstiruudun jossa voidaan syöttää/muokata monia ISBN-arvoja."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "Haun tieto&lähde:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Valitse etsinnässä käytettävä tietokanta"
+
+#: fetchdialog.cpp:177
+msgid "As results are found, they are added to this list. Selecting one will fetch the complete entry and show it in the view below."
+msgstr "Tulosten löytyessä niitä lisätään listaan. Valitsemalla niistä yhden, tietueesta noudetaan täydelliset tiedot ja ne näytetään alhaalla olevassa näkymässä."
+
+#: fetchdialog.cpp:185
+msgid "An entry may be shown here before adding it to the current collection by selecting it in the list above"
+msgstr "Tietue voidaan näyttää tässä ennenkuin se lisätään nykyiseen kokoelmaan valitsemalla se ylläolevasta listasta."
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "Lisää &tietue"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Lisää valittu tietue nykyiseen kokoelmaan"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr "Hae lisää tuloksia"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr "Nouda lisää tuloksia nykyisestä tietolähteestä"
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Tyhjennä kaikki hakukentät ja -tulokset"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Lopetetaan hakeminen..."
+
+#: fetchdialog.cpp:313
+#: fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Haetaan..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "Haku ei palauttanut tuloksia."
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+"Haku palautti yhden tietueen.\n"
+"Haku palautti %n tietuetta."
+
+#: fetchdialog.cpp:412
+msgid "No results were found for the following ISBN values:"
+msgstr "Seuraaville ISBN-arvoille ei löytynyt tuloksia:"
+
+#: fetchdialog.cpp:443
+#: fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Noudetaan %1..."
+
+#: fetchdialog.cpp:528
+#: fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr "Internet-tietolähteitä ei ole saatavilla nykyiselle kokoelmatyypille."
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr "Muokkaa ISBN/UPC-arvoja"
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Anna ISBN- tai UPC-arvo, yksi per rivi.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "&Lataa tiedostosta..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Lataa lista tekstitiedostosta.</qt>"
+
+#: fetchdialog.cpp:624
+msgid "<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first 100 values in your list will be used.</qt>"
+msgstr "<qt>ISBN-haku voi sisältää enintään 100 ISBN-arvoa. Vain 100:aa ensimmäistä arvoa listassasi käytetään haussa.</qt>"
+
+#: entryeditdialog.cpp:51
+#: entryeditdialog.cpp:382
+#: entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Muokkaa tietuetta"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Uusi tietue"
+
+#: entryeditdialog.cpp:66
+#: entryeditdialog.cpp:117
+#: entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "&Tallenna tietue"
+
+#: entryeditdialog.cpp:77
+msgid "Go to the previous entry in the collection"
+msgstr "Siirry kokoelman edelliseen tietueeseen"
+
+#: entryeditdialog.cpp:82
+msgid "Go to the next entry in the collection"
+msgstr "Siirry kokoelman seuraavaan tietueeseen"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Haluatko todella muokata valittuja tietueita?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Muokkaa useita tietueita"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr "Seuraavat kentät vaativat arvon, haluatko jatkaa?"
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Muokkaa tietueita"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "T&allenna tietueet"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"Nykyistä tietuetta on muokattu.\n"
+"Haluatko tallettaa muutokset?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Tallenna tietue"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Kokoelmaraportti"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "&Raportin mallipohja:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "&Luo"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr "Valitse raportin mallipohja ja klikkaa <em>Luo</em>"
+
+#: reportdialog.cpp:108
+msgid "Some reports may take several seconds to generate for large collections."
+msgstr "Isojen kokoelmien raporttien luomiseen voi mennä vähän pidempi aika."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Haluatko todella tuhota tämän suodattimen?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Tuhoa suodatin?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Uusi kokoelman nimi:"
+
+#: tellico_kernel.cpp:377
+msgid "Entry 1"
+msgstr "Tietue 1"
+
+#: tellico_kernel.cpp:378
+msgid "Entry 2"
+msgstr "Tietue 2"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr "Ristiriitaisia arvoja (%1) löydettiin yhdistettäessä tietueita "
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr "Valitse mikä arvo pidetään."
+
+#: entrymerger.cpp:33
+#: tellico_kernel.cpp:398
+msgid "Merge Entries"
+msgstr "Yhdistä tietueet"
+
+#: tellico_kernel.cpp:399
+#: tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr "Valitse arvo %1"
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico ei pysty paikantamaan tietueen oletusmuotoilutyylipohjaa."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Uusi"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Kokoelma"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Kokoelmatyökalupalkki"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Teuvo Eloranta"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "teuvo@piketa.fi"
+
+#: entrymerger.cpp:35
+msgid "Merging entries..."
+msgstr "Yhdistetään tietueita..."
+
+#: entrymerger.cpp:49
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Yhdistettyjä/läpikäytyjä tietueita yhteensä: %1/%2"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>...että jos kirjalla on useampi kirjoittaja, erota nimet puolipisteellä\n"
+"jotta Tellico osaa käsitellä näitä erillisinä tietoina.</p>\n"
+"<p>Kaikkia muitakin kenttiä joihin voi laittaa useita arvoja tulee\n"
+"käyttää samalla tavalla, erottele arvot puolipuolipisteellä.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>...että voit muuttaa listassa näkyviä kenttiä napsauttamalla \n"
+"hiiren kakkospainiketta sarakkeen otsikon päällä.\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>...että voit lisätä tai muokata kokoelman kenttiä kenttäeditorissa. Alla olevilla\n"
+"Nuolinappuloilla voit vaihtaa kentän paikkaa listassa. Tämä vaikuttaa kentän paikkaan tietue-editorissa.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>...että jos halut suodattaa näkymää valintaruudun mukaan,\n"
+" tulee käyttää arvoa \"tosi\". Jos esimerkiksi haluat suodattaa näkyviin\n"
+"vain kaikki lukemattomat scifi-kirjat, valitse <em>\"Sopii kaikkiin seuraaviin\"\n"
+"</em>-valinta, aseta ensimmäiseksi säännöksi: \"Lajityyppi\",\n"
+"\"sisältää\" \"Scifi\" (ei lainausmerkkejä) ja toiseksi säännöksi:\n"
+"\"Luettu\" \"ei sisällä\" \"true\" (ei lainausmerkkejä).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>...että jos erikoismerkkejä käytetään pikasuodattimessa, teksti\n"
+"tulkataan säännönmukaiseksi lausekkeeksi.</p>\n"
+"<p>Esimerkiksi näyttääksesi vain kirjat joiden tekijä on Weber tai Bujold,\n"
+"kirjoita suodatin-ruutuun \"weber|bujold\" (ilman lainausmerkkejä).</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>...että voit muokata useampaa kuin yhtä tietuetta kerralla pitämällä\n"
+"Vaihto- tai Ctrl -nappulaa alhaalla ja valisemalla useamman tietueen.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>...että voit muuttaa olemassa olevan kirjakokoelman bibliografiaksi,\n"
+"joka voidaan sitten viedä Bibtex- tai Bibtexml-muotoon.</p>\n"
+
+#: tips.cpp:50
+msgid "<p>...that you can add, edit, and delete string macros for bibliographies.</p>\n"
+msgstr "<p>...että voit lisätä, muokata ja tuhota bibliografioiden merkkijonomakroja</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an additional\n"
+"group named \"People\" is added to the collection, allowing authors and editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>...että jos useampaa kuin yhtä kenttää muokataan nimenä, ryhmä\n"
+"nimeltä \"Ihmiset\" lisätään kokoelmaan. \n"
+"Näin esim. tekijöitä ja kirjoittajia voidaan järjestellä tai tulostaa yhdessä.</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>...että voit vaikuttaa tulosteen ulkoasuun muokkaamalla <tt>tellico-printing.xsl</tt> -tiedostoa. Tiedoston avulla luodaan HTML- \n"
+"ja CSS-tiedostoja. Muokkaamalla voit vaikuttaa esim. tulosteen kirjasimiin \n"
+"ja marginaaleihin.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr "<p>...että voit tuoda ja viedä tietoja käyttäen mitä tahansa yleistä XSL-tyylitiedostoa joka tuottaa kelvollisen XML-tiedoston </p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr "<p>...että kaksoisklikkaamalla tietuetta aukeaa tietue-editori.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>...että voit lisätä HTML-tageja mihin tahansa kappaleen kenttään muotoillaksesi sitä. esim: \n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>...että yksityiskohtaisessa näkymässä voit painaa näppäimistöstä kirjainta\n"
+"hypätäksesi seuraavaan tuolla kirjaimella alkavaan tietueeseen.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+"<p>...että voit käyttää \"riippuvainen\" -kenttiä yhdistääksesi monia erillisiä kenttiä.\n"
+"Yhdeksi kentäksi. Valitse vain tyyppi \"riippuvainen\" ja käytä tämäntapaista notaatiota\n"
+" \"Value: %{fielda}%{fieldb}\" missä%{...} korvataan \n"
+"kyseessä olevalla kentän arvolla. Tämä on hyödyllistä koostettaessa useita arvoja yhdeksi kentäksi \n"
+"esim. paremman ryhmittelyn takia ja yhdistaaksesi erityyppisiä kenttiä ottaen samalla huomioon niiden lajiteltavuuden. \n"
+"Esim. numeraalinen kenttä jonka perässä on tekstitietoa: 3b, a.</p>\n"
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Albumi"
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr "Tämä mallipohja on tarkoitettu vain musiikkikokoelmille"
+
+#: xslt.cpp:5
+msgid "Total:"
+msgstr "Yhteensä:"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr "Hieno"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "Oletus"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Kompakti"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Video"
+
+#: xslt.cpp:14
+#: xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr "Tämä mallipohja on tarkoitettu vain elokuvakokoelmille"
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Ryhmäyhteenveto"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Ryhmäyhteenveto"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Kenttiä yhteensä:"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Tietueita yhteensä:"
+
+#: xslt.cpp:20
+#: xslt.cpp:32
+#: xslt.cpp:46
+msgid "Generated by Tellico"
+msgstr "Luonut Tellico"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Erilliset arvot:"
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Kuvalista"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Lainausnäkymä"
+
+#: xslt.cpp:27
+#: xslt.cpp:29
+msgid "Loan Date"
+msgstr "Lainauspäivämäärä"
+
+#: xslt.cpp:28
+#: xslt.cpp:31
+msgid "Note"
+msgstr "Muistiinpanot"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Palautuspäivämäärä"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Ryhmänäkymä"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Nimikkeen listaus (horisontaali)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Nimikkeen listaus (vertikaali)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Sarakenäkymä"
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "Tri-Column"
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr "Etsi"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr "The British Library"
+
+#: z3950.cpp:6
+msgid "Sudoc (France)"
+msgstr "Sudoc (Ranska)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr "BIBSYS (Norway)"
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr "Italian National Library"
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr "Portuguese National Library"
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr "National Library of Poland"
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr "National Library of Canada"
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr "Israel Union List"
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr "National Library of Australia"
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr "Liettuan kansallinen kirjasto"
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr "Copac (Englanti ja Irlanti)"
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr "BoardGameGeek"
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr "Dark Horse Comics"
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr "Allocine.fr"
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr "Spanish Ministry of Culture"
+
+#, fuzzy
+#~ msgid "CrossRef"
+#~ msgstr "Ristiviite"
+#~ msgid "MODS"
+#~ msgstr "MODS"
+#~ msgid "RIS"
+#~ msgstr "RIS"
+#~ msgid "GCstar"
+#~ msgstr "GCstar"
+#~ msgid "AMC"
+#~ msgstr "AMC"
+
+#, fuzzy
+#~ msgid "Griffith"
+#~ msgstr "Lahja"
+
+#, fuzzy
+#~ msgid "Referencer"
+#~ msgstr "Ristiviite"
+#~ msgid "Comics"
+#~ msgstr "Sarjakuvat"
+#~ msgid "Stamps"
+#~ msgstr "Postimerkit"
+#~ msgid "Coins"
+#~ msgstr "Kolikot"
+#~ msgid "Books"
+#~ msgstr "Kirjat"
+#~ msgid "Wines"
+#~ msgstr "Viinit"
+#~ msgid "Videos"
+#~ msgstr "Elokuvat"
+#~ msgid "Games"
+#~ msgstr "Pelit"
+#~ msgid "Cards"
+#~ msgstr "Kortit"
+#~ msgid "Entries"
+#~ msgstr "Tietueet"
+#~ msgid "Albums"
+#~ msgstr "Albumi"
+#~ msgid ""
+#~ "If checked, all images will be included in the data file, rather than saved "
+#~ "separately in the Tellico data directory. Saving a lot of images in the data "
+#~ "file cause Tellico to run more slowly."
+#~ msgstr ""
+#~ "Jos valittu, kaikki kuvat sisällytetään tiedostoon, eikä talleteta "
+#~ "erikseen Tellicon data-hakemistoon. Mikäli kuvia on paljon, tämä "
+#~ "talletustapa vaikuttaa Tellicon toimintanopeuteen."
+
+#, fuzzy
+#~ msgid "Copac"
+#~ msgstr "Pilkku"
+#~ msgid "Tellico"
+#~ msgstr "Tellico"
+#~ msgid "&Copy Entry"
+#~ msgstr "&Kopioi tietue"
+#~ msgid "&Copy Entries"
+#~ msgstr "&Kopioi tietueita"
+#~ msgid "<qt>Multiple records were found to match the CD.</qt>"
+#~ msgstr "<qt>Löytyi useita CD-levyä vastaavia hakutuloksia.</qt>"
+#~ msgid "Remo&ve"
+#~ msgstr "Poi&sta"
+#~ msgid "Scanning CDDB cache files..."
+#~ msgstr "Selataan CDDB-välimuistitiedostoja..."
+#~ msgid "Collection &type: "
+#~ msgstr "Kokoelman &tyyppi: "
+#~ msgid "Save Entries"
+#~ msgstr "Tallenna tietueet"
+#~ msgid ""
+#~ "_: Save (Entry Title)\n"
+#~ "Save %1"
+#~ msgstr "Tallenna %1"
+#~ msgid ""
+#~ "Tellico currently supports five source types: Amazon.com, IMDB, z39.50, "
+#~ "Entrez, and external applications."
+#~ msgstr ""
+#~ "Nykyisellään Tellico tukee viittä eri lähdetyyppiä: Amazon.com, IMDB, "
+#~ "z39.50, Entrez, ja ulkoisia sovelluksia."
+#~ msgid "Enable/disable the statusbar"
+#~ msgstr "Näytä/älä näytä tilapalkki"
+#~ msgid ""
+#~ "The password will be saved in plain text in the Tellico configuration file."
+#~ msgstr "Salasana tallennetaan tekstinä Tellicon asetukset-tiedostoon."
+
+#, fuzzy
+#~ msgid "Reading files..."
+#~ msgstr "Talletetaan tiedostoa..."
+
diff --git a/po/fr.po b/po/fr.po
new file mode 100644
index 0000000..8464751
--- /dev/null
+++ b/po/fr.po
@@ -0,0 +1,5283 @@
+# translation of fr.po to
+# This file is distributed under the same license as the tellico package.
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+#
+# RNB <rnb2@wanadoo.fr>, 2004.
+# Rui Nibau <rnb2@wanadoo.fr>, 2004.
+# Regis Boudin <regis@boudin.name>, 2004, 2005, 2006, 2007, 2008.
+# Mathias Monnerville <tellico@monnerville.com>, 2006.
+msgid ""
+msgstr ""
+"Project-Id-Version: fr\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2008-01-30 23:57+0000\n"
+"Last-Translator: Regis Boudin <regis@boudin.name>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Report-Msgid-Bugs-To: \n"
+"X-Generator: KBabel 1.11.4\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "<qt>Tellico ne peut pas écrire dans le serveur pipe <b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr "Connexion à OpenOffice.org..."
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr "Connexion OpenOffice.org"
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+"Tellico n'a pas pu se connecter à OpenOffice.org. Veuillez vérifier les "
+"paramètres de connexion ci-dessous et que le programme OpenOffice.org "
+"Writer est actuellement en cours d'exécution."
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr "Tunnel"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr "TCP/IP"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr "Renommer la colonne"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr "Nouveau nom de colonne :"
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr "Colonne %1"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr "Renommer la colonne..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr "Insérer une ligne"
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr "Supprimer la ligne"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr "Se déplacer d'une ligne vers le haut"
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr "Se déplacer d'une ligne vers le bas"
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr "Effacer le tableau"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr "Aperçu du modèle"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Régler"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr "%1 :"
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Plus"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Moins"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Effacer"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Sélectionner l'image..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr "Enregister uniquement un lien"
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr ""
+"Enregister uniquement un lien n'est possible que pour les nouvelles images."
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Modifier %1"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Ajouter la collection"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Fusionner la collection"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Remplacer la collection"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr "Modifier les entrées"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "Ajouter le champ %1"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Modifier le champ %1"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Supprimer le champ %1"
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr "Ajouter des entrées"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Ajouter %1"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Renommer la collection"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Modifier le prêt"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Ajouter un filtre"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Modifier le filtre"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Supprimer le filtre"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Prêter les articles"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Prêter %1"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Supprimer les entrées"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Supprimer %1"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Réordonner les champs"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Retour de prêt"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Récupérer %1"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Général"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Condition"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Personnel"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Mes timbres"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Titre"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Description"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Dénomination"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "Pays"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Année"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Couleur"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Scott#"
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr "Superbe,Excellent,très bon,Bon,Moyen,Mauvais"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Classement"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Annulé"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Articulé"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Centrée"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Gommé"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Date d'achat"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Prix d'achat"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Emplacement"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Cadeau"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Image"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Commentaires"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Publication"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Classification"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Mes bandes dessinées"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Sous-titre"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Scénariste"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr "Artiste"
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Série"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Numéro"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Éditeur"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Édition"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Année de publication"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Pages"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Langue"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Genre"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Mots clefs"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr ""
+"Neuf,Presque neuf,Excellent,Très très bon,Très bon,Bon,Moyen,Mauvais"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Signé"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Prêté"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Couverture"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Mes pièces"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Type"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Année"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Pièce de monnaie"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Pièce"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+"Flanc bruni-65,Flan bruni-60,Fleur de coin-65,Fleur de "
+"coin-60,Superbe-55,Très très beau-50,Très très beau-40,Très "
+"beau-30,Très beau-20,Très beau-12,Beau-8,Bon-4,Moyen"
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr "PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Type de classement"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Observation"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Verso"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Mes livres"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Auteur"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Rigide"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Souple"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Économique"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "Livre électronique"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Magazine"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Journal"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Format"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Année copyright"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN#"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Numéro international normalisé du livre"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN#"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Numéro de contrôle de la Librairie du Congrès"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr "Traducteur"
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "N° dans la série"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Nouveau"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Usé"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Lu"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Note"
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr "Mes fichiers"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "Nom"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Volume"
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr "Répertoire"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr "Type MIME"
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr "Taille"
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr "Permissions"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr "Proprietaire"
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr "Groupe"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr "Cree le"
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr "Modifie le"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr "Informations additionnelles"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Propriété"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Valeur"
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr "Icone"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Mes vins"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Producteur"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Appellation"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Variété"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Cru"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Vin rouge"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Vin blanc"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Mousseux"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Quantité"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Bu par"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Étiquette"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Autres personnes"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Caractéristiques"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Mes vidéos"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr "Blu-ray"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+msgid "HD DVD"
+msgstr "HD DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Médium"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Année de production"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Certification"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Région 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Région 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Région 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Région 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Région 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Région 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Région 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Région 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Région"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Nationalité"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Format"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Distribution"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr "Acteur/Actrice"
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr "Rôle"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr "Un tableau pour la distribution du film, avec le rôle joué"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Réalisateur"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Compositeur"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Studio"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Langues disponibles"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Langues des sous-titres"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Plages audio"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Durée"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "Durée de la vidéo (en minutes)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Format d'image"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Écran large"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Noir & blanc"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Format couleur"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Version du réalisateur"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Résumé de l'action"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Note personnelle"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Couverture"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "Mes jeux"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr "Xbox 360"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr "PlayStation3"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr "Nintendo Wii"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr "Linux"
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Plateforme"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Année de parution"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Éditeur"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Developpeur"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+"Non classé, Adultes, Matures, Adolescents, Tout public, Jeunes enfants, En "
+"cours"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "Classement ESRB"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Termine"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Mes cartes"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Joueur"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Équipe"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Marque"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Numéro de carte"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Type de carte"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Image recto"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Image verso"
+
+#: collections/boardgamecollection.cpp:26
+msgid "My Board Games"
+msgstr "Mes jeux de plateau"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr "Mécanisme"
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr "Concepteur"
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr "Nombre de joueurs"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Bibliographie"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Type d'entrée"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr "Cette entrée est spécifique à BibTeX. Voir la documentation BibTeX."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Clé BibTeX"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Titre du livre"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Éditeur"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organisation"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Adresse"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr "DOI"
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr "Digital Object Identifier"
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Mois"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Nombre"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Mode de publication"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Chapitre"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Référence croisée"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Résumé"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Notes"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Ma musique"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Album"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "Disque Compact"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Cassette"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Vinyle"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Artiste"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Label"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Pistes"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr "Duree"
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr "un,une,et,dans,de,le,la"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "le,la,les"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr.,jr,iii,iv"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,le,la"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr "ISBNdb.com"
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 ne permet pas la recherche pour ce type de collection."
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Résultats de %1 : %2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "Cette source n'a pas d'option."
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "Base de données Entrez"
+
+#: fetch/entrezfetcher.cpp:485
+msgid "Institution"
+msgstr "Institution"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Erreur de requête!"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Erreur de recherche %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Enregistrer les erreurs de syntaxe"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Erreur de connexion %1: %2"
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr "Serveur SRU"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Bibliothèque du Congres (US)"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr "Hô&te: "
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr "Entrez le nom du serveur."
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Port: "
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Entrez le numéro de port du serveur. Le défaut est %1."
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr "Chemin: "
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr "Entrez le chemin de la base de données utilisée par le serveur."
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr "Format:"
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr "Entrez le format de résultat utilisé par le serveur."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr "Yahoo! Moteur de recherche audio"
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "La couverture n'a pas pu être chargée."
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr "Lien Amazon"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (US)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (UK)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Allemagne)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japon)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (France)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Canada)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Amazon.com"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "&Pays"
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "États Unis"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Royaume Uni"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Allemagne"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Japon"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "France"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Canada"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon.com propose des données de plusieurs serveurs locaux. Choisissez "
+"celui que vous désirez utiliser comme source."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "&Taille de l'image"
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Petite image"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Image moyenne"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Grande image"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Pas d'image"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"La couverture peut être également téléchargée. Cependant, de trop "
+"grosses images dans la collection peuvent dégrader les performances."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "Identité &associée : "
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+"L'identité associée identifie la personne accédant aux services Web "
+"Amazon.com, et est incluse dans tous les liens vers le site Amazon.com."
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr "Serveur z39.50"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr "Utiliser le &serveur préconfiguré :"
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "Base de &données : "
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr "Entrez le nom de base de données utilisé par le serveur."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "Jeu de c&aractères : "
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Entrez le jeu de caractères utilisé par le serveur z39.50. Le choix le "
+"plus probable est MARC-8, bien que ISO-8859-1 soit également courant."
+
+#: fetch/z3950fetcher.cpp:550
+msgid "&Format: "
+msgstr "&Format:"
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr "Détection automatique"
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+"Entrez le format de données utilisé par le serveur z39.50. Tellico "
+"essaiera de le détecter automatiquement si le choix <i>Détection "
+"automatique</i> est sélectioné."
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "&Utilisateur : "
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Optionel"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Entrez le nom de base de données utilisé par le serveur z39.50. La plupart "
+"des serveurs n'en ont pas besoin."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "&Mot de passe : "
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Entrez le mot de passe utilisé par la base de données z39.50. La plupart "
+"des serveurs n'en ont pas besoin. Le mot de passe sera conserve en clair "
+"dans le fichier de configuration de Tellico."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr "Illustrateur"
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Application externe"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "&Type de collection :"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+"Sélectionne le type de collection des données retourné par l'application "
+"externe."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr "Type de &resultat : "
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr ""
+"Sélectionne le type des résultats des données retournées par "
+"l'application externe."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "Chemin de l'a&pplication : "
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+"Sélectionne le chemin de l'application à exécuter qui devrait retourner "
+"un fichier de données Tellico valide."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr ""
+"Sélectionner les touches de recherche supportées par la source de données."
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+"Ajoutez tout argument pouvant être nécessaire.<b>%1</b> sera remplacé par "
+"l'expression recherchée."
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr "Arguments"
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+msgid "Update"
+msgstr "Mettre à jour"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+"<p>Entrer les arguments qui devraient être utilisés pour chercher les "
+"mises à jour disponibles pour une entrée donnée.</p><p>Le format est le "
+"même que pour les champs dépendants dont les valeurs des champs sont entre "
+"crochets (par exemple <i>%{author}</i>). Se référer à la documentation "
+"pour plus de détails.</p>"
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Options de source"
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr "Champs disponibles"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "Base de données de films Internet"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Sélectionnez le résultat IMDB"
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+"<qt>Votre recherche a obtenu plusieurs résultats. Veuillez sélectionner "
+"l'un des suivants.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Sélectionnez un résultat de recherche.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr "Lien IMDB"
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Titres alternatifs"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+msgid "IMDB Rating"
+msgstr "Note IMDB"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Certifications"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"La base de données de films Internet (IMDB) utilise différents serveurs. "
+"Choisissez celui que vous désirez utiliser."
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr "Nombre &maximal d'acteur : "
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+"La liste des membre de la distribution peut contenir beaucoup de personnes. "
+"Sélectionnez le nombre d'occurences maximal retourné par la recherche."
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr "Télécharger la c&ouverture"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr "Librairie internet (ibs.it)"
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Personne"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr "UPC/EAN"
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Mot-clé"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr "ID arXiv"
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr "ID Pubmed"
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Requête brute"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr "Titre original"
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr "Distributeur"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr "Épisodes"
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr "arXiv.org"
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr "%1 nécessite un nom d'utilisateur et un mot de passe."
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+"CrossRef nécessite un compte pour accéder à ses services. Lisez les "
+"termes et conditions et <a "
+"href='http://www.crossref.org/requestaccount/'>demandez un compte</a>, puis "
+"entrez les informations ci-dessous."
+
+#: fetch/crossreffetcher.cpp:343
+msgid "&Username: "
+msgstr "Num d'&utilisateur : "
+
+#: fetch/crossreffetcher.cpp:348
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+"Un nom d'utilisateur et un mot de passe sont nécessaires à l'uitilisation "
+"du service CrossRef. Notez que le mot de passe est conservé en clair dans "
+"le fichier de configuration de Tellico."
+
+#: fetch/crossreffetcher.cpp:354
+msgid "&Password: "
+msgstr "Mot de &passe : "
+
+#: fetch/gcstarpluginfetcher.cpp:190
+msgid "GCstar Plugin"
+msgstr "Greffon GCstar"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr "Sélectionne le type dedonnées retourné par le greffon."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr "&Greffon : "
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr "Sélectionner le greffon GCstar utilisé comme source de données."
+
+#: fetch/gcstarpluginfetcher.cpp:420
+msgid "Author: "
+msgstr "Auteur : "
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr "Recherche audio Discogs"
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr "Clef API :"
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+"Avec votre compte discogs.com, vous recevez une clef API pour l'utilisation "
+"de leur interface XML (voir http://www.discogs.com/help/api)."
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr "Liens Discogs"
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr "Télécharger de nouveaux modules"
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr "Version"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr "Téléchargements"
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr "Date de parution"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+"Cette liste contient les nouveaux modules disponibles au téléchargement. "
+"Ceux déjà installés sont cochés ; ceux pour lesquels une nouvelle "
+"version est disponible ont une icône de mise à jour."
+
+#: newstuff/dialog.cpp:137
+msgid "The name and license of the selected item"
+msgstr "Le nom et la licence de l'entrée sélectionnée"
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr "L'auteur de l'entrée sélectionnée"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr "Installer"
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr "Télécharger et installer le modèle sélectionné."
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+"Télécharger et installer le script sélectionné. Certains scripts peuvent "
+"nécessiter d'être configuré après l'installation."
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr "Une description de l'entrée sélectionnée est affichée ici."
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr "Téléchargement des informations..."
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Prêt."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr "Mise à jour"
+
+#: newstuff/dialog.cpp:413
+msgid "Installing item..."
+msgstr "Installation en cours..."
+
+#: translators/bibteximporter.cpp:79
+msgid "No valid bibtex entries were found"
+msgstr "Aucune entrée BibTeX valide n'a été trouvée"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "Aucune entrée BibTeX valide n'a été trouvée dans le fichier - %1"
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Options BibTeX"
+
+#: translators/bibteximporter.cpp:287
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Utiliser l'encodage Unicode (UTF-8)"
+
+#: translators/bibteximporter.cpp:288
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Lire le fichier importé en Unicode (UTF-8)."
+
+#: translators/bibteximporter.cpp:289
+msgid "Use user locale (%1) encoding"
+msgstr "Utiliser l'encodage de la locale de l'utilisateur (%1)"
+
+#: translators/bibteximporter.cpp:293
+msgid "Read the imported file in the local encoding."
+msgstr "Lire le fichier exporté dans l'encodage local."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "Fichier Zip Tellico"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Fichiers Tellico (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Tous les fichiers"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>Une bibliothèque Alexandria appelée <i>%1</i> existe déjà. Tout "
+"livre existant dans cette bibliothèque pourrait être remplacée</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "Une erreur d'analyse XML est survenue ligne %1, colonne %2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "Le message d'erreur de Qt est:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Ceci est pour une future version de Tellico."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Tellico convertit le fichier en un format plus récent. Il peut y avoir "
+"perte d'informations si ce fichier est lu par la suite avec une ancienne "
+"version de Tellico."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Inconnu"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "Le fichier est vide."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "Le fichier ne contient pas de collection."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Livres non lus"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Vieux films"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "Musique des annees 80"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Favoris"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Analyse des fichiers audio..."
+
+#: translators/audiofileimporter.cpp:129
+msgid "Bitrate"
+msgstr "Bitrate"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr "Pistes (Disque %1)"
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(Varié)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Options de fichier audio"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Recherche récursive"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+"Si cochée, les répertoires sont sont balayés récursivement pour chercher "
+"les fichiers audio."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr "&Inclure l'emplacement du fichier"
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr ""
+"Si cochée, le nom de fichier de chaque plage sera ajouté aux entrées."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr "Inclure le &bitrate"
+
+#: translators/audiofileimporter.cpp:353
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr "Si cochée, le bitrate de chaque plage sera ajouté aux entrées."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|Fichiers CSV (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "Options CSV"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Inclure les noms des champs comme en-tête des colonnes"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr "Si cochée, une ligne d'en-tête sera ajoutée avec le nom des champs."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Séparateur"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"Outre la virgule, d'autres séparateurs peuvent être utilisés pour "
+"délimiter chaque valeur dans le fichier."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Virgule"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Utiliser la virgule comme séparateur."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Point-virgule"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Utiliser le point-virgule comme séparateur."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Tab"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Utiliser la tabulation comme séparateur."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Autre"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Utiliser un autre caractère comme séparateur."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr ""
+"Un signe quelconque, comme les deux-points, peut être utilisé comme "
+"séparateur."
+
+#: translators/filelistingimporter.cpp:63
+msgid "Scanning files..."
+msgstr "Lecture des fichiers..."
+
+#: translators/filelistingimporter.cpp:191
+msgid "File Listing Options"
+msgstr "Options des listes de fichiers"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr "Recherche récursive"
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+"Si cochée, les répertoires sont sont balayés récursivement pour chercher "
+"tous les fichiers."
+
+#: translators/filelistingimporter.cpp:198
+msgid "Generate file previews"
+msgstr "Générer les prévisualisations de fichiers"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+"Si coché, la prévisualisation du contenu du fichier est générée, ce qui "
+"peut ralentir l'affichage du contenu du répertoire."
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "Archive ONIX"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.bib|Fichiers Zip (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "Options de l'archive ONIX"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Inclure les images dans l'archive"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Si cochée, les images du document seront intégrées dans le fichier ONIX."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr ""
+"<qt>Tellico n'a pas pu accéder au périphérique de type CD-ROM - "
+"<b>%1</b>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+msgid "Select CDDB Entry"
+msgstr "Supprimer l'entrée CDDB"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr "Sélectionnez une entrée CDDB:"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>Aucune entrée correspondant au CD n'a été trouvée.</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr ""
+"<qt>Tellico n'a pas pu compléter la recherche des informations du CD.</qt>"
+
+#: translators/freedbimporter.cpp:470
+msgid "Various"
+msgstr "Divers"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Options de CD Audio"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Lire les données depuis le lecteur de CD-ROM"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Sélectionner le périphérique contenant le CD audio."
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Lire dans le cache CDDB seulement"
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+"Lit les données récursivement depuis tous les fichiers de cache de CDDB "
+"dans les répertoire de cache par défaut."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr "GCfilms"
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.gcf|Fichiers de données GCFilms (*.gcf)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.gcs|Fichiers de données GCstar (*.gcs)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "Options XSLT"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "Fichier XSLT :"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr "Choisir le fichier XSLT pour transformer les données Tellico XML."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Options Alexandria"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr "Bib&liothèque :"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "BibTeXML"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Fichiers BibTeXML (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|Fichiers XML (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Options Tellico XML"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Inclure les images dans le document XML"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Si cochée, les images du document seront intégrées au flux XML comme des "
+"éléments encodés en base64."
+
+#: translators/importer.h:100
+msgid "Loading data..."
+msgstr "Importation des données..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr "Chargement de %1..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "BibTeX"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Fichiers BibTeX (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Étendre les lignes de macros"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Si cochée, les lignes de macros seront développées et aucune entrée "
+"@string{} ne sera écrite."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Utiliser le formatage URL"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr "Si cochée, tout champ URL sera transformé en déclaration \\url."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Ignorer les entrées avec des clés de citation vides"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr "Si cochée, toute entrée sans clé de citation BibTeX sera ignorée."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Styles des citations BibTeX :"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Accolades"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Guillemets"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"<qt>Le style de citation est utilisé lorsque vous exportez au format "
+"BibTeX. Les valeurs de tous les champs seront entourés d'accolades ou de "
+"guillemets.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Sélectionner le type de collection à importer."
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr "La &première ligne contient les titres des champs"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr "Si cochée, la première ligne sera utilisée pour le nom des champs."
+
+#: translators/csvimporter.cpp:248
+msgid "&Comma"
+msgstr "&Virgule"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr "&Point-virgule"
+
+#: translators/csvimporter.cpp:259
+msgid "Ta&b"
+msgstr "Ta&b"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr "Au&tre :"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "Le tableau montre les cinq premières lignes du fichier CSV."
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt>Associer chaque colonne à un champ de la collection en choisissant une "
+"colonne, sélectionnant le champ, puis en cliquant sur le bouton "
+"<i>Associer</i>.</qt>"
+
+#: translators/csvimporter.cpp:298
+msgid "Co&lumn:"
+msgstr "Co&lonne :"
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr "Champs de &donnée dans cette colonne:"
+
+#: translators/csvimporter.cpp:315
+msgid "&Assign Field"
+msgstr "&Assigner le champ"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+"Au moins une colonne doit être assignée à un champ. Seules les colonnes "
+"assignées seront exportées."
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Nouveau champ"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|Fichiers Pilot Database (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Afficher les colonnes"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "Options PilotDB"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Valider l'option PDA backup pour la base de données"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>Le fichier n'est pas un fichier GCstar valide.</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Tellico a rencontré une erreur dans le traitement XSLT."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "Un fichier XSLT valide est nécessaire pour importer le fichier."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|Fichiers XSL (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|Fichiers HTML (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Personnes"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(Regroupés par %1)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "Options HTML"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Imprimer les libellés des champs"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr ""
+"Si cochée, le nom des champs sera imprimé comme des titres de tableau."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Grouper les entrées"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr ""
+"Si cochée, les entrées seront regroupées en fonction du champ "
+"sélectionné."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Exporter individuellement les entrées"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr "Si cochée, un fichier individuel sera créé pour chaque entrée."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico n'a pas pu lire les métadonnées du fichier PDF."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+"Tellico peut télécharger les informations à propos des entrées avec un "
+"DOI CrossRef.org. Pour cela, vous devez créer un compte CrossRef et ajouter "
+"une nouvelle source de données l'utilisant."
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Propriétés de la source de données"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "Nom de la &source : "
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr ""
+"Le nom identifie la source de données et devrait être unique et informatif."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "Type de source : "
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr "Tellico supporte plusieurs sources de données différentes."
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr "La mise à jour depuis cette source doit remplacer les données"
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Si cochée, la mise à jour des entrées remplacera les données existantes."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Tout champ"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "contenant"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "ne contenant pas"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "égal à"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "différent de"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "vérifie l'expression rationnelle"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "Ne vérifie pas l'expression rationnelle"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Éditer..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Filtre avancé"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Critère du filtre"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Vérifie &toutes les règles suivantes"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Vérifie &une des règles suivantes"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Nom du filtre :"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "Enregi&strer le filtre"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Texte simple"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Paragraphe"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Choix"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Case à cocher"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Tableau"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Dépendant"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Date"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr "Mise à jour de %1..."
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr "Mettre à jour les entrées..."
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr "Mettre à jour les entrées"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr "Mise à jour de <b>%1</b>..."
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr "Sélectionner une occurence"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+"<qt><b>%1</b> a retourné plusieurs résultats qui pourraient correspondre "
+"à <b>%2</b>, entrée courante dans la collection. Veuillez sélectionner la "
+"correspondance la plus appropriée.</qt>"
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Développer tous les groupes"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Réduire tous les groupes"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Filtrer par groupe"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (Tri par nombres croissants)"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Groupe"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Options d'importation"
+
+#: importdialog.cpp:62
+msgid "&Replace current collection"
+msgstr "&Remplacer la collection actuelle"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr "Remplacer la collection actuelle par le contenu du fichier importé."
+
+#: importdialog.cpp:65
+msgid "A&ppend to current collection"
+msgstr "A&jouter à la collection actuelle"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Ajouter le contenu du fichier importé à la collection courante. Ceci n'est "
+"possible que lorsque les collections sont de même type."
+
+#: importdialog.cpp:69
+msgid "&Merge with current collection"
+msgstr "&Fusionner avec la collection courante"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Fusionner le contenu du fichier importé dans la collection courante. Ceci "
+"n'est possible que si les collections sont de même type. La totalité des "
+"entrées doit correspondre parfaitement pour que la fusion soit possible."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Importer"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|Fichiers RIS (*.ris)"
+
+#: importdialog.cpp:277
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.amc|Fichiers de données AMC (*.amc)"
+
+#: importdialog.cpp:281
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdf|Fichiers PDF (*.pdf)"
+
+#: importdialog.cpp:285
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.reflib|Fichiers Referencer (*.reflib)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico ne peut pas charger le fichier - %1."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico ne peut pas écrire dans le fichier - %1."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico ne peut pas mettre à jour le fichier - %1."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Seules les collections avec des types d'entrées identiques à la collection "
+"actuelle peuvent être ajoutées. Aucune modification n'est apportée à la "
+"collection actuelle."
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Seules les collections avec des types d'entrées identiques à la collection "
+"actuelle peuvent être fusionnées. Aucune modification n'est apportée à "
+"la collection actuelle."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico ne peut pas charger l'image depuis le fichier - %1."
+
+#: entryiconview.cpp:287
+msgid "&Sort By"
+msgstr "Trier &selon"
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Fenêtre des prêts"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "La vérification des articles suivants est en cours:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "L'objet suivant est emprunté:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "&Prêter à :"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Entrez le nom de l'emprunteur. Cliquer sur le bouton vous donne la "
+"possibilité de choisir un nom dans votre carnet d'adresses."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "Date de &l'emprunt :"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+"La date de contrôle est la date à laquelle vous avez prêté des articles. "
+"La date du jour est utilisée par défaut."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "Date de reto&ur:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"La date de retour est la date à laquelle les articles doivent être rendus. "
+"Celle-ci n'est pas obligatoire, à moins que vous ne souhaitiez intégrer ce "
+"prêt à votre calendrier courant."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Note :"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "Vous pouvez également ajouter des notes a propos du prêt."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "&Ajouter un rappel dans le calendrier actif"
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"<qt>Cocher cette case ajoutera une entrée <em>To-do</em> (tâche à faire "
+"dans le futur) dans votre calendrier actif, qui pourra être consulté en "
+"utilisant KOrganizer. Cette case n'est active que la date de retour de prêt "
+"est spécifiée."
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Créer une nouvelle collection"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Nouvelle collection de &livres"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Créer une nouvelle collection de livres"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Nouvelle b&ibliographie"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Créer une nouvelle bibliographie BibTeX"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Nouvelle collection de &bandes dessinées"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Créer une nouvelle collection de bandes dessinées"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Nouvelle collection de &vidéos"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Créer une nouvelle collection de vidéos"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Nouvelle collection &musicale"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Créer une nouvelle collection musicale"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Nouvelle collection de &pièces"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Créer une nouvelle collection de pièces"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Nouvelle collection de &timbres"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Créer une nouvelle collection de timbres"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Nouvelle collection de &cartes"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Créer une nouvelle collection de cartes"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Nouvelle collection de &vins"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Créer une nouvelle collection de vins"
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Nouvelle collection de &jeux"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Créer une nouvelle collection de jeux"
+
+#: mainwindow.cpp:272
+msgid "New Boa&rd Game Collection"
+msgstr "Nouvelle collection de jeux de &plateau"
+
+#: mainwindow.cpp:274
+msgid "Create a new board game collection"
+msgstr "Créer une nouvelle collection de jeux de plateau"
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr "Nouveau catalogue de &fichiers"
+
+#: mainwindow.cpp:282
+msgid "Create a new file catalog"
+msgstr "Créer un nouveau catalogue de fichiers"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Nouvelle collection &personnalisée"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Créer une nouvelle collection personnalisée"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Ouvrir un document existant"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Ouvrir un fichier ouvert récemment"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Enregistrer le document"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Enregistrer le document ouvert avec un nouveau nom..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Imprimer les données du document..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Quitter l'application"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Importer des données depuis d'autres formats"
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Importer des données Tellico..."
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Importer un autre fichier Tellico"
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "Importer des données CSV..."
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Importer un fichier CSV"
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "Importer des données MODS..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Importer un fichier de données MODS"
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Importer des données Alexandria..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Importer un fichier du gestionaire de collection de livres Alexandria"
+
+#: mainwindow.cpp:352
+msgid "Import Delicious Library Data..."
+msgstr "Importer des données Delicious..."
+
+#: mainwindow.cpp:353
+msgid "Import data from Delicious Library"
+msgstr "Importer des données d'une bibilothèque Delicious"
+
+#: mainwindow.cpp:359
+msgid "Import Referencer Data..."
+msgstr "Importer des données Referencer..."
+
+#: mainwindow.cpp:360
+msgid "Import data from Referencer"
+msgstr "Importer des données de Referencer"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Importer des données BibTeX..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Importer un fichier de bibliographie BibTeX"
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Importer des données BibTeXML..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Importer un fichier BibTeXML"
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "Importer des données RIS..."
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Importer un fichier de référence RIS"
+
+#: mainwindow.cpp:387
+msgid "Import PDF File..."
+msgstr "Importater un fichier PDF..."
+
+#: mainwindow.cpp:388
+msgid "Import a PDF file"
+msgstr "Importer un fichier PDF"
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Importer des données d'un fichier audio..."
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Importer des données d'un fichier audio"
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Importer des données d'un CD audio..."
+
+#: mainwindow.cpp:405
+msgid "Import audio CD information"
+msgstr "Importer des données du CD audio"
+
+#: mainwindow.cpp:414
+msgid "Import GCstar Data..."
+msgstr "Importer des données GCstar..."
+
+#: mainwindow.cpp:415
+msgid "Import a GCstar data file"
+msgstr "Importer un fichier de données GCstar"
+
+#: mainwindow.cpp:421
+msgid "Import Griffith Data..."
+msgstr "Importer des données Griffith..."
+
+#: mainwindow.cpp:422
+msgid "Import a Griffith database"
+msgstr "Importer une base de données Griffith"
+
+#: mainwindow.cpp:428
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Importer des données d'un catalogue de films Ant..."
+
+#: mainwindow.cpp:429
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Importer un catalogue de films Ant"
+
+#: mainwindow.cpp:435
+msgid "Import File Listing..."
+msgstr "Importation d'une liste de fichiers..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr "Importer les informations de fichiers dans un repertoire"
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "Importer une transformation XSL..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Importer un fichier en utilisant une transformation XSL"
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Exporter"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Exporter la collection vers un autre format"
+
+#: mainwindow.cpp:461
+msgid "Export to XML..."
+msgstr "Exporter en XML..."
+
+#: mainwindow.cpp:462
+msgid "Export to a Tellico XML file"
+msgstr "Exporter vers un fichier XML"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Exporter en Zip..."
+
+#: mainwindow.cpp:469
+msgid "Export to a Tellico Zip file"
+msgstr "Exporter vers un fichier Zip Tellico"
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "Exporter en HTML..."
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Exporter vers un fichier HTML"
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "Exporter en CSV..."
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Exporter vers un fichier CSV"
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "Exporter en PilotDB..."
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Exporter vers un fichier PilotDB"
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Exporter vers Alexandria..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Exporter vers une bibliothèque Alexandria"
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Exporter en BibTeX..."
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Exporter vers un fichier BibTeX"
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Exporter en BibTeXML..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Exporter vers un fichier BibTeXML"
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "Exporter en ONIX..."
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Exporter vers un fichier ONIX"
+
+#: mainwindow.cpp:524
+msgid "Export to GCfilms..."
+msgstr "Exporter vers GCfilms..."
+
+#: mainwindow.cpp:525
+msgid "Export to a GCfilms data file"
+msgstr "Exporter vers un fichier GCfilms"
+
+#: mainwindow.cpp:531
+msgid "Export to GCstar..."
+msgstr "Exporter vers GCstar..."
+
+#: mainwindow.cpp:532
+msgid "Export to a GCstar data file"
+msgstr "Exporter vers un fichier GCstar"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "Exporter une transformation XSL..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Exporter un fichier en utilisant une transformation XSL"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Couper le texte sélectionner et le placer dans le presse-papiers"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Copier de la sélection dans le presse-papiers"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Coller le contenu du presse-papiers"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Sélectionner toutes les entrées dans cette collection"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Désélectionner toutes les entrées de cette collection"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Chercher sur Internet..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Effectuer une recherche sur Internet..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "Filtre &avancé..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Filtrer la collection"
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&Nouvelle entrée..."
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Créer une nouvelle entrée"
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "&Éditer l'entrée..."
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Éditer les entrées sélectionnées"
+
+#: controller.cpp:621 mainwindow.cpp:577
+msgid "D&uplicate Entry"
+msgstr "D&upliquer l'entrée"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Copier les entrées sélectionnées"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "&Supprimer l'entrée"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Supprimer les entrées sélectionnées"
+
+#: mainwindow.cpp:585
+msgid "&Merge Entries"
+msgstr "&Fusioner les entrées"
+
+#: mainwindow.cpp:588
+msgid "Merge the selected entries"
+msgstr "Fusioner les entrées sélectionnées"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "&Générer des rapports..."
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Générer des rapport de collection"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "Gesti&on des prêts..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Prêter les entrées sélectionnées"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "Récupér&er"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Retour de prêt des entrées sélectionnées"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "&Renommer la collection..."
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Renommer la collection"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "&Champs de la collection..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Modifier les champs de la collection"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "Convertir en &bibliographie"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Convertir une collection de livre en bibliographie"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "Ligne de &Macros..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Éditer les lignes de macros BibTeX"
+
+#: mainwindow.cpp:626
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Copier au format BibTeX vers le &presse-papiers"
+
+#: mainwindow.cpp:627
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Copier les citations BibTeX vers le presse-papiers"
+
+#: mainwindow.cpp:632
+msgid "Cite Entry in &LyX"
+msgstr "Citer l'entrée dans &LyX"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Citer les entrées sélectionnées dans LyX"
+
+#: mainwindow.cpp:638
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Ci&ter l'entrée dans OpenOffice.org"
+
+#: mainwindow.cpp:639
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Assigner les entrées sélectionnées dans OpenOffice.org"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, no-c-format
+msgid "&Update Entry"
+msgstr "&Mettre l'entrée à jour"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr "Toutes les sources"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr ""
+"Mettre à jour les données de l'entrée à partir de l'ensemble des sources "
+"disponibles"
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Montrer la vue par &groupe"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Afficher/masquer la vue de groupe"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Masquer la vue par &groupe"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Afficher l'éditeur d'&entrée"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Afficher/masquer l'éditeur"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "Masquer l'éditeur d'&entrée"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Afficher la vue des &entrées"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Afficher/masquer la vue des entrées"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "Masquer la vue des &entrées"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Changer le regroupement"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "&Options de regroupement"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Changer le groupement de la collection"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Filtre"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Supprimer le contenu du filtre"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Filtrer ici..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Groupes"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt>La <i>vue par groupe</i> trie les entrées par groupes basés sur un "
+"champ sélectionné</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt>La <i>vue en colonnes</i> affiche la valeur de plusieurs champs pour "
+"chaque entrée</qt>"
+
+#: mainwindow.cpp:831
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Bienvenue dans le gestionaire de collections Tellico"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+"<h3>Tellico est un outil pour gérer des collections de livres, vidéos, "
+"musique, ou tout autre type de catalogue.</h3><h3> De nouvelles entréees "
+"peuvent être ajoutées à votre collection en <a "
+"href=\"tc:///coll_new_entry\">les ajoutant manuellement</a> ou en <a "
+"href=\"tc:///edit_search_internet\">téléchargeant les données</a> depuis "
+"différentes sources sur Internet.</h3>"
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Création d'un nouveau document..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Ouverture du fichier..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Ouvrir le fichier"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Enregistrer le fichier..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+"<qt><p>Vous êtes sur le point de sauvegarder un fichier contenant de "
+"nombreuses images, ce qui diminue les performances de Tellico. Voulez-vous "
+"sauvegarder les images séparément dans le répétoire de données de "
+"Tellico pour augmenter les performances de sauvegarde?</p><p>Vous pouvez à "
+"tout moment revenir sur ce choix dans la fenêtre de configuration.</p></qt>"
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr "Enregistrer les images séparément"
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr "Enregistrer les images dans le fichier"
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Enregistrer le fichier sous un nouveau nom..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Impression..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"La collection est actuellement filtrée pour n'afficher qu'une partie des "
+"entrées. Seules les entrées visibles seront imprimées. Continuer?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Traitement du document..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Fermeture..."
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Total des entrées: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 filtrée(s), %2 sélectionnée(s))"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 filtrée(s))"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 sélectionnée(s))"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Impression %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Page %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Veuillez vérifier votre installation."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Importation de données..."
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Importation d'un fichier"
+
+#: mainwindow.cpp:1864
+msgid "Import Directory"
+msgstr "Répertoire de l'import"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Exportation des données..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Exporter sous"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Ligne des macros"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Macro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Ligne"
+
+#: mainwindow.cpp:1999
+msgid "Creating citations..."
+msgstr "Creation des citations en cours..."
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Filtres"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt>La <i>vue par groupe</i> montre les entrées correspondant à certaines "
+"règles de filtrage.</qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Prêts"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt>La <i>vue des prêts en cours</i> affiche une liste de toutes les "
+"personnes ayant emprunté des articles dans votre collection.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr "Mettre à jour les données de l'entrée %1"
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+"Tellico ne peut importer qu'un seul fichier à la fois. Seul %1 sera "
+"importé."
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico ne peut pas charger l'image - %1."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+"Un fichier nommé \"%1\" existe déjà. Êtes-vous sur de vouloir le "
+"remplacer ?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Remplacer le fichier ?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Remplacer"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Filtrer (tri par nombre d'occurences)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Voulez-vous vraiment supprimer cette entrée ?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Supprimer l'entrée"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Voulez-vous vraiment supprimer ces entrées ?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Supprimer plusieurs entrées"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "&Éditer les entrées..."
+
+#: controller.cpp:627
+msgid "D&uplicate Entries"
+msgstr "D&upliquer les entrées"
+
+#: controller.cpp:628
+msgid "&Update Entries"
+msgstr "&Mettre à jour les entrées"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "&Supprimer les entrées"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+"Les articles suivants sont déjà empruntés. Par ailleurs, Tellico ne "
+"supporte pas le prêt multiple d'articles pour le moment. Ces articles vont "
+"être supprimés de la liste des articles à prêter."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Calendrier par defaut"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"Pour le moment, Tellico ne supporte que les ressources locales du "
+"calendrier. Le calendrier actif que vous souhaitez utiliser est une "
+"ressource distante: vos prêts ne seront donc pas ajoutés à ce calendrier."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Calendrier actif"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 doit retourner \"%2\""
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(Vide)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - un gestionnaire de collection pour KDE"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Ne pas charger le dernier fichier ouvert"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Importer <filename> en tant que fichier BibTeX"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Importer <filename> en tant que fichier MODS"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Importer <filename> en tant que fichier CSV"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Fichier à ouvrir"
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr "Scripts de sources de données"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Icones"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Auteur de la bibliothèque btparse"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr "Example de code et inspiration générale"
+
+#: main.cpp:50
+msgid "Author of libcsv library"
+msgstr "Auteur de la bibliothèque libcsv"
+
+#: main.cpp:52
+msgid "Author of rtf2html library"
+msgstr "Auteur de la bibliothèque rtf2html"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Champs de la collection"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Champs courants"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "&Nouveau"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Ajouter un nouveau champ à la collection"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "&Supprimer"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Supprimer un champ de la collection"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Déplacer ce champ vers le haut. L'ordre dans la liste est important pour le "
+"modèle de l'éditeur d'entrée."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Déplacer le champ vers le bas. L'ordre dans la liste est important pour le "
+"modèle de l'éditeur d'entrée."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Propriétés du champ"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "&Titre :"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "Le titre du champ"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "T&ype :"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "Le type du champ détermine quelles values peuvent être utilisées. "
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "<i>Texte simple</i> est utilisé pour la plupart des champs. "
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "<i>Paragraphe</i> est utilisé pour les textes longs. "
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Liste</i> limite le champs à certaines valeurs. "
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "<i>Case à cocher</i> est une simple valeur oui/non. "
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr "<i>Nombre</i> indiqué que le champ contient une valeur numérique. "
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+"<i>URL</i> est pour les champs faisant référence à une URL, contenant des "
+"références à d'autres fichiers. "
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr "<i>Tableau</i> peut contenir une ou plusieurs colonne(s) de valeurs. "
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "Un champs <i>Image</i> contient une image. "
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+"Un champs <i>Date</i> put être utilisé pour des valeurs avec jour, mois et "
+"année. "
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+"Un champ <i>Note</i> utilise des étoiles pour afficher une note donnée. "
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"Un champs <i>Dépendant</i> dépend des valeurs d'autres champs et est mis "
+"en forme en fonction de la description du champ. "
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"Un champ <i>Read Only</i> est utilisé pour les valeurs internes, qui "
+"peuvent être utilises pour l'importation et l'export. "
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "Caté&gorie :"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr ""
+"La catégorie du champ détermine la position du champ dans l'éditeur."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "Descr&iption :"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"La description est utile pour se rappeler quelles sont les informations "
+"contenues dans le champ. Pour les champs <i>Dépendants</i>, la description "
+"est une chaîne du type \"%{year} %{title}\" où les noms des champs sont "
+"insérés."
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr "Valeur par &défaut"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr ""
+"<qt>Une valeur par défaut peut être appliquée aux nouvelles entrées.</qt>"
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr "Va&leurs autorisées :"
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>Pour les champs type <i>Choix</i>, il s'agit des seules valeurs "
+"permises. Elles sont placées dans une liste déroulante. Les valeurs "
+"possibles doivent être séparées par un point-virgule, par exemple : "
+"\"chien; chat; souris\"</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "&Propriétés étendues :"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "&Configurer..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"Les propriétés étendues d'un champ sont utilisées pour définir par "
+"exemple le champ BibTeX correspondant."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Options de mise en forme"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Pas de mise en forme"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+"Cette option empêche le champ d'être automatiquement mis en forme ou en "
+"majuscule."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Autoriser la mise en majuscule automatique seulement"
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+"Cette option permet de mettre le champ en majuscules, sans autre mise en "
+"forme."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Mise en forme comme un titre"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Cette option met en majuscule et en forme le champ comme un titre,seulement "
+"si ces options sont globalement sélectionnées."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Mise en forme comme un nom"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Cette option met en majuscule et formate le champ comme un nom, seulement si "
+"ces options sont globalement sélectionnées."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Options des champs"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Activer l'auto-complétion"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Si cochée, l'auto-complétion de KDE sera active dans l'éditeur de texte "
+"pour ce champ."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Autoriser des valeurs multiples"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Si cochée, Tellico séparera les valeurs du champs en multiples valeurs "
+"séparées par un point-virgule."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Autoriser le regroupement"
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Si cochée, ce champ sera utilisé pour regrouper les entrées dans la vue "
+"par groupe."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr "Revenir aux valeurs par défaut pour les champs sélectionnés."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Modifier les champs"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Supprimer des valeurs possibles du champ <i>%1</i> qui existent dans la "
+"collection peut causer des corruptions de données. Voulez-vous utiliser les "
+"valeurs modifiées ou annuler et revenir aux valeurs précédentes ?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Conserver les valeurs modifiées"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Revenir aux propriétés du champ par défaut"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Voulez-vous vraiment revenir aux propriétés par défaut pour le "
+"champ <em>%1</em> ?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Revenir"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Propriétés étendues du champ"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr "Un champ avec ce nom existe déjà. Veuillez entrer un autre nom."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr ""
+"<qt><p>Voulez-vous vraiment revenir aux propriétés par défaut pour le "
+"champ <em>%1</em> ?</p></qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>Un champ ne doit pas être dans la même catégorie qu'un "
+"<em>paragraphe</em>, un <em>tableau</em> ou une <em>image</em>. Veuillez "
+"choisir une autre catégorie.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"Le nom d'un champ ne doit pas être le même que celui d'une catégorie "
+"existante. Veuillez entrer un autre nom."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+"Les valeurs utilisées pour la notation doivent être comprises entre 1 et "
+"10, la valeur numérique de la limite inférieure devant être inférieure "
+"à celle de la limite supérieure. Veuillez entrer des valeurs différentes "
+"pour les bornes supérieures et inférieures."
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "Les tableaux sont limités à un nombre maximum de dix colonnes."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Le document ouvert a été modifié.\n"
+"Voulez-vous l'enregistrer ?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Changements non sauvegardés"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Sélectionner l'emprunteur"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Configurer Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Options générales"
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr "&Rouvrir le fichier au démarrage"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Si cochée, le dernier fichier ouvert sera ouvert au prochain démarrage du "
+"programme."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "Afficher le&s \"Astuces du jour\" au démarrage"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr ""
+"Si cochée, l'\"Astuce du jour\" sera ouverte au démarrage du programme."
+
+#: configdialog.cpp:213
+msgid "Image Storage Options"
+msgstr "Options de sauvegarde des images"
+
+#: configdialog.cpp:214
+msgid "Store images in data file"
+msgstr "Inclure les images dans le fichier de donnees"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr "Enregistrer les images dans le répertoire de données de Tellico."
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr ""
+"Enregistrer les images dans un répertoire aux côtés du fichier de "
+"données."
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+"Les images peuvent être enregistrées dans le fichier de données "
+"lui-même, ce qui peut ralentir Tellico, dans le repertoire de données de "
+"Tellico, ou dans un répertoire aux cotés du fichier de données."
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Options de mise en forme"
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr "Auto capitaliser les &titres et noms"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Si cochée, les titres et les noms seront automatiquement mis en capitales."
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr "Mise en &forme automatique des titres et des noms"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr ""
+"Si cochée, les titres et les noms seront automatiquement mis en forme."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr "Ne pas mettre en majuscule :"
+
+#: configdialog.cpp:243
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Une liste de mots ne devant pas être mis en majuscules. Les suffixes "
+"doivent être séparés par un point-virgule.</qt>"
+
+#: configdialog.cpp:249
+msgid "Artic&les:"
+msgstr "Artic&les :"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>Une liste de mots qui doivent être considérés comme des articles. Les "
+"articles doivent être séparés par un point-virgule.</qt>"
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr "Suffi&xes personnels :"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Une liste de suffixes qui peuvent être utilisés dans les noms. Les "
+"suffixes doivent être séparés par un point-virgule.</qt>"
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr "&Préfixes de surnoms :"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Une liste de suffixes qui peuvent être utilisés dans les surnoms. Les "
+"suffixes doivent être séparés par un point-virgule.</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Impression"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Options d'impression"
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr "Mise en &forme des titres et des noms"
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr "Im&primer les libellés des champs"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Options de regroupement"
+
+#: configdialog.cpp:313
+msgid "&Group the entries"
+msgstr "&Grouper les entrées"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Options des images"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr "Largeur &maximale de l'image :"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"La largeur maximale de l'image lors de l'impression. Les proportions sont "
+"conservées."
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr "Hauteur &maximale de l'image :"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"La hauteur maximale de l'image lors de l'impression. Les proportions sont "
+"conservées."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Modèles"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Options du modèle"
+
+#: configdialog.cpp:369
+msgid "Template:"
+msgstr "Modèle:"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+"Sélectionez le modèle de page à utiliser pour le type de collection "
+"actuel. Tous les modèles utilisent les paramètres de polices et de "
+"couleurs."
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr "&Aperçu..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr "Afficher un aperçu du modèle"
+
+#: configdialog.cpp:398
+msgid "Font Options"
+msgstr "Options de police"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr "Police :"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr "Cette police est passée au modèle utilisé dans la vue des entrées."
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr "Taille:"
+
+#: configdialog.cpp:425
+msgid "Color Options"
+msgstr "Options de couleurs"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr "Couleur de fond :"
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr ""
+"Cette couleur est passée au modèle utilisé dans la vue des entrées."
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr "Couleur du texte :"
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr "Couleur de mise en valeur :"
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr "Couleur de mise en valeur du texte :"
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr "Gestion des modèles"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr "Installer..."
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr "Cliquer pour installer un nouveau modèle directement."
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr "Télécharger..."
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr ""
+"Cliquer pour pour télécharger des modèles supplémentaires depuis "
+"Internet."
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr "Effacer..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr "Cliquer pour sélectioner et supprimer des modèles installés."
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Sources de données"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Options de la source de données"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Source"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr "Déplacer vers &haut"
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+"L'ordre des sources de données définit l'ordre dans lequel Tellico les "
+"utilise lorsque les entrées sont automatiquement mises à jour."
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr "&Déplacer vers bas"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "&Nouveau..."
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr "Cliquer pour ajouter une nouvelle source de données."
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Modifier..."
+
+#: configdialog.cpp:533
+msgid "Click to modify the selected data source."
+msgstr "Cliquer pour modifier la source de données sélectionnée."
+
+#: configdialog.cpp:536
+msgid "Click to delete the selected data source."
+msgstr "Cliquer pour supprimer la source de données sélectionnée."
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr ""
+"Cliquer pour pour télécharger des sources de données supplémentaires "
+"depuis Internet."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr "*.tar.gz *.tgz|Paquets de momdèle (*.tar.gz)"
+
+#: configdialog.cpp:1049
+msgid "Delete Template"
+msgstr "Supprimer le modèle"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr "Choisissez le modèle à supprimer :"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "Emprunteur"
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Article rendu (fin de prêt)"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Modifier le prêt..."
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "Emprunteur (Classement par nombre d'occurences)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "Ma collection"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Collection de livres"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Collection de bandes dessinées"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Collection de vidéos"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Collection de musique"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Collection de pièces"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Collection de timbres"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Collection de vins"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Collection de cartes"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Collection de jeux"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr "Catalogue de fichiers"
+
+#: collectionfactory.cpp:135
+msgid "Board Game Collection"
+msgstr "Collection de jeux de plateau"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Collection personnalisée"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+"<qt>La <i>vue des entrées</i> affiche une vue formatée du contenu de "
+"l'entrée.</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt>La <i>vue par icônes</i> affiche chaque entrée de la collection ou "
+"groupe en utilisant une icône, qui peut être une image dans l'entrée.</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Options d'exportation"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Formatage"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Formater tous les champs"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Si cochée, tous les champs seront mis en forme selon leur type de format."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Exporter seulement les entrées sélectionnées"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr "Si cochée, seules les entrées sélectionnées seront exportées."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Encodage"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Encoder en Unicode (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Encoder le fichier exporté en Unicode (UTF-8)."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Encoder dans la locale de l'utilisateur (%1)"
+
+#: exportdialog.cpp:72
+msgid "Encode the exported file in the local encoding."
+msgstr "Encoder le fichier exporté au format local."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "&Chercher"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "&Stop"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Recherche Internet"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Requête"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr "R&echercher:"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+"Entrer une valeur à chercher. Une recherche ISBN doit inclure le numéro "
+"ISBN complet."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Choisissez le type de recherche"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Cliquez pour démarrer ou arrêter la recherche"
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr "Recherche ISBN/UPC &multiple"
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr "Cochez cette case pour chercher plusieurs valeurs ISBN ou UPC."
+
+#: fetchdialog.cpp:138
+msgid "Edit List..."
+msgstr "Liste..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr "Cliquez pour entrer ou éditer les valeurs ISBN à chercher."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "S&ource:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Choisissez la base de données dans laquelle chercher"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"Au fur et à mesure que les résultats sont trouvés, ils sont ajoutés à "
+"cette liste. En sélectionner une téléchargera l'entrée complète et "
+"l'affichera dans la vue ci-dessous."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"Une entrée peut être affichée ici avant d'être ajoutée à la "
+"collection, en la sélectionnant dans la liste ci-dessus"
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "&Ajouter l'entrée"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Ajouter l'entrée sélectionnée à la collection"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr "Obtenir plus de résultats"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr "Obtenir plus de résultats pour la recherche actuelle"
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Effacer tous les champs et valeurs"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Annulation de la recherche..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Recherche en cours..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "La recherche n'a rien trouvé."
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+"La recherche a trouvé 1 entrée.\n"
+"La recherche a trouvé %n entrées."
+
+#: fetchdialog.cpp:412
+msgid "No results were found for the following ISBN values:"
+msgstr "Aucune entrée n'a été trouvée pour les ISBN suivants :"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Téléchargement de %1..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr "Aucune source Internet n'est disponible pour ce type de collection."
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr "Éditer les valeurs ISBN/UPC"
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Entrez les valeurs ISBN ou UPC, une par ligne.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "&Charger depuis un fichier..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Charge la liste depuis un fichier texte.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>Une recherche ISBN peut contenir un maximum de 100 valeurs ISBN. Seules "
+"les 100 premières valeurs de votre liste seront utilisées.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Éditer l'entrée"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Nouvelle entrée"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "En&registrer l'entrée"
+
+#: entryeditdialog.cpp:77
+msgid "Go to the previous entry in the collection"
+msgstr "Aller à l'entrée précédente dans la collection"
+
+#: entryeditdialog.cpp:82
+msgid "Go to the next entry in the collection"
+msgstr "Aller à l'entrée suivante dans la collection"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Voulez-vous vraiment modifier ces entrées ?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Modifier plusieurs entrées"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr ""
+"Une valeur est nécessaire pour les champs suivants. Voulez-vous continuer ?"
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Éditer les entrées"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "En&registrer les entrées"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"L'entrée courante a été modifiée.\n"
+"Voulez-vous valider les modifications ?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Enregistrer l'entrée"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Rapport de collection"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "Modèle de &rapport:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "&Générer"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr "Sélectionner un modèle de rapport et cliquez sur <em>Générer</em>."
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+"Le temps de génération des rapports peut être assez long dans le cas de "
+"collections volumineuses."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Voulez-vous vraiment supprimer ce filtre ?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Supprimer le filtre ?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Nouveau nom de la collection :"
+
+#: tellico_kernel.cpp:377
+msgid "Entry 1"
+msgstr "Entrée 1"
+
+#: tellico_kernel.cpp:378
+msgid "Entry 2"
+msgstr "Entrée 2"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+"Des valeurs en conflit pour %1 ont été trouvées en fusionant des entrées."
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr "Choisissez la valeur à conserver."
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+msgid "Merge Entries"
+msgstr "Fusionner les entrées"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr "Sélectioner la valeur de %1"
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico ne peut pas trouver la feuille de style d'entrée par défaut."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Nouveau"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Collection"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Barre d'outils Collection"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Rui Nibau (RNB) Régis Boudin"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "rnb2@wanadoo.fr regis@boudin.name"
+
+#: entrymerger.cpp:35
+msgid "Merging entries..."
+msgstr "Fusion des entrées..."
+
+#: entrymerger.cpp:49
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Total des entrées scannées/fusionnées : %1"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>... que si un livre a plusieurs auteurs, vous devez séparer\n"
+" leur noms par un point-virgule. Tellico saura les séparer et les utiliser "
+"indépendamment.</p>\n"
+"<p>Tout autre champ permettant de multiples valeurs devra avoir la même "
+"structure, avec un point-virgule (;) séparant chaque valeur.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>...que vous pouvez modifier les champs à afficher dans la liste avec\n"
+"un clic droit sur l'en-tête des colonnes.</p>\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>...que vous pouvez ajouter, éditer, ou modifier les champs de la "
+"collection en utilisant\n"
+"le champ d'édition. Les boutons avec une flèche sous la liste des champs "
+"permet de modifier\n"
+"la position du champ dans la liste, ce qui affectera sa position dans "
+"l'éditeur d'entrée.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>...que si vous voulez filtrer à partir d'un champ à cocher, une valeur\n"
+"\"vrai\" devrait être définie. Si vous voulez par exemple n'afficher que "
+"les livres\n"
+"de science-fiction que vous n'avez pas encore lu, cochez\n"
+"<em>Vérifier toutes les règles</em>, ajuster la première comme suit, "
+"\"Genre\"\n"
+"\"contenant\" \"Science-fiction\" (pas de guillemets) et la seconde règles "
+"ainsi:\n"
+"\"Lu\" \"Ne contient pas\" \"Vrai\" (pas de guillemets).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>...que si un caractère non alphabétique est utilisé dans le filtrage "
+"rapide,\n"
+"le texte est interprété comme une expression régulière.</p>\n"
+"<p>Pour n'afficher que les livres de Weber ou Bujold par exemple, tapez\n"
+"\"weber|bujold\" (pas de guillemets) dans le champ du filtre.</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>...que vous pouvez éditer plus d'une entrée à la fois, en gardant "
+"appuyé\n"
+"le bouton Maj ou le bouton Ctrl et en sélectionnant plusieurs "
+"entrées.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>...que vous pouvez convertir une collection de livres en bibliographie,\n"
+"qui peut ensuite être exporter en format BibTeX ou BibTeXML.</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>...que vous pouvez ajouter, éditer et supprimer des lignes de macros\n"
+"pour les bibliographies.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>...que si plus d'un champ est formaté en tant que nom, alors un groupe\n"
+"supplémentaires nommé \"Personnes\" est ajouté à la collection, "
+"autorisant\n"
+"les auteurs et les éditeurs à être triés et imprimés ensemble par "
+"exemple.</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>...que vous pouvez modifier l'apparence de l'impression en modifiant\n"
+"le fichier <tt>tellico-printing.xsl</tt>. Le fichier produit du HTML, et "
+"les\n"
+"styles CSS déterminent la police, les marges, etc.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>...que vous pouvez importer et exporter n'importe quel modèle XSL qui\n"
+"produit un fichier Tellico XML valide.</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+"<p>...qu'un double clic sur une entrée permet d'ouvrir la fenêtre "
+"d'édition des entrées.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>...que vous pouvez ajouter des balises HTML a un champ de type paragraphe "
+"pour le mise en forme, telles que\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>...que dans la vue détaillée, vous pouvez presser une touche du clavier "
+"pour aller directement à le prochaine entrée débutant par cette "
+"lettre.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+"<p>...que vous pouvez utiliser des champs dépendants pour combiner "
+"plusieurs champs séparés en un seul ? Choisissez le type Dépendant et "
+"attribuez-lui une description du type \"Value: %{champa}%{champb}\" en "
+"remplaçant le contenu de %{...} par les noms de champs appropriés.\n"
+"Cette fonctionalité peut être utile pour grouper plusieurs valeurs en un "
+"seul champ, par exemple afin de disposer d'un meilleur regroupement; ou "
+"combiner des champs de différents types tout en respectant un ordre "
+"d'affichage cohérent. Par exemple un champ de type numérique suivi d'un de "
+"type texte permet d'avoir les entrées 3b et 14a</p>\n"
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Album"
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr "Ce modèle ne peut être utilisé que pour les collections musicales."
+
+#: xslt.cpp:5
+msgid "Total:"
+msgstr "Total :"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr "Fantaisie"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "Défaut"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Compact"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Vidéo"
+
+#: xslt.cpp:14 xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr "Ce modèle ne peut être utiliser que pour les collections de vidéos."
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Résumé des groupes"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Résumé du groupe"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Nombre total de champs :"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Nombre total d'entrées:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+msgid "Generated by Tellico"
+msgstr "Généré par Tellico"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Valeurs distinctes: "
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Liste des images"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Vue des prêts en cours"
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Date d'emprunt"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Note"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Date de retour"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Vue par groupe"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Liste des titres (horizontale)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Liste des titres (verticale)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Vue en colonne"
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "Vue sur trois colonnes"
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr "Chercher"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr "La bibliothèque britanique (The British Library)"
+
+#: z3950.cpp:6
+msgid "Sudoc (France)"
+msgstr "Sudoc (France)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr "BIBSYS (Norvège)"
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr "Bibliothèque nationale italienne"
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr "Bibliothèque nationale portugaise"
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr "Bibliothèque nationale de Pologne"
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr "Bibliothèque nationale du Canada"
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr "Israël Union List"
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr "Bibliothèque nationale d'Australie"
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr "Bibliothèque nationale de Lituanie"
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr "Copac (Royaume Uni et Irlande)"
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr "BoardGameGeek"
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr "Dark Horse Comics"
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr "Allociné.fr"
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr "Ministère Espagnol de la culture"
diff --git a/po/hu.po b/po/hu.po
new file mode 100644
index 0000000..1a8867b
--- /dev/null
+++ b/po/hu.po
@@ -0,0 +1,5246 @@
+# translation of hu.po to Hungarian
+# Marcel Hilzinger <hili@suselinux.hu>, 2003.
+# Zakariás, Csaba <csaba.zakarias@gmail.com>, 2008.
+# This file is distributed under the same license as the tellico package.
+# Copyright (C) 2004 Robby Stephenson
+msgid ""
+msgstr ""
+"Project-Id-Version: hu\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2006-06-10 13:51+0200\n"
+"Last-Translator: Zakariás, Csaba <csaba.zakarias@gmail.com>\n"
+"Language-Team: <hu@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Report-Msgid-Bugs-To: \n"
+"X-Generator: KBabel 1.11.2\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "<qt>A Tellico nem tud a fájlba írni: <b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr "Kapcsolódás OpenOffice.org-hoz..."
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr "OpenOffice.org kapcsolat"
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+"Tellcio nem tud csatlakozni az OpenOffice.org-hoz. Kérem ellenőrizze a "
+"csatlakozás beállításait, valamint azt is, hogy az OpenOffice.org "
+"Szöveg jelenleg fut-e."
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr "Cső"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr "TCP/IP"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr "Oszlop átnevezése"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr "Új oszlop név:"
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr "Oszlopok:"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr "Oszlop átnevezése..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr "Sor beszúrása"
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr "Sor eltávolítása"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr "Sor mozgatása felfelé"
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr "Sor mozgatása lefelé"
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr "Tábla tartalmának törlése"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr "Sablon előnézet"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Beállítás"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr "%1:"
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Több"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Kevesebb"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Törlés"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Kép kiválasztása..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr "Csak a hivatkozás mentése"
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr ""
+"Hivatkozást csak újonnan hozzáadott képek esetében lehet elmenteni."
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "%1 módosítása"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Gyűjtemény hozzátoldása"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Gyűjtemények összefűzése"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Gyűjtemény kicserélése"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr "Bejegyzések szerkesztése"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "%1 mező hozzáadása"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "%1 mező módosítása"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "%1 mező törlése"
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr "Bejegyzések hozzáadása"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "%1 hozzáadása"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Gyűjtemény átnevezése"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Kölcsönzés módosítása"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Szűrő hozzáadása"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Szűrő módosítása"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Szűrő törlése"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Elemek kivétele"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "%1 kivétele"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Bejegyzések törlése"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "%1 törlése"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Mezők úrarendezése"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Bejegyzések bevezetése"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "%1 bevezetése"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Általános"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Állapot"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Személyes"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Bélyegeim"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Cím"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Leírás"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Névérték"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "Ország"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Kiadás éve"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Színes"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Épség"
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr ""
+"Kíváló,Igen nagyszerű,Meglehetősen nagyszerű,Nagyszerű,Átlagos,Gyenge"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Fajta"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Visszavont"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Fogazott"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Középre állított"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Enyvezett hátú"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Vásárlás dátuma"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Vásárlási ár"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Hely"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Ajándék"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Kép"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Megjegyzések"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Kiadás"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Osztályozás"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Képregényeim"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Alcím"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Szerző"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr "Képregény illusztrátor"
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Sorozat"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Kiadás"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Kiadó"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Kiadás"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Kiadás éve"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Oldalak"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Nyelv"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Fajta"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Kulcsszavak"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr ""
+"Eredeti,Majdnem eredeti,Nagyon nagyszerű,Nagyszerű,Nagyon "
+"jó,Jó,Elmegy,Gyenge"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Dedikált"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Kölcsön adva"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Fedlap"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Érméim"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Típus"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Év"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Pénzverde jele"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Érme sorozat"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr "PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Osztályozás"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Fej"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Irás"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Könyveim"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Szerző"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Kemény tábla"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Kartonált"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Papírtábla"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "E-könyv"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Újság"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Folyóirat"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Kötészet"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Copyright éve"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN#"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "International Standard Book Number"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN#"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Library of Congress Control Number"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr "Fordító"
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Sorozatszám"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Új"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Használt"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Olvasva"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Értékelés"
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr "Fájljaim"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "Név"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Kötet"
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr "Könyvtár"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr "Mime típus"
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr "Méret"
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr "Jogosultságok"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr "Tulajdonos"
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr "Csoport"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr "Létrehozva"
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr "Módosítva"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr "Meta információ"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Tulajdonság"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Érték"
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr "Ikon"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Boraim"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Producer"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Elnevezés"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Változat"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Évjárat"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Vörös bor"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Fehér bor"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Pezsgő bor"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Mennyiség"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Kostólta"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Címke"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Készítők"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Jellemzők"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Videóim"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr "Blu-ray"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+msgid "HD DVD"
+msgstr "HD DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Hordozó"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Kiadás éve"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "KN, 12, 16, 18"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Osztályozás"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "1 régió"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "2 régió"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "3 régió"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "4 régió"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "5 régió"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "6 régió"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "7 régió"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "8 régió"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Régió"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Nemzetiség"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Formátum"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Szereposztás"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr "Színész/nő"
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr "Szerep"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr "A szereplők táblázata az alakított szerepekkel"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Rendező"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Zeneszerző"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Stúdió"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Nyelvek"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Felíratok nyelve"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Hangsávok"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Játékidő"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "Videó játékideje (percben)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Képarány"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Szélesvásznú"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Fekete - fehér"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Szín mód"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Rendező vágása"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Tartalom összefoglalója"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Személyes értékelés"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Fedél"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "Játékaim"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr "Xbox 360"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr "PlayStation3"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr "Nintendo Wii"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr "Linux"
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Platform"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Kiadás éve"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Kiadó"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Fejlesztő"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+"Kategória nélküli, Felnőtt, Tinédzser, Kisgyermek, Mindenki, Nem "
+"eldöntött"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "ESRB Értékelés"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Befejezve"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Kártyáim"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Játékos"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Csapat"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Márka"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Kártya szám"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Kártya típusa"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Előlap"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Hátlap"
+
+#: collections/boardgamecollection.cpp:26
+msgid "My Board Games"
+msgstr "Társasjátékaim"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr "Mechanizmus"
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr "Tervező"
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr "Játékosok száma"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Bibliográfia"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Bejegyzés típusa"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+"Ez a bejegyzés típus bibtex formátumú. Lásd a bibtex dokumentációt."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Bibtex kulcs"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Könyv címe"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Szerkesztő"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Szervezet"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Postacím"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr "DOI"
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr "Digitális objektum azonosító"
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Hónap"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Szám"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Kiadás módja"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Fejezet"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Keresztreferencia"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Összefoglalás"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Megjegyzések"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Zenéim"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Album"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "CD lemez"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Kazetta"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "LP"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Előadó"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Cím"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Sávok"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr "Hossz"
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "a(z)"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr.,jr,iii,iv"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,van,der,van der,von"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr "ISBNdb.com"
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 nem engedi meg, hogy ezt a típusú gyűjteményben keressen."
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Eredmény %1 -ből: %2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "A forrás nem rendelkezik beállításokkal."
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "Belépő adatbázis"
+
+#: fetch/entrezfetcher.cpp:485
+msgid "Institution"
+msgstr "Állapot"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Lekérdezési hiba!"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Csatlakozás keresési hiba %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Rekord szintaxis hiba"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Csatlakozási hiba %1: %2"
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr "SRU szerver"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Kongresszusi könyvtár (Egyesült Államok)"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr "&Hoszt:"
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr "Adja meg a szerver nevét."
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Port szám:"
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Adja meg a szerver nevét. Az alapértelmezett: %1."
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr "Útvonal:"
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr "Adja meg a szerver által használt adatbázis elérési útvonalát."
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr "Formátum: "
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr "Adja meg a szerver által használt formátumot."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr "Yahoo! Audió keresés"
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "Nem tölthető be a címlap kép."
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr "Amazon (Japán)"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (Egyesült Államok)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (Nagy Britannia)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Németország)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japán)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (Franciaország)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Kanada)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Amazon.com Web Szervízek"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "&Ország:"
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "Egyesült Államok"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Nagy Britannia"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Németország"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Japán"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "Franciaország"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Kanada"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Az Amazon.com számos különböző helyi oldalról nyújt adatokat. "
+"Válasszon egyet, melyet az adatforráshoz használni akar."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "&Kép méret: "
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Kis méretű kép"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Közepes méretű kép"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Nagy méretű kép"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Kép nélkül"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"A fedlap kép feltehetőleg megfelelően töltődött be. Azonban a "
+"gyűjteményben lévő túl sok nagyméretű kép csökkenti a "
+"teljesítményt."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "&Társított azonosító:"
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+"A kisegítő azonosító az Amazon.com web szolgáltatást igénybevevő "
+"személyt azonosítja, ez benne van minden Amazon.com webehlyre mutató "
+"linkben."
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr "z39.50 Szerver"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr "Használja az előre beállított szervert:"
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "&Adatbázis:"
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr "Adja meg a szerver által használt adatbázis nevét."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "Karakter készlet:"
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Adja meg a z39.50 szerver által használt karakter készlet kódolását. A "
+"legvalószínűbb választás a MARC-8, habár ISO-8859-1 az általános."
+
+#: fetch/z3950fetcher.cpp:550
+msgid "&Format: "
+msgstr "&Formátum: "
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr "Automatikus kijelölés"
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+"Adja meg a z39.50 szerver által használt adat formátumot. A Tellico "
+"automatikusan a legjobb beállítást választja, ha az <i>Automatikus "
+"kijelölés</i>t kiválasztotta."
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "&Felhasználó: "
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Opcionális"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Adja meg a z39.50 adatbázishoz az érvényes felhasználó nevét. A "
+"legtöbb szervernél ez nem szükséges."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "&Jelszó: "
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Adja meg a z39.50 adatbázishoz az érvényes jelszót. A legtöbb "
+"szervernél ez nem szükséges. A jelszót nyílt szövegként a Tellico "
+"beállítási fáljba kerül elmentésre."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr "Illusztrátor"
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Külső alkalmazás"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "Gyű&jtemény típusa:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+"Állítsa be a külső alkalmazás által visszaadott adat gyűjtemény "
+"típusát."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr "&Eredmény típusa: "
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr "Állítsa be a külső alkalmazás által visszaadott adat típusát."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "&Alkalmazás elérési útja:"
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+"Állítsa be a futtatandó alkalmazás elérési útvonalát, mely "
+"érvényes Tellico adatfájlt hoz létre."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr "Válassza ki az adat forrásnak megfelelő keresési kulcsokat."
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+"Addja meg a szükséges változókat. A(z) <b>%1</b> a keresési "
+"kifejezésekkel lesz helyettesítve."
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr "Változók"
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+msgid "Update"
+msgstr "Frissítés"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+"<p>Adja meg azokat az argumentumokat, melyek alapján a bejegyzés "
+"elérhető frissítését megkeresheti.</p><p>A formátum a <i>Függő</i> "
+"mezőkhöz hasonló, ahol a mező értékek kapcsos zárójelek között "
+"találhatók, például <i>%{author}%</i>. További részletekért "
+"fordultjon a dokumentációhoz.</p>"
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Forrás beállítások"
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr "Elérhető mezők"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "Internet Movie Database"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Válassza ki az IMDB eredmény"
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+"<qt>A keresés eredménye több értékű. Kérem válasszon közülük.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Válasszon a keresés eredményeiből.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr "IMDB kapcsolat"
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Alternatív címek"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+msgid "IMDB Rating"
+msgstr "IMDB értékelés"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Osztályozás"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr "Az IMDB több szervert használ. Válasszon közülük. "
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr "&Maximális stáb:"
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+"A stáb tagjainak listája sok személyt tartalmazhat. Adja meg a keresési "
+"eredmény számának maximális értékét."
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr "&Fedlap kép letöltése"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr "Internet Bookshop (ibs.it)"
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Személy"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr "UPC/EAN"
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Kulcsszó"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr "arXiv azonosító"
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr "Pubmed azonosító"
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Nyers lekérdezés"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr "Eredeti cím"
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr "Forgalmazó"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr "Epizódok"
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr "arXiv.org"
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr "%1 felhasználó nevet és jelszót kér."
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+"A CrossRef hozzáféréshez hozzáférésre van szüksége. Olvassa el a "
+"feltételeket, <a href='http://www.crossref.org/requestaccount/'>kérjen "
+"hozzáférést</a>. Adja meg az OpenURL hozzáférési információkat."
+
+#: fetch/crossreffetcher.cpp:343
+msgid "&Username: "
+msgstr "&Felhasználónév: "
+
+#: fetch/crossreffetcher.cpp:348
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+"Felhasználónévre és jelszóra van szükség a CrossRef "
+"szolgáltatáshoz.A jelszót nyílt szövegként a Tellico beállítási "
+"fáljba kerül elmentésre."
+
+#: fetch/crossreffetcher.cpp:354
+msgid "&Password: "
+msgstr "&Jelszó: "
+
+#: fetch/gcstarpluginfetcher.cpp:190
+msgid "GCstar Plugin"
+msgstr "GCstar beépülő modul"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr ""
+"Állítsa be a beépülő modul által visszaadott adat gyűjtemény "
+"típusát."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr "&Beépülő modul"
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr "Válassza ki a GCstar beépülő modult az adat forráshoz."
+
+#: fetch/gcstarpluginfetcher.cpp:420
+msgid "Author: "
+msgstr "Szerző : "
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr "Discogs Audió keresés"
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr "API &kulcs: "
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+"A discogs.com hozzáférésével megkapja az XML alapú felület "
+"hsaználatához szükséges API kulcsot (lásd "
+"http://www.discogs.com/help/api)"
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr "Discogs kapcsolat"
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr "Vadiúj dolgok letöltése"
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr "Verzió"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr "Letöltések"
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr "Kibocsátás éve"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+"A letölthető elemek listája. A már feltelepített elemek előtt pipa, "
+"azelérhető új verziók előtt frissítés ikon található."
+
+#: newstuff/dialog.cpp:137
+msgid "The name and license of the selected item"
+msgstr "Kiválasztott elemek neve és licencelése"
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr "Kiválasztott elem szerzője"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr "Telepítés"
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr "A kiválasztott sablon letöltése és telepítése"
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+"A kiválasztott szkript letöltése és telepítése. Néhány szkriptet a "
+"letöltés után be kell még állítani."
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr "Kiválasztott elemek leírása"
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr "Letöltési információ..."
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Kész."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr "Frissítés"
+
+#: newstuff/dialog.cpp:413
+msgid "Installing item..."
+msgstr "Elem telepítése..."
+
+#: translators/bibteximporter.cpp:79
+msgid "No valid bibtex entries were found"
+msgstr "Nem található érvényes bibtex bejegyzés"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "Nem található érvényes bibtex bejegyzés a fájlban - %1"
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Bibtex beállítások"
+
+#: translators/bibteximporter.cpp:287
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Használja a Unicode (UTF-8) kódolást"
+
+#: translators/bibteximporter.cpp:288
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Exportált fájl beolvasása Unicode (UTF-8)-ban."
+
+#: translators/bibteximporter.cpp:289
+msgid "Use user locale (%1) encoding"
+msgstr "A felhasználói (%1) kódolás használata"
+
+#: translators/bibteximporter.cpp:293
+msgid "Read the imported file in the local encoding."
+msgstr "Exportált fájl olvasása helyi kódolási formátumban."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "Tellico Zip fájl"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Tellico fájlok (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Minden fájl"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>A kért <i>%1</i> Alexandria könyvtár már létezik. A könyvtárban "
+"bármelyik létező könyv felülírható.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "A %1 sor, %2 oszlopában XML hiba van."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "A Qt hibaüzenet a következő:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Ez egy későbbi verzióhoz tartozik."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Tellico átkonvertálja a fájlt egy mot használt formátumra. "
+"Előfordulhat információ vesztés, ha a Tellico egy régebbi verziójával "
+"olvassa be a jövőben."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Ismeretlen"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "A fájl üres."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "A fájl nem tartalmaz gyűjtemény adatot."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Még nem olvasott könyvek"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Régi mozik"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "80-s évek zenéje"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Kedvencek"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Hang fájlok átvizsgálása"
+
+#: translators/audiofileimporter.cpp:129
+msgid "Bitrate"
+msgstr "Bitráta"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr "Sávok (lemez %1)"
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(Különböző)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Hang fájlok beállításai"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Rekurzív könyvtár keresés"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr "Ha kijelöli, a hang fáljokat rekurzívan keresi a könyvtárakban."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr "&Fájl helyének belefoglalása"
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr ""
+"Ha kijelöli, az egyes sávok fájl nevei hozzáadódnak a bejegyzésekhez."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr "&Bitráta tartalmazása"
+
+#: translators/audiofileimporter.cpp:353
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr ""
+"Ha kijelöli, az egyes sávok bitrátái hozzáadódnak a bejegyzésekhez."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|CSV fájlok (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "CSV beállítások"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Mező címek belefoglalása oszlop fejlécekként"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr "Ha kijelöli, a mező cimekkel együtt a fejléc sort is hozzáadja."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Határoló"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"Vessző, vagy más karaktert htárolóként alkalmazva a fájlban az egyes "
+"értékek megkülönböztethetők."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Vessző"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Vesszőt használja határolóként."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Pontos vessző"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Pontos vesszőt használja határolóként."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Tabulátor"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Tabulátort használja határolóként."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Más"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Az egyedi karaktert használja határolóként."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr "Egyedi karakter, pl. vessző, használható határolóként."
+
+#: translators/filelistingimporter.cpp:63
+msgid "Scanning files..."
+msgstr "Hang fájlok átvizsgálása..."
+
+#: translators/filelistingimporter.cpp:191
+msgid "File Listing Options"
+msgstr "Fájl listázási beállítások"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr "Rekurzív könyvtár keresés"
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr "Ha kijelöli, a fáljokat rekurzívan keresi a könyvtárakban."
+
+#: translators/filelistingimporter.cpp:198
+msgid "Generate file previews"
+msgstr "Fájl előnézet létrehozása"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+"Ha kijelöüli, a fájl tartalmának előnézete létrejön, ez "
+"lelassíthatja könyvtár listázást."
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "ONIX archiv"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.zip|Zip fájlok (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "ONIX archiv beállítások"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Képek hozzáadása az archívumhoz"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Ha kijelöli, a dokumentumban lévő képeet is tartalmazza a zippelt ONIX "
+"archívum."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr ""
+"<qt>Tellico nem tudott hozzáférni a <i>%1</i> CD-ROM eszközhöz.</qt>"
+
+#: translators/freedbimporter.cpp:196
+msgid "Select CDDB Entry"
+msgstr "CDDB bejegyzés kijelölése"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr "Válassza ki az CDDB bejegyzést:"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>A CD-hez nem található megfelelő rekord.</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "<qt>A Tellico nem tudta befejezni a CD keresését.</qt>"
+
+#: translators/freedbimporter.cpp:470
+msgid "Various"
+msgstr "Különböző"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Hang CD beállítások"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Adatok olvasása a CD-ROM-ról"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Válassza ki, vagy adja meg a CD-ROM elérését."
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Csak a CDDB fájlok olvasása"
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+"Az alapértelmezett gyorstár könyvtárban lévő CDDB gyorstár fájlok "
+"rekurzív olvasása."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr "GCFilmek"
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.gcf|GCFilm adatfájlok (*.gcf)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.gcs|GCstar adatfájlok (*.gcs)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "XSLT beállítások"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "XSLT fájl:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr "Válassza ki a Tellico XML adat transzformálásához az XSLT fájlt."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Alexandria beállítások"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr "&Könyvtár:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "Bibtexml"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Bibtexml fájlok (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|XML fájlok (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Tellico XML beállítások"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Az XML dokumentum tartalmazza a képeket"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Ha kijelöli ezt a pontot, akkor a csoportnév mögött a csoportban lévő "
+"elemek száma is megjelenik."
+
+#: translators/importer.h:100
+msgid "Loading data..."
+msgstr "Adat betöltése..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr "%1 betöltése..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "Bibtex"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Bibtex fájlok (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Karakterlánc makrók kibontása"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Ha kijelöli ezt az opciót, a karakterlánc makrók kibonthatók, @string{} "
+"bejegyzések nem kerülnek felülírásra."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Használja az URL csomagot"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr ""
+"Ha kijelöli ezt az opciót, akkor a mezőnevek fejlécként kinyomtatásra "
+"kerülnek"
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Hagyja figyelmen kívül az üres idézőjeleket."
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr ""
+"Ha kijelöli az opciót, figyelmen kívül hagyjuk a bibtex idézőjelek "
+"nélküli bejegyzéseket."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Bibtex idézőjel stílusa:"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Kapcsos zárójel"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Idéző jelek"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"<qt>Bibtex exportálásakor alkalmazott idézőjel stílusa. A kapcsos "
+"zárójellel, vagy idézőjellel ellátott mezők értékét figyelmen "
+"kívül hagyja.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Jelölje ki az importálandó gyűjtemény típusát."
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr "&Első sor a mező címeit tartalmazza"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr "Ha kijelöli, az első sormező címként kerül feldolgozásra."
+
+#: translators/csvimporter.cpp:248
+msgid "&Comma"
+msgstr "&Vessző"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr "&Pontos vessző"
+
+#: translators/csvimporter.cpp:259
+msgid "Ta&b"
+msgstr "&Tabulátor"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr "&Más:"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "A táblázat a CSV fájl első öt sorát mutatja."
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt>Az oszlop kiválasztásával kapcsolja összes az egyes oszlopokat a "
+"gyűjtemény mezőivel, válassza ki a mezőt, majd kattintson a <i>Mező "
+"hozzárendelése</i> gombra.</qt>"
+
+#: translators/csvimporter.cpp:298
+msgid "Co&lumn:"
+msgstr "&Oszlop:"
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr "&Adatmező az oszlopban:"
+
+#: translators/csvimporter.cpp:315
+msgid "&Assign Field"
+msgstr "&Kapcsolt mező"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+"Legalább egy oszlopot hozz kell rendelnie a mezőhöz. Csak a hozzárendelt "
+"oszlopok importálódnak."
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Új mező"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|Pilot Adatbázis fájlok (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Oszlopok megtekintése"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "PilotDB beállítások"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "PDA mentési jel beállítása az adatbázishoz"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>A fájl nem GCstar adat fájl.</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Hiba keletkezett az XSLT feldolgozásakor."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "Érvényes XSLT fájlra van szükség az importáláshoz."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|XSL fájlok (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|HTML fájlok (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Személy"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(%1 szerint csoportosítva)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "HTML beállítások"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Mező fejlécek nyomtatása"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr "Ha kijelöli, a mezőnevek fejlécként nyomtatja ki."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Bejegyzések csoportosítása"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr ""
+"Ha kijelöli, a kiválasztott mező alapján csoportosíthatja az elemeket."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Egyedi bejegyzés fájlok exportálása"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr "Ha kijelöli, az egyes bejegyzésekhez egyedi fájlok készülnek."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Nem sikerült a PDF fájlból a metaadatok kiolvasása."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+"Tellico le tudj atölteni az információt a CrossRef.rg-ról. Azoban ehhez "
+"létre kell hoznia egy CrossRef hozzáférést, valamint egy adatforrást a "
+"hozzáférési információival."
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Adatforrás tulajdonságok"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "&Forrás neve:"
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr ""
+"A név azonosítja az adatforrást, egyedinek és informatívnak kell lennie."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "Forrás típusa:"
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr "Tellico számos különböző adat forrást támogat."
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr ""
+"A forrásból történő frissítés felülírja a felhasználói adatokat"
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Ha kijelöli, a frissülő bejegyzések felülírják a meglévő "
+"információkat."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Bármelyik mező"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "tartalmaz"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "nem tartalmaz"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "egyenlő"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "nem egyenlő"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "egyező reguláris kifejezés"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "nem egyező reguláris kifejezés"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Szerkesztés..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Finomított szűrő"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Szűrés kritériuma"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Minden alábbival egyező"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Az alábbiakkal nem egyező"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Szűrő neve:"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "&Szűrő mentése"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Egyszerű szöveg"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Bekezdés"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Választás"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Kijelölés"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Táblázat"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Függő"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Dátum"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr "%1 frissítése..."
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr "Bejegyzések frissítése..."
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr "Bejegyzések frissítése"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr "<b>%1</b> frissítése..."
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr "Válassza ki az egyezőt"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+"<qt><b>%1</b> többszörös eredményt adott vissza, mely megegyezik "
+"<b>%2</b>-vel, az egyik bejegyzéssel a gyűjteményben. Kérem válassza ki "
+"a megfelelőt.</qt>"
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Csoportok kibontakozása"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Csoportok összecsukása"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Szűrés csoport szerint"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (Mennyiség szerint csoportosítva)"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Csoport"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Importálás beállításai"
+
+#: importdialog.cpp:62
+msgid "&Replace current collection"
+msgstr "&Jelenlegi gyűjtemény kicserélése"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr ""
+"A jelenlegi gyűjtemény kicserélése az importált fájl tartalmával."
+
+#: importdialog.cpp:65
+msgid "A&ppend to current collection"
+msgstr "&Hozzáfűzés a jelenlegi gyűtményhez"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Az importált fájl tartalmának hozzáfűzése a jelenlegi gyűjteményhez. "
+"Ez csak akkor lehetséges, ha egyezik a gyűjtemény típusa."
+
+#: importdialog.cpp:69
+msgid "&Merge with current collection"
+msgstr "Össze&fésülés a jelenlegi gyűjteménnyel"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Az importált fájl tartalmának összefésülése a jelenlegi "
+"gyűjteményhez. Ez csak akkor lehetséges, ha egyezik a gyűjtemény "
+"típusa. A bejegyzéseknek pontosan egyezniük kell az összefésüléshez."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Importálás"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|RIS fájlok (*.ris)"
+
+#: importdialog.cpp:277
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.amc|ANC adatfájlok (*.amc)"
+
+#: importdialog.cpp:281
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdf|PDF fájlok (*.pdf)"
+
+#: importdialog.cpp:285
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.rflib|Referencia fájlok (*.rflib)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Nem sikerült a(z) %1 fájl betöltése."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "A Tellico nem tud a fájlba írni: %1."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Nem sikerült a(z) %1 fájl feltöltése."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Csak a jelenlegivel azonos bejegyzés típusú gyűjtemények adhatók "
+"össze. A jelenlegi gyűjtemény nem változik."
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Csak a jelenlegivel azonos bejegyzés típusú gyűjtemények "
+"egyesíthetők. A jelenlegi gyűjtemény nem változik."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Nem sikerült a(z) %1 fájlból a kép betöltése."
+
+#: entryiconview.cpp:287
+msgid "&Sort By"
+msgstr "&E szerint rendezve"
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Kölcsönzés dialógus"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "A következő elemek lesznek kivezetve:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "A következő elem kölcsön van adva:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "Kölcsönözve:"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Adja meg a személyt, mely ezt kölcsönvette Öntöl. A gombra kattintva a "
+"címjegyzékből kiválaszhatja."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "Kölcsönadás dátuma:"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+"A kiadás dátuma az a nap, mikor kölcsönadta ezt. Alapértelmezésként a "
+"mai napot használjuk."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "&Lejárat napja:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"A lejárat napja az, mikor vissza kell adni. A lajárat napja nem "
+"szükséges, kivéve ha az archívum naptárhoz ezt hozzá akarja adni."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Megjegyzés:"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "Hozzáadhat megjegyzéseket a kölcsönadáshoz."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "&Emlékeztető hozzáadása az aktív naptárhoz."
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"<qt>Ha kijelöli, egy <em>To-do</em> elemet ad hozzá az aktív naptárhoz, "
+"ezt a KOrganizer-ben láthatja. Ez csak akkor aktív, ha beállította a "
+"lejárat napját.</qt>"
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Új gyűjtemény létrehozása"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Új &Könyv gyűjtemény"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Új könyv gyűjtemény létrehozása"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Új B&ibliográfia"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Új bibtex bibliográfia létrehozása"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Új K&épregény gyűjtemény"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Új Képregény gyűjtemény létrehozása"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Új Fi&lm gyűjtemény"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Új Film gyűjtemény létrehozása"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Új &Zene gyűjtemény"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Új Zene gyűjtemény létrehozása"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Új Ér&me gyűjtemény"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Új Érme gyűjtemény létrehozása"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Új &Bélyeg gyűjtemény"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Új Bélyeg gyűjtemény létrehozása"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Új K&ártya gyűjtemény"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Új Névkártya gyűjtemény létrehozása"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Új Bo&r gyűjtemény"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Új Bor gyűjtemény létrehozása"
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Új &Játék gyűjtemény"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Új Játék gyűjtemény létrehozása"
+
+#: mainwindow.cpp:272
+msgid "New Boa&rd Game Collection"
+msgstr "Új &Társasjáték gyűjtemény"
+
+#: mainwindow.cpp:274
+msgid "Create a new board game collection"
+msgstr "Új Társasjáték gyűjtemény létrehozása"
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr "Új &Fájl gyűjtemény"
+
+#: mainwindow.cpp:282
+msgid "Create a new file catalog"
+msgstr "Új Fájl gyűjtemény létrehozása"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Új &Egyedi gyűjtemény"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Új Egyedi gyűjtemény létrehozása"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Meglévő dokumentum megnyitása"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Mostanában használt fájl megnyitása"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Jelenlegi dokumentum mentése"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Jelenlegi dokumentum mentése másként..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Dokumentum tartalmának nyomtatása..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Kilépés a programból"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Gyűjtemény adat importálása más formátumokból"
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Tellico adat importálása..."
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Más Tellico adat fájl importálása"
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "CSV adat importálása"
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "CSV fájl importálása..."
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "MODS adat importálása..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "MODS adat fájl importálása..."
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Alexandria adat importálása..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Adat importálása Alexandria könyv gyűjtemény kezelőből"
+
+#: mainwindow.cpp:352
+msgid "Import Delicious Library Data..."
+msgstr "Delicious Library adat importálása..."
+
+#: mainwindow.cpp:353
+msgid "Import data from Delicious Library"
+msgstr "Adat importálása a Delicious Library-ból"
+
+#: mainwindow.cpp:359
+msgid "Import Referencer Data..."
+msgstr "Rerefencia adat importálása"
+
+#: mainwindow.cpp:360
+msgid "Import data from Referencer"
+msgstr "Adat importálása referenciából"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Bibtex adat importálása..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Bibtex bibliográfia fájl importálása..."
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Bibtexml adat importálása..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Bibtexml bibliográfia fájl importálása..."
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "RIS adat importálása"
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "RIS referencia fájl importálása..."
+
+#: mainwindow.cpp:387
+msgid "Import PDF File..."
+msgstr "PDF fájl importálása..."
+
+#: mainwindow.cpp:388
+msgid "Import a PDF file"
+msgstr "Egy PDF fájl importálása..."
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Hang fájl metaadat importálása..."
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Metaadat importálása hang fájlból..."
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Hang CD adat importálása..."
+
+#: mainwindow.cpp:405
+msgid "Import audio CD information"
+msgstr "Hang CD információ importálása"
+
+#: mainwindow.cpp:414
+msgid "Import GCstar Data..."
+msgstr "GCstar adat importálása..."
+
+#: mainwindow.cpp:415
+msgid "Import a GCstar data file"
+msgstr "GCstar adat fájl importálása"
+
+#: mainwindow.cpp:421
+msgid "Import Griffith Data..."
+msgstr "Griffith adat importálása..."
+
+#: mainwindow.cpp:422
+msgid "Import a Griffith database"
+msgstr "Exportálás Griffith adatázisba..."
+
+#: mainwindow.cpp:428
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Ant mozi katalógus adat importálása..."
+
+#: mainwindow.cpp:429
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Ant mozi katalógus adat fájl importálása"
+
+#: mainwindow.cpp:435
+msgid "Import File Listing..."
+msgstr "Fájl lista importálása..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr "Fájl információ importálása egy könyvtárba"
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "Importálás XSL átalakító segítségével..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Fájl importálása az XSL átalakító segítségével..."
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Exportálás"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Gyűjtemény adatainak exportálása más formátumba"
+
+#: mainwindow.cpp:461
+msgid "Export to XML..."
+msgstr "Exportálás XML-be..."
+
+#: mainwindow.cpp:462
+msgid "Export to a Tellico XML file"
+msgstr "Exportálás Tellcio XML fájlba"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Exportálás Zip-be..."
+
+#: mainwindow.cpp:469
+msgid "Export to a Tellico Zip file"
+msgstr "Exportálás Tellcio Zip fájlba"
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "Exportálás HTML-be..."
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Exportálás HTML fájlba..."
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "&Exportálás CSV-be..."
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Exportálás vesszővel határolt fájlba..."
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "Exportálás PilotDB fájlba..."
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Exportálás PilotDB adatázisba..."
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Exportálás Alexandriába..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Exportálás egy Alexandria könyvtárba..."
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Exportálás Bibtex-be..."
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Exportálás Bibtex fájlba..."
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Exportálás Bibtexml fájlba..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Exportálás Bibtexml fájlba..."
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "Exportálás ONIX-ba..."
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Exportálás ONIX fájlba..."
+
+#: mainwindow.cpp:524
+msgid "Export to GCfilms..."
+msgstr "Exportálás GCFilmbe..."
+
+#: mainwindow.cpp:525
+msgid "Export to a GCfilms data file"
+msgstr "Exportálás GCFilm adatfájlba"
+
+#: mainwindow.cpp:531
+msgid "Export to GCstar..."
+msgstr "Exportálás GCstarba.."
+
+#: mainwindow.cpp:532
+msgid "Export to a GCstar data file"
+msgstr "Exportálás GCstar adatfájlba"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "Exportálás XSL átalakító segítségével..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Fájl exportálása az XSL átalakító segítségével..."
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Kivágja a kiválasztott szöveget és átmásolja a vágólapra"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Átmásolja a kijelölt szöveget a vágólapra"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "A vágólap tartalmának beillesztése ide"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "A gyüjteményben lévő összes mező kiválasztása"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr ""
+"A gyüjteményben lévő összes mező kiválasztásának megszüntetése"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Internet keresés..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Keresés az interneten..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "&Finomított szűrés..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Gyűjtemény szűrése"
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&Új bejegyzés..."
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Új bejegyzés létrehozása"
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "B&ejegyzés szerkesztése..."
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Kiválasztott bejegyzés szerkesztése"
+
+#: controller.cpp:621 mainwindow.cpp:577
+msgid "D&uplicate Entry"
+msgstr "&Bejegyzés megduplázása"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Kiválasztott bejegyzés másolása"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "B&ejegyzés törlése"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Kiválasztott bejegyzés törlése"
+
+#: mainwindow.cpp:585
+msgid "&Merge Entries"
+msgstr "Bejegyzések &összefűzése"
+
+#: mainwindow.cpp:588
+msgid "Merge the selected entries"
+msgstr "Kiválasztott bejegyzések összefűzése"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "&Riport létrehozása..."
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Gyűjtemény riportok létrehozása"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "Kölcsönadás..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Kiválasztott elem kölcsönadása"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "Visszavétel"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Kiválasztott elemek visszavétele"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "&Gyűjtemény átnevezése..."
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Gyűjtemény átnevezése"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "Gyűjtemény &mezői..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Gyűjtemény mezőinek módosítása"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "&Bibliográfiába konvertálás"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Könyv gyűjtemény bibliográfiába konvertálása"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "&Karakterlánc makrók..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Bibtex karakterlánc makrók szerkesztése"
+
+#: mainwindow.cpp:626
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Bibtex másolása a vágólapra"
+
+#: mainwindow.cpp:627
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Bibtex idézet másolása a vágólapra"
+
+#: mainwindow.cpp:632
+msgid "Cite Entry in &LyX"
+msgstr "B&ejegyzés idézése LyX-ben"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Kiválasztott bejegyzés idézése LyX-ben"
+
+#: mainwindow.cpp:638
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "B&ejegyzés idézése OpenOffice.org-ban"
+
+#: mainwindow.cpp:639
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Kiválasztott bejegyzés idézése OpenOffice.org-ban"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, no-c-format
+msgid "&Update Entry"
+msgstr "B&ejegyzés frissítése"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr "Források"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr "Bejegyzés frissítése az összes elérhető forrásból"
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "&Csoportnézet mutatása"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Csoport nézet be/kikapcsolása"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Csoportnézet elrejtése"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "B&ejegyzés szerkesztő mutatása"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Szerkesztő be/kikapcsolása"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "B&ejegyzés szerkesztő elrejtése"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Bejegyzés &nézet mutatása"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Bejegyzés nézet be/kikapcsolása"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "Bejegyzés nézet elrejtése"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Csoportosítás megváltoztatása"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "&Csoport kiválasztása"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "A gyűjtemények csoportosításának megváltoztatása"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Szűrő"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Szűrő törlése"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Szűrés innen..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Csoportosítások"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt>A kiválasztott mező alapján a <i>Csoport nézet</i> csoportokba "
+"rendezi a bejegyzéseket.</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt>Az <i>Oszlop nézet</i> megmutatja az egyes bejegyzések többértékű "
+"mezőit.</qt>"
+
+#: mainwindow.cpp:831
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Üdvözöljük a Tellico gyűjtemény kezelőben"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+"<h3>A Tellico segítségével kezelheti a könyv, videó, zene és egyéb "
+"gyűjteményét.</h3><h3>A gyűjteményhez új bejegyzést adhat <a "
+"href=\"tc:///coll_new_entry\">manuálisan</a>, vagy <a "
+"href=\"tc:///edit_search_internet\">letöltheti az adatokat</a> "
+"különböző internetes forrásokból.</h3>"
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Új dokumentum létrehozása..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Fájl megnyitása..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Fájl megnyitása"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Fájl mentése..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+"<qt><p>Sok képet tartalmazó fájl mentése esetén a Tellico jelentősen "
+"lelassul. A teljesítmény növelése érdekében akarja a képeket "
+"különállón a Tellico adat könyvtárba elmenteni?</p><p>Választását "
+"bármikor megváltoztathatja a beállítások között.</p></qt>"
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr "Képek mentése különállóan"
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr "Képek mentése a fájlba"
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Fájl mentése új néven..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Nyomtatás..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"A gyűjtemény jelenleg a bejegyzések egy részét mutatja a szűrésnek "
+"megfelelően. Csak a látható bejegyzéseket nyomtatjuk ki. Folytatja?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Dokumentum feldolgozása..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Kilépés..."
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Összes bejegyzés: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 szűrt; %2 kiválasztott)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 szűrt)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 kiválasztott)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "%1 nyomtatása"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "%1. oldal"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Kérem, ellenőrizze a rendszer beállításait."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Adat importálása..."
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Fájl importálása..."
+
+#: mainwindow.cpp:1864
+msgid "Import Directory"
+msgstr "Könyvtár importálása"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Adat exportálása..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Exportálás mint"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Karakterlánc makrók"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Makró"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Karakterlánc"
+
+#: mainwindow.cpp:1999
+msgid "Creating citations..."
+msgstr "Idézet létrehozása..."
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Szűrők"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt>A <i>Szűrő nézet</i> az adott szűrési feltételnek megfelelő "
+"bejegyzéseket mutatja.</qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Kölcsön adva"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt>A <i>Kölcsönadás nézet</i> azokat a személyeket mutatja, akik a "
+"gyűjteményből kölcsönöztek.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr "Bejegyzés frissítése innen: %1"
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+"Tellico csak egy ilyen típusú fájlt tud egy időben importálni., Csak a "
+"%1 importálódik."
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Nem sikerült a(z) %1 fájl betöltése."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr "Egy \"%1\" nevű fájl már létezik. Felül akarja írni?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Fájl felülírása?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Felülírás"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Szűrő (mennyiség szerint rendezve)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Tényleg törölni akarja a bejegyzést?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Bejegyzés törlése"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Tényleg törölni akarja a bejegyzéseket?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Több bejegyzés törlése"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "Bejegyzések szerkesztése..."
+
+#: controller.cpp:627
+msgid "D&uplicate Entries"
+msgstr "&Bejegyzések megduplázása"
+
+#: controller.cpp:628
+msgid "&Update Entries"
+msgstr "&Bejegyzések frissítése"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "Bejegyzések &törlése"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+"Az alábbi elem már kölcsön van adva, a Tellico jelenleg nem támogatja "
+"az elem kölcsönadását több időpontra. Ezeket eltávolítja a "
+"kölcsönadott elemek listájáról."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Alapértelmezett naptár"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"Jelenleg a Tellico csak a helyi napárt támogatja. Az aktív naptár "
+"távoli helyen van, így a kölcsönök nem adhatók hozzá."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Aktív naptár"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 a \"%2\" miatt."
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(üres)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - gyűjtemény kezelő program KDE-hez"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Ne nyissa meg a legutóbb használt fájlt"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "<filename> Bibtex fájlként importálása"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "<filename> MODS fájlként importálása"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "<filename> RIS fájlként importálása"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Megnyitandó fájl"
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr "Adatforrás szkriptek"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Ikonok"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "btparse könyvtár szerzője"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr "Kód példa és általános segítség"
+
+#: main.cpp:50
+msgid "Author of libcsv library"
+msgstr "libcsv könyvtár szerzője"
+
+#: main.cpp:52
+msgid "Author of rtf2html library"
+msgstr "rtf2html könyvtár szerzője"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Gyűjtemény mezői"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Jelenlegi mezők"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "&Új"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Új mező hozzáadása a gyűjteményhez"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "&Törlés"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Mező eltávolítása a gyűjteményből"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Mező felfele mozgatása a listán. A lista sorrendje a bejegyzés "
+"szerkesztő megjelenésekor fontos."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Mező lefele mozgatása a listán. A lista sorrendje a bejegyzés "
+"szerkesztő megjelenésekor fontos."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Mező tulajdonságok"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "&Cím:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "Mező címe"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "Tí&pus:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "A mező típusa meghatározza, milyen érték alkalmazható."
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "<i>Egyszerű szöveg</i> használható a legtöbb mezőnél."
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "A <i>Bekezdés</i> a nagy szöveg blokkokhoz alkalmazható."
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "A <i>Választás</i> csak adott értékekre korlátozza a mezőt."
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "A <i>Kijelölés</i> egy egyszerű igen / nem érték."
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr ""
+"A <i>Szám</i> azt jelenti, hogy a mező csak szám értéket tartalmazhat."
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr "Az <i>URL</i> olyan mező, mely URL-re, vagy fájlra hivatkozik."
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr "A <i>Táblázat</i> egy vag ytöbb oszlopot tartalmazhat."
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "A <i>Kép</i> mező képeket tárol."
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr "A <i>Dátum</i> év, hónap, nap adatot tárol."
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+"Az <i>Értékelés</i> mező csillagok segítségével mutatja az "
+"értékelés számát."
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"A <i>Függés</i> mező más mezők értékeitől függ, valamint a mező "
+"leírásnak megflelően formázott."
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"A <i>Csak olvasható</i> egy belső érték, importálásnál, "
+"exportálásnál hasznos."
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "Kategória:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr ""
+"A mező kategória határozza meg azt, hol van a mező a szerkesztőben."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "Leírás:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"A leírás egy hasznos emlékeztető arról, hogy a mező milyen "
+"információt tartalmaz. A <i>Függő</i> mezők esetében a leírás egy "
+"formázott karakterlánc, például \"%{year} %{title}\", ahol a "
+"karakterláncban az adott mezők behelyettesítésre kerülnek."
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr "&Alapértelmezett érték:"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr ""
+"<qt>Egy alapértelmezett értéket meg kell adni az új bejegyzéshez.</qt>"
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr "Engedélyezett értékek:"
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>A <i>Választás</i> típusú mezők esetében csak az adott értékek "
+"léteznek. Ezek a combo boxban találhatók.</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "Részletes tulajdonságok:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "&Beállítás..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"Kíbővített mező tulajdonságokat használjuk például a bibtex mező "
+"specifikálásához."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Formázási beállítások"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Nincs formázás"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+"Ez a beállítás megakadályozza, hogy a mező automatikusan formázott, "
+"vagy nagybetűsített legyen."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Csak az automatikus nagybetűsítés engedélyezett"
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+"Ez a beállítás engedélyezi a mező nagybetűsítését, de nem a "
+"speciális formázását."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Formázás címként"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Ez a beállítás a mezőt címként nagybetűsíti és formázza, de csak "
+"akkor, ha a beállítás általánosan érvényes."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Formázás névként"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Ez a beállítás a mezőt névként nagybetűsíti és formázza, de csak "
+"akkor, ha a beállítás általánosan érvényes."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Mező beállítások"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Automatikus kiegészítés engedélyezése"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Ha kijelölt, a szöveg szerkesztő mezőben a KDE automatikus "
+"kiegészítés engedélyezett lesz."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Többszörös érték engedélyezése"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Ha kijelölt, a Tellico a mezőben megadott értékeket pontosvesszővel "
+"elválasztott többszörös értéké alakítja."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Csoportosítás engedélyezése"
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Ha kijelöli, a mezőt használja a csoport nézetben a bejegyzések "
+"csoportosításához."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr ""
+"A kiválaszott mező tulajdonságait visszaállítja az alapértelmezett "
+"értékekre."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Mezők módosítása"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>A gyűjteményben létező <i>%1</i> mezőből az adatok törlése "
+"adatok sérüléséhez vezethet. Meg akarja tartani a módosított "
+"értékeket, vagy visszaállítja a jelenlegire?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Megváltozott értékek megtartása"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Mező tulajdonságok visszaállítása"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Tényleg vissza akarja állítani a <em>%1</em> mező tulajdonságait "
+"az alapértelmezettre?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Visszaállítás"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Kibővített mező tulajdonságok"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr "A mező ezzel a névvel már létezik. Adjon meg más nevet."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr "<qt>A kategória nem lehet üres. Adja meg a kategóriát.</qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>A mező nem lehet azonso kategóriában, mint a <em>Bekezdés</em>, "
+"<em>Táblázat</em> vagy a <em>Kép</em>. Adjon meg másik kategóriát.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"A mező címe nem egyezhet meg egy létező kategóriával. Adjon meg egy "
+"másik címet."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+"Az értékelés mező tartománya 1 és 10 közé essen, valamint az alsó "
+"határ alacsonyabb legyen, mint a felső. Adjon meg más alsó, felső "
+"értéket."
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "A táblázatok maximum 10 oszlopot tartalmazhatnak."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr "A jelenlegi fájl megváltozott. Menti a módosításokat?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Nem mentett változások"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Válassza ki a kölcsönvevőt"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Tellico beállítása"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Általános beállítások"
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr "&Fájl újbóli megnyitása a program indításakor"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Ha kijelöli, akkor az utoljára megnyitott fájl a program indításakor "
+"automatikusan betöltődik."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "&Mutassa a \"Nap tippjét\" induláskor"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr "Ha kijelöli, a program indításakor a \"Nap tippjét\" elolvashatja."
+
+#: configdialog.cpp:213
+msgid "Image Storage Options"
+msgstr "Kép tárolási beállítások"
+
+#: configdialog.cpp:214
+msgid "Store images in data file"
+msgstr "Képek tárolása az adatfájlban"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr "Képek tárolása a közös alkalmazás könyvtárban"
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr "Képek tárolása az adatfájl könyvtárában"
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+"A képeket elmentheti magába az adatfájlba - ez lelassíthatja a Tellico-t "
+"-, tárolhatja a Tellico alkalmazás könyvtárban, vagy tárolhatja abban a "
+"könyvtárban, ahol az adatfájl is van."
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Formázási beállítások"
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr "&Címek és szerzők automatikusan nagybetűvel"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Ha kijelöli, akkor a címek és a szerzők automatikusan nagybetűvel "
+"íródnak."
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr "Cí&mek és szerzők automatikus formázása"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr ""
+"Ha kijelöli, akkor a Tellico automatikusan formázza a címeket és a "
+"szerzőket."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr "&Nincs nagybetűsítés"
+
+#: configdialog.cpp:243
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>A vezetékneveknél használható előtagok listája. Többszörös "
+"értéket pontosvesszővel kell elválasztani.</qt>"
+
+#: configdialog.cpp:249
+msgid "Artic&les:"
+msgstr "&Bekezdések:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>Szavak listája, melyek acím első szavai. Többszörös értékeket "
+"pontos vesszővel kell elválasztani.</qt>"
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr "&Személyes utótagok:"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>A személyi neveknél használható adatok listája. Többszörös "
+"értéket pontosvesszővel kell elválasztani.</qt>"
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr "&Vezetéknév előtagjai:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>A vezetékneveknél használható előtagok listája. Többszörös "
+"értéket pontosvesszővel kell elválasztani.</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Nyomtatás"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Nyomtatási beállítások"
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr "Címe&k és nevek formázása"
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr "Me&ző fejlécek nyomtatása"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Csoportosítási beállítások"
+
+#: configdialog.cpp:313
+msgid "&Group the entries"
+msgstr "&Bejegyzések csoportosítása"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Kép beállítások"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr "Maximális &kép szélesség:"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"A nyomtatásnál a maximális kép szélesség. Az oldal arány rögzített."
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr "Maximális ké&p magasság:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"A nyomtatásnál a maximális kép magasság. Az oldal arány rögzített."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Sablonok"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Sablon beállítások"
+
+#: configdialog.cpp:369
+msgid "Template:"
+msgstr "Sablonok:"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+"Válassza ki a jelenlegi gyűjteményhez alkalmazadnó sablont. Nem "
+"mindegyik sablon használ betűkészlet és szín beállításokat."
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr "Előnézet..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr "Sablon előnézetének mutatása"
+
+#: configdialog.cpp:398
+msgid "Font Options"
+msgstr "Betűkészlet beállítások"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr "Betűkészlet:"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr ""
+"Ez a betűkészlet a bejegyzés nézetben használt sablonhoz lett rendelve."
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr "Méret:"
+
+#: configdialog.cpp:425
+msgid "Color Options"
+msgstr "Szín beállítások"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr "Háttér szín:"
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr "Ez a szín a bejegyzés nézetben használt sablonhoz lett rendelve."
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr "Szöveg színe:"
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr "Kiemelés színe:"
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr "Kiemelt szöveg színe:"
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr "Sablonok kezelése"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr "Telepítés..."
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr "Kattintson az új sablon közvetlen telepítéshez."
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr "Letöltés..."
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr "Kattintson további sablonok internetről történő letöltéséhez."
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr "Törlés..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr ""
+"Kattintson a telepíatett sablonok kijelöléshez és eltávolításához."
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Adatforrások"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Adatforrás beállítások"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Forrás"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr "Mozgatás &felfele"
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+"Az adatforrások sorrendje meghatározza, hogy a Tellico melyiket használja "
+"a bejegyzések automatikus frissítéséhez."
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr "&Mozgatás lefele"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "Új"
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr "Kattintson új adatforrás megadásához."
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Módosítás..."
+
+#: configdialog.cpp:533
+msgid "Click to modify the selected data source."
+msgstr "Kattintson a kijelölt adatforrrás módosításához."
+
+#: configdialog.cpp:536
+msgid "Click to delete the selected data source."
+msgstr "Kattintson a kijelölt adatforrás törléséhez."
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr ""
+"Kattintson továbbo adatforrások internetről történő letöltéséhez."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr "*.tar.gz *.tgz|Sablon csomagok (*.tar.gz)"
+
+#: configdialog.cpp:1049
+msgid "Delete Template"
+msgstr "Sablon törlése"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr "Adatbázis kiválasztása törléshez:"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "Kölcsönvevő"
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Visszavétel"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Kölcsön módosítása"
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "Kölcsönvevő (mennyiség szerint rendezve)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "Gyűjteményem"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Könyv gyűjtemény"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Képregény gyűjtemény"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Film gyűjtemény"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Zene gyűjtemény"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Érme gyűjtemény"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Bélyeg gyűjtemény"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Bor gyűjtemény"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Kártya gyűjtemény"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Játék gyűjtemény"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr "Fájl gyűjtemény"
+
+#: collectionfactory.cpp:135
+msgid "Board Game Collection"
+msgstr "Társasjáték gyűjtemény"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Egyedi gyűjtemény"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+"<qt>A <i>Bejegyzés nézet</i> a bejegyzések tartalmának formázott "
+"nézetét mutatja.</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt>Az <i>Ikon nézet</i> a gyűjtemény vagy csoport egyes elemeit "
+"ikonként mutatja.</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Exportálási beállítások"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Formázás"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Összes mező formázása"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Ha kijelöli, a formázási típusnak megfelelően automatikusan formázza a "
+"mező értékeit."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Csak a kiválasztott bejegyzések exportálása"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr "Ha kijelöli, csak a kiválasztott bejegyzések exportálódnak."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Kódolás"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Kódolás Unicode (UTF-8)-ban"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Exportált fájl kódolása Unicode (UTF-8)-ban."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Kódolás helyi felhasználóként (%1)"
+
+#: exportdialog.cpp:72
+msgid "Encode the exported file in the local encoding."
+msgstr "Exportált fájl kódolása helyi formátumban."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "&Keresés itt:"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "&Állj"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Internet keresés"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Keresés itt:"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr "Keresés indítása"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+"Adja meg a keresendő értéket. Az ISBN keresésnek a teljes ISBN-t "
+"tartalmaznia kell."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Keresés típúsának kiválasztása"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Kattintson a keresés elindításához, leállításához"
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr "&Többszörös ISBN/UPC keresés"
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr "Jelölje ki a többszörös ISBN vagy UPC értékek kereséséhez."
+
+#: fetchdialog.cpp:138
+msgid "Edit List..."
+msgstr "Lista szerkesztése..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+"Kattintson a szöveg szerkesztési ablak kinyitásához, ahol a "
+"többszörös ISBN értékeket megadhatja, vagy megváltoztathatja."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "Forrás keresése:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Adatbázis kiválasztása kereséshez"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"A találati eredmények hozzáadódnak a listához. Egyet kiválasztva a "
+"teljes bejegyzés bekerül és az alábbi nézetben látható."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"A fenti listából kiválasztott bejegyzés itt látható mielőtt a "
+"jelenlegi gyűjteményhez hozzáadná."
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "Bejegyzés hozzáadása"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Kiválasztott bejegyzés hozzáadása a jelenlegi gyűjteményhez"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr "Több eredmény kérése"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr "Több eredmény lekérése az aktuális adatforrásból"
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Az összes keresési mező és az eredmények törlése"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "A keresés leállítása..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Keresés..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "A keresés nem talált semmit."
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr "A keresés %n elemet adott vissza."
+
+#: fetchdialog.cpp:412
+msgid "No results were found for the following ISBN values:"
+msgstr "A következő ISBN számban nem található az érték:"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "%1 feldolgozása..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr ""
+"A jelenlegi gyűjteméyn típusához nincs elérhető internet forrás."
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr "ISBN/UPC értékek szerkesztése"
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Soronként egy ISBN vagy UPC érték megadása.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "Betöltés fájlból..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Szöveg fájlból lista betöltése.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>Az ISBN keresés maximum 100 ISBN értéket tartalmazhat. A listából "
+"csak az első 100 értéket használhatja.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Bejegyzés szerkesztése"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Új bejegyzés"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "B&ejegyzés mentése"
+
+#: entryeditdialog.cpp:77
+msgid "Go to the previous entry in the collection"
+msgstr "A gyüjteményben lévő előző bejegyzéshez ugrás"
+
+#: entryeditdialog.cpp:82
+msgid "Go to the next entry in the collection"
+msgstr "A gyüjteményben lévő következő bejegyzéshez ugrás"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Tényleg módosítani akarja ezeket a bejegyzéseket?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Többszörös bejegyzés módosítása"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr "A következő mezőknek értéket kell adnia. Folytatja?"
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Bejegyzések szerkesztése"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "B&ejegyzések mentése"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"A jelenlegi könyv megváltozott.\n"
+"Menti a módosításokat?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Bejegyzés mentése"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Gyüjtemény riport"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "Riport sablon:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "Létrehozás"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr ""
+"Válassza ki a riport sablont, majd kattinson a <em>Létrehozásra</em>."
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+"Nagy méretű gyűjtemény esetén néhány riport létrehozása hosszabb "
+"időt is igénybe vehet."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Tényleg törölni akarja ezt a szűrőt?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Szűrő törlése?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Új gyűjteménynév:"
+
+#: tellico_kernel.cpp:377
+msgid "Entry 1"
+msgstr "Bejegyzés 1"
+
+#: tellico_kernel.cpp:378
+msgid "Entry 2"
+msgstr "Bejegyzés 2"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr "Bejegyzések összefűzésekor érték konfliktus lépett fel: %1"
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr "Válassza ki a megtartandó értéket."
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+msgid "Merge Entries"
+msgstr "Bejegyzések összefűzése"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr "Érték kiválasztása %1 -ből"
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico nem találja az alapértelmezett bejegyzés stíluslapot."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Új"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Gyűjtemény"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Gyűjtemény eszköztár"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Marcel Hilzinger, Csaba Zakarias"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "hili@suselinux.hu, csaba.zakarias@gmail.com"
+
+#: entrymerger.cpp:35
+msgid "Merging entries..."
+msgstr "Bejegyzések összefűzése..."
+
+#: entrymerger.cpp:49
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Összes összefűzött/átfutott bejegyzés: %1/%2"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>...ha egy könyv több szerzővel rendelkezik, pontosvesszővel válassza "
+"el \n"
+"a neveket, a Tellico így felosztja \n"
+"és több értékként kezeli.</p>\n"
+"<p>A többi mezők esetén, melyeknél több értéket adhat meg \n"
+"hasonló módon pontosvesszővel választhatja el ez egyes értékeket.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>... ha meg akarja változtani, hogy mely mezők jelenjenek meg a lista "
+"nézetben\n"
+"az oszlop fejlécére jobb gombbal kattinson.</p>\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>... mezőket hozzáadhat, szerkeszthet, vagy megváltoztathat a "
+"gyűjteményben\n"
+"a mező szerkesztővel. A mező lista mellett lévő nyíl gomb "
+"segítségével megváltoztathatja \n"
+"a mező listán elfoglalt pozícióját, mely a bejegyzés szerkesztőben a "
+"helyét határozza meg.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>...ha a Kijelölés mező alapján akar szűrni, akkor \"valós\" "
+"értéket kell használnia. Ha például inkább csak a sci-fi könyvet "
+"akarja kiszűrni, melyet még nem olvasott, jelölje be a <em>Minden "
+"alábbival egyező</em> gombot, az első szabálynál adja meg \"Sci-fi\" "
+"(idézőjelek nélkül), a második szabálynál adja meg \"olvasva\" "
+"érték nem \"igaz\" (idézőjelek nélkül).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>... ha a gyors szűrésben nem szó karaktert használ, a szöveget \n"
+"mint általános kifejezést értelmezi.</p>\n"
+"<p>Ha például csak a Weber, vagy Bujold könyveit akarja megjeleníteni, \n"
+"a szűrésnél adja meg a \"weber|bujold\" szavakat (nincs vessző)</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>... egy időben több bejegyzést is szerkeszthet a Shift vagy Ctrl "
+"gombot\n"
+"lenyomása mellett kiláasztja az egyes bejegyzéseket.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>... átkonvertálhatja a létező könyv gyűjteményét "
+"bibliográfiává,\n"
+"mely ezután exportálható bibtex, vagy Bibtexml formátumba.</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>... a bibliográfiához hozzáadhat, szerkeszthet és törölhet karakter "
+"makrókat.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>... ha több mező névként van formázva, akkor egy további\n"
+"\"Emberek\" csoport is létrejön a gyűjteményben, mely segítségével "
+"például a szerzők és szerkesztők\n"
+"egyszerre rendezhetők, vagy nyomtathatók ki.</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>...módosíthatja a nyomtatási kimenet viselkedését a "
+"<tt>tellico-printing.xsl</tt> fájl módosításával. A fájl HTML-t és "
+"CSS-t hoz létre a stíluslap beállításokkal, mint betűkészlet, margók "
+"stb.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>... importálhat bármilyen általános XSL stíluslap segítségével,\n"
+"melynek kimenete érvényes Tellico XML fájl.</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+"<p>... egy bejegyzésre kétszer kattintva megnyílik a Bejegyzés "
+"szerkesztő.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>... bármelyik Bekezdés mező formázására HTML tagok használhatók, "
+"mint például\n"
+"<b>kövér</b> vagy <i>dőlt</i>.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>...a Részletes nézetben nyomjon meg egy betűt a billentyűzeten az "
+"ezzel a betűvel kezdődő következő bejegyzésre ugráshoz.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+"<p>...használhatja a Függő mezőket több független mező "
+"összekapcsolására egy mezővé. Csak jelölje ki a Független típust és "
+"hsaználja a következőt: \"Value: %{fielda}%{fieldb}\" ahol %{...} a "
+"megfelelő mezőnevet tartalmazza. Ez jól használható több érték egy "
+"mezőben kezelésekor.</p>\n"
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Album XSL sablon"
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr "Ez a sablon csak zene gyűjteményhez használható."
+
+#: xslt.cpp:5
+msgid "Total:"
+msgstr "Teljes:"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr "Fancy XSL sablon"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "Alapértelmezett XSL sablon"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Tömörített XSL sablon"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Video XSL sablon"
+
+#: xslt.cpp:14 xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr "Ez a sablon csak film gyűjteményhez használható."
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Csoport összegző XSL sablon"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Csoport összegző"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Mezők összesen:"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Bejegyzések összesen:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+msgid "Generated by Tellico"
+msgstr "Létrehozta Tellico-val"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Különállő értékek: "
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Kép lista XSL sablon"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Kölcsön nézet XSL sablon"
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Kölcsönadás dátuma"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Megjegyzés"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Lejárat dátuma"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Csoport nézet XSL sablon"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Cím listázás (vízszintes) XSL sablon"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Cím listázás (fügőleges) XSL sablon"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Oszlop nézet XSL sablon"
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "Három oszlopos XSL sablon"
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr "Keresés"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr "A Brit Könyvtár"
+
+#: z3950.cpp:6
+msgid "Sudoc (France)"
+msgstr "Sudoc (Franciaország)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr "BIBSYS (Norvégia)"
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr "Olasz Nemzeti Könyvtár"
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr "Portugál Nemzeti Könyvtár"
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr "Lengyel Nemzeti Könyvtár"
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr "Kanadai Nemzeti Könyvtár"
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr "Izraeli Union List"
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr "Ausztrál Nemzeti Könyvtár"
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr "Litván Nemzeti Könyvtár"
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr "Copac (Egyesült Királyság és Írország)"
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr "BoardGameGeek"
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr "Dark Horse Comics"
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr "Allocine.fr"
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr "Spanyol Kultúrális Minisztérium"
diff --git a/po/it.po b/po/it.po
new file mode 100644
index 0000000..98d695d
--- /dev/null
+++ b/po/it.po
@@ -0,0 +1,6027 @@
+# translation of it.po to Italiano
+# Copyright (C) 2001-2002, Robby Stephenson
+# This file is distributed under the same license as the Tellico package.
+# First translation by FaUsT <faust@inventati.org>, 2002, 2003, 2004.
+# Lorenzo Novaro <novalore@inwind.it>, 2004, 2005.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: it\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2005-10-12 18:20+0200\n"
+"Last-Translator: Lorenzo Novaro <novalore@inwind.it>\n"
+"Language-Team: Italiano <kde-i18n-it@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Report-Msgid-Bugs-To: \n"
+"X-Generator: KBabel 1.10.2\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "<qt>Tellico non riesce a scrivere sulla server pipe in <b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr ""
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr ""
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+
+#: cite/openoffice.cpp:191
+#, fuzzy
+msgid "Pipe"
+msgstr "Gente"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:181
+#, fuzzy
+msgid "Rename Column"
+msgstr "Rinomina Collezione"
+
+#: gui/tablefieldwidget.cpp:181
+#, fuzzy
+msgid "New column name:"
+msgstr "Nuovo nome della collezione:"
+
+#: gui/tablefieldwidget.cpp:206
+#, fuzzy, c-format
+msgid "Column %1"
+msgstr "Colonna:"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+#, fuzzy
+msgid "Rename Column..."
+msgstr "&Rinomina Collezione ..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:276
+#, fuzzy
+msgid "Remove Row"
+msgstr "Rimuo&vi"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:295
+#, fuzzy
+msgid "Clear Table"
+msgstr "Cancella filtro"
+
+#: gui/previewdialog.cpp:27
+#, fuzzy
+msgid "Template Preview"
+msgstr "Template"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Set"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr ""
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Più"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Meno"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Cancella"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Seleziona immagine ..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr ""
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr ""
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, fuzzy, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Salva %1"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Collega Collezione"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Incorpora Collezione"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Rimpiazza Collezione"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+#, fuzzy
+msgid "Modify Entries"
+msgstr "Modifica elementi"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "Aggiungi %1 campo"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Modifica %1 campo"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Cancella %1 campo"
+
+#: commands/addentries.cpp:50
+#, fuzzy
+msgid "Add Entries"
+msgstr "Modifica elementi"
+
+#: commands/addentries.cpp:51
+#, fuzzy, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Salva %1"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Rinomina Collezione"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Modifica prestito"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Aggiungi filtro"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Modifica filtro"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Cancella campo"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Verifica oggetti"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Verifica %1"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Cancella elementi"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Cancella %1"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Riordina campi"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Registra elementi"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Registra %1"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Generale"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Condizioni"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Personale"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "I miei francobolli"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Titolo"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Descrizione"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Denominazione"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "Paese"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Anno di emissione"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "A colori"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Scott#"
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr ""
+"Mint,Near Mint,Molto soddisfacente,Soddisfacente,Molto "
+"buono,Buono,Insomma,Cattivo"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Grado"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Cancellato"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Incollato (Hinged)"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Centratura"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Adesivo"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Data di acquisto"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Prezzo"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Provenienza"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Regalo"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Immagine"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Commenti"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Pubblicazione"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Classificazione"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "I miei fumetti"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Sottotitolo"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Sceneggiatore"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Collana"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Serie"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Casa editrice"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Edizione"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Anno di pubblicazione"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Pagine"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Lingua"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Genere"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Parole chiave"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr ""
+"Mint,Near Mint,Molto soddisfacente,Soddisfacente,Molto "
+"buono,Buono,Insomma,Cattivo"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Autografato"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Prestato"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Copertina"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Le mie monete"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Tipo"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Anno"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Mint"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Set di monete"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+"Fior di conio-65,Fior di conio-60,Fior di "
+"conio-65,Splendida-60,Splendida-55,Splendida-50,Bellissima-40,Bellissima-30,M"
+"olto bella-20,Molto bella-12,Bella-8,Bella-4,Fair"
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr "PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "SeErvizi di valutazione"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Osserva"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Seconda faccia"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "I miei libri"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Autore"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Rigida"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Morbida"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Economica"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "E-Book"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Rivista"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Giornale"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Rilegatura"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Copyright (anno)"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "num. ISBN"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Numero Standard Internazionale per i libri"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "num. LCCN"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Numero di Controllo della Biblioteca del Congresso"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr ""
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Numero"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Nuovo"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Usato"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Letto"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Voto"
+
+#: collections/filecatalog.cpp:25
+#, fuzzy
+msgid "My Files"
+msgstr "I miei vini"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "Nome"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Volume"
+
+#: collections/filecatalog.cpp:55
+#, fuzzy
+msgid "Folder"
+msgstr "Filtro"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr ""
+
+#: collections/filecatalog.cpp:65
+#, fuzzy
+msgid "Size"
+msgstr "Autografato"
+
+#: collections/filecatalog.cpp:69
+#, fuzzy
+msgid "Permissions"
+msgstr "Persona"
+
+#: collections/filecatalog.cpp:74
+#, fuzzy
+msgid "Owner"
+msgstr "Altro"
+
+#: collections/filecatalog.cpp:79
+#, fuzzy
+msgid "Group"
+msgstr "Raggruppa per:"
+
+#: collections/filecatalog.cpp:85
+#, fuzzy
+msgid "Created"
+msgstr "Finito"
+
+#: collections/filecatalog.cpp:89
+#, fuzzy
+msgid "Modified"
+msgstr "Modifica campi"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Proprietà"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Valore"
+
+#: collections/filecatalog.cpp:99
+#, fuzzy
+msgid "Icon"
+msgstr "Icone"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "I miei vini"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Produttore"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Denominazione "
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Varietà"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Annata"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Vino rosso"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Vino bianco"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Spumante"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Quantità"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Da bere"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Immagine dell'etichetta"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Altre persone"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Features"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "I miei video"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "Videocassetta"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr ""
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+#, fuzzy
+msgid "HD DVD"
+msgstr "DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Supporto"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Anno di produzione"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr ""
+"Per tutti -G (USA),Da vedere con un adulto -PG (USA),Vietato ai minori di 13 "
+"anni -PG-13 (USA),Vietato ai minori di 17 anni -R (USA)"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Certificazione"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Regione 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Regione 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Regione 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Regione 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Regione 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Regione 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Regione 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Regione 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Regione"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Nazionalità"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Formato"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Cast"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr ""
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+#, fuzzy
+msgid "Role"
+msgstr "Volume"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr "Una tabella comprendente gli attori del cast con i ruoli interpretati"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Regista"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Autore della colonna sonora"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Studio"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Lingue del sonoro"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Lingue dei sottotitoli"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Tracce audio"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Durata"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "La durata del video in minuti"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Tipo di visualizzazione"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Grande schermo"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Bianco e nero"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Modalità a colori"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Director's Cut"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Trama-Riassunto"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Valutazione personale"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Copertina"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "I miei giochi"
+
+#: collections/gamecollection.cpp:44
+#, fuzzy
+msgid "Xbox 360"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+#, fuzzy
+msgid "PlayStation3"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+#, fuzzy
+msgid "Nintendo Wii"
+msgstr "Regione"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr ""
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Piattaforma"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Anno di pubblicazione"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Casa editrice"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Sviluppatore"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+"Non classificato, Pubblico Adulto, Teenager, Per tutti, Per bambini, "
+"Classificazione in corso"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "ESRB Rating"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Finito"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Le mie carte"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Giocatore"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Squadra"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Marca"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Numero della carta"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Tipo della carta"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Immagine frontale"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Immagine posteriore"
+
+#: collections/boardgamecollection.cpp:26
+#, fuzzy
+msgid "My Board Games"
+msgstr "I miei giochi"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:72
+#, fuzzy
+msgid "Number of Players"
+msgstr "Elementi totali: %1"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Bibliografia"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Tipo di elemento"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+"Questi tipi di elementi sono specifici di Bibtex. Vedi la documentazione di "
+"Bibtex."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Bibtex Key"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Titolo del libro"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Editore"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organizzazione"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Indirizzo"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Mese"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Numero"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Pubblicato come"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Capitolo"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Riferimento incrociato"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Sunto"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Note"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "La mia musica"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Album"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "Compact Disc"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Musicassetta"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Vinile"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Artista"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Etichetta"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Tracce"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr ""
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr "uno,un,una,un',in,di,del,della,il,la,lo,a"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "il,lo,la,l',i,gli,le"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr.,jr,iii,iv"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,De,di,Di,van,der,van der,von,mc"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 non permette ricerche per questo tipo di collezione."
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Risultati da %1: %2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "Questa fonte non ha opzioni."
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "Database Entrez"
+
+#: fetch/entrezfetcher.cpp:485
+#, fuzzy
+msgid "Institution"
+msgstr "Condizioni"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Errore nella query!"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Connection search error %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Errore nella sintassi dell'elemento"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Errore nella connessione %1: %2"
+
+#: fetch/srufetcher.cpp:72
+#, fuzzy
+msgid "SRU Server"
+msgstr "Ripristinare"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Biblioteca del Congresso (USA)"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+#, fuzzy
+msgid "Hos&t: "
+msgstr "&Host: "
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+#, fuzzy
+msgid "Enter the host name of the server."
+msgstr "Inserisci l'hostname del server z39.50."
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Porta: "
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, fuzzy, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr ""
+"Inserisci il numero della porta del server z39.50. La porta di default è %1."
+
+#: fetch/srufetcher.cpp:450
+#, fuzzy
+msgid "Path: "
+msgstr "&Porta: "
+
+#: fetch/srufetcher.cpp:455
+#, fuzzy
+msgid "Enter the path to the database used by the server."
+msgstr "Inserisci il nome del database usato dal server z39.50."
+
+#: fetch/srufetcher.cpp:460
+#, fuzzy
+msgid "Format: "
+msgstr "Formato"
+
+#: fetch/srufetcher.cpp:468
+#, fuzzy
+msgid "Enter the result format used by the server."
+msgstr "Inserisci il nome del database usato dal server z39.50."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "Immagine di copertina non caricata."
+
+#: fetch/amazonfetcher.cpp:53
+#, fuzzy
+msgid "Amazon Link"
+msgstr "Amazon (Giappone)"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (USA)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (GB)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Germania)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Giappone)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (Francia)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Canada)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Servizi Web di Amazon.com"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "&Paese: "
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "Stati Uniti"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Gran Bretagna"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Germania"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Giappone"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "Francia"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Canada"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon.com fornisce dati attraverso diversi siti nazionali. Scegli quello "
+"che vuoi usare come fonte per questi dati."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "Dimensione &Immagine: "
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Immagine piccola"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Immagine media"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Immagine grande"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Nessuna immagine"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"L'immagine di copertina può essere scaricata. Inserire troppe immagini "
+"grandi nella collezione può però peggiorare le performance."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "ID del &socio: "
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+"L'ID del socio identifica la persona che accede ai servizi di Amazon.com ed "
+"incluso in tutti i link al sito Amazon.com."
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+#, fuzzy
+msgid "z39.50 Server"
+msgstr "z39.50"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "&Database: "
+
+#: fetch/z3950fetcher.cpp:530
+#, fuzzy
+msgid "Enter the database name used by the server."
+msgstr "Inserisci il nome del database usato dal server z39.50."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "Set di c&aratteri: "
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Inserisci il set di caratteri utilizzato dal server z39.50. La scelta più "
+"probabile è MARC-8, anche se ISO-8859-1 è altrettanto comune."
+
+#: fetch/z3950fetcher.cpp:550
+#, fuzzy
+msgid "&Format: "
+msgstr "Formato"
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "&Utente: "
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Facoltativo"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Inserisci lo username per l'autenticazione nel database z39.50. Per molti "
+"server non è necessario."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "Pass&word: "
+
+#: fetch/z3950fetcher.cpp:586
+#, fuzzy
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Inserisci la password di autenticazione utilizzata dal database z39.50. Per "
+"molti server non è necessario."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Programma esterno"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "&Tipo di collezione:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+"Seleziona il tipo di collezione per i dati forniti dal programma esterno."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:365
+#, fuzzy
+msgid "Set the result type of the data returned from the external application."
+msgstr ""
+"Seleziona il tipo di collezione per i dati forniti dal programma esterno."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "&path del programma: "
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+"Inserisci il percorso del programma da avviare che possa produrre un valido "
+"file di dati per Tellico."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+"Aggiungi ogni argomento necessario. <b>%1</b> verrà sostituito dalle parole "
+"ricercate."
+
+#: fetch/execexternalfetcher.cpp:382
+#, fuzzy
+msgid "Arguments"
+msgstr "&Argomenti: "
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+#, fuzzy
+msgid "Update"
+msgstr "&Cita elemento"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Opzioni della fonte"
+
+#: fetch/configwidget.cpp:40
+#, fuzzy
+msgid "Available Fields"
+msgstr "Campi disponibili"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "Internet Movie Database"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Seleziona il risultato IMDB"
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+"<qt>La tua ricerca ha dato più di un risultato. Seleziona uno dei "
+"seguenti.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Seleziona un risultato.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Titoli alternativi"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+#, fuzzy
+msgid "IMDB Rating"
+msgstr "ESRB Rating"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Certificazioni"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"L' Internet Movie Database (IMDB) usa molti server. Scegli quello che vuoi "
+"usare."
+
+#: fetch/imdbfetcher.cpp:1132
+#, fuzzy
+msgid "&Maximum cast: "
+msgstr "Larghezza massima delle immagini:"
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+#, fuzzy
+msgid "Download cover &image"
+msgstr "Scarica l'immagine di copertina"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Persona"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Parola chiave"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Query in modalità Raw"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:264
+#, fuzzy
+msgid "Distributor"
+msgstr "Regista"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr ""
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:343
+#, fuzzy
+msgid "&Username: "
+msgstr "&Utente: "
+
+#: fetch/crossreffetcher.cpp:348
+#, fuzzy
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+"Inserisci la password di autenticazione utilizzata dal database z39.50. Per "
+"molti server non è necessario."
+
+#: fetch/crossreffetcher.cpp:354
+#, fuzzy
+msgid "&Password: "
+msgstr "Pass&word: "
+
+#: fetch/gcstarpluginfetcher.cpp:190
+#, fuzzy
+msgid "GCstar Plugin"
+msgstr "GCstar"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+#, fuzzy
+msgid "Set the collection type of the data returned from the plugin."
+msgstr ""
+"Seleziona il tipo di collezione per i dati forniti dal programma esterno."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:420
+#, fuzzy
+msgid "Author: "
+msgstr "Autore"
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr ""
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr ""
+
+#: newstuff/dialog.cpp:114
+#, fuzzy
+msgid "Version"
+msgstr "Persona"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr ""
+
+#: newstuff/dialog.cpp:117
+#, fuzzy
+msgid "Release Date"
+msgstr "Anno di pubblicazione"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+
+#: newstuff/dialog.cpp:137
+#, fuzzy
+msgid "The name and license of the selected item"
+msgstr "Registra gli elementi selezionati"
+
+#: newstuff/dialog.cpp:140
+#, fuzzy
+msgid "The author of the selected item"
+msgstr "Controlla gli elementi selezionati"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr ""
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr ""
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+
+#: newstuff/dialog.cpp:194
+#, fuzzy
+msgid "A description of the selected item is shown here."
+msgstr "Registra gli elementi selezionati"
+
+#: newstuff/dialog.cpp:224
+#, fuzzy
+msgid "Downloading information..."
+msgstr "Importa le informazioni CDAudio da FreeDB"
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Pronto."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr ""
+
+#: newstuff/dialog.cpp:413
+#, fuzzy
+msgid "Installing item..."
+msgstr "Sto salvando il file ..."
+
+#: translators/bibteximporter.cpp:79
+#, fuzzy
+msgid "No valid bibtex entries were found"
+msgstr "Non è stato trovato alcun elemento Bibtex valido nel file - %1"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "Non è stato trovato alcun elemento Bibtex valido nel file - %1"
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Opzioni Bibtex"
+
+#: translators/bibteximporter.cpp:287
+#, fuzzy
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Codifica in Unicode (UTF-8)"
+
+#: translators/bibteximporter.cpp:288
+#, fuzzy
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Codifica il file esportato in Unicode (UTF-8)."
+
+#: translators/bibteximporter.cpp:289
+#, fuzzy
+msgid "Use user locale (%1) encoding"
+msgstr "Codifica secondo le impostazioni dell'utente (%1)"
+
+#: translators/bibteximporter.cpp:293
+#, fuzzy
+msgid "Read the imported file in the local encoding."
+msgstr "Codifica il file esportato secondo l'impostazione locale."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "File Zip Tellico"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|File di Tellico (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Tutti i file"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>Una biblioteca di Alexandria denominata <i>%1</i> esiste già. Tutti i "
+"file contenuti nella biblioteca potrebbe venire sovrascritti.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "C'è un errore di parsing HTML nella linea %1, colonna %2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "Il messaggio di errore Qt è:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Il file sembra appartenere ad una versione futura di Tellico."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Tellico sta convertendo il file in un formato più recente. Se in futuro "
+"venisse usata una versione più vecchia di Tellico per aprire il documento "
+"potrebbero verificarsi perdite di dati."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Sconosciuto"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "Il file è vuoto."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "Il file non contiene dati di una collezione."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Libri non letti"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Vecchi film"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "Musica anni '80"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Preferiti"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Scansione dei file audio ..."
+
+#: translators/audiofileimporter.cpp:129
+#, fuzzy
+msgid "Bitrate"
+msgstr "Bibtex"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(Varie)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Opzioni file audio"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Ricerca ricorsiva"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+"Se selezionato, i file audio verranno ricercati ricorsivamente all'interno "
+"delle cartelle."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:348
+#, fuzzy
+msgid "If checked, the file names for each track are added to the entries."
+msgstr ""
+"Se selezionato, i nomi di campo saranno stampati come headers della tabella."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:353
+#, fuzzy
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr ""
+"Se selezionato, i nomi di campo saranno stampati come headers della tabella."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|file CSV (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "Opzioni CSV"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Includi i titoli degli elementi com header della colonna"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr "Se selezionato, verrà aggiunta una riga con i titoli dei campi."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Delimitatore"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"Oltre alla virgola, altri caratteri possono essere usati come delimitatori, "
+"separando un valore da un altro."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Virgola"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Usa una virgola come delimitatore."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Punto e virgola"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Usa un punto e virgola come delimitatore."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Tab"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Usa uno spazio di tabulazione (tab) come delimitatore."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Altro"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Usa una stringa personalizzata come delimitatore."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr ""
+"Una stringa personalizzata, come per esempio due punti (:), può essere "
+"usata come delimitatore."
+
+#: translators/filelistingimporter.cpp:63
+#, fuzzy
+msgid "Scanning files..."
+msgstr "Scansione dei file audio ..."
+
+#: translators/filelistingimporter.cpp:191
+#, fuzzy
+msgid "File Listing Options"
+msgstr "Opzioni di stampa"
+
+#: translators/filelistingimporter.cpp:193
+#, fuzzy
+msgid "Recursive folder search"
+msgstr "Ricerca ricorsiva"
+
+#: translators/filelistingimporter.cpp:194
+#, fuzzy
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+"Se selezionato, i file audio verranno ricercati ricorsivamente all'interno "
+"delle cartelle."
+
+#: translators/filelistingimporter.cpp:198
+#, fuzzy
+msgid "Generate file previews"
+msgstr "&Genera resoconti ..."
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "Archivio ONIX"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.zip|file zip (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "Opzioni archivio ONIX"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Includi immagini nell'archivio"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Se selzionato, le immagini contenute nel documento verranno incluse "
+"nell'archivio ONIX compresso."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr ""
+"<qt>Tellico non è riuscito ad accedere alla periferica CD-ROM "
+"<i>%1</i>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+#, fuzzy
+msgid "Select CDDB Entry"
+msgstr "Cancella Elemento"
+
+#: translators/freedbimporter.cpp:197
+#, fuzzy
+msgid "Select a CDDB entry:"
+msgstr "Seleziona il risultato IMDB"
+
+#: translators/freedbimporter.cpp:220
+#, fuzzy
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>No ho trovato elementi da confrontare con il CD.</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "<qt>Tellico mnon ha potuto completare il controllo del CD.</qt>"
+
+#: translators/freedbimporter.cpp:470
+#, fuzzy
+msgid "Various"
+msgstr "(Varie)"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Opzioni CDAudio"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Leggi i dati dal CD-ROM"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Seleziona o inserisci la periferica CD-ROM."
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Leggi solo i file di cache CDDB"
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+"Leggi ricorsivamente i dati dai file di cache CDDB contenuti nelle cartelle "
+"di default della cache."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr ""
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+#, fuzzy
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.csv|file CSV (*.csv)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+#, fuzzy
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.csv|file CSV (*.csv)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "Opzioni XSLT"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "File XSLT:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr "Scegli il file XSLT utilizzato per trasforma i dati XML di Tellico."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Opzioni di Alexandria"
+
+#: translators/alexandriaimporter.cpp:195
+#, fuzzy
+msgid "&Library:"
+msgstr "Biblioteca:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "Bibtexml"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|file bibtexml (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|file XML (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Opzioni XML di Tellico"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Includi immagini nel file XML"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Se selzionato le immagini contenute nel documento verranno incluse nel "
+"flusso XML come elementi codificati in base64."
+
+#: translators/importer.h:100
+#, fuzzy
+msgid "Loading data..."
+msgstr "Sto importando i dati ..."
+
+#: translators/importer.h:100
+#, fuzzy
+msgid "Loading %1..."
+msgstr "Passo in rassegna %1 ..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "Bibtex"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|file bibtex (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Espandi string macros"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Se selezionato le string macros verranno espanse e nessun elemento @string{} "
+"verrà scritto."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Usa il pacchetto URL"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr ""
+"Se selezionato, qualsiasi campo URL verrà tradotto in un indirizzo \\url."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Salta elementi senza citazioni"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr "Se selzionato, ogni elemento senza citazione bibtex verrà saltato."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Stile per le citazioni Bibtex:"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Sostegni"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Citazioni"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"<qt>Lo stile usato per le citazioni quando si esporta bibtex. Tutti i valori "
+"dei campi verrano racchiusi tra parentesi graffe o virgolette.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Seleziona il tipo di collezione importato."
+
+#: translators/csvimporter.cpp:235
+#, fuzzy
+msgid "&First row contains field titles"
+msgstr "La prima riga contiene i titoli dei campi"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr ""
+"Se selezionato, la prima riga verrà utilizzata per contenere i titoli dei "
+"campi."
+
+#: translators/csvimporter.cpp:248
+#, fuzzy
+msgid "&Comma"
+msgstr "Virgola"
+
+#: translators/csvimporter.cpp:254
+#, fuzzy
+msgid "&Semicolon"
+msgstr "Punto e virgola"
+
+#: translators/csvimporter.cpp:259
+#, fuzzy
+msgid "Ta&b"
+msgstr "Tab"
+
+#: translators/csvimporter.cpp:264
+#, fuzzy
+msgid "Ot&her:"
+msgstr "Altro:"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "La tabella mostra fino alle prime cinque linee del file CSV."
+
+#: translators/csvimporter.cpp:296
+#, fuzzy
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt>Configura ogni colonna per corrispondere ad un campo della collezione "
+"selezionando una colonna e un campo e premendo il pulsante <i>Set</i>.</qt>"
+
+#: translators/csvimporter.cpp:298
+#, fuzzy
+msgid "Co&lumn:"
+msgstr "Colonna:"
+
+#: translators/csvimporter.cpp:307
+#, fuzzy
+msgid "&Data field in this column:"
+msgstr "Campo di dati in questa colonna:"
+
+#: translators/csvimporter.cpp:315
+#, fuzzy
+msgid "&Assign Field"
+msgstr "Assegna campo"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Nuovo campo"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|File di database Pilot (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Vedi colonne"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "Opzioni PilotDB"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Imposta la flag di backup del palmare per il database"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+#, fuzzy
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>Importa la lista dei numeri ISBN da un file di testo.</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Tellico ha rilevato un errore processando XSLT."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "è necessario un file XSLT per importare il file."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|file XSL (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|file HTML (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Gente"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(raggruppato per %1)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "Opzioni HTML"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Stampa i field headers"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr ""
+"Se selezionato, i nomi di campo saranno stampati come headers della tabella."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Raggruppa gli elementi"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr ""
+"Se selezionato, gli elementi verranno raggruppati secondo il campo "
+"selezionato."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Esporta file per singoli elementi"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr "Se selezionato, verranno creati singoli file per ogni elemento."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+#, fuzzy
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Impossibile caricare immagini dal file - %1."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Proprietà della fonte dei fati"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "Nome della &fonte: "
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr ""
+"Il nome identifica òa fonte dei dati e dovrebbe essere univoco e "
+"permetterne la facile identificazione."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "Tipo della fon&te: "
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr ""
+
+#: fetcherconfigdialog.cpp:114
+#, fuzzy
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Se selezionato, gli elementi verranno raggruppati secondo il campo "
+"selezionato."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Tutti i campi"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "contiene"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "non contiene"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "equivale"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "non è uguale"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "corrisponde alla espressione regolare"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "non corrisponde alla espressione regolare"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Modifica ..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Filtro Avanzato"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Criteri di filtro"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Verifica &tutti i criteri seguenti"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Verifica alme&no uno dei criteri seguenti"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Nome del filtro:"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "&Salva filtro"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Testo semplice"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Paragrafo"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Scelta"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Checkbox"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Tabella"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Dipendente"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Data"
+
+#: entryupdater.cpp:81
+#, fuzzy
+msgid "Updating %1..."
+msgstr "Passo in rassegna %1 ..."
+
+#: entryupdater.cpp:83
+#, fuzzy
+msgid "Updating entries..."
+msgstr "&Modifica elementi ..."
+
+#: entryupdater.cpp:85
+#, fuzzy
+msgid "Update Entries"
+msgstr "Modifica elementi"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr ""
+
+#: entryupdater.cpp:209
+#, fuzzy
+msgid "Select Match"
+msgstr "Seleziona il risultato IMDB"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Espandi elenco"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Riduci elenco"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Filtra per gruppo"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (ordina per conteggio)"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Gruppo"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Importa Opzioni"
+
+#: importdialog.cpp:62
+#, fuzzy
+msgid "&Replace current collection"
+msgstr "Sostituisci la collezione attuale"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr "Sostituisci la collezione attuale con i contenuti del file importato."
+
+#: importdialog.cpp:65
+#, fuzzy
+msgid "A&ppend to current collection"
+msgstr "Allega alla collezione attuale"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Allega il contenuto del file importato alla collezione attuale. This è "
+"possibile solo se le collezioni sono dello stesso tipo."
+
+#: importdialog.cpp:69
+#, fuzzy
+msgid "&Merge with current collection"
+msgstr "Unisci alla collezione attuale"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Unifica i contenuti del file importato a quelli della collezione attuale. "
+"Questo è possibile solo quando le collezioni sono dello stesso tipo. Per "
+"poter essere unificati tutti gli elementi devono corrispondere esattamente."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Importa"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|file RIS (*.ris)"
+
+#: importdialog.cpp:277
+#, fuzzy
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.csv|file CSV (*.csv)"
+
+#: importdialog.cpp:281
+#, fuzzy
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdb|File di database Pilot (*.pdb)"
+
+#: importdialog.cpp:285
+#, fuzzy
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.ris|file RIS (*.ris)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Impossibile caricare il file - %1."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Impossibile scrivere sul file - %1."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Impossibile uploadare il file - %1."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Solo le collezioni con lo stesso tipo di elementi di quella attuale posso "
+"essere allegate. Nessuna modifica verrà applicata alla collezione attuale."
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Solo le collezioni con lo stesso tipo di elementi di quella attuale possono "
+"essere unificate. Nessuna modifica verrà applicata alla collezione attuale."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Impossibile caricare immagini dal file - %1."
+
+#: entryiconview.cpp:287
+#, fuzzy
+msgid "&Sort By"
+msgstr "&Porta: "
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Modulo per il prestito"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "I seguenti oggetti sono stati controllati:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "Il seguente oggetto è stato prestato:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "pr&esta a:"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Inserisci il nome della persona che riceve l'oggetto da te. Il pulsante ti "
+"permette di selezionare qualcuno presente nella tua rubrica."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "Data del p&restito:"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+"La dara in cui tu hai prestato gli oggetti. La data di default è quella di "
+"oggi."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "Data di restit&uzione:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"È la data in cui dovrebbero esserti restituiti gli oggetti. La data di "
+"restituzione è facoltativa a meno che tu non voglia inserire il prestito al "
+"tuo calendario."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Nota:"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "Puoi aggiungere delle note riguardanti il prestito."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "&Aggiungi un memorandum al calendario"
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"<qt>Selezionando questa casella aggiungerai un <em>To-do</em> al calendario "
+"attivo che viene mostrato da KOrganizer. Puoi selezionare la casella solo se "
+"hai impostato una data di restituzione.</qt>"
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Crea una nuova collezione"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Nuova Collez&ione di libri"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Crea una nuova collezione di libri"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Nuova B&ibliografia"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Crea una nuova bibliografia bibtex"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Nuova &Collezione di fumetti"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Crea una nuova collezione di fumetti"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Nuova collezione &Video"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Crea una nuova collezione di video"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Nuova Collezione &Musicale"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Crea una nuova collezione di musica"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Nuova Collezione di m&onete"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Crea una nuova collezione di monete"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Nuova collezione di f&rancobolli"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Crea una nuova collezione di francobolli"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Nuova collezione di c&arte"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Crea una nuova collezione di carte collezionabili"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Nuova collezione di &Vini"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Crea una nuova collezione di vini"
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Nuova collezione di &giochi"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Crea una nuova collezione di giochi"
+
+#: mainwindow.cpp:272
+#, fuzzy
+msgid "New Boa&rd Game Collection"
+msgstr "Nuova collezione di &giochi"
+
+#: mainwindow.cpp:274
+#, fuzzy
+msgid "Create a new board game collection"
+msgstr "Crea una nuova collezione di giochi"
+
+#: mainwindow.cpp:280
+#, fuzzy
+msgid "New &File Catalog"
+msgstr "Nuovo campo"
+
+#: mainwindow.cpp:282
+#, fuzzy
+msgid "Create a new file catalog"
+msgstr "Crea una nuova collezione"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Nuova colle&zione personalizzata"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Crea una nuova collezione personalizzata"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Apri un documento esistente"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Apri un documento recente"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Salva il documento"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Salva il documento su un file diverso ..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Stampa il documento ..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Chiudi il programma"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Importa i dati di una collezione da un formato diverso"
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Importa dati Tellico ..."
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Importa un altro file Tellico"
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "Importa dati CSV ..."
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Importa un file CSV"
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "Importa dati MODS ..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Importa un file di dati MODS"
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Importa dati Alexandria ..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Importa dati dal gestore di collezioni Alexandria"
+
+#: mainwindow.cpp:352
+#, fuzzy
+msgid "Import Delicious Library Data..."
+msgstr "Importa dati Tellico ..."
+
+#: mainwindow.cpp:353
+#, fuzzy
+msgid "Import data from Delicious Library"
+msgstr "Importa metadati dai file audio"
+
+#: mainwindow.cpp:359
+#, fuzzy
+msgid "Import Referencer Data..."
+msgstr "Importa dati RIS ..."
+
+#: mainwindow.cpp:360
+#, fuzzy
+msgid "Import data from Referencer"
+msgstr "Importa un reference file RIS"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Importa dati Bibtex ..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Importa un file di bibliografia Bibtex"
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Importa dati Bibtexml ..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Importa un file di bibliografia Bibtexml"
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "Importa dati RIS ..."
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Importa un reference file RIS"
+
+#: mainwindow.cpp:387
+#, fuzzy
+msgid "Import PDF File..."
+msgstr "Importa file"
+
+#: mainwindow.cpp:388
+#, fuzzy
+msgid "Import a PDF file"
+msgstr "Importa un file CSV"
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Importa metadati di un file audio ..."
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Importa metadati dai file audio"
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Importa dati CDAudio ..."
+
+#: mainwindow.cpp:405
+#, fuzzy
+msgid "Import audio CD information"
+msgstr "Importa le informazioni CDAudio da FreeDB"
+
+#: mainwindow.cpp:414
+#, fuzzy
+msgid "Import GCstar Data..."
+msgstr "Importa dati CSV ..."
+
+#: mainwindow.cpp:415
+#, fuzzy
+msgid "Import a GCstar data file"
+msgstr "Importa un file di dati MODS"
+
+#: mainwindow.cpp:421
+#, fuzzy
+msgid "Import Griffith Data..."
+msgstr "Importa dati CSV ..."
+
+#: mainwindow.cpp:422
+#, fuzzy
+msgid "Import a Griffith database"
+msgstr "Esporta in un database PilotDB"
+
+#: mainwindow.cpp:428
+#, fuzzy
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Importa dati CDAudio ..."
+
+#: mainwindow.cpp:429
+#, fuzzy
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Importa un altro file Tellico"
+
+#: mainwindow.cpp:435
+#, fuzzy
+msgid "Import File Listing..."
+msgstr "Importa file"
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr ""
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "Importa XSL Transform ..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Importa un file usando XSL transform"
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Esporta"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Esporta i dati della collezione in un altro formato"
+
+#: mainwindow.cpp:461
+#, fuzzy
+msgid "Export to XML..."
+msgstr "Esporta in HTML ..."
+
+#: mainwindow.cpp:462
+#, fuzzy
+msgid "Export to a Tellico XML file"
+msgstr "Esporta in un file XML di Tellico"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Esporta in Zip ..."
+
+#: mainwindow.cpp:469
+#, fuzzy
+msgid "Export to a Tellico Zip file"
+msgstr "Esporta in un file XML di Tellico"
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "Esporta in HTML ..."
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Esporta in un file HTML"
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "Esporta in CSV ..."
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Esporta su un file Comma-Separated Values"
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "Esporta in PilotDB ..."
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Esporta in un database PilotDB"
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Esporta in Alexandria ..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Esporta in una biblioteca Alexandria"
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Esporta in Bibtex ..."
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Esporta come file Bibtex"
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Esporta in Bibtexml ..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Esporta come file Bibtexml"
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "Esporta in ONIX ..."
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Esporta in un file ONIX"
+
+#: mainwindow.cpp:524
+#, fuzzy
+msgid "Export to GCfilms..."
+msgstr "Esporta in CSV ..."
+
+#: mainwindow.cpp:525
+#, fuzzy
+msgid "Export to a GCfilms data file"
+msgstr "Esporta come file Bibtex"
+
+#: mainwindow.cpp:531
+#, fuzzy
+msgid "Export to GCstar..."
+msgstr "Esporta in CSV ..."
+
+#: mainwindow.cpp:532
+#, fuzzy
+msgid "Export to a GCstar data file"
+msgstr "Esporta come file Bibtex"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "Esporta XSL Transform ..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Esporta il file usando un XSL transform"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Taglia il testo selezionato e lo memorizza negli appunti"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Copia il testo selezionato negli appunti"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Incolla il contenuto degli appunti"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Seleziona tutti i campi della collezione"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Deseleziona tutti i campi della collezione"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Ricerca su Internet ..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Ricerca attraverso Internet ..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "&Filtro avanzato ..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Applica filtri"
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&Nuovo Elemento ..."
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Crea un nuovo elemento"
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "&Modifica elemento ..."
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Modifica gli elementi selezionati"
+
+#: controller.cpp:621 mainwindow.cpp:577
+#, fuzzy
+msgid "D&uplicate Entry"
+msgstr "Duplica elemento"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Copia l'elemento selezionato"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "&Cancella Elemento"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Cancella gli elementi selezionati"
+
+#: mainwindow.cpp:585
+#, fuzzy
+msgid "&Merge Entries"
+msgstr "Cance&lla elementi"
+
+#: mainwindow.cpp:588
+#, fuzzy
+msgid "Merge the selected entries"
+msgstr "Cancella gli elementi selezionati"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "&Genera resoconti ..."
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Genera resoconti sulla collezione"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "&Verifica ..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Controlla gli elementi selezionati"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "Reg&istrazione"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Registra gli elementi selezionati"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "&Rinomina Collezione ..."
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Rinomina la collezione"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "Campi della colle&zione ..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Modifica i campi della tabella della collezione"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "Converti in &Bibliografia"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Trasforma una collezione di libri in una bibliografia"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "String &Macros..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Edita le string macros Bibtex"
+
+#: mainwindow.cpp:626
+#, fuzzy
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Copia il testo selezionato negli appunti"
+
+#: mainwindow.cpp:627
+#, fuzzy
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Copia il testo selezionato negli appunti"
+
+#: mainwindow.cpp:632
+#, fuzzy
+msgid "Cite Entry in &LyX"
+msgstr "&Cita elemento"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Cita l'elemento selezionato in LyX"
+
+#: mainwindow.cpp:638
+#, fuzzy
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "&Cita elemento"
+
+#: mainwindow.cpp:639
+#, fuzzy
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Cita l'elemento selezionato in LyX"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, fuzzy, no-c-format
+msgid "&Update Entry"
+msgstr "&Cita elemento"
+
+#: mainwindow.cpp:652
+#, fuzzy
+msgid "All Sources"
+msgstr "Fonte"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr ""
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Mostra la vista di grup&po"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Abilita/disabilita la vista di gruppo"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Nascondi la vista di grup&po"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Mostra l'&Editor degli elementi"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Abilita/disabilita l'editor"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "Nascondi l'&Editor degli elementi"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Mostra la &Vista degli elementi"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Abilita/disabilita la vista degli elementi"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "Nascondi la &Vista degli elementi"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Cambia raggruppamento"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "Selezione di &gruppo"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Cambia il modo di raggruppamento"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Filtro"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Cancella filtro"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Filtra qui ..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Gruppi"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt>La <i>vista di gruppo</i> ordina gli elementi in gruppi secondo il campo "
+"selezionato.</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt>La <i>vista per colonne</i> mostra il vaolre di diversi campi per ogni "
+"elemento.</qt>"
+
+#: mainwindow.cpp:831
+#, fuzzy
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Tellico - un gestore delle collezioni personali per KDE"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Creazione nuovo documento ..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Sto aprendo il file ..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Apri file"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Sto salvando il file ..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr ""
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr ""
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Sto salvando il file con un nuovo nome ..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "In stampa ..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"Sto filtrando la collezione per mostrare solo un numero ridotto di elementi. "
+"Solo gli elementi visibili saranno stampati. Continuare?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Sto processando il documento ..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Chiusura ..."
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Elementi totali: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 filtrato, %2 selezionato)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 filtrato)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 selezionato)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Stampa %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Pagina %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Controlla la tua installazione, grazie."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Sto importando i dati ..."
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Importa file"
+
+#: mainwindow.cpp:1864
+#, fuzzy
+msgid "Import Directory"
+msgstr "Importatore"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Sto esportando i dati ..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Esporta come"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "String Macros"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Macro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Stringa"
+
+#: mainwindow.cpp:1999
+#, fuzzy
+msgid "Creating citations..."
+msgstr "Sto tagliando ..."
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Filtri"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt>La <i>vista filtrata</i> mostra gli elementi che soddisfano certi filtri "
+"di ricerca.</qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Prestiti"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt>La <i>vista per prestiti</i> mostra tutte le persone che hanno preso in "
+"prestito elementi della tua collezione.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr ""
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Impossibile caricare l'immagine - %1."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr "Il file \"%1\" esiste già. lo vuoi sovrascrivere?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Sovrascrivere il file?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Sovrascrivi"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Filtra (ordina per conteggio)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Vuoi davvero cancellare questo elemento?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Cancella Elemento"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Vuoi davvero cancellare questi elementi?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Cancella diversi elementi"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "&Modifica elementi ..."
+
+#: controller.cpp:627
+#, fuzzy
+msgid "D&uplicate Entries"
+msgstr "Duplica elemento"
+
+#: controller.cpp:628
+#, fuzzy
+msgid "&Update Entries"
+msgstr "Modifica elementi"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "Cance&lla elementi"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+"I seguenti oggetti sono già in prestito, ma Tellico non supporta il "
+"prestito di un oggetto a più di una persona. Essi verranno cancellati dalla "
+"lista degli oggetti in prestito."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Calendario di default"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"Attualmente Tellico supporta solo il calendario locale. Il calendario attivo "
+"è remoto, dunque i tuoi prestiti non saranno inseriti nel calendario."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Calendario attivo"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 dev'essermi restituito \"%2\""
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(Vuoto)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - un gestore delle collezioni personali per KDE"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Non riaprire l'ultimo file aperto"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Importa <filename> come file bibtex"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Importa <filename> come file MODS"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Importa <filename> come file RIS"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "File da aprire"
+
+#: main.cpp:42
+#, fuzzy
+msgid "Data source scripts"
+msgstr "Opzioni della fonte dei dati"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Icone"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Autore della libreria btparse"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr ""
+
+#: main.cpp:50
+#, fuzzy
+msgid "Author of libcsv library"
+msgstr "Autore della libreria btparse"
+
+#: main.cpp:52
+#, fuzzy
+msgid "Author of rtf2html library"
+msgstr "Autore della libreria btparse"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Campi della collezione"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Campi attuali"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "&Nuovo"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Aggiungi un campo alla collezione"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "Cance&lla"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Rimuovi un campo dalla collezione"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Sposta verso l'alto questo campo. L'ordine della lista è importante per "
+"l'editor degli elementi."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Sposta verso il basso questo campo. L'ordine della lista è importante per "
+"l'editor degli elementi."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Proprietà del campo"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "&Titolo:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "Titolo del campo"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "T&ipo:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "Il tipo del campo determina i valori che possono esservi inseriti. "
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "Per la maggior parte dei campi si usa <i>Testo semplice</i>. "
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "Per i grossi blocchi di testo si usa <i>Paragrafo</i>. "
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Scelta</i> limita i campi a certi valori. "
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "<i>Checkbox</i> permette di inserire solo valori si/no. "
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr "<i>Numero</i> indica che il campo contiene valori numerici. "
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+"Per i campi che contengono URL, compresi riferimenti ad altri file si usa "
+"<i>URL</i>. "
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr "Una <i>Tabella</i> può contenere una o più colonne di valori. "
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "Un campo <i>Immagine</i> contiene immagini. "
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+"In un campo <i>Data</i> si possono inserire valori comprensivi di giorno, "
+"mese e anno. "
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+"Un campo <i>Valutazione</i> usa delle stelline per mostrare un valore di "
+"valutazione. "
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"Un campo <i>Dipendente</i> dipende dai valori di altri campi ed è "
+"formattato secondo la descrizione del campo. "
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"Un campo <i>Sola lettura</i> serve per uso interno, può risultare utile per "
+"l'importazione e l'esportazione. "
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "Cate&goria:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr "La categoria determina dove sarà collocato il campo nell'editor."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "Descr&izione:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"La descrizione è utile per ricordare che cosa è contenuto in un campo. Per "
+"i campi <i>Dipendenti</i> la descrizione è una stringa di formattazione "
+"tipo: \"%{year} %{title}\" dove i campi definiti (anno, titolo) vengono "
+"sostituiti nella stringa."
+
+#: collectionfieldsdialog.cpp:193
+#, fuzzy
+msgid "&Default value:"
+msgstr "Calendario di default"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:203
+#, fuzzy
+msgid "A&llowed values:"
+msgstr "A&mmessi:"
+
+#: collectionfieldsdialog.cpp:208
+#, fuzzy
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>Per i campi di tipo <i>Scelta</i>, questi sono gli unici valori ammessi. "
+"Vengono inseriti in una combo box.</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "Pro&prietà estese:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "Impo&sta ..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"Le proprietà avanzate possono essere usate per specificare cose come il "
+"campo bibtex corrispondente."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Opzioni di formattazione"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Nessuna formattazione"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+"Questa opzione evita che il campo venga formattato automaticamente o che "
+"venga applicato il maiuscolo automatico."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Permetti il maiuscolo automatico"
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+"Questa opzione permette che gli elementi del campo vengano automaticamente "
+"resi maiuscoli, senza però cambiare la formattazione."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Formatta come titolo"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Questa opzione applica le maiuscole e formatta il campo come titolo, ma solo "
+"se queste opzioni sono state specificate nella configurazione globale."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Formatta come nome"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Questa opzione applica le maiuscole e formatta il campo come nome, ma solo "
+"se queste opzioni sono state specificate nella configurazione globale."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Opzioni del campo"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Abilita l'autocompletamento"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Se selezionato, l'autocompletamento di KDE verrà abilitato per la casella "
+"di testo di questo campo."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Ammetti valori multipli"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Se selezionato, Tellico analizzerà i valori del campo cercando valori "
+"multipli, i valori devono essere diviso da un punto e virgola."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Ammetti il raggruppamento"
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Se selezionato, il campo può essere usato per ragruppare gli elementi nella "
+"vista di gruppo."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr ""
+"Ripristina le proprietà dei campi selezionati secondo i valori predefiniti."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Modifica campi"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Cancellare i valori ammessi dal campo <i>%1</i> attualmente esistente "
+"può causare la corruzione dei dati contenuti nella collezione. Vuoi usare i "
+"valori modificati o annullarli e mantenere quelli attuali?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Usa i valori modificati"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Inverti le proprietà del campo"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Vuoi davvero ripristinare le proprietà del campo <em>%1</em> "
+"riportandole ai valori predefiniti?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Ripristinare"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Proprietà estese del campo"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr "Esiste già un campo con questo titolo. Inserisci un titolo diverso."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr "<qt>La categoria non può essere nulla, Inserisci una categoria. </qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>Un campo potrebbe non essere nella stessa categoria del campo "
+"<em>Paragrafo</em>, <em>Tabella</em> o <em>Immagine</em>. Inserisci un'altra "
+"categoria.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"Il titolo non un campo non può essere uguale al nome di una categoria. "
+"Inserisci un altro titolo."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+"Il valore di un campo di valutazione dev'essere compreso tra 1 e 10 e il "
+"limite minimo dev'essere necessariamente inferiore a quello massimo. "
+"Inserisci proprietà alte e basse differenti."
+
+#: collectionfieldsdialog.cpp:952
+#, fuzzy
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "Le tabelle hanno un limite massimo di cinque colonne."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Il file attuale �stato modificato.\n"
+"Lo vuoi salvare?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Modifiche non salvate"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Seleziona a chi hai fatto il prestito "
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Configura Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Opzioni generali"
+
+#: configdialog.cpp:201
+#, fuzzy
+msgid "&Reopen file at startup"
+msgstr "Riapri il file all'avvio"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr "Se selezionato, l'ultimo file aperto dev'essere riaperto all'avvio."
+
+#: configdialog.cpp:207
+#, fuzzy
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "Mostra \"suggerimento del giorno\" all'avvio"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr ""
+"Se selezionato, un \"suggerimento del giorno\" verrà visualizzato ad ogni "
+"avvio."
+
+#: configdialog.cpp:213
+#, fuzzy
+msgid "Image Storage Options"
+msgstr "Opzioni dell'immagine"
+
+#: configdialog.cpp:214
+#, fuzzy
+msgid "Store images in data file"
+msgstr "Includi immagini nell'archivio"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr ""
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr ""
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Opzioni di formattazione"
+
+#: configdialog.cpp:227
+#, fuzzy
+msgid "Auto capitalize &titles and names"
+msgstr "Maiuscolo automatico in titoli e nomi"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Se selezionato, i titoli e gli autori diventeranno automaticamente maiuscoli."
+
+#: configdialog.cpp:232
+#, fuzzy
+msgid "Auto &format titles and names"
+msgstr "Formattazione automatica di titoli e nomi"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr "Se selezionato, titoli e nomi verranno ordinati automaticamente."
+
+#: configdialog.cpp:240
+#, fuzzy
+msgid "No capitali&zation:"
+msgstr "Permetti il maiuscolo automatico"
+
+#: configdialog.cpp:243
+#, fuzzy
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Una lista di prefissi, separati da punto e virgola, da usare nei "
+"cognomi.</qt>"
+
+#: configdialog.cpp:249
+#, fuzzy
+msgid "Artic&les:"
+msgstr "Articoli:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>Un elenco di parole, separate da punto e virgola, che saranno "
+"considerati articoli se appaiono come prima parola di un titolo.</qt>"
+
+#: configdialog.cpp:259
+#, fuzzy
+msgid "Personal suffi&xes:"
+msgstr "Suffissi personali:"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Una lista di suffissi ,separati da punto e virgola, da usare nei nomi di "
+"persona</qt>"
+
+#: configdialog.cpp:268
+#, fuzzy
+msgid "Surname &prefixes:"
+msgstr "Prefissi dei cognomi:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Una lista di prefissi, separati da punto e virgola, da usare nei "
+"cognomi.</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "In stampa"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Opzioni di stampa"
+
+#: configdialog.cpp:302
+#, fuzzy
+msgid "&Format titles and names"
+msgstr "Formatta titoli e nomi"
+
+#: configdialog.cpp:306
+#, fuzzy
+msgid "&Print field headers"
+msgstr "Stampa i field headers"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Opzioni di raggruppamento"
+
+#: configdialog.cpp:313
+#, fuzzy
+msgid "&Group the entries"
+msgstr "Raggruppa gli elementi"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Opzioni dell'immagine"
+
+#: configdialog.cpp:323
+#, fuzzy
+msgid "Maximum image &width:"
+msgstr "Larghezza massima delle immagini:"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"La larghezza massima delle immagini in stampa. Le proporzioni sono "
+"rispettate."
+
+#: configdialog.cpp:336
+#, fuzzy
+msgid "&Maximum image height:"
+msgstr "Altezza massima delle immagini:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"L'altezza massima delle immagini in stampa. Le proporzioni sono rispettate."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Template"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Opzioni Template"
+
+#: configdialog.cpp:369
+#, fuzzy
+msgid "Template:"
+msgstr "Template"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+
+#: configdialog.cpp:380
+#, fuzzy
+msgid "&Preview..."
+msgstr "&Nuovo ..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr ""
+
+#: configdialog.cpp:398
+#, fuzzy
+msgid "Font Options"
+msgstr "Opzioni di formattazione"
+
+#: configdialog.cpp:405
+#, fuzzy
+msgid "Font:"
+msgstr "Mese"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:415
+#, fuzzy
+msgid "Size:"
+msgstr "Autografato"
+
+#: configdialog.cpp:425
+#, fuzzy
+msgid "Color Options"
+msgstr "Opzioni CSV"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr ""
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr ""
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr ""
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr ""
+
+#: configdialog.cpp:469
+#, fuzzy
+msgid "Manage Templates"
+msgstr "Template"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr ""
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr ""
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr ""
+
+#: configdialog.cpp:484
+#, fuzzy
+msgid "Click to download additional templates via the Internet."
+msgstr ""
+"Clicca per aprire una casella in cui inserire o modificare i valori ISBN."
+
+#: configdialog.cpp:487
+#, fuzzy
+msgid "Delete..."
+msgstr "Seleziona immagine ..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr ""
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Fonti dei dati"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Opzioni della fonte dei dati"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Fonte"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr ""
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+
+#: configdialog.cpp:521
+#, fuzzy
+msgid "Move &Down"
+msgstr "Rimuo&vi"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "&Nuovo ..."
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr ""
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Modifica ..."
+
+#: configdialog.cpp:533
+#, fuzzy
+msgid "Click to modify the selected data source."
+msgstr "Controlla gli elementi selezionati"
+
+#: configdialog.cpp:536
+#, fuzzy
+msgid "Click to delete the selected data source."
+msgstr "Cancella gli elementi selezionati"
+
+#: configdialog.cpp:539
+#, fuzzy
+msgid "Click to download additional data sources via the Internet."
+msgstr ""
+"Clicca per aprire una casella in cui inserire o modificare i valori ISBN."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr ""
+
+#: configdialog.cpp:1049
+#, fuzzy
+msgid "Delete Template"
+msgstr "Cancella campo"
+
+#: configdialog.cpp:1050
+#, fuzzy
+msgid "Select template to delete:"
+msgstr "Seleziona il database per la ricerca"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "A chi hai fatto il prestito "
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Registrazione"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Modifica prestito ..."
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "A chi hai fatto il prestito (ordina per conteggio)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "La mia Collezione"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Collezione di libri"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Collezione difumetti"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Collezione di video"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Collezione musicale"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Collezione di monete"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Collezione di cartoline"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Collezione di vini"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Collection di carte"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Collezione di giochi"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr ""
+
+#: collectionfactory.cpp:135
+#, fuzzy
+msgid "Board Game Collection"
+msgstr "Collezione di giochi"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Collezione Personalizzata"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+"<qt>La <i>vista per elementi</i> riordina la vista secondo i contenuti degli "
+"elementi.</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt>La <i>vista per icone</i> mostra ogni elemento della collezione o del "
+"gruppo usando un'icona, che può essere un'immagine contenuta "
+"nell'elemento.</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Esporta opzioni"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Formattazione"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Formatta tutti i campi"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Se selezionato, i valori nei campi saranno automaticamente formattati "
+"secondo il tipo di formattazione."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Esporta solo gli elementi selezionati"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr "Se selezionato, verranno esportati solo gli elementi selezionati."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Codifica"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Codifica in Unicode (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Codifica il file esportato in Unicode (UTF-8)."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Codifica secondo le impostazioni dell'utente (%1)"
+
+#: exportdialog.cpp:72
+#, fuzzy
+msgid "Encode the exported file in the local encoding."
+msgstr "Codifica il file esportato secondo l'impostazione locale."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "Cer&ca"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "&Stop"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Ricerca Internet"
+
+#: fetchdialog.cpp:94
+#, fuzzy
+msgid "Search Query"
+msgstr "Search Query"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr "Ric&erca:"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+"Inserisci una valore da ricercare. Una ricerca ISBN deve includere il numero "
+"ISBN completo."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Scegli il tipo di ricerca"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Clicca per cominciare o fermare la ricerca"
+
+#: fetchdialog.cpp:134
+#, fuzzy
+msgid "&Multiple ISBN/UPC search"
+msgstr "Ricerca di ISBN &Multipli"
+
+#: fetchdialog.cpp:135
+#, fuzzy
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr "Seleziona questa casella per ricercare diversi valori ISBN."
+
+#: fetchdialog.cpp:138
+#, fuzzy
+msgid "Edit List..."
+msgstr "Modifica la lista degli &ISBN ..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+"Clicca per aprire una casella in cui inserire o modificare i valori ISBN."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "Cerca f&onte:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Seleziona il database per la ricerca"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"I risultati trovati vengono aggiunti a questa lista. Selezionandone uno si "
+"visualizzerà l'intero elemento."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"Un elemento può essere visualizzato qui prima di aggiungerlo alla "
+"colelzione attuale selezionando dalla lista sopra. "
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "&Aggiungi elemento"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Aggiungi l'elemento selezionato alla collezione attuale"
+
+#: fetchdialog.cpp:198
+#, fuzzy
+msgid "Get More Results"
+msgstr "Seleziona il risultato IMDB"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr ""
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Pulisci tutti i campi di ricerca e i risultati"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Ripulisco la ricerca ..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Ricerca in corso ..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "La ricerca non ha dato risultati."
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+"La ricerca ha trovato 1 oggetto.\n"
+"La ricerca ha trovato %n oggetti."
+
+#: fetchdialog.cpp:412
+#, fuzzy
+msgid "No results were found for the following ISBN values:"
+msgstr "<qt>Non ho trovato voci per i seguenti valori ISBN:</qt>"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Passo in rassegna %1 ..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr ""
+"Non sono disponibili su Internet fonti adatte a questo tipo di collezione."
+
+#: fetchdialog.cpp:594
+#, fuzzy
+msgid "Edit ISBN/UPC Values"
+msgstr "Modifica i valori ISBN"
+
+#: fetchdialog.cpp:598
+#, fuzzy
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Inserisci i valori ISBN, uno per riga.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "&Carica da file ..."
+
+#: fetchdialog.cpp:605
+#, fuzzy
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Importa la lista dei numeri ISBN da un file di testo.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>Una ricerca ISBN può contenere al massimo 100 valori ISBN.Verranno "
+"utilizzat solo i primi cento numeri della tua lista.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Modifica elemento"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Nuovo Elemento"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "Sal&va elemento"
+
+#: entryeditdialog.cpp:77
+#, fuzzy
+msgid "Go to the previous entry in the collection"
+msgstr "Trova la pecedente corrispondenza nella collezione"
+
+#: entryeditdialog.cpp:82
+#, fuzzy
+msgid "Go to the next entry in the collection"
+msgstr "Seleziona tutti i campi della collezione"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Vuoi davvero modificare questi elementi?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Modifica vari elementi"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr ""
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Modifica elementi"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "Sal&va elementi"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"Il file attuale è stato modificato.\n"
+"Lo vuoi salvare?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Salva Elemento"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Resoconto sulla collezione"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "Template del &resoconto:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "&Genera"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr "Seleziona un template per il resoconto e clicca su <em>Genera</em>."
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+"Per generare i resoconti di grandi collezioni possono essere necessari "
+"diversi secondi."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Vuoi davvero cancellare questo elemento?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Cancellare filtro?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Nuovo nome della collezione:"
+
+#: tellico_kernel.cpp:377
+#, fuzzy
+msgid "Entry 1"
+msgstr "Elemento"
+
+#: tellico_kernel.cpp:378
+#, fuzzy
+msgid "Entry 2"
+msgstr "Elemento"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr ""
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+#, fuzzy
+msgid "Merge Entries"
+msgstr "Cancella elementi"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr ""
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico non è in grado di trovare il foglio di stile di default."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Nuovo"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Collezione"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Barra degli strumenti-collezione"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Lorenzo Novaro"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "novalore@inwind.it"
+
+#: entrymerger.cpp:35
+#, fuzzy
+msgid "Merging entries..."
+msgstr "&Modifica elementi ..."
+
+#: entrymerger.cpp:49
+#, fuzzy
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Elementi totali: %1"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>... che se un libro ha più di un autore, dovresti separare i diversi "
+"nomi \n"
+"usando un punto e virgola, cosicché Tellico possa suddividerli \n"
+"ed usarli separatamente.</p>\n"
+"<p>Qualsiasi campo che ammetta valori multipli riconoscerà i diversi \n"
+"valori allo stesso modo, identificando il punto e virgola (;) come "
+"separatore.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>... che puoi cambiare i campi che vengono visualizzati cliccando con il "
+"tasto \n"
+" destro sul titolo della colonna.</p>\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>... che puoi aggiungere, modificare e cambiare i campi della collezione\n"
+"usando l'editor. I tasti freccia sotto i campi possono essere usati per "
+"cambiare\n"
+"la posizione all'interno della lista, il che modificherà la posizione "
+"nell'editor degli elementi.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>... che se vuoi filtrare dei contenuti secondo un campo checkbox,\n"
+"dovresti usare un valore \"true\".Se, per esempio, vuoi che un filtro\n"
+"ti mostri solo i libri di fantascienza che non hai ancora letto seleziona\n"
+"il pulsante <em>Verifica tutti i criteri seguenti</em>, imposta la prima\n"
+"regola così: \"Genere\" \"contiene\" \"Fantascienza\" (non usare le "
+"virgolette)\n"
+"e la seconda regola così: \"Letto\" \"non contiene\" |\"vero\"\n"
+"(anche qui non usare le virgolette).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>.. che se nel filtro rapido inserisci un carattere diverso da una "
+"lettera, il testo\n"
+"verrà interpretato come una espressione regolare (regexp).</p>\n"
+"<p>Per mostrare solo i libri di Vidal o Weber, per esempio, digita \n"
+"\"vidal|weber\" (senza virgolette) nella casella del filtro rapido</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>... che puoi modificare più di un elemento alla volta tenendo premuto il "
+"tasto Ctrl o\n"
+"Shift (il tasto delle maiuscole) e selezionando vari elementi.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>... che puoi convertire una collezione di libri in una bibliografia,\n"
+"che può essere poi esportata in formato Bibtex o Bibtexml.</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>... che puoi aggiungere modificare e cancellare le string macros per le "
+"bibliografie.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p> ... che se più di un campo contiene un nome, allora viene aggiunto un "
+"gruppo alla collezione\n"
+"chiamato \"persone\", permettendo così, per esempio, di stampare un elenco "
+"di autori ed editor.</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>... che puoi cambiare l'aspetto delle pagine stampate modificando il "
+"file\n"
+"<tt>tellico-printing.xsl</tt>. Il file genera l'HTML, mentre il CSS interno "
+"gestisce cose come\n"
+"i caratteri, i margini eccetera ...</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>... che puoi importare ed esportare file usando un qualsiasi stylesheet "
+"XSL \n"
+"che produca un file XML valido per Tellico.</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr "<p>...che cliccare due volte su un elemento apre l'editor.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>...che puoi aggiungere tag HTML come &lt;b&gt;bold&lt;/b&gt;\n"
+"o &lt;i&gt;italic&lt;/i&gt; a qualsiasi campo Paragrafo per migliorarne\n"
+"la formattazione.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>...che nella vista dettagliata basta premere un pulsante sulla tastiera\n"
+"per saltare al primo elemento che comincia con quella lettera.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Album"
+
+#: xslt.cpp:3
+#, fuzzy
+msgid "This template is meant for music collections only."
+msgstr "Crea una nuova collezione di musica"
+
+#: xslt.cpp:5
+#, fuzzy
+msgid "Total:"
+msgstr "Totale"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr "Fantasioso"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "Default"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Compatto"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Video"
+
+#: xslt.cpp:14 xslt.cpp:43
+#, fuzzy
+msgid "This template is meant for video collections only."
+msgstr "Crea una nuova collezione di video"
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Sommario di gruppo"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Sommario di gruppo"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Numero totale di campi:"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Numero totale di elementi:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+#, fuzzy
+msgid "Generated by Tellico"
+msgstr "Generato da"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Valori distinti: "
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Lista di immagini"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Vista per prestiti"
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Data di prestito"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Nota"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Data di restituzione"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Vista di gruppo"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Lista per titolo (Orizzontale)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Lista per titolo (Verticale)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Vista a colonne"
+
+#: xslt.cpp:42
+#, fuzzy
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "Vista a colonne"
+
+#: xslt.cpp:44
+#, fuzzy
+msgid "Search"
+msgstr "Cer&ca"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr ""
+
+#: z3950.cpp:6
+#, fuzzy
+msgid "Sudoc (France)"
+msgstr "Amazon (Francia)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr ""
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr ""
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr ""
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr ""
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr ""
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr ""
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr ""
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr ""
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr ""
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr ""
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr ""
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr ""
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr ""
+
+#, fuzzy
+#~ msgid "CrossRef"
+#~ msgstr "Riferimento incrociato"
+
+#, fuzzy
+#~ msgid "MODS"
+#~ msgstr "Mac OS"
+
+#~ msgid "GCstar"
+#~ msgstr "GCstar"
+
+#, fuzzy
+#~ msgid "Griffith"
+#~ msgstr "Regalo"
+
+#, fuzzy
+#~ msgid "Referencer"
+#~ msgstr "Riferimento incrociato"
+
+#~ msgid "Comics"
+#~ msgstr "Fumetti"
+
+#~ msgid "Stamps"
+#~ msgstr "Francobolli"
+
+#~ msgid "Coins"
+#~ msgstr "Monete"
+
+#~ msgid "Books"
+#~ msgstr "Libri"
+
+#~ msgid "Wines"
+#~ msgstr "Vini"
+
+#~ msgid "Videos"
+#~ msgstr "Video"
+
+#~ msgid "Games"
+#~ msgstr "Giochi"
+
+#~ msgid "Cards"
+#~ msgstr "Carte"
+
+#~ msgid "Entries"
+#~ msgstr "Elementi"
+
+#~ msgid "Albums"
+#~ msgstr "Album"
+
+#, fuzzy
+#~ msgid "Copac"
+#~ msgstr "Virgola"
+
+#~ msgid "Tellico"
+#~ msgstr "Tellico"
+
+#~ msgid "&Copy Entry"
+#~ msgstr "&Copia elemento"
+
+#~ msgid "&Copy Entries"
+#~ msgstr "&Copia elementi"
+
+#, fuzzy
+#~ msgid "<qt>Multiple records were found to match the CD.</qt>"
+#~ msgstr "<qt>Ho trovato diversi elementi da confrontare con il CD.</qt>"
+
+#~ msgid "Remo&ve"
+#~ msgstr "Rimuo&vi"
+
+#~ msgid "Scanning CDDB cache files..."
+#~ msgstr "Scansione dei file di cache CDDB ..."
+
+#~ msgid "Collection &type: "
+#~ msgstr "&tipo di collezione: "
+
+#~ msgid "Save Entries"
+#~ msgstr "Salva elementi"
+
+#~ msgid ""
+#~ "_: Save (Entry Title)\n"
+#~ "Save %1"
+#~ msgstr "Salva %1"
+
+#~ msgid ""
+#~ "Tellico currently supports five source types: Amazon.com, IMDB, z39.50, "
+#~ "Entrez, and external applications."
+#~ msgstr ""
+#~ "Tellico attualmente supporta cinque tipi di fonti: Amazon.com, IMDB, z39.50, "
+#~ "Entrez e l'uso di programmi esterni."
+
+#~ msgid "Enable/disable the statusbar"
+#~ msgstr "Abilita/disabilita la barra di stato"
+
+#~ msgid ""
+#~ "The password will be saved in plain text in the Tellico configuration file."
+#~ msgstr ""
+#~ "La password verrà salvata in chiaro nel file di configurazione di Tellico."
+
+#, fuzzy
+#~ msgid "Reading files..."
+#~ msgstr "Sto salvando il file ..."
+
+#~ msgid ""
+#~ "<p>...that you can rename a collection by right-clicking on\n"
+#~ "the top collection item in the left column.</p>\n"
+#~ msgstr ""
+#~ "<p>... che puoi rinominare una collezione clickando con il tasto destro sul "
+#~ "primo elemento\n"
+#~ " in alto nella colonna di sinistra.</p>\n"
+
+#, fuzzy
+#~ msgid "S&earch:"
+#~ msgstr "Cerca in:"
+
+#, fuzzy
+#~ msgid "Group by:"
+#~ msgstr "Raggruppa per:"
+
+#, fuzzy
+#~ msgid "Quick filter:"
+#~ msgstr "Filtro rapido:"
+
+#~ msgid "Filter Entry"
+#~ msgstr "Filtra elemento"
+
+#, fuzzy
+#~ msgid "Tellico: %1 is due to return %2"
+#~ msgstr "Impossibile leggere il file - %1."
+
+#~ msgid "Find Text"
+#~ msgstr "Trova testo"
+
+#~ msgid "&Find"
+#~ msgstr "&Trova"
+
+#, fuzzy
+#~ msgid "Find"
+#~ msgstr "&Trova"
+
+#~ msgid "&Text to find:"
+#~ msgstr "Testo da trovare:"
+
+#~ msgid "The search string"
+#~ msgstr "La stringa da ricercare"
+
+#~ msgid "As regular e&xpression"
+#~ msgstr "Come Espressione &Regolare"
+
+#~ msgid "If checked, the search string is used as a regular expression."
+#~ msgstr ""
+#~ "Se selezionato, la stringa inserita viene cercata come espressione regolare."
+
+#, fuzzy
+#~ msgid "&Edit Regular Expression..."
+#~ msgstr "&Edita espressione regolare ..."
+
+#, fuzzy
+#~ msgid "Field"
+#~ msgstr "Campi"
+
+#~ msgid "Search in:"
+#~ msgstr "Cerca in:"
+
+#~ msgid "Select which field should be searched."
+#~ msgstr "Seleziona in quale campo eseguire la ricerca."
+
+#~ msgid "C&ase sensitive"
+#~ msgstr "C&ase sensitive"
+
+#~ msgid "If checked, the search is case-sensitive."
+#~ msgstr "Se selezionato, la ricerca distingue tra maiuscole e minuscole."
+
+#~ msgid "Find &backwards"
+#~ msgstr "Trova &Indietro"
+
+#~ msgid "If checked, the document is searched in reverse."
+#~ msgstr ""
+#~ "Se selezionato, la ricerca procede dalla fine all'inizio del documento."
+
+#~ msgid "&Whole words only"
+#~ msgstr "S&olo parole intere"
+
+#~ msgid "If checked, the search is limited to whole words."
+#~ msgstr "Se selezionato, la ricerca si limita alle parole intere."
+
+#~ msgid "All Fields"
+#~ msgstr "Tutti i campi"
+
+#~ msgid "Invalid regular expression."
+#~ msgstr "Espressione regolare non valida."
+
+#~ msgid "5 - Best"
+#~ msgstr "5 - Bellissimo"
+
+#~ msgid "4 - Good"
+#~ msgstr "4 - Bello"
+
+#~ msgid "3 - Neutral"
+#~ msgstr "3 - Insomma..."
+
+#~ msgid "2 - Bad"
+#~ msgstr "2 - Brutto"
+
+#~ msgid "1 - Worst"
+#~ msgstr "1 - Pessimo"
+
+#~ msgid "Table (2 Columns)"
+#~ msgstr "Tabella (2 Colonne)"
+
+#, fuzzy
+#~ msgid "Delete Entry?"
+#~ msgstr "&Cancella Elemento"
+
+#~ msgid "Warning!"
+#~ msgstr "Attenzione!"
+
+#~ msgid "(grouped by %1; sorted by %2)"
+#~ msgstr "(Raggruppa per %1; ordinato per %2)"
+
+#~ msgid "(sorted by %1)"
+#~ msgstr "(ordina per %1)"
+
+#~ msgid ""
+#~ "<qt><p>Do you really want to delete the <em>%1</em> field? This action "
+#~ "occurs immediately and can not be undone!</p></qt>"
+#~ msgstr ""
+#~ "<qt><p>Vuoi davvero cancellare il campo <em>%1</em>? Questa azione non può "
+#~ "essere annullata!</p></qt>"
+
+#~ msgid "Sort by Group, Ascending"
+#~ msgstr "Ordine ascendente per gruppo, "
+
+#~ msgid "Sort by Group, Descending"
+#~ msgstr "Ordine discendente per gruppo"
+
+#~ msgid "Sort by Count, Ascending"
+#~ msgstr "Ordine ascendente per conteggio"
+
+#~ msgid "Sort by Count, Descending"
+#~ msgstr "Ordine discendente per conteggio"
+
+#~ msgid "Search the collection"
+#~ msgstr "Ricerca la collezione"
+
+#~ msgid "Find next match in the collection"
+#~ msgstr "Trova la prossima corrispondenza nella collezione"
+
+#, fuzzy
+#~ msgid "Reports"
+#~ msgstr "&Esporta"
+
+#~ msgid "Show number of items in group"
+#~ msgstr "Mostra il numero degli oggetti nel gruppo"
+
+#~ msgid ""
+#~ "If checked, the number of items in the group will be appended to the group "
+#~ "name."
+#~ msgstr ""
+#~ "Se selezionato, il numero di oggetti nel gruppo viene allegato al nome del "
+#~ "gruppo."
+
+#~ msgid "Search string '%1' not found."
+#~ msgstr "Stringa '%1' non trovata."
+
+#~ msgid "Video"
+#~ msgstr "Video"
+
+#, fuzzy
+#~ msgid "*.bc .tc|Tellico files (*.tc)"
+#~ msgstr "*.tc *.bc|File di Tellico (*.tc)"
+
+#~ msgid "&From Beginning"
+#~ msgstr "&Dall'inizio"
+
+#~ msgid "If checked, the document is searched from the beginning."
+#~ msgstr "Se selezionato, la ricerca comincia dall'inizio del documento."
+
+#~ msgid "Path to LyX server:"
+#~ msgstr "Percorso per il server LyX:"
+
+#~ msgid ""
+#~ "<qt>The location of the LyX server for citing bibliographic entries. Also "
+#~ "used by other applications such as Kile or Pybliographer. Do not include the "
+#~ "trailing .in suffix.</qt>"
+#~ msgstr ""
+#~ "<qt>L'ubicazione del server LyX per citare elementi bibliografici. È anche "
+#~ "usata da altre applicazioni come Kile o Pybliographer. Non includere il "
+#~ "suffisso .in</qt>"
+
+#, fuzzy
+#~ msgid "<qt>Tellico was unable to open the CD-ROM device - <i>%1</i>.</qt>"
+#~ msgstr ""
+#~ "<qt>Tellico non riesce a scrivere sulla server pipe in <b>%1</b>.</qt>"
+
+#~ msgid "Do you really want to modify these books?"
+#~ msgstr "Vuoi davvero modificare questi libri?"
+
+#~ msgid "*.ogg|Ogg files (*.ogg)"
+#~ msgstr "*.ogg|file Ogg (*.ogg)"
+
+#~ msgid ""
+#~ "<qt>The type of the field determines what values may be used. <i>Simple "
+#~ "Text</i> is used for most fields. <i>Paragraph</i> is for large text blocks. "
+#~ "<i>Choice</i> limits the field to certain values. <i>Checkbox</i> is for a "
+#~ "simple yes/no value. <i>Number</i> indicates that the field contains a "
+#~ "numerical value. <i>URL</i> is for fields which refer to URLs, including "
+#~ "references to other files. <i>Table</i>s may be a single or double column of "
+#~ "values, while <i>Read Only</i> is for internal values, possibly useful for "
+#~ "import and export. A <i>Dependent</i> field depends on the values of other "
+#~ "fields, and is formatted according to the field description. An <i>Image</i> "
+#~ "holds a picture.</qt>"
+#~ msgstr ""
+#~ "<qt>Il tipo di campo determina quali valori possono esservi inseriti. "
+#~ "<i>Testo semplice</i> è utilizzato per la gran parte dei campi. "
+#~ "<i>Paragrafo</i> è utilizzato per ampi blocchi di testo. <i>Scelta</i> "
+#~ "Permette di inserire nel campo solo alcuni valori. <i>Checkbox</i> permette "
+#~ "di inserire solo sì o no. <i>Numero</i> indica che il campo può contenere "
+#~ "solo un valore numerico. <i>URL</i> serve per i campi che contengono "
+#~ "riferimenti ipertestuali, inclusi riferimenti ad altri file. <i>Tabella</i> "
+#~ "può essere uina colonna o una doppia colonna di valori, mentre <i>Sola "
+#~ "lettura</i> serve per valori interni, utili per l'importazione e "
+#~ "l'esportazione di file. Un campo <i>Dipendente</i> dipende dai valori di "
+#~ "altri campi ed è creato secondo la descrizione del campo. Un campo "
+#~ "<i>Immagine</i> contiene una figura</qt>"
+
+#, fuzzy
+#~ msgid "Export images"
+#~ msgstr "Esporta immagini"
+
+#~ msgid "List"
+#~ msgstr "Lista"
+
+#~ msgid "(Requires restart)"
+#~ msgstr "(�necessario riavviare il programma)"
+
+#~ msgid ""
+#~ "A comma-separated list of suffixes which might be used in personal names."
+#~ msgstr ""
+#~ "Un elenco di parole separate da virgole da usare nei nomi di persona."
+
+#~ msgid "A comma-separated list of prefixes which might be used in surnames."
+#~ msgstr "Un elenco di parole separate da virgole da usare nei cognomi."
+
+#~ msgid "Enable/disable the toolbar"
+#~ msgstr "Abilita/disabilita la barra degli strumenti"
+
+#~ msgid "Show Co&llection ToolBar"
+#~ msgstr "Mostra la barra degli strumenti-co&llezione"
+
+#~ msgid "Enable/disable the collection toolbar"
+#~ msgstr "Abilita/disabilita la barra degli strumenti-collezione"
+
+#~ msgid "Tip of the &Day"
+#~ msgstr "Consiglio &del giorno"
+
+#~ msgid "Show the \"Tip of the Day\" dialog..."
+#~ msgstr "Mostra la finestra del \"consiglio del giorno\" ..."
+
+#~ msgid "*.bcz|Tellico files(*.bcz)"
+#~ msgstr "*.bcz|File di Tellico (*.bcz)"
+
+#, fuzzy
+#~ msgid "Good"
+#~ msgstr "4 - Bello"
+
+#~ msgid ""
+#~ "An article is from a journal or magazine. A book has an explicit publisher, "
+#~ "while a booklet does not."
+#~ msgstr ""
+#~ "Un articolo è parte di una rivista o di un giornale. Un libro riporta "
+#~ "l'indicazione di un editore, mentre un libretto no."
+
+#, fuzzy
+#~ msgid "Mint"
+#~ msgstr "Mese"
+
+#, fuzzy
+#~ msgid "Fine"
+#~ msgstr "Trova:"
+
+#, fuzzy
+#~ msgid "New Entry"
+#~ msgstr "&Nuovo Elemento"
+
+#~ msgid "Copying selection to clipboard..."
+#~ msgstr "Sto copiando ..."
+
+#~ msgid "Inserting clipboard contents..."
+#~ msgstr "Sto incollando ..."
+
+#~ msgid "Toggling toolbar..."
+#~ msgstr "Sto modificando la barra degli strumenti ..."
+
+#~ msgid "Toggling collection toolbar..."
+#~ msgstr "Sto modificando la barra degli strumenti-collezione ..."
+
+#~ msgid "Toggle the statusbar..."
+#~ msgstr "Sto modificando la barra di stato ..."
+
+#~ msgid "Tellico is unable to find a required file - %1.\n"
+#~ msgstr "Impossibile trovare un file necessario - %1.\n"
+
+#~ msgid "Editing string macros..."
+#~ msgstr "Sto editando le string macros ..."
+
+#~ msgid "&New Collection"
+#~ msgstr "&Nuova Collezione"
+
+#~ msgid "TextImporter"
+#~ msgstr "TextImporter"
+
+#~ msgid "XSLTImporter"
+#~ msgstr "XSLTImporter"
+
+#~ msgid "CSVImporter"
+#~ msgstr "CSVImporter"
+
+#~ msgid "BibtexImporter"
+#~ msgstr "BibtexImporter"
+
+#~ msgid ""
+#~ "Both the macro and the string can be edited by triple-clicking the item."
+#~ msgstr ""
+#~ "Sia la macro che la stringa possono essere modificate con tre click "
+#~ "sull'oggetto."
+
+#~ msgid ""
+#~ "The description is useful reminder of what information is contained in the "
+#~ "field."
+#~ msgstr ""
+#~ "La descrizione è utile per ricordare quale informazione è contenuta nei "
+#~ "campi."
+
+#~ msgid "Bibtex Field Name:"
+#~ msgstr "Campo Nome-Bibtex:"
+
+#~ msgid ""
+#~ "The Bibtex field name determines the entry name for exporting to "
+#~ "bibliogrgaphy files."
+#~ msgstr ""
+#~ "Il campo Nome-Bibtex determina i nomi degli lementi per l'esportazione su "
+#~ "file di bibliografia."
+
+#, fuzzy
+#~ msgid "Processing new entries..."
+#~ msgstr "Sto processando il documento ..."
+
+#, fuzzy
+#~ msgid "If checked, the first row is used as field headers."
+#~ msgstr ""
+#~ "Se selezionato, i nomi di campo saranno stampati come headers della tabella."
+
+#, fuzzy
+#~ msgid "Collection Field in this Column:"
+#~ msgstr "Opzioni per la collezione di audio"
+
+#~ msgid "Tellico is unable to find the file - %1."
+#~ msgstr "Impossibile trovare il file - %1."
+
+#~ msgid "Tellico is unable to download the file - %1."
+#~ msgstr "Impossibile scaricare il file - %1."
+
+#~ msgid "The collection is grouped by this field."
+#~ msgstr "La collezione viene ordinata secondo questo campo"
+
+#~ msgid "These are the available fields in the collection."
+#~ msgstr "Questi sono i campi disponibili per la collezione"
+
+#~ msgid "Selected Fields"
+#~ msgstr "Campi selezionati"
+
+#, fuzzy
+#~ msgid "Import..."
+#~ msgstr "In stampa ..."
+
+#, fuzzy
+#~ msgid "Read Only"
+#~ msgstr "Pronto."
+
+#, fuzzy
+#~ msgid "Text"
+#~ msgstr "Trova testo"
+
+#, fuzzy
+#~ msgid "Enoding Options"
+#~ msgstr "Raggruppamento"
+
+#, fuzzy
+#~ msgid "Edit Collection Fields..."
+#~ msgstr "Chiusura ..."
+
+#, fuzzy
+#~ msgid "&Create new collection"
+#~ msgstr "Crea un nuovo documento"
+
+#, fuzzy
+#~ msgid "*.txt|Text files (*.txt)"
+#~ msgstr "*.xsl|file XSLT (*.xsl)"
+
+#~ msgid "New Book"
+#~ msgstr "Nuovo libro"
+
+#, fuzzy
+#~ msgid "Modify Books"
+#~ msgstr "Modifica libro"
+
+#, fuzzy
+#~ msgid "Delete Books"
+#~ msgstr "Cancella libro"
+
+#~ msgid "Group Books By"
+#~ msgstr "Raggruppa libri per"
+
+#~ msgid "Configure the options for the application..."
+#~ msgstr "Configura le opzioni di Tellico ..."
+
+#~ msgid "Importing from Bibtex..."
+#~ msgstr "Sto importando da bibtex ..."
+
+#~ msgid "Import from Bibtex..."
+#~ msgstr "Sto importando da bibtex ..."
+
+#~ msgid "Importing from Bibtexml..."
+#~ msgstr "Sto importando da bibtexml ..."
+
+#~ msgid "Song"
+#~ msgstr "Canzone"
+
+#~ msgid "CD"
+#~ msgstr "CD"
+
+#~ msgid "Clear Data"
+#~ msgstr "Cancella dati"
+
+#~ msgid ""
+#~ "*.tc *.bc|Tellico files (*.tc)\n"
+#~ "*.xml|XML files (*.xml)\n"
+#~ "*|All files"
+#~ msgstr ""
+#~ "*.tc *.bc|file di Tellico (*.tc)\n"
+#~ "*.xml|file XML (*.xml)\n"
+#~ "*|tutti i file"
+
+#, fuzzy
+#~ msgid "Unable to upload file - %1."
+#~ msgstr "Impossibile scaricare il file - %1."
+
+#, fuzzy
+#~ msgid "Unable to write file - %1."
+#~ msgstr "Impossibile leggere il file - %1."
+
+#~ msgid ""
+#~ "Unable to find a file needed for printing - %1.\n"
+#~ "Please check your installation."
+#~ msgstr ""
+#~ "Impossibile trovare un file necessario per la stampa - %1.\n"
+#~ "Controlla la tua installazione, grazie."
+
+#, fuzzy
+#~ msgid "Unable to find file - %1."
+#~ msgstr "Impossibile aprire il file - %1."
+
+#~ msgid "Unable to download file - %1."
+#~ msgstr "Impossibile scaricare il file - %1."
+
+#~ msgid "Unable to open file - %1."
+#~ msgstr "Impossibile aprire il file - %1."
+
+#~ msgid "Unable to read file - %1."
+#~ msgstr "Impossibile leggere il file - %1."
+
+#~ msgid "File is not in XML format - %1."
+#~ msgstr "Il file non ha l'aspetto di un file XML -%1."
+
+#, fuzzy
+#~ msgid "Unable to load file - %1."
+#~ msgstr "Impossibile scaricare il file - %1."
+
+#, fuzzy
+#~ msgid "File has no syntax version - %1."
+#~ msgstr "Il file non ha l'aspetto di un file XML -%1."
+
+#~ msgid "8mm"
+#~ msgstr "8mm"
+
+#~ msgid "LaserDisc"
+#~ msgstr "LaserDisc"
+
+#~ msgid "Betamax"
+#~ msgstr "Beta"
+
+#~ msgid "CDs"
+#~ msgstr "CD"
+
+#~ msgid "%1 %2"
+#~ msgstr "%1 %2"
+
+#, fuzzy
+#~ msgid ""
+#~ "Unable to find a required file - %1.\n"
+#~ "Please check your installation."
+#~ msgstr ""
+#~ "Impossibile trovare un file necessario per la stampa - %1.\n"
+#~ "Controlla la tua installazione, grazie."
+
+#~ msgid "(None)"
+#~ msgstr "(Nessuno)"
+
+#~ msgid "Full Contents"
+#~ msgstr "Intero contenuto"
+
+#~ msgid "Creates a full report"
+#~ msgstr "Crea un report completo"
+
+#~ msgid "Unable to find %1 in standard KDE directories."
+#~ msgstr "Impossibile trovare %1 nelle directory standard di KDE."
+
+#~ msgid "Show Browse Toolbar"
+#~ msgstr "Mostra la barra di navigazione"
diff --git a/po/nb.po b/po/nb.po
new file mode 100644
index 0000000..b49208e
--- /dev/null
+++ b/po/nb.po
@@ -0,0 +1,6012 @@
+# translation of nb.po to Norsk bokmål
+# This file is distributed under the same license as the Tellico package.
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+# First translation by Leif Mathis Gaup <lmgaup@nsn.no>, 2003, 2004.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: nb\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2004-12-03 17:17+0100\n"
+"Last-Translator: Leif Mathis Gaup <lmgaup@nsn.no>\n"
+"Language-Team: Norsk bokmål\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Report-Msgid-Bugs-To: \n"
+"X-Generator: KBabel 1.9.1\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "<qt>Tellico klarer ikke å skrive til tjeneren på <b>%1</b>.</qt>."
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr ""
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr ""
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+
+#: cite/openoffice.cpp:191
+#, fuzzy
+msgid "Pipe"
+msgstr "Personer"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:181
+#, fuzzy
+msgid "Rename Column"
+msgstr "Gi samling nytt navn"
+
+#: gui/tablefieldwidget.cpp:181
+#, fuzzy
+msgid "New column name:"
+msgstr "Nytt navn på samling"
+
+#: gui/tablefieldwidget.cpp:206
+#, fuzzy, c-format
+msgid "Column %1"
+msgstr "Kolonne:"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+#, fuzzy
+msgid "Rename Column..."
+msgstr "Gi samling nytt navn..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:276
+#, fuzzy
+msgid "Remove Row"
+msgstr "Fjern"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:295
+#, fuzzy
+msgid "Clear Table"
+msgstr "Slett felt?"
+
+#: gui/previewdialog.cpp:27
+#, fuzzy
+msgid "Template Preview"
+msgstr "Mal"
+
+#: gui/stringmapdialog.cpp:57
+#, fuzzy
+msgid "&Set"
+msgstr "Sett"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr ""
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Flere"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Færre"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Rens"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Velg bilde..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr ""
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr ""
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, fuzzy, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr ""
+"Slett felt\n"
+"Slett"
+
+#: commands/collectioncommand.cpp:110
+#, fuzzy
+msgid "Append Collection"
+msgstr "Gi samling nytt navn"
+
+#: commands/collectioncommand.cpp:112
+#, fuzzy
+msgid "Merge Collection"
+msgstr "Min samling"
+
+#: commands/collectioncommand.cpp:114
+#, fuzzy
+msgid "Replace Collection"
+msgstr "Gi samling nytt navn"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+#, fuzzy
+msgid "Modify Entries"
+msgstr "Endre innslag"
+
+#: commands/fieldcommand.cpp:104
+#, fuzzy
+msgid "Add %1 Field"
+msgstr "Uansett felt"
+
+#: commands/fieldcommand.cpp:106
+#, fuzzy
+msgid "Modify %1 Field"
+msgstr "Hurtigfilter:"
+
+#: commands/fieldcommand.cpp:108
+#, fuzzy
+msgid "Delete %1 Field"
+msgstr "Slett felt?"
+
+#: commands/addentries.cpp:50
+#, fuzzy
+msgid "Add Entries"
+msgstr "Endre innslag"
+
+#: commands/addentries.cpp:51
+#, fuzzy, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr ""
+"Slett felt\n"
+"Slett"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Gi samling nytt navn"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+#, fuzzy
+msgid "Modify Loan"
+msgstr "Endre bok"
+
+#: commands/filtercommand.cpp:98
+#, fuzzy
+msgid "Add Filter"
+msgstr "Avansert filter"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+#, fuzzy
+msgid "Modify Filter"
+msgstr "Hurtigfilter:"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+#, fuzzy
+msgid "Delete Filter"
+msgstr "Slett felt?"
+
+#: commands/addloans.cpp:108
+#, fuzzy
+msgid "Check-out Items"
+msgstr "Kopier valgte innslag"
+
+#: commands/addloans.cpp:109
+#, fuzzy, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr ""
+"Slett felt\n"
+"Slett"
+
+#: commands/removeentries.cpp:48
+#, fuzzy
+msgid "Delete Entries"
+msgstr "Slett innslag"
+
+#: commands/removeentries.cpp:49
+#, fuzzy, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr ""
+"Slett felt\n"
+"Slett"
+
+#: commands/reorderfields.cpp:54
+#, fuzzy
+msgid "Reorder Fields"
+msgstr "Gjeldende felter"
+
+#: commands/removeloans.cpp:79
+#, fuzzy
+msgid "Check-in Entries"
+msgstr "Avkrysningsboks"
+
+#: commands/removeloans.cpp:80
+#, fuzzy, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr ""
+"Slett felt\n"
+"Slett"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Hovedvalg"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Tilstand"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Personlig"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Mine frimerker"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Tittel"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Beskrivelse"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Denominering"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "Land"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Utsendelsesår"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Farge"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Scott#"
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr "Perfekt,Ekstremt fin, Veldig fin,Fin,Gjennomsnittlig,Dårlig"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Gradering"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Kansellert"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Hengslet"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Sentrering"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Limt fast"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Innkjøpsdato"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Innkjøpspris"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Lokalisering"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Gave"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Bilde"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Kommentar"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Utgivelse"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Klassifisering"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Mine tegneserier"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Undertittel"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Forfatter"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Serie"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Nummer"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Utgiver"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Utgave"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Utgivelsesår"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Sider"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Språk"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Sjanger"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Nøkkelord"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr ""
+"Perfekt,Som ny - uten feil,Nydelig,Fin,Helt OK,Godt brukt,Slitt,Elendig"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Signert"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Lånt"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Forside"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Mine mynter"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Type"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "År"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Myntslag"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Myntsett"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr "PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Graderingstjeneste"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Obvers"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Revers"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Mine bøker"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Forfatter"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Stivt omslag"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Papprygg"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Papirrygg"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "Elektronisk bok"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Blad"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Hefte"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Omslag"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Kopirettsår"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Internasjonalt Standard Bok Nummer"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Library of Congress Control Number"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr ""
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Serienummer"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Ny"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Brukt"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Lest"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Karakter"
+
+#: collections/filecatalog.cpp:25
+#, fuzzy
+msgid "My Files"
+msgstr "Mine viner"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+#, fuzzy
+msgid "Name"
+msgstr "Nummer"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Antall"
+
+#: collections/filecatalog.cpp:55
+#, fuzzy
+msgid "Folder"
+msgstr "Filtrer innslag"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr ""
+
+#: collections/filecatalog.cpp:65
+#, fuzzy
+msgid "Size"
+msgstr "Signert"
+
+#: collections/filecatalog.cpp:69
+#, fuzzy
+msgid "Permissions"
+msgstr "Person"
+
+#: collections/filecatalog.cpp:74
+#, fuzzy
+msgid "Owner"
+msgstr "Annet"
+
+#: collections/filecatalog.cpp:79
+#, fuzzy
+msgid "Group"
+msgstr "Grupper på: "
+
+#: collections/filecatalog.cpp:85
+#, fuzzy
+msgid "Created"
+msgstr "CD"
+
+#: collections/filecatalog.cpp:89
+#, fuzzy
+msgid "Modified"
+msgstr "Hurtigfilter:"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Egenskap"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Verdi"
+
+#: collections/filecatalog.cpp:99
+#, fuzzy
+msgid "Icon"
+msgstr "Ikoner"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Mine viner"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Produsent"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Appellasjon"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Varietal"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Årgang"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Rødvin"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Hvitvin"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Musserende vin"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Kvantitet"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Drikkes med"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Etikettbilde"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Andre personer"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Egenskaper"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Mine Videofilmer"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr ""
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+#, fuzzy
+msgid "HD DVD"
+msgstr "DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Media"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Produksjonsår"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "7 (Norge),10 (Norge),15 (Norge),18 (Norge)"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Ratifisering"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Region 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Region 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Region 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Region 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Region 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Region 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Region 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Region 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Region"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Nasjonalitet"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Format"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Besetning"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr ""
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+#, fuzzy
+msgid "Role"
+msgstr "Antall"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr "En liste over personer med i filmen og hvilken rolle de spiller"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Regissør"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Komponist"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Studio"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Språkspor"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Språk for undertittel"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Lydspor"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Varighet"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "Varigheten på filmen (i minutter)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Visningsforhold"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Bredskjerm"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Svart-hvitt"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Fargemodus"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Regissørens kutt"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Sammendrag av handlingen"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Personlig karakter"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Omslag"
+
+#: collections/gamecollection.cpp:26
+#, fuzzy
+msgid "My Games"
+msgstr "Mine frimerker"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr ""
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+#, fuzzy
+msgid "Nintendo Wii"
+msgstr "Region"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+#, fuzzy
+msgid "GameCube"
+msgstr "Nummer"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr ""
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr ""
+
+#: collections/gamecollection.cpp:47
+#, fuzzy
+msgid "Game Boy Color"
+msgstr "Gi samling nytt navn"
+
+#: collections/gamecollection.cpp:47
+#, fuzzy
+msgid "Game Boy"
+msgstr "Nummer"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr ""
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr ""
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr ""
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+#, fuzzy
+msgid "Release Year"
+msgstr "Utsendelsesår"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Utgiver"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr ""
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+
+#: collections/gamecollection.cpp:82
+#, fuzzy
+msgid "ESRB Rating"
+msgstr "Karakter"
+
+#: collections/gamecollection.cpp:95
+#, fuzzy
+msgid "Completed"
+msgstr "CD"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Mine kort"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Spiller"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Lag"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Merke"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Kortnummer"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Korttype"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Bilde av forside"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Bilde av bakside"
+
+#: collections/boardgamecollection.cpp:26
+#, fuzzy
+msgid "My Board Games"
+msgstr "Mine frimerker"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:72
+#, fuzzy
+msgid "Number of Players"
+msgstr "antall innslag: %1"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Bibliografi"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Innslagstype"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+"Disse innslagsverdiene er spesifikke for Bibtex. Se dokumentasjon for bibtex."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Bibtex-nøkkel"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Boktittel"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Redaktør"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organisasjon"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Addresse"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Måned"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Nummer"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Publiseringsmåte"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Kapittel"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Kryssreferanse"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Abstrakt"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Notat"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Min musikk"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Album"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "CD"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Kassett"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Vinyl"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Artist"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Plateselskap"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Spor"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr ""
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr "en,ei,et,i,av,den,det,de,til,fra"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "den"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr,Sr,"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "van,von"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 tillater ikke søk for samlinger av denne typen."
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Resultater fra %1: %2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "Denne kilden har ingen valgmuligheter."
+
+#: fetch/entrezfetcher.cpp:56
+#, fuzzy
+msgid "Entrez Database"
+msgstr "Internet filmdatabase (IMDB)"
+
+#: fetch/entrezfetcher.cpp:485
+#, fuzzy
+msgid "Institution"
+msgstr "Tilstand"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Feil i spørringen"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Feil i søkeforbindelsen %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr ""
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Forbindelsesfeil %1: %2"
+
+#: fetch/srufetcher.cpp:72
+#, fuzzy
+msgid "SRU Server"
+msgstr "Tilbakestill"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Library of Congress (USA)"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+#, fuzzy
+msgid "Hos&t: "
+msgstr "Vert"
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+#, fuzzy
+msgid "Enter the host name of the server."
+msgstr "Skriv inn navn på tjeneren for z30.50-tjenesten."
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "Port:"
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, fuzzy, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Skriv inn portnummer for z39.50-tjeneren. Standardport er%1."
+
+#: fetch/srufetcher.cpp:450
+#, fuzzy
+msgid "Path: "
+msgstr "Port:"
+
+#: fetch/srufetcher.cpp:455
+#, fuzzy
+msgid "Enter the path to the database used by the server."
+msgstr "Skriv inn databasenavnet brukt av z39.50-tjeneren."
+
+#: fetch/srufetcher.cpp:460
+#, fuzzy
+msgid "Format: "
+msgstr "Format"
+
+#: fetch/srufetcher.cpp:468
+#, fuzzy
+msgid "Enter the result format used by the server."
+msgstr "Skriv inn databasenavnet brukt av z39.50-tjeneren."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "Omslagsbilde kunne ikke lastes."
+
+#: fetch/amazonfetcher.cpp:53
+#, fuzzy
+msgid "Amazon Link"
+msgstr "Amazon (Japan)"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (USA)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (UK)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Tyskland)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japan)"
+
+#: fetch/amazonfetcher.cpp:74
+#, fuzzy
+msgid "Amazon (France)"
+msgstr "Amazon (Tyskland)"
+
+#: fetch/amazonfetcher.cpp:77
+#, fuzzy
+msgid "Amazon (Canada)"
+msgstr "Amazon (Japan)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Amazon.coms nettjenester"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "Land"
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "USA"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Storbritania"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Tyskland"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Japan"
+
+#: fetch/amazonfetcher.cpp:855
+#, fuzzy
+msgid "France"
+msgstr "Bueparanteser"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon.com tilbyr data fra flere lokaliserte steder. Velg ett sted du vil "
+"bruke som datakilde."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "Bildestørrelse:"
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Lite bilde"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Medium bilde"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Stort bilde"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Ingen bilder"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"Omslagsbildet kan også lastes ned. Bemerk at for mange store bilder i "
+"samlingen kan føre til dårligere ytelse."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "Tilknytt ID:"
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+"Tilknytning av ID identifiserer personen som aksesserer nettjenesten til "
+"Amazon.com, og er inkludert i lenker for Amazon.coms nettsted."
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+#, fuzzy
+msgid "z39.50 Server"
+msgstr "z39.50"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "Database:"
+
+#: fetch/z3950fetcher.cpp:530
+#, fuzzy
+msgid "Enter the database name used by the server."
+msgstr "Skriv inn databasenavnet brukt av z39.50-tjeneren."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "Tegnsett:"
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Skriv inn tegnsettet brukt av z39.50-tjeneren. Det mest sannsynlige valget "
+"er MARC-8, selc om SIO-8859-1 også er vanlig."
+
+#: fetch/z3950fetcher.cpp:550
+#, fuzzy
+msgid "&Format: "
+msgstr "Format"
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "Bruker:"
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+#, fuzzy
+msgid "Optional"
+msgstr "Valg for CSV"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Skriv inn autentifiseringsnavnet brukt av z39.50-tjeneren. De fleste "
+"tjenerene trenger ikke dette."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "Passord:"
+
+#: fetch/z3950fetcher.cpp:586
+#, fuzzy
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Skriv inn passord for autentifisering. De fleste tjenerene trenger ikke "
+"dette."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:82
+#, fuzzy
+msgid "External Application"
+msgstr "Avslutt"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "Samlingstype"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:370
+#, fuzzy
+msgid "Application &path: "
+msgstr "Appellasjon"
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+#, fuzzy
+msgid "Update"
+msgstr "Sit&er innslag"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Valg for kilde"
+
+#: fetch/configwidget.cpp:40
+#, fuzzy
+msgid "Available Fields"
+msgstr "Tilgjengelige felter"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "Internet filmdatabase (IMDB)"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Velg resultat fra IMDB"
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr "<qt>Ditt søk returnerte flere treff. Vennligst velg ett treff.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Velg ett søkeresultat.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Alternative titler"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+#, fuzzy
+msgid "IMDB Rating"
+msgstr "Karakter"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Sertifiseringer"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"Internett filmdatabasen (IMDB) benytter seg av flere forskjellige tjenere. "
+"Velg den du ønsker å benytte."
+
+#: fetch/imdbfetcher.cpp:1132
+#, fuzzy
+msgid "&Maximum cast: "
+msgstr "Maks bredde på bilder:"
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+#, fuzzy
+msgid "Download cover &image"
+msgstr "Last ned omslagsbilde"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Person"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN-nummer"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Nøkkelord"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Forespørsel:"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:264
+#, fuzzy
+msgid "Distributor"
+msgstr "Regissør"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr ""
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:343
+#, fuzzy
+msgid "&Username: "
+msgstr "Bruker:"
+
+#: fetch/crossreffetcher.cpp:348
+#, fuzzy
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+"Skriv inn passord for autentifisering. De fleste tjenerene trenger ikke "
+"dette."
+
+#: fetch/crossreffetcher.cpp:354
+#, fuzzy
+msgid "&Password: "
+msgstr "Passord:"
+
+#: fetch/gcstarpluginfetcher.cpp:190
+#, fuzzy
+msgid "GCstar Plugin"
+msgstr "GCstar"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:420
+#, fuzzy
+msgid "Author: "
+msgstr "Forfatter"
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr ""
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr ""
+
+#: newstuff/dialog.cpp:114
+#, fuzzy
+msgid "Version"
+msgstr "Person"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr ""
+
+#: newstuff/dialog.cpp:117
+#, fuzzy
+msgid "Release Date"
+msgstr "Utsendelsesår"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+
+#: newstuff/dialog.cpp:137
+#, fuzzy
+msgid "The name and license of the selected item"
+msgstr "Kopier valgte innslag"
+
+#: newstuff/dialog.cpp:140
+#, fuzzy
+msgid "The author of the selected item"
+msgstr "Kopier valgte innslag"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr ""
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr ""
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+
+#: newstuff/dialog.cpp:194
+#, fuzzy
+msgid "A description of the selected item is shown here."
+msgstr "Kopier valgte innslag"
+
+#: newstuff/dialog.cpp:224
+#, fuzzy
+msgid "Downloading information..."
+msgstr "Importer informasjon om CD fra FreeDB"
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Klar."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr ""
+
+#: newstuff/dialog.cpp:413
+#, fuzzy
+msgid "Installing item..."
+msgstr "Lagrer filen..."
+
+#: translators/bibteximporter.cpp:79
+#, fuzzy
+msgid "No valid bibtex entries were found"
+msgstr "Ingen gyldig Bibtex-innslag ble funnet i filen - %1"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "Ingen gyldig Bibtex-innslag ble funnet i filen - %1"
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Valg for Bibtex"
+
+#: translators/bibteximporter.cpp:287
+#, fuzzy
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Tegnsettet Unicode (UTF-8)"
+
+#: translators/bibteximporter.cpp:288
+#, fuzzy
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Eksporter filen i tegnsettet Unicode (UTF-8)."
+
+#: translators/bibteximporter.cpp:289
+#, fuzzy
+msgid "Use user locale (%1) encoding"
+msgstr "Bruk ditt systems tegnsett (%1)"
+
+#: translators/bibteximporter.cpp:293
+#, fuzzy
+msgid "Read the imported file in the local encoding."
+msgstr "Eksporter filen i ditt lokale tegnsett."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "Tellico zipfil"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+#, fuzzy
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Tellico filer (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+#, fuzzy
+msgid "*|All Files"
+msgstr "*|Alle filer"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>Ett Alexandria bibliotek som heter <i>%1</i> eksisterer allerede. "
+"Eksisterende bøker i biblioteket kan bli overskrevet.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "Det er en XML sammenflettingsfeil på linje %1, kolonne %2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "Feilmeldingen fra QT er:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Denne er fra en fremtidig versjon Tellico"
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Tellico konverterer filen til et nyere format. Informasjonstap kan opptre om "
+"en eldre versjon av Tellico blir brukt til å lese denne filen senere."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Ukjent"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "Filer er tom."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "Filen inneholder ingen data for samling."
+
+#: translators/tellicoimporter.cpp:940
+#, fuzzy
+msgid "Unread Books"
+msgstr "Sett inn bok"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr ""
+
+#: translators/tellicoimporter.cpp:968
+#, fuzzy
+msgid "80's Music"
+msgstr "Min musikk"
+
+#: translators/tellicoimporter.cpp:980
+#, fuzzy
+msgid "Favorites"
+msgstr "Filtrer innslag"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Sjekker lydfiler..."
+
+#: translators/audiofileimporter.cpp:129
+#, fuzzy
+msgid "Bitrate"
+msgstr "Bibtex"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Valg for lydfiler"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Rekursivt søk i kataloger "
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+"Om slått på vil det søkes i katalog (og alle underliggende kataloger) for "
+"lydfiler "
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:348
+#, fuzzy
+msgid "If checked, the file names for each track are added to the entries."
+msgstr "Feltnavn blir skrevet ut som tabelloverskrift."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:353
+#, fuzzy
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr "Feltnavn blir skrevet ut som tabelloverskrift."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+#, fuzzy
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|CSV filer (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "Valg for CSV"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Inkluder feltet tittel som kolonneoverskrift"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr "Om slått på vil en overskriftsrad bli lagt til med feltet tittel"
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Feltvelger"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"I tillegg til et komma, kan andre tegn bli brukt som feltvelgere, som "
+"separerer hver verdi i filen."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Komma"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Bruk komma som feltvelger."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Semikolon"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Bruk semikolon som feltvelger."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Tabulator"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Bruk en tabulator som feltvelger."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Annet"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Bruk egendefinert tegn som feltvelger."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr "Et egendefinert tegn slik som kolon kan bli brukt som feltvelger."
+
+#: translators/filelistingimporter.cpp:63
+#, fuzzy
+msgid "Scanning files..."
+msgstr "Sjekker lydfiler..."
+
+#: translators/filelistingimporter.cpp:191
+#, fuzzy
+msgid "File Listing Options"
+msgstr "Valg for utskrift"
+
+#: translators/filelistingimporter.cpp:193
+#, fuzzy
+msgid "Recursive folder search"
+msgstr "Rekursivt søk i kataloger "
+
+#: translators/filelistingimporter.cpp:194
+#, fuzzy
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+"Om slått på vil det søkes i katalog (og alle underliggende kataloger) for "
+"lydfiler "
+
+#: translators/filelistingimporter.cpp:198
+#, fuzzy
+msgid "Generate file previews"
+msgstr "Lag ny samling"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+
+#: translators/onixexporter.cpp:63
+#, fuzzy
+msgid "ONIX Archive"
+msgstr "Valg for kilde"
+
+#: translators/onixexporter.cpp:67
+#, fuzzy
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.bib|Bibtex filer (*.bib)"
+
+#: translators/onixexporter.cpp:176
+#, fuzzy
+msgid "ONIX Archive Options"
+msgstr "Valg for kilde"
+
+#: translators/onixexporter.cpp:179
+#, fuzzy
+msgid "Include images in archive"
+msgstr "Inkluder bilder i XML-dokumentet"
+
+#: translators/onixexporter.cpp:181
+#, fuzzy
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Om slått på vil bilder i dokumentet bli inkludert som ett base64-enkodet "
+"element i XML-dokumentet."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr "<qt>Tellico klarer ikke å skrive til tjeneren på <b>%1</b>.</qt>."
+
+#: translators/freedbimporter.cpp:196
+#, fuzzy
+msgid "Select CDDB Entry"
+msgstr "Sl&ett innslag"
+
+#: translators/freedbimporter.cpp:197
+#, fuzzy
+msgid "Select a CDDB entry:"
+msgstr "Velg resultat fra IMDB"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>Ingen treff som likner på CD-platen ble funnet</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "<qt>Tellico klarte ikke å fullføre sjekk av CD-platen.</qt>"
+
+#: translators/freedbimporter.cpp:470
+#, fuzzy
+msgid "Various"
+msgstr "Grupper på: "
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Valg for CD-plate"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr ""
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Velg eller skriv inn plassering av CD-ROM-enhet."
+
+#: translators/freedbimporter.cpp:502
+#, fuzzy
+msgid "Read all CDDB cache files only"
+msgstr "Sjekker lydfiler..."
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr ""
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+#, fuzzy
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.csv|CSV filer (*.csv)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+#, fuzzy
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.csv|CSV filer (*.csv)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "Valg for XSLT"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+#, fuzzy
+msgid "XSLT file:"
+msgstr "XSLT-fil:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr "Velg en XSLT-fil for omgjøring til Tellico XML-data."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Valg for Alexandria"
+
+#: translators/alexandriaimporter.cpp:195
+#, fuzzy
+msgid "&Library:"
+msgstr "Bibliotek:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "Bibtexml"
+
+#: translators/bibtexmlexporter.cpp:40
+#, fuzzy
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Bibtexml filer (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+#, fuzzy
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|XML filer (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Valg for Tellico XML"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Inkluder bilder i XML-dokumentet"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Om slått på vil bilder i dokumentet bli inkludert som ett base64-enkodet "
+"element i XML-dokumentet."
+
+#: translators/importer.h:100
+#, fuzzy
+msgid "Loading data..."
+msgstr "Importer data"
+
+#: translators/importer.h:100
+#, fuzzy
+msgid "Loading %1..."
+msgstr "Henter %1..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "Bibtex"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+#, fuzzy
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Bibtex filer (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Utvid tekststreng-makroer"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Om slått på vil tekststreng-makroer bli utvidet og ingen @innhold{} "
+"innslag vil bli skrevet."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Bruk URL-innpakking"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr "Om slått på vil alle URL-felter bli satt inn i en \\URL-deklarasjon."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Hopp over innslag med tomme siteringsnøkler"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr "Om slått på vil innslag uten en bibtex-nøkkel bli hoppet over."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Bibtex siteringsstil"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Frankrike"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Sitat"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"Kanada<qt>Siteringsstil brukt ved eksport til bibtex. Alle felter vil bli "
+"sendt gjennom en tolker ved hjelp av enten paranteser eller "
+"siteringstegn.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Velg typen av samling for import."
+
+#: translators/csvimporter.cpp:235
+#, fuzzy
+msgid "&First row contains field titles"
+msgstr "Første rad inneholder feltet tittel"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr "Om slått på vil første rad bli brukt for feltet tittel"
+
+#: translators/csvimporter.cpp:248
+#, fuzzy
+msgid "&Comma"
+msgstr "Komma"
+
+#: translators/csvimporter.cpp:254
+#, fuzzy
+msgid "&Semicolon"
+msgstr "Semikolon"
+
+#: translators/csvimporter.cpp:259
+#, fuzzy
+msgid "Ta&b"
+msgstr "Tabulator"
+
+#: translators/csvimporter.cpp:264
+#, fuzzy
+msgid "Ot&her:"
+msgstr "Annet"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "Tabellen viser opp til de fem første linjene i CSV-filen."
+
+#: translators/csvimporter.cpp:296
+#, fuzzy
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt>Sett hver kolonne til korresponderende felt i samlingen ved å velge en "
+"kolonne, velge feltet og så klikke på <i>Sett</i>-knappen.</qt>"
+
+#: translators/csvimporter.cpp:298
+#, fuzzy
+msgid "Co&lumn:"
+msgstr "Kolonne:"
+
+#: translators/csvimporter.cpp:307
+#, fuzzy
+msgid "&Data field in this column:"
+msgstr "Datafelter i denne kolonnen:"
+
+#: translators/csvimporter.cpp:315
+#, fuzzy
+msgid "&Assign Field"
+msgstr "Sett til felt"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Nytt felt"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+#, fuzzy
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|Pilot-databasefil (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Vis kolonner"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "Valg for PilotDB"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Slå på backup av database for PDA"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+#, fuzzy
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>Last inn en liste med ISBN-nummer fra en tekstfil</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Tellico fikk en feil i XSLT prosesseringen."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "En gyldig XSLT-fil er nødvendig for å importere filen."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+#, fuzzy
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|XSL filer (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+#, fuzzy
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.hml|HTML fil(*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Personer"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(grupper på %1)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "Valg for HTML"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Skriv ut feltoverskrifter"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr "Feltnavn blir skrevet ut som tabelloverskrift."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Grupper innslag"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr "Om slått på vil man gruppere innslag ved hjelp av nedtrekkslisten."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Eksporter innslag til egne filer"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr "Om slått på vil hvert innslag få sin egen fil."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+#, fuzzy
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico klarte ikke å laste filen - %1."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Egenskaper for datakilde"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "Kildenavn"
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr "Navnet identifiserer datakilden og bør være unik og informativ."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "Kildetype:"
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr ""
+
+#: fetcherconfigdialog.cpp:114
+#, fuzzy
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr "Om slått på vil man gruppere innslag ved hjelp av nedtrekkslisten."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Uansett felt"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "inneholder"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "inneholder ikke"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "er lik"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "er ikke lik"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "treffer regulært uttrykk"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "treffer ikke regulært uttrykk"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Endre..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Avansert filter"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Filterkriterie"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Treff på a&lle"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Treff på e&n eller flere"
+
+#: filterdialog.cpp:311
+#, fuzzy
+msgid "Filter name:"
+msgstr "Filtrer innslag"
+
+#: filterdialog.cpp:319
+#, fuzzy
+msgid "&Save Filter"
+msgstr "Avansert filter"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Enkel tekst"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Avsnitt"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Valg"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Avkrysningsboks"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Tabell"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Avhenger"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Dato"
+
+#: entryupdater.cpp:81
+#, fuzzy
+msgid "Updating %1..."
+msgstr "Henter %1..."
+
+#: entryupdater.cpp:83
+#, fuzzy
+msgid "Updating entries..."
+msgstr "Endre innslag"
+
+#: entryupdater.cpp:85
+#, fuzzy
+msgid "Update Entries"
+msgstr "Endre innslag"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr ""
+
+#: entryupdater.cpp:209
+#, fuzzy
+msgid "Select Match"
+msgstr "Velg resultat fra IMDB"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Utvid alle grupper"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Fold sammen alle grupper"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Filtrer på gruppe"
+
+#: groupview.cpp:466
+#, fuzzy
+msgid "%1 (Sort by Count)"
+msgstr "Filtrer på gruppe"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr ""
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Valg for import"
+
+#: importdialog.cpp:62
+#, fuzzy
+msgid "&Replace current collection"
+msgstr "Bytt ut nåværende samling"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr ""
+"Bytter ut den nåværende samlingen med innholdet fra den importerte filen."
+
+#: importdialog.cpp:65
+#, fuzzy
+msgid "A&ppend to current collection"
+msgstr "Legg til den nåværende samlingen"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Legg til innholdet av den importerte samlingen. Dette er mulig kun når "
+"samlingene er av samme type."
+
+#: importdialog.cpp:69
+#, fuzzy
+msgid "&Merge with current collection"
+msgstr "Legg til i den nåværende samlingen"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Legg til innholdet av den importerte samlingen. Dette er mulig kun når "
+"samlingene er av samme type. Innslag må stemme eksakt for å kunne bli lagt "
+"til."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Importer"
+
+#: importdialog.cpp:268
+#, fuzzy
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|RIS filer (*.ris)"
+
+#: importdialog.cpp:277
+#, fuzzy
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.csv|CSV filer (*.csv)"
+
+#: importdialog.cpp:281
+#, fuzzy
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdb|Pilot-databasefil (*.pdb)"
+
+#: importdialog.cpp:285
+#, fuzzy
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.ris|RIS filer (*.ris)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico klarte ikke å laste filen - %1."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico klarte ikke å skrive til filen - %1."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico klarte ikke å laste opp filen - %1."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Bare samlinger av samme type innslag som den nåværende kan bli lagt til. "
+"Ingen forandringer er gjort i den nåværende samlingen"
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Bare samlinger av samme type innslag som den nåværende kan bli lagt til. "
+"Ingen forandringer er gjort i den nåværende samlingen"
+
+#: tellico_strings.cpp:27
+#, fuzzy, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico klarte ikke å laste filen - %1."
+
+#: entryiconview.cpp:287
+#, fuzzy
+msgid "&Sort By"
+msgstr "Port:"
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr ""
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr ""
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr ""
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr ""
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+
+#: loandialog.cpp:117
+#, fuzzy
+msgid "&Loan date:"
+msgstr "Dato"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+
+#: loandialog.cpp:132
+#, fuzzy
+msgid "D&ue date:"
+msgstr "Dato"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+
+#: loandialog.cpp:144
+#, fuzzy
+msgid "&Note:"
+msgstr "Notat"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr ""
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr ""
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Lag ny samling"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Ny &boksamling"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Lag ny boksamling"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Ny b&ibliografi"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Lag ny Bibtex bibliografi"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Ny &tegneseriesamling"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Lag ny tegneseriesamling"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Ny &videosamling"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Lag ny videosamling"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Ny &musikksamling"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Lag ny musikksamling"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Ny &myntsamling"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Lag ny myntsamling"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Ny &frimerkesamling"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Lag ny frimerkesamling"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Ny &kortsamling"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Lag ny kortsamling"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Ny &vinsamling"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Lag ny vinsamling"
+
+#: mainwindow.cpp:264
+#, fuzzy
+msgid "New &Game Collection"
+msgstr "Ny &frimerkesamling"
+
+#: mainwindow.cpp:266
+#, fuzzy
+msgid "Create a new game collection"
+msgstr "Lag ny frimerkesamling"
+
+#: mainwindow.cpp:272
+#, fuzzy
+msgid "New Boa&rd Game Collection"
+msgstr "Ny &frimerkesamling"
+
+#: mainwindow.cpp:274
+#, fuzzy
+msgid "Create a new board game collection"
+msgstr "Lag ny frimerkesamling"
+
+#: mainwindow.cpp:280
+#, fuzzy
+msgid "New &File Catalog"
+msgstr "Nytt felt"
+
+#: mainwindow.cpp:282
+#, fuzzy
+msgid "Create a new file catalog"
+msgstr "Lag ny samling"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Ny &spesialsamling"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Lag ny spesialsamling"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Åpne eksisterende dokument"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Åpne nylig"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Lagre gjeldende samling"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Lagre gjeldende samling som..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Skriv ut innhold i dokumentet..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Avslutt"
+
+#: mainwindow.cpp:320
+#, fuzzy
+msgid "Import collection data from other formats"
+msgstr "Importer samling av data fra andre formater..."
+
+#: mainwindow.cpp:324
+#, fuzzy
+msgid "Import Tellico Data..."
+msgstr "Importer Tellico-data"
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Importer andre Tellico-datafiler"
+
+#: mainwindow.cpp:331
+#, fuzzy
+msgid "Import CSV Data..."
+msgstr "Importer CSV-data"
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Importer en CSV-fil"
+
+#: mainwindow.cpp:338
+#, fuzzy
+msgid "Import MODS Data..."
+msgstr "Importer MODS-data"
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Importer en MODS-fil"
+
+#: mainwindow.cpp:345
+#, fuzzy
+msgid "Import Alexandria Data..."
+msgstr "Importer Alexandria data"
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Importer data fra Alexandria boksamlingshåndtereren"
+
+#: mainwindow.cpp:352
+#, fuzzy
+msgid "Import Delicious Library Data..."
+msgstr "Importer Tellico-data"
+
+#: mainwindow.cpp:353
+#, fuzzy
+msgid "Import data from Delicious Library"
+msgstr "Import metadata fra lydfiler"
+
+#: mainwindow.cpp:359
+#, fuzzy
+msgid "Import Referencer Data..."
+msgstr "Importer RIS-data"
+
+#: mainwindow.cpp:360
+#, fuzzy
+msgid "Import data from Referencer"
+msgstr "Importer en RIS-referansefil"
+
+#: mainwindow.cpp:366
+#, fuzzy
+msgid "Import Bibtex Data..."
+msgstr "Importer Bibtex data"
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Importer en Bibtex bibliografi-fil"
+
+#: mainwindow.cpp:373
+#, fuzzy
+msgid "Import Bibtexml Data..."
+msgstr "Importer Bibtexml-data"
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Importer en Bibtexml-bibliografi fil"
+
+#: mainwindow.cpp:380
+#, fuzzy
+msgid "Import RIS Data..."
+msgstr "Importer RIS-data"
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Importer en RIS-referansefil"
+
+#: mainwindow.cpp:387
+#, fuzzy
+msgid "Import PDF File..."
+msgstr "Importer fil..."
+
+#: mainwindow.cpp:388
+#, fuzzy
+msgid "Import a PDF file"
+msgstr "Importer en CSV-fil"
+
+#: mainwindow.cpp:394
+#, fuzzy
+msgid "Import Audio File Metadata..."
+msgstr "Importer en metadatafil for lydfil"
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Import metadata fra lydfiler"
+
+#: mainwindow.cpp:404
+#, fuzzy
+msgid "Import Audio CD Data..."
+msgstr "Importer data for CD"
+
+#: mainwindow.cpp:405
+#, fuzzy
+msgid "Import audio CD information"
+msgstr "Importer informasjon om CD fra FreeDB"
+
+#: mainwindow.cpp:414
+#, fuzzy
+msgid "Import GCstar Data..."
+msgstr "Importer CSV-data"
+
+#: mainwindow.cpp:415
+#, fuzzy
+msgid "Import a GCstar data file"
+msgstr "Importer en MODS-fil"
+
+#: mainwindow.cpp:421
+#, fuzzy
+msgid "Import Griffith Data..."
+msgstr "Importer CSV-data"
+
+#: mainwindow.cpp:422
+#, fuzzy
+msgid "Import a Griffith database"
+msgstr "Eksporter til en PilotDB-database"
+
+#: mainwindow.cpp:428
+#, fuzzy
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Importer data for CD"
+
+#: mainwindow.cpp:429
+#, fuzzy
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Importer andre Tellico-datafiler"
+
+#: mainwindow.cpp:435
+#, fuzzy
+msgid "Import File Listing..."
+msgstr "Importer fil..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr ""
+
+#: mainwindow.cpp:442
+#, fuzzy
+msgid "Import XSL Transform..."
+msgstr "Importer via XSL-omgjøring..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Importer en fil via XSL omgjøring..."
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Eksporter..."
+
+#: mainwindow.cpp:457
+#, fuzzy
+msgid "Export the collection data to other formats"
+msgstr "Eksporter samlingens data til annet format..."
+
+#: mainwindow.cpp:461
+#, fuzzy
+msgid "Export to XML..."
+msgstr "Eksporter til html"
+
+#: mainwindow.cpp:462
+#, fuzzy
+msgid "Export to a Tellico XML file"
+msgstr "Eksporter til en Tellico-xml-fil"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Eksporter til zip"
+
+#: mainwindow.cpp:469
+#, fuzzy
+msgid "Export to a Tellico Zip file"
+msgstr "Eksporter til en Tellico-xml-fil"
+
+#: mainwindow.cpp:475
+#, fuzzy
+msgid "Export to HTML..."
+msgstr "Eksporter til html"
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Eksporter til en html-fil"
+
+#: mainwindow.cpp:482
+#, fuzzy
+msgid "Export to CSV..."
+msgstr "Eksporter til CSV"
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Eksporter til en fil med kommaseparerte verdier"
+
+#: mainwindow.cpp:489
+#, fuzzy
+msgid "Export to PilotDB..."
+msgstr "Eksporter til PilotDB"
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Eksporter til en PilotDB-database"
+
+#: mainwindow.cpp:496
+#, fuzzy
+msgid "Export to Alexandria..."
+msgstr "Importer til en Alexandria datafil"
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Eksporter til ett Alexandria databibliotek"
+
+#: mainwindow.cpp:503
+#, fuzzy
+msgid "Export to Bibtex..."
+msgstr "Eksporter til Bibtex"
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Eksporter til en Bibtex fil"
+
+#: mainwindow.cpp:510
+#, fuzzy
+msgid "Export to Bibtexml..."
+msgstr "Eksporter til Bibtexml"
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Eksporter til en Bibtexml fil"
+
+#: mainwindow.cpp:517
+#, fuzzy
+msgid "Export to ONIX..."
+msgstr "Eksporter til xml"
+
+#: mainwindow.cpp:518
+#, fuzzy
+msgid "Export to an ONIX file"
+msgstr "Eksporter til en html-fil"
+
+#: mainwindow.cpp:524
+#, fuzzy
+msgid "Export to GCfilms..."
+msgstr "Eksporter til CSV"
+
+#: mainwindow.cpp:525
+#, fuzzy
+msgid "Export to a GCfilms data file"
+msgstr "Eksporter til en Bibtex fil"
+
+#: mainwindow.cpp:531
+#, fuzzy
+msgid "Export to GCstar..."
+msgstr "Eksporter til CSV"
+
+#: mainwindow.cpp:532
+#, fuzzy
+msgid "Export to a GCstar data file"
+msgstr "Eksporter til en Bibtex fil"
+
+#: mainwindow.cpp:536
+#, fuzzy
+msgid "Export XSL Transform..."
+msgstr "Eksporter via XSL-omgjøring"
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Eksporter en fil via XSL omgjøring"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Klipp ut valgt tekst og sett den i utklippstavlen"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Kopierer utvalg til utklippstavle"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Sett inn utklippstavlens innhold"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Velg alle felter i samlingen."
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Fjern alle valgte felter i samlingen."
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Søk på internett"
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Søk på internett..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "Avansert &filter..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Filtrer samlingen"
+
+#: mainwindow.cpp:569
+#, fuzzy
+msgid "&New Entry..."
+msgstr "&Nytt innslag"
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Lag nytt innslag"
+
+#: controller.cpp:620 mainwindow.cpp:573
+#, fuzzy
+msgid "&Edit Entry..."
+msgstr "&Endre innslag"
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Endre valgt innslag"
+
+#: controller.cpp:621 mainwindow.cpp:577
+#, fuzzy
+msgid "D&uplicate Entry"
+msgstr "Dupliser innslag"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Kopier valgte innslag"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "Sl&ett innslag"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Slett valgte innslag"
+
+#: mainwindow.cpp:585
+#, fuzzy
+msgid "&Merge Entries"
+msgstr "Sle&tt innslag"
+
+#: mainwindow.cpp:588
+#, fuzzy
+msgid "Merge the selected entries"
+msgstr "Slett valgte innslag"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr ""
+
+#: mainwindow.cpp:594
+#, fuzzy
+msgid "Generate collection reports"
+msgstr "Lag ny samling"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr ""
+
+#: mainwindow.cpp:598
+#, fuzzy
+msgid "Check-out the selected items"
+msgstr "Kopier valgte innslag"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr ""
+
+#: mainwindow.cpp:602
+#, fuzzy
+msgid "Check-in the selected items"
+msgstr "Kopier valgte innslag"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "Gi samling nytt navn..."
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Gi samling nytt navn..."
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "Felter for samling..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Modifiser samlingens felter..."
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "Konverter til en &bibliografi"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Konverter en boksamling til en bibliografi"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "Makro for tekststreng"
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Endre Bibtex tekststrengmakro"
+
+#: mainwindow.cpp:626
+#, fuzzy
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Kopierer utvalg til utklippstavle"
+
+#: mainwindow.cpp:627
+#, fuzzy
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Kopierer utvalg til utklippstavle"
+
+#: mainwindow.cpp:632
+#, fuzzy
+msgid "Cite Entry in &LyX"
+msgstr "Sit&er innslag"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Siter valgte innslag i Lyx"
+
+#: mainwindow.cpp:638
+#, fuzzy
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Sit&er innslag"
+
+#: mainwindow.cpp:639
+#, fuzzy
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Siter valgte innslag i Lyx"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, fuzzy, no-c-format
+msgid "&Update Entry"
+msgstr "Sit&er innslag"
+
+#: mainwindow.cpp:652
+#, fuzzy
+msgid "All Sources"
+msgstr "Kilde"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr ""
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Bruk &gruppevisning"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Slå på/av grupperingsvisning"
+
+#: mainwindow.cpp:669
+#, fuzzy
+msgid "Hide Grou&p View"
+msgstr "Bruk &gruppevisning"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Vis redigerer for &innslag"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Slå på/av redigerer"
+
+#: mainwindow.cpp:675
+#, fuzzy
+msgid "Hide Entry &Editor"
+msgstr "Vis redigerer for &innslag"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Vis &innslag"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Slå på/av innslagsvisning"
+
+#: mainwindow.cpp:681
+#, fuzzy
+msgid "Hide Entry &View"
+msgstr "Vis &innslag"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr ""
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "&Valg for gruppering"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Endre gruppering av samlingen"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+#, fuzzy
+msgid "Filter"
+msgstr "Filtrer innslag"
+
+#: mainwindow.cpp:705
+#, fuzzy
+msgid "Clear Filter"
+msgstr "Slett felt?"
+
+#: mainwindow.cpp:710
+#, fuzzy
+msgid "Filter here..."
+msgstr "Filterkriterie"
+
+#: mainwindow.cpp:768
+#, fuzzy
+msgid "Groups"
+msgstr "Grupper på: "
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt><i>Gruppevisning</i> sorterer innslag i grupper på grunnlag av valgt "
+"felt.</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt><i>Kolonnevisning</i> viser verdier for flere felter for hvert "
+"innslag.</qt>"
+
+#: mainwindow.cpp:831
+#, fuzzy
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Tellico - en boksamlingshåndterer for KDE"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Lag nytt dokument"
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Åpne fil..."
+
+#: mainwindow.cpp:1108
+#, fuzzy
+msgid "Open File"
+msgstr "Åpne fil..."
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Lagrer filen..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr ""
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr ""
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Lagrer fil med nytt navn..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Skriver ut..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"Samlingen er foreløpig satt opp til å vise en begrenset antall av innslag. "
+"Bare innslag som er synlige vil bli skrevet ut. Vil du fortsette?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Prosesserer dokument..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Avslutter..."
+
+#: mainwindow.cpp:1498
+#, fuzzy, c-format
+msgid "Total entries: %1"
+msgstr "antall innslag: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 filtrert, %2 valgt)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 filtrert)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 valgt)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Skriv ut %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Side %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Vennligst sjekk din installasjon."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Importer data"
+
+#: mainwindow.cpp:1858
+#, fuzzy
+msgid "Import File"
+msgstr "Importer fil..."
+
+#: mainwindow.cpp:1864
+#, fuzzy
+msgid "Import Directory"
+msgstr "Importer"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Eksporterer data..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "E&ksporter som"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Tekststreng-makro"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Makro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Tekststreng"
+
+#: mainwindow.cpp:1999
+#, fuzzy
+msgid "Creating citations..."
+msgstr "Klipper ut utvalg..."
+
+#: mainwindow.cpp:2104
+#, fuzzy
+msgid "Filters"
+msgstr "Filtrer innslag"
+
+#: mainwindow.cpp:2105
+#, fuzzy
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt><i>Innslagsvisning</i> gir ett formatert syn på innslagets innhold</qt>"
+
+#: mainwindow.cpp:2121
+#, fuzzy
+msgid "Loans"
+msgstr "Lånt"
+
+#: mainwindow.cpp:2122
+#, fuzzy
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt><i>Kolonnevisning</i> viser verdier for flere felter for hvert "
+"innslag.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr ""
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico klarer ikke å laste filen - %1."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+"En fil med navnet \"%1\" finnes allerede. Er du sikker på at du vil "
+"overskrive?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Overskrive fil?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Skriv over"
+
+#: filterview.cpp:87
+#, fuzzy
+msgid "Filter (Sort by Count)"
+msgstr "Filtrer på gruppe"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Vil du slette dette innslaget?"
+
+#: controller.cpp:429
+#, fuzzy
+msgid "Delete Entry"
+msgstr "Sl&ett innslag"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Vil du slette disse innslagene?"
+
+#: controller.cpp:443
+#, fuzzy
+msgid "Delete Multiple Entries"
+msgstr "Slett flere innslag?"
+
+#: controller.cpp:626
+#, fuzzy
+msgid "&Edit Entries..."
+msgstr "Endre innslag"
+
+#: controller.cpp:627
+#, fuzzy
+msgid "D&uplicate Entries"
+msgstr "Dupliser innslag"
+
+#: controller.cpp:628
+#, fuzzy
+msgid "&Update Entries"
+msgstr "Endre innslag"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "Sle&tt innslag"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr ""
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr ""
+
+#: calendarhandler.cpp:203
+#, fuzzy
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico klarer ikke å lese filen - %1."
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(Tom)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - en boksamlingshåndterer for KDE"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Ikke åpne siste brukte fil"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Importer <filename> som Bibtexfil"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Import <filename> som en MODS-fil"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Import <filename> som en RIS-fil"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Åpne fil"
+
+#: main.cpp:42
+#, fuzzy
+msgid "Data source scripts"
+msgstr "Valg for datakilde"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Ikoner"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Forfatter av btparse-biblioteket"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr ""
+
+#: main.cpp:50
+#, fuzzy
+msgid "Author of libcsv library"
+msgstr "Forfatter av btparse-biblioteket"
+
+#: main.cpp:52
+#, fuzzy
+msgid "Author of rtf2html library"
+msgstr "Forfatter av btparse-biblioteket"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Felter for samling"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Gjeldende felter"
+
+#: collectionfieldsdialog.cpp:84
+#, fuzzy
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "Ny"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Legg nytt felt til i samlingen"
+
+#: collectionfieldsdialog.cpp:87
+#, fuzzy
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr ""
+"Slett felt\n"
+"Slett"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Slett et felt fra samlingen"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Flytt dette feltet opp i listen. Listerekkefølgen er viktig for utseende av "
+"innholdsredigerer"
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Flytt dette feltet ned i listen. Listerekkefølgen er viktig for utseende av "
+"innholdsredigerer"
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Feltverdi"
+
+#: collectionfieldsdialog.cpp:119
+#, fuzzy
+msgid "&Title:"
+msgstr "Tittel:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "Tittel for feltet"
+
+#: collectionfieldsdialog.cpp:129
+#, fuzzy
+msgid "T&ype:"
+msgstr "Type:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "Typen felt bestemmer hvilke verdier som kan benyttes."
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "<i>Enkel tekst</i> benyttes for de vanligste feltene."
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "<i>Avsnitt</i> er for store tekstblokker."
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Valg</i> begrenser felter til bestemte verdier."
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "<i>Avkrysningsboks</i> er for enkle ja/nei verdier."
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr "<i>Nummer</i> indikerer at feltet inneholdet ett tall."
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+"<i>URL</i> er for felter som refererer til nettlenker, inkludert referanser "
+"til andre filer."
+
+#: collectionfieldsdialog.cpp:142
+#, fuzzy
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr "<i>Tabell</i>er kan være enkle eller doble kolonner med verdier."
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "<i>Bilde</i> brukes for lagring av bilde."
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr "<i>Dato</i>feltet benyttes for dag, måned og år."
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"<i>Avhenger</i>-feltet benyttes for felter som avhenger av andre felter, og "
+"er formatert etter feltets beskrivelse."
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"<i>Kun les</i> er for interne verdier, og er muligens brukbar til import og "
+"eksport."
+
+#: collectionfieldsdialog.cpp:157
+#, fuzzy
+msgid "Cate&gory:"
+msgstr "Kategori:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr "Feltet kategori bestemmer hvor feltet er plassert i redigereren."
+
+#: collectionfieldsdialog.cpp:179
+#, fuzzy
+msgid "Descr&iption:"
+msgstr "Beskrivelse:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"Beskrivelse er en nyttig påminner om hvilken informasjon som ett felt "
+"inneholder. For <i>avhenger</i>-felter er beskrivelsen en formateringsstreng "
+"slik som \"%{year} %{title}\", hvor hvor de aktuelle feltene blir byttet ut "
+"i tekststrengen."
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:203
+#, fuzzy
+msgid "A&llowed values:"
+msgstr "Tillatt:"
+
+#: collectionfieldsdialog.cpp:208
+#, fuzzy
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>For <i>valg</i>-felter, disse er de eneste verdiene som er tillatt. De "
+"er plassert i en kombinasjonsliste.</qt>"
+
+#: collectionfieldsdialog.cpp:215
+#, fuzzy
+msgid "Extended &properties:"
+msgstr "Utvidete egenskaper"
+
+#: collectionfieldsdialog.cpp:217
+#, fuzzy
+msgid "&Set..."
+msgstr "Sett..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"Utvidete felter blir brukt for å spesifisere ting, slik som "
+"korresponderende bibtex-felter."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Formateringsvalg"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Ingen formatering"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+"Dette valget forhindrer feltet fra automatisk formatering eller stor bokstav."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Tillat kun automatisk stor bokstav"
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+"Dette valget tillater feltet å få automatisk stor forbokstav, men ikke "
+"spesielt formatert."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Formater som tittel"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Dette valget setter stor forbokstav og formaterer feltet som en tittel, men "
+"kun om disse valgene er slått på globalt."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Formater som navn"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Dette valget setter stor forbokstav og formaterer feltet som ett navn, men "
+"kun om disse valgene er slått på globalt."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Feltvalg"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Slå på auto-fullføring"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Om slått på vil KDEs auto-fullføring bli skrudd på i tekst-redigereren "
+"for dette feltet."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Tillat flere verdier"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Om slått på vil Tellico tolke verdiene i feltene som flere verdier, "
+"separert av et semi-kolon."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Tillat gruppering"
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Om slått på vil dette feltet bli brukt til å gruppere innslag i "
+"gruppevisningen."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr "Sett valgte felters verdier tilbake til standardverdier."
+
+#: collectionfieldsdialog.cpp:306
+#, fuzzy
+msgid "Modify Fields"
+msgstr "Hurtigfilter:"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Fjerning av tillatte verdier fra <i>%1</i>-feltet som er i bruk i "
+"samlingen kan føre til korrupsjon av data. Vil du beholde dine modifiserte "
+"verdier, avbryte eller revertere til nåværende?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Behold modifiserte verdier"
+
+#: collectionfieldsdialog.cpp:745
+#, fuzzy
+msgid "Revert Field Properties"
+msgstr "Tilbakestill feltverdi?"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Vil du virkelig sette egenskapene <em>%1</em>-feltet tilbake til sine "
+"originale verdier?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Tilbakestill"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Utvidete feltegenskaper"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr ""
+"Ett felt med denne tittelen eksisterer allerede. Vennligst velg en annen "
+"tittel."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>Ett felt kan ikke være i samme kategori som en <em>paragraf</em>-, "
+"<em>tabell</em>- eller <em>bilde</em>felt. Vennligst velg en annen "
+"kategori.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"Ett felts tittel kan ikke den samme som en eksisterende kategori. Vennligst "
+"velg en annen tittel."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr ""
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Dette dokumentet er endret.\n"
+"Vil du lagre?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr ""
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr ""
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Oppsett av Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Hovedvalg"
+
+#: configdialog.cpp:201
+#, fuzzy
+msgid "&Reopen file at startup"
+msgstr "Åpne siste fil ved oppstart"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr "Filen som sist var åpnet vil bli lastet ved nesteprogramstart."
+
+#: configdialog.cpp:207
+#, fuzzy
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "Vis \" Dagens tips\" ved oppstart"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr ""
+"Om slått på vil \"Dagens tips\" bli vist når programmet starter opp."
+
+#: configdialog.cpp:213
+#, fuzzy
+msgid "Image Storage Options"
+msgstr "Valg for bilder"
+
+#: configdialog.cpp:214
+#, fuzzy
+msgid "Store images in data file"
+msgstr "Inkluder bilder i XML-dokumentet"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr ""
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr ""
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Formateringsvalg"
+
+#: configdialog.cpp:227
+#, fuzzy
+msgid "Auto capitalize &titles and names"
+msgstr "Stor bokstav i titler og navn"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr "Titler og navn vil automatisk få stor forbokstav."
+
+#: configdialog.cpp:232
+#, fuzzy
+msgid "Auto &format titles and names"
+msgstr "Autoformater titler og navn"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr "Om slått på vil titler og navn bli automatisk formatert"
+
+#: configdialog.cpp:240
+#, fuzzy
+msgid "No capitali&zation:"
+msgstr "Tillat kun automatisk stor bokstav"
+
+#: configdialog.cpp:243
+#, fuzzy
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>En liste over en persons prefiks som kan bli brukt. Flere verdier bør "
+"separeres med ett semikolon.</qt>"
+
+#: configdialog.cpp:249
+#, fuzzy
+msgid "Artic&les:"
+msgstr "Artikler:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>En liste av ord som burde bli regnet som artikler om de er det første "
+"ordet i en tittel. Flere verdier bør bli separert med ett semikolon.</qt>"
+
+#: configdialog.cpp:259
+#, fuzzy
+msgid "Personal suffi&xes:"
+msgstr "Personsuffiks:"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>En liste over suffiks som kan bli brukt i en persons navn. Flere verdier "
+"bør separeres med ett semikolon.</qt>"
+
+#: configdialog.cpp:268
+#, fuzzy
+msgid "Surname &prefixes:"
+msgstr "Prefiks for etternavn:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>En liste over en persons prefiks som kan bli brukt. Flere verdier bør "
+"separeres med ett semikolon.</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Utskrift"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Valg for utskrift"
+
+#: configdialog.cpp:302
+#, fuzzy
+msgid "&Format titles and names"
+msgstr "Formater titler og navn"
+
+#: configdialog.cpp:306
+#, fuzzy
+msgid "&Print field headers"
+msgstr "Skriv ut feltoverskrifter"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Grupperingsvalg"
+
+#: configdialog.cpp:313
+#, fuzzy
+msgid "&Group the entries"
+msgstr "Grupper innslag"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Valg for bilder"
+
+#: configdialog.cpp:323
+#, fuzzy
+msgid "Maximum image &width:"
+msgstr "Maks bredde på bilder:"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Maksbredden på bilder ved utskrift. Forholdet mellom høyde og bredde blir "
+"ivaretatt."
+
+#: configdialog.cpp:336
+#, fuzzy
+msgid "&Maximum image height:"
+msgstr "Maks bildehøyde:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Maks høyde på bilde ved utskrift. Forholdet mellom høyde og bredde vil "
+"bli ivaretatt."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Mal"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Valg for maler"
+
+#: configdialog.cpp:369
+#, fuzzy
+msgid "Template:"
+msgstr "Mal"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+
+#: configdialog.cpp:380
+#, fuzzy
+msgid "&Preview..."
+msgstr "Ny"
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr ""
+
+#: configdialog.cpp:398
+#, fuzzy
+msgid "Font Options"
+msgstr "Formateringsvalg"
+
+#: configdialog.cpp:405
+#, fuzzy
+msgid "Font:"
+msgstr "Måned"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:415
+#, fuzzy
+msgid "Size:"
+msgstr "Signert"
+
+#: configdialog.cpp:425
+#, fuzzy
+msgid "Color Options"
+msgstr "Valg for CSV"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr ""
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr ""
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr ""
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr ""
+
+#: configdialog.cpp:469
+#, fuzzy
+msgid "Manage Templates"
+msgstr "Mal"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr ""
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr ""
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr ""
+
+#: configdialog.cpp:484
+#, fuzzy
+msgid "Click to download additional templates via the Internet."
+msgstr ""
+"Klikk for å åpne en tekstboks for å skrive inn flere eller endre "
+"ISBN-nummer."
+
+#: configdialog.cpp:487
+#, fuzzy
+msgid "Delete..."
+msgstr "Velg bilde..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr ""
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Datakilde"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Valg for datakilde"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Kilde"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr ""
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+
+#: configdialog.cpp:521
+#, fuzzy
+msgid "Move &Down"
+msgstr "Fjern"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "Ny"
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr ""
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "Endre"
+
+#: configdialog.cpp:533
+#, fuzzy
+msgid "Click to modify the selected data source."
+msgstr "Kopier valgte innslag"
+
+#: configdialog.cpp:536
+#, fuzzy
+msgid "Click to delete the selected data source."
+msgstr "Slett valgte innslag"
+
+#: configdialog.cpp:539
+#, fuzzy
+msgid "Click to download additional data sources via the Internet."
+msgstr ""
+"Klikk for å åpne en tekstboks for å skrive inn flere eller endre "
+"ISBN-nummer."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr ""
+
+#: configdialog.cpp:1049
+#, fuzzy
+msgid "Delete Template"
+msgstr "Slett felt?"
+
+#: configdialog.cpp:1050
+#, fuzzy
+msgid "Select template to delete:"
+msgstr "Velg database å søke i"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr ""
+
+#: loanview.cpp:74
+#, fuzzy
+msgid "Check-in"
+msgstr "Avkrysningsboks"
+
+#: loanview.cpp:76
+#, fuzzy
+msgid "Modify Loan..."
+msgstr "Endre"
+
+#: loanview.cpp:93
+#, fuzzy
+msgid "Borrower (Sort by Count)"
+msgstr "Filtrer på gruppe"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "Min samling"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Samling av bøker"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Samling av tegneserier"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Samling av videofilmer"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Samling med musikk"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Samling av mynter"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Samling med frimerker"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Samling med viner"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Samling av kort"
+
+#: collectionfactory.cpp:133
+#, fuzzy
+msgid "Game Collection"
+msgstr "Gi samling nytt navn"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr ""
+
+#: collectionfactory.cpp:135
+#, fuzzy
+msgid "Board Game Collection"
+msgstr "Gi samling nytt navn"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Egendefinert samling"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+"<qt><i>Innslagsvisning</i> gir ett formatert syn på innslagets innhold</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt><i>Ikon</i> viser hvert innslag eller gruppe i samlingen som ett ikon. "
+"Dette kan være ett bilde i innslaget.</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Valg for eksport"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Formatering"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Formater alle felter"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Om slått på vil felter bli automatisk formatert i henhold til sin "
+"format-type."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Eksporter kun valgte innslag"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr "Om slått på vil kun valgte innslag bli eksportert."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Tegnsett"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Tegnsettet Unicode (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Eksporter filen i tegnsettet Unicode (UTF-8)."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Bruk ditt systems tegnsett (%1)"
+
+#: exportdialog.cpp:72
+#, fuzzy
+msgid "Encode the exported file in the local encoding."
+msgstr "Eksporter filen i ditt lokale tegnsett."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "Søk"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "Stopp"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Internettsøk"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Søkeforespørsel"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr ""
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+"Skriv inn en søkeverdi. Ett ISBN-nummer må være fullstendig inntastet."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Velg søketype"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Klikk for å starte søket"
+
+#: fetchdialog.cpp:134
+#, fuzzy
+msgid "&Multiple ISBN/UPC search"
+msgstr "Søk etter flere ISBN-nummer"
+
+#: fetchdialog.cpp:135
+#, fuzzy
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr "Kryss av i boksen for å søke etter flere ISBN-nummer."
+
+#: fetchdialog.cpp:138
+#, fuzzy
+msgid "Edit List..."
+msgstr "Endre liste av ISBN-nummer..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+"Klikk for å åpne en tekstboks for å skrive inn flere eller endre "
+"ISBN-nummer."
+
+#: fetchdialog.cpp:146
+#, fuzzy
+msgid "Search s&ource:"
+msgstr "Søkekilde:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Velg database å søke i"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"Etterhvert som man får resultater vil disse bli lagt til i listen. Å velge "
+"ett treff vil hente alle data om treffet og vise informasjonen under."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"Ett treff kan bli vist her før man legger det inn i samlingen ved å klikke "
+"på treffet i listen over"
+
+#: fetchdialog.cpp:192
+#, fuzzy
+msgid "&Add Entry"
+msgstr "Legg til innslag"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Legg valgt innslag til i samlingen"
+
+#: fetchdialog.cpp:198
+#, fuzzy
+msgid "Get More Results"
+msgstr "Velg resultat fra IMDB"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr ""
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Tøm alle søkefelter og søkeresultater"
+
+#: fetchdialog.cpp:298
+#, fuzzy
+msgid "Cancelling the search..."
+msgstr "Søk på internett"
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Søker..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "Søket ga ingen treff."
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+"Søket returnerte ett treff.\n"
+"Søket returnerte %n treff."
+
+#: fetchdialog.cpp:412
+#, fuzzy
+msgid "No results were found for the following ISBN values:"
+msgstr "<qt>Ingen treff for søk etter følgende ISBN-nummer:</qt>"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Henter %1..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr "Ingen nettkilder er tilgjengelige for din nåværende samlingstype."
+
+#: fetchdialog.cpp:594
+#, fuzzy
+msgid "Edit ISBN/UPC Values"
+msgstr "Endre ISBN-nummer"
+
+#: fetchdialog.cpp:598
+#, fuzzy
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Skriv inn ISBN-nummer, ett nummer per linje.</qt>"
+
+#: fetchdialog.cpp:604
+#, fuzzy
+msgid "&Load From File..."
+msgstr "Last inn fra fil"
+
+#: fetchdialog.cpp:605
+#, fuzzy
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Last inn en liste med ISBN-nummer fra en tekstfil</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>Ett søk etter ISBN-nummer kan maksimalt innholde 100 verdier. Bare de "
+"100 første verdiene i listen vil bli benyttet.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Endre innslag"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Nytt innslag"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "&Lagre innslag"
+
+#: entryeditdialog.cpp:77
+#, fuzzy
+msgid "Go to the previous entry in the collection"
+msgstr "Finn forrige treff i samlingen"
+
+#: entryeditdialog.cpp:82
+#, fuzzy
+msgid "Go to the next entry in the collection"
+msgstr "Velg alle felter i samlingen."
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Vil du virkelig endre disse innslagene?"
+
+#: entryeditdialog.cpp:317
+#, fuzzy
+msgid "Modify Multiple Entries"
+msgstr "Endre flere innslag?"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr ""
+
+#: entryeditdialog.cpp:456
+#, fuzzy
+msgid "Edit Entries"
+msgstr "Endre innslag"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "L&agre innslag"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"Innslaget har blitt endret.\n"
+"Vil du lagre endringene?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Lagre innslag"
+
+#: reportdialog.cpp:53
+#, fuzzy
+msgid "Collection Report"
+msgstr "Verktøylinjen Samling"
+
+#: reportdialog.cpp:60
+#, fuzzy
+msgid "&Report template:"
+msgstr "Importer Bibtexml-data"
+
+#: reportdialog.cpp:83
+#, fuzzy
+msgid "&Generate"
+msgstr "Hovedvalg"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr ""
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+
+#: tellico_kernel.cpp:285
+#, fuzzy
+msgid "Do you really want to delete this filter?"
+msgstr "Vil du slette dette innslaget?"
+
+#: tellico_kernel.cpp:287
+#, fuzzy
+msgid "Delete Filter?"
+msgstr "Slett felt?"
+
+#: tellico_kernel.cpp:323
+#, fuzzy
+msgid "New collection name:"
+msgstr "Nytt navn på samling"
+
+#: tellico_kernel.cpp:377
+#, fuzzy
+msgid "Entry 1"
+msgstr "Innslag"
+
+#: tellico_kernel.cpp:378
+#, fuzzy
+msgid "Entry 2"
+msgstr "Innslag"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr ""
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+#, fuzzy
+msgid "Merge Entries"
+msgstr "Slett innslag"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr ""
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico klarer ikke å finne standardmalens visningsark."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Ny"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Samling"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Verktøylinjen Samling"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Leif Mathis Gaup"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "lmgaup@nsn.no"
+
+#: entrymerger.cpp:35
+#, fuzzy
+msgid "Merging entries..."
+msgstr "Endre innslag"
+
+#: entrymerger.cpp:49
+#, fuzzy
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "antall innslag: %1"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>...om en bok har mer enn en forfatter, bør du separere deres\n"
+"navn ved bruk av semikolon, slik at Tellico kan dele de opp og\n"
+"håndtere de separat.</p> <p>Alle andre felter som tillater flere verdier "
+"bør tastes inn på samme\n"
+"måte, med ett semikolon (;).</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>...at du kan endre hvilke felter som blir vist ved å høyreklikke\n"
+"på kolonnetittelen.\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>...at du kan legge til, endre eller modifisere felter i samlingen ved\n"
+"å bruke Feltredigerer. Pilknappene under feltene kan bli brukt til å\n"
+"forandre posisjonen til feltet i listen, noe som påvirker plasseringen\n"
+"i innslagsredigereren.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>...at hvis du vil filtrere på en avkrysningsboks, bør en verdi lik\n"
+"\"sann\" bli brukt. Hvis du vil filtrere på kun leste science fiction "
+"bøker\n"
+"som du ikke har lest, så kan du for eksempel sette <em>Treff på "
+"alle</em>,\n"
+",sette første regel til \"Sjanger\" \"inneholder\" \"Science Fiction\" "
+"(ingen apostrofer)\n"
+"og den andre regelen til \"Lest\" \"inneholder ikke\" \"true\" (ingen "
+"apostrofer).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>...at om et kommandotegn blir brukt i et hurtigfilter, vil teksten bli "
+"tolket\n"
+"som et regulært uttrykk.</p>\n"
+"<p>For å vise bare bøker som er av Weber eller Bujold, kan de for\n"
+"eksempel skrive inn \"weber|bujold\" (uten apostrofer) i filterboksen</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>...at du kan endre mer enn ett innslag om gangen ved å holde nede\n"
+"shift eller Ctrl-knappen og velge flere innslag.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>...at du kan konvertere en eksisterende samling til en bibliografi,\n"
+"som kan videre eksporteres til Bibtex eller Bibtexml-format.</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>...at du kan legge til, endre og slette tekststreng-makroer for "
+"bibliografier.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>...at om flere enn ett felt er formatert som navn, så kan en ekstra\n"
+"gruppe kalt \"Personer\" bli lagt til samlingen, slik at man kan sortere "
+"eller\n"
+"skrive ut for eksempel forfattere eller redaktører sammen.</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>...at du kan endre utseendet på utskrift ved å endre på\n"
+"<tt>tellico-printing.xsl</tt>-filen. Denne filen genererer\n"
+"HTML, og CSS-stilsettet styrer ting slik som fonter, marginer\n"
+"og så videre.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>...at du kan importere og eksportere alle generiske XSL-stilark som\n"
+"gir ut gyldig Tellico XML-filer.</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr "<p>...at dobbeltklikking åpner en redigerer for innslaget.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>...at du kan legge til HTML-tagger til avsnitt for å formatere felter, "
+"slik som\n"
+"&lt;b&gt;fet&lt;/b&gt; eller &lt;i&gt;skråstilt&lt;/i&gt;.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>...at du i detaljert visning kan presse ned en bokstav på tastaturet\n"
+"for å komme deg til neste innslag som starter med den bokstaven.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr ""
+
+#: xslt.cpp:3
+#, fuzzy
+msgid "This template is meant for music collections only."
+msgstr "Lag ny musikksamling"
+
+#: xslt.cpp:5
+#, fuzzy
+msgid "Total:"
+msgstr "%1 totalt"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr ""
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr ""
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr ""
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr ""
+
+#: xslt.cpp:14 xslt.cpp:43
+#, fuzzy
+msgid "This template is meant for video collections only."
+msgstr "Lag ny videosamling"
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr ""
+
+#: xslt.cpp:17
+#, fuzzy
+msgid ": Group Summary"
+msgstr "Sammendrag av handlingen"
+
+#: xslt.cpp:18
+#, fuzzy
+msgid "Total number of fields:"
+msgstr "antall innslag: %1"
+
+#: xslt.cpp:19
+#, fuzzy
+msgid "Total number of entries:"
+msgstr "antall innslag: %1"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+#, fuzzy
+msgid "Generated by Tellico"
+msgstr "Hovedvalg"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr ""
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr ""
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr ""
+
+#: xslt.cpp:27 xslt.cpp:29
+#, fuzzy
+msgid "Loan Date"
+msgstr "Lånt"
+
+#: xslt.cpp:28 xslt.cpp:31
+#, fuzzy
+msgid "Note"
+msgstr "Notat"
+
+#: xslt.cpp:30
+#, fuzzy
+msgid "Due Date"
+msgstr "Dato"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr ""
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr ""
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr ""
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr ""
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr ""
+
+#: xslt.cpp:44
+#, fuzzy
+msgid "Search"
+msgstr "Søk"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr ""
+
+#: z3950.cpp:6
+#, fuzzy
+msgid "Sudoc (France)"
+msgstr "Amazon (Tyskland)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr ""
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr ""
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr ""
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr ""
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr ""
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr ""
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr ""
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr ""
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr ""
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr ""
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr ""
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr ""
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr ""
+
+#, fuzzy
+#~ msgid "CrossRef"
+#~ msgstr "Kryssreferanse"
+
+#~ msgid "GCstar"
+#~ msgstr "GCstar"
+
+#, fuzzy
+#~ msgid "Griffith"
+#~ msgstr "Gave"
+
+#, fuzzy
+#~ msgid "Referencer"
+#~ msgstr "Kryssreferanse"
+
+#~ msgid "Comics"
+#~ msgstr "Tegneserie"
+
+#~ msgid "Stamps"
+#~ msgstr "Frimerker"
+
+#~ msgid "Coins"
+#~ msgstr "Mynter"
+
+#~ msgid "Books"
+#~ msgstr "Bøker"
+
+#~ msgid "Wines"
+#~ msgstr "Vin"
+
+#~ msgid "Videos"
+#~ msgstr "Videoer"
+
+#, fuzzy
+#~ msgid "Games"
+#~ msgstr "Nummer"
+
+#~ msgid "Cards"
+#~ msgstr "Kort"
+
+#~ msgid "Entries"
+#~ msgstr "Innslag"
+
+#~ msgid "Albums"
+#~ msgstr "Album"
+
+#, fuzzy
+#~ msgid "Copac"
+#~ msgstr "Komma"
+
+#~ msgid "Tellico"
+#~ msgstr "Tellico"
+
+#~ msgid "&Copy Entry"
+#~ msgstr "&Kopier innslag"
+
+#~ msgid "&Copy Entries"
+#~ msgstr "Kopier innslag"
+
+#~ msgid "<qt>Multiple records were found to match the CD.</qt>"
+#~ msgstr "<qt>Flere treff som likner på CD-platen ble funnet.</qt>"
+
+#~ msgid "Remo&ve"
+#~ msgstr "Fjern"
+
+#, fuzzy
+#~ msgid "Scanning CDDB cache files..."
+#~ msgstr "Sjekker lydfiler..."
+
+#, fuzzy
+#~ msgid "Collection &type: "
+#~ msgstr "Samlingstype"
+
+#, fuzzy
+#~ msgid "Save Entries"
+#~ msgstr "L&agre innslag"
+
+#, fuzzy
+#~ msgid ""
+#~ "_: Save (Entry Title)\n"
+#~ "Save %1"
+#~ msgstr ""
+#~ "Slett felt\n"
+#~ "Slett"
+
+#, fuzzy
+#~ msgid ""
+#~ "Tellico currently supports five source types: Amazon.com, IMDB, z39.50, "
+#~ "Entrez, and external applications."
+#~ msgstr "Tellico støtter tre datakilder: Amazon.com, IMDB og z39.50"
+
+#~ msgid "Enable/disable the statusbar"
+#~ msgstr "Slå på/av statuslinje"
+
+#, fuzzy
+#~ msgid "Reading files..."
+#~ msgstr "Lagrer filen..."
+
+#~ msgid ""
+#~ "<p>...that you can rename a collection by right-clicking on\n"
+#~ "the top collection item in the left column.</p>\n"
+#~ msgstr ""
+#~ "<p>...at du kan gi nytt navn til en samling ved å høyreklikke på\n"
+#~ "samlingens toppenhet i venstre kolonne.</p>\n"
+
+#, fuzzy
+#~ msgid "S&earch:"
+#~ msgstr "Søk:"
+
+#, fuzzy
+#~ msgid "Group by:"
+#~ msgstr "Grupper på:"
+
+#, fuzzy
+#~ msgid "Quick filter:"
+#~ msgstr "Hurtigfilter:"
+
+#~ msgid "Filter Entry"
+#~ msgstr "Filtrer innslag"
+
+#, fuzzy
+#~ msgid "Source type: "
+#~ msgstr "Kildetype:"
+
+#, fuzzy
+#~ msgid "Tellico: %1 is due to return %2"
+#~ msgstr "Tellico klarer ikke å lese filen - %1."
+
+#~ msgid "Find Text"
+#~ msgstr "Finn tekst"
+
+#~ msgid "&Find"
+#~ msgstr "&Finn"
+
+#~ msgid "Find"
+#~ msgstr "Finn"
+
+#~ msgid "&Text to find:"
+#~ msgstr "&Tekst å finne:"
+
+#~ msgid "The search string"
+#~ msgstr "Søkestreng"
+
+#~ msgid "As regular e&xpression"
+#~ msgstr "Som &regulært uttrykk"
+
+#~ msgid "If checked, the search string is used as a regular expression."
+#~ msgstr "Om slått på blir søkestrengen brukt som et regulært uttrykk."
+
+#, fuzzy
+#~ msgid "&Edit Regular Expression..."
+#~ msgstr "&Rediger uttrykk..."
+
+#~ msgid "Field"
+#~ msgstr "Felt"
+
+#~ msgid "Search in:"
+#~ msgstr "Søk i:"
+
+#~ msgid "Select which field should be searched."
+#~ msgstr "Velg hvilke felt som det skal søkes i."
+
+#~ msgid "C&ase sensitive"
+#~ msgstr "Skill mellom s&må og store"
+
+#~ msgid "If checked, the search is case-sensitive."
+#~ msgstr "Om slått på vil søk avhenge av store og små bokstaver."
+
+#~ msgid "Find &backwards"
+#~ msgstr "Søk &baklengs"
+
+#~ msgid "If checked, the document is searched in reverse."
+#~ msgstr "Om slått på vil søk skje bakover i dokumentet."
+
+#~ msgid "&Whole words only"
+#~ msgstr "Bare &hele ord"
+
+#~ msgid "If checked, the search is limited to whole words."
+#~ msgstr "Om slått på så søkes kun etter hele ord."
+
+#~ msgid "All Fields"
+#~ msgstr "Alle felter"
+
+#~ msgid "Invalid regular expression."
+#~ msgstr "Ugyldig regulært uttrykk."
+
+#~ msgid "5 - Best"
+#~ msgstr "5 - Bra"
+
+#~ msgid "4 - Good"
+#~ msgstr "4 - God"
+
+#~ msgid "3 - Neutral"
+#~ msgstr "3 - Nøytral"
+
+#~ msgid "2 - Bad"
+#~ msgstr "2 - Dårlig"
+
+#~ msgid "1 - Worst"
+#~ msgstr "1 - Elendig"
+
+#~ msgid "Table (2 Columns)"
+#~ msgstr "Tabell (2 kolonner)"
+
+#~ msgid "Delete Entry?"
+#~ msgstr "Slett innslag"
+
+#~ msgid "Warning!"
+#~ msgstr "Advarsel!"
+
+#~ msgid "CD-ROM Device:"
+#~ msgstr "Enhet for CD-ROM:"
+
+#~ msgid "(grouped by %1; sorted by %2)"
+#~ msgstr "(gruppert på %1;sortert på %2)"
+
+#~ msgid "(sorted by %1)"
+#~ msgstr "(sortert på %1)"
+
+#~ msgid ""
+#~ "<qt><p>Do you really want to delete the <em>%1</em> field? This action "
+#~ "occurs immediately and can not be undone!</p></qt>"
+#~ msgstr ""
+#~ "<qt><p>Vil du virkelig slette <em>%1</em>-feltet. Denne handlingen skjer med "
+#~ "en gang og kan ikke bli omgjort!</p></qt>"
+
+#~ msgid "Sort by Group, Ascending"
+#~ msgstr "Sorter på gruppe, synkende"
+
+#~ msgid "Sort by Group, Descending"
+#~ msgstr "Sorter på gruppe, stigende"
+
+#~ msgid "Sort by Count, Ascending"
+#~ msgstr "Sorter på antall, synkende"
+
+#~ msgid "Sort by Count, Descending"
+#~ msgstr "Sorter på antall, stigende"
+
+#~ msgid "Search the collection"
+#~ msgstr "Søk i samlingen"
+
+#~ msgid "Find next match in the collection"
+#~ msgstr "Finn neste treff i samlingen"
+
+#, fuzzy
+#~ msgid "Reports"
+#~ msgstr "&Eksporter..."
+
+#~ msgid "Show number of items in group"
+#~ msgstr "Vis antall i gruppering"
+
+#~ msgid ""
+#~ "If checked, the number of items in the group will be appended to the group "
+#~ "name."
+#~ msgstr "Vis antall elementer i en gruppe ved siden av gruppenavnet."
+
+#~ msgid "Search string '%1' not found."
+#~ msgstr "Søkestrengen '%1' ble ikke funnet."
+
+#, fuzzy
+#~ msgid "Video"
+#~ msgstr "Videoer"
+
+#, fuzzy
+#~ msgid "*.bc .tc|Tellico files (*.tc)"
+#~ msgstr "*.tc *.bc|Tellico filer (*.tc)"
+
+#~ msgid "&From Beginning"
+#~ msgstr "&Fra begynnelsen"
+
+#~ msgid "If checked, the document is searched from the beginning."
+#~ msgstr "Om slått på så søkes fra begynnelsen av dokumentet."
+
+#~ msgid "Path to LyX server:"
+#~ msgstr "Sti til lyx-tjener:"
+
+#~ msgid ""
+#~ "<qt>The location of the LyX server for citing bibliographic entries. Also "
+#~ "used by other applications such as Kile or Pybliographer. Do not include the "
+#~ "trailing .in suffix.</qt>"
+#~ msgstr ""
+#~ "<qt>Plassering av lyx-tjeneren for oppslah mot bibliografiske innslag. Også "
+#~ "benyttet av andre programmer som Kile eller Pybibliographer. Ikke inkluder "
+#~ "den etterfølgende .in suffikset.</qt>"
+
+#, fuzzy
+#~ msgid "<qt>Tellico was unable to open the CD-ROM device - <i>%1</i>.</qt>"
+#~ msgstr "<qt>Tellico klarer ikke å skrive tol tjeneren på <b>%1</b>.</qt>."
+
+#~ msgid "Do you really want to modify these books?"
+#~ msgstr "Vil du virkelig endre disse bøkene?"
+
+#~ msgid "*.ogg|Ogg files (*.ogg)"
+#~ msgstr "*.ogg|Ogg-filer (*.ogg)"
+
+#~ msgid ""
+#~ "<qt>The type of the field determines what values may be used. <i>Simple "
+#~ "Text</i> is used for most fields. <i>Paragraph</i> is for large text blocks. "
+#~ "<i>Choice</i> limits the field to certain values. <i>Checkbox</i> is for a "
+#~ "simple yes/no value. <i>Number</i> indicates that the field contains a "
+#~ "numerical value. <i>URL</i> is for fields which refer to URLs, including "
+#~ "references to other files. <i>Table</i>s may be a single or double column of "
+#~ "values, while <i>Read Only</i> is for internal values, possibly useful for "
+#~ "import and export. A <i>Dependent</i> field depends on the values of other "
+#~ "fields, and is formatted according to the field description. An <i>Image</i> "
+#~ "holds a picture.</qt>"
+#~ msgstr ""
+#~ "<qt>Typen av feltet bestemmer hvilke verdier som kan bli brukt. <i>Enkel "
+#~ "tekst</i> blir brukt for de fleste feltene. <i>Paragraf</i> er for store "
+#~ "tekstblokker. <i>Liste</i> begrenser feltene til fastsatte verdier. "
+#~ "<i>Avkrysningsboks</i> er for enkle ja/nei verdier. <i>Nummer</i> indikerer "
+#~ "at feltet er av numerisk type. <i>URL</i> er for felter som refererer til "
+#~ "hyperlenker, inkludert referanser til andre filer. <Tabell</i>er kan bli "
+#~ "brukt til enkle eller doble kolonner av verdier, mens <i>Kun les</i> er for "
+#~ "interne verdier, kanskje brukbare for import og eksport.<i>Avhenger</i> "
+#~ "feltet trenger verdier i andre felter, og er formatert ifølge "
+#~ "feltbeskrivelsen. Ett <i>bilde</i> viser ett bilde.</qt>"
+
+#, fuzzy
+#~ msgid "Export images"
+#~ msgstr "E&ksporter som"
+
+#~ msgid "(Requires restart)"
+#~ msgstr "(Trenger omstart)"
+
+#~ msgid ""
+#~ "A comma-separated list of suffixes which might be used in personal names."
+#~ msgstr "En kommaseparert liste over suffiks som er brukt i personnavn."
+
+#~ msgid "A comma-separated list of prefixes which might be used in surnames."
+#~ msgstr "En kommaseparert liste over prefiks som kan bli brukt i etternavn."
+
+#~ msgid "Enable/disable the toolbar"
+#~ msgstr "Slå på/av verktøylinje"
+
+#~ msgid "Show Co&llection ToolBar"
+#~ msgstr "Vis verktøylinjen &samling"
+
+#~ msgid "Enable/disable the collection toolbar"
+#~ msgstr "Slå på/av samlingens verktøylinje"
+
+#~ msgid "Tip of the &Day"
+#~ msgstr "&Dagens tips"
+
+#~ msgid "Show the \"Tip of the Day\" dialog..."
+#~ msgstr "Vis \"Dagens tips\" dialogboksen..."
+
+#, fuzzy
+#~ msgid "*.bcz|Tellico files(*.bcz)"
+#~ msgstr "*.bcz|Tellico filer(*.bcz)"
+
+#~ msgid "List"
+#~ msgstr "Liste"
+
+#, fuzzy
+#~ msgid "Good"
+#~ msgstr "4 - God"
+
+#~ msgid ""
+#~ "An article is from a journal or magazine. A book has an explicit publisher, "
+#~ "while a booklet does not."
+#~ msgstr ""
+#~ "En artikkel er fra en journal eller ett blad. En bok har en eksplisitt "
+#~ "utgiver, mens en booklet ikke har det."
+
+#, fuzzy
+#~ msgid "Mint"
+#~ msgstr "Måned"
+
+#, fuzzy
+#~ msgid "Fine"
+#~ msgstr "&Finn"
+
+#, fuzzy
+#~ msgid "New Entry"
+#~ msgstr "&Nytt innslag"
+
+#~ msgid ""
+#~ "The description is useful reminder of what information is contained in the "
+#~ "field."
+#~ msgstr ""
+#~ "Beskrivelse er en nyttig påminnelse om hvilken informasjon som et felt "
+#~ "inneholder."
+
+#~ msgid "Bibtex Field Name:"
+#~ msgstr "Bibtex feltnavn:"
+
+#~ msgid ""
+#~ "The Bibtex field name determines the entry name for exporting to "
+#~ "bibliogrgaphy files."
+#~ msgstr ""
+#~ "Bibtex feltnavnet bestemmer innslagets navn for eksport til "
+#~ "bibliografi-filer."
+
+#~ msgid "Toggling toolbar..."
+#~ msgstr "Endrer verktøylinje..."
+
+#~ msgid "Toggling collection toolbar..."
+#~ msgstr "Endrer samlingens verktøylinje"
+
+#~ msgid "Toggle the statusbar..."
+#~ msgstr "Skru på/av statuslinjen"
+
+#~ msgid "Tellico is unable to find a required file - %1.\n"
+#~ msgstr "Tellico klarer ikke å finne en nødvendig fil : %1.\n"
+
+#~ msgid "Editing string macros..."
+#~ msgstr "Endre på tekststreng makroer"
+
+#~ msgid ""
+#~ "Both the macro and the string can be edited by triple-clicking the item."
+#~ msgstr ""
+#~ "Både makroer og tekststrenger man redigeres ved å bli klikket på tre "
+#~ "ganger."
+
+#~ msgid "XSLTImporter"
+#~ msgstr "XSLT i&mporterer"
+
+#~ msgid "CSVImporter"
+#~ msgstr "CSV-importerer"
+
+#~ msgid "TextImporter"
+#~ msgstr "Tekst-importerer"
+
+#~ msgid "BibtexImporter"
+#~ msgstr "Bibtex-importerer"
+
+#~ msgid "&New Collection"
+#~ msgstr "Ny &samling"
+
+#~ msgid "BCTabControl"
+#~ msgstr "BCTabControl"
+
+#~ msgid "BCAttributeWidget"
+#~ msgstr "BCAttributeWidget"
+
+#~ msgid "BCUnitEditWidget"
+#~ msgstr "BCUnitEditWidget"
+
+#, fuzzy
+#~ msgid "Processing new entries..."
+#~ msgstr "Prosesserer dokument..."
+
+#, fuzzy
+#~ msgid "If checked, the first row is used as field headers."
+#~ msgstr "Feltnavn blir skrevet ut som tabelloverskrift."
+
+#, fuzzy
+#~ msgid "Collection Field in this Column:"
+#~ msgstr "Felter for boksamling..."
+
+#~ msgid "Tellico is unable to find the file - %1."
+#~ msgstr "Tellico klarer ikke å finne filen - %1."
+
+#~ msgid "Tellico is unable to download the file - %1."
+#~ msgstr "Tellico klarer ikke å laste ned filen - %1."
+
+#~ msgid "Edit Collection Fields"
+#~ msgstr "Endre felter for Tellico"
+
+#~ msgid "The fields are grouped by common categories for editing."
+#~ msgstr "Feltene er gruppert på vanlige kategorier for redigering."
+
+#~ msgid "The collection is grouped by this field."
+#~ msgstr "Denne samlingen er gruppert av dette feltet."
+
+#~ msgid "These are the available fields in the collection."
+#~ msgstr "Dette er de tilgjengelige feltene i samlingen."
+
+#~ msgid "Selected Fields"
+#~ msgstr "Valgte felter"
+
+#, fuzzy
+#~ msgid "Import..."
+#~ msgstr "Eksporter..."
+
+#, fuzzy
+#~ msgid "Read Only"
+#~ msgstr "Klar."
+
+#, fuzzy
+#~ msgid "Text"
+#~ msgstr "Finn tekst"
+
+#, fuzzy
+#~ msgid "Enoding Options"
+#~ msgstr "Grupperingsvalg"
+
+#~ msgid "Edit Collection Fields..."
+#~ msgstr "Endre felter"
+
+#, fuzzy
+#~ msgid "&Create new collection"
+#~ msgstr "Lag nytt dokument"
+
+#, fuzzy
+#~ msgid "*.txt|Text files (*.txt)"
+#~ msgstr "*.xsl|XSLT filer (*.xsl)"
+
+#~ msgid "New Book"
+#~ msgstr "Ny bok"
+
+#~ msgid "Modify Books"
+#~ msgstr "Endre bøker"
+
+#~ msgid "Delete Books"
+#~ msgstr "Slett bøker"
+
+#~ msgid "Lookup book..."
+#~ msgstr "Slå opp bok..."
+
+#~ msgid "Group Books By"
+#~ msgstr "Grupper bøker på"
+
+#~ msgid "Configure the options for the application..."
+#~ msgstr "Oppsett av programmet..."
+
+#~ msgid "Save as..."
+#~ msgstr "Lagre som..."
+
+#~ msgid "Importing from Bibtex..."
+#~ msgstr "Importerer fra Bibtex..."
+
+#~ msgid "Import from Bibtex..."
+#~ msgstr "Importer fra Bibtex..."
+
+#~ msgid "Importing from Bibtexml..."
+#~ msgstr "Importerer fra Bibtexml..."
+
+#~ msgid "Song"
+#~ msgstr "Sanger"
+
+#~ msgid "CD"
+#~ msgstr "CD"
diff --git a/po/nl.po b/po/nl.po
new file mode 100644
index 0000000..e628ac3
--- /dev/null
+++ b/po/nl.po
@@ -0,0 +1,5505 @@
+# translation of nl.po to Nederlands
+# This file is distributed under the same license as the tellico package.
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+# Fred Marchee <fred@intercookie.com>, 2005.
+# Fred Marchee <fredmarchee@gmail.com>, 2005.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: nl\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2005-08-11 11:02+0200\n"
+"Last-Translator: Fred Marchee <fredmarchee@gmail.com>\n"
+"Language-Team: Nederlands <kde-i18n-nl@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Report-Msgid-Bugs-To: \n"
+"X-Generator: KBabel 1.10.2\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "<qt>Tellico naar de server pipe schrijven op <b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr ""
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr ""
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+
+#: cite/openoffice.cpp:191
+#, fuzzy
+msgid "Pipe"
+msgstr "Mensen"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:181
+#, fuzzy
+msgid "Rename Column"
+msgstr "Hernoem verzameling"
+
+#: gui/tablefieldwidget.cpp:181
+#, fuzzy
+msgid "New column name:"
+msgstr "Nieuwe verzamelingsnaam:"
+
+#: gui/tablefieldwidget.cpp:206
+#, fuzzy, c-format
+msgid "Column %1"
+msgstr "Kolom:"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+#, fuzzy
+msgid "Rename Column..."
+msgstr "&Hernoem verzameling..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:276
+#, fuzzy
+msgid "Remove Row"
+msgstr "Ver&wijder"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:295
+#, fuzzy
+msgid "Clear Table"
+msgstr "Wis filter"
+
+#: gui/previewdialog.cpp:27
+#, fuzzy
+msgid "Template Preview"
+msgstr "Sjablonen"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Instellen"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr ""
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Meer"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Minder"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Wis"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Kies een afbeelding..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr ""
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr ""
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, fuzzy, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "%1 opslaan"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Verzameling toevoegen"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Verzameling samenvoegen"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Verzameling vervangen"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+#, fuzzy
+msgid "Modify Entries"
+msgstr "Bewerk items"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "%1 veld toevoegen"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Wijzig %1 veld"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Veld %1 wissen"
+
+#: commands/addentries.cpp:50
+#, fuzzy
+msgid "Add Entries"
+msgstr "Bewerk items"
+
+#: commands/addentries.cpp:51
+#, fuzzy, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "%1 opslaan"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Hernoem verzameling"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Bewerk uitlenen"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Filter toevoegen"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Bewerk filter"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Filter wissen"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Items uitchecken"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "%1 uit checken"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Wis items"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Wis %1"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Velden opnieuw sorteren"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Items inchecken"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "%1 inchecken"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Algemeen"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Staat"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Persoonlijk"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Mijn postzegels"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Titel"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Omschrijving"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Benaming"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "Land"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Jaar van uitgave"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Kleur"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Waarde#"
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr "Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Waardering"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Geannuleerd"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Vals"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Gecentreerd"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Gegomd"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Aankoopdatum"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Aankoopprijs"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Locatie"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Geschenk"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Afbeelding"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Opmerkingen"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Uitgever"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Categorie"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Mijn strips"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Ondertitel"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Auteur"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Serie"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Uitgave"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Uitgever"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Editie"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Jaar van publicatie"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Pagina's"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Taal"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Genre"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Trefwoorden"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr "Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Gesigneerd"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Geleend"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Voorzijde"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Mijn munten"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Type"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Jaar"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Mint markering"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Set munten"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr "PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Waardering service"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Voorzijde"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Achterzijde"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Mijn boeken"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Auteur"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Gebonden"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Paperback"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Trade Paperback"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "E-Boek"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Tijdschrift"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Dagblad"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Binding"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Jaar Copyright "
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN#"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Internationaal Standaard Boeken Nummer"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN#"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Library of Congress Control Number"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr ""
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Serienummer"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Nieuw"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Gebruikt"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Gelezen"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Waardering"
+
+#: collections/filecatalog.cpp:25
+#, fuzzy
+msgid "My Files"
+msgstr "Mijn wijnen"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "naam"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL-adres"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Deel"
+
+#: collections/filecatalog.cpp:55
+#, fuzzy
+msgid "Folder"
+msgstr "Filter"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr ""
+
+#: collections/filecatalog.cpp:65
+#, fuzzy
+msgid "Size"
+msgstr "Gesigneerd"
+
+#: collections/filecatalog.cpp:69
+#, fuzzy
+msgid "Permissions"
+msgstr "Persoon"
+
+#: collections/filecatalog.cpp:74
+#, fuzzy
+msgid "Owner"
+msgstr "Ander"
+
+#: collections/filecatalog.cpp:79
+#, fuzzy
+msgid "Group"
+msgstr "Groepen"
+
+#: collections/filecatalog.cpp:85
+#, fuzzy
+msgid "Created"
+msgstr "Voltooid"
+
+#: collections/filecatalog.cpp:89
+#, fuzzy
+msgid "Modified"
+msgstr "Bewerk velden"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Eigenschap"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Waarde"
+
+#: collections/filecatalog.cpp:99
+#, fuzzy
+msgid "Icon"
+msgstr "Pictogrammen"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Mijn wijnen"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Producent"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Wijnstreek"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Druivensoort"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Jaartal"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Rode wijn"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Witte wijn"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Mousserende wijn"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Hoeveelheid"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Consumeren voor"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Afbeelding etiket"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Overige medewerkers"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Mogelijkheden"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Mijn films"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr ""
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+#, fuzzy
+msgid "HD DVD"
+msgstr "DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Drager"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Productie jaar"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Leeftijdscategorie"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Regio 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Regio 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Regio 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Regio 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Regio 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Regio 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Regio 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Regio 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Regio"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Land"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Videosysteem"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Acteurs"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr ""
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+#, fuzzy
+msgid "Role"
+msgstr "Deel"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr "Een lijst met acteurs en de rol die zij spelen"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Regisseur"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Componist"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Studio"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Talen"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Ondertitel talen"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Audiotracks"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Speeltijd"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "De speeltijd van de film (in minuten)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Beeldverhouding"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Breedbeeld"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Zwart wit"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Kleur standaard"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Director's Cut"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Samenvatting"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Persoonlijke waardering"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Hoes"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "Mijn spellen"
+
+#: collections/gamecollection.cpp:44
+#, fuzzy
+msgid "Xbox 360"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+#, fuzzy
+msgid "PlayStation3"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+#, fuzzy
+msgid "Nintendo Wii"
+msgstr "Regio"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr ""
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Platform"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Jaar van uitgave"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Uitgever"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Ontwikkelaar"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr "Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "ESRB classificatie"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Voltooid"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Mijn kaarten"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Speler"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Team"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Merk"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Kaartnummer"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Kaart type"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Afbeelding voorzijde"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Afbeelding achterzijde"
+
+#: collections/boardgamecollection.cpp:26
+#, fuzzy
+msgid "My Board Games"
+msgstr "Mijn spellen"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:72
+#, fuzzy
+msgid "Number of Players"
+msgstr "Totaal aantal afbeeldingen:"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Bibliografie"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Item type"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+"Deze items types zijn specifiek voor BibTeX. Zie de BibTeX documentatie."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "BibTeX sleutel"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Boektitel"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Uitgever"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organisatie"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Adres"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Maand"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Nummer"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Hoe uitgegeven"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Hoofdstuk"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Verwijzingen"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Samenvatting"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Notities"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Mijn muziek"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Album"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "Compact Disc"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Cassette"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Vinyl"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Artiest"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Label"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Nummers"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr ""
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr "een,en,in,van,de,naar"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "de, het, een"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr, sr"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,van de,van,vande,vanden"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 staat niet toe dat er voor deze verzameling wordt gezocht."
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Resultaten van %1: %2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "Deze bron heeft geen opties."
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "Entrez Database"
+
+#: fetch/entrezfetcher.cpp:485
+#, fuzzy
+msgid "Institution"
+msgstr "Staat"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Zoek fout!"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Verbindings zoekfout %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Structuur syntaxisfout"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Verbindingsfout %1: %2"
+
+#: fetch/srufetcher.cpp:72
+#, fuzzy
+msgid "SRU Server"
+msgstr "Terugzetten"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Library of Congress Control (VS)"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+#, fuzzy
+msgid "Hos&t: "
+msgstr "&Host: "
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+#, fuzzy
+msgid "Enter the host name of the server."
+msgstr "Geef de hostnaam van de z39.50 server."
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Poort: "
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, fuzzy, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Geef het poortnummer van de z39.50 server. Standaard is %1."
+
+#: fetch/srufetcher.cpp:450
+#, fuzzy
+msgid "Path: "
+msgstr "&Poort: "
+
+#: fetch/srufetcher.cpp:455
+#, fuzzy
+msgid "Enter the path to the database used by the server."
+msgstr "Geef de database naam die door de z39.50 server gebruikt wordt."
+
+#: fetch/srufetcher.cpp:460
+#, fuzzy
+msgid "Format: "
+msgstr "Videosysteem"
+
+#: fetch/srufetcher.cpp:468
+#, fuzzy
+msgid "Enter the result format used by the server."
+msgstr "Geef de database naam die door de z39.50 server gebruikt wordt."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "De afbeelding van de voorzijde kon niet worden geladen."
+
+#: fetch/amazonfetcher.cpp:53
+#, fuzzy
+msgid "Amazon Link"
+msgstr "Amazon (Japan)"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (VS)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (Engeland)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Duitsland)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japan)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (Frankrijk)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Canada)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Amazon.com web services"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "&Land: "
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "Verenigde Staten"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Engeland"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Duitsland"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Japan"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "Frankrijk"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Canada"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon geeft data van verschillende lokale websites. Kies welke u wilt "
+"gebruiken als data bron."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "&Afbeelding grootte: "
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Kleine afbeelding"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Medium afbeelding"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Grote afbeelding"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Geen afbeelding"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"De afbeelding van de hoes kan ook worden gedownload. Een grote hoeveelheid "
+"grote afbeeldingen kan echter wel de snelheid van het programma beïnvloeden."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "&Associate's ID: "
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+"De associate's ID herkent de persoon die toegang heeft op de Amazon.com Web "
+"Services en wordt gebruikt in iedere link naar de Amazon.com website."
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+#, fuzzy
+msgid "z39.50 Server"
+msgstr "z39.50"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "&Database: "
+
+#: fetch/z3950fetcher.cpp:530
+#, fuzzy
+msgid "Enter the database name used by the server."
+msgstr "Geef de database naam die door de z39.50 server gebruikt wordt."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "&Teken set: "
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Geef de tekenset codering die gebruikt wordt door de z39.50 server. De meest "
+"waarschijnlijke keuze is MARC-8 hoewel ISO-8859-1 ook veel gebruikt wordt."
+
+#: fetch/z3950fetcher.cpp:550
+#, fuzzy
+msgid "&Format: "
+msgstr "Videosysteem"
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "&Gebruiker: "
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Optioneel"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Geef de gebruikersnaam van de z39.50 database. De meeste server hebben er "
+"geen nodig."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "Wacht&woord: "
+
+#: fetch/z3950fetcher.cpp:586
+#, fuzzy
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Geef het wachtwoord van de z39.50 database. De meeste server hebben er geen "
+"nodig."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Externe toepassing"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "Verzameling &type:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+"Stel de verzameling type in voor de data die wordt teruggegeven door de "
+"externe toepassing."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:365
+#, fuzzy
+msgid "Set the result type of the data returned from the external application."
+msgstr ""
+"Stel de verzameling type in voor de data die wordt teruggegeven door de "
+"externe toepassing."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "Toepassing &pad: "
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+"Geef het pad naar de toepassing welke moet worden uitgevoerd voor een geldig "
+"Tellico data bestand."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+"Voeg een aantal parameters toe die mogelijk nodig zijn. <b>%1</b> wordt "
+"vervangen door de zoektermen."
+
+#: fetch/execexternalfetcher.cpp:382
+#, fuzzy
+msgid "Arguments"
+msgstr "&Parameters: "
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+#, fuzzy
+msgid "Update"
+msgstr "Item &Aanhalen"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Bronopties"
+
+#: fetch/configwidget.cpp:40
+#, fuzzy
+msgid "Available Fields"
+msgstr "Verzamelingsvelden"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "Internet Movie Database"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Kies IMDB resultaat"
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+"<qt>Uw zoekopdracht heeft meerdere overeenkomsten gevonden. Kies een van de "
+"onderstaande.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Kies een zoekresultaat.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Alternatieve titels"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+#, fuzzy
+msgid "IMDB Rating"
+msgstr "ESRB classificatie"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Leeftijdcategorie"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"De Internet Movie Database gebruikt verschillende servers. Kies welke u wilt "
+"gebruiken."
+
+#: fetch/imdbfetcher.cpp:1132
+#, fuzzy
+msgid "&Maximum cast: "
+msgstr "Maximale afbeelding breedte:"
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+#, fuzzy
+msgid "Download cover &image"
+msgstr "Download hoesafbeelding"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Persoon"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN#"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Trefwoord"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Ruwe zoekopdracht"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:264
+#, fuzzy
+msgid "Distributor"
+msgstr "Regisseur"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr ""
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:343
+#, fuzzy
+msgid "&Username: "
+msgstr "&Gebruiker: "
+
+#: fetch/crossreffetcher.cpp:348
+#, fuzzy
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+"Geef het wachtwoord van de z39.50 database. De meeste server hebben er geen "
+"nodig."
+
+#: fetch/crossreffetcher.cpp:354
+#, fuzzy
+msgid "&Password: "
+msgstr "Wacht&woord: "
+
+#: fetch/gcstarpluginfetcher.cpp:190
+#, fuzzy
+msgid "GCstar Plugin"
+msgstr "GCstar"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+#, fuzzy
+msgid "Set the collection type of the data returned from the plugin."
+msgstr ""
+"Stel de verzameling type in voor de data die wordt teruggegeven door de "
+"externe toepassing."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:420
+#, fuzzy
+msgid "Author: "
+msgstr "Auteur"
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr ""
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr ""
+
+#: newstuff/dialog.cpp:114
+#, fuzzy
+msgid "Version"
+msgstr "Persoon"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr ""
+
+#: newstuff/dialog.cpp:117
+#, fuzzy
+msgid "Release Date"
+msgstr "Jaar van uitgave"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+
+#: newstuff/dialog.cpp:137
+#, fuzzy
+msgid "The name and license of the selected item"
+msgstr "Geselecteerde items inchecken"
+
+#: newstuff/dialog.cpp:140
+#, fuzzy
+msgid "The author of the selected item"
+msgstr "Geselecteerde items uitchecken"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr ""
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr ""
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+
+#: newstuff/dialog.cpp:194
+#, fuzzy
+msgid "A description of the selected item is shown here."
+msgstr "Geselecteerde items inchecken"
+
+#: newstuff/dialog.cpp:224
+#, fuzzy
+msgid "Downloading information..."
+msgstr "Importeer audio cd informatie van de FreeDB"
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Klaar."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr ""
+
+#: newstuff/dialog.cpp:413
+#, fuzzy
+msgid "Installing item..."
+msgstr "Bestand wordt opgeslagen..."
+
+#: translators/bibteximporter.cpp:79
+#, fuzzy
+msgid "No valid bibtex entries were found"
+msgstr "Geen geldige BibTeX items gevonden in het %1 bestand"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "Geen geldige BibTeX items gevonden in het %1 bestand"
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "BibTeX opties"
+
+#: translators/bibteximporter.cpp:287
+#, fuzzy
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Codeer in Unicode (UTF-8)"
+
+#: translators/bibteximporter.cpp:288
+#, fuzzy
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Codeer het geëxporteerde bestand in Unicode (UTF-8)."
+
+#: translators/bibteximporter.cpp:289
+#, fuzzy
+msgid "Use user locale (%1) encoding"
+msgstr "Codeer in user locale (%1)"
+
+#: translators/bibteximporter.cpp:293
+#, fuzzy
+msgid "Read the imported file in the local encoding."
+msgstr "Codeer het geëxporteerde bestande in het lokale formaat."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "Tellico zip bestand"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Tellico-bestanden (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Alle bestanden"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>een Alexandria bibliotheek met de naam <i>%1</i> bestaat al. Ieder "
+"bestaand boek in die bibliotheek kan worden overschreven.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "Er is een XML parsing fout op lijn %1, kolom %2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "De fout melding van QT is:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Dit is van een toekomstige versie van Tellico."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Tellico zet dit bestand om naar een recenter document formaat. Dataverlies "
+"kan optreden wanneer een oudere versie van Tellico wordt gebruikt om het "
+"nieuwe bestand te lezen."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Onbekend"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "Het bestand is leeg."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "Het bestand bevat geen verzamel data."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Ongelezen boeken"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Oude films"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "80er jaren muziek"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Favorieten"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Audiobestanden doorzoeken..."
+
+#: translators/audiofileimporter.cpp:129
+#, fuzzy
+msgid "Bitrate"
+msgstr "BibTeX"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(Diversen)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Audiobestand opties"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Folders recursief doorzoeken"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+"Indien aangevinkt worden folders recursief doorzocht naar audiobestanden."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:348
+#, fuzzy
+msgid "If checked, the file names for each track are added to the entries."
+msgstr "Indien aangevinkt worden de veldnamen afgedrukt als tabel-kop."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:353
+#, fuzzy
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr "Indien aangevinkt worden de veldnamen afgedrukt als tabel-kop."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|CSV bestanden (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "CSV opties"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Gebruik veldtitels als kolom koppen"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr "Indien aangevinkt wordt een koprij toegevoegd met de veldtitels."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Scheidingsteken"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"Behalve een komma mogen ook andere tekens gebruikt worden als "
+"scheidingsteken."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Komma"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Gebruik een komma als scheidingsteken."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Puntkomma"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Gebruik een puntkomma als scheiding teken."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Tab"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Gebruik een tab als scheidingsteken."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Ander"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Gebruik een eigen tekenreeks als scheidingteken."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr ""
+"Een eigen tekenreeks, zoals een dubbele punt, kan worden gebruikt als "
+"scheidingsteken."
+
+#: translators/filelistingimporter.cpp:63
+#, fuzzy
+msgid "Scanning files..."
+msgstr "Audiobestanden doorzoeken..."
+
+#: translators/filelistingimporter.cpp:191
+#, fuzzy
+msgid "File Listing Options"
+msgstr "Afdrukopties"
+
+#: translators/filelistingimporter.cpp:193
+#, fuzzy
+msgid "Recursive folder search"
+msgstr "Folders recursief doorzoeken"
+
+#: translators/filelistingimporter.cpp:194
+#, fuzzy
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+"Indien aangevinkt worden folders recursief doorzocht naar audiobestanden."
+
+#: translators/filelistingimporter.cpp:198
+#, fuzzy
+msgid "Generate file previews"
+msgstr "&Maak lijsten..."
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "ONIX archief"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.zip|ZIP bestanden (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "ONIX Archief opties"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Afbeeldingen in het archief opnemen"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Wanneer aangevinkt worden de afbeeldingen in het document opgenomen in het "
+"ingepakte ONIX archief."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr "<qt>Tellico kon de CD-ROM speler - <i>%1</i> niet benaderen.</qt>"
+
+#: translators/freedbimporter.cpp:196
+#, fuzzy
+msgid "Select CDDB Entry"
+msgstr "Wis item"
+
+#: translators/freedbimporter.cpp:197
+#, fuzzy
+msgid "Select a CDDB entry:"
+msgstr "Kies IMDB resultaat"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>Geen dataingangen gevonden voor deze CD.</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr ""
+"<qt>Tellico is er niet ingeslaagd om de CD zoekopdracht volledig uit te "
+"voeren.</qt>"
+
+#: translators/freedbimporter.cpp:470
+#, fuzzy
+msgid "Various"
+msgstr "(Diversen)"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Audio CD opties"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Data lezen van de CD-ROM speler"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Selecteer of vul de CD-Rom speler in."
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Alleen alle CDDB cache bestanden lezen"
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+"Lees alle data recursief uit alle CDDB cache bestanden in de standaard cache "
+"map."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr ""
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+#, fuzzy
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.csv|CSV bestanden (*.csv)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+#, fuzzy
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.csv|CSV bestanden (*.csv)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "XSLT opties"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "XSLT bestand:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr ""
+"Kies het XSLT bestand dat gebruikt moet worden om de Tellico XML data te om "
+"te zetten."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Alexandria opties"
+
+#: translators/alexandriaimporter.cpp:195
+#, fuzzy
+msgid "&Library:"
+msgstr "Bibliotheek:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "BibTeXML"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|BibTeXML-bestanden (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|XML-bestanden (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Tellico XML opties"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Inclusief afbeeldingen in het XML document"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Indien aangevinkt worden de afbeeldingen ingesloten in het XML bestande als "
+"base64 gecodeerde elementen."
+
+#: translators/importer.h:100
+#, fuzzy
+msgid "Loading data..."
+msgstr "Data importeren..."
+
+#: translators/importer.h:100
+#, fuzzy
+msgid "Loading %1..."
+msgstr "%1 ophalen..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "BibTeX"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|BibTeX-bestanden (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Tekenreeks macro uitbreiden"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Indien aangevinkt worden de tekenreeks macros uitgebreid en worden @ "
+"tekenreeksen{} niet weggeschreven."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Gebruik URL pakket"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr ""
+"Indien aangevinkt worden URL velden verpakt als een \\url omschrijving."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Sla items over met lege citaat sleutels"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr ""
+"Indien aangevinkt, zal ieder item zonder een bibtexcitaat sleutel worden "
+"overgeslagen."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "BibTeX citaatstijl:"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Accolades"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Aanhalingstekens"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"<qt>De citaatstijl die gebruikt wordt wanneer BibTeX bestanden worden "
+"geëxporteerd. Alle veldenwaardes zullen worden vrijgelaten met zowel "
+"accolades als aanhalingstekens.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Selecteer het type verzameling dat moet worden geïmporteerd."
+
+#: translators/csvimporter.cpp:235
+#, fuzzy
+msgid "&First row contains field titles"
+msgstr "De eerste rij bevat de veldtitels"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr "Indien aangevinkt wordt de eerste rij als veldtitel gebruikt."
+
+#: translators/csvimporter.cpp:248
+#, fuzzy
+msgid "&Comma"
+msgstr "Komma"
+
+#: translators/csvimporter.cpp:254
+#, fuzzy
+msgid "&Semicolon"
+msgstr "Puntkomma"
+
+#: translators/csvimporter.cpp:259
+#, fuzzy
+msgid "Ta&b"
+msgstr "Tab"
+
+#: translators/csvimporter.cpp:264
+#, fuzzy
+msgid "Ot&her:"
+msgstr "Ander:"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "De tabel toont de eerste vijf regels van het CSV bestand."
+
+#: translators/csvimporter.cpp:296
+#, fuzzy
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt>Stel iedere kolom in met een overeenkomstig veld in de verzameling door "
+"een kolom te selecteren, een veld te selecteren en dan op de "
+"<i>instellen</i> knop klikken.</qt>"
+
+#: translators/csvimporter.cpp:298
+#, fuzzy
+msgid "Co&lumn:"
+msgstr "Kolom:"
+
+#: translators/csvimporter.cpp:307
+#, fuzzy
+msgid "&Data field in this column:"
+msgstr "Dataveld in deze kolom:"
+
+#: translators/csvimporter.cpp:315
+#, fuzzy
+msgid "&Assign Field"
+msgstr "Veld toewijzen"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Nieuw veld"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|Pilot Database bestanden (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Toon Kolommen"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "PilotDB opties"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Stel PDA back-up flag in voor de database"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+#, fuzzy
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>Laad de ISBN lijst van een bestand.</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Tellico kreeg een fout bij de XSLT verwerking."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr ""
+"Een geldig XSLT bestand is noodzakelijk om het bestand te kunnen importeren."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|XSL bestanden (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|HTML bestanden (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Mensen"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(gegroepeerd naar %1)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "HTML opties"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Veldnamen afdrukken"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr "Indien aangevinkt worden de veldnamen afgedrukt als tabel-kop."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Groepeer de items"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr ""
+"Indien aangevinkt zullen de items gegroepeerd worden onder het gekozen veld."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Exporteer individuele item bestanden"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr ""
+"Indien aangevinkt worden er individuele bestanden aangemaakt voor elk item."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+#, fuzzy
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico kan de afbeelding uit het bestand %1 niet laden."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Databron eigenschappen"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "&Bronnaam: "
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr "De naam identificeert de databron en moet uniek en informatief zijn."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "&Brontype: "
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr ""
+
+#: fetcherconfigdialog.cpp:114
+#, fuzzy
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Indien aangevinkt zullen de items gegroepeerd worden onder het gekozen veld."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Elk veld"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "bevat"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "bevat niet"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "is gelijk"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "is niet gelijk"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "voldoet aan reguliere expressie"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "voldoet niet aan reguliere expressie"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Bewerken..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Uitgebreid Filter"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Filter criteria"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Voldoe aan a&lle van de volgende"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Voldoe aan éé&n van de volgende"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Filter naam:"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "Filter op&slaan"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Eenvoudige tekst"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Paragraaf"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Keuze"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Keuzevakje"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Tabel"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Afhankelijk van"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Datum"
+
+#: entryupdater.cpp:81
+#, fuzzy
+msgid "Updating %1..."
+msgstr "%1 ophalen..."
+
+#: entryupdater.cpp:83
+#, fuzzy
+msgid "Updating entries..."
+msgstr "&Bewerk items..."
+
+#: entryupdater.cpp:85
+#, fuzzy
+msgid "Update Entries"
+msgstr "Bewerk items"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr ""
+
+#: entryupdater.cpp:209
+#, fuzzy
+msgid "Select Match"
+msgstr "Kies IMDB resultaat"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Alle groepen uitklappen"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Alle groepen inklappen"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Filter naar groep"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (Sorteer naar aantal)"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Groeperen"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Import opties"
+
+#: importdialog.cpp:62
+#, fuzzy
+msgid "&Replace current collection"
+msgstr "Vervang huidige verzameling"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr ""
+"Vervang de huidige verzameling met de inhoud van het geïmporteerde bestand."
+
+#: importdialog.cpp:65
+#, fuzzy
+msgid "A&ppend to current collection"
+msgstr "Voeg toe aan de huidige verzameling"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Voeg de inhoud van het geïmporteerde bestand toe aan de huidige "
+"verzameling. Dit is alleen mogelijk wanneer de verzamelingen overeen komen."
+
+#: importdialog.cpp:69
+#, fuzzy
+msgid "&Merge with current collection"
+msgstr "Voeg samen met de huidige verzameling"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Voeg de inhoud van het geïmporteerde bestand samen met de huidige "
+"verzameling. Dit is alleen mogelijk als de verzameling gelijk zijn. De items "
+"moeten exact gelijk zijn om te worden samengevoegd."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "I&mporteren"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|RIS bestanden (*.ris)"
+
+#: importdialog.cpp:277
+#, fuzzy
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.csv|CSV bestanden (*.csv)"
+
+#: importdialog.cpp:281
+#, fuzzy
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdb|Pilot Database bestanden (*.pdb)"
+
+#: importdialog.cpp:285
+#, fuzzy
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.ris|RIS bestanden (*.ris)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico kan het bestand %1 niet laden."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico kan het bestand %1 niet schrijven."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico kan het bestand %1 niet uploaden."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Alleen verzamelingen met dezelfde soort items kunnen worden toegevoegd. Er "
+"worden geen veranderingen gemaakt aan de huidige verzameling."
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Alleen verzamelingen met dezelfde soort items kunnen worden samengevoegd. Er "
+"worden geen veranderingen gemaakt aan de huidige verzameling."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico kan de afbeelding uit het bestand %1 niet laden."
+
+#: entryiconview.cpp:287
+#, fuzzy
+msgid "&Sort By"
+msgstr "&Poort: "
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Uitleen venster"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "De volgende items zijn uitgecheckt:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "Het volgende item is uitgeleend:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "&Uitgeleend aan:"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Geef de naam van degene die items van u leent. U kunt op de knop klikken om "
+"de persoon te selecteren uit uw adresboek."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "&Uitleen datum:"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+"De uitcheck datum is de datum waarop u de items heeft uitgeleend. Standaard "
+"wordt de huidige datum gebruikt."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "&Verval datum:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"De vervaldatum is de datum wanneer de items retour moeten komen. De "
+"vervaldatum is niet verplicht tenzij u het uitgeleende wilt toevoegen aan de "
+"actieve kalender."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Aantekeningen:"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "U kunt aantekeningen toevoegen over het uitlenen."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "&Voeg een herinnering toe aan de actieve kalender"
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"<qt>Wanneer u dit keuze vakje aanvinkt wordt er een <em>Nieuwe taak</em> aan "
+"uw actieve kalender toegevoegd welke kan worden bekeken in KOrganizer. Dit "
+"is alleen actief wanneer u een verloopdatum heeft opgegeven."
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Maak een nieuwe verzameling"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Nieuwe &Boekenverzameling"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Maak een nieuwe boekenverzameling"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Nieuwe B&ibliografie"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Maak een nieuwe BibTeX bibliografie"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Nieuwe &Stripverzameling"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Maak een nieuwe stripverzameling"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Nieuwe &Filmverzameling"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Maak een nieuwe filmverzameling"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Nieuwe &Muziekverzameling"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Maak een nieuwe muziekverzameling"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Nieuwe &Muntenverzameling"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Maak een nieuwe muntenverzameling"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Nieuwe &Postzegelverzameling"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Maak een nieuwe postzegelverzameling"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Nieuwe &Kaartenverzameling"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Maak een nieuwe kaartenverzameling"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Nieuwe &Wijnverzameling"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Maak een nieuwe wijnverzameling"
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Nieuwe &spellen verzameling"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Maak een nieuwe spellenverzameling"
+
+#: mainwindow.cpp:272
+#, fuzzy
+msgid "New Boa&rd Game Collection"
+msgstr "Nieuwe &spellen verzameling"
+
+#: mainwindow.cpp:274
+#, fuzzy
+msgid "Create a new board game collection"
+msgstr "Maak een nieuwe spellenverzameling"
+
+#: mainwindow.cpp:280
+#, fuzzy
+msgid "New &File Catalog"
+msgstr "Nieuw veld"
+
+#: mainwindow.cpp:282
+#, fuzzy
+msgid "Create a new file catalog"
+msgstr "Maak een nieuwe verzameling"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Nieuwe &Eigen verzameling"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Maak een nieuwe eigen verzameling"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Open een bestaand document"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Open een recent gebruikt bestand"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Sla het huidige document op"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Sla het huidig document op als..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Druk de inhoud van het document af..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Sluit de toepassing"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Importeer verzameldata uit andere formaten"
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Importeer Tellico data..."
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Importeer een ander Tellico data bestand"
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "Importeer CSV data..."
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Importeer een CSV bestand"
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "Importeer MODS data..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Importeer een MODS data bestand"
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Importeer Alexandria data..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Importeer data van het Alexandria boekenverzameling programma"
+
+#: mainwindow.cpp:352
+#, fuzzy
+msgid "Import Delicious Library Data..."
+msgstr "Importeer Tellico data..."
+
+#: mainwindow.cpp:353
+#, fuzzy
+msgid "Import data from Delicious Library"
+msgstr "Importeer metadata uit audio bestanden"
+
+#: mainwindow.cpp:359
+#, fuzzy
+msgid "Import Referencer Data..."
+msgstr "Importeer RIS data..."
+
+#: mainwindow.cpp:360
+#, fuzzy
+msgid "Import data from Referencer"
+msgstr "Importeer een RIS referentie bestand"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Importeer BibTeX data..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Importeer een BibTeX bibliografie bestand"
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Importeer BibTeXML data..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Importeer een BibTeXML bibliografie bestand"
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "Importeer RIS data..."
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Importeer een RIS referentie bestand"
+
+#: mainwindow.cpp:387
+#, fuzzy
+msgid "Import PDF File..."
+msgstr "Bestand importeren"
+
+#: mainwindow.cpp:388
+#, fuzzy
+msgid "Import a PDF file"
+msgstr "Importeer een CSV bestand"
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Importeer audio file metadata..."
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Importeer metadata uit audio bestanden"
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Importeer audio cd data..."
+
+#: mainwindow.cpp:405
+#, fuzzy
+msgid "Import audio CD information"
+msgstr "Importeer audio cd informatie van de FreeDB"
+
+#: mainwindow.cpp:414
+#, fuzzy
+msgid "Import GCstar Data..."
+msgstr "Importeer CSV data..."
+
+#: mainwindow.cpp:415
+#, fuzzy
+msgid "Import a GCstar data file"
+msgstr "Importeer een MODS data bestand"
+
+#: mainwindow.cpp:421
+#, fuzzy
+msgid "Import Griffith Data..."
+msgstr "Importeer CSV data..."
+
+#: mainwindow.cpp:422
+#, fuzzy
+msgid "Import a Griffith database"
+msgstr "Exporteer naar een PilotDB database"
+
+#: mainwindow.cpp:428
+#, fuzzy
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Importeer audio cd data..."
+
+#: mainwindow.cpp:429
+#, fuzzy
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Importeer een ander Tellico data bestand"
+
+#: mainwindow.cpp:435
+#, fuzzy
+msgid "Import File Listing..."
+msgstr "Bestand importeren"
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr ""
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "Importeer XSL Transformatie..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Importeer een bestand met gebruik van een XSL-transformatie"
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Exporteer"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Exporteer de verzameling data naar andere formaten"
+
+#: mainwindow.cpp:461
+#, fuzzy
+msgid "Export to XML..."
+msgstr "Exporteer naar HTML..."
+
+#: mainwindow.cpp:462
+#, fuzzy
+msgid "Export to a Tellico XML file"
+msgstr "Exporteer naar een Tellico XML bestand"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Exporteer naar Zip..."
+
+#: mainwindow.cpp:469
+#, fuzzy
+msgid "Export to a Tellico Zip file"
+msgstr "Exporteer naar een Tellico XML bestand"
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "Exporteer naar HTML..."
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Exporteer naar een HTML bestand"
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "Exporteer naar CSV..."
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Exporteer naar een Comma Separated Value bestand"
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "Exporteer naar PilotDB..."
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Exporteer naar een PilotDB database"
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Exporteer naar Alexandria..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Exporteer naar een Alexandria bibliotheek"
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Exporteer naar BibTeX..."
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Exporteer naar een BibTeX bestand"
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Exporteer naar BibTeXML..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Exporteer naar een BibTeXML-bestand"
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "Exporteer naar ONIX..."
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Exporteer naar een ONIX bestand"
+
+#: mainwindow.cpp:524
+#, fuzzy
+msgid "Export to GCfilms..."
+msgstr "Exporteer naar CSV..."
+
+#: mainwindow.cpp:525
+#, fuzzy
+msgid "Export to a GCfilms data file"
+msgstr "Exporteer naar een BibTeX bestand"
+
+#: mainwindow.cpp:531
+#, fuzzy
+msgid "Export to GCstar..."
+msgstr "Exporteer naar CSV..."
+
+#: mainwindow.cpp:532
+#, fuzzy
+msgid "Export to a GCstar data file"
+msgstr "Exporteer naar een BibTeX bestand"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "Exporteer naar XSL Transformatie..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Exporteer een bestand met gebruik van een XSL-transformatie"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Knip de geselecteerde tekst en plaats het op het klembord"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Kopieer de geselecteerde tekst naar het klembord"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Plak de inhoud van het klembord"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Selecteer alle item in de verzameling"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Deselecteer alle item in de verzameling"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Internet zoekopdracht..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Zoek op het internet..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "Uitgebreid &Filter..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Filter de verzameling"
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&Nieuw item..."
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Maak een nieuw item"
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "&Bewerk item..."
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Bewerk de geselecteerde items"
+
+#: controller.cpp:621 mainwindow.cpp:577
+#, fuzzy
+msgid "D&uplicate Entry"
+msgstr "Item &Aanhalen"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Kopieer de geselecteerde items"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "&Wis item"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Wis de geselecteerde items"
+
+#: mainwindow.cpp:585
+#, fuzzy
+msgid "&Merge Entries"
+msgstr "&Wis items"
+
+#: mainwindow.cpp:588
+#, fuzzy
+msgid "Merge the selected entries"
+msgstr "Wis de geselecteerde items"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "&Maak lijsten..."
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Maak verzameling lijsten"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "&Uitchecken..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Geselecteerde items uitchecken"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "&Inchecken"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Geselecteerde items inchecken"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "&Hernoem verzameling..."
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Hernoem de verzameling"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "Verzamelings&velden..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Pas de verzamelingsvelden aan"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "Converteer naar een &Bibliografie"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Converteer een boekenverzameling naar een bibliografie"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "Tekenreeks &Macros..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Bewerk de BibTeX tekenreeks macros"
+
+#: mainwindow.cpp:626
+#, fuzzy
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Kopieer de geselecteerde tekst naar het klembord"
+
+#: mainwindow.cpp:627
+#, fuzzy
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Kopieer de geselecteerde tekst naar het klembord"
+
+#: mainwindow.cpp:632
+#, fuzzy
+msgid "Cite Entry in &LyX"
+msgstr "Item &Aanhalen"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "De geselecteerde items in LyX aanhalen"
+
+#: mainwindow.cpp:638
+#, fuzzy
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Item &Aanhalen"
+
+#: mainwindow.cpp:639
+#, fuzzy
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "De geselecteerde items in LyX aanhalen"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, fuzzy, no-c-format
+msgid "&Update Entry"
+msgstr "Item &Aanhalen"
+
+#: mainwindow.cpp:652
+#, fuzzy
+msgid "All Sources"
+msgstr "Bron"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr ""
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Groe&psweergave"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Groepweergave aan/uitzetten"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Verberg groe&psweergave"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Toon item &editor"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Item editor aan/uitzetten"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "Verberg item &editor"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Toon item &weergave"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Itemweergave aan/uitzetten"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "Verberg item &weergave"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Verander groepering"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "&Groepering selectie"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Verander de groepering van de verzameling"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Filter"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Wis filter"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Filter hier..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Groepen"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt>De <i>Groepweergave</i> sorteert de items in groepen gebaseerd op een "
+"geselecteerd veld.</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt>De <i>Kolomweergave</i> toont de inhoud van meerdere velden voor ieder "
+"item.</qt>"
+
+#: mainwindow.cpp:831
+#, fuzzy
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Tellico - een verzameling beheerder voor KDE"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Maak een nieuw document..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Bestand wordt geopend..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Open bestand"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Bestand wordt opgeslagen..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr ""
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr ""
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Bestand wordt opgeslagen onder een nieuwe naam..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Bezig met afdrukken..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"De verzameling wordt momenteel gefilterd en toont een selectie van alle "
+"items. Alleen de zichtbare items worden afgedrukt. Doorgaan?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Document verwerken..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Programma wordt afgesloten..."
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Aantal items: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 gefilterd; %2 geselecteerd)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 gefilterd)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 geselecteerd)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Druk %1 af"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Pagina %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Controleer uw installatie."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Data importeren..."
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Bestand importeren"
+
+#: mainwindow.cpp:1864
+#, fuzzy
+msgid "Import Directory"
+msgstr "Regisseur"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Data exporteren..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Exporteer als"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Tekenreeks macros"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Macro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Tekenreeks"
+
+#: mainwindow.cpp:1999
+#, fuzzy
+msgid "Creating citations..."
+msgstr "Leeftijdcategorie"
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Filters"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt>De <i>Filter weergave</i> toont de items die voldoen aan bepaalde "
+"filterregels.</qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Uitgeleend"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt>De <i>Uitleen weergave</i> toont een lijst van mensen die items van u "
+"hebben geleend.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr ""
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico kan de afbeelding niet laden - %1."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+"Een bestand met naam \"%1\" bestaat al. Wilt u dit bestand overschrijven?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Bestand overschrijven?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Overschrijven"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Filter (gesorteerd naar aantal)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Weet u zeker dat u dit item wilt verwijderen?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Wis item"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Weet u zeker dat u deze items wilt verwijderen?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Meerdere items wissen"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "&Bewerk items..."
+
+#: controller.cpp:627
+#, fuzzy
+msgid "D&uplicate Entries"
+msgstr "Bewerk items"
+
+#: controller.cpp:628
+#, fuzzy
+msgid "&Update Entries"
+msgstr "Bewerk items"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "&Wis items"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+"De onderstaande items zijn al uitgeleend. Tellico ondersteunt op dit moment "
+"het meermaals uitlenen van één item niet."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Standaard kalender"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"Op dit moment ondersteunt Tellico alleen lokale kalenders. De actieve "
+"kalender bevindt zich op een andere computer. Hierdoor kunnen uw uitleningen "
+"niet worden toegevoegd."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Actieve kalender"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 moet \"%2\" terugbrengen"
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(Leeg)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - een verzameling beheerder voor KDE"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Open niet opnieuw het laatst geopende bestand"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Importeer <filename> als een BibTeX-bestand"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Importeer <filename> als een MODS-bestand"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Importeer <filename> als een RIS-bestand"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Te openen bestand"
+
+#: main.cpp:42
+#, fuzzy
+msgid "Data source scripts"
+msgstr "Databron opties"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Pictogrammen"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Auteur van de btparse bibliotheek"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr ""
+
+#: main.cpp:50
+#, fuzzy
+msgid "Author of libcsv library"
+msgstr "Auteur van de btparse bibliotheek"
+
+#: main.cpp:52
+#, fuzzy
+msgid "Author of rtf2html library"
+msgstr "Auteur van de btparse bibliotheek"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Verzamelingsvelden"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Huidige Velden"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "&Nieuw"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Voeg een nieuw veld toe aan de verzameling"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "&Wis"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Verwijder een veld uit de verzameling"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Verplaats dit veld omhoog in de lijst. De volgorde is belangrijk voor de "
+"lay-out van de item editor."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Verplaats dit veld omlaag in de lijst. De volgorde is belangrijk voor de "
+"lay-out van de item editor."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Veldeigenschappen"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "&Titel:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "De titel van het veld"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "T&ype:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "Het type van het veld bepaald welke waardes mogen worden gebruikt. "
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "<i>Eenvoudige tekst</i> wordt gebruikt voor de meeste velden. "
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "<i>Paragraaf</i> is voor grote tekstblokken. "
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Keuze</i> beperkt de invoer tot bepaalde waardes. "
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "<i>Keuzevakje</i> wordt gebruikt is voor een eenvoudig ja/nee waarde. "
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr "<i>Getal</i> geeft aan dat het veld een numerieke waarde bevat. "
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+"<i>URL</i> is voor velden de verwijzen naar een webkoppeling of een "
+"verwijzing naar andere bestanden. "
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr "Een <i>Tabel</i> kan een enkele of dubbele kolom met waarden zijn. "
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "Een <i>afbeelding</i> veld bevat een afbeelding. "
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+"Een <i>datum</i> veld kan worden gebruikt voor waardes met een dag, maand en "
+"jaar. "
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+"Een <i>Waardering</i> veld gebruikt een aantal sterren om de waardering aan "
+"te geven. "
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"Een <i>Afhankelijk van</i> veld is afhankelijk van de waarde van andere "
+"velden en wordt opgemaakt volgens veld omschrijving. "
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"Een <i>Alleen lezen</i> veld is voor interne waarden, mogelijk handig voor "
+"import en export. "
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "Cate&gorie:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr "De veldcategorie bepaald waar het veld wordt geplaatst in de editor."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "Om&schrijving:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"De omschrijving is een geheugensteuntje voor de inhoud van een veld. Voor "
+"<i>Afhankelijk van</i> velden is de omschrijving een tekenreeks zoals "
+"\"%{year} %{title}\" waarbij de velden worden vervangen in de tekenreeks."
+
+#: collectionfieldsdialog.cpp:193
+#, fuzzy
+msgid "&Default value:"
+msgstr "Standaard kalender"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:203
+#, fuzzy
+msgid "A&llowed values:"
+msgstr "&Toegestaan:"
+
+#: collectionfieldsdialog.cpp:208
+#, fuzzy
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>Voor <i>Keuze</i> velden zijn dit de enige mogelijke waardes. Ze worden "
+"geplaatst in een keuze vak.</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "&Uitgebreide eigenschappen:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "&Instellen..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"Uitgebreide veldeigenschappen worden gebruikt om bepaalde dingen te "
+"specificeren zoals het bijbehorende BibTeX veld."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Opmaak opties"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Geen opmaak"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+"Deze optie voorkomt dat het veld automatisch ooit wordt opgemaakt of "
+"voorzien van hoofdletters."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Alleen auto-hoofdletters toestaan"
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+"Deze optie zorgt dat het veld auto-hoofdletters krijgt maar niet speciaal "
+"wordt opgemaakt."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Opmaak als titel"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Deze optie maakt het veld op als een titel met auto-hoofdletters, maar doet "
+"dit alleen als deze opties als algemeen zijn ingesteld."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Opmaak als naam"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Deze optie maakt het veld op als een naam met auto-hoofdletters, maar doet "
+"dit alleen als deze opties als algemeen zijn ingesteld."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Veld Opties"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Auto-aanvullen aanzetten"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Indien aangevinkt wordt auto-aanvullen van KDE aangezet in het invulvak van "
+"dit veld."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Meerdere waarden toestaan"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Indien aangevinkt zal Tellico de waardes in het veld ontleden in meerdere "
+"waardes gescheiden door een puntkomma."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Groepering toestaan"
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Indien aangevinkt kan dit veld worden gebruikt om item te groeperen in de "
+"groepweergave."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr ""
+"Zet de veldeigenschappen van de geselecteerde velden terug naar de standaard "
+"waarden."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Bewerk velden"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Het verwijderen van toegestane waardes uit het <i>%1</i> veld die "
+"voorkomen in de verzameling kan data corruptie veroorzaken. Wilt u de "
+"veranderde waardes behouden of terugkeren naar de huidige waardes?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Bewaar veranderde waarden"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Veldeigenschappen terugzetten"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Weet u zeker dat u de eigenschappen van het <em>%1</em> veld terug "
+"wilt zetten naar de standaard waarde?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Terugzetten"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Uitgebreide veldeigenschappen"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr "Een veld met deze titel bestaat al. Kies een andere titel."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr "<qt>De categorie mag niet leeg zijn. Geef een categorie op.</qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>Een veld mag niet in dezelfde categorie zitten als een "
+"<em>Paragraaf</em>, <em>Tabel</em> of <em>Afbeelding</em> veld. Geef een "
+"andere categorie.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"Een veldtitel mag gelijk zijn aan een bestaande categorie. Geef een andere "
+"titel."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+"Het bereik van een waarderingsveld moet tussen de 1 en 10 zijn en de "
+"ondergrens mag niet hoger zijn dan de bovengrens. Geef andere waardes."
+
+#: collectionfieldsdialog.cpp:952
+#, fuzzy
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "Tabellen kunnen maximaal vijf kolommen hebben."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Het huidige bestand is aangepast.\n"
+"Wil U dit opslaan?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Niet opgeslagen veranderingen"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Kies lener"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Tellico instellen"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Algemene opties"
+
+#: configdialog.cpp:201
+#, fuzzy
+msgid "&Reopen file at startup"
+msgstr "Open het bestand opnieuw bij het opstarten"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Indien aangevinkt wordt het laatst geopende bestand bij het opstarten "
+"opnieuw geopend."
+
+#: configdialog.cpp:207
+#, fuzzy
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "Toon \"Tip van de dag\" bij het opstarten"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr ""
+"Indien aangevinkt wordt de \"Tip van de dag\" getoond bij het opstarten."
+
+#: configdialog.cpp:213
+#, fuzzy
+msgid "Image Storage Options"
+msgstr "Afbeeldingsopties"
+
+#: configdialog.cpp:214
+#, fuzzy
+msgid "Store images in data file"
+msgstr "Afbeeldingen in het archief opnemen"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr ""
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr ""
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Opmaakopties"
+
+#: configdialog.cpp:227
+#, fuzzy
+msgid "Auto capitalize &titles and names"
+msgstr "Auto-hoofdletters voor titels en namen"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Indien aangevinkt zullen titels en namen automatisch hoofdletters krijgen."
+
+#: configdialog.cpp:232
+#, fuzzy
+msgid "Auto &format titles and names"
+msgstr "Automatische opmaak titels en namen"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr "Indien aangevinkt zullen titels en namen automatisch opgemaakt worden."
+
+#: configdialog.cpp:240
+#, fuzzy
+msgid "No capitali&zation:"
+msgstr "Alleen auto-hoofdletters toestaan"
+
+#: configdialog.cpp:243
+#, fuzzy
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Een lijst van voorvoegsels, meerdere waardes moeten worden gescheiden "
+"door een puntkomma.</qt>"
+
+#: configdialog.cpp:249
+#, fuzzy
+msgid "Artic&les:"
+msgstr "Lidwoorden:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>Een lijst van woorden die als lidwoord moeten worden aangezien als ze "
+"het eerste woord in een titel zijn. Meerdere waarden moeten een puntkomma "
+"gescheiden woorden.</qt>"
+
+#: configdialog.cpp:259
+#, fuzzy
+msgid "Personal suffi&xes:"
+msgstr "Achtervoegsels:"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Een lijst van achtervoegsels, meerdere waardes moeten worden gescheiden "
+"door een puntkomma.</qt>"
+
+#: configdialog.cpp:268
+#, fuzzy
+msgid "Surname &prefixes:"
+msgstr "Voorvoegsels:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Een lijst van voorvoegsels, meerdere waardes moeten worden gescheiden "
+"door een puntkomma.</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Afdrukken"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Afdrukopties"
+
+#: configdialog.cpp:302
+#, fuzzy
+msgid "&Format titles and names"
+msgstr "Opmaak titels en namen"
+
+#: configdialog.cpp:306
+#, fuzzy
+msgid "&Print field headers"
+msgstr "Veldnamen afdrukken"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Groeperingsopties"
+
+#: configdialog.cpp:313
+#, fuzzy
+msgid "&Group the entries"
+msgstr "Groepeer de items"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Afbeeldingsopties"
+
+#: configdialog.cpp:323
+#, fuzzy
+msgid "Maximum image &width:"
+msgstr "Maximale afbeelding breedte:"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"De maximale breedte van de afbeeldingen in de afdruk. De verhoudingen "
+"blijven behouden."
+
+#: configdialog.cpp:336
+#, fuzzy
+msgid "&Maximum image height:"
+msgstr "Maximale afbeelding hoogte:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"De maximale hoogte van de afbeeldingen in de afdruk. De verhoudingen blijven "
+"behouden."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Sjablonen"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Sjabloonopties"
+
+#: configdialog.cpp:369
+#, fuzzy
+msgid "Template:"
+msgstr "Sjablonen"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+
+#: configdialog.cpp:380
+#, fuzzy
+msgid "&Preview..."
+msgstr "&Nieuw..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr ""
+
+#: configdialog.cpp:398
+#, fuzzy
+msgid "Font Options"
+msgstr "Opmaak opties"
+
+#: configdialog.cpp:405
+#, fuzzy
+msgid "Font:"
+msgstr "Maand"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:415
+#, fuzzy
+msgid "Size:"
+msgstr "Gesigneerd"
+
+#: configdialog.cpp:425
+#, fuzzy
+msgid "Color Options"
+msgstr "CSV opties"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr ""
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr ""
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr ""
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr ""
+
+#: configdialog.cpp:469
+#, fuzzy
+msgid "Manage Templates"
+msgstr "Sjablonen"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr ""
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr ""
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr ""
+
+#: configdialog.cpp:484
+#, fuzzy
+msgid "Click to download additional templates via the Internet."
+msgstr ""
+"Klik om een tekstvenster te open om meerdere ISBN waardes in te geven of te "
+"bewerken."
+
+#: configdialog.cpp:487
+#, fuzzy
+msgid "Delete..."
+msgstr "Kies een afbeelding..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr ""
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Databronnen"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Databron opties"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Bron"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr ""
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+
+#: configdialog.cpp:521
+#, fuzzy
+msgid "Move &Down"
+msgstr "Ver&wijder"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "&Nieuw..."
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr ""
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Wijzig..."
+
+#: configdialog.cpp:533
+#, fuzzy
+msgid "Click to modify the selected data source."
+msgstr "Geselecteerde items uitchecken"
+
+#: configdialog.cpp:536
+#, fuzzy
+msgid "Click to delete the selected data source."
+msgstr "Wis de geselecteerde items"
+
+#: configdialog.cpp:539
+#, fuzzy
+msgid "Click to download additional data sources via the Internet."
+msgstr ""
+"Klik om een tekstvenster te open om meerdere ISBN waardes in te geven of te "
+"bewerken."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr ""
+
+#: configdialog.cpp:1049
+#, fuzzy
+msgid "Delete Template"
+msgstr "Filter wissen"
+
+#: configdialog.cpp:1050
+#, fuzzy
+msgid "Select template to delete:"
+msgstr "Kies de database die doorzocht moet worden"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "Lener"
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Inchecken"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Bewerk uitlenen..."
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "Lener (gesorteerd naar aantal)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "Mijn verzameling"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Boekenverzameling"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Stripverzameling"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Filmverzameling"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Muziekverzameling"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Muntverzameling"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Postverzameling"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Wijnverzameling"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Kaartenverzameling"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Spellen verzameling"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr ""
+
+#: collectionfactory.cpp:135
+#, fuzzy
+msgid "Board Game Collection"
+msgstr "Spellen verzameling"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Eigen verzameling"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+"<qt>De <i>Itemweergave</i> toont een opgemaakte weergave van items</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt>De <i>Pictogramweergave</i> toont een ieder item in de verzameling of "
+"groep als een pictogram, dit is afbeelding van dat item indien aanwezig</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Exportopties"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Opmaak"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Alle velden opmaken"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Indien aangevinkt worden de velden automatisch opgemaakt volgens hun formaat "
+"type."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Alleen geselecteerde item exporteren"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr "Indien aangevinkt worden alleen de geselecteerde items geëxporteerd."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Codering"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Codeer in Unicode (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Codeer het geëxporteerde bestand in Unicode (UTF-8)."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Codeer in user locale (%1)"
+
+#: exportdialog.cpp:72
+#, fuzzy
+msgid "Encode the exported file in the local encoding."
+msgstr "Codeer het geëxporteerde bestande in het lokale formaat."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "&Zoeken"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "&Stoppen"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Internet zoekopdracht"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Zoek opdracht"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr "&Zoeken:"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+"Geef een zoekwaarde.Een ISBN zoekopdracht moet het volledige ISBN bevatten."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Kies de wijze van zoeken"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Klik om het zoeken te starten of te stoppen"
+
+#: fetchdialog.cpp:134
+#, fuzzy
+msgid "&Multiple ISBN/UPC search"
+msgstr "&Meervoudige ISBN zoekopdracht"
+
+#: fetchdialog.cpp:135
+#, fuzzy
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr "Vink aan om meerdere ISBN waardes te zoeken."
+
+#: fetchdialog.cpp:138
+#, fuzzy
+msgid "Edit List..."
+msgstr "Bewerk &ISBN lijst..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+"Klik om een tekstvenster te open om meerdere ISBN waardes in te geven of te "
+"bewerken."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "&Zoekbron:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Kies de database die doorzocht moet worden"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"Wanneer er resultaten gevonden zijn worden deze toegevoegd aan deze lijst. "
+"Wanneer u een resultaat selecteert wordt het volledige item onderstaand "
+"getoond."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"Een item kan hier worden getoond voordat u het aan de huidige verzameling "
+"toevoegt"
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "Item &toevoegen"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Voeg het geselecteerde toe aan de huidige verzameling"
+
+#: fetchdialog.cpp:198
+#, fuzzy
+msgid "Get More Results"
+msgstr "Kies IMDB resultaat"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr ""
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Wis alle zoekvelden en resultaten"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Zoekopdracht beëindigen..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Zoeken..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "De zoekopdracht gaf geen items."
+
+#: fetchdialog.cpp:372
+#, fuzzy, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr "De zoekopdracht gaf %n items."
+
+#: fetchdialog.cpp:412
+#, fuzzy
+msgid "No results were found for the following ISBN values:"
+msgstr "<qt>Geen items gevonden voor de volgende ISBN waardes:</qt>"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "%1 ophalen..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr "Er zijn geen internet bronnen beschikbaar voor uw huidige verzameling."
+
+#: fetchdialog.cpp:594
+#, fuzzy
+msgid "Edit ISBN/UPC Values"
+msgstr "Bewerk ISBN waardes"
+
+#: fetchdialog.cpp:598
+#, fuzzy
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Geef de ISBN waardes, één per regel.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "&Laad van bestand..."
+
+#: fetchdialog.cpp:605
+#, fuzzy
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Laad de ISBN lijst van een bestand.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>Een ISBN zoekopdracht kan maximaal 100 ISBN waardes tegelijkertijd aan. "
+"Alleen de eerste 100 waardes in uw lijst worden gebruikt.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Bewerk item"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Nieuw item"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "Item op&slaan"
+
+#: entryeditdialog.cpp:77
+#, fuzzy
+msgid "Go to the previous entry in the collection"
+msgstr "Selecteer alle item in de verzameling"
+
+#: entryeditdialog.cpp:82
+#, fuzzy
+msgid "Go to the next entry in the collection"
+msgstr "Selecteer alle item in de verzameling"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Wilt u deze items bewerken?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Meedere items bewerken"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr ""
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Bewerk items"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "Items op&slaan"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"Het huidige item is bewerkt.\n"
+"Wilt u deze veranderen invoeren?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Item opslaan"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Verzameling lijst"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "&Lijst sjabloon:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "&Genereren"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr "Selecteer een lijst sjabloon en klik op <em>Genereren</em>."
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+"Bij sommige lijsten duurt het genereren even, vooral bij grote verzamelingen."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Weet u zeker dat u dit item wilt verwijderen?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Filter wissen?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Nieuwe verzamelingsnaam:"
+
+#: tellico_kernel.cpp:377
+#, fuzzy
+msgid "Entry 1"
+msgstr "Item type"
+
+#: tellico_kernel.cpp:378
+#, fuzzy
+msgid "Entry 2"
+msgstr "Item type"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr ""
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+#, fuzzy
+msgid "Merge Entries"
+msgstr "Wis items"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr ""
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico kan het standaard stylesheet niet vinden."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Nieuw"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Verzameling"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Verzameling werkbalk"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Liese de Vos, Fred Marchee"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "onlineit@mail.be, fredmarchee@gmail.com"
+
+#: entrymerger.cpp:35
+#, fuzzy
+msgid "Merging entries..."
+msgstr "&Bewerk items..."
+
+#: entrymerger.cpp:49
+#, fuzzy
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Aantal items: %1"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>...dat wanneer een boek meer dan een schrijver heeft u de namen\n"
+"moet scheiden met behulp van een puntkomma. Tellico weet dan dat\n"
+"de namen gescheiden moeten worden en apart moet worden gebruikt</p>\n"
+"<p>Ieder ander veld waar meerdere waardes zijn toegestaan moeten\n"
+"worden ingevuld op dezelfde manier met een puntkomma (;) die iedere\n"
+"waarde scheid</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>...dat u de velden die getoond woorden in de lijstweergave door\n"
+"recht te klikken op kolom kop.\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>...dat u velden kunt toevoegen, bewerken of veranderen in de verzameling\n"
+"met behulp van de veld editor. De pijl knoppen onder de veldlijst kan "
+"worden\n"
+"gebruikt om de positie van het veld te veranderen waardoor de plaats in de\n"
+"item editor wordt gewijzigd.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>...dat wanneer u wilt filteren op een keuzevak veld de waarde \"ja\" \n"
+"moet worden gebruikt. Wanneer u bijvoorbeeld alle science fiction boeken\n"
+"die u nog niet heeft gelezen wilt tonen kies dan de <em>Voldoe aan alle\n"
+"van de volgende</em> knop en stel de volgende regels in; \"Genre\"\n"
+"bevat \"Science Fiction\" (geen aanhalingtekens) en de tweede regel\n"
+"\"Gelezen\" \"bevat niet\" \"ja\" (geen aanhalingstekens).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>...wanneer een speciaal karakter wordt gebruikt in het snelfilter\n"
+"dit wordt geïnterpreteerd als een reguliere expressie.</p>\n"
+"<p>Om alleen boeken die bijvoorbeeld door Weber of Bujold zijn geschreven \n"
+"type dan \"weber|bujold\" (geen aanhalingstekens) in het filterveld</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>...dat u meerdere items tegelijkertijd kunt bewerken, door de Shift of "
+"Ctrl toets\n"
+"ingedrukt te houden en meerdere items te selecteren.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>...dat u een bestaande boekenverzameling kunt omzetten naar een\n"
+"bibliografie die vervolgens kan worden geëxporteerd naar BibTeX of "
+"BibTeXML</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>...dat u tekenreeks macros kunt toevoegen, bewerken en wissen voor "
+"bibliografieën.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>...dat wanneer meer dan een veld is opgemaakt als een naam een\n"
+"extra groep genaamd \"mensen\"wordt toegevoegd aan de verzameling\n"
+"zodat deze groepen verzameld kunnen worden</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>..dat u het uiterlijk van de afdruk kunt aanpassen door het bestand\n"
+"<tt>tellico-printing.xsl</tt> te bewerken. Het bestand geneert HTML en de "
+"CSS\n"
+"binnen het stylesheet regelt dingen als het lettertype, de kantlijnen "
+"enz.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>..dat u een XSL stylesheet kunt importeren die een \n"
+"geldige Tellico XML uitvoer maakt</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr "<p>...dat dubbelklikken op een item de item editor opent.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>... dat u HTML tags kunt gebruiken bij de paragraaf velden voor de juiste "
+"opmaak\n"
+"zoals &lt;b&gt;bold&lt;/b&gt; of &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>...dat u in de gedetailleerde weergave een letter op uw toetsenbord\n"
+"kunt indrukken waarna u naar het volgende item dat met deze letter begint "
+"springt.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Album"
+
+#: xslt.cpp:3
+#, fuzzy
+msgid "This template is meant for music collections only."
+msgstr "Maak een nieuwe muziekverzameling"
+
+#: xslt.cpp:5
+#, fuzzy
+msgid "Total:"
+msgstr "&Titel:"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr "Fancy"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "Standaard"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Compact"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Video"
+
+#: xslt.cpp:14 xslt.cpp:43
+#, fuzzy
+msgid "This template is meant for video collections only."
+msgstr "Maak een nieuwe filmverzameling"
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Groep samenvatting"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Groep samenvatting"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Totaal aantal velden:"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Totaal aantal items:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+#, fuzzy
+msgid "Generated by Tellico"
+msgstr "Gegenereerd door"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Verschillende waarden:"
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Afbeeldingen lijst"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Uitleen weergave"
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Uitleen datum"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Notities"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Verval datum"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Groepsweergave"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Titel lijst (horizontaal)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Titel lijst (verticaal)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Kolomweergave"
+
+#: xslt.cpp:42
+#, fuzzy
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "Kolomweergave"
+
+#: xslt.cpp:44
+#, fuzzy
+msgid "Search"
+msgstr "&Zoeken"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr ""
+
+#: z3950.cpp:6
+#, fuzzy
+msgid "Sudoc (France)"
+msgstr "Amazon (Frankrijk)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr ""
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr ""
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr ""
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr ""
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr ""
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr ""
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr ""
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr ""
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr ""
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr ""
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr ""
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr ""
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr ""
+
+#, fuzzy
+#~ msgid "CrossRef"
+#~ msgstr "Verwijzingen"
+
+#, fuzzy
+#~ msgid "MODS"
+#~ msgstr "Mac OS"
+
+#~ msgid "GCstar"
+#~ msgstr "GCstar"
+
+#, fuzzy
+#~ msgid "Griffith"
+#~ msgstr "Geschenk"
+
+#, fuzzy
+#~ msgid "Referencer"
+#~ msgstr "Verwijzingen"
+
+#~ msgid "Comics"
+#~ msgstr "Strips"
+
+#~ msgid "Stamps"
+#~ msgstr "Postzegels"
+
+#~ msgid "Coins"
+#~ msgstr "Munten"
+
+#~ msgid "Books"
+#~ msgstr "Boeken"
+
+#~ msgid "Wines"
+#~ msgstr "Wijnen"
+
+#~ msgid "Videos"
+#~ msgstr "Films"
+
+#~ msgid "Games"
+#~ msgstr "Spellen"
+
+#~ msgid "Cards"
+#~ msgstr "Kaarten"
+
+#~ msgid "Entries"
+#~ msgstr "Items"
+
+#~ msgid "Albums"
+#~ msgstr "Albums"
+
+#, fuzzy
+#~ msgid "Copac"
+#~ msgstr "Komma"
+
+#~ msgid "Tellico"
+#~ msgstr "Tellico"
+
+#~ msgid "&Copy Entry"
+#~ msgstr "&Kopieer item"
+
+#~ msgid "&Copy Entries"
+#~ msgstr "Items &kopiëren"
+
+#~ msgid "<qt>Multiple records were found to match the CD.</qt>"
+#~ msgstr "<qt>Meerdere dataingangen gevonden voor deze CD.</qt>"
+
+#~ msgid "Remo&ve"
+#~ msgstr "Ver&wijder"
+
+#~ msgid "Scanning CDDB cache files..."
+#~ msgstr "CDDB cache bestanden doorzoeken..."
+
+#~ msgid "Collection &type: "
+#~ msgstr "Verzameling &type: "
+
+#~ msgid "Save Entries"
+#~ msgstr "Items opslaan"
+
+#~ msgid ""
+#~ "_: Save (Entry Title)\n"
+#~ "Save %1"
+#~ msgstr "%1 opslaan"
+
+#~ msgid ""
+#~ "Tellico currently supports five source types: Amazon.com, IMDB, z39.50, "
+#~ "Entrez, and external applications."
+#~ msgstr ""
+#~ "Tellico ondersteunt momenteel vijf brontypen: Amazon, IMDB, z39.50 Entrez en "
+#~ "externe toepassingen."
+
+#~ msgid "Enable/disable the statusbar"
+#~ msgstr "Statusbalk aan/uitzetten"
+
+#~ msgid ""
+#~ "The password will be saved in plain text in the Tellico configuration file."
+#~ msgstr ""
+#~ "Het wachtwoord wordt ongecodeerd opgeslagen in het Tellico "
+#~ "configuratiebestand."
+
+#, fuzzy
+#~ msgid "Reading files..."
+#~ msgstr "Bestand wordt opgeslagen..."
+
+#~ msgid ""
+#~ "<p>...that you can rename a collection by right-clicking on\n"
+#~ "the top collection item in the left column.</p>\n"
+#~ msgstr ""
+#~ "<p>...dat u de verzameling kunt hernoemen door rechts te klikken\n"
+#~ "op bovenste verzameling item in de linker kolom.</p>\n"
+
+#~ msgid ""
+#~ "_: Default XSL Template\n"
+#~ "Fancy"
+#~ msgstr "Fancy"
diff --git a/po/nn.po b/po/nn.po
new file mode 100644
index 0000000..f762131
--- /dev/null
+++ b/po/nn.po
@@ -0,0 +1,5147 @@
+# Translation of nn to Norwegian Nynorsk
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+#
+# Karl Ove Hufthammer <karl@huftis.org>, 2005, 2006, 2007, 2008.
+msgid ""
+msgstr ""
+"Project-Id-Version: nn\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2008-03-23 18:52+0100\n"
+"Last-Translator: Karl Ove Hufthammer <karl@huftis.org>\n"
+"Language-Team: Norwegian Nynorsk <i18n-nn@lister.ping.uio.no>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "<qt>Klarte ikkje skriva til tenarrøyret på <b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr "Koplar til OpenOffice.org …"
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr "OpenOffice.org-samband"
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+"Tellico klarte ikkje kopla til OpenOffice.org. Sjå til at "
+"sambandsinnstillingane nedanfor er rette, og at OpenOffice.org Writer "
+"køyrer."
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr "Røyr"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr "TCP/IP"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr "Endra namn på kolonne"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr "Nytt namn på kolonne:"
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr "Kolonne %1"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr "Endra namn på kolonne …"
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr "Set inn rad"
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr "Fjern rad"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr "Flytt rad opp"
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr "Flytt rad ned"
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr "Tøm tabell"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr "Førehandsvising av mal"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Kopla"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr "%1:"
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Fleire"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Færre"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Tøm"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Vel bilete …"
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr "Berre lagra lenkje"
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr "Du kan berre lagra bilete du nyleg har lagt til som lenkjer."
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Rediger %1"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Legg til samling"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Slå saman samling"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Byt ut samling"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr "Rediger oppføringar"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "Legg til feltet «%1»"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Endra feltet «%1»"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Sletta feltet «%1»"
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr "Legg til oppføringar"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Legg til %1"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Endra namn på samling"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Endra lån"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Legg til filter"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Endra filter"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Slett filter"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Lån ut gjenstandar"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Lån ut «%1»"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Slett oppføringar"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Slett «%1»"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Endra rekkjefølgje på felt"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Registrer innleveringar"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Lever inn «%1»"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Generelt"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Tilstand"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Personleg"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Frimerka mine"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Tittel"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Skildring"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Pålydande verdi"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "Land"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Utgjevingsår"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Farge"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Scott#"
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr "Perfekt,Ekstremt bra,Veldig bra,Bra,Middels,Dårleg"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Kvalitet"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Annullert"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Hengsler"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Sentrering"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Gummi"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Kjøpsdato"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Kjøpspris"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Plassering"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Gåve"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Bilete"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Merknader"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Utgjeving"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Klassifisering"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Teikneseriane mine"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Undertittel"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Forfattar"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr "Teiknar"
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Serie"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Nummer"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Forlag"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Utgåve"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Utgjevingsår"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Sider"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Språk"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Sjanger"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Nøkkelord"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr "Som ny,Nesten som ny,Veldig bra,Bra,OK,Tydelig brukt,Slitt,Elendig"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Signert"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Lånt ut"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Forside"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Myntane mine"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Type"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "År"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Stempelglans"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Myntsett"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr "PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Graderingsteneste"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Framside"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Bakside"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Bøkene mine"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Forfattar"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Innbunden"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Mjuk perm"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Stiv perm"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "E-bok"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Blad"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Tidsskrift"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Innbinding"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Copyrightår"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "International Standard Book Number (internasjonalt standardboknummer)."
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Library of Congress Control Number."
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr "Omsetjar"
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Serienummer"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Ny"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Brukt"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Lesen"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Karakter"
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr "Filene mine"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "Namn"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "Adresse"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Volum"
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr "Mappe"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr "MIME-type"
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr "Storleik"
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr "Løyve"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr "Eigar"
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr "Gruppe"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr "Oppretta"
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr "Sist endra"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr "Metainformasjon"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Eigenskap"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Verdi"
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr "Ikon"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Vinane mine"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Produsent"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Appellasjon"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Éidruevin"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Årgang"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Raudvin"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Kvitvin"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Musserande vin"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Kvantum"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Drikk før"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Etikettbilete"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Andre personar"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Eigenskapar"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Filmane mine"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr "Blu-ray"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+msgid "HD DVD"
+msgstr "HD DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Medium"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Produksjonsår"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr ""
+"7 (Noreg),11 (Noreg),15 (Noreg),18 (Noreg),G (USA),PG (USA),PG-13 (USA),R "
+"(USA),U (USA)"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Aldersgrense"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Sone 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Sone 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Sone 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Sone 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Sone 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Sone 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Sone 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Sone 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Sone"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Nasjonalitet"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Format"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Skodespelarar"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr "Skodespelar(inne)"
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr "Rolle"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr "Ein tabell med oversikt over skodespelarar og rollene dei spelar."
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Regissør"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Komponist"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Studio"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Språkspor"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Undertekstspråk"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Lydspor"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Speletid"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "Kor lenge filmen varer (minutt)."
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Breidd-/høgdforhold"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Breiformat"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Svartkvitt"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Fargemodus"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Regissørversjon"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Handlingssamandrag"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Personleg karakter"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Omslag"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "Spela mine"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr "Xbox 360"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr "PlayStation 3"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation 2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr "Nintendo Wii"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr "Linux"
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Plattform"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Utgjevingsår"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Forlag"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Utviklar"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr "Inga aldersgrense, Vaksne, Ungdom, Alle, Barn, Ikkje fastsett"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "ESRB-aldersgrense"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Rundspelt"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Samlekorta mine"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Spelar"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Lag"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Merke"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Kortnummer"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Korttype"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Framside"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Bakside"
+
+#: collections/boardgamecollection.cpp:26
+msgid "My Board Games"
+msgstr "Brettspela mine"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr "Mekanisme"
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr "Designar"
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr "Talet på spelarar"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Litteraturliste"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Oppføringstype"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr "Desse oppføringstypane gjeld berre BibTeX. Sjå hjelpeteksten til BibTeX."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "BibTeX-nøkkel"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Boktittel"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Redaktør"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organisasjon"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Adresse"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr "DOI"
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr "Digitalobjekt-identifikator"
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Månad"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Tal"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Publiseringsmåte"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Kapittel"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Kryssreferanse"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Samandrag"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Merknader"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Musikken min"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Album"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "CD"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Kassett"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Vinyl"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Artist"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Plateselskap"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Spor"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr "Lengd"
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with,ein,ei,eit,og,i,av,om,den,dei,å"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "den,the"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr.,jr,iii,iv"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "van,von"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr "ISBNdb.com"
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 lèt deg ikkje søkja i denne samlingstypen."
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Resultat frå %1: %2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "Kjelda inneheld ingen val."
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "Entrez-database"
+
+#: fetch/entrezfetcher.cpp:485
+msgid "Institution"
+msgstr "Institusjon"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Søkjefeil"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Sambandssøkjefeil %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Syntaksfeil i oppføring"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Sambandsfeil %1: %2"
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr "SRU-tenar"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Library of Congress (USA)"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr "&Vert: "
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr "Skriv inn vertsnamnet til tenaren."
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Port: "
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Skriv inn portnummeret til tenaren. Standardverdien er %1."
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr "Stig: "
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr "Skriv inn stigen til databasen på tenaren."
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr "Format: "
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr "Skriv inn resultatformatet brukt på tenaren."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr "Yahoo!-lydsøk"
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "Klarte ikkje lasta ned omslaget."
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr "Amazon-lenkje"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (USA)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (Storbritannia)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Tyskland)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japan)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (Frankrike)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Canada)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Amazon.com-vevtenester"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "&Land: "
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "USA"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Storbritannia"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Tyskland"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Japan"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "Frankrike"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Canada"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon.com har data på fleire forskjellige nettstadar i forskjellige land. "
+"Vel den av dei du vil bruka for denne datakjelda."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "&Biletstorleik: "
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Lite bilete"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Mellomstort bilete"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Stort bilete"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Ingen bilete"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"Du kan òg lasta ned omslagsbilete. Men merk at mange store bilete i "
+"samlinga kan føra til at programmet går seinare."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "&Tilhøyrande ID: "
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+"Den tilhøyrande ID-en identifiserer personen som brukar "
+"Amazon.com-vevtenestene, og følgjer med alle lenkjer til "
+"Amazon.com-nettstaden."
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr "z39.50-tenar"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr "Bruk &ferdigdefinert tenar:"
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "&Database: "
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr "Skriv inn namnet på databasen på tenaren."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "&Teiknkoding: "
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Vel teiknkodinga brukt på z39.50-tenaren. Den vanlegaste teiknkodinga er "
+"MARC-8, men ISO-8859-1 er òg mykje brukt."
+
+#: fetch/z3950fetcher.cpp:550
+msgid "&Format: "
+msgstr "&Format: "
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr "Oppdag automatisk"
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+"Skriv inn dataformatet brukt på z39.50-tenaren. Tellico vil prøva å finna "
+"dei beste innstillingane automatisk viss vel <i>Oppdag automatisk</i>."
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "&Brukar: "
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Valfri"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Skriv inn brukarnamnet du vil bruka for å få tilgang til z39.50-databasen. "
+"Dette er for dei fleste tenarar ikkje nødvendig."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "&Passord: "
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Skriv inn passordet du vil bruka for å få tilgang til z39.50-databasen. "
+"Dette er for dei fleste tenarar ikkje nødvendig. Passordet vert lagra som "
+"reint tekst i oppsettfila til Tellico."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr "Illustratør"
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Eksternt program"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "Samlings&type:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid "Set the collection type of the data returned from the external application."
+msgstr "Vel samlingstypen til data frå det eksterne programmet."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr "&Resultattype: "
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr "Vel resultattypen til data frå det eksterne programmet."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "Program&stig: "
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr "Stigen til programmet som skal køyrast og gje ut ei gyldig Tellico-datafil."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr "Vel søkjenøklane som er støtta av datakjelda."
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr "Legg til nødvendige argument. <b>%1</b> vert bytt ut med søkjeorda."
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr "Argument"
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+msgid "Update"
+msgstr "Oppdater"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+"<p>Skriv inn argumenta som skal brukast til å søkja etter tilgjengelege "
+"oppdateringar til oppføringane.</p><p>Formatet er det same som for "
+"«Avhengig»-felta, der feltaverdiane står i krøllparentesar, som for "
+"eksempel <i>%{author}</i>. Sjå brukarhandboka for meir informasjon.</p>"
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Kjeldeval"
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr "Tilgjengelege felt"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "Internett-filmdatabasen (IMDb)"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Vel IMDb-resultat"
+
+#: fetch/imdbfetcher.cpp:581
+msgid "<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr "<qt>Søket gav fleire treff. Vel eitt av dei nedanfor.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Vel søkjetreff.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr "IMDB-lenkje"
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Alternativ tittel"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+msgid "IMDB Rating"
+msgstr "IMDB-karakter"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Aldersgrenser"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"Internett-filmdatabasen (IMDb) brukar fleire ulike tenarar. Vel den av dei "
+"du vil bruka."
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr "&Ikkje fleire enn: "
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+"Oversikta over skodespelarar og andre medverkande ofte vera veldig stor. Her "
+"kan du velja kor mange menneske du vil ha med i søkjeresultatet."
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr "Last ned &omslag"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr "Internett-bokhandel (ibs.it)"
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Person"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr "UPC/EAN"
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Nøkkelord"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr "arXiv-ID"
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr "Pubmed-ID"
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Råførespurnad"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr "Opphavleg tittel"
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr "Distributør"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr "Episodar"
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr "arXiv.org"
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr "%1 krev eit brukarnamn og passord."
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr "Du treng ein konto for å få tilgang til CrossRef. Les bruksvilkåra, og <a href='http://www.crossref.org/requestaccount/'>be om ein konto</a>. Skriv inn OpenURL-kontoinformasjonen din nedanfor."
+
+#: fetch/crossreffetcher.cpp:343
+msgid "&Username: "
+msgstr "&Brukarnamn: "
+
+#: fetch/crossreffetcher.cpp:348
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr "Du treng brukarnamn og passord for å få tilgang til CrossRef-tenesta. Passordet vert lagra som reintekst i oppsettfila til Tellico."
+
+#: fetch/crossreffetcher.cpp:354
+msgid "&Password: "
+msgstr "&Passord: "
+
+#: fetch/gcstarpluginfetcher.cpp:190
+msgid "GCstar Plugin"
+msgstr "GCstar-programtillegg"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr "Vel samlingstypen til data som kjem frå programtillegget."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr "&Programtillegg: "
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr "Vel GCstar-programtillegget du vil bruka som datakjelde."
+
+#: fetch/gcstarpluginfetcher.cpp:420
+msgid "Author: "
+msgstr "Forfattar: "
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr "Discogs-lydsøk"
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr "API-&nøkkel: "
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr "Med discogs.com-kontoen din mottek du ein API-nøkkel for bruk av XML-grensesnittet. Sjå http://www.discogs.com/help/api for meir informasjon."
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr "Discogs-lenkje"
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr "Hent nye godsaker"
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr "Versjon"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr "Nedlastingar"
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr "Utgjevingsdato"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+"Dette er ei oversikt over alt du kan lasta ned. Tidlegare installerte "
+"element har eit avkryssingsmerke ved sidan av seg, mens element det finst "
+"nye versjonar av har eit oppdateringsikon."
+
+#: newstuff/dialog.cpp:137
+msgid "The name and license of the selected item"
+msgstr "Namnet og lisensvilkåra for vald element."
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr "Forfattaren av vald element."
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr "Installer"
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr "Last ned og installer vald mal."
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+"Last ned og installert valt skript. Nokre skript må stillast inn etter at "
+"dei er installert."
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr "Ei skildring av vald element."
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr "Lastar ned informasjon …"
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Klar."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr "Oppdater"
+
+#: newstuff/dialog.cpp:413
+msgid "Installing item..."
+msgstr "Installer …"
+
+#: translators/bibteximporter.cpp:79
+msgid "No valid bibtex entries were found"
+msgstr "Fann ingen gyldige BibTeX-oppføringar"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "Fann ingen gyldige BibTeX-oppføringar i fila «%1»."
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "BibTeX-val"
+
+#: translators/bibteximporter.cpp:287
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Bruk Unicode-teiknkoding (UTF-8)"
+
+#: translators/bibteximporter.cpp:288
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Les inn den importerte fila som Unicode (UTF-8)."
+
+#: translators/bibteximporter.cpp:289
+msgid "Use user locale (%1) encoding"
+msgstr "Bruk brukarlokale-teiknkoding (%1)"
+
+#: translators/bibteximporter.cpp:293
+msgid "Read the imported file in the local encoding."
+msgstr "Les inn den importerte fila i den lokale teiknkodinga."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "Tellico Zip-fil"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Tellico-filer (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Alle filer"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>Det finst allereie eit Alexandria-bibliotek med namnet <i>%1</i>. Alle "
+"bøkene her kan verta overskrivne.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "Det oppstod ein XML-tolkefeil i linje %1, kolonne %2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "Feilmeldinga frå Qt er:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Ho er frå ein nyare versjon av Tellico."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Gjer om fila til det nye dokumentformatet. Merk at du kan tapa informasjon "
+"om du seinare opnar fila i ein eldre versjon av Tellico."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Ukjend"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "Fila er tom."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "Fila inneheld ikkje noko samlingsdata."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Ulesne bøker"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Gamle filmar"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "80-talsmusikk"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Favorittar"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Søkjer gjennom lydfiler …"
+
+#: translators/audiofileimporter.cpp:129
+msgid "Bitrate"
+msgstr "Bitrate"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr "Spor (disk %1)"
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(Ymse)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Lydfilval"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Søk òg i undermapper"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr "Søk i mapper og i undermapper etter lydfiler."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr "&Ta med filplassering"
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr "Legg filnamna til kvart spor til oppføringane."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr "Ta med &bitrate"
+
+#: translators/audiofileimporter.cpp:353
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr "Legg bitraten til kvart spor til oppføringane."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|CSV-filer (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "CSV-val"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Bruk feltnamn som kolonneoverskrifter"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr "Ta med ei overskriftsrad med feltnamn."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Skiljeteikn"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr "Du kan bruka andre teikn enn komma for å skilja verdiar i fila."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Komma"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Bruk komma som skiljeteikn."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Semikolon"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Bruk semikolon som skiljeteikn."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Tabulator"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Bruk tabulator som skiljeteikn."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Anna"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Bruk sjølvvald tekst som skiljeteikn."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr "Du kan bruka ein sjølvvald tekst, eksempelvis eit kolon, som skiljeteikn."
+
+#: translators/filelistingimporter.cpp:63
+msgid "Scanning files..."
+msgstr "Søkjer gjennom …"
+
+#: translators/filelistingimporter.cpp:191
+msgid "File Listing Options"
+msgstr "Fillisteval"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr "Søk òg i undermapper"
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr "Søk i mapper og i undermapper etter filer."
+
+#: translators/filelistingimporter.cpp:198
+msgid "Generate file previews"
+msgstr "Lag førehandsvisingar"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+"Lag førehandsvisingar av innhaldet i filene, noko som kan gjera "
+"mappevisinga mykje seinare."
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "ONIX-arkiv"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.zip|Zip-filer (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "ONIX-arkivval"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Ta bilete med i arkiv"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr "Ta med bileta i dokumentet i det komprimerte ONIX-arkivet."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr "<qt>Fekk ikkje tilgang til CD-ROM-eininga – <i>%1</i>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+msgid "Select CDDB Entry"
+msgstr "Vel CDDB-oppføring"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr "Vel CDDB-oppføring:"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>Fann ingen oppføringar som samsvarar med CD-en.</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "<qt>Klarte ikkje fullføra oppslag for CD-plata.</qt>"
+
+#: translators/freedbimporter.cpp:470
+msgid "Various"
+msgstr "Ymse"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Lyd-CD-val"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Les data frå CD-ROM-eininga"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Vel eller skriv inn adressa til CD-ROM-eininga."
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Berre les data frå lokalt CDDB-lager"
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+"Les data rekursivt frå alle lokale CDDB-lagerfilene i standardmappene for "
+"desse filene."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr "GCfilms"
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.gcf|GCfilms-filer (*.gcf)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.gcs|GCstar-filer (*.gcs)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "XSLT-val"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "XSLT-fil:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr "Vel XSLT-fila du vil bruka til å transformera Tellico XML-dataa."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Alexandria-val"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr "&Bibliotek:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "BibTeXML"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|BibteXML-filer (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|XML-filer (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Tellico XML-val"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Ta med bilete i XML-dokument"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr "Ta med bilete i XML-straumen som base64-koda element."
+
+#: translators/importer.h:100
+msgid "Loading data..."
+msgstr "Hentar data …"
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr "Hentar %1 …"
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "BibTeX"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|BibTeX-filer (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Utvid tekstmakroar"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr "Utvida automatisk tekstmakroar og ikkje lagra @string{}-oppføringar."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Bruk pakken «URL»"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr "Legg kommandoen \\url rundt alle URL-felt (nettadresser)."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Hopp over oppføringar med tomme siteringsnøklar"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr "Hopp over eventuelle oppføringar som ikkje inneheld siteringsnøklar."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "BibTeX-siteringsstil:"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Krøllparentesar"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Hermeteikn"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"<qt>Siteringsstilen vert brukt ved eksportering til BibTeX. Alle feltverdiar "
+"vert syntaksverna med anten krøllparentesar eller hermeteikn.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Vel kva type samlinga som vert importert."
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr "&Første rad inneheld feltnamn"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr "Bruk første rad som feltnamn."
+
+#: translators/csvimporter.cpp:248
+msgid "&Comma"
+msgstr "&Komma"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr "&Semikolon"
+
+#: translators/csvimporter.cpp:259
+msgid "Ta&b"
+msgstr "&Tabulator"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr "&Anna:"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "Tabellen viser opptil dei første fem linjene i CSV-fila."
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt>Kopla kvar kolonne til tilhøyrande felt i samlinga ved å velja "
+"kolonna, velja feltet, og så trykkja <i>Tildel felt</i>.</qt>"
+
+#: translators/csvimporter.cpp:298
+msgid "Co&lumn:"
+msgstr "&Kolonne:"
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr "&Datafelt i denne kolonnen:"
+
+#: translators/csvimporter.cpp:315
+msgid "&Assign Field"
+msgstr "&Tildel felt"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr "Du må tildela minst éin kolonne til kvart felt. Berre tildelte kolonnar vert importerte."
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Nytt felt"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|Pilot-databasefiler (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Vis kolonnar"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "PilotDB-val"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Slå på PDA-reservekopieringsflagget for databasen"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>Denne fila er ikkje ei gyldig GCstar-datafil.</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Det oppstod ein feil ved XSLT-handsaming."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "Du treng ei gyldig XSLT-fil for å importera fila."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|XSL-filer (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|HTML-filer (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Personar"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(gruppert etter %1)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "HTML-val"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Skriv ut feltoverskrifter"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr "Skriv ut feltnamn som kolonneoverskrifter."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Grupper oppføringane"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr "Grupper oppføringane etter vald felt."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Eksporter oppføringar til einskildfiler"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr "Kopier kvar oppføring til si eiga fil."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Klarte ikkje lesa metadata frå PDF-fila."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr "Tellico kan lasta ned informasjon om oppføringar med DOI-identifikatorar frå CrossRef.org. For å bruka denne funksjonen må du først oppretta ein CrossRef-konto, og så leggja til ei ny datakjelde med kontoinformasjonen din."
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Datakjeldeeigenskapar"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "&Kjeldenamn: "
+
+#: fetcherconfigdialog.cpp:79
+msgid "The name identifies the data source and should be unique and informative."
+msgstr "Namnet identifiserer datakjelda, og bør vera unikt og informativt."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "Kjelde&type: "
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr "Tellico støttar fleire forskjellige datakjelder."
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr "Overskriv brukardata ved oppdatering frå kjelde"
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Overskriv eventuelle brukarendringar i oppføringane ved ved oppdatering "
+"frå kjeldene."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Vilkårleg felt"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "inneheld"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "ikkje inneheld"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "er lik"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "er ulik"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "som regulært uttrykk"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "ikkje som regulært uttrykk"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Rediger …"
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Avansert filter"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Filterkriterium"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "O&ppfyll alle felt"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "&Oppfyll eitt eller fleire felt"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Filternamn:"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "&Lagra filter"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Enkel tekst"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Avsnitt"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Valboks"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Avkryssingsboks"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Tabell"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Avhengig"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Dato"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr "Oppdaterer %1 …"
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr "Oppdaterer oppføringar …"
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr "Oppdater oppføringar"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr "Oppdaterer <b>%1</b> …"
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr "Vel treff"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+"<qt><b>%1</b> gav fleire treff som kan stemma med <b>%2</b>, som er "
+"oppføringa i samlinga. Vel kva treff som er det rette.</qt>"
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Utvida alle grupper"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Fald saman alle grupper"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Filtrer etter gruppe"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (sorter etter tal)"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Gruppe"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Importeringsval"
+
+#: importdialog.cpp:62
+msgid "&Replace current collection"
+msgstr "&Byt ut samling"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr "Byt ut gjeldande samling med innhaldet i den importerte fila."
+
+#: importdialog.cpp:65
+msgid "A&ppend to current collection"
+msgstr "&Legg til samling"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Legg innhaldet i den importerte fila til den gjeldande samlinga. Dette er "
+"berre mogleg viss samlingane er av same type."
+
+#: importdialog.cpp:69
+msgid "&Merge with current collection"
+msgstr "&Slå saman med samling"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Slå saman innhaldet i den importerte fila med gjeldande samling. Dette er "
+"berre mogleg viss samlingane er av same type. Oppføringane må vera "
+"nøyaktig like for å verta slått saman."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Importer frå"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|RIS-filer (*.ris)"
+
+#: importdialog.cpp:277
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.amc|AMC-datafiler (*.amc)"
+
+#: importdialog.cpp:281
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdf|PDF-filer (*.pdf)"
+
+#: importdialog.cpp:285
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.reflib|Referencer-filer (*.reflib)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Klarte ikkje opna fila «%1»."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Klarte ikkje lagra fila «%1»."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Klarte ikkje lasta opp fila «%1»."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Du kan berre leggja til oppføringar av same type i samlinga. Det vart ikkje "
+"gjort nokon endringar."
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Du kan berre slå saman oppføringar av same type. Det vart ikkje gjort "
+"nokon endringar."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Klarte ikkje opna bilete frå fila «%1»."
+
+#: entryiconview.cpp:287
+msgid "&Sort By"
+msgstr "&Sorter etter"
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Lånevindauge"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "Desse gjenstandane vert lånt vekk:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "Desse gjenstandane er lånt vekk:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "&Lån til:"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Skriv inn namnet på han eller ho du vil låna til. Trykk på knappen for å "
+"velja frå adresseboka."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "&Lånedato:"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+"Lånedatoen er når du lånte ut gjenstanden eller gjenstandane. Som "
+"standard vert dagens dato brukt."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "&Innleveringsfrist:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"Innleveringsfristen er når gjenstanden skal leverast inn. Du treng ikkje "
+"leggja til ein innleveringsfrist om du ikkje vil leggja lånet til "
+"kalenderen din."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Merknad:"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "Du kan òg leggja merknader til lånet."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "&Legg til varsel i gjeldande kalender"
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"<qt>Kryss av her for å leggja ei <em>oppgåve</em> til gjeldande kalender, "
+"som du finn i programmet KOrganizer. Du kan berre gjera dette viss du har "
+"vald ein innleveringsfrist."
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Lag ny samling"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Ny &boksamling"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Lag ei ny boksamling."
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Ny &litteraturliste"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Lag ei ny BibTeX-basert litteraturliste."
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Ny &teikneseriesamling"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Lag ei ny teikneseriesamling."
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Ny &filmsamling"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Lag ei ny filmsamling."
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Ny &musikksamling"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Lag ei ny musikksamling."
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Ny m&yntsamling"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Lag ei ny myntsamling."
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Ny f&rimerkesamling"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Lag ei ny frimerkesamling."
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Ny &samlekortsamling"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Lag ei ny samlekortsamling."
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Ny &vinsamling"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Lag ei ny vinsamling."
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Ny s&pelsamling"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Lag ei ny spelsamling."
+
+#: mainwindow.cpp:272
+msgid "New Boa&rd Game Collection"
+msgstr "Ny br&ettspelsamling"
+
+#: mainwindow.cpp:274
+msgid "Create a new board game collection"
+msgstr "Lag ei ny brettspelsamling."
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr "Ny fil&katalog"
+
+#: mainwindow.cpp:282
+msgid "Create a new file catalog"
+msgstr "Lag ny filkatalog"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Ny s&jølvvald samling"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Lag ei ny sjølvvald samling."
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Opna eit gammalt dokument."
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Opna ei nyleg brukt fil."
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Lagra dokumentet."
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Lagra dokumentet under eit nytt filnamn."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Skriv ut innhaldet i dokumentet."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Avslutt programmet."
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Importer ei samling frå andre dataformat."
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Tellico …"
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Importer samling frå ei anna Tellico-fil."
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "CSV …"
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Importer samling frå ei CSV-fil (kommadelt format)."
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "MODS …"
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Importer samling frå ei MODS-fil."
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Alexandria …"
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Importer samling frå boksamlingprogrammet Alexandria."
+
+#: mainwindow.cpp:352
+msgid "Import Delicious Library Data..."
+msgstr "Delicious Library …"
+
+#: mainwindow.cpp:353
+msgid "Import data from Delicious Library"
+msgstr "Importer samling frå Delicious Library."
+
+#: mainwindow.cpp:359
+msgid "Import Referencer Data..."
+msgstr "Referencer …"
+
+#: mainwindow.cpp:360
+msgid "Import data from Referencer"
+msgstr "Importer samling frå Referencer."
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "BibTeX …"
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Importer samling frå ei BibTeX-basert litteraturliste."
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "BibTeXML …"
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Importer samling frå ei BibTeXML-fil."
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "RIS …"
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Importer samling frå ei RIS-referansefil."
+
+#: mainwindow.cpp:387
+msgid "Import PDF File..."
+msgstr "PDF-fil …"
+
+#: mainwindow.cpp:388
+msgid "Import a PDF file"
+msgstr "Importer ei PDF-fil."
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Lydfil-metadata …"
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Importer metadata frå lydfiler."
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Lyd-CD …"
+
+#: mainwindow.cpp:405
+msgid "Import audio CD information"
+msgstr "Importer lyd-CD-informasjon."
+
+#: mainwindow.cpp:414
+msgid "Import GCstar Data..."
+msgstr "GCstar …"
+
+#: mainwindow.cpp:415
+msgid "Import a GCstar data file"
+msgstr "Importer samling frå ei GCstar-fil."
+
+#: mainwindow.cpp:421
+msgid "Import Griffith Data..."
+msgstr "Griffith …"
+
+#: mainwindow.cpp:422
+msgid "Import a Griffith database"
+msgstr "Importer ein Griffith-database."
+
+#: mainwindow.cpp:428
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Ant Movie Catalog …"
+
+#: mainwindow.cpp:429
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Importer samling frå ei Ant Movie Catalog-fil."
+
+#: mainwindow.cpp:435
+msgid "Import File Listing..."
+msgstr "Filliste …"
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr "Importer informasjon om filer i ei mappe."
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "XSLT-transformering"
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Importer samling via ei XSLT-transformering."
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Eksporter til"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Eksporter samlinga til andre dataformat."
+
+#: mainwindow.cpp:461
+msgid "Export to XML..."
+msgstr "XML …"
+
+#: mainwindow.cpp:462
+msgid "Export to a Tellico XML file"
+msgstr "Eksporter samlinga til ei Tellico XML-fil."
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Zip …"
+
+#: mainwindow.cpp:469
+msgid "Export to a Tellico Zip file"
+msgstr "Eksporter samlinga til ei Tellico Zip-fil."
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "HTML …"
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Eksporter samlinga til ei HTML-fil."
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "CSV-fil …"
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Eksporter samlinga til ei CSV-fil (kommadelt format)."
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "PilotDB …"
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Eksporter samlinga til ein PilotDB-database."
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Alexandria …"
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Eksporter samlinga til eit Alexandria-bibliotek."
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "BibTeX …"
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Eksporter samlinga til ei BibTeX-fil."
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "BibTeXML …"
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Eksporter samlinga til ei BibTeXML-fil."
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "ONIX …"
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Eksporter samlinga til ei ONIX-fil."
+
+#: mainwindow.cpp:524
+msgid "Export to GCfilms..."
+msgstr "GCfilms …"
+
+#: mainwindow.cpp:525
+msgid "Export to a GCfilms data file"
+msgstr "Eksporter samlinga til ei GCfilms-fil."
+
+#: mainwindow.cpp:531
+msgid "Export to GCstar..."
+msgstr "GCstar …"
+
+#: mainwindow.cpp:532
+msgid "Export to a GCstar data file"
+msgstr "Eksporter samlinga til ei GCstar-fil."
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "XSLT-transformering …"
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Eksporter samlinga via ei XSLT-transformering."
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Klipp ut merkt tekst til utklippstavla."
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Kopier merkt tekst til utklippstavla."
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Lim inn innhaldet på utklippstavla."
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Merk alle oppføringane i samlinga."
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Fjern merkinga frå alle oppføringane i samlinga."
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Nettsøk …"
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Søk på Internett …"
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "&Avanserte filter …"
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Filtrer samlinga."
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&Ny oppføring …"
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Legg til ei ny oppføring."
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "&Rediger oppføring …"
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Rediger merkte oppføringar."
+
+#: controller.cpp:621 mainwindow.cpp:577
+msgid "D&uplicate Entry"
+msgstr "L&ag kopi av oppføring"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Kopier merkte oppføringar."
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "&Slett oppføring"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Slett merkte oppføringar."
+
+#: mainwindow.cpp:585
+msgid "&Merge Entries"
+msgstr "Slå saman o&ppføringar"
+
+#: mainwindow.cpp:588
+msgid "Merge the selected entries"
+msgstr "Slå saman dei merkte oppføringane."
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "Lag rappor&tar …"
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Lag samlingsrapportar."
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "&Lån ut …"
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Lån ut merkte gjenstandar."
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "&Innlevering"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Registrer innlevering av merkte gjenstandar."
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "&Gje nytt namn til samling …"
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Gje nytt namn til samlinga."
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "Samlings&felt …"
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Rediger samlingsfelt."
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "G&jer om til litteraturliste"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Gjer boksamlinga om til ei litteraturliste."
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "Tekst&makroar …"
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Rediger BibTeX-tekstmakroar."
+
+#: mainwindow.cpp:626
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Kopier BibTeX til &utklippstavle"
+
+#: mainwindow.cpp:627
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Kopier BibTeX-referansar til utklippstavla."
+
+#: mainwindow.cpp:632
+msgid "Cite Entry in &LyX"
+msgstr "Siter oppføring i L&yX"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Siter merkte oppføringar i LyX."
+
+#: mainwindow.cpp:638
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Siter oppf&øring i OpenOffice.org"
+
+#: mainwindow.cpp:639
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Siter merkte oppføringar i OpenOffice.org."
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, no-c-format
+msgid "&Update Entry"
+msgstr "&Oppdater oppføring"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr "Alle kjelder"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr "Oppdater oppføringsdata frå alle kjelder."
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Vis gr&upperute"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Vis/skjul grupperute."
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Skjul gr&upperute"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Vis &redigeringsvindauge"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Vis/skjul redigeringsvindauge for oppføringar."
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "Skjul &oppføringsredigering"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Vis &oppføringsrute"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Vis/skjul oppføringsrute."
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "Skjul &oppføringsrute"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Endra gruppering"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "&Grupper etter"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Endra grupperinga av samlinga."
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Filter"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Tøm filter"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Skriv inn filtertekst her …"
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Grupper"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr "<qt><i>Grupperuta</i> sorterer oppføringane i grupper basert på felt.</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt><i>Kolonnevisinga</i> viser verdien til fleire felt for kvar "
+"oppføring.</qt>"
+
+#: mainwindow.cpp:831
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Velkommen til samlingsdatabasen Tellico"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr "<h3>Tellico er eit verktøy for handtering av samlingar med bøker, filmar, musikk og alt anna du måtte ønskja å halda oversikt over.</h3><h3>Du kan leggja nye oppføringar til samlinga di ved å <a href=\"tc:///coll_new_entry\">skriva inn data manuelt</a>, eller ved å <a href=\"tc:///edit_search_internet\">lasta ned data</a> frå fleire Internett-kjelder.</h3>"
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Lagar nytt dokument …"
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Opnar fil …"
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Opna fil"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Lagrar fil …"
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+"<qt><p>Du er i ferd med å lagra ei fil med mange bilete, noko som gjer at "
+"Tellico arbeidar mykje tregare. Vil du heller lagra bileta for seg i "
+"datamappa til Tellico, slik at programmet køyrer raskare?</p><p>Du kan "
+"alltid endra valet du gjer i oppsettvindauget.</p></qt>"
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr "Lagra bilete for seg"
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr "Lagra bilete i fil"
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Lagrar fil med nytt filnamn …"
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Skriv ut …"
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"Samlinga vert filtrert, og viser berre nokre av oppføringane. Berre dei "
+"synlege oppføringane vert skrivne ut. Vil du halda fram?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Handsamar dokument …"
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Avsluttar …"
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Oppføringar totalt: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 filtrert – %2 merkt)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 filtrert)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 merkt)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Skriv ut %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Side %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Kontroller installeringa."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Importerer data …"
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Importer fil"
+
+#: mainwindow.cpp:1864
+msgid "Import Directory"
+msgstr "Importer mappe"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Eksporterer data …"
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Eksporter som"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Tekstmakroar"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Makro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Tekst"
+
+#: mainwindow.cpp:1999
+msgid "Creating citations..."
+msgstr "Lagar referansar …"
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Filter"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt>The <i>Filtervisinga</i> viser oppføringane i samsvar med visse "
+"filterreglar.</qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Lån"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt><i>Lånvisinga</i> viser ei oversikt over alle som har lånt noko i "
+"samlinga.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr "Oppdater oppføringsdata frå %1"
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr "Tellico kan berre importera éi fil av denne typen om gongen."
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Klarte ikkja opna biletet «%1»."
+
+#: filehandler.cpp:207
+msgid "A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr "Fila «%1» finst frå før. Er du sikker på at du vil skriva over ho?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Vil du overskriva fila?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Skriv over"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Filter (sorter etter tal)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Er du sikker på at du vil sletta denne oppføringa?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Slett oppføring"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Er du sikker på at du vil sletta desse oppføringane?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Slett fleire oppføringar"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "&Rediger oppføringar …"
+
+#: controller.cpp:627
+msgid "D&uplicate Entries"
+msgstr "L&ag kopi av oppføringar"
+
+#: controller.cpp:628
+msgid "&Update Entries"
+msgstr "&Oppdater oppføringar"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "&Slett oppføringar"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+"Du har allereie lånt ut desse gjenstandane, men Tellico støttar ikkje "
+"utlån av éin gjenstand fleire gongar samtidig. Dei vert derfor fjerna frå "
+"lånelista."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Standardkalender"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"Tellico støttar for tida berre lokale kalenderresursar. Den gjeldande "
+"kalenderen er lagra ekstern, og låna vert derfor ikkje lagt til."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Aktiv kalender"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 må levera att «%2»."
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(Tom)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Ein samlingsdatabase for KDE."
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Ikkje opna den sist opna fila på nytt"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Importer <filename> som BibTeX-fil"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Importer <filename> som MODS-fil"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Importer <filename> som RIS-fil"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Fil å opna"
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr "Datakjeldeskript"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Ikona brukt i programmet"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Utviklar av btparse-biblioteket"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr "Programkodeeksempel og generell inspirasjon"
+
+#: main.cpp:50
+msgid "Author of libcsv library"
+msgstr "Utviklar av libcsv-biblioteket"
+
+#: main.cpp:52
+msgid "Author of rtf2html library"
+msgstr "Utviklar av rtf2html-biblioteket"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Samlingsfelt"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Gjeldande felt"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "&Nytt"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Legg nytt felt til samlinga."
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "&Slett"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Slett felt frå samlinga."
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Flytt feltet oppover i lista. Rekkjefølgja avgjer korleis "
+"innskrivingsvindauget vert utforma."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Flytt feltet nedover i lista. Rekkjefølgja avgjer korleis "
+"innskrivingsvindauget vert utforma."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Felteigenskapar"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "&Tittel:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "Tittelen på feltet"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "&Type:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "Felttypen fastset kva verdiar som kan brukast. "
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "<i>Enkel tekst</i> er den vanlegaste felttypen. "
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "<i>Avsnitt</i> er for større tekstbolkar. "
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Valboks</i> avgrenser feltet til visse verdiar. "
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "<i>Avkryssingsboks</i> er for ja/nei-verdiar. "
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr "<i>Tal</i> er for felt som berre kan innehelda tal. "
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+"<i>Nettadresse</i> er for felt som refererer til nettadresser eller eksterne "
+"filer. "
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr "Ein <i>tabell</i> kan innehelda éin eller fleire kolonnar med verdiar. "
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "Eit <i>biletfelt</i> inneheld eit bilete. "
+
+#: collectionfieldsdialog.cpp:144
+msgid "A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr "Eit <i>datofelt</i> kan brukast for verdiar med dag, månad og år. "
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr "Eit <i>karakterfelt</i> bruker stjerner for å visa kvalitetsverdien. "
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"Eit <i>avhengig</i> felt brukar verdiar frå andre felt, og vert formatert "
+"etter feltskildringa. "
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"Eit <i>skriveverna</i> felt er for interne verdiar, og kan vera nyttig ved "
+"importering og eksportering. "
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "&Kategori:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr "Feltkategorien avgjer kor feltet skal plasserast i redigeringsvindauget."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "&Skildring:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"Skildringa er ei nyttig påminning om kva informasjon feltet skal innehelda. "
+"For <i>avhengige</i> felt er skildringa ein formateringskommando, som "
+"«%{year} %{title}», der «%{year}» og «%{title}» er plasshaldarar som "
+"vert erstatta med innhaldet i felta."
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr "&Standardverdi:"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr "<qt>Ein standardverdi som vert brukt for nye oppføringar.</qt>"
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr "&Moglege verdiar:"
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>For <i>valfelt</i> er desse dei moglege alternativa. Dei vert plasserte "
+"i ein kombinasjonsboks. Dei ulike verdiane må skiljast med ei semikolon, "
+"slik: «hund; katt; mus».</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "Utvida &eigenskapar:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "&Set …"
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"Du kan bruka utvida felteigenskapar for å spesifisera for eksempel "
+"tilhøyrande BibTeX-felt."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Formateringsval"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Inga formatering"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+"Ikkje formater eller endra innhaldet i feltet til store forbokstavar "
+"automatisk."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Berre endra til store forbokstavar"
+
+#: collectionfieldsdialog.cpp:231
+msgid "This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+"Endra innhaldet i feltet til store forbokstavar automatisk, men ikkje "
+"formater det."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Formater som tittel"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Endra innhaldet i feltet til store forbokstavar automatisk og formater det "
+"som ein tittel, men berre viss desse vala er slått på globalt."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Formater som namn"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Endra innhaldet i feltet til store forbokstavar automatisk og formater det "
+"som eit namn, men berre viss desse vala er slått på globalt."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Feltval"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Bruk autofullføring"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr "Bruk den innebygde KDE-autofullføringa i dette skrivefelt."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Tillèt fleire verdiar"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Tillèt fleire verdiar i feltet. Innhaldet vert tolka som ei semikolondelt "
+"liste over verdiar."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Tillèt gruppering"
+
+#: collectionfieldsdialog.cpp:249
+msgid "If checked, this field may be used to group the entries in the group view."
+msgstr "Feltet kan brukast til å gruppera oppføringane i grupperuta."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr "Tilbakestill felteigenskapane til standardverdiane."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Endra felt"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Fjerning av tilletne verdiar frå feltet <i>%1</i> kan føra til "
+"datatap. Vil du behalda dei endra verdiane, eller avbryta, og gå tilbake "
+"dei gamle?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Behald dei endra verdiane"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Tilbakestill felteigenskapar"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Er du sikker på at du vil tilbakestilla eigenskapane for feltet "
+"<em>%1</em> til standardverdiane?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Tilbakestill"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Utvida felteigenskapar"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr "Det finst allereie eit felt med denne tittelen. Vel ein annan tittel."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr "<qt>Kategorien kan ikkje vera tom. Vel kategori.</qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>Eit felt kan ikkje vera i same kategori som eit <em>avsnitts-</em>, "
+"<em>tabell</em> eller <em>biletfelt</em>. Vel ein annan kategori.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"Tittelen til felt kan ikkje vera lik ein eksisterande kategori. Vel ein "
+"annan tittel."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+"Verdiområdet til eit karakterfelt må vera mellom 1 og 10, og den nedre "
+"grensa må vera mindre enn den øvre. Vel nye verdiar."
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "Tabellar kan ikkje ha meir enn ti kolonnar."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Fila er endra.\n"
+"Vil du lagra ho?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Ulagra endringar"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Vel lånar"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Set opp Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Generelle val"
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr "&Opna fil på nytt ved oppstart"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Opna fila som var open ved avslutting av Tellico neste gong Tellico vert "
+"starta."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "&Vis «Dagens tips» ved oppstart"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr "Vis eit nytt tips om bruk av Tellico kvar gong programmet vert starta."
+
+#: configdialog.cpp:213
+msgid "Image Storage Options"
+msgstr "Lagringsval for bilete"
+
+#: configdialog.cpp:214
+msgid "Store images in data file"
+msgstr "Lagra bileta i datafila"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr "Lagra bileta i programmappa"
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr "Lagra bileta i ei mappe relativ til datafila"
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr "Du kan lagra bileta i sjølve datafila, noko som gjer at Tellico kan verta tregt, lagra dei i programmappa, eller lagra dei i ei undermappe av mappa der datafila ligg."
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Formateringsval"
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr "Bruk automatisk &store forbokstavar i titlar og namn"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr "Bruk automatisk store forbokstavar i titlar og namn."
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr "&Formater automatisk titlar og namn"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr "Formater automatisk titlar og namn."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr "&Inga endring til store forbokstavar:"
+
+#: configdialog.cpp:243
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Ei liste over ord som ikkje skal endrast til å ha store forbokstavar. "
+"Verdiane skal skiljast med semikolon.</qt>"
+
+#: configdialog.cpp:249
+msgid "Artic&les:"
+msgstr "&Artiklar:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>Ei liste over ord som skal reknast som artiklar når dei er første ord "
+"i ein tittel. Verdiane skal skiljast med semikolon.</qt>"
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr "&Personsuffiks:"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Ei liste over suffiks som vert brukt i namn på personar. Verdiane skal "
+"skiljast med semikolon.</qt>"
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr "Prefiks for &etternamn:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Ei liste over prefiks som vert brukt i etternamnnamn til personar. "
+"Verdiane skal skiljast med semikolon.</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Utskrift"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Utskriftsval"
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr "&Formater titlar og namn"
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr "&Skriv ut feltoverskrifter"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Grupperingsval"
+
+#: configdialog.cpp:313
+msgid "&Group the entries"
+msgstr "&Grupper oppføringane"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Biletval"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr "Største bilet&breidd:"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Største moglege breidd på bileta ved utskrift. Høgd/breidd-forholdet vert "
+"bevart."
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr "Største bilet&høgd:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Største moglege høgd på bileta ved utskrift. Høgd/breidd-forholdet vert "
+"bevart."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Malar"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Malval"
+
+#: configdialog.cpp:369
+msgid "Template:"
+msgstr "Mal:"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+"Vel malen du vil bruka for denne typen samling. Merk at ikkje alle malane "
+"brukar skrift- og fargevala dine."
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr "&Førehandsvising …"
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr "Vis ei førehandsvising av malen."
+
+#: configdialog.cpp:398
+msgid "Font Options"
+msgstr "Skriftval"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr "Skrift:"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr "Denne skrifta vert sendt til malen brukt i oppføringsvisinga."
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr "Storleik:"
+
+#: configdialog.cpp:425
+msgid "Color Options"
+msgstr "Fargeval"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr "Bakgrunnsfarge:"
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr "Denne fargen vert sendt til malen brukt i oppføringsvisinga."
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr "Tekstfarge:"
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr "Uthevingsfarge (bakgrunn):"
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr "Uthevingsfarge (tekst):"
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr "Ordna malar"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr "Installer …"
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr "Installer ein ny mal direkte."
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr "Last ned …"
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr "Last ned nye malar frå Internett."
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr "Slett …"
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr "Vel og fjern installerte malar."
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Datakjelder"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Datakjeldeval"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Kjelde"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr "Flytt &opp"
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+"Rekkjefølgja på datakjeldene avgjer i kva rekkjefølgja Tellico skal sjå "
+"etter oppdateringar for oppføringane."
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr "Flytt &ned"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "&Ny …"
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr "Legg til ei ny datakjelde."
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Endra …"
+
+#: configdialog.cpp:533
+msgid "Click to modify the selected data source."
+msgstr "Rediger den merkte datakjelda."
+
+#: configdialog.cpp:536
+msgid "Click to delete the selected data source."
+msgstr "Slett den merkte datakjelda."
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr "Last ned nye datakjelder frå Internett."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr "*.tar.gz *.tgz|Mal-pakkar (*.tar.gz)"
+
+#: configdialog.cpp:1049
+msgid "Delete Template"
+msgstr "Slett mal"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr "Vel malen du vil sletta:"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "Lånar"
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Lever inn"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Endra lån …"
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "Lånar (sorter etter tal)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "Samlinga mi"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Bøker"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Teikneseriar"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Filmar"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Musikk"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Myntar"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Frimerke"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Vin"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Samlekort"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Spel"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr "Filkatalog"
+
+#: collectionfactory.cpp:135
+msgid "Board Game Collection"
+msgstr "Brettspelsamling"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Sjølvvald"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+"<qt><i>Oppføringsruta</i> viser ei formatert vising av innhaldet til "
+"oppføringane.</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt><i>Ikonvisinga</i> viser kvar oppføring i samlinga eller gruppa som eit "
+"ikon, som kan vera eit bilete frå oppføringa.</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Eksporteringsval"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Formatering"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Formater alle felt"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr "Formater automatisk felta etter formattypen."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Eksporter berre merkte oppføringar"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr "Berre eksporter dei oppføringane som er merkte."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Koding"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Kod som Unicode (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Bruk teiknkodinga UTF-8 på den eksporterte fila."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Kod etter brukarlokalet (%1)"
+
+#: exportdialog.cpp:72
+msgid "Encode the exported file in the local encoding."
+msgstr "Bruk standardteiknkodinga frå lokalet i den eksporterte fila."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "&Søk"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "&Stopp"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Nettsøk"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Søkjeførespurnad"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr "Søk &etter:"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr "Skriv inn søkjeverdi. Eit ISBN-søk må innehelda heile ISBN-koden."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Vel søkjetype"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Trykk for å starta eller stoppa søket"
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr "Søk etter &fleire ISBN/UPC-nummer"
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr "Kryss av her for å søkja etter fleire ISBN- eller UPC-verdiar."
+
+#: fetchdialog.cpp:138
+msgid "Edit List..."
+msgstr "Rediger liste …"
+
+#: fetchdialog.cpp:140
+msgid "Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr "Trykk for å opna eit skrivefelt for redigering av fleire ISBN-nummer."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "Søkje&kjelde:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Vel databasen du vil søkja i"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"Etter kvart som søkjeresultata kjem inn, vert dei lagt til lista her. Vel "
+"eitt av dei for å henta og visa heile oppføringa."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"Du kan sjå nærare på ei oppføring utan å leggja ho til samlinga ved å "
+"trykkja på ho."
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "&Legg til oppføring"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Legg til merkt oppføring i samlinga."
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr "Hent fleire resultat"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr "Hent fleire resultat frå datakjelda."
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Tøm alle søkjefelta og søkjeresultata."
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Avbryt søket …"
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Søkjer …"
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "Søket gav ikkje nokon treff."
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+"Søket gav eitt treff.\n"
+"Søket gav %n treff."
+
+#: fetchdialog.cpp:412
+msgid "No results were found for the following ISBN values:"
+msgstr "Fann ikkje nokon oppføringar for desse ISBN-verdiane:"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Hentar %1 …"
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr "Det finst ingen Internett-kjelder for denne samlingstypen."
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr "Rediger ISBN-/UPC-verdiar"
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Skriv inn ISBN- eller UPC-nummer – eitt per linje.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "&Hent frå fil …"
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Opna liste frå tekstfil.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>Eit ISBN-søk kan ikkje innehelda meir enn 100 ISBN-nummer. Berre dei "
+"første 100 verdiane i lista vert derfor brukt.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Rediger oppføring"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Ny oppføring"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "&Lagra oppføring"
+
+#: entryeditdialog.cpp:77
+msgid "Go to the previous entry in the collection"
+msgstr "Gå til førre oppføring i samlinga."
+
+#: entryeditdialog.cpp:82
+msgid "Go to the next entry in the collection"
+msgstr "Gå til neste oppføring i samlinga."
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Er du sikker på at du vil endra desse oppføringane?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Endra fleire oppføringar"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr "Desse felta må ha verdiar. Vil du halda fram?"
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Rediger oppføringar"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "La&gra oppføringar"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"Oppføringa er endra.\n"
+"Vil du lagra endringane?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Lagra oppføring"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Samlingsrapport"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "&Rapportmal:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "&Lag"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr "Vel ein rapportmal og trykk <em>Lag</em>."
+
+#: reportdialog.cpp:108
+msgid "Some reports may take several seconds to generate for large collections."
+msgstr "Det kan ta fleire sekund å lagra rapportar for store samlingar."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Er du sikker på at du vil sletta dette filteret?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Vil du sletta dette filteret?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Nytt samlingsnamn:"
+
+#: tellico_kernel.cpp:377
+msgid "Entry 1"
+msgstr "Oppføring 1"
+
+#: tellico_kernel.cpp:378
+msgid "Entry 2"
+msgstr "Oppføring 2"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr "Fann ulike verdiar for %1 ved samanslåing av oppføringane."
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr "Vel kven av verdiane du ønskjer å behalda."
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+msgid "Merge Entries"
+msgstr "Slå saman oppføringar"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr "Vel verdi frå %1"
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Klarte ikkje finna standardstilsett for oppføring."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Ny"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Samling"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Samlingsverktøylinje"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Karl Ove Hufthammer"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "karl@huftis.org"
+
+#: entrymerger.cpp:35
+msgid "Merging entries..."
+msgstr "Slår saman oppføringar …"
+
+#: entrymerger.cpp:49
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Totalt samanslegne/skanna oppføringar: %1/%2"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>… når ei bok har meir enn éin forfattar, kan du skilja namna deira "
+"med semikolon. Tellico vil då handtera namna rett.</p>\n"
+"<p>Du skriv òg andre felt som kan innehelda fleire verdiar på same måte "
+"– med eit semikolon («;») mellom kvar verdi.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>… du kan endra kva felt som skal visast i listevisinga ved å "
+"høgreklikka på kolonneoverskriftene.</p>\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>… du kan leggja til, redigera eller endra felta i samlinga i "
+"feltredigeringsvindauget. Du bruker pilknappane under feltlista for å endra "
+"plasseringa av felta i lista, som igjen endrar plasseringa i "
+"redigeringsvindauget.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>… viss du vil filtrera på ein avkryssingsboks, brukar du verdien "
+"«true». Viss du for eksempel berre vil visa barnebøkene du ikkje har "
+"lest, kryssar du av <em>Oppfyll alle felt</em>, set første regel til å la "
+"«Sjanger» innehelda «barnebok» (utan hermeteikn), og set andre regel til "
+"å la «Lesen» ikkje innehelda «true» (igjen utan hermeteikn).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>… viss du brukar eit ikkje-alfabetisk teikn i snøggfilteret, vert "
+"teksten tolka som eit regulært uttrykk.</p>\n"
+"<p>Viss du for eksempel berre vil visa bøker skrivne av Ibsen eller "
+"Bjørnson, kan du skriva «ibsen|bjørnson» (utan hermeteikn) i "
+"filterfeltet.</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>… du kan redigera meir enn éi oppføring om gongen ved å helda inne "
+"«Shift» eller «Ctrl» og velja fleire oppføringar.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>… du kan konvertera ei eksisterande boksamling til ei litteraturliste, "
+"som du så kan eksportera til BibTeX- eller BibTeXML-format.</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>… du kan leggja til, redigera og sletta tekstmakroar for "
+"litteraturlister.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>… viss meir enn eitt felt er formatert som namn, vert automatisk gruppa "
+"«Personar» lagt til i samlinga, slik at du kan sortera og skriva ut for "
+"eksempel forfattarar og redaktørar samtidig.</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>… du kan endra utsjånaden på utskrifta ved å redigera fila "
+"<tt>tellico-printing.xsl</tt>. Fila lagar HTML, og CSS-blokka i stilsettet "
+"fastset skrift, margar og liknande.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>… du kan importera ved å bruka eitkvart XSLT-stilsett som gjev ut "
+"gyldige Tellico XML-filer.</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+"<p>… du kan dobbeltklikka på oppføringar for å opna "
+"redigeringsvindauget.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>… du kan leggja HTML-element til alle avsnittsfelt, som\n"
+"&lt;em&gt;utheving&lt;/em&gt; og &lt;strong&gt;sterk "
+"utheving&lt;/strong&gt;.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>… i detaljert vising kan du trykkja ein tast på tastaturet for å "
+"hoppa direkte til neste oppføring som startar på denne bokstaven.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+"<p>… du kan bruka avhengige felt for å setja saman data frå fleire felt "
+"til eit nytt felt. Berre velg felttypen «Avhengig», og bruk ei skildring "
+"på formatet «Verdi: %{feltA}%{feltB}». Teksten «%{…}» vert automatisk "
+"erstatta med feltverdiane. Dette er nyttig for å samla fleire verdiar i "
+"eitt felt, for eksempel for betre gruppering, og for å kombinera felt av "
+"forskjellige typar og samtidig ha rett sortering. Eit eksempel kan vera eit "
+"talfelt følgd av eit tekstunderfelt, med oppføringar som «3b» eller "
+"«14a».</p>\n"
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Album"
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr "Denne malen er berre meint for musikksamlingar."
+
+#: xslt.cpp:5
+msgid "Total:"
+msgstr "Totalt:"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr "Stilig"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "Standard"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Kompakt"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Film"
+
+#: xslt.cpp:14 xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr "Denne malen er berre meint for filmsamlingar."
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Gruppesamandrag"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Gruppesamandrag"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Talet på felt totalt:"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Talet på oppføringar totalt:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+msgid "Generated by Tellico"
+msgstr "Laga av Tellico"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Forskjellige verdiar: "
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Biletliste"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Lånevising"
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Lånedato"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Merknad"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Innleveringsfrist"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Gruppevising"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Titlar (vassrett)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Titlar (loddrett)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Kolonnevising"
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "Trekolonne"
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr "Søk"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr "The British Library"
+
+#: z3950.cpp:6
+msgid "Sudoc (France)"
+msgstr "Sudoc (Frankrike)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr "BIBSYS (Noreg)"
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr "Nasjonalbiblioteket i Italia"
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr "Nasjonalbiblioteket i Portugal"
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr "Nasjonalbiblioteket i Polen"
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr "Nasjonalbiblioteket i Canada"
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr "Israelsk samsøk"
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr "Nasjonalbiblioteket i Australia"
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr "Nasjonalbiblioteket i Litauen"
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr "Copac (Storbritannia og Irland)"
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr "BoardGameGeek"
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr "Dark Horse Comics"
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr "Allocine.fr"
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr "Det spanske kulturdepartementet"
+
diff --git a/po/pl.po b/po/pl.po
new file mode 100644
index 0000000..21df217
--- /dev/null
+++ b/po/pl.po
@@ -0,0 +1,5441 @@
+# translation of Tellico to Polish
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+#
+#
+# Marek Janukowicz <marek@janukowicz.net>, 2005.
+# Marek Janukowicz <marek@power.com.pl>, 2005.
+# Leszek Cimala <ernierasta@gmail.com>, 2007.
+msgid ""
+msgstr ""
+"Project-Id-Version: pl\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2007-10-11 08:41+0200\n"
+"Last-Translator: Leszek Cimala <ernierasta@gmail.com>\n"
+"Language-Team: <pl@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Report-Msgid-Bugs-To: \n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "<qt>Tellico nie może zapisywać do potoku serwera <b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr "Łączenie z OpenOffice.org..."
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+#, fuzzy
+msgid "OpenOffice.org Connection"
+msgstr "OpenOffice.org Łączenie"
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+"Tellico nie mógł połączyć się z OpenOffice.org. Proszę sprawdź "
+"poniższe ustawienia oraz czy OpenOffice.org Writer jest uruchomiony."
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr "Potok"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr "TCP/IP"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr "Zmień nazwę kolumny"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr "Nowa nazwa kolumny:"
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr "Kolumna %1"
+
+# CHECKME
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr "Zmień &nazwę kolumny..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr "Wstaw wiersz"
+
+# CHECKME
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr "&Usuń wiersz"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr "Przesuń w górę"
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr "Przesuń w dół"
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr "Wyczyść tabelę"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr "Podgląd Szablonu"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Ustaw"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr "%1:"
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Więcej"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Mniej"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Wyczyść"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Wybierz obrazek..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr ""
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr ""
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Edytuj %1"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Dodaj kolekcję"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Połącz kolekcje"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Zastąp kolekcję"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr "Edytuj wpisy"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "Dodaj pole %1"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Zmień pole %1"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Usuń pole %1"
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr "Dodaj wpisy"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Dodaj %1"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Zmień nazwę kolekcji"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Modyfikuj wypożyczenie"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Dodaj filtr"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Modyfikuj filtr"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Kasuj filtr"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Wypożycz przedmioty"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Wypożycz %1"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Usuń wpisy"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Usuń %1"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Zmień kolejność pól"
+
+#: commands/removeloans.cpp:79
+#, fuzzy
+msgid "Check-in Entries"
+msgstr "Oddaj przedmioty"
+
+#: commands/removeloans.cpp:80
+#, fuzzy, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Zwróć"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Ogólne"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Stan"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+#, fuzzy
+msgid "Personal"
+msgstr "Osobiste"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Moje znaczki"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Tytuł"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Opis"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Wartość nominalna"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "Państwo"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Rok emisji"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Kolor"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr ""
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr "świetny,wyjątkowo dobry,bardzo dobry,dobry,średni,zły"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Stan"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Anulowany"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+#, fuzzy
+msgid "Hinged"
+msgstr "Podklejony"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr ""
+
+#: collections/stampcollection.cpp:100
+#, fuzzy
+msgid "Gummed"
+msgstr "Pognieciony"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Data zakupu"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Cena zakupu"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+#, fuzzy
+msgid "Location"
+msgstr "Umieszczenie"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Podarunek"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Obraz"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Komentarz"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Wydanie"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Klasyfikacja"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Moje komiksy"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Podtytuł"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Scenariusz"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr "Ilustracje"
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Seria"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Zeszyt"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Wydawnictwo"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Edycja"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Rok wydania"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Ilość stron"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Język"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Gatunek"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Słowa kluczowe"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr "doskonały,prawie doskonały,bardzo dobry,dobry,zadowalający,marny"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Podpisana"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Wypożyczona"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Okładka"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Moje monety"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Typ"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Rok"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr ""
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Zestaw monet"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr ""
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr ""
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Awers"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Rewers"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Moje książki"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Autor"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Twarda oprawa"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Miękka oprawa"
+
+#: collections/bookcollection.cpp:57
+#, fuzzy
+msgid "Trade Paperback"
+msgstr "Miękka oprawa.(dobry papier)"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "E-Book"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Czasopismo"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Dziennik"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Oprawa"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Rok 1. opublikowania"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN#"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Międzynarodowy Stardardowy Numer Książki"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN#"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Numer Kontrolny Biblioteki Kongresu"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr ""
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Numer serii"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Nowa"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Używana"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Przeczytana"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Ocena"
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr "Moje pliki"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "Nazwa"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Część"
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr "Katalog"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr "Typy MIME"
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr "Rozmiar"
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr "Uprawnienia"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr "Właściciel"
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr "Grupa"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr "Utworzony"
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr "Zmodyfikowany"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr "Dodatkowe informacje"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Właściwość"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Wartość"
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr "Ikona"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Moje wina"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Producent"
+
+#: collections/winecollection.cpp:49
+#, fuzzy
+msgid "Appellation"
+msgstr "Nazwa (region)"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Odmiana"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Rocznik"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Czerwone wino"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Białe wino"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Wino musujące"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Ilość"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Wypite przez"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Obrazek etykiety"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Inni ludzie"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Właściwości"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Moje filmy"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr "Blu-ray"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+msgid "HD DVD"
+msgstr "HD DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Nośnik"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Rok produkcji"
+
+# er -
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr ""
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Certyfikacja"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Region 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Region 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Region 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Region 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Region 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Region 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Region 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Region 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Region"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Kraj"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Format"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Występują"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr "Aktor/Aktorka"
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr "Rola"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr "Tabela z występującymi aktorami oraz ich rolami"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Reżyser"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Muzyka"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Studio"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Ścieżki językowe"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Języki podpisów"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Ścieżki audio"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Czas trwania"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "Czas trwania filmu (w minutach)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Proporcje"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Szerokoekranowy"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Czarno-biały"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Tryb koloru"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Wersja reżyserska"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Streszczenie"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Ocena własna"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Okładka"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "Moje gry"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr "Xbox 360"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr "PlayStation3"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr "Nintendo Wii"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr ""
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Platforma"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Rok wydania"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Wydawca"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Programista"
+
+#: collections/gamecollection.cpp:80
+#, fuzzy
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+"Brak oceny, Dla dorosłych, Dla nastolatków, Dla wszystkich, Dla dzieci, "
+"Oczekiwanie na ocenę"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "Klasyfikacja ESRB"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Ukończona"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Moje karty"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Gracz"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Zespół"
+
+#: collections/cardcollection.cpp:55
+#, fuzzy
+msgid "Brand"
+msgstr "Marka"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Numer karty"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Typ karty"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Obrazek z przodu"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Obrazej z tyłu"
+
+#: collections/boardgamecollection.cpp:26
+#, fuzzy
+msgid "My Board Games"
+msgstr "Moje gry"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr ""
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Bibliografia"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Typ wpisu"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+"Te typy wpisów są specyficzne dla BibTeXa - patrz dokumentacja BibTeXa."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Klucz Bibtex"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Tytuł książki"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Edytor"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organizacja"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Adres"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Miesiąc"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Liczba"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Jak wydana"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Rozdział"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Odnośnik"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Streszczenie"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Notatki"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Moja muzyka"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Album"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "Płyta CD"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Kaseta magnetofonowa"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Płyta winylowa"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Wykonawca"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Etykieta"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Ścieżki"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr "Długość"
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "the"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr.,jr,iii,iv"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,van,der,van der,von"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 nie umożliwia wyszukiwania dla tego typu kolekcji."
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Ilość rezultatów z %1: %2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "Dane źródło nie posiada żadnych opcji."
+
+#: fetch/entrezfetcher.cpp:56
+#, fuzzy
+msgid "Entrez Database"
+msgstr "Baza wpisów"
+
+#: fetch/entrezfetcher.cpp:485
+#, fuzzy
+msgid "Institution"
+msgstr "Warunek"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Błąd zapytania!"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Błąd poszukiwania połączenia %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Błąd składni rekordu"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Błąd połączenia %1: %2"
+
+#: fetch/srufetcher.cpp:72
+#, fuzzy
+msgid "SRU Server"
+msgstr "Serwer SRU"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Biblioteka Kongresu (USA)"
+
+# CHECKME: spaces! other mesages are effected as well
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr "&Serwer:"
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr "Wprowadź nazwę serwera"
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Port:"
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Podaj numer portu serwera (domyślnie %1)."
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr "Ścieżka: "
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr "Wpisz ścieżkę bazy danych używaną przez serwer z39.50."
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr "Format: "
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr "Wpisz nazwę bazy danych używaną przez serwer."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr "Yahoo! Wyszukiwarka audio"
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "Obrazek okładki nie mógł zostać pobrany."
+
+#: fetch/amazonfetcher.cpp:53
+#, fuzzy
+msgid "Amazon Link"
+msgstr "Amazon (Japonia)"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (USA)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (Wielka Brytania)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Niemcy)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japonia)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (Francja)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Kanada)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Amazon.com Web Services"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "&Państwo:"
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "Stany Zjednoczone"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Wielka Brytania"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Niemcy"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Japonia"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "Francja"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Kanada"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon.com udostępnia dane z kilku zlokalizowanych stron. Wybierz której "
+"chcesz używać dla tego źródła danych."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "&Rozmiar obrazka:"
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Mały obrazek"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Średni obrazek"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Duży obrazek"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Brak obrazka"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"Obrazek okładki może zostać pobrany z Internetu. Nadmierna liczba dużych "
+"obrazków w kolekcji może jednak spowodować zmniejszenie wydajności."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr "Serwer z39.50"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr "Użyj predefiniowanego serwera:"
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "&Baza danych:"
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr "Wpisz nazwę bazy danych używaną przez serwer."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "&Kodowanie:"
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Wpisz kodowanie używane przez serwer z39.50. Najprawdopodobniejszym wyborem "
+"jest MARC-8, chociaż ISO-8859-1 jest również popularne."
+
+#: fetch/z3950fetcher.cpp:550
+#, fuzzy
+msgid "&Format: "
+msgstr "Format"
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr "Rozpoznaj automatycznie"
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+"Podaj format danych używanych przez serwer z39.50. Tellico spróbuje "
+"odgadnąć najlepsze ustawienia jeżeli zaznaczono <i> Rozpoznaj "
+"automatycznie </i>."
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "&Użytkownik:"
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Opcjonalne"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Wpisz nazwę użytkownika używaną przez bazę danych z39.50. Większość "
+"serwerów go nie potrzebuje."
+
+# CHECKME
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "&Hasło"
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Wpisz hasło używane przez bazę danych z39.50. Większość serwerów go "
+"nie potrzebuje. Hasło zostanie zapisane w pliku konfiguracyjnym Tellico w "
+"postaci niekodowanego tekstu."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Zewnętrzna aplikacja"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "&Typ kolekcji:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr "Ustawia typ kolekcji zwróconej z zewnętrznej aplikacji."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:365
+#, fuzzy
+msgid "Set the result type of the data returned from the external application."
+msgstr "Ustawia typ kolekcji zwróconej z zewnętrznej aplikacji."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "Ścieżka do &aplikacji:"
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+"Ustawia ścieżkę do aplikacji, która powinna zwrócić poprawny plik z "
+"danymi w formacie Tellico."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr "Wybierz słowa kluczowe wspierane przez wyszukiwarkę serwera."
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+"Dodaje argumenty, które mogą być potrzebne. <b>%1</b> zostanie "
+"zastąpione przez warunki wyszukiwania."
+
+#: fetch/execexternalfetcher.cpp:382
+#, fuzzy
+msgid "Arguments"
+msgstr "&Argumenty:"
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+msgid "Update"
+msgstr "Uaktualnij"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+"<p>Wprowadź dane, które powinny zostać użyte przy wyszukiwaniu "
+"dostępnych uaktualnień wpisu.</p><p>Format jest taki sam jak dla <i> pól "
+"zależnych</i>. ,gdzie nazwa pola wpisana jest w klamry, na przykład "
+"<i>%{author}</i>. Więcej informacji można znaleźć w dokumentacji "
+"programu."
+
+#: fetch/configwidget.cpp:29
+#, fuzzy
+msgid "Source Options"
+msgstr "Opcje źródła"
+
+#: fetch/configwidget.cpp:40
+#, fuzzy
+msgid "Available Fields"
+msgstr "Pola kolekcji"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "Internetowa baza filmów"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Wybierz rezultat IMDB"
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+"<qt>Twoje zapytanie zwróciło wiele rezultatów. Proszę wybrać jeden z "
+"listy poniżej.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Wybierz rezultat wyszukiwania</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Alternatywne tytuły"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+#, fuzzy
+msgid "IMDB Rating"
+msgstr "Klasyfikacja ESRB"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"Internetowa baza filmów używa wielu różnych serwerów. Wybierz ten, "
+"którego chcesz używać."
+
+#: fetch/imdbfetcher.cpp:1132
+#, fuzzy
+msgid "&Maximum cast: "
+msgstr "Maksymalna szerokość obrazka:"
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+#, fuzzy
+msgid "Download cover &image"
+msgstr "Pobierz obrazek okładki"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr "Księgarnia internetowa (ibs.it)"
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Osoba"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Słowo kluczowe"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr "Dystrybucja"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr ""
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:343
+#, fuzzy
+msgid "&Username: "
+msgstr "&Użytkownik:"
+
+#: fetch/crossreffetcher.cpp:348
+#, fuzzy
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+"Wpisz hasło używane przez bazę danych z39.50. Większość serwerów go "
+"nie potrzebuje. Hasło zostanie zapisane w pliku konfiguracyjnym Tellico w "
+"postaci niekodowanego tekstu."
+
+# CHECKME
+#: fetch/crossreffetcher.cpp:354
+#, fuzzy
+msgid "&Password: "
+msgstr "&Hasło"
+
+#: fetch/gcstarpluginfetcher.cpp:190
+#, fuzzy
+msgid "GCstar Plugin"
+msgstr "Występują"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+#, fuzzy
+msgid "Set the collection type of the data returned from the plugin."
+msgstr "Ustawia typ kolekcji zwróconej z zewnętrznej aplikacji."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:415
+#, fuzzy
+msgid "Select the GCstar plugin used for the data source."
+msgstr "Wybierz słowa kluczowe wspierane przez wyszukiwarkę serwera."
+
+#: fetch/gcstarpluginfetcher.cpp:420
+#, fuzzy
+msgid "Author: "
+msgstr "Autor"
+
+#: fetch/discogsfetcher.cpp:58
+#, fuzzy
+msgid "Discogs Audio Search"
+msgstr "Yahoo! Wyszukiwarka audio"
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr ""
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr ""
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr "Wersja"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr ""
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr "Rok wydania"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+
+#: newstuff/dialog.cpp:137
+#, fuzzy
+msgid "The name and license of the selected item"
+msgstr "Zwrot wybranych przedmiotów"
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr "Autor wybranych przedmiotów"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr "Zainstaluj"
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr "Pobierz i zainstaluj wybrany szablon."
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr "Opis wybranych przedmiotów wyświetla się tutaj."
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr "Ściągam dane..."
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Gotowy."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr ""
+
+#: newstuff/dialog.cpp:413
+#, fuzzy
+msgid "Installing item..."
+msgstr "Zapisywanie pliku..."
+
+#: translators/bibteximporter.cpp:79
+#, fuzzy
+msgid "No valid bibtex entries were found"
+msgstr "Plik %1 nie zawiera żadnych poprawnych wpisów bibtex."
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "Plik %1 nie zawiera żadnych poprawnych wpisów bibtex."
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Opcje bibtexa"
+
+#: translators/bibteximporter.cpp:287
+#, fuzzy
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Koduj w Unicode (UTF-8)"
+
+#: translators/bibteximporter.cpp:288
+#, fuzzy
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Koduj eksportowany plik w Unicode (UTF-8)"
+
+#: translators/bibteximporter.cpp:289
+#, fuzzy
+msgid "Use user locale (%1) encoding"
+msgstr "Koduj używając ustawień użytkownika (%1)"
+
+#: translators/bibteximporter.cpp:293
+#, fuzzy
+msgid "Read the imported file in the local encoding."
+msgstr "Koduj eksportowany plik w lokalnym formacie."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "Plik Zip Tellico"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Pliki Tellico (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Wszystkie Pliki"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>Biblioteka Alexandrii o nazwie <i>%1</i> już istnieje. Istniejące "
+"książki w tej bibliotece zostaną nadpisane.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "Błąd parsowania XML, linia %1, kolumna %2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "Komunikat błędu z Qt:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Ten plik jest z przyszłej wersji Tellico."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Tellico konwertuje plik do nowszego formatu. Jeśli starsza wersja Tellico "
+"zostanie użyta do odczytania tego piku w przyszłości, pewne informacje "
+"mogą zostać utracone."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Nieznany"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "Plik jest pusty."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "Plik nie zawiera kolekcji."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Nieprzeczytane książki"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Stare filmy"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "Muzyka lat 80"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Ulubione"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Skanowanie plików audio..."
+
+#: translators/audiofileimporter.cpp:129
+#, fuzzy
+msgid "Bitrate"
+msgstr "Bibtex"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(Różne)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Opcji plików audio"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Szukaj rekursywnie w folderach"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+"Jeśli zaznaczone, foldery będą przeszukiwane rekursywnie w poszukiwaniu "
+"plików audio."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:348
+#, fuzzy
+msgid "If checked, the file names for each track are added to the entries."
+msgstr ""
+"Jeśli zaznaczone, nazwy pól zostaną wydrukowane jako nagłówki tabeli."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:353
+#, fuzzy
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr ""
+"Jeśli zaznaczone, nazwy pól zostaną wydrukowane jako nagłówki tabeli."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|Pliki CSV (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "Opcje CSV"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Użyj nazw pól jako nagłówków kolumn"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr ""
+"Jeśli zaznaczone,dodany zostanie rząd nagłówkowy zawierający nazwy pól."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Ogranicznik"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"Oprócz przecinka, również inne znaki mogą być używane jako ogranicznik "
+"oddzielający poszczególne wartości w pliku."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Przecinek"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Użyj przecinka jako ogranicznika."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Średnik"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Użyj średnika jako ogranicznika."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Tab"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Użyj tabulatora jako ogranicznika."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Inny"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Użyj innego łańcucha jako ogranicznika."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr ""
+"Inny łańcuch, taki jak dwukropek, może być używany jako ogranicznik."
+
+#: translators/filelistingimporter.cpp:63
+#, fuzzy
+msgid "Scanning files..."
+msgstr "Skanowanie plików audio..."
+
+#: translators/filelistingimporter.cpp:191
+#, fuzzy
+msgid "File Listing Options"
+msgstr "Opcje drukowania"
+
+#: translators/filelistingimporter.cpp:193
+#, fuzzy
+msgid "Recursive folder search"
+msgstr "Szukaj rekursywnie w folderach"
+
+#: translators/filelistingimporter.cpp:194
+#, fuzzy
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+"Jeśli zaznaczone, foldery będą przeszukiwane rekursywnie w poszukiwaniu "
+"plików audio."
+
+#: translators/filelistingimporter.cpp:198
+#, fuzzy
+msgid "Generate file previews"
+msgstr "&Generuj raporty..."
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "Archiwum ONIX"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.zip|Pliki Zip (*zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "Opcje archiwum ONIX"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Dołącz obrazki do archiwum"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Jeśli zaznaczone, obrazki w dokumencie zostaną załączone do archiwum "
+"ONIX."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr ""
+"<qt>Tellico nie mogło uzyskać dostępu do urządzenia CD-ROM - "
+"<i>%1</i>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+#, fuzzy
+msgid "Select CDDB Entry"
+msgstr "Usuń wpis"
+
+#: translators/freedbimporter.cpp:197
+#, fuzzy
+msgid "Select a CDDB entry:"
+msgstr "Wybierz rezultat IMDB"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>Żaden rekord nie pasuje do płyty CD.</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "<qt>Tellico nie mogło ukończyć poszukiwania płyty CD.</qt>"
+
+#: translators/freedbimporter.cpp:470
+#, fuzzy
+msgid "Various"
+msgstr "(Różne)"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Opcje Audio CD"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Odczytaj dane z urządzenia CD-ROM."
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Wybierz lub wprowadź lokację urządzenia CD-ROM."
+
+#: translators/freedbimporter.cpp:502
+#, fuzzy
+msgid "Read all CDDB cache files only"
+msgstr "Odczytuj tylko pliki cache CDDB."
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+"Odczytuj dane rekursywnie ze wszystkich pliku cache CDDB zawartych w "
+"domyślnych folderach cache."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr ""
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+#, fuzzy
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.csv|Pliki CSV (*.csv)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+#, fuzzy
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.csv|Pliki CSV (*.csv)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "Opcje XSLT"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "Plik XSLT:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr "Wybierz plik XSLT do przetransformowania danych XML."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Opcje Alexandrii"
+
+#: translators/alexandriaimporter.cpp:195
+#, fuzzy
+msgid "&Library:"
+msgstr "Biblioteka:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "Bibtexml"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Pliki Bibtexml (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|Pliki XML (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Opcje XML Tellico"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Załącz obrazki w dokumencie XML"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Jeśli zaznaczone, obrazki w dokumencie zostaną załączone w strumieniu "
+"XML jako elementy zakodowane base64."
+
+#: translators/importer.h:100
+#, fuzzy
+msgid "Loading data..."
+msgstr "Importowanie danych..."
+
+#: translators/importer.h:100
+#, fuzzy
+msgid "Loading %1..."
+msgstr "Pobieranie %1..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "Bibtex"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Pliki Bibtexa (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Rozwiń makra łańcuchowe"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Jeśli zaznaczone, makra łańcuchowe zostaną rozwinięte, a żadne wpisy "
+"@string{} nie zostaną zapisane."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Użyj pakietu URL"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr ""
+"Jeśli zaznaczone, wszystkie pola URL zostaną zawinięte w deklarację "
+"\\url."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Opuść wpisy z pustymi kluczami cytowania."
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr ""
+"Jeśli zaznaczone, wpisy bez klucza cytowania bibtexa zostaną opuszczone."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Styl cytowania bibtexa:"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Klamry"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Cytowanie"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"<qt>Styl cytowania używany przy eksporcie bibtexa. Wszystkie wartości pól "
+"będą objęte albo klamrami albo znakami cytowania.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Wybierz typ importowanej kolekcji."
+
+#: translators/csvimporter.cpp:235
+#, fuzzy
+msgid "&First row contains field titles"
+msgstr "Pierwszy rząd zawiera nazwy pól"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr "Jeśli zaznaczone, pierwszy rząd jest używany jako nazwy pól."
+
+#: translators/csvimporter.cpp:248
+#, fuzzy
+msgid "&Comma"
+msgstr "Przecinek"
+
+#: translators/csvimporter.cpp:254
+#, fuzzy
+msgid "&Semicolon"
+msgstr "Średnik"
+
+#: translators/csvimporter.cpp:259
+#, fuzzy
+msgid "Ta&b"
+msgstr "Tab"
+
+#: translators/csvimporter.cpp:264
+#, fuzzy
+msgid "Ot&her:"
+msgstr "Inny:"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "Tabela pokazuje do pięciu pierwszych linii pliku CSV."
+
+#: translators/csvimporter.cpp:296
+#, fuzzy
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt>Ustaw każdą kolumnę tak, by odpowiadała polu w kolekcji wybierając "
+"kolumnę i pole, a następnie klikając przycisk <i>Ustaw</i>.</qt>"
+
+#: translators/csvimporter.cpp:298
+#, fuzzy
+msgid "Co&lumn:"
+msgstr "Kolumna:"
+
+#: translators/csvimporter.cpp:307
+#, fuzzy
+msgid "&Data field in this column:"
+msgstr "Pole danych w tej kolumnie:"
+
+#: translators/csvimporter.cpp:315
+#, fuzzy
+msgid "&Assign Field"
+msgstr "Przypisz pole"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Nowe pole"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|Pliki bazy danych Pilot (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Widoczne kolumny"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "Opcje PilotDB"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Ustaw flagę \"kopia zapasowa\" dla bazy danych"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+#, fuzzy
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>Wczytuje listę ISBN z pliku tekstowego.</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Tellico napotkało błąd podczas przetwarzania XSLT."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "Poprawny plik XSLT jest konieczny do zaimportowania pliku."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|Pliki XSL (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|Pliki HTML (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Ludzie"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(zgrupowane po: %1)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "Opcje HTML"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Drukuj nagłówki pól"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr ""
+"Jeśli zaznaczone, nazwy pól zostaną wydrukowane jako nagłówki tabeli."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Grupuj wpisy"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr "Jeśli zaznaczone, wpisy będą grupowane wg. wybranego pola."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Eksportuj poszczególne wpisy w osobnych plikach"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr "Jeśli zaznaczone, dla każdego wpisu zostanie stworzony osobny plik."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+#, fuzzy
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico nie może odczytać obrazu z pliku - %1"
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Właściwości źródła danych"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "&Nazwa źródła:"
+
+#: fetcherconfigdialog.cpp:79
+#, fuzzy
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr ""
+"Nazwa identyfikuje źródło danych, więc powinna być unikatowa i "
+"informacyjna."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "&Typ źródła:"
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr ""
+"Uaktualnienie powinno spowodować nadpisanie danych wprowadzonych przez "
+"użytkownika"
+
+#: fetcherconfigdialog.cpp:114
+#, fuzzy
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr "Jeśli zaznaczone, wpisy będą grupowane wg. wybranego pola."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Dowolne pole"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "zawiera"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "nie zawiera"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "równe"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "nierówne"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "pasuje do wyrażenia"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "nie pasuje do wyrażenia"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Edytuj..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Zaawansowany filtr"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Kryteria filtrowania"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Dopasuj &wszystkie kryteria"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Dopasuj &dowolne kryterium"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Nazwa filtru:"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "Zapisz filtr"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Prosty tekst"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Paragraf"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Lista wyboru"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Pole zaznaczane"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Tabela"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Pole zależne"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Data"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr "Uaktualnianie %1..."
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr "&Uaktualnianie wpisów..."
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr "Uaktualnij wpisy"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr "Uaktualnianie <b>%1</b>..."
+
+#: entryupdater.cpp:209
+#, fuzzy
+msgid "Select Match"
+msgstr "Wybierz rezultat IMDB"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Rozwiń wszystkie grupy"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Zwiń wszystkie grupy"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Filtruj wg grupy"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (Sortuj wg. ilości)"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Grupa"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Opcje importu"
+
+#: importdialog.cpp:62
+#, fuzzy
+msgid "&Replace current collection"
+msgstr "Zastąp aktualną kolekcję"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr "Zastąp obecną kolekcję zawartością zaimportowanego pliku"
+
+#: importdialog.cpp:65
+#, fuzzy
+msgid "A&ppend to current collection"
+msgstr "Dodaj do aktualnej kolekcji"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Dodaj zawartość importowanego pliku do aktualnej kolekcji. Jest to "
+"możliwe tylko wtedy, gdy typy kolekcji się zgadzają."
+
+#: importdialog.cpp:69
+#, fuzzy
+msgid "&Merge with current collection"
+msgstr "Połącz z aktualną kolekcją"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Połącz zawartość importowanego pliku z aktualną kolekcją. Jest to "
+"możliwe tylko jeśli typy kolekcji się zgadzają. Wpisy muszą sobie "
+"odpowiadać by zostać połączone."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Importuj"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|Pliki RIS (*.ris)"
+
+#: importdialog.cpp:277
+#, fuzzy
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.csv|Pliki CSV (*.csv)"
+
+#: importdialog.cpp:281
+#, fuzzy
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdb|Pliki bazy danych Pilot (*.pdb)"
+
+#: importdialog.cpp:285
+#, fuzzy
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.ris|Pliki RIS (*.ris)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico nie może odczytać pliku - %1."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico nie może zapisać pliku - %1"
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico nie może przesłać pliku - %1."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Tylko kolekcje z takim samym typem wpisów jak aktualna mogą zostać "
+"dodane. Zmiany w aktualnej kolekcji nie zostały dokonane."
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Tylko kolekcje z takim samym typem wpisów jak aktualna mogą zostać "
+"połączone. Zmiany w aktualnej kolekcji nie zostały dokonane."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico nie może odczytać obrazu z pliku - %1"
+
+#: entryiconview.cpp:287
+#, fuzzy
+msgid "&Sort By"
+msgstr "&Port:"
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Dialog wypożyczenia"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "Następujące przedmioty są właśnie wypożyczane:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "Następujący przedmiot jest wypożyczony:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "&Wypożyczający:"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Wpisz imię i nazwisko osoby wypożyczającej przedmioty od ciebie. "
+"Naciśnięcie przycisku pozwala na wybranie z twojej książki adresowej."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "&Data wypożyczenia:"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+"Data wypożyczenia to dzień, w którym wypożyczyłeś przedmioty. "
+"Dzisiejsza data jest wybrana domyślnie."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "Data &zwrotu:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"Data zwrotu to dzień, kiedy przedmiote mają zostać zwrócone. Data zwrotu "
+"nie jest wymagana, chyba że chcesz dodać wypożyczenie do swojego "
+"kalendarza."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Uwagi:"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "Tutaj możesz dodać uwagi nt. wypożyczenia."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "D&odaj przypomnienie do aktywnego kalendarza"
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"Zaznaczenie tego pola spowoduje oddanie <em>Zadania</em> do twojego "
+"aktywnego kalendarza, który możesz obejrzeć używając KOrganizera. To "
+"pole jest aktywne tylko jeśli ustawiłeś datę zwrotu."
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Tworzy nową kolekcję"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Nowa kolekcja &książek"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Tworzy nową kolekcję książek"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Nowa &bibliografia"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Tworzy nową bibliografię BibTexa"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Nowa kolekcja ko&miksów"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Tworzy nową kolekcję komiksów"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Nowa kolekcja &filmów"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Tworzy nową kolekcję filmów"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Nowa kolekcja &muzyki"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Tworzy nową kolekcję muzyki"
+
+# CHECKME
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Nowa kolekcja monet"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Tworzy nową kolekcję monet"
+
+# CHECKME
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Nowa kolekcja znaczków"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Tworzy nową kolekcję znaczków"
+
+# CHECKME
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Nowa kolekcja kart"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Tworzy nową kolekcję kart"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Nowa kolekcja &win"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Tworzy nową kolekcję win"
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Nowa kolekcja &gier"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Tworzy nową kolekcję gier"
+
+#: mainwindow.cpp:272
+#, fuzzy
+msgid "New Boa&rd Game Collection"
+msgstr "Nowa kolekcja &gier"
+
+#: mainwindow.cpp:274
+#, fuzzy
+msgid "Create a new board game collection"
+msgstr "Tworzy nową kolekcję gier"
+
+#: mainwindow.cpp:280
+#, fuzzy
+msgid "New &File Catalog"
+msgstr "Nowe pole"
+
+#: mainwindow.cpp:282
+#, fuzzy
+msgid "Create a new file catalog"
+msgstr "Tworzy nową kolekcję"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Nowa kolekcja &dowolna"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Tworzy nową kolekcję dowolną"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Otwórz istniejący dokument"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Otwórz ostatnio używany plik"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Zapisz dokument"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Zapisz dokument w innym pliku..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Drukuj zawartość dokumentu..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Zakończ aplikację"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Importuje dane kolekcji z innych formatów"
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Importuj dane Tellico"
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Importuje plik z danymi Tellico"
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "Importuj dane CSV..."
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Importuje plik CSV"
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "Importuj dane MODS..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Importuje plik MODS"
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Importuj dane Alexandrii..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Importuje dane z managera kolekcji książek Aleksandria"
+
+#: mainwindow.cpp:352
+#, fuzzy
+msgid "Import Delicious Library Data..."
+msgstr "Importuj dane Tellico"
+
+#: mainwindow.cpp:353
+#, fuzzy
+msgid "Import data from Delicious Library"
+msgstr "Importuje metadane z plików audio"
+
+#: mainwindow.cpp:359
+#, fuzzy
+msgid "Import Referencer Data..."
+msgstr "Importuj dane RIS..."
+
+#: mainwindow.cpp:360
+#, fuzzy
+msgid "Import data from Referencer"
+msgstr "Importuje plik odniesień RIS"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Importuj dane BibTeXa..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Importuje plik bibliografii BibTeXa"
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Importuj dane BibTeXml..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Importuje plik bibliografii BibTeXml"
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "Importuj dane RIS..."
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Importuje plik odniesień RIS"
+
+#: mainwindow.cpp:387
+#, fuzzy
+msgid "Import PDF File..."
+msgstr "Importuj plik"
+
+#: mainwindow.cpp:388
+#, fuzzy
+msgid "Import a PDF file"
+msgstr "Importuje plik CSV"
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Importuj metadane plików audio..."
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Importuje metadane z plików audio"
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Importuj dane z Audio CD..."
+
+#: mainwindow.cpp:405
+#, fuzzy
+msgid "Import audio CD information"
+msgstr "Importuje informacje o Audio CD z FreeDB"
+
+#: mainwindow.cpp:414
+#, fuzzy
+msgid "Import GCstar Data..."
+msgstr "Importuj dane CSV..."
+
+#: mainwindow.cpp:415
+#, fuzzy
+msgid "Import a GCstar data file"
+msgstr "Importuje plik MODS"
+
+#: mainwindow.cpp:421
+#, fuzzy
+msgid "Import Griffith Data..."
+msgstr "Importuj dane CSV..."
+
+#: mainwindow.cpp:422
+#, fuzzy
+msgid "Import a Griffith database"
+msgstr "Eksportuje do bazy danych PilotDB"
+
+#: mainwindow.cpp:428
+#, fuzzy
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Importuj dane z Audio CD..."
+
+#: mainwindow.cpp:429
+#, fuzzy
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Importuje plik z danymi Tellico"
+
+#: mainwindow.cpp:435
+#, fuzzy
+msgid "Import File Listing..."
+msgstr "Importuj plik"
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr ""
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "Importuj transformatą XSL..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Importuje za pomocą transformaty XSL"
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Eksportuj"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Eksportuje dane kolekcji do innych formatów"
+
+#: mainwindow.cpp:461
+#, fuzzy
+msgid "Export to XML..."
+msgstr "Eksportuj do HTML..."
+
+#: mainwindow.cpp:462
+#, fuzzy
+msgid "Export to a Tellico XML file"
+msgstr "Eksportuje do pliku XML Tellico"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Eksportuj do Zip..."
+
+#: mainwindow.cpp:469
+#, fuzzy
+msgid "Export to a Tellico Zip file"
+msgstr "Eksportuje do pliku XML Tellico"
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "Eksportuj do HTML..."
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Eksportuje do pliku HTML"
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "Eksportuj do CSV..."
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Eksportuje wartości oddzielone przecinkami"
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "Eksportuj do PilotDB..."
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Eksportuje do bazy danych PilotDB"
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Eksportuj do Alexandrii..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Eksportuje do biblioteki Alexandrii"
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Eksportuj do BibTeXa..."
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Eksportuje do pliku BibTeXa"
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Eksportuj do BibTeXml..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Eksportuje do pliku BibTeXml"
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "Eksportuj do ONIXa..."
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Eksportuje do pliku ONIX"
+
+#: mainwindow.cpp:524
+#, fuzzy
+msgid "Export to GCfilms..."
+msgstr "Eksportuj do CSV..."
+
+#: mainwindow.cpp:525
+#, fuzzy
+msgid "Export to a GCfilms data file"
+msgstr "Eksportuje do pliku BibTeXa"
+
+#: mainwindow.cpp:531
+#, fuzzy
+msgid "Export to GCstar..."
+msgstr "Eksportuj do CSV..."
+
+#: mainwindow.cpp:532
+#, fuzzy
+msgid "Export to a GCstar data file"
+msgstr "Eksportuje do pliku BibTeXa"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "Eksportuj transformatą XSL..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Eksportuje używając transformaty XSL"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Wycina zaznaczony tekst i umieszcza go w schowku"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Kopiuje zaznaczony tekst do schowka"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Wkleja zawartość schowka"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Zaznacza wszystkie wpisy w kolekcji"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Usuwa zaznaczenie wszystkich wpisów w kolekcji"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Szukaj w Internecie..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Szuka w Internecie..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "Zaawansowane &filtrowanie..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Filtruje kolekcję"
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&Nowy wpis"
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Tworzy nowy wpis"
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "&Edytuj wpis"
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Edytuje wybrane wpisy"
+
+#: controller.cpp:621 mainwindow.cpp:577
+#, fuzzy
+msgid "D&uplicate Entry"
+msgstr "Za&cytuj wpis"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Kopiuj wybrane wpisy"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "&Usuń wpis"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Usuwa wybrane wpisy"
+
+#: mainwindow.cpp:585
+#, fuzzy
+msgid "&Merge Entries"
+msgstr "&Usuń wpisy"
+
+#: mainwindow.cpp:588
+#, fuzzy
+msgid "Merge the selected entries"
+msgstr "Usuwa wybrane wpisy"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "&Generuj raporty..."
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Generuje raporty z kolekcji"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "&Wypożycz..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Wypożyczenie wybranych przedmiotów"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "&Zwróć"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Zwrot wybranych przedmiotów"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "Zmień &nazwę kolekcji"
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Zmienia nazwę kolekcji"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "&Pola kolekcji..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Modyfikuje pola kolekcji"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "Konwertuj do &Bibliografii"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Konwertuje kolekcję książek do bibliografii"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "&Makra łańcuchowe..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Edycja makr łańcuchowych bibtexa"
+
+#: mainwindow.cpp:626
+#, fuzzy
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Kopiuje zaznaczony tekst do schowka"
+
+#: mainwindow.cpp:627
+#, fuzzy
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Kopiuje zaznaczony tekst do schowka"
+
+#: mainwindow.cpp:632
+#, fuzzy
+msgid "Cite Entry in &LyX"
+msgstr "Za&cytuj wpis"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Cytuje wybrane wpisy w LyXie"
+
+#: mainwindow.cpp:638
+#, fuzzy
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Za&cytuj wpis"
+
+#: mainwindow.cpp:639
+#, fuzzy
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Cytuje wybrane wpisy w LyXie"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, fuzzy, no-c-format
+msgid "&Update Entry"
+msgstr "Za&cytuj wpis"
+
+#: mainwindow.cpp:652
+#, fuzzy
+msgid "All Sources"
+msgstr "Źródło"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr "Uaktualnij wpisy z wszystkich dostępnych źródeł"
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Pokaż widok &grupowy"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Włącza/wyłącza widok grupowy"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Ukryj widok gru&powy"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Pokaż &edytor wpisów"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Włącza/wyłącza edytor wpisów"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "Ukryj Edy&tor wpisów"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Pokaż widok &wpisów"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Włącza/wyłącza widok wpisów"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "Ukryj widok wp&isów"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Zmień grupowanie"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "Wybór &grupowy"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Zmienia grupowanie kolekcji"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Filtr"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Wyczyść filtr"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Wpisz filtr tutaj..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Grupy"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt><i>Widok Grupowy</i>dzieli wpisy na grupy bazując na wybranym polu.</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt><i>Widok kolumn</i> pokazuje wartości wybranych pól dla każdego "
+"wpisu.</qt>"
+
+#: mainwindow.cpp:831
+#, fuzzy
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Tellico - manager kolekcji dla KDE"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Tworzenie nowego dokumentu..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Otwieranie pliku..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Otwórz plik"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Zapisywanie pliku..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+"<qt><p>Zapisujesz plik zawierający wiele obrazków, co powoduje, że "
+"Tellico pracuje wolniej.Chcesz zapisać obrazki osobno w katalogu danych "
+"Tellico? To przyśpieszy pracę programu.</p><p>Zawsze możesz to zmienić w "
+"ustawieniach.</p></qt>"
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr ""
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr ""
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Zapisywanie pliku pod nową nazwą..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Drukowanie..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"Kolekcja jest aktualnie filtrowana i pokazuje tylko ograniczony podzbiór "
+"wpisów. Tylko widoczne wpisy zostaną wydrukowane. Kontynuować?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Przetwarzanie dokumentu..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Zamykanie programu..."
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Liczba wpisów: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 pasujących; %2 wybranych)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 pasujących)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 wybranych)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Drukuj %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Strona %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Proszę sprawdzić swoją instalację."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Importowanie danych..."
+
+#: mainwindow.cpp:1858
+#, fuzzy
+msgid "Import File"
+msgstr "Importuj plik"
+
+#: mainwindow.cpp:1864
+#, fuzzy
+msgid "Import Directory"
+msgstr "Reżyser"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Eksportowanie danych..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Eksportuj jako"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Makra łańcuchowe"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Makro"
+
+#: mainwindow.cpp:1936
+#, fuzzy
+msgid "String"
+msgstr "Łańcuch"
+
+#: mainwindow.cpp:1999
+#, fuzzy
+msgid "Creating citations..."
+msgstr "Tworzenie nowego dokumentu..."
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Filtry"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt><i>Widok przefiltrowany</i> pokazuje wpisy pasujące do wybranych reguł "
+"filtrowania.</qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Wypożyczenia"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt><i>Widok wypożyczeń</i>pokazuje listę wszystkich ludzi, którzy "
+"wypożyczyli przedmioty z twojej kolekcji.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr "Uaktualnij wpisy z %1"
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico nie może wczytać obrazka - %1."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+"Plik o nazwie \"%1\" już istnieje. Czy jesteś pewny, że chcesz go "
+"nadpisać?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Nadpisać plik?"
+
+#: filehandler.cpp:211
+#, fuzzy
+msgid "Overwrite"
+msgstr "Nadpisać"
+
+#: filterview.cpp:87
+#, fuzzy
+msgid "Filter (Sort by Count)"
+msgstr "Filtruj (sortuj wg. ilości)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Czy naprawdę chcesz usunąć ten wpis?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Usuń wpis"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Czy naprawdę chcesz usunąć te wpisy?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Usuń wpisy"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "&Edytuj wpisy..."
+
+#: controller.cpp:627
+#, fuzzy
+msgid "D&uplicate Entries"
+msgstr "Edytuj wpisy"
+
+#: controller.cpp:628
+#, fuzzy
+msgid "&Update Entries"
+msgstr "Edytuj wpisy"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "&Usuń wpisy"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+"Następujące przedmioty są aktualnie wypożyczone, zaś Tellico nie "
+"pozwala obecnie na wypożyczanie przedmioty wiele razy jednocześnie. Te "
+"przedmioty zostaną usunięte z listy przedmiotów do wypożyczenia."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Domyślny kalendarz"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"Obecnie Tellico potrafi obsługiwać tylko lokalny kalendarz. Aktywny "
+"kalendarz jest umieszczony zdalnie, więc wypożyczenia nie zostaną dodane."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Aktywny kalendarz"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 powinien zwrócić \"%2\""
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(pusty)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - manager kolekcji dla KDE"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Nie otwieraj ostatnio otwartego pliku"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Importuj <nazwapliku> jako plik bibtex"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Importuj <nazwapliku> jako plik MODS"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Importuj <nazwapliku> jako plik RIS"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Plik do otwarcia"
+
+#: main.cpp:42
+#, fuzzy
+msgid "Data source scripts"
+msgstr "Opcje źródła danych"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Ikony"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Autor biblioteki btparse"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr ""
+
+#: main.cpp:50
+#, fuzzy
+msgid "Author of libcsv library"
+msgstr "Autor biblioteki btparse"
+
+#: main.cpp:52
+#, fuzzy
+msgid "Author of rtf2html library"
+msgstr "Autor biblioteki btparse"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Pola kolekcji"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Obecne pola"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "&Nowe"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Dodaje nowe pole do kolekcji"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "&Usuń"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Usuwa pole z kolekcji"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Przesuwa pole w górę listy. Kolejność jest ważna dla układu pól w "
+"edytorze wpisów."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Przesuwa pole w dół listy. Kolejność jest ważna dla układu pól w "
+"edytorze wpisów."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Właściwości pola"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "&Nazwa:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "Nazwa pola"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "T&yp:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "Typ pola określa wartości jakie mogą być w nim umieszczone"
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "<i>Prosty Tekst</i> jest używany dla większości pól."
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "<i>Paragraf</i>jest używany do dużych bloków tekstu."
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Lista wyboru</i> ogranicza pole do konkretnych wartości."
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "<i>Pole zaznaczane</i> jest używane dla wartości tak/nie."
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr "<i>Liczba</i> wskazuje, że pole zawiera wartość numeryczną."
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+"<i>URL</i>jest używany dla pól odnoszących się do URLi, w tym również "
+"odnośników do innych plików."
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr ""
+"<i>Tabela</i>może przechowywać jedną lub więcej kolumn z wartościami."
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "<i>Obrazek</i> przechowuje obraz."
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+"Pole <i>Data</i> może być używane dla wartości z dniem, miesiącem i "
+"rokiem."
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr "Pole <i>Ocena</i> używa gwiazdek by pokazać wartość oceny."
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"<i>Pole zależne</i>zależy od wartości innych pól i jest formatowane "
+"zgodnie z opisem pola."
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"Pole <i>Tylko Do Odczytu</i> jest używane dla wartości wewnętrznych, "
+"użytecznych przy eksporcie i imporcie."
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "Kate&goria:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr ""
+"Kategoria pola określa zakładkę w edytorze, w której pole zostanie "
+"umieszczone."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "&Opis:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"Opis przypomina jakie informacje są zawarte w pole. Dla <i>Pól "
+"Zależnych</i> opis zawiera łańcuch formatujący taki jak \"%{year} "
+"%{title}\", gdzie nazwy pól są zastępowane przez wartości."
+
+#: collectionfieldsdialog.cpp:193
+#, fuzzy
+msgid "&Default value:"
+msgstr "Domyślny kalendarz"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:203
+#, fuzzy
+msgid "A&llowed values:"
+msgstr "Do&zwolone wartości:"
+
+#: collectionfieldsdialog.cpp:208
+#, fuzzy
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>Dla <i>List Wyboru</i> to pole wyszczególnia dozwolone wartości. Są "
+"one oddzielone średnikiem i umieszczane w liście rozwijanej.</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "Właściwości &rozszerzone:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "&Ustaw..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"Właściwości rozszerzone pola są używane dla określenia parametrów "
+"takich jak odpowiadające pole BibTeXa."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Opcje formatowania"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Brak formatowania"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr "Ta opcja powoduje, że pole nie jest formatowane ani kapitalizowane."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Zezwól tylko na automatyczną kapitalizację"
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr "Opcja pozwala na kapitalizację pola, ale nie na jego formatowanie."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Formatuj jako tytuł"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Ta opcja kapitalizuje (ustawia pierwszą literę w wyrazach na dużą) i "
+"formatuje pole jako tytuł, ale tylko jeśli te opcje są włączone "
+"głobalnie."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Formatuj jako imię i nazwisko"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Ta opcja kapitalizuje i formatuje pole jako imię i nazwisko, ale tylko "
+"jeśli te opcje są włączone globalnie."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Opcje pola"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Włącz autouzupełnianie"
+
+#: collectionfieldsdialog.cpp:243
+#, fuzzy
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Jeśli zaznaczone, autouzupełnianie KDE będzie włączone w polu edycji "
+"dla tego pola."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Pozwól na wiele wartości"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Jeśli zaznaczone, Tellico będzie dzieliło tekst w polu na wiele wartości "
+"(separatorem jest przecinek)."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Pozwól na grupowanie"
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Jeśli zaznaczone, to pole będzie mogło być używane do grupowania "
+"wpisów w widoku grupowym."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr "Przywróć domyślne wartości właściwości wybranego pola."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Zmień pola"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Usuwanie dozwolonych wartości z pola <i>%1</i>, które obecnie istnieje "
+"w kolekcji może spowodować uszkodzenie danych. Czy chcesz zachować "
+"zmienione wartości czy anulować i przywrócić obecnie używane?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Zachowaj zmienione wartości"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Przywróć domyślne właściwości pola"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Czy na pewno chcesz przywrócić wartości domyślne dla "
+"właściwości pola <em>%1</em>?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Przywróć"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Rozszerzone właściwości pola"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr "Pole o tej nazwie już istnieje. Proszę wybrać inną nazwę."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr ""
+"<qt>Kategoria nie może być pusta. Proszę wprowadzić kategorię.</qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>Pole nie może być w takiej samej kategorii jak "
+"<em>Paragraf</em>,<em>Tabela</em> albo <em>Obrazek</em>.Proszę wprowadzić "
+"inną kategorię.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"Nazwa pola nie może być taka sama jak istniejącej kategorii. Proszę "
+"wprowadzić inną nazwę."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+"Zakres oceny musi zawierać się między 1 a 10, a dolna granica musi być "
+"mniejsza niż górna. Proszę wprowadzić poprawne granice."
+
+#: collectionfieldsdialog.cpp:952
+#, fuzzy
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "Tabele są ograniczone do pięciu kolumn."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Aktualny plik został zmieniony.\n"
+"Czy chcesz go zapisać?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Niezapisane zmiany"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Wybierz wypożyczającego"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Konfiguracja Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Opcje ogólne"
+
+#: configdialog.cpp:201
+#, fuzzy
+msgid "&Reopen file at startup"
+msgstr "Otwieraj ostatnio używany plik przy starcie"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Jeśli zaznaczone, plik który ostatnio był otwarty zostanie otwarty przy "
+"starcie programu."
+
+#: configdialog.cpp:207
+#, fuzzy
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "Pokazuj \"Poradę dnia\" przy starcie"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr "Jeśli zaznaczone, \"Porada dnia\" będzie pokazywana przy starcie."
+
+#: configdialog.cpp:213
+#, fuzzy
+msgid "Image Storage Options"
+msgstr "Opcje obrazków"
+
+#: configdialog.cpp:214
+#, fuzzy
+msgid "Store images in data file"
+msgstr "Dołącz obrazki do archiwum"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr ""
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr ""
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Opcje formatowania"
+
+#: configdialog.cpp:227
+#, fuzzy
+msgid "Auto capitalize &titles and names"
+msgstr "Automatycznie kapitalizuj tytuły i nazwiska"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Jeśli zaznaczone, tytuły i nazwiska będą automatycznie kapitalizowane "
+"(pierwsza litera w wyrazach będzie zamieniana na dużą)."
+
+#: configdialog.cpp:232
+#, fuzzy
+msgid "Auto &format titles and names"
+msgstr "Formatuj automatycznie tytuły i nazwiska"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr ""
+"Jeśli zaznaczone, tytuły i nazwiska będą automatycznie formatowane."
+
+#: configdialog.cpp:240
+#, fuzzy
+msgid "No capitali&zation:"
+msgstr "Zezwól tylko na automatyczną kapitalizację"
+
+#: configdialog.cpp:243
+#, fuzzy
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Lista przedrostków, które mogą być używane w nazwiskach. Kolejne "
+"wartości należy oddzielić średnikiem.</qt>"
+
+#: configdialog.cpp:249
+#, fuzzy
+msgid "Artic&les:"
+msgstr "Przedrostki tytułu:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>Lista słów, które powinny być uważane za przedrostki, jeśli są "
+"pierwszym słowem w tytule. Poszczególne wartości należy oddzielać "
+"średnikiem.</qt>"
+
+#: configdialog.cpp:259
+#, fuzzy
+msgid "Personal suffi&xes:"
+msgstr "Przyrostki osobiste:"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Lista przyrostków, które mogą występować w nazwiskach. "
+"Poszczególne przyrostki należy oddzielać średnikiem.</qt>"
+
+#: configdialog.cpp:268
+#, fuzzy
+msgid "Surname &prefixes:"
+msgstr "Przedrostki nazwiska:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Lista przedrostków, które mogą być używane w nazwiskach. Kolejne "
+"wartości należy oddzielić średnikiem.</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Drukowanie"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Opcje drukowania"
+
+#: configdialog.cpp:302
+#, fuzzy
+msgid "&Format titles and names"
+msgstr "Formatuj tytuły i nazwiska"
+
+#: configdialog.cpp:306
+#, fuzzy
+msgid "&Print field headers"
+msgstr "Drukuj nagłówki pól"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Opcje grupowania"
+
+#: configdialog.cpp:313
+#, fuzzy
+msgid "&Group the entries"
+msgstr "Grupuj wpisy"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Opcje obrazków"
+
+#: configdialog.cpp:323
+#, fuzzy
+msgid "Maximum image &width:"
+msgstr "Maksymalna szerokość obrazka:"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Maksymalna szerokość obrazka na wydruku. Proporcje zostaną zachowane."
+
+#: configdialog.cpp:336
+#, fuzzy
+msgid "&Maximum image height:"
+msgstr "Maksymalna wysokość obrazka:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Maksymalna wysokość obrazka na wydruku. Proporcje zostaną zachowane."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Szablony"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Opcje szablonów"
+
+#: configdialog.cpp:369
+#, fuzzy
+msgid "Template:"
+msgstr "Szablony"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+
+#: configdialog.cpp:380
+#, fuzzy
+msgid "&Preview..."
+msgstr "&Nowe..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr ""
+
+#: configdialog.cpp:398
+#, fuzzy
+msgid "Font Options"
+msgstr "Opcje formatowania"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr "Czcionka:"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr "Wielkość:"
+
+#: configdialog.cpp:425
+#, fuzzy
+msgid "Color Options"
+msgstr "Opcje CSV"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr ""
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr ""
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr ""
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr ""
+
+#: configdialog.cpp:469
+#, fuzzy
+msgid "Manage Templates"
+msgstr "Szablony"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr ""
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr ""
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr ""
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr "Kliknij by pobrać dodatkowe schematy z internetu."
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr "Skasuj..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr ""
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Źródła danych"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Opcje źródła danych"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Źródło"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr ""
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+
+#: configdialog.cpp:521
+#, fuzzy
+msgid "Move &Down"
+msgstr "&Usuń"
+
+#: configdialog.cpp:528
+#, fuzzy
+msgid "&New..."
+msgstr "&Nowe..."
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr ""
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Zmień..."
+
+#: configdialog.cpp:533
+#, fuzzy
+msgid "Click to modify the selected data source."
+msgstr "Wypożyczenie wybranych przedmiotów"
+
+#: configdialog.cpp:536
+#, fuzzy
+msgid "Click to delete the selected data source."
+msgstr "Usuwa wybrane wpisy"
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr "Kliknij by pobrać dodatkowe źródła danych z internetu."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr ""
+
+#: configdialog.cpp:1049
+#, fuzzy
+msgid "Delete Template"
+msgstr "Kasuj filtr"
+
+#: configdialog.cpp:1050
+#, fuzzy
+msgid "Select template to delete:"
+msgstr "Wybierz bazę danych do przeszukania"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "Wypożyczający"
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Zwróć"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Zmień wypożyczenie..."
+
+#: loanview.cpp:93
+#, fuzzy
+msgid "Borrower (Sort by Count)"
+msgstr "Wypożyczający (posortowane po ilości)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "Moja kolekcja"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Kolekcja książek"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Kolekcja Komiksów"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Kolekcja filmów"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Kolekcja muzyki"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Kolekcja monet"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Kolekcja znaczków"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Kolekcja win"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Kolekcja kart"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Kolekcja gier"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr ""
+
+#: collectionfactory.cpp:135
+#, fuzzy
+msgid "Board Game Collection"
+msgstr "Kolekcja gier"
+
+#: collectionfactory.cpp:136
+#, fuzzy
+msgid "Custom Collection"
+msgstr "Kolekcja dowolna"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+"<qt><i>Widok wpisów</i> pokazuje sformatowany widok zawartości wpisu.</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt><i>Widok Ikon</i> pokazuje każdy wpis w kolekcji lub grupie używając "
+"ikony, która może być obrazkiem we wpisie.</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Opcje eksportu"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Formatowanie"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Formatuj wszystkie pola"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Jeśli zaznaczone, wartości pól zostaną automatycznie sformatowane "
+"zgodnie z ustawionym dla nich formatem."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Eksportuj tylko wybrane wpisy"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr "Jeśli zaznaczone, tylko wybrane wpisy zostaną wyeksportowane."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Kodowanie"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Koduj w Unicode (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Koduj eksportowany plik w Unicode (UTF-8)"
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Koduj używając ustawień użytkownika (%1)"
+
+#: exportdialog.cpp:72
+#, fuzzy
+msgid "Encode the exported file in the local encoding."
+msgstr "Koduj eksportowany plik w lokalnym formacie."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "Wy&szukaj"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "&Zatrzymaj"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Wyszukiwanie w Internecie"
+
+#: fetchdialog.cpp:94
+#, fuzzy
+msgid "Search Query"
+msgstr "Zapytanie wyszukiwania"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr "Wy&szukaj:"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+"Wprowadź wartość do wyszukania. Wyszukiwanie ISBN musi zawierać pełny "
+"ISBN."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Wybierz typ wyszukiwania"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Kliknij by uruchomić lub zatrzymać wyszukiwanie"
+
+#: fetchdialog.cpp:134
+#, fuzzy
+msgid "&Multiple ISBN/UPC search"
+msgstr "Szukanie &wielu wartości ISBN"
+
+#: fetchdialog.cpp:135
+#, fuzzy
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr "Zaznacz to pole by szukać wielu wartości ISBN."
+
+#: fetchdialog.cpp:138
+#, fuzzy
+msgid "Edit List..."
+msgstr "Edytuj listę ISBN..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+"Kliknij by otworzyć pole edycji by wprowadzić lub edytować wiele "
+"wartości ISBN."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "Prze&szukaj źródło:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Wybierz bazę danych do przeszukania"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"Znajdowane rezultaty są dodawane do listy. Wybranie jednego z nich "
+"spowoduje pobranie całego wpisu i pokazanie go w widoku poniżej."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"Wpis może być pokazany tutaj poprzez wybranie z listy powyżej zanim "
+"zostanie dodany do aktualnej kolekcji."
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "&Dodaj wpis"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Dodaje wybrany wpis do aktualnej kolekcji"
+
+#: fetchdialog.cpp:198
+#, fuzzy
+msgid "Get More Results"
+msgstr "Wybierz rezultat IMDB"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr ""
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Wyczyść wszystkie pola wyszukiwania i rezultaty"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Przerywanie wyszukiwania..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Szukanie..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "Wyszukiwanie nie zwróciło żadnych rezultatów."
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+"Wyszukiwanie zwróciło 1 rezultat.\n"
+"Wyszukiwanie zwróciło %n rezultatów."
+
+#: fetchdialog.cpp:412
+#, fuzzy
+msgid "No results were found for the following ISBN values:"
+msgstr ""
+"<qt>Żadne wpisy nie zostały znalezione dla następujących wartości "
+"ISBN:</qt>"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Pobieranie %1..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr "Brak dostępnych źródeł internetowych dla aktualnego typu kolekcji."
+
+#: fetchdialog.cpp:594
+#, fuzzy
+msgid "Edit ISBN/UPC Values"
+msgstr "Edytuj wartości ISBN"
+
+#: fetchdialog.cpp:598
+#, fuzzy
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Wprowadź wartości ISBN, jedną w każdej linii.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "&Odczytaj z pliku..."
+
+#: fetchdialog.cpp:605
+#, fuzzy
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Wczytuje listę ISBN z pliku tekstowego.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>Poszukiwanie ISBN może zawierać maksymalnie 100 wartości ISBN. Tylko "
+"pierwszych 100 wartości z twojej listy zostanie użytych.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Edytuj wpis"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Nowy wpis"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "&Zapisz wpis"
+
+#: entryeditdialog.cpp:77
+#, fuzzy
+msgid "Go to the previous entry in the collection"
+msgstr "Zaznacza wszystkie wpisy w kolekcji"
+
+#: entryeditdialog.cpp:82
+#, fuzzy
+msgid "Go to the next entry in the collection"
+msgstr "Zaznacza wszystkie wpisy w kolekcji"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Czy naprawdę chcesz zmienić te wpisy?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Zmień wiele wpisów"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr ""
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Edytuj wpisy"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "&Zapisz wpisy"
+
+#: entryeditdialog.cpp:656
+#, fuzzy
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"Aktualny wpis został zmodyfikowany\n"
+"Czy chcesz zapisać zmiany?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Zapisz wpis"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Raport kolekcji"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "Szablon &raportu:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "&Generuj"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr "Wybierz szablon raportu i kliknij <em>Generuj</em>."
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+"Generowanie niektórych raportów dla dużych kolekcji może zająć "
+"kilkanaście sekund."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Czy naprawdę chcesz usunąć ten filtr?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Usunąć filtr?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Nowa nazwa kolekcji:"
+
+#: tellico_kernel.cpp:377
+#, fuzzy
+msgid "Entry 1"
+msgstr "Typ wpisu"
+
+#: tellico_kernel.cpp:378
+#, fuzzy
+msgid "Entry 2"
+msgstr "Typ wpisu"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr ""
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+#, fuzzy
+msgid "Merge Entries"
+msgstr "Usuń wpisy"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr ""
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico nie może znaleźć domyślnego arkusza stylu dla wpisów."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Nowy"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Kolekcja"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Pasek kolekcji"
+
+#: _translatorinfo.cpp:1
+#, fuzzy
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Marek Janukowicz"
+
+#: _translatorinfo.cpp:3
+#, fuzzy
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "marek@janukowicz.net"
+
+#: entrymerger.cpp:35
+#, fuzzy
+msgid "Merging entries..."
+msgstr "&Uaktualnianie wpisów..."
+
+#: entrymerger.cpp:49
+#, fuzzy
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Liczba wpisów: %1"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>... ze jeśli książka ma więcej niż jednego autora, powinieneś "
+"oddzielić ich\n"
+"nazwiska średnikami, co pozwoli Tellico na podzielenie ich i używanie "
+"oddzielnie.</p>\n"
+"<p>Dowolne inne pole dopuszczające wiele wartości powinno być "
+"wprowadzane\n"
+"w ten sam sposób, ze średnikiem oddzielającym poszczególne "
+"wartości.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>... że możesz zmienić pola pokazywane w widoku listy \n"
+"klikając prawym przyciskiem na nagłówku kolumny.</p>\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>... że możesz dodawać, edytować lub zmieniać pola kolekcji "
+"używając\n"
+"Edytora Pól. Przyciski ze strzałkami poniżej listy pól służą do\n"
+"zmiany pozycji pola na liście, która z kolei wpływa na pozycję w "
+"edytorze wpisów.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>... że jeśli chcesz filtrować po Polu Zaznaczanym, należy używać "
+"wartości\n"
+" \"true\". Np. jeśli chciałbyć wyfiltrować książki science fiction, "
+"których nie\n"
+" przeczytałeś, zaznacz przycisk <em>Dopasuj wszystkie kryteria</em>, "
+"ustaw\n"
+" pierwszą regułę na \"Gatunek\" \"zawiera\" \"Science Fiction\" (bez "
+"cudzysłowów),\n"
+"a drugą na \"Przeczytana\" \"nie zawiera\" \"true\"</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>... ze jeśli w Szybkim Filtrze zostanie użyty znak niealfanumeryczny, "
+"to tekst jest interpretowany jako wyrażenie regularne.</p>\n"
+"<p>Np. by pokazać książki Webera lub Bujolda, należy wpisać "
+"\"weber/bujold\" (bez cudzysłowów) w polu filtra.</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>... że możesz edytowac więcej niż jeden wpis jednocześnie\n"
+"przytrzymując klawisz Shift lub Ctrl i zaznaczając wiele wpisów.<p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>... że możesz przekonwertować istniejącą kolekcję książek w "
+"bibliografię,\n"
+"która potem może zostać wyeksportowana do formatu bibtex lub "
+"Bibtexml.</p>\n"
+
+#: tips.cpp:50
+#, fuzzy
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>... że możesz dodawać, edytować i kasować makra łańcuchowe do "
+"bibliografii.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>... że jeśli więcej niż jedno pole jest formatowane jako nazwisko, to "
+"do kolekcji\n"
+"dodawana jest dodatkowa grupa \"Ludzie\", pozwalająca np. na sortowanie\n"
+"lub drukowanie zgrupowanych autorów lub edytorów.</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>...że możesz zmieniać wygląd wydruku poprzez modyfikację pliku\n"
+"<tt>tellico-printing.xsl</tt>. Ten plik służy do generacji HTML, a arkusz "
+"CSS\n"
+"ustala rzeczy takie jak fonty, marginesy itp.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>... że możesz importować używając dowolnego szablonu XSL, który "
+"zwraca poprawny plik XML Tellico.</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+"<p>... że podwójne kliknięcie na wpisie otwiera Edytor Wpisów.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>... że do pól typu Paragraf możesz dodawać tagi HTML takie jak\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>... że w Widoku Szczegółowym możesz nacisnąć\n"
+"literę na klawiaturze, by przejść do następnego wpisu\n"
+"zaczynającego się od tej litery.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Album"
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr "Ten szablon przeznaczony jest do tworzenia kolekcji muzyki."
+
+#: xslt.cpp:5
+#, fuzzy
+msgid "Total:"
+msgstr "&Nazwa:"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr ""
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "Domyślny"
+
+#: xslt.cpp:11
+#, fuzzy
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Płyty CD"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Filmy"
+
+#: xslt.cpp:14 xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr "Ten·szablon przeznaczony·jest·do·tworzenia kolekcji filmów."
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Podsumowanie grup"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Podsumowanie grup"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Liczba pól:"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Liczba wpisów:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+#, fuzzy
+msgid "Generated by Tellico"
+msgstr "Wygenerowany przez"
+
+#: xslt.cpp:21
+#, fuzzy
+msgid "Distinct values: "
+msgstr "Liczba różnych wartości:"
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Lista obrazków"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Widok Wypożyczeń"
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Data wypożyczenia"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Uwaga"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Data zwrotu"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Widok Grupowy"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Lista Tytułów (Pozioma)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Lista Tytułów (Pionowa)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Widok Kolumnowy"
+
+#: xslt.cpp:42
+#, fuzzy
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "Widok Kolumnowy"
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr "Wy&szukaj"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr ""
+
+#: z3950.cpp:6
+#, fuzzy
+msgid "Sudoc (France)"
+msgstr "Amazon (Francja)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr ""
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr ""
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr ""
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr ""
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr ""
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr ""
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr ""
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr ""
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr ""
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr ""
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr ""
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr ""
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr ""
+
+#, fuzzy
+#~ msgid "CrossRef"
+#~ msgstr "Odnośnik"
+
+#, fuzzy
+#~ msgid "MODS"
+#~ msgstr "Mac OS"
+
+#, fuzzy
+#~ msgid "GCstar"
+#~ msgstr "Występują"
+
+#, fuzzy
+#~ msgid "Griffith"
+#~ msgstr "Podarunek"
+
+#, fuzzy
+#~ msgid "Referencer"
+#~ msgstr "Odnośnik"
+
+#~ msgid "Comics"
+#~ msgstr "Komiksy"
+
+#~ msgid "Stamps"
+#~ msgstr "Znaczki"
+
+#~ msgid "Coins"
+#~ msgstr "Monety"
+
+#~ msgid "Books"
+#~ msgstr "Książki"
+
+#~ msgid "Wines"
+#~ msgstr "Wina"
+
+#~ msgid "Videos"
+#~ msgstr "Filmy"
+
+#~ msgid "Games"
+#~ msgstr "Gry"
+
+#~ msgid "Cards"
+#~ msgstr "Karty"
+
+#~ msgid "Entries"
+#~ msgstr "Wpisy"
+
+#~ msgid "Albums"
+#~ msgstr "Albumy"
diff --git a/po/pt.po b/po/pt.po
new file mode 100644
index 0000000..0eeaacd
--- /dev/null
+++ b/po/pt.po
@@ -0,0 +1,5227 @@
+# translation of pt.po to portuguese
+# This file is distributed under the same license as the tellico package.
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+#
+# Lígia Moreira <ligia.moreira@netvisao.pt>, 2005, 2006.
+# Carlos Gonçalves <carlos@pinguix.com>, 2006, 2007.
+# Carlos Goncalves <carlos@pinguix.com>, 2007.
+# Ligia Moreira <ligia.moreira@netvisao.pt>, 2008.
+msgid ""
+msgstr ""
+"Project-Id-Version: pt\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2008-03-15 08:27+0000\n"
+"Last-Translator: Ligia Moreira <ligia.moreira@netvisao.pt>\n"
+"Language-Team: portuguese <pt@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Report-Msgid-Bugs-To: \n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr ""
+"<qt>Tellico não consegue escrever para o 'pipe' do servidor em "
+"<b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr "Ligando-se ao OpenOffice.org..."
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr "Ligação ao OpenOffice.org"
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+"O Tellico não conseguiu ligar-se ao OpenOffice.org. Por favor, verifique as "
+"opções de conexão abaixo e se o OpenOffice.org Writer está a correr."
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr "Pipe"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr "TCP/IP"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr "Renomear Coluna"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr "Novo nome da coluna:"
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr "Coluna %1"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr "Renomear Coluna..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr "Inserir Linha"
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr "Remover Linha"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr "Mover Linha para cima"
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr "Mover Linha para baixo"
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr "Limpar Tabela"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr "Antevisão de Modelo"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Definir"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr "%1:"
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Mais"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Menos"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Apagar"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Seleccionar a imagem..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr "Guardar só a ligação"
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr "Só é possível guardar uma ligação para imagens recentemente adicionadas."
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Modificar %1"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Continuar Colecção"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Combinar Colecção"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Substituir Colecção"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr "Modificar Entradas"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "Adicionar %1 Campo"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Modificar %1 Campo"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Apagar %1 Campo"
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr "Adicionar Entradas"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Adicionar %1"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Renomear Colecção"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Alterar Empréstimo"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Adicionar Filtro"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Alterar Filtro"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Apagar Filtro"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Registar saída de artigos"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Registar saída de %1"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Apagar Entradas"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Apagar %1"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Reordenar Campos"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Registar Entradas de Devoluções"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Registar entrada de %1"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Geral"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Condição"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Pessoal"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Os meus Selos"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Título"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Descrição"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Denominação"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "País"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Ano de Edição"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Cor"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Scott#"
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr "Soberbo,Excelente,Muito bom,Bom,Médio,Mau"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Classificação"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Cancelado"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Articulado"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Centrada"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Colado"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Data de compra"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Preço de compra"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Localização"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Oferta"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Imagem"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Comentários"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Publicação"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Classificação"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "As minhas BD's"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Sub-Título"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Escritor"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr "Artista"
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Série"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Número"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Editor"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Edição"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Ano de Publicação"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Páginas"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Língua"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Género"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Palavras-chave"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr "Novo,Quase novo,Excelente,Óptimo,Muito bom, Bom,Médio,Mau"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Autografado"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Emprestado"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Capa"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "As minhas Moedas"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Tipo"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Ano"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Marca da Casa Emissora"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Conjunto de Moedas"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+"Proof-65,Proof-60,Mint-65,Mint-60,Quase não Circulada-55,Quase não "
+"Circulada-50,Extremamente Rara-40,Muito Rara-30,Muito Rara-20,Rara-12,Muito "
+"Boa-8,Boa-4,Razoável"
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr "PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Tipo de Classificação"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Observação"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Verso"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Os meus Livros"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Autor"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Capa Dura"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Capa Flexível"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Económico"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "Livro Electrónico (e-book)"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Revista"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Jornal"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Formato"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Ano de Copyright"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN#"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Número Internacional Normalizado do Livro"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN#"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Número de Controlo da Livraria do Congresso"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr "Tradutor"
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Nº de Série"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Novo"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Usado"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Lido"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Classificação"
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr "Os meus Ficheiros"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "Nome"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Volume"
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr "Pasta"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr "Tipo MIME"
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr "Tamanho"
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr "Permissões"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr "Proprietário"
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr "Grupo"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr "Criado"
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr "Modificado"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr "Meta-informação (Informações adicionais)"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Propriedade"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Valor"
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr "Ícones"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Os meus Vinhos"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Produtor"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Apelação"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Variedade"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Safra"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Vinho tinto"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Vinho branco"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Espumoso"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Quantidade"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Bebido por"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Etiqueta"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Outras pessoas"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Características"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Os meus Vídeos"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr "Blu-ray"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+msgid "HD DVD"
+msgstr "HD DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Disco"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Ano de Produção"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Certificação"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Região 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Região 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Região 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Região 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Região 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Região 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Região 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Região 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Região"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Nacionalidade"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Formato"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Elenco"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr "Actor/Actriz"
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr "Personagem (Papel)"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr "Um folheto para o elenco do filme, com o papel representado por cada um"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Realizador"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Compositor"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Estúdio"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Línguas Disponíveis"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Língua dos Sub-títulos"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Áudios Disponíveis"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Duração"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "Duração do vídeo (em minutos)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Formato da imagem"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Grande écran"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Preto & branco"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Formato de cor"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Versão do Realizador"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Resumo da acção"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Classificação pessoal"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Capa"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "Os meus Jogos"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr "Xbox 360"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr "PlayStation3"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr "Nintendo Wii"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr "Linux"
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Plataforma"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Ano de Lançamento"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Editor"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Desenvolvedor"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+"Não Classificado, Somente Adultos, Jovens, Adolescentes, Sem Censura, "
+"Infantil, Pendente"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "Classificação ESRB"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Completo"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "As minhas Cartas"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Jogador"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Equipa"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Marca"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Número de carta"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Tipo de Carta"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Imagem Frontal"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Imagem de contra-capa"
+
+#: collections/boardgamecollection.cpp:26
+msgid "My Board Games"
+msgstr "Os meus Jogos de Tabuleiro"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr "Mecanismo"
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr "Designer"
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr "Número de Jogadores"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Bibliografia"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Tipo de Entrada"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr "Esta entrada é específica da BibTeX. Ver a documentação BibTeX."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Chave da BibTeX"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Título do Livro"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Editor"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organização"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Endereço"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr "IOD"
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr "Identificador de Ojecto Digital"
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Mês"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Número"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Modo de Publicação"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Capítulo"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Descritores"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Resumo"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Notas"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "A minha Música"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Álbum"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "CD"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Cassete"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Vinil"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Artista"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Etiqueta"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Pistas"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr "Duração"
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr "um,uma,e,em,de,o,a"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "o,a,os,as"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr.,jr,iii,iv"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,o,a"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr "ISBNdb.com"
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 não permite a pesquisa para este tipo de colecção."
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Resultados de %1 : %2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "Esta fonte não tem opções."
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "Inserir Base de Dados"
+
+#: fetch/entrezfetcher.cpp:485
+msgid "Institution"
+msgstr "Instituição"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Erro de pesquisa!"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Erro na procura da conexão %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Erro de sintaxe no registo"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Erro de conexão %1: %2"
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr "Servidor SRU"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Biblioteca do Congresso (Estados Unidos)"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr "&Servidor: "
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr "Insira o nome do servidor."
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Porta: "
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Insira o número de porta do servidor. A porta padrão é %1."
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr "Caminho: "
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr "Insira a localização da base de dados utilizada pelo servidor."
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr "Formato: "
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr "Insira o formato do resultado utilizado pelo servidor."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr "Motor de pesquisa áudio Yahoo!"
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "A capa não pôde ser carregada."
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr "Ligação Amazon"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (Estados Unidos)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (Reino Unido)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Alemanha)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japão)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (França)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Canadá)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Serviços Web da Amazon.com"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "&País: "
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "Estados Unidos"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Reino Unido"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Alemanha"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Japão"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "França"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Canadá"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon.com disponibiliza dados de vários servidores locais. Escolha o que "
+"deseja utilizar como fonte."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "&Tamanho da imagem"
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Imagem pequena"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Imagem de Disco"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Imagem grande"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Sem imagem"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"A imagem de capa pode ser transferida. No entanto, imagens grandes na "
+"colecção podem degradar o desempenho."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "Identidade &associada: "
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+"A identidade associada identifica a pessoa acedendo aos serviços Web "
+"Amazon.com, e está incluída em todos os links para o sítio Amazon.com."
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr "Servidor z39.50"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr "Usar predefinições do &servidor:"
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "Base de &Dados: "
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr "Insira o nome da base de dados utilizado pelo servidor."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "Conjunto de c&aracteres: "
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Insira o conjunto de caracteres utilizado pelo servidor z39.50. A escolha "
+"mais provável é MARC-8, se bem que ISO-8859-1 seja igualmente comum."
+
+#: fetch/z3950fetcher.cpp:550
+msgid "&Format: "
+msgstr "&Formato: "
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr "Auto-detectar"
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+"Introduza o formato da data usada pelo z39.50 server. O Tellico irá tentar "
+"automaticamente detectar a melhor configuração se a <i>auto-detecção</i> "
+"estiver selecionada."
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "&Utilizador: "
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Opcional"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Insira o nome da base de dados utilizada pelo servidor z39.50. A maioria dos "
+"servidores não precisa dele."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "&Palavra-passe: "
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Insira a palavra-passe utilizada para a base de dados z39.50. A maior parte "
+"dos servidores não precisa dela. A palavra-passe será guardada em formato "
+"texto no ficheiro de configuração do Tellico."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr "Ilustrador"
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Aplicação externa"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "&Tipo de Colecção:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid "Set the collection type of the data returned from the external application."
+msgstr ""
+"Especifique o tipo de colecção dos dados devolvidos pela aplicação "
+"externa."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr "Tipo de &resultado: "
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr "Especifique o tipo de resultado dos dados devolvidos pela aplicação externa."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "&Caminho da aplicação: "
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+"Especifique o caminho da aplicação a ser executada que deve gerar um "
+"ficheiro de dados Tellico válido."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr "Seleccionar as teclas de pesquisa suportadas pela fonte de dados."
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+"Adicione qualquer argumento que possa ser necessário. <b> %1 </b> vai ser "
+"substituído pelo termo a ser pesquisado."
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr "Argumentos"
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+msgid "Update"
+msgstr "Actualizar"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+"<p>Insira os argumentos que devem ser usados para procurar actualizações "
+"disponíveis para uma entrada.</p><p>O formato é o mesmo dos campos "
+"<i>Dependentes</i>, onde os valores dos campos estão contidos entre "
+"chavetas, como <i>%{author}</i>. Veja a documentação para mais "
+"detalhes.</p>"
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Opções de Fonte"
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr "Campos Disponíveis"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "Base de Dados de Filmes Internet"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Seleccione o resultado IMDB"
+
+#: fetch/imdbfetcher.cpp:581
+msgid "<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+"<qt>A sua pesquisa obteve vários resultados. Queira seleccionar um dos "
+"seguintes:</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Seleccione um resultado da pesquisa.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr "Ligação IMDB"
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Títulos alternativos"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+msgid "IMDB Rating"
+msgstr "Classificação IMDB"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Certificações"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"A base de dados de filmes Internet (IMDB) utiliza diferentes servidores. "
+"Escolha o que deseja utilizar."
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr "Número &máximo de actores: "
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+"A lista de membros do elenco pode incluir muitas pessoas. Especifique o "
+"número máximo de ocurrências a ser devolvido pela pesquisa."
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr "Transferir a &imagem da capa"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr "Livraria Internet (ibs.it)"
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Pessoa"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr "UPC/EAN"
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Palavra-chave"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr "ID de arXiv"
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr "ID de Pubmed"
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Pesquisa não refinada"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr "Título Original"
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr "Distribuidor"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr "Episódios"
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr "arXiv.org"
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr "%1 requer um nome de utilizador e uma palavra-passe."
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr "CrossRef requer uma conta de acesso. Por favor, leia os temos e condições e <a href='http://www.crossref.org/requestaccount/'>peça uma conta</a>. Insira abaixo a informação da sua conta OpenURL."
+
+#: fetch/crossreffetcher.cpp:343
+msgid "&Username: "
+msgstr "&Nome de Utilizador: "
+
+#: fetch/crossreffetcher.cpp:348
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr "Insira a palavra-passe utilizada para aceder ao serviço CrossRef. A palavra-passe está gurdada como texto simples no ficheiro de configuração de Tellico."
+
+#: fetch/crossreffetcher.cpp:354
+msgid "&Password: "
+msgstr "Palavra-passe: "
+
+#: fetch/gcstarpluginfetcher.cpp:190
+msgid "GCstar Plugin"
+msgstr "Plugin GCstar"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr "Especifique o tipo de colecção dos dados devolvidos pela aplicação externa."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr "&Plugin: "
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr "Seleccionar o plugin GCstar usado pela fonte de dados."
+
+#: fetch/gcstarpluginfetcher.cpp:420
+msgid "Author: "
+msgstr "Autor:"
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr "Motor de pesquisa áudio Discogs"
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr "API &Chave:"
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr "Com a sua conta discogs.com, recebe uma chave API para utilização da interface de base de dados XML (Ver http://www.discogs.com/help/api)."
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr "Ligação Discogs"
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr "Obtenha Coisas Novas"
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr "Versão"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr "Recepções"
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr "Data de Lançamento"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+"Esta é a lista de todos os itens disponíveis para transferência. Depois "
+"de instalados os itens terão um ícone de marcação, enquanto que itens "
+"com nova versão disponível terão um ícone de actualização"
+
+#: newstuff/dialog.cpp:137
+msgid "The name and license of the selected item"
+msgstr "O nome e licença do item selecionado"
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr "O autor do item selecionado"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr "Instalar"
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr "Transferir e instalar o modelo selecionado."
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+"Transferir e instalar o programa selecionado. Alguns programas podem "
+"necessitar que sejam configurados depois de serem instalados."
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr "A descrição do item selecionado é mostrada aqui."
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr "Transferir informação..."
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Pronto."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr "Actualizar"
+
+#: newstuff/dialog.cpp:413
+msgid "Installing item..."
+msgstr "A instalar o item..."
+
+#: translators/bibteximporter.cpp:79
+msgid "No valid bibtex entries were found"
+msgstr "Não foi encontrada nenhuma entrada BibTeX válida"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "Nenhuma entrada BibTeX válida foi encontrada no ficheiro - %1"
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Opções BibTeX"
+
+#: translators/bibteximporter.cpp:287
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Usar codificação Unicode (UTF-8)"
+
+#: translators/bibteximporter.cpp:288
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Ler o ficheiro mportado em Unicode (UTF-8)."
+
+#: translators/bibteximporter.cpp:289
+msgid "Use user locale (%1) encoding"
+msgstr "Usar codificação da localização do utilizador (%1)"
+
+#: translators/bibteximporter.cpp:293
+msgid "Read the imported file in the local encoding."
+msgstr "Ler o ficheiro importado em formato local."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "Ficheiro Zip Tellico"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Ficheiros Tellico (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Todos os Ficheiros"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>Uma biblioteca Alexandria chamada <i>%1</i> já existe. Qualquer livro "
+"existente nesta biblioteca pode ser sobreposto.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "Um erro de análise XML apareceu na linha %1, coluna %2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "A mensagem de erro de Qt é:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Isto é para uma futura versão de Tellico."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Tellico está a converter o ficheiro num documento com formato mais recente. "
+"Pode haver perda de informações se este ficheiro for lido, no futuro, por "
+"uma versão antiga do Tellico."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Desconhecido"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "O ficheiro está vazio."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "O ficheiro não contém dados da colecção."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Livros não lidos"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Filmes Antigos"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "Música dos anos 80"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Favoritos"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "A analisar os ficheiros áudio..."
+
+#: translators/audiofileimporter.cpp:129
+msgid "Bitrate"
+msgstr "Bitrate"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr "Pistas (Disc %1)"
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(Vários)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Opções de Ficheiro áudio"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Pesquisa recursiva de &pastas"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+"Se seleccionado, as pastas são varridas recursivamente para procurar os "
+"ficheiros áudio."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr "&Incluir localização do ficheiro"
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr ""
+"Se seleccionado, os nomes dos ficheiros de cada faixa serão adicionados às "
+"entradas."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr "Include &bitrate"
+
+#: translators/audiofileimporter.cpp:353
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr ""
+"Se seleccionado, o bitrate para cada pista será adicionado às "
+"entradas."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|Ficheiros CSV (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "Opções CSV"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Incluir os nomes dos campos como cabeçalho das colunas"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr ""
+"Se seleccionada, uma linha de cabeçalho será adicionada com o nome dos "
+"campos."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Separador"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"Para além da vírgula, outros caracteres podem ser utilizados para "
+"delimitar cada valor no ficheiro."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Vírgula"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Utilizar a vírgula como separador."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Ponto e vírgula"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Utilizar o ponto e vírgula como separador."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Tabulação"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Utilizar a tabulação como separador."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Outro"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Utilizar um outro caracter como separador."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr "Um caracter qualquer, como os dois pontos, pode ser utilizado como separador."
+
+#: translators/filelistingimporter.cpp:63
+msgid "Scanning files..."
+msgstr "Varrendo ficheiros..."
+
+#: translators/filelistingimporter.cpp:191
+msgid "File Listing Options"
+msgstr "Opções de Listagem de Ficheiro"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr "Pesquisa recursiva de pastas"
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+"Se seleccionado, as pastas são varridas recursivamente para procurar todos "
+"os ficheiros."
+
+#: translators/filelistingimporter.cpp:198
+msgid "Generate file previews"
+msgstr "Gerar pré-visualizações dos ficheiros"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+"Se seleccionado, serão geradas pré-visualizações dos conteúdos dos "
+"ficheiros, o que pode causar lentidão na listagem das pastas."
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "Arquivo ONIX"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.zip|Ficheiros Zip (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "Opções de Arquivo ONIX"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Incluir as imagens no arquivo"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Se seleccionadas, as imagens do documento serão integradas no arquivo "
+"zipado ONIX."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr "<qt>Tellico não pôde aceder ao periférico de tipo CD-ROM - <b>%1</b>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+msgid "Select CDDB Entry"
+msgstr "Selecionar Entrada CDDB"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr "Seleccione a entrada CDDB:"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>Não foi encontrada nenhuma entrada correspondente ao CD.</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "<qt>Tellico não pôde completar a pesquisa das informações do CD.</qt>"
+
+#: translators/freedbimporter.cpp:470
+msgid "Various"
+msgstr "Vários"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Opções de CD Áudio"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Ler dados do periférico CD-ROM"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Seleccionar o periférico contendo o CD áudio."
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Ler apenas todos os ficheiros de cache CDDB"
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+"Ler recursivamente os dados de todos os ficheiros de cache CDDB contidos nas "
+"pastas de cache padrão."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr "GCfilms"
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.gcf|Ficheiros de Dados GCfilms (*.gcf)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.gcs|Ficheiros de Dados GCstar (*.gcs)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "Opções XSLT"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "Ficheiro XSLT:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr "Escolher o ficheiro XSLT para transformar os dados XML do Tellico."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Opções do Alexandria"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr "&Biblioteca:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "Bibtexml"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Ficheiros BibTeXML (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|Ficheiros XML (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Opções Tellico XML"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Incluir as imagens no documento XML"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Se seleccionadas, as imagens do documento serão integradas nos dados XML "
+"como elementos codificados em base64."
+
+#: translators/importer.h:100
+msgid "Loading data..."
+msgstr "Carregando dados..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr "Carregando %1..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "BibTeX"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Ficheiros BibTeX (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Expandir as linhas de macros"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Se seleccionadas, as linhas de macros serão desenvolvidas e nenhuma entrada "
+"@string{} será escrita."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Utilizar o pacote URL"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr "Se seleccionado, qualquer campo URL será transformado em declaração \\url."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Ignorar as entradas com chaves de citação vazias"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr ""
+"Se seleccionado, qualquer entrada sem chave de citação BibTeX será "
+"ignorada."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Estilos das citações BibTeX:"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Chavetas"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Aspas"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"<qt>O estilo de citação é utilizado quando exporta no formato BibTeX. Os "
+"valores de todos os campos serão envolvidos por chavetas ou por aspas.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Seleccionar o tipo de colecção a importar."
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr "A &primeira linha contém os títulos dos campos"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr "Se seleccionado, a primeira linha será utilizada para o nome dos campos."
+
+#: translators/csvimporter.cpp:248
+msgid "&Comma"
+msgstr "&Vírgula"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr "&Ponto e vírgula"
+
+#: translators/csvimporter.cpp:259
+msgid "Ta&b"
+msgstr "Ta&bulação"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr "Out&ro:"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "O quadro mostra as cinco primeiras linhas do ficheiro CSV."
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt>Para associar cada coluna a um campo da colecção, escolha uma coluna, "
+"seleccione o campo e clique no botão <i>Associar</i>.</qt>"
+
+#: translators/csvimporter.cpp:298
+msgid "Co&lumn:"
+msgstr "Co&luna:"
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr "Campo de &dados nesta coluna:"
+
+#: translators/csvimporter.cpp:315
+msgid "&Assign Field"
+msgstr "&Associar Campo"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr "Tem que haver pelo menos uma coluna associada a um campo. Só serão importadas colunas associadas."
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Novo Campo"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|Ficheiros Pilot Database (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Ver Colunas"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "Opções PilotDB"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Validar a opção PDA backup para a base de dados"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>O ficheiro não é um ficheiro de dados GCstar válido</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Tellico encontrou um erro no processamento XSLT."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "É necessário um ficheiro XSLT válido para importar o ficheiro."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|Ficheiros XSL (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|Ficheiros HTML (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Pessoas"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(agrupados por %1)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "Opções HTML"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Imprimir os cabeçalhos dos campos"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr "Se seleccionado, o nome dos campos será imprimido como títulos de tabela."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Agrupar as entradas"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr ""
+"Se seleccionado, as entradas serão agrupadas em função do campo "
+"seleccionado."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Exportar individualmente as entradas"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr "Se seleccionado, ficheiros isolados serão criados para cada entrada."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico não consegue ler nenhum metadado do ficheiro PDF."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr "Tellico pode descarregar informação do CrossRef.org sobre registos com IOD. Contudo, tem que criar uma conta CrossRef e adicionar uma nova fonte de dados juntamente com a informação da sua conta."
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Propriedades da Fonte de Dados"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "Nome da &fonte: "
+
+#: fetcherconfigdialog.cpp:79
+msgid "The name identifies the data source and should be unique and informative."
+msgstr "O nome identifica a fonte de dados e deverá ser único e informativo."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "&Tipo de fonte: "
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr "Tellico suporta várias fontes de dados diferentes."
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr "Actualizar da fonte pode substituir dados do utilizador"
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Se seleccionado, actualizando as entradas irá substituir toda a "
+"informação existente."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Qualquer campo"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "contém"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "não contém"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "igual a"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "diferente de"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "Verifica a expressão regular"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "Não verfica a expressão regular"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Editar..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Filtro Avançado"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Critérios de filtragem"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Verificar &todas as regras"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Verficar qualquer&uma das regras seguintes"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Nome do filtro:"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "&Guardar Filtro"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Texto Simples"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Parágrafo"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Escolha"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Marcador"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Tabela"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Dependente"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Data"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr "A actualizar %1..."
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr "A actualizar entradas..."
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr "Actualizar Entradas"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr "A actualizar <b>%1</b>..."
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr "Seleccionar Correspondência"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+"<qt><b>%1</b> foram devolvidos vários resultados que correspondem a "
+"<b>%2</b>, que é a entrada actual na colecção. Por favor, seleccione a "
+"correspondência mais apropriada.</qt>"
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Expandir todos os grupos"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Reduzir todos os grupos"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Filtrar por Grupo"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (Classificar por Ordem de Contagem)"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Grupo"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Opções de Importação"
+
+#: importdialog.cpp:62
+msgid "&Replace current collection"
+msgstr "&Substituir a colecção actual"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr "Substitui a colecção aberta pelo conteúdo do ficheiro importado."
+
+#: importdialog.cpp:65
+msgid "A&ppend to current collection"
+msgstr "A&dicionar à colecção actual"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Adiciona os dados do ficheiro importado à colecção aberta. Isso só é "
+"possível se as colecções forem do mesmo tipo."
+
+#: importdialog.cpp:69
+msgid "&Merge with current collection"
+msgstr "&Combinar com a colecção actual"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Combina os dados do ficheiro importado com a colecção actual. Isso só é "
+"possível se as colecções forem do mesmo tipo. As entradas devem ser "
+"exactamente do mesmo tipo para poderem ser combinadas."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Importar"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|Ficheiros RIS (*.ris)"
+
+#: importdialog.cpp:277
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.amc|Ficheiros de dados AMCAMC (*.amc)"
+
+#: importdialog.cpp:281
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdb|Ficheiros PDF (*.pdf)"
+
+#: importdialog.cpp:285
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.reflib|Ficheiros Referencer (*.reflib)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico não consegue carregar o ficheiro - %1."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico não consegue escrever o ficheiro - %1."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico não consegue actualizar o ficheiro - %1."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Só as colecções com o mesmo tipo de campos do da colecção actual podem "
+"ser adicionadas. Não causa nenhuma alteração na colecção actual."
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Só as colecções com tipos de campos idênticos aos da colecção actual "
+"podem ser combinadas. Não provoca nenhuma alteração na colecção actual."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico não consegue carregar uma imagem do ficheiro - %1."
+
+#: entryiconview.cpp:287
+msgid "&Sort By"
+msgstr "&Ordenado por: "
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Janela de Empréstimos"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "Está em curso a verificação dos seguintes artigos:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "O artigo que se segue está emprestado:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "&Emprestar a:"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Escreva o nome do requisitante. Clicar neste botão permitir-lhe-á "
+"seleccioná-lo do seu livro de endereços."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "&Data de Empréstimo:"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+"A data de saída é aquela em que emprestou os artigos. Por omissão, é "
+"usada a data de hoje."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "Data de &devolução:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"A data de devolução é a prevista para a entrega dos artigos. Não é "
+"obrigatória, a não ser que queira adicionar o empréstimo ao seu "
+"calendário activo."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Nota:"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "Pode, igualmente, adicionar observações sobre o empréstimo."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "&Adicionar uma chamada de atenção ao calendário activo"
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"<qt>Assinalar esta casa adicionará uma entrada <em>To-do</em>.(tarefa a "
+"fazer no futuro) ao seu calendário activo que poderá ser consultado "
+"utilizando o KOrganizer. Esta casa só será activada se especificar a data "
+"de devolução do artigo emprestado."
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Criar uma nova colecção"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Nova Colecção de &Livros"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Criar uma nova colecção de livros"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Nova &Bibliografia"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Criar uma nova bibliografia BibTeX"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Nova Colecção de &BD"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Criar uma nova colecção de BD"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Nova Colecção de &Vídeos"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Criar uma nova colecção de vídeos"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Nova Colecção &Musical"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Criar uma nova colecção musical"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Nova Colecção de &Moedas"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Criar uma nova colecção de moedas"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Nova Colecção de &Selos"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Criar uma nova colecção de selos"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Nova Colecção de &Cartas"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Criar uma nova colecção de cartas"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Nova Colecção de &Vinhos"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Criar uma nova colecção de vinhos"
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Nova Colecção de &Jogos"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Criar uma nova colecção de jogos"
+
+#: mainwindow.cpp:272
+msgid "New Boa&rd Game Collection"
+msgstr "Nova Colecção de &Jogos de Tabuleiro"
+
+#: mainwindow.cpp:274
+msgid "Create a new board game collection"
+msgstr "Criar uma nova colecção de jogos de tabuleiro"
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr "Novo Catálogo de &Ficheiros"
+
+#: mainwindow.cpp:282
+msgid "Create a new file catalog"
+msgstr "Criar um novo catálogo de ficheiros"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Nova Colecção &Personalizada"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Criar uma nova colecção personalizada"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Abrir um documento existente"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Abrir um ficheiro recentemente utilizado"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Guardar o documento"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Guardar o documento com um novo nome..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Imprimir os dados do documento..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Sair da aplicação"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Importar dados da colecção a partir de outros formatos"
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Importar Dados do Tellico..."
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Importar um outro ficheiro Tellico"
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "Importar dados CSV..."
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Importar um ficheiro CSV"
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "Importar dados MODS..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Importar um ficheiro MODS"
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Importar dados do Alexandria..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Importar um ficheiro do gestor de colecção de livros Alexandria"
+
+#: mainwindow.cpp:352
+msgid "Import Delicious Library Data..."
+msgstr "Importar Dados da Biblioteca Delicious..."
+
+#: mainwindow.cpp:353
+msgid "Import data from Delicious Library"
+msgstr "Importar dados da Biblioteca Delicious"
+
+#: mainwindow.cpp:359
+msgid "Import Referencer Data..."
+msgstr "Importar dados Referencer..."
+
+#: mainwindow.cpp:360
+msgid "Import data from Referencer"
+msgstr "Importar dados do Referencer"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Importar dados BibTeX..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Importar um ficheiro de bibliografia BibTeX"
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Importar dados BibTeXML..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Importar um ficheiro bibliográfico BibTeXML"
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "Importar dados RIS..."
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Importar um ficheiro de referência RIS"
+
+#: mainwindow.cpp:387
+msgid "Import PDF File..."
+msgstr "Importar Ficheiro PDF"
+
+#: mainwindow.cpp:388
+msgid "Import a PDF file"
+msgstr "Importar um ficheiro PDF"
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Importar ficheiro de metadados áudio "
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Importar metadados de um ficheiro áudio"
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Importar dados de um CD áudio..."
+
+#: mainwindow.cpp:405
+msgid "Import audio CD information"
+msgstr "Importar informações de um CD áudio"
+
+#: mainwindow.cpp:414
+msgid "Import GCstar Data..."
+msgstr "Importar dados GCstar..."
+
+#: mainwindow.cpp:415
+msgid "Import a GCstar data file"
+msgstr "Importar um ficheiro de dados GCstar"
+
+#: mainwindow.cpp:421
+msgid "Import Griffith Data..."
+msgstr "Importar dados Griffith..."
+
+#: mainwindow.cpp:422
+msgid "Import a Griffith database"
+msgstr "Importar uma base de dados Griffith"
+
+#: mainwindow.cpp:428
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Importar Dados do Catálogo Ant Movie..."
+
+#: mainwindow.cpp:429
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Importar um ficheiro de dados do Catálogo Ant Movie"
+
+#: mainwindow.cpp:435
+msgid "Import File Listing..."
+msgstr "Importar Listagem de Ficheiros..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr "Importar informações sobre os ficheiros de uma pasta "
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "Importar Transformação XSL..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Importar um ficheiro utilizando uma transformação XSL"
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Exportar"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Exportar os dados da colecção para outros formatos"
+
+#: mainwindow.cpp:461
+msgid "Export to XML..."
+msgstr "Exportar para XML..."
+
+#: mainwindow.cpp:462
+msgid "Export to a Tellico XML file"
+msgstr "Exportar para um ficheiro Tellico XML "
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Exportar para Zip..."
+
+#: mainwindow.cpp:469
+msgid "Export to a Tellico Zip file"
+msgstr "Exportar para um ficheiro Zip Tellico"
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "Exportar para HTML..."
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Exportar para um ficheiro HTML"
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "Exportar para CSV..."
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Exportar para um ficheiro CSV"
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "Exportar para PilotDB..."
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Exportar para uma base de dados PilotDB"
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Exportar para o Alexandria..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Exportar para uma biblioteca Alexandria"
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Exportar para BibTeX..."
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Exportar para um ficheiro BibTeX"
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Exportar para BibTeXML..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Exportar para um ficheiro BibTeXML"
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "Exportar para ONIX..."
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Exportar para um ficheiro ONIX"
+
+#: mainwindow.cpp:524
+msgid "Export to GCfilms..."
+msgstr "Exportar para GCfilms..."
+
+#: mainwindow.cpp:525
+msgid "Export to a GCfilms data file"
+msgstr "Exportar para um ficheiro de dados GCfilms"
+
+#: mainwindow.cpp:531
+msgid "Export to GCstar..."
+msgstr "Exportar para GCstar..."
+
+#: mainwindow.cpp:532
+msgid "Export to a GCstar data file"
+msgstr "Exportar para um ficheiro de dados GCstar"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "Exportar Transformação XSL..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Exportar utilizando uma transformação XSL"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Cortar o texto seleccionado e colocá-lo na área de transferência"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Copie o texto seleccionado para a área de transferência"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Cole o conteúdo da área de transferência"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Seleccionar todas as entradas desta colecção"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Desfazer a selecção de todas as entradas desta colecção"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Pesquisa na Internet..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Pesquisar na internet..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "Filtro &Avançado..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Filtrar a colecção"
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&Nova Entrada..."
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Criar uma nova entrada"
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "&Editar Entrada..."
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Editar as entradas seleccionadas"
+
+#: controller.cpp:621 mainwindow.cpp:577
+msgid "D&uplicate Entry"
+msgstr "D&uplicar Entrada"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Copiar as entradas seleccionadas"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "&Apagar Entrada"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Apagar as entradas seleccionadas"
+
+#: mainwindow.cpp:585
+msgid "&Merge Entries"
+msgstr "&combinar Entradas"
+
+#: mainwindow.cpp:588
+msgid "Merge the selected entries"
+msgstr "Combinar as entradas seleccionadas"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "&Gerar Relatórios..."
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Gerar relatórios da colecção"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "&Registar empréstimo..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Regista saída das entradas seleccionadas "
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "Registar &entrada de devolução"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Regista entrada de empréstimos devolvidos seleccionados"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "&Renomear Colecção..."
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Renomear a colecção"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "&Campos da Colecção..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Modificar os campos da colecção"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "Converter para &Bibliografia"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Converter uma colecção de livros para uma bibliografia"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "Linha &Macros..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Editar as linhas de macros BibTeX"
+
+#: mainwindow.cpp:626
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Copiar em formato BibTeX para a &Área de Transferência"
+
+#: mainwindow.cpp:627
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Copiar citações BibTeX para a área de transferência"
+
+#: mainwindow.cpp:632
+msgid "Cite Entry in &LyX"
+msgstr "Citar Entrada no &LyX"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Citar as entradas seleccionadas no LyX"
+
+#: mainwindow.cpp:638
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "&Citar Entrada no OpenOffice.org"
+
+#: mainwindow.cpp:639
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Citar as entradas seleccionadas no OpenOffice.org"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, no-c-format
+msgid "&Update Entry"
+msgstr "&Actualizar Entrada"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr "Todas as Fontes"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr "Actualizar as entradas a partir de todas as fontes disponíveis"
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Mostrar &Grupo"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Activar/desactivar a visão de grupo"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Ocultar &Grupo"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Mostrar Editor de &Entrada"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Activar/desactivar o editor"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "Ocultar Editor de &Entrada"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Mostrar &Entradas"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Activar/desactivar visão de entradas"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "Ocultar &Entradas"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Modificar Agrupamento"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "&Selecção de Agrupamento"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Modificar o agrupamento da colecção"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Filtro"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Limpar Filtro"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Filtrar aqui..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Grupos"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt>A <i>Visão de Grupo</i> faz a triagem das entradas por grupos baseados "
+"num campo seleccionado</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt>A <i>Visão de Colunas</i> mostra os valores de vários campos para cada "
+"entrada</qt>"
+
+#: mainwindow.cpp:831
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Bem-vindo ao gestor de colecção Tellico"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr "<h3>Tellico é uma ferramenta para gestão de colecções de livros, música e o que mais quiser catalogar.</h3><h3>Novos registos podem ser adicionados à sua colecção ao <a href=\"tc:///coll_new_entry\">adicionar dados manualmente</a> ou ao <a href=\"tc:///edit_search_internet\">descarregar dados </a> de várias fontes da Internet.</h3>"
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Criação de um novo documento..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "A abrir ficheiro..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Abrir um Ficheiro"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Guardar o ficheiro..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+"<qt><p>Está a guardar um ficheiro com muitas imagens, levando o Tellico a "
+"ficar significativamente lento. Gostaria de guardar as imagens separadamente "
+"no directório de dados do Tellico para melhorar o seu desempenho?</p><p>A "
+"sua escolha pode sempre ser alterada na janela de configuração.</p></qt>"
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr "Guardar imagens separadamente"
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr "Guardar imagens no ficheiro"
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Guardar o ficheiro com um novo nome..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Impressão..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"A colecção é actualmente filtrada para mostrar só uma parte das "
+"entradas. Só as entradas visíveis serão imprimidas. Continuar?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Processando documento..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Saindo..."
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Total de registos: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr ""
+"(%1 filtrada(s), %2 seleccionada(s))\n"
+"(%1 filtrado(s), %2 seleccionado(s))"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr ""
+"(%1 filtrada(s))\n"
+"(%1 filtrado(s))"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr ""
+"(%1 seleccionada(s))\n"
+"(%1 seleccionado(s))"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Imprimir %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Página %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Queira verificar a sua instalação."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Importação de dados..."
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Importar Ficheiro"
+
+#: mainwindow.cpp:1864
+msgid "Import Directory"
+msgstr "Importar Directório"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Exportação de dados..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Exportar como"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Linha de macros"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Macro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Linha"
+
+#: mainwindow.cpp:1999
+msgid "Creating citations..."
+msgstr "A criar citações..."
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Filtros"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt>A <i>Visão de Filtros</i> mostra as entradas que correspondem a "
+"determinadas regras de filtragem.</qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Empréstimos"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt>A <i>Visão de Empréstimos</i> mostra uma lista com todas as pessoas "
+"que requisitaram artigos da sua sua colecção.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr "Actualizar os dados do registo %1"
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr "Tellico só pode importar um ficheiro deste tipo de cada vez. Só %1 será importado."
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico não pode carregar a imagem - %1."
+
+#: filehandler.cpp:207
+msgid "A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr "Um ficheiro chamado \"%1\" já existe. Quer mesmo substituí-lo?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Sobrepor o ficheiro?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Sobrepor"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Filtrar (classificar por número de ocurrências)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Quer mesmo apagar esta entrada?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Apagar Entrada"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Quer mesmo apagar estas entradas?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Apagar várias entradas"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "&Editar Entradas..."
+
+#: controller.cpp:627
+msgid "D&uplicate Entries"
+msgstr "D&uplicar Entradas"
+
+#: controller.cpp:628
+msgid "&Update Entries"
+msgstr "&Actualizar Entradas"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "&Apagar Entradas"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+"Os seguintes artigos já estão emprestados. Como Tellico não suporta o "
+"empréstimo múltiplo de artigos, de momento eles serão removidos da lista "
+"de artigos a serem emprestados."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Calendário Padrão"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"Presentemente, Tellico só suporta recursos de calendário local. O "
+"calendário activo está localizado remotamente, e por isso, os seus "
+"empréstimos não serão adicionados."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Calendário Activo"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 está previsto regressar a \"%2\""
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(Vazio)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - um gestor de colecção para KDE"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Não reabrir o último ficheiro aberto"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Importar <filename> como ficheiro BibTeX"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Importar <filename> como ficheiro MODS"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Importar <filename> como ficheiro RIS"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Ficheiro a abrir"
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr "Programas de fontes de dados"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Ícones"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Autor da livraria btparse"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr "Exemplos de código e inspiração geral"
+
+#: main.cpp:50
+msgid "Author of libcsv library"
+msgstr "Autor da livraria libcsv"
+
+#: main.cpp:52
+msgid "Author of rtf2html library"
+msgstr "Autor da livraria rtf2html"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Campos da Colecção"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Campos Actuais"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "&Novo"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Adicionar um novo campo à colecção"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "&Apagar"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Apagar um campo da colecção"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Deslocar este campo para cima. A ordem na lista é importante para o modelo "
+"do editor de entrada."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Deslocar este campo para baixo. A ordem na lista é importante para o modelo "
+"do editor de entrada."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Propriedades do Campo"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "&Título:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "O título do campo"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "T&ipo:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "O tipo do campo determina quais os valores que podem ser utilizados. "
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "<i>Texto simples</i> é utilizado para a maioria dos campos. "
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "<i>Parágrafo</i> é utilizado para os textos longos. "
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Lista</i> limita o campo a certos valores. "
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "<i>Marcador</i> é um simples valor sim/não. "
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr "<i>Número</i> indica que o campo contém um valor numérico. "
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+"<i>URL</i> é para os campos que fazem referência a uma URL, contendo "
+"referências a outros ficheiros. "
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr "Uma <i>Tabela</i> pode conter uma ou várias colunas de valores. "
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "Um campo <i>Imagem</i> contém uma imagem, foto ou figura. "
+
+#: collectionfieldsdialog.cpp:144
+msgid "A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr "Um campo <i>Data</i> pode ser utilizado para valores com dia, mês e ano. "
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr "Campos <i> Classificação</i> usam estrelas para indicar uma nota. "
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"Um campo <i>Dependente</i> depende dos valores de outros campos e é "
+"formatado em função da descrição do campo. "
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"Um campo <i>Read Only</i> é utilizado para os valores internos, que podem "
+"ser úteis para a importação e a exportação de dados. "
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "Cate&goria:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr "A categoria do campo determina a posição do campo no editor."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "Descr&ição:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"A descrição é útil para se lembrar quais são as informações contidas "
+"no campo. Para os campos <i>Dependentes</i>, a descrição é uma cadeia do "
+"tipo \"%{year} %{title}\" em que os campos nomeados são substituídos pelos "
+"seus valores."
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr "&Valor por omissão:"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr "<qt>O valor por omissão pode ser configurado para novas entradas</qt>"
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr "Valores &permitidos:"
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>Para os campos do tipo <i>Escolha</i>, estes são os únicos valores "
+"permitidos. Eles são colocados numa lista de opções. Os valores "
+"possíveis têm de ser separados por ponto e vírgula, por exemplo: \"cão, "
+"gato, rato\"</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "&Propriedades alargadas:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "&Configurar..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"As propriedades alargadas de um campo são utilizadas para definir coisas "
+"tais como, por exemplo, o campo BibTeX correspondente."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Opções de Formatação"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Sem formatação"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr "Esta opção impede de ser automaticamente formatado ou posto em maiúscula."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Autorizar só a formatação automática em maiúsculas"
+
+#: collectionfieldsdialog.cpp:231
+msgid "This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+"Esta opção permite pôr o campo em maiúsculas, sem outra formatação "
+"especial."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Formatar como um título"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Esta opção põe em maiúsculas e formata o campo como um título,mas só "
+"se estas opções forem globalmente seleccionadas."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Formatar como um nome"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Esta opção põe em maiúsculas e formata o campo como um nome,mas só se "
+"estas opções forem globalmente seleccionadas."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Opções dos Campos"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Activar o auto-preenchimento"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Se seleccionado, o auto-preenchimento do KDE será activado no editor de "
+"texto para este campo."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Autorizar valores múltiplos"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Se seleccionado, Tellico separará os valores do campos em múltiplos "
+"valores separados por um ponto e vírgula."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Autorizar Agrupamento"
+
+#: collectionfieldsdialog.cpp:249
+msgid "If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Se seleccionado, este campo será utilizado para agrupar as entradas na "
+"visão por grupo."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr ""
+"Reverter as propriedades dos campos seleccionados para os seus valores por "
+"omissão."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Modificar Campos"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Apagar os valores possíveis do campo <i>%1</i> que existem na "
+"colecção pode causar corrupção de dados. Quer manter os valores "
+"modificados ou anular e regressar aos valores precedentes ?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Manter os valores modificados"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Reverter Propriedades do Campo"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Deseja realmente reverter as propriedades do campo <em>%1</em> para "
+"os seus valores padrão?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Reverter"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Propriedades Alargadas do Campo"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr "Já existe um campo com este nome. Queira inserir um nome diferente."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr ""
+"<qt>A categoria não pode ser deixada em branco. Por favor,escolha uma "
+"categoria.</qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>Um campo não pode estar na mesma categoria que um <em>Parágrafo</em>, "
+"uma <em>Tabela</em> ou uma <em>Imagem</em>. Queira escolher uma outra "
+"categoria.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"O nome de um campo não deve ser o mesmo que o de uma categoria existente. "
+"Queira inserir um outro nome."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+"Os valores utilizados para uma classificação têm que ser entre 1 e 10, e "
+"o limite inferior deve ser menor que o limite superior. Por favor, insira "
+"novos valores para cada um dos limites."
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "As tabelas são limitadas a um máximo de dez colunas."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"O documento aberto foi modificado.\n"
+" Quer guardá-lo?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Alterações não guardadas"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Seleccionar Requisitante"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Configurar Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Opções Gerais"
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr "&Reabrir o ficheiro ao iniciar o programa"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Se seleccionado, o último ficheiro aberto será reaberto ao iniciar "
+"novamente o programa."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "&Mostrar as \"Dicas do dia\" ao iniciar o programa"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr "Se seleccionado, l'\"Dicas do dia\" será mostrada ao iniciar o programa."
+
+#: configdialog.cpp:213
+msgid "Image Storage Options"
+msgstr "Opções de armazenamento das imagens"
+
+#: configdialog.cpp:214
+msgid "Store images in data file"
+msgstr "&Armazenar imagens no ficheiro de dados"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr "Armazenar imagens num directório aplicativo comum"
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr "Armazenar imagens num directório relacionado com os dados do ficheiro"
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr "As imagens podem ser guardadas ou no próprio ficheiro de dados, o que poderá causar alguma lentidão de processamento no Tellico, ou no directório aplicativo do Tellico, ou num directório com a mesma localização do ficheiro de dados."
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Opções de Formatação"
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr "Capitalização automática de &títulos e nomes"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Se seleccionado, os títulos e os nomes serão automaticamente postos em "
+"maiúsculas."
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr "&Formatação automática dos títulos e dos nomes"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr "Se seleccionado, os títulos e os nomes serão automaticamente formatados."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr "Não capitali&zar:"
+
+#: configdialog.cpp:243
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Uma lista de palavras que não podem ser escritas em maiúsculas. As "
+"palavras devem ser separadas por um ponto e vírgula.</qt>"
+
+#: configdialog.cpp:249
+msgid "Artic&les:"
+msgstr "Arti&gos:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>Uma lista de palavras que devem ser consideradas como artigos.se forem a "
+"primeira palavra de um título. As palavras devem ser separadas por um ponto "
+"e vírgula.</qt>"
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr "Sufi&xos pessoais:"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Uma lista de sufixos que podem ser utilizados nos nomes. Os sufixos "
+"devem ser separados por um ponto e vírgula.</qt>"
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr "&Prefixos de sobrenomes:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Uma lista de sufixos que podem ser utilizados nos sobrenomes. Os sufixos "
+"devem ser separados por um ponto e vírgula.</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Impressão"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Opções de impressão"
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr "&Formatação dos títulos e dos nomes"
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr "Im&primir cabeçalhos dos campos"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Opções de Agrupamento"
+
+#: configdialog.cpp:313
+msgid "&Group the entries"
+msgstr "&Agrupar as entradas"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Opções das imagens"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr "&Largura máxima da imagem:"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Largura máxima da imagem aquando da impressão. As proporções são "
+"conservadas."
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr "&Altura máxima da imagem:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Altura máxima da imagem aquando da impressão. As proporções são "
+"conservadas."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Modelos"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Opções do Modelo"
+
+#: configdialog.cpp:369
+msgid "Template:"
+msgstr "Modelo:"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+"Selecionoe o modelo para usar para o tipo de colecção actual. Nem todos os "
+"modelos iram usar as configurações fonte e cor."
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr "&Antevisão..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr "Mostrar a antevisão do modelo"
+
+#: configdialog.cpp:398
+msgid "Font Options"
+msgstr "Opções de Fonte"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr "Fonte:"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr "Esta fonte foi definida para o modelo usado na Lista de Entrada."
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr "Tamanho:"
+
+#: configdialog.cpp:425
+msgid "Color Options"
+msgstr "Opções de Cor"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr "Cor de fundo:"
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr "Esta cor foi definida para o modelo usado na Lista de Entrada."
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr "Cor de texto:"
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr "Cor de realce:"
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr "Cor de texto de realce:"
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr "Gerir Modelos"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr "Instalar..."
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr "Clique para instalar directamente um novo modelo."
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr "Transferir..."
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr "Clique para transferir modelos adicionais via Internet."
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr "Apagar..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr "Clique para selecionar e remover modelos instalados."
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Fontes de Dados"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Opções da Fonte de Dados"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Fonte"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr "Mover para &cima"
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+"A ordem das fontes de dados configura a ordem que o Tellico usa quando as "
+"entradas são automaticamente actualizadas."
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr "Mover para &baixo"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "&Novo..."
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr "Clique para adicionar uma nova fonte de dados."
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Modificar..."
+
+#: configdialog.cpp:533
+msgid "Click to modify the selected data source."
+msgstr "Clique para modificar a fonte de dados selecionada."
+
+#: configdialog.cpp:536
+msgid "Click to delete the selected data source."
+msgstr "Clique para apagar a fonte de dados selecionada."
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr "Clique para transferir fontes de dados adicionais via Internet."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr "*.tar.gz *.tgz|Pacotes Modelo (*.tar.gz)"
+
+#: configdialog.cpp:1049
+msgid "Delete Template"
+msgstr "Apagar Modelo"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr "Selecione o modelo para apagar:"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "Requisitante"
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Registro de entrada de devolução"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Modificar empréstimo..."
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "Requisitante (Classificar por número de ocurrências)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "A minha Colecção"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Colecção de Livros"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Colecção de BD"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Colecção de Vídeos"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Colecção de Música"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Colecção de Moedas"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Colecção de Selos"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Colecção de Vinhos"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Colecção de Cartas"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Colecção de Jogos"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr "Catálogo de Ficheiros"
+
+#: collectionfactory.cpp:135
+msgid "Board Game Collection"
+msgstr "Colecção de Jogos de Tabuleiro"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Colecção Personalizada"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+"<qt>A <i>Visão de Entradas</i> mostra uma visão formatada do conteúdo da "
+"entrada.</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt>A <i>Visão por Ícones</i> mostra cada entrada da colecção ou grupo "
+"utlizando um ícone, que pode ser uma imagem na entrada.</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Opções de Exportação"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Formatação"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Formatar todos os campos"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Se seleccionados, todos os campos serão automaticamente formatados de "
+"acordo com o seu tipo de formato."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Exportar só as entradas seleccionadas"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr "Se seleccionado, só as entradas seleccionadas serão exportadas."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Codificação"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Codificar em Unicode (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Codificar o ficheiro exportado em Unicode (UTF-8)."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Codificar na localização do utilizador (%1)"
+
+#: exportdialog.cpp:72
+msgid "Encode the exported file in the local encoding."
+msgstr "Codificar em formato local o ficheiro exportado."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "&Procurar"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "&Interromper"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Pesquisa na Internet"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Parâmetros da pesquisa"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr "P&esquisar:"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+"Inserir um valor de pesquisa. Uma pesquisa ISBN deve incluir o número ISBN "
+"completo."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Escolha o tipo de pesquisa"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Clique para iniciar ou interromper a pesquisa"
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr "Pesquisa ISBN/UPC &múltipla"
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr "Assinale esta casa para pesquisar vários valores ISBN ou UPC."
+
+#: fetchdialog.cpp:138
+msgid "Edit List..."
+msgstr "Editar Lista..."
+
+#: fetchdialog.cpp:140
+msgid "Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr "Clique para inserir ou editar os valores ISBN a pesquisar."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "Procurar f&onte:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Escolha a base de dados a pesquisar"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"À medida que os resultados forem encontrados, eles são adicionados a esta "
+"lista. Ao seleccionar um deles descarregará a entrada completa e "
+"mostra-la-á na lista abaixo."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"Uma entrada pode ser mostrada aqui antes de ser adicionada à colecção, "
+"seleccionando-a na lista acima"
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "&Adicionar Entrada"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Adicionar a entrada seleccionada à colecção actual"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr "Obter Mais Resultados"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr "Obter mais resultados pela actual fonte de dados"
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Apagar todos os campos e valores"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Cancelar a pesquisa..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Pesquisa a decorrer..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "A pesquisa não encontrou nada."
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+"A pesquisa encontrou 1 entrada.\n"
+"A pesquisa encontrou %n entradas."
+
+#: fetchdialog.cpp:412
+msgid "No results were found for the following ISBN values:"
+msgstr "<qt>Não foi encontrado qualquer resultado para os ISBN seguintes:</qt>"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Carregando %1..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr "Não há fontes na Internet disponíveis para este tipo de colecção."
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr "Editar os valores ISBN/UPC"
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Insira os valores ISBN ou UPC, um por linha.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "&Carregar a partir de um ficheiro..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Carregar a lista a partir de um ficheiro de texto.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>Uma pesquisa ISBN pode conter um máximo de 100 valores ISBN. Só os 100 "
+"primeiros valores da sua lista serão utilizados.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Editar Entrada"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Nova Entrada"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "Guar&dar Entrada"
+
+#: entryeditdialog.cpp:77
+msgid "Go to the previous entry in the collection"
+msgstr "Ir para a entrada anterior na colecção"
+
+#: entryeditdialog.cpp:82
+msgid "Go to the next entry in the collection"
+msgstr "Ir para a próxima entrada na colecção"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Quer mesmo modificar estas entradas?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Modificar várias entradas"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr "É necessário um valor para os campos seguintes. Deseja continuar?"
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Editar Entradas"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "Guar&dar Entradas"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"A entrada actual foi modificada.\n"
+"Quer validar as modificações?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Guardar Entrada"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Relatório da Colecção"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "Modelo de &relatório:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "&Gerar"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr "Seleccione um modelo de relatório e clique em <em>Gerar</em>."
+
+#: reportdialog.cpp:108
+msgid "Some reports may take several seconds to generate for large collections."
+msgstr ""
+"Para grandes colecções, alguns relatórios podem levar vários segundos a "
+"serem criados."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Quer mesmo apagar este filtro?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Apagar o Filtro?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Novo nome da colecção:"
+
+#: tellico_kernel.cpp:377
+msgid "Entry 1"
+msgstr "Entrada 1"
+
+#: tellico_kernel.cpp:378
+msgid "Entry 2"
+msgstr "Entrada 2"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr "Foram encontrados valores em conflito para %1 durante a combinação de registos."
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr "Por favor, escolha o valor a manter."
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+msgid "Merge Entries"
+msgstr "Combinar Entradas"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr "Seleccionar valor de %1"
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico não consegue encontrar a folha de estilo padrão para as entradas."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Novo"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Colecção"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Barra de ferramentas de Colecção"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Lígia Moreira"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "ligia.moreira@netvisao.pt,carlos@pinguix.com"
+
+#: entrymerger.cpp:35
+msgid "Merging entries..."
+msgstr "A combinar entradas..."
+
+#: entrymerger.cpp:49
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Total de registos combinados/visualizados: %1/%2"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>... que se um livro tem vários autores, deve separar\n"
+" os nomes deles com um ponto e vírgula. Tellico saberá separá-los e "
+"utilizá-los independentemente.</p>\n"
+"<p>Qualquer outro campo que permita múltiplos valores deverá ter a mesma "
+"estrutura, com um ponto e vírgula (;) a separar cada valor.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>...que pode alterar quais os campos a mostrar na lista \n"
+"clicando no botão direito sobre o cabeçalho das colunas.</p>\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>...que pode adicionar, editar, ou modificar os campos da colecção "
+"utilizando\n"
+"o campo de edição. Os botões com uma seta sob a lista dos campos permitem "
+"modificar\n"
+"a posição do campo na lista, o que afectará a sua posição no editor da "
+"entrada.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>...que se quiser filtrar a partir de um campo do tipo Marcador, um valor\n"
+"\"verdadeiro\" deverá ser definido. Se quiser por exemplo, mostrar só os "
+"livros\n"
+"de ficção científica que ainda nãoleu, assinale\n"
+"<em>Verificar todas as regras</em>, ajuste a primeira como se segue, "
+"\"Género\"\n"
+"\"contém\" \"Ficção científica\" (sem aspas) e a segunda regra assim:\n"
+"\"Lido\" \"Não contém\" \"Verdadeiro\" (sem aspas).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>...que se um caractere não alfabético for utilizado na filtragem "
+"rápida,\n"
+"o texto é interpretado como uma expressão regular.</p>\n"
+"<p>Para mostrar somente os livros de Weber ou Bujold por exemplo, escreva\n"
+"\"weber|bujold\" (sem aspas) no campo do filtro.</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>...que pode editar mais de uma entrada de cada vez, clicando e "
+"pressionando a tecla Shift ou Ctrll e seleccionando várias entradas.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>...que pode converter uma colecção de livros já existente numa "
+"bibliografia,\n"
+"que pode em seguida, ser exportada em formato BibTeX ou BibTeXML.</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>...que pode adicionar, editar e suprimir linhas de macros\n"
+"para as bibliografias.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>...que se mais de um campo for formatado como nome, então um grupo\n"
+"suplementar chamado \"Pessoas\" é adicionado à colecção, autorizando\n"
+"que autores e editores sejam classificados ou impressos juntos,por "
+"exemplo.</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>...que pode modificar a aparência da impressão alterando\n"
+"o ficheiro <tt>tellico-printing.xsl</tt>. O ficheiro produz HTML, e os\n"
+"estilos CSS determinam as fontes, as margens, etc.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>...que pode importar e exportar dados usando uma folha de estilo XSL "
+"genérica que\n"
+"seja capaz de produzir um ficheiro XML válido do Tellico.</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+"<p>...que um duplo clique sobre uma entrada permite abrir a janela do editor "
+"de entradas.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>...que pode adicionar marcas HTML a um campo de tipo parágrafo para a "
+"sua formatação, tais como\n"
+"&lt;b&gt;bold&lt;/b&gt; ou &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>...que na visão detalhada, pode pressionar uma letra do teclado para ir "
+"directamente para a próxima entrada que começa por essa letra.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+"<p>...pode usar Campos Dependentes para combinar campos múltiplos "
+"separados\n"
+"num só campo. Apenas seleccione o tipo Dependente e use uma descrição\n"
+"similar a \"Valor: %{fielda}%{fieldb}\" onde%{...} é substituído pelo\n"
+"valor do campo apropriado. Isto é útil para coleccionar campos multiplos "
+"num\n"
+"simples campo; ex: para melhor o agrupamento e para combinar campos de "
+"diferentes\n"
+"tipos respeitando a devida ordenem ao mesmo tempo. Considere por exemplo\n"
+"um campo numérico seguido de um subcampo de texto com entradas 3b, "
+"14a.</p>\n"
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Álbum"
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr "Este modelo é apenas para colecções de música."
+
+#: xslt.cpp:5
+msgid "Total:"
+msgstr "Total:"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr "Sofisticado"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "Padrão"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Compacto"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Vídeo"
+
+#: xslt.cpp:14 xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr "Este modelo é apenas para colecções de vídeo."
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Resumo dos Grupos"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Resumo dos Grupos"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Número total de campos:"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Número total de entradas:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+msgid "Generated by Tellico"
+msgstr "Generated pelo Tellico"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Valores distintos: "
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Lista de Imagens"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Visão de Empréstimos"
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Data de Requisição"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Observação"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Data de Devolução"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Visão por Grupos"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Listagem de títulos (horizontal)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Listagem de títulos (vertical)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Visão por Colunas"
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "Coluna Tripla"
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr "Procurar"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr "Biblioteca Britânica"
+
+#: z3950.cpp:6
+msgid "Sudoc (France)"
+msgstr "Sudoc (França)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr "BIBSYS (Noruega)"
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr "Biblioteca Nacional Italiana"
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr "Biblioteca Nacional Portuguesa"
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr "Biblioteca Nacional da Polónia"
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr "Biblioteca Nacional do Canadá"
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr "União Nacional Israelita"
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr "Biblioteca Nacional da Austrália"
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr "Biblioteca Nacional do Lituânia"
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr "Copac (Reino Unido e Irlanda)"
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr "Jogos de Tabuleiro"
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr "Dark Horse Comics"
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr "Allocine.fr"
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr "Ministério Espanhol da Cultura"
+
diff --git a/po/pt_BR.po b/po/pt_BR.po
new file mode 100644
index 0000000..8d396f4
--- /dev/null
+++ b/po/pt_BR.po
@@ -0,0 +1,5364 @@
+# translation of pt_BR.po to Brazillian Portuguese
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+#
+# Claudio Henrique Fortes Felix <claudio@helpo.com.br>, 2006.
+msgid ""
+msgstr ""
+"Project-Id-Version: pt_BR\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2006-12-25 01:47-0200\n"
+"Last-Translator: Claudio Henrique Fortes Felix <claudio@helpo.com.br>\n"
+"Language-Team: Brazillian Portuguese\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr ""
+"<qt>Tellico não conseguiu escrever para o 'pipe' do servidor em "
+"<b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr "Conectando ao OpenOffice.org..."
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr "Conexão ao OpenOffice.org"
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+"Tellico não conseguiu se conectar ao OpenOffice.org. Por favor verifique as "
+"opções de conexão abaixo e verifique se o OpenOffice.org Writer está "
+"rodando."
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr "Pipe"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr "TCP/IP"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr "Renomear Coluna"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr "Novo nome da coluna:"
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr "Coluna %1"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr "Renomear Coluna..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr "Inserir Linha "
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr "Remover Linha "
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr "Mover Linha para Cima"
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr "Mover Linha para Baixo"
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr "Limpar Tabela"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr "Visão de Modelos"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Definir"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr "%1:"
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Mais"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Menos"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Limpar"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Selecionar Imagem..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr ""
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr ""
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Modificar %1"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Continuar Coleção"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Combinar Coleção"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Substituir Coleção"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr "Modificar Registros"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "Adicionar Campo %1"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Modificar Campo %1"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Apagar Campo %1"
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr "Adicionar Registros"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Adicionar %1"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Renomear a Coleção"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Modificar Empréstimo "
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Adicionar Filtro"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Modifica Filtro "
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Apagar o Filtro"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Registrar Saída de Itens"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Registrar saída de %1"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Apagar Registros"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Apagar %1"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Reordenar Campos"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Registros de Entrada"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Registrar entrada de %1"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Geral "
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Condição"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Pessoal"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Meus Selos"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Título"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Descrição"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Denominação"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "País"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Ano de Edição"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Cor"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Scott#"
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr "Soberbo,Excelente,Muito Bom,Bom,Regular,Ruim"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Classificação"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Cancelado"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Articulado"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Centrada"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Colado"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Data de compra"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Preço de compra"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Localização"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Presente"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Imagem "
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Comentários"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Publicação"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Classificação"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Minhas Revistas em Quadrinhos"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Sub-Título"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Escritor"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr "Artista Gráfico"
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Série"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Número"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Editora"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Edição"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Ano de Publicação"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Páginas"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Língua"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Gênero"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Palavras-chave"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr "Novo,Quase novo,Excelente,Ótimo,Muito bom,Bom,Razoável,Ruim"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Autografado"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Emprestado"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Capa"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Minhas Moedas"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Tipo"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Ano"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Marca da Casa Emissora"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Conjunto de Moedas"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+"Proof-65,Proof-60,Mint-65,Mint-60,Quase não Circulada-55,Quase não "
+"Circulada-50,Extremamente Rara-40,Muito Rara-30,Muito Rara-20,Rara-12,Muito "
+"Boa-8,Boa-4,Razoável"
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr "PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Serviços de Classificação"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Observação"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Verso"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Meus Livros"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Autor"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Capa Dura"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Capa Flexível Econômica"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Capa Flexível"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "Livro Eletrônico"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Revista"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Jornal"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Formato"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Ano do Copyright"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN#"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Número Internacional Normalizado do Livro"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN#"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Número de Controlo da Biblioteca do Congresso"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr ""
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Nº de série"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Novo "
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Usado"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Lido"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Classificação "
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr "Meus Arquivos"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "Nome"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Volume"
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr "Pasta"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr "Tipo MIME"
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr "Tamanho"
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr "Permissões"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr "Dono"
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr "Grupo"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr "Criado"
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr "Modificado"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr "Meta-informação"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Propriedade"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Valor"
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr "Ícone"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Meus Vinhos"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Produtor"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Apelação"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Variedade"
+
+# Não sei ainda qual a tradução correta
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Safra"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Vinho tinto"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Vinho branco"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Espumoso"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Quantidade"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Bebido Por"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Etiqueta"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Outras Pessoas"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Características"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Meus Vídeos"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr ""
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+#, fuzzy
+msgid "HD DVD"
+msgstr "DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Mídia"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Ano de Produção"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Certificação"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Região 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Região 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Região 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Região 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Região 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Região 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Região 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Região 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Região"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Nacionalidade"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Formato"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Elenco"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr "Ator/Atriz"
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr "Personagem"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr ""
+"Uma tabela para o elenco do filme, com o papel representado por cada um"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Diretor"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Compositor"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Estúdio"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Línguas disponíveis"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Língua das Legendas"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Áudios Disponíveis"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Duração"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "Duração do vídeo (em minutos)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Formato da Imagem"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Tela Larga"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Preto & Branco"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Formato de Cor"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Cortes do Diretor"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Resumo da Ação"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Nota Pessoal"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Capa"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "Meus Jogos"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr "Xbox 360"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr "PlayStation3"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr "Revolução"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr ""
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Platforma"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Ano de Lançamento"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Editora"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Desenvolvedor"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+"Não Classificado, Somente Adultos, Jovens, Adolescentes, Sem Censura, "
+"Infantil, Pendente"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "Classificação da ESRB"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Completado"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Meus Cartões"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Jogador"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Time"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Marca"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Número do Cartão"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Tipo do Cartão"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Imagem Frontal"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Imagem no Verso"
+
+#: collections/boardgamecollection.cpp:26
+#, fuzzy
+msgid "My Board Games"
+msgstr "Meus Jogos"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr ""
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Bibliografia"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Tipo de Registro"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+"Estes tipos de registro são específicos para o BibTeX. Consulte a "
+"documentação do mesmo."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Chave do BibTeX"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Título do livro"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Editor"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organização"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Endereço"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Mês"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Número "
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Modo de publicação"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Capítulo"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Referência cruzada"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Resumo"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Notas"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Minhas Músicas"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Álbum"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "CD"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Cassete"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Vinil"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Artista"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Selo"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Pistas"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr "Duração"
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr "um,uma,e,em,de,o,a "
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "o,a,os,as "
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr.,jr,iii,iv "
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,o,a "
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr "ISBNdb.com"
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 não permite a pesquisa para este tipo de coleção."
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Resultados de %1 : %2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "Esta fonte não tem opções"
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "Banco de Dados Entrez"
+
+#: fetch/entrezfetcher.cpp:485
+msgid "Institution"
+msgstr "Instituição"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Erro na pesquisa!"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Erro na procura da conexão %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Erro de Sintaxe no Registro"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Erro de conexão %1: %2"
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr "Servidor SRU"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Biblioteca do Congresso (Estados Unidos)"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr "&Servidor:"
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr "Insira o nome do servidor"
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Porta:"
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Insira o número da porta do servidor z39.50. A porta padrão é %1."
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr "Caminho:"
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr "Insira o caminho para o banco de dados utilizado pelo servidor"
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr "Formato:"
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr "Informe o formato de resultado utilizado pelo servidor."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr "Yahoo! Audio Search"
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "A imagem da capa não pôde ser carregada."
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr "Amazon Link"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (Estados Unidos)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (Reino Unido)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Alemanha)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japão)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (França)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Canadá)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Serviços Web da Amazon.com"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "&País"
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "Estados Unidos"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Reino Unido"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Alemanha"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Japão"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "França"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Canadá"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon.com disponibiliza dados de vários sites em diferentes "
+"localizações. Escolha o que deseja utilizar como fonte de dados."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "&Tamanho da Imagem"
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Imagem Pequena"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Imagem Média"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Imagem Grande"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Sem Imagem"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"A imagem da capa pode obtida da mesma forma. No entanto, imagens grandes na "
+"coleção podem degradar o desempenho."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "Identidade &associada: "
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+"A identidade associada identifica a pessoa acessando os serviços Web "
+"Amazon.com, e será incluída em todos os links para o site Amazon.com."
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr "Servidor z39.50"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr "Usar &servidor pré-definido"
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "Base de &dados:"
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr "Insira o nome da base de dados utilizado pelo servidor."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "Conjunto de c&aracteres: "
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Insira o conjunto de caracteres utilizado pelo servidor z39.50. A escolha "
+"mais provável é MARC-8, apesar do ISO-8859-1 ser tão comum quanto."
+
+#: fetch/z3950fetcher.cpp:550
+msgid "&Format: "
+msgstr "&Formato:"
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr "Detectar automaticamente"
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+"Entre com o formato de dados utilizado pelo servidor z39.50. Tellico vai "
+"tentar detectar a melhor configuração se <i>Detectar automaticamente</i> "
+"estiver selecionado."
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "&Usuário:"
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Opcional"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Insira o nome da base de dados utilizada pelo servidor z39.50. A maioria dos "
+"servidores não precisam dele."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "&Senha:"
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Insira a senha utilizada para a base de dados z39.50. A maior parte dos "
+"servidores não precisam dela. A senha será salva em formato texto no "
+"arquivo de configuração do Tellico."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr "Ilustrador"
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Aplicativo Externo"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "&Tipo de coleção:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+"Especifique o tipo de coleção dos dados retornados do aplicativo externo."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr "Tipo de &Resultado:"
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr ""
+"Especifique o tipo de resultado dos dados retornados do aplicativo externo."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "&Caminho do Aplicativo:"
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+"Especifique o caminho do aplicativo a ser executado que deve gerar um "
+"arquivo de dados Tellico válido."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr "Selecione as chaves de procura suportadas pela fonte de dados."
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+"Adicione todos os argumentos necessários. <b> %1 </b> vai ser substituído "
+"pelo termo a ser pesquisado."
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr "Argumentos"
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+msgid "Update"
+msgstr "Atualizar"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+"<p>Forneça os argumentos que devem ser usados para procurar por "
+"atualizações disponíveis para um registro.</p><p>O formato é o mesmo dos "
+"campos <i>Dependentes</i>, onde os valores dos campos são contidos entre "
+"colchetes, como <i>%{author}</i>. Veja a documentação para maiores "
+"detalhes.</p>"
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Opções da Fonte"
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr "Campos Disponíveis"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "Base de dados de filmes na Internet"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Selecione o resultado IMDB"
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+"<qt>A sua pesquisa retornou vários resultados. Por favor selecione um dos "
+"seguintes.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Selecione um resultado da pesquisa.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr "Link IMDB"
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Títulos alternativos"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+msgid "IMDB Rating"
+msgstr "Classificação IMDB"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Certificações"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"A base de dados de filmes na Internet (IMDB) utiliza vários servidores "
+"diferentes. Escolha o que deseja utilizar."
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr "Elenco &máximo:"
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+"A lista de membros do elenco pode incluir muitas pessoas. Especifique o "
+"número máximo a ser retornado da pesquisa."
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr "Efetuar o Download da &Imagem da Capa"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr "Internet Bookshop (ibs.it)"
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Pessoa"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+#, fuzzy
+msgid "UPC/EAN"
+msgstr "UPC"
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Palavra chave"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Pesquisa não refinada"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr "Título Original"
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr "Distribuidor"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr "Episódios"
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:343
+#, fuzzy
+msgid "&Username: "
+msgstr "&Usuário:"
+
+#: fetch/crossreffetcher.cpp:348
+#, fuzzy
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+"Insira a senha utilizada para a base de dados z39.50. A maior parte dos "
+"servidores não precisam dela. A senha será salva em formato texto no "
+"arquivo de configuração do Tellico."
+
+#: fetch/crossreffetcher.cpp:354
+#, fuzzy
+msgid "&Password: "
+msgstr "&Senha:"
+
+#: fetch/gcstarpluginfetcher.cpp:190
+#, fuzzy
+msgid "GCstar Plugin"
+msgstr "Elenco"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+#, fuzzy
+msgid "Set the collection type of the data returned from the plugin."
+msgstr ""
+"Especifique o tipo de coleção dos dados retornados do aplicativo externo."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:415
+#, fuzzy
+msgid "Select the GCstar plugin used for the data source."
+msgstr "Selecione as chaves de procura suportadas pela fonte de dados."
+
+#: fetch/gcstarpluginfetcher.cpp:420
+#, fuzzy
+msgid "Author: "
+msgstr "Autor"
+
+#: fetch/discogsfetcher.cpp:58
+#, fuzzy
+msgid "Discogs Audio Search"
+msgstr "Yahoo! Audio Search"
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr ""
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr "Novidades Quentes"
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr "Versão"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr "Downloads"
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr "Data de Lançamento"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+"Essa é uma lista de todos os itens disponíveis para download. Itens "
+"previamente instalados são mostrados com um tique, enquanto itens que "
+"tenham novas versões disponíveis tem um ícone de atualização."
+
+#: newstuff/dialog.cpp:137
+msgid "The name and license of the selected item"
+msgstr "O nome e a licença do item selecionado"
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr "O autor do item selecionado"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr "Instalar"
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr "Baixa e instala o modelo selecionado."
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+"Baixa e instala o script selecionado. Alguns scripts podem precisar ser "
+"configurados após a instalação."
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr "Uma descrição do item selecionado é mostrada aqui."
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr "Baixando informações..."
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Pronto."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr "Atualização"
+
+#: newstuff/dialog.cpp:413
+msgid "Installing item..."
+msgstr "Instalando item..."
+
+#: translators/bibteximporter.cpp:79
+#, fuzzy
+msgid "No valid bibtex entries were found"
+msgstr "Nenhum registro válido do BibTeX encontrado no arquivo - %1"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "Nenhum registro válido do BibTeX encontrado no arquivo - %1"
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Opções do BibTeX"
+
+#: translators/bibteximporter.cpp:287
+#, fuzzy
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Codificar em Unicode (UTF-8)"
+
+#: translators/bibteximporter.cpp:288
+#, fuzzy
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Codificar o arquivo exportado em Unicode (UTF-8)."
+
+#: translators/bibteximporter.cpp:289
+#, fuzzy
+msgid "Use user locale (%1) encoding"
+msgstr "Codificar na localização do usuário (%1)"
+
+#: translators/bibteximporter.cpp:293
+#, fuzzy
+msgid "Read the imported file in the local encoding."
+msgstr "Codifica o arquivo exportado no formato local."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "Arquivo Zip Tellico"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Arquivos Tellico (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Todos os Arquivos"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>Uma biblioteca do Alexandria chamada <i>%1</i> já existe. Quaisquer "
+"livros existentes nesta biblioteca podem ser sobrescritos.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "Há um erro de análise XML na linha %1, coluna %2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "A mensagem de erro do Qt é:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Isto é para uma futura versão do Tellico."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Tellico está convertendo o arquivo para um formato mais recente. Pode haver "
+"perda de informações se este arquivo for lido no futuro por uma versão "
+"antiga do Tellico."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Desconhecido"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "O arquivo está vazio."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "O arquivo não contém dados de coleção."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Livros Não Lidos"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Filmes Antigos"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "Música dos anos 80"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Favoritos"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Procurando arquivos de áudio..."
+
+#: translators/audiofileimporter.cpp:129
+#, fuzzy
+msgid "Bitrate"
+msgstr "BibTeX"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(Vários)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Opções de Arquivo de Áudio"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Pesquisa recursiva de &pastas"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+"Se selecionado, as pastas são varridas recursivamente para procurar "
+"arquivos de áudio."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr "&Incluir localização do arquivo"
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr ""
+"Se selecionado, os nomes dos arquivos de cada faixa serão adicionados aos "
+"registros."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:353
+#, fuzzy
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr ""
+"Se selecionado, os nomes dos arquivos de cada faixa serão adicionados aos "
+"registros."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|Arquivos CSV (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "Opções CSV"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Incluir os nomes dos campos como cabeçalho das colunas"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr ""
+"Se selecionada, uma linha de cabeçalho será adicionada com o nome dos "
+"campos."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Separador"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"Além da vírgula, outros caracteres podem ser utilizados para delimitar "
+"cada valor no arquivo."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Vírgula"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Utilizar a vírgula como separador."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Ponto e vírgula"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Utilizar o ponto e vírgula como separador."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Aba"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Utilizar a tabulação como separador."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Outro"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Utilizar um outro caractere como separador."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr ""
+"Um caractere qualquer, como os dois pontos, pode ser utilizado como "
+"separador."
+
+#: translators/filelistingimporter.cpp:63
+msgid "Scanning files..."
+msgstr "Varrendo arquivos..."
+
+#: translators/filelistingimporter.cpp:191
+msgid "File Listing Options"
+msgstr "Opções de Listagem de Arquivo"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr "Procura recursiva de pastas"
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+"Se selecionado, as pastas são varridas recursivamente para procurar todos "
+"os arquivos."
+
+#: translators/filelistingimporter.cpp:198
+msgid "Generate file previews"
+msgstr "Gerar pré-visualizações dos arquivos"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+"Se selecionado, serão geradas pré-visualizações do conteúdo dos "
+"arquivos, o que pode causar lentidão na listagem das pastas."
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "Arquivo ONIX"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.zip|Arquivos Zip (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "Opções de Arquivo ONIX"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Incluir as imagens no arquivo"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Se selecionado, as imagens do documento serão incluídas no arquivo zipado "
+"ONIX."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr ""
+"<qt>Tellico não pôde acessar o dispositivo de CD-ROM - <b>%1</b>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+msgid "Select CDDB Entry"
+msgstr "Seleciona Registro CDDB"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr "Selecione um registro do CDDB:"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>Nenhum registro correspondente ao CD foi encontrado.</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr ""
+"<qt>Tellico não pôde completar a pesquisa das informações do CD.</qt>"
+
+#: translators/freedbimporter.cpp:470
+msgid "Various"
+msgstr "Vários"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Opções de CD de Áudio"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Ler dados do dispositivo de CD-ROM"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Selecione ou informe a localização do dispositivo de CD-ROM."
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Ler apenas os arquivos de cache do CDDB"
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+"Ler recursivamente os dados de todos os arquivos de cache do CDDB contidos "
+"nas pastas de cache padrão."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr "GCfilms "
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.gcf|Arquivos de Dados GCfilms (*.gcf) "
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.gcs|Arquivos de Dados GCstar (*.gcs) "
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "Opções de XSLT"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "Arquivo XSLT:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr "Escolher o arquivo XSLT para transformar os dados XML do Tellico."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Opções do Alexandria"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr "&Biblioteca:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "BibTeXML "
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Arquivos BibTeXML (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|Arquivos XML (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Opções XML do Tellico"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Incluir as imagens no documento XML"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Se selecionado, as imagens do documento serão integradas aos dados em XML "
+"como elementos codificados em base64."
+
+#: translators/importer.h:100
+msgid "Loading data..."
+msgstr "Carregando dados..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr "Carregando %1..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "BibTeX"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Arquivos BibTeX (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Expandir as macros de string"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Se selecionado, as macros de string vão ser expandidas e nenhum registro "
+"@string{} será escrito."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Utilizar o pacote URL"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr ""
+"Se selecionado, qualquer campo URL será transformado em uma declaração "
+"\\url."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Ignorar os registros com chaves de citação vazias"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr ""
+"Se selecionado, qualquer registro sem uma chave de citação do BibTeX será "
+"ignorado."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Estilo das citações do BibTeX:"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Colchetes"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Aspas"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"<qt>Estilo de citação utilizado para arquivos no formato BibTeX. Os "
+"valores de todos os campos serão envolvidos por colchetes ou aspas.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Selecionar o tipo de coleção a importar."
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr "A &primeira linha contém os títulos dos campos"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr ""
+"Se selecionado, a primeira linha será utilizada para o nome dos campos."
+
+#: translators/csvimporter.cpp:248
+msgid "&Comma"
+msgstr "&Vírgula"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr "&Ponto e vírgula"
+
+#: translators/csvimporter.cpp:259
+msgid "Ta&b"
+msgstr "Ta&bulação"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr "Out&ro"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "A tabela mostra as cinco primeiras linhas do arquivo CSV."
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt> Marque cada coluna para corresponder a um campo na coleção escolhendo "
+"uma coluna, selecionando o campo e clicando no botão <i> Associar Campo </i>"
+
+#: translators/csvimporter.cpp:298
+msgid "Co&lumn:"
+msgstr "Co&luna:"
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr "Campo de &dados nesta coluna:"
+
+#: translators/csvimporter.cpp:315
+msgid "&Assign Field"
+msgstr "&Associar Campo"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Novo campo"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|Arquivos Pilot Database (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Ver Colunas"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "Opções do PilotDB"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Marcar a opção PDA backup para a base de dados"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>O arquivo não é um arquivo de dados GCstar válido</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Tellico encontrou um erro no processamento do XSLT."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "Um arquivo XSLT válido é necessário para importar o arquivo."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|Arquivos XSL (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|Arquivos HTML (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Pessoas"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(Agrupados por %1)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "Opções HTML"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Imprimir os cabeçalhos dos campos"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr ""
+"Se selecionado, o nome dos campos será impresso como títulos de uma tabela."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Agrupar os registros"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr ""
+"Se selecionado, os registros serão agrupados em função do campo "
+"selecionado."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Exporta arquivos de registros isolados"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr ""
+"Se selecionado, serão criados arquivos individuais para cada registro."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+#, fuzzy
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico não pôde carregar o arquivo - %1."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Propriedades da Fonte de Dados"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "Nome da &fonte: "
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr "O nome identifica a fonte de dados, devendo ser único e informativo."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "&Tipo de fonte: "
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr "Tellico suporta várias fontes de dados diferentes."
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr ""
+"A atualização a partir de uma fonte sobrescreverá dados preenchidos pelo "
+"usuário"
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Se selecionado, a atualização dos registros sobrescreverá toda "
+"informação existente."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Qualquer campo"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "contém "
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "não contém"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "igual a "
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "diferente de"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "verifica a expressão regular "
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "não verifica a expressão regular"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Editar..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Filtro Avançado "
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Critérios de Filtragem"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Verificar &todas as regras seguintes"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Verificar qualquer &uma das regras seguintes"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Nome do filtro:"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "&Salvar Filtro "
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Texto Simples "
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Parágrafo "
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Escolha "
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Marcador "
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Tabela"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Dependente "
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Data "
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr "Carregando %1..."
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr "Atualizando registros..."
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr "Atualizar Registros"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr "Atualizando <b>%1</b>..."
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr "Selecionar Correspondência"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+"<qt><b>%1</b> foram retornados múltiplos resultados que correspondem a "
+"<b>%2</b>, que é o registro corrente na coleção. Por favor selecione o "
+"resultado desejado.</qt>"
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Mostrar Todos os Grupos"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Ocultar Todos os Grupos "
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Filtrar por grupo "
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (Classificar por Ordem de Contagem) "
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Grupo"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Opções de Importação"
+
+#: importdialog.cpp:62
+msgid "&Replace current collection"
+msgstr "&Substituir a coleção atual"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr "Substitui a coleção atual pelo conteúdo do arquivo importado."
+
+#: importdialog.cpp:65
+msgid "A&ppend to current collection"
+msgstr "A&dicionar à coleção"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Adiciona os dados do arquivo importado à coleção atual. Isso só é "
+"possível se as coleções forem do mesmo tipo."
+
+#: importdialog.cpp:69
+msgid "&Merge with current collection"
+msgstr "&Combinar com a coleção atual"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Combina os dados do arquivo importado com a coleção atual. Isso só é "
+"possível se as coleções forem do mesmo tipo. Os registros devem ser "
+"exatamente do mesmo tipo para que possam ser combinados."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Importar "
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|Arquivos RIS (*.ris)"
+
+#: importdialog.cpp:277
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.amc|Arquivos de Dados AMC (*.amc) "
+
+#: importdialog.cpp:281
+#, fuzzy
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdb|Arquivos Pilot Database (*.pdb)"
+
+#: importdialog.cpp:285
+#, fuzzy
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.ris|Arquivos RIS (*.ris)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico não pôde carregar o arquivo - %1."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico não pôde escrever o arquivo - %1."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico não consegue atualizar o arquivo - %1."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Somente coleções com os mesmos tipos de registros do da coleção atual "
+"podem ser adicionadas. Nenhuma mudança foi feita à coleção atual."
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Somente coleções com os mesmos tipos de registro da coleção atual podem "
+"ser combinadas. Nenhuma mudança será feita à coleção atual."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico não pôde carregar o arquivo - %1."
+
+#: entryiconview.cpp:287
+#, fuzzy
+msgid "&Sort By"
+msgstr "&Porta:"
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Diálogo de Empréstimo"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "Os seguintes itens estão registrados para saída:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "O item seguinte está emprestado:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "&Emprestar para:"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Entre com o nome da pessoa para quem você está emprestando esses itens. "
+"Você pode selecioná-lo do seu livro de endereços clicando neste botão."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "Data do &Empréstimo:"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+"A data de saída é a data em que você emprestou os itens. Por padrão, a "
+"data de hoje é usada."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "Data para &Devolução:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"A data para devolução é o dia previsto para que os itens sejam "
+"devolvidos. Ela não é requerida, a menos que você queira adicionar o "
+"empréstimo ao seu calendário ativo."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Observação:"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "Você também pode adicionar observações sobre o empréstimo."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "&Adiciona um lembrete ao calendário ativo. "
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"<qt>A checagem deste marcador vai adicionar um item <em>A fazer</em> no seu "
+"calendário ativo, podendo ser acessado pelo KOrganizer. Este marcador será "
+"habilitado somente se você especificar uma data para devolução."
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Cria uma nova coleção "
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Nova Coleção de &Livros "
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Cria uma nova coleção de livros "
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Nova &Bibliografia"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Cria uma nova bibliografia do BibTeX"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Nova Coleção de &Revistas em Quadrinhos"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Cria uma nova coleção de revistas em quadrinhos"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Nova Coleção de &Vídeos"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Cria uma nova coleção de vídeos "
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Nova Coleção de &Músicas"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Cria uma nova coleção de músicas"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Nova Coleção de M&oedas"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Cria uma nova coleção de moedas"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Nova Coleção de &Selos "
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Cria uma nova coleção de selos "
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Nova Coleção de &Cartões"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Cria uma nova coleção de cartões"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Nova Coleção de &Vinhos"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Cria uma nova coleção de vinhos "
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Nova Coleção de &Jogos"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Cria uma nova coleção de jogos "
+
+#: mainwindow.cpp:272
+#, fuzzy
+msgid "New Boa&rd Game Collection"
+msgstr "Nova Coleção de &Jogos"
+
+#: mainwindow.cpp:274
+#, fuzzy
+msgid "Create a new board game collection"
+msgstr "Cria uma nova coleção de jogos "
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr "Novo Catálogo de &Arquivos"
+
+#: mainwindow.cpp:282
+msgid "Create a new file catalog"
+msgstr "Cria um novo catálogo de arquivos "
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Nova Coleção &Personalizada"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Cria uma nova coleção personalizada "
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Abre um documento existente"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Abre um arquivo usado recentemente"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Salva o documento"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Salva o documento como um novo arquivo"
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Imprime os dados do documento"
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Sai do aplicativo"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Importa dados a partir de outros formatos"
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Importar Dados do Tellico..."
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Importa outro arquivo de dados do Tellico "
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "Importar Dados CSV... "
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Importa um arquivo de valores separados por vírgula"
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "Importar Dados do MODS..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Importa um arquivo do MODS"
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Importar Dados do Alexandria..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Importa um arquivo do gerenciador de coleção de livros Alexandria"
+
+#: mainwindow.cpp:352
+#, fuzzy
+msgid "Import Delicious Library Data..."
+msgstr "Importar Dados do Tellico..."
+
+#: mainwindow.cpp:353
+#, fuzzy
+msgid "Import data from Delicious Library"
+msgstr "Importa meta-dados de arquivos de áudio"
+
+#: mainwindow.cpp:359
+#, fuzzy
+msgid "Import Referencer Data..."
+msgstr "Importar Dados do RIS..."
+
+#: mainwindow.cpp:360
+#, fuzzy
+msgid "Import data from Referencer"
+msgstr "Importa um arquivo de referência do RIS"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Importar Dados do BibTeX..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Importa um arquivo de bibliografia do BibTeX"
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Importar Dados do BibTeXML..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Importa um arquivo de bibliografia do BibTeXML"
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "Importar Dados do RIS..."
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Importa um arquivo de referência do RIS"
+
+#: mainwindow.cpp:387
+#, fuzzy
+msgid "Import PDF File..."
+msgstr "Importar Arquivo"
+
+#: mainwindow.cpp:388
+#, fuzzy
+msgid "Import a PDF file"
+msgstr "Importa um arquivo de valores separados por vírgula"
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Importar Meta-dados de um Arquivo de Áudio..."
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Importa meta-dados de arquivos de áudio"
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Importar Dados de CD de Áudio..."
+
+#: mainwindow.cpp:405
+msgid "Import audio CD information"
+msgstr "Importa informações de um CD de áudio "
+
+#: mainwindow.cpp:414
+msgid "Import GCstar Data..."
+msgstr "Importar Dados do GCstar..."
+
+#: mainwindow.cpp:415
+msgid "Import a GCstar data file"
+msgstr "Importa um arquivo de dados do GCstar"
+
+#: mainwindow.cpp:421
+#, fuzzy
+msgid "Import Griffith Data..."
+msgstr "Importar Dados do GCstar..."
+
+#: mainwindow.cpp:422
+#, fuzzy
+msgid "Import a Griffith database"
+msgstr "Exporta para um banco de dados PilotDB"
+
+#: mainwindow.cpp:428
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Importar Dados do Ant Movie Catalog..."
+
+#: mainwindow.cpp:429
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Importa um arquivo de dados do Ant Movie Catalog"
+
+#: mainwindow.cpp:435
+msgid "Import File Listing..."
+msgstr "Importar Listagem de Arquivos..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr "Importa informações sobre os arquivos de uma pasta "
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "Importar Transformação XSL..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Importa dados utilizando uma transformação XSL "
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Exportar "
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Exporta os dados da coleção para outros formatos "
+
+#: mainwindow.cpp:461
+msgid "Export to XML..."
+msgstr "Exportar para XML... "
+
+#: mainwindow.cpp:462
+msgid "Export to a Tellico XML file"
+msgstr "Exporta para um arquivo XML do Tellico "
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Exportar para Zip... "
+
+#: mainwindow.cpp:469
+msgid "Export to a Tellico Zip file"
+msgstr "Exporta para um arquivo Zip do Tellico "
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "Exportar para HTML... "
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Exporta para um arquivo HTML "
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "Exportar para CSV... "
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Exporta para um arquivo de valores separados por vírgula "
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "Exportar para &PilotDB... "
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Exporta para um banco de dados PilotDB"
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Exportar para o Alexandria... "
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Exporta para uma biblioteca do Alexandria "
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Exportar para o BibTeX... "
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Exporta para um arquivo do BibTeX "
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Exportar para o BibTeXML..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Exporta para um arquivo BibTeXML"
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "Exportar para o ONIX... "
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Exporta para um arquivo ONIX"
+
+#: mainwindow.cpp:524
+msgid "Export to GCfilms..."
+msgstr "Exportar para o GCfilms... "
+
+#: mainwindow.cpp:525
+msgid "Export to a GCfilms data file"
+msgstr "Exporta para um arquivo de dados do GCfilms"
+
+#: mainwindow.cpp:531
+#, fuzzy
+msgid "Export to GCstar..."
+msgstr "Exportar para o GCfilms... "
+
+#: mainwindow.cpp:532
+#, fuzzy
+msgid "Export to a GCstar data file"
+msgstr "Exporta para um arquivo de dados do GCfilms"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "Exportar Transformação XSL..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Exporta utilizando uma transformação XSL"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Corta o texto selecionado e coloca-o na área de transferência"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Copia o texto selecionado para a área de transferência"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Cola o conteúdo da área de transferência"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Seleciona todos os registros da coleção"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "De-seleciona todos os registros da coleção"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Pesquisa na Internet..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Pesquisa registros em fontes da Internet"
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "&Filtro Avançado..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Filtrar a coleção "
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&Novo registro..."
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Cria um novo registro"
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "&Editar Registro..."
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Edita os registros selecionados"
+
+#: controller.cpp:621 mainwindow.cpp:577
+msgid "D&uplicate Entry"
+msgstr "D&uplicar Registro"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Copia os registros selecionados"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "&Apagar Registro"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Apaga os registros selecionados "
+
+#: mainwindow.cpp:585
+#, fuzzy
+msgid "&Merge Entries"
+msgstr "&Apagar Registros"
+
+#: mainwindow.cpp:588
+#, fuzzy
+msgid "Merge the selected entries"
+msgstr "Apaga os registros selecionados "
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "&Gerar Relatórios... "
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Gera relatórios da coleção "
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "&Registrar saída..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Registra saída dos itens selecionados "
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "Registrar &entrada..."
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Registra entrada dos itens selecionados"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "&Renomear Coleção..."
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Renomeia a coleção"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "&Campos da Coleção..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Modifica os campos da coleção"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "Converter para &Bibliografia"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Converter uma coleção de livros para uma bibliografia"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "&Macros de String..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Editar linhas de macros do BibTeX "
+
+#: mainwindow.cpp:626
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Copia BibTeX para a &Área de Transferência"
+
+#: mainwindow.cpp:627
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Copia citações do BibTeX para a área de transferência"
+
+#: mainwindow.cpp:632
+msgid "Cite Entry in &LyX"
+msgstr "Citar Registro no &LyX"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Citar os registros selecionados no LyX"
+
+#: mainwindow.cpp:638
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Ci&tar Registro no OpenOffice.org"
+
+#: mainwindow.cpp:639
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Citar os registros selecionados no OpenOffice.org"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, no-c-format
+msgid "&Update Entry"
+msgstr "&Atualizar o Registro"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr "Todas as Fontes"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr "Atualizar o registro a partir de todas as fontes disponíveis "
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Mostrar Visão de &Grupo"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Ativar/desativar a visão de grupo"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Ocultar Visão de Gru&po "
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Mostrar &Editor de Registros"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Habilitar/desabilitar o editor"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "Ocultar &Editor de Registros"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Mostrar &Visão de Registros"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Habilitar/desabilitar visão de registros"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "Ocultar &Visão de Registros"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Alterar o Agrupamento"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "Seleção de &Grupo"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Alterar o agrupamento da coleção"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Filtrar"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Limpar Filtro"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Filtrar Aqui..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Grupos"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt>A <i>Visão de Grupos</i> classifica os registros em grupos com base em "
+"um campo selecionado.</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt>A <i>Visão de Colunas</i> mostra os valores de vários campos para cada "
+"registro</qt>"
+
+#: mainwindow.cpp:831
+#, fuzzy
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Tellico - um gerenciador de coleções para o KDE"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Criação de um novo documento... "
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Abrindo arquivo..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Abrir Arquivo"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Salvando Arquivo..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+"<qt><p>Você está salvando um arquivo com muitas imagens, levando o Tellico "
+"a ficar significativamente lento. Você gostaria de salvar as imagens "
+"separadamente no diretório de dados do Tellico para melhorar a "
+"performance?</p><p>Sua escolha pode sempre ser alterada na caixa de diálogo "
+"de configuração.</p></qt>"
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr "Salvar Imagens Separadamente"
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr "Salvar Imagens no Arquivo"
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Salvando arquivo com um novo nome..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Impressão..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"A coleção esta sendo filtrada para mostrar um subconjunto limitado de seus "
+"registros. Apenas os registros visíveis serão impressos. Continuar?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Processamento do documento..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Saindo..."
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Total de registros: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr ""
+"(%1 filtrado, %2 selecionado)\n"
+"(%1 filtrados, %2 selecionados)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr ""
+"(%1 filtrado)\n"
+"(%1 filtrados)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr ""
+"(%1 selecionado)\n"
+"(%1 selecionados)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Impressão %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Página %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Por favor, confira sua instalação."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Importação de dados..."
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Importar Arquivo"
+
+#: mainwindow.cpp:1864
+msgid "Import Directory"
+msgstr "Importar Diretório"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Exportação de dados..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Exportar Como"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Macros de String"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Macro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "String"
+
+#: mainwindow.cpp:1999
+msgid "Creating citations..."
+msgstr "Criando citações..."
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Filtros"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt>A <i>Visão de Filtros</i> mostra os registros que atendem determinadas "
+"regras de filtros.</qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Empréstimos"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt>A <i>Visão de Empréstimos</i> mostra uma lista com todas as pessoas "
+"que pegaram itens emprestados de sua coleção.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr "Atualiza os dados do registro %1"
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico não pôde carregar a imagem - %1."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+"Um arquivo chamado \"%1\" já existe. Tem certeza que deseja mesmo "
+"sobrescrevê-lo?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Sobrescrever o Arquivo?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Sobrescrever"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Filtro (Classificar por Contagem)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Quer mesmo apagar este registro?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Apagar a entrada?"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Quer mesmo apagar estes registros?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Apagar Múltiplos Registros"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "&Editar Registros..."
+
+#: controller.cpp:627
+msgid "D&uplicate Entries"
+msgstr "D&uplicar Registros"
+
+#: controller.cpp:628
+msgid "&Update Entries"
+msgstr "&Editar Registros"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "&Apagar Registros"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+"Os seguintes itens já estão emprestados. Como Tellico não suporta "
+"emprestar itens múltiplas vezes, eles serão removidos da lista de itens a "
+"serem emprestados."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Calendário Padrão"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"Presentemente, Tellico suporta apenas recursos de calendário locais. O "
+"calendário ativo está localizado remotamente, então seus empréstimos "
+"não serão adicionados."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Calendário Ativo"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 está previsto para ser devolvido para \"%2\""
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(Vazio)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - um gerenciador de coleções para o KDE"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Não reabrir o último arquivo aberto"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Importar <filename> como um arquivo do BibTeX"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Importar <filename> como um arquivo MODS"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Importar <filename> como um arquivo RIS"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Arquivo a ser aberto"
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr "Scripts de fontes de dados"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Ícones"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Autor da biblioteca btparse"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr "Exemplos de código e inspiração em geral"
+
+#: main.cpp:50
+#, fuzzy
+msgid "Author of libcsv library"
+msgstr "Autor da biblioteca btparse"
+
+#: main.cpp:52
+#, fuzzy
+msgid "Author of rtf2html library"
+msgstr "Autor da biblioteca btparse"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Campos da Coleção"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Campos Atuais"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "&Novo"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Adicionar um novo campo à coleção"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "&Apagar"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Apagar um campo da coleção"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Mover este campo para cima. A ordem na lista é importante para o layout do "
+"editor de registros."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Mover este campo para baixo. A ordem na lista é importante para o layout do "
+"editor de registros."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Propriedades do Campo"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "&Título:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "O título do campo"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "T&ipo:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "O tipo do campo determina que valores podem ser utilizados. "
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "<i>Texto Simples</i> é utilizado para a maioria dos campos."
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "<i>Parágrafo</i> é utilizado para grandes blocos de texto. "
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Escolha</i> limita o campo a certos valores. "
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "<i>Marcador</i> é usado para descrever valores do tipo sim/não."
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr "<i>Número</i> indica que o campo contém um valor numérico."
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+"<i>URL</i> é para os campos que fazem referência a uma URL, contendo "
+"referências a outros arquivos."
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr "Uma <i>Tabela</i> pode conter uma ou duas colunas de valores."
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "Um campo <i>Imagem</i> serve para armazenar uma foto ou figura."
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+"Um campo <i>Data</i> pode ser utilizado para valores com dia, mês e ano."
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr "Campos <i> Classificação</i> usam estrelas para indicar uma nota."
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"Um campo <i>Dependente</i> depende dos valores de outros campos, sendo "
+"formatado conforme a descrição do campo."
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"Um campo <i>Read Only</i> é utilizado para valores internos, que podem ser "
+"úteis para importação e exportação de dados."
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "Cate&goria:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr "O campo categoria determina a posição do campo no editor."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "Descr&ição:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"A descrição serve como lembrete de que informação o campo deve conter. "
+"Para campos <i>Dependentes</i>, a descrição é uma string de formatação "
+"do tipo \"%{year} %{title}\" onde os campos nomeados são substituídos por "
+"seus valores."
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr "Valor pa&drão:"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr "<qt> Um valor padrão pode ser definido para novos registros </qt>"
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr "Va&lores permitidos:"
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>Para os campos do tipo <i>Escolha</i>, estes são os únicos valores "
+"permitidos. Eles são colocados numa lista de opções. Os possíveis "
+"valores tem de ser separados por ponto e vírgula, por exemplo: \"cachorro, "
+"gato, rato\"</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "&Propriedades Estendidas:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "&Definir..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"As propriedades estendidas de um campo são utilizadas para definir coisas "
+"como o campo BibTeX correspondente."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Opções de Formato"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Sem formatação"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+"Esta opção impede o campo de ser automaticamente formatado ou posto em "
+"letras maiúsculas."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Permitir apenas a formatação automática em letras maiúsculas"
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+"Esta opção permite pôr o campo em maiúsculas, mas sem formatações "
+"especiais."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Formatar como título"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Esta opção põe em maiúsculas e formata o campo como um título,mas "
+"apenas se estas opções forem definidas globalmente."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Formatar como nome"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Esta opção põe em maiúsculas e formata o campo como um nome,mas apenas "
+"se estas opções forem definidas globalmente."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Opções do campo"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Ativar o auto-preenchimento"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Se selecionado, o auto-preenchimento do KDE será ativado na caixa de texto "
+"deste campo."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Permitir múltiplos valores"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Se selecionado, Tellico separará os valores separados por ponto e vírgula "
+"no campo de múltiplos valores."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Permitir agrupamento"
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Se selecionado, este campo será utilizado para reagrupar os registros na "
+"visão de grupos."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr ""
+"Reverter as propriedades dos campos selecionados para seus valores padrão."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Modificar Campos"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Apagar os valores possíveis do campo <i>%1</i> que existem na coleção "
+"pode causar corrupção de dados. Você deseja manter seus valores "
+"modificados ou cancelar e reverter aos valores anteriores?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Manter os valores modificados"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Reverter Propriedades do Campo"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Deseja realmente reverter as propriedades do campo <em>%1</em> para "
+"seus valores padrão?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Reverter"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Propriedades Estendidas dos Campos"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr "Já existe um campo com este nome. Favor escolher um nome diferente."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr ""
+"<qt>A categoria não pode ser deixada em branco. Por favor,informe uma "
+"categoria.</qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>Um campo não pode estar na mesma categoria que um <em>Parágrafo</em>, "
+"uma <em>Tabela</em> ou uma <em>Imagem</em>. Favor escolher uma outra "
+"categoria.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"O nome de um campo não deve ser o mesmo que o de uma categoria existente. "
+"Por favor insera um outro nome."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+"A faixa para uma classificação tem que ser de 1 até 10, e o limite "
+"inferior deve ser menor que o limite superior. Por favor entre com novos "
+"limites."
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "Tabelas são limitadas a um máximo de dez colunas."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"O arquivo atual foi modificado.\n"
+"Deseja salvá-lo?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Alterações não salvas"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Selecione a pessoa que pegou o item emprestado"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Configurar Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Opções Gerais"
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr "&Reabrir o arquivo ao iniciar"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Se selecionado, o último arquivo aberto será reaberto na próxima "
+"inicialização do programa."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "&Mostrar \"Dicas do Dia\" ao iniciar"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr ""
+"Se selecionado, as '\"Dicas do Dia\" serão mostradas ao iniciar o programa."
+
+#: configdialog.cpp:213
+#, fuzzy
+msgid "Image Storage Options"
+msgstr "Opções das Imagens"
+
+#: configdialog.cpp:214
+#, fuzzy
+msgid "Store images in data file"
+msgstr "&Incluir imagens no arquivo de dados"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr ""
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr ""
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Opções de formatação"
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr "Auto capitalizar &títulos e nomes"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Se selecionado, os títulos e os nomes serão automaticamente postos em "
+"maiúsculas."
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr "&Formatação automática dos títulos e nomes"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr ""
+"Se selecionado, os títulos e os nomes serão automaticamente formatados."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr "Não capitali&zar"
+
+#: configdialog.cpp:243
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Uma lista de palavras que não devem ser capitalizadas. As palavras "
+"devem ser separadas por ponto e vírgula.</qt>"
+
+#: configdialog.cpp:249
+msgid "Artic&les:"
+msgstr "Arti&gos:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>Uma lista de palavras que devem ser consideradas como artigos se forem a "
+"primeira palavra em um título. As palavras devem ser separadas por ponto e "
+"vírgula.</qt>"
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr "Sufi&xos pessoais:"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Uma lista de sufixos que podem ser utilizados nos nomes de pessoas. Os "
+"sufixos devem ser separados por um ponto e vírgula.</qt>"
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr "&Prefixos de sobrenomes:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Uma lista de prefixos que podem ser utilizados em sobrenomes. Os "
+"prefixos devem ser separados por um ponto e vírgula.</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Impressão"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Opções de Impressão"
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr "&Formatação dos títulos e nomes"
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr "Im&primir cabeçalhos dos campos"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Opções de agrupamento"
+
+#: configdialog.cpp:313
+msgid "&Group the entries"
+msgstr "A&grupar os registros"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Opções das Imagens"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr "&Largura máxima da imagem:"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Largura máxima das imagens na impressão. As proporções são conservadas."
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr "Altura &máxima da imagem:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Altura máxima da imagem na impressão. As proporções são conservadas."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Modelos"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Opções do Modelo"
+
+#: configdialog.cpp:369
+msgid "Template:"
+msgstr "Modelo:"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+"Selecione o modelo a ser utilizado para o tipo de coleção selecionado. Nem "
+"todos os modelos permitem a alteração do tipo e cor da fonte."
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr "&Pré-visualização..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr "Apresenta uma amostra do modelo"
+
+#: configdialog.cpp:398
+msgid "Font Options"
+msgstr "Opções de Fonte"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr "Fonte:"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr "Esta fonte é utilizada no modelo usado na Visão de Registros"
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr "Tamanho:"
+
+#: configdialog.cpp:425
+msgid "Color Options"
+msgstr "Opções de Cor"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr "Cor de fundo:"
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr "Esta cor é utilizada no modelo usado na Visão de Registro"
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr "Cor do texto:"
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr "Cor do destaque:"
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr "Cor do texto em destaque:"
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr "Gerenciamento de Modelos"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr "Instalar..."
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr "Clique para instalar um modelo diretamente"
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr "Baixar..."
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr "Clique para baixar modelos adicionais da internet"
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr "Deletar..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr "Clique para selecionar e remover modelos instalados"
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Fontes de Dados"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Opções da Fonte de Dados"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Fonte"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr "Mover para &Cima"
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+"A ordem das fontes de dados define a ordem que o Tellico usa quando as "
+"entradas são automaticamente atualizadas."
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr "Mover para &Baixo"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "&Novo..."
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr "Clique para adicionar uma nova fonte de dados"
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Modificar..."
+
+#: configdialog.cpp:533
+msgid "Click to modify the selected data source."
+msgstr "Clique para modificar a fonte de dados selecionada"
+
+#: configdialog.cpp:536
+msgid "Click to delete the selected data source."
+msgstr "Clique para apagar a fonte de dados selecionada"
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr "Clique para baixar fontes de dados adicionais da internet."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr "*.tar.gz *.tgz|Pacotes de Modelos (*.tar.gz)"
+
+#: configdialog.cpp:1049
+msgid "Delete Template"
+msgstr "Apaga Modelo"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr "Seleciona modelo a ser apagado"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "Pessoa que pegou emprestado"
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Registro de entrada"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "&Modificar empréstimo..."
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "Pessoa que pegou emprestado (Classificar por Contagem)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "Minha Coleção"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Coleção de Livros"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Coleção de Revistas em Quadrinhos"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Coleção de Vídeos"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Coleção de Músicas"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Coleção de Moedas"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Coleção de Selos"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Coleção de Vinhos"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Coleção de Cartões"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Coleção de Jogos"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr "Catálogo de Arquivos"
+
+#: collectionfactory.cpp:135
+#, fuzzy
+msgid "Board Game Collection"
+msgstr "Coleção de Jogos"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Coleção Personalizada"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+"<qt>A <i>Visão de Registros</i> mostra uma visão formatada do conteúdo do "
+"registro.</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt>A <i>Visão de Ícones</i> mostra cada registro da coleção ou grupo "
+"utilizando um ícone, que pode ser uma imagem no registro.</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Opções de Exportação"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Formatação"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Formatar todos os campos"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Se selecionados, os valores de todos os campos serão automaticamente "
+"formatados de acordo com seus tipos de formato."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Exporta apenas os registros selecionados"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr "Se marcado, apenas os registros selecionados serão exportados."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Codificação"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Codificar em Unicode (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Codificar o arquivo exportado em Unicode (UTF-8)."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Codificar na localização do usuário (%1)"
+
+#: exportdialog.cpp:72
+#, fuzzy
+msgid "Encode the exported file in the local encoding."
+msgstr "Codifica o arquivo exportado no formato local."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "&Procurar"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "&Interromper"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Pesquisa na Internet"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Parâmetros da Pesquisa"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr "P&esquisa:"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+"Forneça um valor de procura. Uma pesquisa por ISBN deve incluir o número "
+"ISBN completo."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Escolha o tipo de pesquisa"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Clique para iniciar ou interromper a pesquisa"
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr "Pesquisa &múltiplos ISBN/UPC"
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr "Assinale este marcador para pesquisar vários valores ISBN ou UPC."
+
+#: fetchdialog.cpp:138
+msgid "Edit List..."
+msgstr "Editar Lista..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr "Clique para inserir ou editar os múltiplos ISBN a serem pesquisados."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "Procurar f&onte:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Escolha a base de dados a pesquisar"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"À medida em que os resultados são encontrados, eles são adicionados a "
+"esta lista. Ao selecionar um deles a informação completa do registro será "
+"descarregada e mostrada na lista abaixo."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"Um registro pode ser mostrado aqui antes de ser adicionado à coleção, "
+"bastando selecioná-lo na lista abaixo"
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "&Adicionar registro"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Adicionar o registro selecionado à coleção atual"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr "Obter mais resultados"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr "Obter mais resultados da fonte de dados atual"
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Apagar todos os campos e valores"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Cancelando a pesquisa..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Pesquisando..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "A pesquisa não retornou resultados."
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+"A pesquisa retornou 1 item.\n"
+"A pesquisa retornou %n items."
+
+#: fetchdialog.cpp:412
+#, fuzzy
+msgid "No results were found for the following ISBN values:"
+msgstr "<qt>Nenhuma entrada encontrada para os ISBN seguintes:</qt>"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Carregando %1..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr "Não há fontes na Internet disponíveis para este tipo de coleção."
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr "Editar os valores ISBN/UPC"
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Insira os valores ISBN ou UPC, um por linha.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "&Carregar de um arquivo..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Carrega a lista de um arquivo texto.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>Uma pesquisa ISBN pode conter um máximo de 100 valores ISBN. Apenas os "
+"100 primeiros serão utilizados.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Editar Registro"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Novo Registro"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "Sal&var Registro"
+
+#: entryeditdialog.cpp:77
+msgid "Go to the previous entry in the collection"
+msgstr "Retorna ao registro anterior na coleção"
+
+#: entryeditdialog.cpp:82
+msgid "Go to the next entry in the collection"
+msgstr "Avança ao próximo registro na coleção"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Deseja realmente modificar estes registros?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Modificar Múltiplos Registros"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr ""
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "&Editar Registros"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "Sal&var Registros"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"A entrada corrente foi modificada.\n"
+"Deseja salvar as modificações?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Salvar Registro"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Relatório da Coleção"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "Modelo de &Relatório:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "&Gerar"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr "Selecione um modelo de relatório e clique em <em>Gerar</em>."
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+"Alguns relatórios de grandes coleções podem levar vários segundos para "
+"serem gerados."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Deseja realmente apagar este filtro?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Apagar o Filtro?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Novo nome da coleção:"
+
+#: tellico_kernel.cpp:377
+#, fuzzy
+msgid "Entry 1"
+msgstr "Tipo de Registro"
+
+#: tellico_kernel.cpp:378
+#, fuzzy
+msgid "Entry 2"
+msgstr "Tipo de Registro"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr ""
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+#, fuzzy
+msgid "Merge Entries"
+msgstr "Apagar Registros"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr ""
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr ""
+"Tellico não pôde encontrar a folha de estilo padrão para os registros."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Novo"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Coleção"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Barra de Ferramentas de Coleção"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Cláudio Henrique Fortes Félix"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "claudio@helpo.com.br"
+
+#: entrymerger.cpp:35
+#, fuzzy
+msgid "Merging entries..."
+msgstr "Atualizando registros..."
+
+#: entrymerger.cpp:49
+#, fuzzy
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Total de registros: %1"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>... que se um livro tiver vários autores, você deve separar\n"
+" os nomes deles com ponto e vírgula, informando ao Tellico como\n"
+"separá-los e utilizá-los independentemente.</p>\n"
+"<p>Qualquer outro campo que permita múltiplos valores deverá ter a\n"
+"mesma estrutura, com um ponto e vírgula (;) separando cada valor.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>...que você pode alterar que campos serão apresentados na Visão\n"
+"de Lista ao clicar com o botão direito sobre o cabeçalho das colunas.\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>...que você pode adicionar, editar, ou modificar os campos da coleção "
+"usando\n"
+"o Editor de Campos. Os botões com setas sob a lista de campos permitem "
+"modificar\n"
+"a posição do campo na lista, o que afetará sua posição no editor de "
+"registro.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>...que se você quiser filtrar a partir de um campo do tipo Marcador,\n"
+"um valor \"verdadeiro\" deve ser usado. Se quiser, por exemplo, mostrar\n"
+"apenas os livros de ficção científica que ainda não leu, marque o "
+"botão\n"
+"<em>Verificar todas as regras seguintes</em>, ajuste a primeira regra\n"
+"para \"Género\" contém\" \"Ficção científica\" (sem aspas) e a segunda "
+"regra\n"
+"para: \"Lido\" \"Não contém\" \"Verdadeiro\" (sem aspas).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>...que se um caractere não alfabético for utilizado no Filtro Rápido, "
+"o\n"
+"o texto é interpretado como uma expressão regular.</p>\n"
+"<p>Para mostrar somente os livros de Weber ou Bujold, por exemplo,\n"
+"escreva \"weber|bujold\" (sem aspas) no campo do filtro.</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>...que você pode editar mais de um registro de cada vez, segurando\n"
+"a tecla Shift ou Ctrl e selecionando múltiplos registros.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>...que você pode converter uma coleção de livros em bibliografia,\n"
+"que pode então ser exportada em formato BibTeX ou BibTeXML.</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>...que você pode adicionar, editar e apagar linhas de macros\n"
+"para bibliografias.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>...que se mais de um campo for formatado como nome, então um grupo\n"
+"adicional chamado \"Pessoas\" é adicionado à coleção, permitindo que "
+"autores e editores\n"
+"sejam classificados ou impressos juntos, por exemplo.</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>...que você pode modificar a aparência da impressão modificando o "
+"arquivo\n"
+"<tt>tellico-printing.xsl</tt>. O arquivo produz HTML, e o código CSS na "
+"página\n"
+" de estilo determina parâmetros visuais como fontes, margens, etc.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>...que você pode importar dados usando uma folha de estilo XSL genérica "
+"que\n"
+"seja capaz de produzir um arquivo XML do Tellico válido.</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+"<p>...que um duplo clique sobre um registro permite abrir o editor de "
+"Registros.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>...que você pode adicionar marcas HTML para formatar qualquer campo de "
+"tipo Parágrafo, tais como\n"
+"&lt;b&gt;bold&lt;/b&gt; ou &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>...que na Visão Detalhada, você pode pressionar uma letra do teclado "
+"para ir diretamente ao próximo registro que começa por esta letra.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Álbum"
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr "Este modelo é apenas para coleções de música"
+
+#: xslt.cpp:5
+msgid "Total:"
+msgstr "Total:"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr "Sofisticado"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "Padrão"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Compacto"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Vídeo"
+
+#: xslt.cpp:14 xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr "Este modelo é apenas para coleções de vídeo"
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Resumo de Grupos"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Resumo de Grupos"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Número total de campos:"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Número total de registros:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+msgid "Generated by Tellico"
+msgstr "Gerado por Tellico"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Valores Distintos:"
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Lista de Imagens"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Visão de Empréstimos"
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Data de Empréstimo"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Observação"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Data para Devolução"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Visão de Grupos"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Listagem de Títulos (Horizontal)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Listagem de Títulos (Vertical)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Visão de Colunas"
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "Tripla Coluna"
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr "Procura"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr "A Biblioteca Britânica"
+
+#: z3950.cpp:6
+msgid "Sudoc (France)"
+msgstr "Sudoc (França)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr "BIBSYS (Noruega)"
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr "Biblioteca Nacional Italiana"
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr "Biblioteca Nacional Portuguesa"
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr "Biblioteca Nacional da Polônia"
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr "Biblioteca Nacional do Canadá"
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr "Lista Unida de Israel"
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr "Biblioteca Nacional da Austrália"
+
+#: z3950.cpp:22
+#, fuzzy
+msgid "National Library of Lithuania"
+msgstr "Biblioteca Nacional do Canadá"
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr ""
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr ""
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr "Quadrinhos Dark Horse"
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr "Allocine.fr"
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr "Ministério da Cultura da Espanha"
+
+#, fuzzy
+#~ msgid "CrossRef"
+#~ msgstr "Referência cruzada"
+
+#~ msgid "MODS"
+#~ msgstr "MODS"
+
+#~ msgid "RIS"
+#~ msgstr "RIS "
+
+#, fuzzy
+#~ msgid "GCstar"
+#~ msgstr "Elenco"
+
+#~ msgid "AMC"
+#~ msgstr "AMC"
+
+#, fuzzy
+#~ msgid "Griffith"
+#~ msgstr "Presente"
+
+#, fuzzy
+#~ msgid "Referencer"
+#~ msgstr "Referência cruzada"
+
+#~ msgid "Comics"
+#~ msgstr "Revistas em Quadrinhos"
+
+#~ msgid "Stamps"
+#~ msgstr "Selos"
+
+#~ msgid "Coins"
+#~ msgstr "Moedas"
+
+#~ msgid "Books"
+#~ msgstr "Livros"
+
+#~ msgid "Wines"
+#~ msgstr "Vinhos"
+
+#~ msgid "Videos"
+#~ msgstr "Vídeos"
+
+#~ msgid "Games"
+#~ msgstr "Jogos"
+
+#~ msgid "Cards"
+#~ msgstr "Cartões"
+
+#~ msgid "Entries"
+#~ msgstr "Registros"
+
+#~ msgid "Albums"
+#~ msgstr "Álbuns"
+
+#~ msgid ""
+#~ "If checked, all images will be included in the data file, rather than saved "
+#~ "separately in the Tellico data directory. Saving a lot of images in the data "
+#~ "file cause Tellico to run more slowly."
+#~ msgstr ""
+#~ "Se marcado, todas as imagens vão ser incluídas no arquivo de dados, ao "
+#~ "invés de salvas separadamente no diretório de dados do Tellico. Salvar "
+#~ "muitas imagens no arquivo de dados pode levar o Tellico a ficar mais lento."
+
+#, fuzzy
+#~ msgid "Copac"
+#~ msgstr "Vírgula"
diff --git a/po/ro.po b/po/ro.po
new file mode 100644
index 0000000..be3e8a0
--- /dev/null
+++ b/po/ro.po
@@ -0,0 +1,5951 @@
+# translation of ro.po to Romanian
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+# This file is distributed under the same license as the tellico package.
+# Iulian Ursache <iulianu@cs.tuiasi.ro>, 2002.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: tellico 1.2\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2002-12-03 17:29-0800\n"
+"Last-Translator: Iulian Ursache <iulianu@cs.tuiasi.ro>\n"
+"Language-Team: Română <ro@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Report-Msgid-Bugs-To: \n"
+"X-Generator: KBabel 0.9.6\n"
+
+#: cite/lyxpipe.cpp:50
+#, fuzzy
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "Nu pot deschide fişierul - %1."
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr ""
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr ""
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr ""
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:181
+#, fuzzy
+msgid "Rename Column"
+msgstr "Redenumeşte colecţie..."
+
+#: gui/tablefieldwidget.cpp:181
+#, fuzzy
+msgid "New column name:"
+msgstr "Nume nou colecţie"
+
+#: gui/tablefieldwidget.cpp:206
+#, fuzzy, c-format
+msgid "Column %1"
+msgstr "Şterge carte"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+#, fuzzy
+msgid "Rename Column..."
+msgstr "Redenumeşte colecţie..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:295
+#, fuzzy
+msgid "Clear Table"
+msgstr "Şterge carte"
+
+#: gui/previewdialog.cpp:27
+#, fuzzy
+msgid "Template Preview"
+msgstr "Opţiuni generale"
+
+#: gui/stringmapdialog.cpp:57
+#, fuzzy
+msgid "&Set"
+msgstr "Ies..."
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr ""
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr ""
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr ""
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr ""
+
+#: gui/imagewidget.cpp:57
+#, fuzzy
+msgid "Select Image..."
+msgstr "Titlu"
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr ""
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr ""
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, fuzzy, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Şterge carte"
+
+#: commands/collectioncommand.cpp:110
+#, fuzzy
+msgid "Append Collection"
+msgstr "Redenumeşte colecţie..."
+
+#: commands/collectioncommand.cpp:112
+#, fuzzy
+msgid "Merge Collection"
+msgstr "Opţiuni colecţii cărţi"
+
+#: commands/collectioncommand.cpp:114
+#, fuzzy
+msgid "Replace Collection"
+msgstr "Redenumeşte colecţie..."
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+#, fuzzy
+msgid "Modify Entries"
+msgstr "Şterge carte"
+
+#: commands/fieldcommand.cpp:104
+#, fuzzy
+msgid "Add %1 Field"
+msgstr "Opţiuni colecţii audio"
+
+#: commands/fieldcommand.cpp:106
+#, fuzzy
+msgid "Modify %1 Field"
+msgstr "Modifică carte"
+
+#: commands/fieldcommand.cpp:108
+#, fuzzy
+msgid "Delete %1 Field"
+msgstr "Şterge carte"
+
+#: commands/addentries.cpp:50
+#, fuzzy
+msgid "Add Entries"
+msgstr "Şterge carte"
+
+#: commands/addentries.cpp:51
+#, fuzzy, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Şterge carte"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+#, fuzzy
+msgid "Rename Collection"
+msgstr "Redenumeşte colecţie..."
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+#, fuzzy
+msgid "Modify Loan"
+msgstr "Modifică carte"
+
+#: commands/filtercommand.cpp:98
+#, fuzzy
+msgid "Add Filter"
+msgstr "Deschide fişier..."
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr ""
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+#, fuzzy
+msgid "Delete Filter"
+msgstr "Şterge carte"
+
+#: commands/addloans.cpp:108
+#, fuzzy
+msgid "Check-out Items"
+msgstr "Şterge carte"
+
+#: commands/addloans.cpp:109
+#, fuzzy, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Şterge carte"
+
+#: commands/removeentries.cpp:48
+#, fuzzy
+msgid "Delete Entries"
+msgstr "Şterge carte"
+
+#: commands/removeentries.cpp:49
+#, fuzzy, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Şterge carte"
+
+#: commands/reorderfields.cpp:54
+#, fuzzy
+msgid "Reorder Fields"
+msgstr "Opţiuni colecţii audio"
+
+#: commands/removeloans.cpp:79
+#, fuzzy
+msgid "Check-in Entries"
+msgstr "Şterge carte"
+
+#: commands/removeloans.cpp:80
+#, fuzzy, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Şterge carte"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "General"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Stare"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+#, fuzzy
+msgid "Personal"
+msgstr "Personal"
+
+#: collections/stampcollection.cpp:27
+#, fuzzy
+msgid "My Stamps"
+msgstr "Filmele mele"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Titlu"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr ""
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+#, fuzzy
+msgid "Denomination"
+msgstr "Opţiuni colecţii cărţi"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+#, fuzzy
+msgid "Country"
+msgstr "Şterge carte"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr ""
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+#, fuzzy
+msgid "Color"
+msgstr "Ies..."
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr ""
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr ""
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+#, fuzzy
+msgid "Grade"
+msgstr "Gen"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr ""
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+#, fuzzy
+msgid "Hinged"
+msgstr "Semnată"
+
+#: collections/stampcollection.cpp:95
+#, fuzzy
+msgid "Centering"
+msgstr "Calificativ"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Data achiziţionării"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Preţ achiziţie"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+#, fuzzy
+msgid "Location"
+msgstr "Opţiuni colecţii cărţi"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Cadou"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+#, fuzzy
+msgid "Image"
+msgstr "Pagini"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Comentarii"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+#, fuzzy
+msgid "Publishing"
+msgstr "Editare"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+#, fuzzy
+msgid "Classification"
+msgstr "Clasificare"
+
+#: collections/comicbookcollection.cpp:28
+#, fuzzy
+msgid "My Comic Books"
+msgstr "Cărţile mele"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Subtitlu"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+#, fuzzy
+msgid "Writer"
+msgstr "Şterge carte"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Serie"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Editură"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Ediţie"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "An apariţie"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Pagini"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Limbă"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Gen"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Cuvinte cheie"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr ""
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Semnată"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Împrumutată"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+#, fuzzy
+msgid "Front Cover"
+msgstr "Ies..."
+
+#: collections/coincollection.cpp:26
+#, fuzzy
+msgid "My Coins"
+msgstr "Cărţile mele"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+#, fuzzy
+msgid "Type"
+msgstr "Nr. în serie"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "An"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr ""
+
+#: collections/coincollection.cpp:73
+#, fuzzy
+msgid "Coin Set"
+msgstr "Comentarii"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr ""
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr ""
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr ""
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr ""
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Cărţile mele"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Autor"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr ""
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr ""
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr ""
+
+#: collections/bookcollection.cpp:58
+#, fuzzy
+msgid "E-Book"
+msgstr "Cărţi"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Revistă"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Jurnal"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Legare"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "An copyright"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "Nr. ISBN"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr ""
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "Nr. LCCN"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr ""
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr ""
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Nr. în serie"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Nouă"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Folosită"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Citită"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Calificativ"
+
+#: collections/filecatalog.cpp:25
+#, fuzzy
+msgid "My Files"
+msgstr "Filmele mele"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+#, fuzzy
+msgid "Name"
+msgstr "Nr. în serie"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+#, fuzzy
+msgid "Volume"
+msgstr "Titlu"
+
+#: collections/filecatalog.cpp:55
+#, fuzzy
+msgid "Folder"
+msgstr "Şterge carte"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr ""
+
+#: collections/filecatalog.cpp:65
+#, fuzzy
+msgid "Size"
+msgstr "Semnată"
+
+#: collections/filecatalog.cpp:69
+#, fuzzy
+msgid "Permissions"
+msgstr "Personal"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr ""
+
+#: collections/filecatalog.cpp:79
+#, fuzzy
+msgid "Group"
+msgstr "Grupează după: "
+
+#: collections/filecatalog.cpp:85
+#, fuzzy
+msgid "Created"
+msgstr "Comentarii"
+
+#: collections/filecatalog.cpp:89
+#, fuzzy
+msgid "Modified"
+msgstr "Modifică carte"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+#, fuzzy
+msgid "Property"
+msgstr "An apariţie"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+#, fuzzy
+msgid "Value"
+msgstr "Titlu"
+
+#: collections/filecatalog.cpp:99
+#, fuzzy
+msgid "Icon"
+msgstr "Comentarii"
+
+#: collections/winecollection.cpp:26
+#, fuzzy
+msgid "My Wines"
+msgstr "Filmele mele"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+#, fuzzy
+msgid "Producer"
+msgstr "An apariţie"
+
+#: collections/winecollection.cpp:49
+#, fuzzy
+msgid "Appellation"
+msgstr "Redenumeşte colecţie..."
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr ""
+
+#: collections/winecollection.cpp:61
+#, fuzzy
+msgid "Vintage"
+msgstr "Semnată"
+
+#: collections/winecollection.cpp:67
+#, fuzzy
+msgid "Red Wine"
+msgstr "Filmele mele"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr ""
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr ""
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr ""
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr ""
+
+#: collections/winecollection.cpp:111
+#, fuzzy
+msgid "Label Image"
+msgstr "Titlu"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr ""
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr ""
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Filmele mele"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr ""
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+#, fuzzy
+msgid "HD DVD"
+msgstr "DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Suport"
+
+#: collections/videocollection.cpp:52
+#, fuzzy
+msgid "Production Year"
+msgstr "An apariţie"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr ""
+
+#: collections/videocollection.cpp:62
+#, fuzzy
+msgid "Certification"
+msgstr "Clasificare"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr ""
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr ""
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr ""
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr ""
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr ""
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr ""
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr ""
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr ""
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr ""
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr ""
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr ""
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr ""
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr ""
+
+#: collections/videocollection.cpp:95
+#, fuzzy
+msgid "Format"
+msgstr "Opţiuni generale"
+
+#: collections/videocollection.cpp:100
+#, fuzzy
+msgid "Cast"
+msgstr "Casetă"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr ""
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+#, fuzzy
+msgid "Role"
+msgstr "Titlu"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr ""
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr ""
+
+#: collections/videocollection.cpp:127
+#, fuzzy
+msgid "Composer"
+msgstr "Ies..."
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr ""
+
+#: collections/videocollection.cpp:139
+#, fuzzy
+msgid "Language Tracks"
+msgstr "Limbă"
+
+#: collections/videocollection.cpp:145
+#, fuzzy
+msgid "Subtitle Languages"
+msgstr "Subtitlu"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr ""
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr ""
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr ""
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr ""
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr ""
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr ""
+
+#: collections/videocollection.cpp:173
+#, fuzzy
+msgid "Color Mode"
+msgstr "Ies..."
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr ""
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr ""
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+#, fuzzy
+msgid "Personal Rating"
+msgstr "Personal"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+#, fuzzy
+msgid "Cover"
+msgstr "Ies..."
+
+#: collections/gamecollection.cpp:26
+#, fuzzy
+msgid "My Games"
+msgstr "Filmele mele"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr ""
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+#, fuzzy
+msgid "GameCube"
+msgstr "Nr. în serie"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr ""
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr ""
+
+#: collections/gamecollection.cpp:47
+#, fuzzy
+msgid "Game Boy Color"
+msgstr "Redenumeşte colecţie..."
+
+#: collections/gamecollection.cpp:47
+#, fuzzy
+msgid "Game Boy"
+msgstr "Nr. în serie"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr ""
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr ""
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr ""
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr ""
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Editură"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr ""
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+
+#: collections/gamecollection.cpp:82
+#, fuzzy
+msgid "ESRB Rating"
+msgstr "Calificativ"
+
+#: collections/gamecollection.cpp:95
+#, fuzzy
+msgid "Completed"
+msgstr "Comentarii"
+
+#: collections/cardcollection.cpp:26
+#, fuzzy
+msgid "My Cards"
+msgstr "CD-urile mele"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr ""
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr ""
+
+#: collections/cardcollection.cpp:55
+#, fuzzy
+msgid "Brand"
+msgstr "Gen"
+
+#: collections/cardcollection.cpp:62
+#, fuzzy
+msgid "Card Number"
+msgstr "Nr. în serie"
+
+#: collections/cardcollection.cpp:77
+#, fuzzy
+msgid "Card Type"
+msgstr "Nr. în serie"
+
+#: collections/cardcollection.cpp:109
+#, fuzzy
+msgid "Front Image"
+msgstr "Pagini"
+
+#: collections/cardcollection.cpp:112
+#, fuzzy
+msgid "Back Image"
+msgstr "Pagini"
+
+#: collections/boardgamecollection.cpp:26
+#, fuzzy
+msgid "My Board Games"
+msgstr "Filmele mele"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:72
+#, fuzzy
+msgid "Number of Players"
+msgstr "Şterge carte"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+#, fuzzy
+msgid "Bibliography"
+msgstr "Imprim..."
+
+#: collections/bibtexcollection.cpp:72
+#, fuzzy
+msgid "Entry Type"
+msgstr "Serie"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+
+#: collections/bibtexcollection.cpp:86
+#, fuzzy
+msgid "Bibtex Key"
+msgstr "Opţiuni generale"
+
+#: collections/bibtexcollection.cpp:92
+#, fuzzy
+msgid "Book Title"
+msgstr "Titlu"
+
+#: collections/bibtexcollection.cpp:98
+#, fuzzy
+msgid "Editor"
+msgstr "Ediţie"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+#, fuzzy
+msgid "Number"
+msgstr "Nr. în serie"
+
+#: collections/bibtexcollection.cpp:183
+#, fuzzy
+msgid "How Published"
+msgstr "Editură"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:236
+#, fuzzy
+msgid "Notes"
+msgstr "Ies..."
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr ""
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr ""
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr ""
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Casetă"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr ""
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Artist"
+
+#: collections/musiccollection.cpp:56
+#, fuzzy
+msgid "Label"
+msgstr "Titlu"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr ""
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr ""
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr ""
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr ""
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr ""
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr ""
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr ""
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr ""
+
+#: fetch/entrezfetcher.cpp:485
+#, fuzzy
+msgid "Institution"
+msgstr "Stare"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr ""
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr ""
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr ""
+
+#: fetch/z3950connection.cpp:345
+#, fuzzy
+msgid "Connection error %1: %2"
+msgstr "Bara de colecţii"
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr ""
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+#, fuzzy
+msgid "Hos&t: "
+msgstr "Ies..."
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr ""
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+#, fuzzy
+msgid "&Port: "
+msgstr "Ies..."
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr ""
+
+#: fetch/srufetcher.cpp:450
+#, fuzzy
+msgid "Path: "
+msgstr "Ies..."
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr ""
+
+#: fetch/srufetcher.cpp:460
+#, fuzzy
+msgid "Format: "
+msgstr "Opţiuni generale"
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr ""
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:848
+#, fuzzy
+msgid "Co&untry: "
+msgstr "Şterge carte"
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:855
+#, fuzzy
+msgid "France"
+msgstr "Caută:"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:869
+#, fuzzy
+msgid "Small Image"
+msgstr "Titlu"
+
+#: fetch/amazonfetcher.cpp:870
+#, fuzzy
+msgid "Medium Image"
+msgstr "Suport"
+
+#: fetch/amazonfetcher.cpp:871
+#, fuzzy
+msgid "Large Image"
+msgstr "Titlu"
+
+#: fetch/amazonfetcher.cpp:872
+#, fuzzy
+msgid "No Image"
+msgstr "Pagini"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:550
+#, fuzzy
+msgid "&Format: "
+msgstr "Opţiuni generale"
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+#, fuzzy
+msgid "Optional"
+msgstr "Opţiuni generale"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:82
+#, fuzzy
+msgid "External Application"
+msgstr "Părăseşte aplicaţia"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+#, fuzzy
+msgid "Collection &type:"
+msgstr "Opţiuni colecţii cărţi"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+#, fuzzy
+msgid "Update"
+msgstr "Şterge carte"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+
+#: fetch/configwidget.cpp:29
+#, fuzzy
+msgid "Source Options"
+msgstr "Opţiuni generale"
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+#, fuzzy
+msgid "IMDB Rating"
+msgstr "Calificativ"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+#, fuzzy
+msgid "Certifications"
+msgstr "Clasificare"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr ""
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:69
+#, fuzzy
+msgid "Person"
+msgstr "Personal"
+
+#: fetch/fetchmanager.cpp:70
+#, fuzzy
+msgid "ISBN"
+msgstr "Nr. ISBN"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:72
+#, fuzzy
+msgid "Keyword"
+msgstr "Cuvinte cheie"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr ""
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:343
+#, fuzzy
+msgid "&Username: "
+msgstr "Şterge carte"
+
+#: fetch/crossreffetcher.cpp:348
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:354
+#, fuzzy
+msgid "&Password: "
+msgstr "Ies..."
+
+#: fetch/gcstarpluginfetcher.cpp:190
+#, fuzzy
+msgid "GCstar Plugin"
+msgstr "Casetă"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:420
+#, fuzzy
+msgid "Author: "
+msgstr "Autor"
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr ""
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr ""
+
+#: newstuff/dialog.cpp:114
+#, fuzzy
+msgid "Version"
+msgstr "Personal"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr ""
+
+#: newstuff/dialog.cpp:117
+#, fuzzy
+msgid "Release Date"
+msgstr "Data achiziţionării"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+
+#: newstuff/dialog.cpp:137
+#, fuzzy
+msgid "The name and license of the selected item"
+msgstr "Şterge carte"
+
+#: newstuff/dialog.cpp:140
+#, fuzzy
+msgid "The author of the selected item"
+msgstr "Şterge carte"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr ""
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr ""
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+
+#: newstuff/dialog.cpp:194
+#, fuzzy
+msgid "A description of the selected item is shown here."
+msgstr "Şterge carte"
+
+#: newstuff/dialog.cpp:224
+#, fuzzy
+msgid "Downloading information..."
+msgstr "Imprim..."
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Gata."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr ""
+
+#: newstuff/dialog.cpp:413
+#, fuzzy
+msgid "Installing item..."
+msgstr "Salvez fişierul..."
+
+#: translators/bibteximporter.cpp:79
+msgid "No valid bibtex entries were found"
+msgstr ""
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+#, fuzzy
+msgid "Bibtex Options"
+msgstr "Opţiuni generale"
+
+#: translators/bibteximporter.cpp:287
+msgid "Use Unicode (UTF-8) encoding"
+msgstr ""
+
+#: translators/bibteximporter.cpp:288
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr ""
+
+#: translators/bibteximporter.cpp:289
+msgid "Use user locale (%1) encoding"
+msgstr ""
+
+#: translators/bibteximporter.cpp:293
+msgid "Read the imported file in the local encoding."
+msgstr ""
+
+#: translators/tellicozipexporter.cpp:35
+#, fuzzy
+msgid "Tellico Zip File"
+msgstr "Tellico"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Fişiere Tellico (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+#, fuzzy
+msgid "*|All Files"
+msgstr "Opţiuni colecţii audio"
+
+#: translators/alexandriaexporter.cpp:43
+#, fuzzy
+msgid "Alexandria"
+msgstr "Opţiuni generale"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr ""
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr ""
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr ""
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "necunoscut"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr ""
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr ""
+
+#: translators/tellicoimporter.cpp:940
+#, fuzzy
+msgid "Unread Books"
+msgstr "Introdu carte"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr ""
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr ""
+
+#: translators/tellicoimporter.cpp:980
+#, fuzzy
+msgid "Favorites"
+msgstr "Şterge carte"
+
+#: translators/audiofileimporter.cpp:69
+#, fuzzy
+msgid "Scanning audio files..."
+msgstr "Salvez fişierul..."
+
+#: translators/audiofileimporter.cpp:129
+#, fuzzy
+msgid "Bitrate"
+msgstr "Opţiuni generale"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:340
+#, fuzzy
+msgid "Audio File Options"
+msgstr "Opţiuni generale"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:348
+#, fuzzy
+msgid "If checked, the file names for each track are added to the entries."
+msgstr ""
+"Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+"programului."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:353
+#, fuzzy
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr ""
+"Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+"programului."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr ""
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+#, fuzzy
+msgid "*.csv|CSV Files (*.csv)"
+msgstr ""
+"*.tc *.bc|Fişiere Tellico (*.tc)\n"
+"*.xml|Fişiere XML (*.xml)\n"
+"*|Toate fişierele"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+#, fuzzy
+msgid "CSV Options"
+msgstr "Opţiuni generale"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr ""
+
+#: translators/csvexporter.cpp:114
+#, fuzzy
+msgid "If checked, a header row will be added with the field titles."
+msgstr ""
+"Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+"programului."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+#, fuzzy
+msgid "Delimiter"
+msgstr "Şterge carte"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+
+#: translators/csvexporter.cpp:124
+#, fuzzy
+msgid "Comma"
+msgstr "Comentarii"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr ""
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:135
+#, fuzzy
+msgid "Tab"
+msgstr "Titlu"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr ""
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr ""
+
+#: translators/filelistingimporter.cpp:63
+#, fuzzy
+msgid "Scanning files..."
+msgstr "Salvez fişierul..."
+
+#: translators/filelistingimporter.cpp:191
+#, fuzzy
+msgid "File Listing Options"
+msgstr "Opţiuni colecţii video"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr ""
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+
+#: translators/filelistingimporter.cpp:198
+#, fuzzy
+msgid "Generate file previews"
+msgstr "Creează un document nou"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+
+#: translators/onixexporter.cpp:63
+#, fuzzy
+msgid "ONIX Archive"
+msgstr "Opţiuni generale"
+
+#: translators/onixexporter.cpp:67
+#, fuzzy
+msgid "*.zip|Zip Files (*.zip)"
+msgstr ""
+"*.tc *.bc|Fişiere Tellico (*.tc)\n"
+"*.xml|Fişiere XML (*.xml)\n"
+"*|Toate fişierele"
+
+#: translators/onixexporter.cpp:176
+#, fuzzy
+msgid "ONIX Archive Options"
+msgstr "Opţiuni generale"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr ""
+
+#: translators/onixexporter.cpp:181
+#, fuzzy
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Dacă bifaţi, la numele grupului se va adăuga şi numărul de elemente din "
+"acel grup."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+#, fuzzy
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr "Nu pot deschide fişierul - %1."
+
+#: translators/freedbimporter.cpp:196
+#, fuzzy
+msgid "Select CDDB Entry"
+msgstr "Şterge carte"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr ""
+
+#: translators/freedbimporter.cpp:220
+#, fuzzy
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "Nu pot deschide fişierul - %1."
+
+#: translators/freedbimporter.cpp:238
+#, fuzzy
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "Nu pot deschide fişierul - %1."
+
+#: translators/freedbimporter.cpp:470
+#, fuzzy
+msgid "Various"
+msgstr "Grupează după: "
+
+#: translators/freedbimporter.cpp:489
+#, fuzzy
+msgid "Audio CD Options"
+msgstr "Opţiuni generale"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr ""
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr ""
+
+#: translators/freedbimporter.cpp:502
+#, fuzzy
+msgid "Read all CDDB cache files only"
+msgstr "Salvez fişierul..."
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr ""
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+#, fuzzy
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr ""
+"*.tc *.bc|Fişiere Tellico (*.tc)\n"
+"*.xml|Fişiere XML (*.xml)\n"
+"*|Toate fişierele"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+#, fuzzy
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr ""
+"*.tc *.bc|Fişiere Tellico (*.tc)\n"
+"*.xml|Fişiere XML (*.xml)\n"
+"*|Toate fişierele"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr ""
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+#, fuzzy
+msgid "XSLT Options"
+msgstr "Opţiuni generale"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+#, fuzzy
+msgid "XSLT file:"
+msgstr "Titlu"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr ""
+
+#: translators/alexandriaimporter.cpp:194
+#, fuzzy
+msgid "Alexandria Options"
+msgstr "Opţiuni generale"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr ""
+
+#: translators/bibtexmlexporter.cpp:36
+#, fuzzy
+msgid "Bibtexml"
+msgstr "Imprim..."
+
+#: translators/bibtexmlexporter.cpp:40
+#, fuzzy
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr ""
+"*.tc *.bc|Fişiere Tellico (*.tc)\n"
+"*.xml|Fişiere XML (*.xml)\n"
+"*|Toate fişierele"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr ""
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+#, fuzzy
+msgid "*.xml|XML Files (*.xml)"
+msgstr ""
+"*.tc *.bc|Fişiere Tellico (*.tc)\n"
+"*.xml|Fişiere XML (*.xml)\n"
+"*|Toate fişierele"
+
+#: translators/tellicoxmlexporter.cpp:480
+#, fuzzy
+msgid "Tellico XML Options"
+msgstr "Tellico"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr ""
+
+#: translators/tellicoxmlexporter.cpp:485
+#, fuzzy
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Dacă bifaţi, la numele grupului se va adăuga şi numărul de elemente din "
+"acel grup."
+
+#: translators/importer.h:100
+#, fuzzy
+msgid "Loading data..."
+msgstr "Imprim..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:48
+#, fuzzy
+msgid "Bibtex"
+msgstr "Opţiuni generale"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+#, fuzzy
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr ""
+"*.tc *.bc|Fişiere Tellico (*.tc)\n"
+"*.xml|Fişiere XML (*.xml)\n"
+"*|Toate fişierele"
+
+#: translators/bibtexexporter.cpp:203
+#, fuzzy
+msgid "Expand string macros"
+msgstr "Calificativ"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:210
+#, fuzzy
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr ""
+"Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+"programului."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:219
+#, fuzzy
+msgid "Bibtex quotation style:"
+msgstr "Opţiuni generale"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+#, fuzzy
+msgid "Braces"
+msgstr "Caută:"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr ""
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr ""
+
+#: translators/csvimporter.cpp:236
+#, fuzzy
+msgid "If checked, the first row is used as field titles."
+msgstr ""
+"Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+"programului."
+
+#: translators/csvimporter.cpp:248
+#, fuzzy
+msgid "&Comma"
+msgstr "Comentarii"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr ""
+
+#: translators/csvimporter.cpp:259
+#, fuzzy
+msgid "Ta&b"
+msgstr "Titlu"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr ""
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr ""
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+
+#: translators/csvimporter.cpp:298
+#, fuzzy
+msgid "Co&lumn:"
+msgstr "Şterge carte"
+
+#: translators/csvimporter.cpp:307
+#, fuzzy
+msgid "&Data field in this column:"
+msgstr "Opţiuni colecţii audio"
+
+#: translators/csvimporter.cpp:315
+#, fuzzy
+msgid "&Assign Field"
+msgstr "Opţiuni colecţii audio"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+#, fuzzy
+msgid "New Field"
+msgstr "Şterge carte"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr ""
+
+#: translators/pilotdbexporter.cpp:43
+#, fuzzy
+msgid "PilotDB"
+msgstr "Opţiuni generale"
+
+#: translators/pilotdbexporter.cpp:47
+#, fuzzy
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr ""
+"*.tc *.bc|Fişiere Tellico (*.tc)\n"
+"*.xml|Fişiere XML (*.xml)\n"
+"*|Toate fişierele"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr ""
+
+#: translators/pilotdbexporter.cpp:210
+#, fuzzy
+msgid "PilotDB Options"
+msgstr "Opţiuni generale"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr ""
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+#, fuzzy
+msgid "Tellico encountered an error in XSLT processing."
+msgstr ""
+"Eroare în procesarea XSLT.\n"
+"Vă rog verificaţi instalarea."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr ""
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+#, fuzzy
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr ""
+"*.tc *.bc|Fişiere Tellico (*.tc)\n"
+"*.xml|Fişiere XML (*.xml)\n"
+"*|Toate fişierele"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr ""
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+#, fuzzy
+msgid "*.html|HTML Files (*.html)"
+msgstr ""
+"*.tc *.bc|Fişiere Tellico (*.tc)\n"
+"*.xml|Fişiere XML (*.xml)\n"
+"*|Toate fişierele"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr ""
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr ""
+
+#: translators/htmlexporter.cpp:465
+#, fuzzy
+msgid "HTML Options"
+msgstr "Opţiuni generale"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr ""
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+#, fuzzy
+msgid "If checked, the field names will be printed as table headers."
+msgstr ""
+"Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+"programului."
+
+#: translators/htmlexporter.cpp:473
+#, fuzzy
+msgid "Group the entries"
+msgstr "Cărţile mele"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+#, fuzzy
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr ""
+"Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+"programului."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr ""
+
+#: translators/htmlexporter.cpp:479
+#, fuzzy
+msgid "If checked, individual files will be created for each entry."
+msgstr ""
+"Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+"programului."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+#, fuzzy
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Nu pot deschide fişierul - %1."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+#, fuzzy
+msgid "Data Source Properties"
+msgstr "Opţiuni generale"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr ""
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr ""
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr ""
+
+#: fetcherconfigdialog.cpp:114
+#, fuzzy
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+"programului."
+
+#: filterdialog.cpp:60
+#, fuzzy
+msgid "Any Field"
+msgstr "Opţiuni colecţii audio"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr ""
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr ""
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr ""
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr ""
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr ""
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr ""
+
+#: filterdialog.cpp:90
+#, fuzzy
+msgid "Edit..."
+msgstr "Ies..."
+
+#: filterdialog.cpp:282
+#, fuzzy
+msgid "Advanced Filter"
+msgstr "Deschide fişier..."
+
+#: filterdialog.cpp:294
+#, fuzzy
+msgid "Filter Criteria"
+msgstr "Şterge carte"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr ""
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr ""
+
+#: filterdialog.cpp:311
+#, fuzzy
+msgid "Filter name:"
+msgstr "Şterge carte"
+
+#: filterdialog.cpp:319
+#, fuzzy
+msgid "&Save Filter"
+msgstr "Deschide fişier..."
+
+#: field.cpp:490
+#, fuzzy
+msgid "Simple Text"
+msgstr "Caută"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr ""
+
+#: field.cpp:492
+msgid "Choice"
+msgstr ""
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr ""
+
+#: field.cpp:496
+#, fuzzy
+msgid "Table"
+msgstr "Titlu"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr ""
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Data"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr ""
+
+#: entryupdater.cpp:83
+#, fuzzy
+msgid "Updating entries..."
+msgstr "Şterge carte"
+
+#: entryupdater.cpp:85
+#, fuzzy
+msgid "Update Entries"
+msgstr "Şterge carte"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr ""
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr ""
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Desfă toate grupurile"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Pliază toate grupurile"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr ""
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr ""
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr ""
+
+#: importdialog.cpp:54 importdialog.cpp:60
+#, fuzzy
+msgid "Import Options"
+msgstr "Opţiuni generale"
+
+#: importdialog.cpp:62
+#, fuzzy
+msgid "&Replace current collection"
+msgstr "Redenumeşte colecţie..."
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr ""
+
+#: importdialog.cpp:65
+#, fuzzy
+msgid "A&ppend to current collection"
+msgstr "Schimbă modul de grupare a colecţiei"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+
+#: importdialog.cpp:69
+#, fuzzy
+msgid "&Merge with current collection"
+msgstr "Schimbă modul de grupare a colecţiei"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, fuzzy, no-c-format
+msgid "&Import"
+msgstr "Imprim..."
+
+#: importdialog.cpp:268
+#, fuzzy
+msgid "*.ris|RIS Files (*.ris)"
+msgstr ""
+"*.tc *.bc|Fişiere Tellico (*.tc)\n"
+"*.xml|Fişiere XML (*.xml)\n"
+"*|Toate fişierele"
+
+#: importdialog.cpp:277
+#, fuzzy
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr ""
+"*.tc *.bc|Fişiere Tellico (*.tc)\n"
+"*.xml|Fişiere XML (*.xml)\n"
+"*|Toate fişierele"
+
+#: importdialog.cpp:281
+#, fuzzy
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr ""
+"*.tc *.bc|Fişiere Tellico (*.tc)\n"
+"*.xml|Fişiere XML (*.xml)\n"
+"*|Toate fişierele"
+
+#: importdialog.cpp:285
+#, fuzzy
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr ""
+"*.tc *.bc|Fişiere Tellico (*.tc)\n"
+"*.xml|Fişiere XML (*.xml)\n"
+"*|Toate fişierele"
+
+#: tellico_strings.cpp:18
+#, fuzzy, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Nu pot deschide fişierul - %1."
+
+#: tellico_strings.cpp:19
+#, fuzzy, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Nu pot deschide fişierul - %1."
+
+#: tellico_strings.cpp:20
+#, fuzzy, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Nu pot deschide fişierul - %1."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+
+#: tellico_strings.cpp:27
+#, fuzzy, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Nu pot deschide fişierul - %1."
+
+#: entryiconview.cpp:287
+#, fuzzy
+msgid "&Sort By"
+msgstr "Ies..."
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr ""
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr ""
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr ""
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr ""
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+
+#: loandialog.cpp:117
+#, fuzzy
+msgid "&Loan date:"
+msgstr "Data"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+
+#: loandialog.cpp:132
+#, fuzzy
+msgid "D&ue date:"
+msgstr "Data"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+
+#: loandialog.cpp:144
+#, fuzzy
+msgid "&Note:"
+msgstr "Ies..."
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr ""
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr ""
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+
+#: mainwindow.cpp:188
+#, fuzzy
+msgid "Create a new collection"
+msgstr "Creează un document nou"
+
+#: mainwindow.cpp:192
+#, fuzzy
+msgid "New &Book Collection"
+msgstr "&Colecţie nouă"
+
+#: mainwindow.cpp:194
+#, fuzzy
+msgid "Create a new book collection"
+msgstr "Creează un document nou"
+
+#: mainwindow.cpp:200
+#, fuzzy
+msgid "New B&ibliography"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:202
+#, fuzzy
+msgid "Create a new bibtex bibliography"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:208
+#, fuzzy
+msgid "New &Comic Book Collection"
+msgstr "&Colecţie nouă"
+
+#: mainwindow.cpp:210
+#, fuzzy
+msgid "Create a new comic book collection"
+msgstr "Creează un document nou"
+
+#: mainwindow.cpp:216
+#, fuzzy
+msgid "New &Video Collection"
+msgstr "Opţiuni colecţii video"
+
+#: mainwindow.cpp:218
+#, fuzzy
+msgid "Create a new video collection"
+msgstr "Creează un document nou"
+
+#: mainwindow.cpp:224
+#, fuzzy
+msgid "New &Music Collection"
+msgstr "&Colecţie nouă"
+
+#: mainwindow.cpp:226
+#, fuzzy
+msgid "Create a new music collection"
+msgstr "Creează un document nou"
+
+#: mainwindow.cpp:232
+#, fuzzy
+msgid "New C&oin Collection"
+msgstr "&Colecţie nouă"
+
+#: mainwindow.cpp:234
+#, fuzzy
+msgid "Create a new coin collection"
+msgstr "Creează un document nou"
+
+#: mainwindow.cpp:240
+#, fuzzy
+msgid "New &Stamp Collection"
+msgstr "&Colecţie nouă"
+
+#: mainwindow.cpp:242
+#, fuzzy
+msgid "Create a new stamp collection"
+msgstr "Creează un document nou"
+
+#: mainwindow.cpp:248
+#, fuzzy
+msgid "New C&ard Collection"
+msgstr "Opţiuni colecţii video"
+
+#: mainwindow.cpp:250
+#, fuzzy
+msgid "Create a new trading card collection"
+msgstr "Creează un document nou"
+
+#: mainwindow.cpp:256
+#, fuzzy
+msgid "New &Wine Collection"
+msgstr "Opţiuni colecţii video"
+
+#: mainwindow.cpp:258
+#, fuzzy
+msgid "Create a new wine collection"
+msgstr "Creează un document nou"
+
+#: mainwindow.cpp:264
+#, fuzzy
+msgid "New &Game Collection"
+msgstr "&Colecţie nouă"
+
+#: mainwindow.cpp:266
+#, fuzzy
+msgid "Create a new game collection"
+msgstr "Creează un document nou"
+
+#: mainwindow.cpp:272
+#, fuzzy
+msgid "New Boa&rd Game Collection"
+msgstr "&Colecţie nouă"
+
+#: mainwindow.cpp:274
+#, fuzzy
+msgid "Create a new board game collection"
+msgstr "Creează un document nou"
+
+#: mainwindow.cpp:280
+#, fuzzy
+msgid "New &File Catalog"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:282
+#, fuzzy
+msgid "Create a new file catalog"
+msgstr "Creează un document nou"
+
+#: mainwindow.cpp:288
+#, fuzzy
+msgid "New C&ustom Collection"
+msgstr "&Colecţie nouă"
+
+#: mainwindow.cpp:290
+#, fuzzy
+msgid "Create a new custom collection"
+msgstr "Creează un document nou"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Deschide un document existent"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Deschide un fişier utilizat recent"
+
+#: mainwindow.cpp:303
+#, fuzzy
+msgid "Save the document"
+msgstr "Salvează documentul actual"
+
+#: mainwindow.cpp:305
+#, fuzzy
+msgid "Save the document as a different file..."
+msgstr "Salvează documentul actual ca..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Imprimă conţinutul documentului..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Părăseşte aplicaţia"
+
+#: mainwindow.cpp:320
+#, fuzzy
+msgid "Import collection data from other formats"
+msgstr "Imprimă conţinutul documentului..."
+
+#: mainwindow.cpp:324
+#, fuzzy
+msgid "Import Tellico Data..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:325
+#, fuzzy
+msgid "Import another Tellico data file"
+msgstr "%1 nu este un fişier de date Tellico."
+
+#: mainwindow.cpp:331
+#, fuzzy
+msgid "Import CSV Data..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:332
+#, fuzzy
+msgid "Import a CSV file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:338
+#, fuzzy
+msgid "Import MODS Data..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:339
+#, fuzzy
+msgid "Import a MODS data file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:345
+#, fuzzy
+msgid "Import Alexandria Data..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr ""
+
+#: mainwindow.cpp:352
+#, fuzzy
+msgid "Import Delicious Library Data..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:353
+#, fuzzy
+msgid "Import data from Delicious Library"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:359
+#, fuzzy
+msgid "Import Referencer Data..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:360
+#, fuzzy
+msgid "Import data from Referencer"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:366
+#, fuzzy
+msgid "Import Bibtex Data..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:367
+#, fuzzy
+msgid "Import a bibtex bibliography file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:373
+#, fuzzy
+msgid "Import Bibtexml Data..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:374
+#, fuzzy
+msgid "Import a Bibtexml bibliography file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:380
+#, fuzzy
+msgid "Import RIS Data..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:381
+#, fuzzy
+msgid "Import an RIS reference file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:387
+#, fuzzy
+msgid "Import PDF File..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:388
+#, fuzzy
+msgid "Import a PDF file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:394
+#, fuzzy
+msgid "Import Audio File Metadata..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:395
+#, fuzzy
+msgid "Import meta-data from audio files"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:404
+#, fuzzy
+msgid "Import Audio CD Data..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:405
+#, fuzzy
+msgid "Import audio CD information"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:414
+#, fuzzy
+msgid "Import GCstar Data..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:415
+#, fuzzy
+msgid "Import a GCstar data file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:421
+#, fuzzy
+msgid "Import Griffith Data..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:422
+#, fuzzy
+msgid "Import a Griffith database"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:428
+#, fuzzy
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:429
+#, fuzzy
+msgid "Import an Ant Movie Catalog data file"
+msgstr "%1 nu este un fişier de date Tellico."
+
+#: mainwindow.cpp:435
+#, fuzzy
+msgid "Import File Listing..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr ""
+
+#: mainwindow.cpp:442
+#, fuzzy
+msgid "Import XSL Transform..."
+msgstr "Ies..."
+
+#: mainwindow.cpp:443
+#, fuzzy
+msgid "Import using an XSL Transform"
+msgstr "Ies..."
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, fuzzy, no-c-format
+msgid "&Export"
+msgstr "Ies..."
+
+#: mainwindow.cpp:457
+#, fuzzy
+msgid "Export the collection data to other formats"
+msgstr "Imprimă conţinutul documentului..."
+
+#: mainwindow.cpp:461
+#, fuzzy
+msgid "Export to XML..."
+msgstr "Ies..."
+
+#: mainwindow.cpp:462
+#, fuzzy
+msgid "Export to a Tellico XML file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:468
+#, fuzzy
+msgid "Export to Zip..."
+msgstr "Ies..."
+
+#: mainwindow.cpp:469
+#, fuzzy
+msgid "Export to a Tellico Zip file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:475
+#, fuzzy
+msgid "Export to HTML..."
+msgstr "Ies..."
+
+#: mainwindow.cpp:476
+#, fuzzy
+msgid "Export to an HTML file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:482
+#, fuzzy
+msgid "Export to CSV..."
+msgstr "Ies..."
+
+#: mainwindow.cpp:483
+#, fuzzy
+msgid "Export to a comma-separated values file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:489
+#, fuzzy
+msgid "Export to PilotDB..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:490
+#, fuzzy
+msgid "Export to a PilotDB database"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:496
+#, fuzzy
+msgid "Export to Alexandria..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:497
+#, fuzzy
+msgid "Export to an Alexandria library"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:503
+#, fuzzy
+msgid "Export to Bibtex..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:504
+#, fuzzy
+msgid "Export to a bibtex file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:510
+#, fuzzy
+msgid "Export to Bibtexml..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:511
+#, fuzzy
+msgid "Export to a Bibtexml file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:517
+#, fuzzy
+msgid "Export to ONIX..."
+msgstr "Ies..."
+
+#: mainwindow.cpp:518
+#, fuzzy
+msgid "Export to an ONIX file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:524
+#, fuzzy
+msgid "Export to GCfilms..."
+msgstr "Ies..."
+
+#: mainwindow.cpp:525
+#, fuzzy
+msgid "Export to a GCfilms data file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:531
+#, fuzzy
+msgid "Export to GCstar..."
+msgstr "Ies..."
+
+#: mainwindow.cpp:532
+#, fuzzy
+msgid "Export to a GCstar data file"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:536
+#, fuzzy
+msgid "Export XSL Transform..."
+msgstr "Ies..."
+
+#: mainwindow.cpp:537
+#, fuzzy
+msgid "Export using an XSL Transform"
+msgstr "Ies..."
+
+#: mainwindow.cpp:546
+#, fuzzy
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Taie regiunea selectată şi o plasează în clipboard"
+
+#: mainwindow.cpp:548
+#, fuzzy
+msgid "Copy the selected text to the clipboard"
+msgstr "Copie în clipboard regiunea selectată"
+
+#: mainwindow.cpp:550
+#, fuzzy
+msgid "Paste the clipboard contents"
+msgstr "Lipeşte conţinutul clipboard-ului în poziţia actuală"
+
+#: mainwindow.cpp:552
+#, fuzzy
+msgid "Select all the entries in the collection"
+msgstr "Schimbă modul de grupare a colecţiei"
+
+#: mainwindow.cpp:554
+#, fuzzy
+msgid "Deselect all the entries in the collection"
+msgstr "Schimbă modul de grupare a colecţiei"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr ""
+
+#: mainwindow.cpp:559
+#, fuzzy
+msgid "Search the internet..."
+msgstr "Caută în document..."
+
+#: mainwindow.cpp:561
+#, fuzzy
+msgid "Advanced &Filter..."
+msgstr "Deschide fişier..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+#, fuzzy
+msgid "Filter the collection"
+msgstr "Părăseşte aplicaţia"
+
+#: mainwindow.cpp:569
+#, fuzzy
+msgid "&New Entry..."
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:572
+#, fuzzy
+msgid "Create a new entry"
+msgstr "Creează un document nou"
+
+#: controller.cpp:620 mainwindow.cpp:573
+#, fuzzy
+msgid "&Edit Entry..."
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:576
+#, fuzzy
+msgid "Edit the selected entries"
+msgstr "Şterge carte"
+
+#: controller.cpp:621 mainwindow.cpp:577
+#, fuzzy
+msgid "D&uplicate Entry"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:580
+#, fuzzy
+msgid "Copy the selected entries"
+msgstr "Şterge carte"
+
+#: controller.cpp:623 mainwindow.cpp:581
+#, fuzzy
+msgid "&Delete Entry"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:584
+#, fuzzy
+msgid "Delete the selected entries"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:585
+#, fuzzy
+msgid "&Merge Entries"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:588
+#, fuzzy
+msgid "Merge the selected entries"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr ""
+
+#: mainwindow.cpp:594
+#, fuzzy
+msgid "Generate collection reports"
+msgstr "Creează un document nou"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr ""
+
+#: mainwindow.cpp:598
+#, fuzzy
+msgid "Check-out the selected items"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr ""
+
+#: mainwindow.cpp:602
+#, fuzzy
+msgid "Check-in the selected items"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:604
+#, fuzzy
+msgid "&Rename Collection..."
+msgstr "Redenumeşte colecţie..."
+
+#: mainwindow.cpp:607
+#, fuzzy
+msgid "Rename the collection"
+msgstr "Redenumeşte colecţie..."
+
+#: mainwindow.cpp:608
+#, fuzzy
+msgid "Collection &Fields..."
+msgstr "Opţiuni colecţii audio"
+
+#: mainwindow.cpp:611
+#, fuzzy
+msgid "Modify the collection fields"
+msgstr "Opţiuni colecţii audio"
+
+#: mainwindow.cpp:612
+#, fuzzy
+msgid "Convert to &Bibliography"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:615
+#, fuzzy
+msgid "Convert a book collection to a bibliography"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:616
+#, fuzzy
+msgid "String &Macros..."
+msgstr "Calificativ"
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr ""
+
+#: mainwindow.cpp:626
+#, fuzzy
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Copie în clipboard regiunea selectată"
+
+#: mainwindow.cpp:627
+#, fuzzy
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Copie în clipboard regiunea selectată"
+
+#: mainwindow.cpp:632
+#, fuzzy
+msgid "Cite Entry in &LyX"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:633
+#, fuzzy
+msgid "Cite the selected entries in LyX"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:638
+#, fuzzy
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:639
+#, fuzzy
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Şterge carte"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, fuzzy, no-c-format
+msgid "&Update Entry"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr ""
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr ""
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr ""
+
+#: mainwindow.cpp:668
+#, fuzzy
+msgid "Enable/disable the group view"
+msgstr "Activează/dezactivează bara de unelte"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr ""
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr ""
+
+#: mainwindow.cpp:674
+#, fuzzy
+msgid "Enable/disable the editor"
+msgstr "Activează/dezactivează bara de unelte"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr ""
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr ""
+
+#: mainwindow.cpp:680
+#, fuzzy
+msgid "Enable/disable the entry view"
+msgstr "Activează/dezactivează bara de unelte"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr ""
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr ""
+
+#: mainwindow.cpp:697
+#, fuzzy
+msgid "&Group Selection"
+msgstr "Grupare"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Schimbă modul de grupare a colecţiei"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+#, fuzzy
+msgid "Filter"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:705
+#, fuzzy
+msgid "Clear Filter"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:710
+#, fuzzy
+msgid "Filter here..."
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:768
+#, fuzzy
+msgid "Groups"
+msgstr "Grupează după: "
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:831
+#, fuzzy
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Tellico - gestionar de colecţii personale de cărţi pentru KDE"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Creez documentul nou..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Deschid fişierul..."
+
+#: mainwindow.cpp:1108
+#, fuzzy
+msgid "Open File"
+msgstr "Deschide fişier..."
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Salvez fişierul..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr ""
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr ""
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Salvez fişierul sub un nou nume..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+
+#: mainwindow.cpp:1337
+#, fuzzy
+msgid "Processing document..."
+msgstr "Creez documentul nou..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Ies..."
+
+#: mainwindow.cpp:1498
+#, fuzzy, c-format
+msgid "Total entries: %1"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr ""
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr ""
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr ""
+
+#: mainwindow.cpp:1679
+#, fuzzy, c-format
+msgid "Print %1"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Pagina %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+#, fuzzy
+msgid "Please check your installation."
+msgstr ""
+"Eroare în procesarea XSLT.\n"
+"Vă rog verificaţi instalarea."
+
+#: mainwindow.cpp:1849
+#, fuzzy
+msgid "Importing data..."
+msgstr "Imprim..."
+
+#: mainwindow.cpp:1858
+#, fuzzy
+msgid "Import File"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:1864
+#, fuzzy
+msgid "Import Directory"
+msgstr "Imprim..."
+
+#: mainwindow.cpp:1885
+#, fuzzy
+msgid "Exporting data..."
+msgstr "Ies..."
+
+#: mainwindow.cpp:1907
+#, fuzzy
+msgid "Export As"
+msgstr "Ies..."
+
+#: mainwindow.cpp:1935
+#, fuzzy
+msgid "String Macros"
+msgstr "Calificativ"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr ""
+
+#: mainwindow.cpp:1936
+#, fuzzy
+msgid "String"
+msgstr "Calificativ"
+
+#: mainwindow.cpp:1999
+#, fuzzy
+msgid "Creating citations..."
+msgstr "Tai selecţia..."
+
+#: mainwindow.cpp:2104
+#, fuzzy
+msgid "Filters"
+msgstr "Şterge carte"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:2121
+#, fuzzy
+msgid "Loans"
+msgstr "Împrumutată"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr ""
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+
+#: filehandler.cpp:193
+#, fuzzy, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Nu pot deschide fişierul - %1."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr ""
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr ""
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr ""
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr ""
+
+#: controller.cpp:429
+#, fuzzy
+msgid "Delete Entry"
+msgstr "Şterge carte"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr ""
+
+#: controller.cpp:443
+#, fuzzy
+msgid "Delete Multiple Entries"
+msgstr "Şterge carte"
+
+#: controller.cpp:626
+#, fuzzy
+msgid "&Edit Entries..."
+msgstr "Şterge carte"
+
+#: controller.cpp:627
+#, fuzzy
+msgid "D&uplicate Entries"
+msgstr "Şterge carte"
+
+#: controller.cpp:628
+#, fuzzy
+msgid "&Update Entries"
+msgstr "Şterge carte"
+
+#: controller.cpp:629
+#, fuzzy
+msgid "&Delete Entries"
+msgstr "Şterge carte"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr ""
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr ""
+
+#: calendarhandler.cpp:203
+#, fuzzy
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Nu pot deschide fişierul - %1."
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(gol)"
+
+#: main.cpp:23
+#, fuzzy
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - gestionar de colecţii personale de cărţi pentru KDE"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr ""
+
+#: main.cpp:28
+#, fuzzy
+msgid "Import <filename> as a bibtex file"
+msgstr "Imprim..."
+
+#: main.cpp:29
+#, fuzzy
+msgid "Import <filename> as a MODS file"
+msgstr "Imprim..."
+
+#: main.cpp:30
+#, fuzzy
+msgid "Import <filename> as a RIS file"
+msgstr "Imprim..."
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Fişierul de deschis"
+
+#: main.cpp:42
+#, fuzzy
+msgid "Data source scripts"
+msgstr "Opţiuni generale"
+
+#: main.cpp:44
+#, fuzzy
+msgid "Icons"
+msgstr "Comentarii"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr ""
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr ""
+
+#: main.cpp:50
+msgid "Author of libcsv library"
+msgstr ""
+
+#: main.cpp:52
+msgid "Author of rtf2html library"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:56
+#, fuzzy
+msgid "Collection Fields"
+msgstr "Opţiuni colecţii audio"
+
+#: collectionfieldsdialog.cpp:68
+#, fuzzy
+msgid "Current Fields"
+msgstr "Opţiuni colecţii audio"
+
+#: collectionfieldsdialog.cpp:84
+#, fuzzy
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "Şterge carte"
+
+#: collectionfieldsdialog.cpp:86
+#, fuzzy
+msgid "Add a new field to the collection"
+msgstr "Creează un document nou"
+
+#: collectionfieldsdialog.cpp:87
+#, fuzzy
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "Şterge carte"
+
+#: collectionfieldsdialog.cpp:89
+#, fuzzy
+msgid "Remove a field from the collection"
+msgstr "Părăseşte aplicaţia"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:112
+#, fuzzy
+msgid "Field Properties"
+msgstr "Opţiuni generale"
+
+#: collectionfieldsdialog.cpp:119
+#, fuzzy
+msgid "&Title:"
+msgstr "Titlu"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr ""
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:215
+#, fuzzy
+msgid "Extended &properties:"
+msgstr "Opţiuni generale"
+
+#: collectionfieldsdialog.cpp:217
+#, fuzzy
+msgid "&Set..."
+msgstr "Ies..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:226
+#, fuzzy
+msgid "Format Options"
+msgstr "Opţiuni generale"
+
+#: collectionfieldsdialog.cpp:227
+#, fuzzy
+msgid "No formatting"
+msgstr "Opţiuni generale"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:233
+#, fuzzy
+msgid "Format as a title"
+msgstr "Pune automat majuscule la autori şi titluri"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:236
+#, fuzzy
+msgid "Format as a name"
+msgstr "Pune automat majuscule la autori şi titluri"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:241
+#, fuzzy
+msgid "Field Options"
+msgstr "Opţiuni generale"
+
+#: collectionfieldsdialog.cpp:242
+#, fuzzy
+msgid "Enable auto-completion"
+msgstr "Redenumeşte colecţie..."
+
+#: collectionfieldsdialog.cpp:243
+#, fuzzy
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+"programului."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:249
+#, fuzzy
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Dacă bifaţi, la numele grupului se va adăuga şi numărul de elemente din "
+"acel grup."
+
+#: collectionfieldsdialog.cpp:263
+#, fuzzy
+msgid "Revert the selected field's properties to the default values."
+msgstr "Schimbă modul de grupare a colecţiei"
+
+#: collectionfieldsdialog.cpp:306
+#, fuzzy
+msgid "Modify Fields"
+msgstr "Modifică carte"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:745
+#, fuzzy
+msgid "Revert Field Properties"
+msgstr "Opţiuni generale"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:872
+#, fuzzy
+msgid "Extended Field Properties"
+msgstr "Opţiuni generale"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr ""
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Fişierul curent a fost modificat.\n"
+"Doriţi să îl salvaţi?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr ""
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr ""
+
+#: configdialog.cpp:103
+#, fuzzy
+msgid "Configure Tellico"
+msgstr "Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Opţiuni generale"
+
+#: configdialog.cpp:201
+#, fuzzy
+msgid "&Reopen file at startup"
+msgstr "Redeschide fişierul la pornire"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+"programului."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr ""
+
+#: configdialog.cpp:208
+#, fuzzy
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr ""
+"Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+"programului."
+
+#: configdialog.cpp:213
+#, fuzzy
+msgid "Image Storage Options"
+msgstr "Opţiuni generale"
+
+#: configdialog.cpp:214
+#, fuzzy
+msgid "Store images in data file"
+msgstr "Imprim..."
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr ""
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr ""
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+
+#: configdialog.cpp:224 configdialog.cpp:299
+#, fuzzy
+msgid "Formatting Options"
+msgstr "Opţiuni generale"
+
+#: configdialog.cpp:227
+#, fuzzy
+msgid "Auto capitalize &titles and names"
+msgstr "Pune automat majuscule la autori şi titluri"
+
+#: configdialog.cpp:228
+#, fuzzy
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Dacă bifaţi, iniţialele numelor de autori şi titlurilor vor fi "
+"convertite automat la majuscule."
+
+#: configdialog.cpp:232
+#, fuzzy
+msgid "Auto &format titles and names"
+msgstr "Pune automat majuscule la autori şi titluri"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+#, fuzzy
+msgid "If checked, titles and names will be automatically formatted."
+msgstr ""
+"Dacă bifaţi, iniţialele numelor de autori şi titlurilor vor fi "
+"convertite automat la majuscule."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr ""
+
+#: configdialog.cpp:243
+#, fuzzy
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"Listă de cuvinte, separate de virgulă, care vor fi considerate articole "
+"când apar la începutul unui titlu"
+
+#: configdialog.cpp:249
+#, fuzzy
+msgid "Artic&les:"
+msgstr "Articole:"
+
+#: configdialog.cpp:252
+#, fuzzy
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"Listă de cuvinte, separate de virgulă, care vor fi considerate articole "
+"când apar la începutul unui titlu"
+
+#: configdialog.cpp:259
+#, fuzzy
+msgid "Personal suffi&xes:"
+msgstr "Sufixe nume:"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr ""
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+
+#: configdialog.cpp:296
+#, fuzzy
+msgid "Printing"
+msgstr "Imprim..."
+
+#: configdialog.cpp:296
+#, fuzzy
+msgid "Printing Options"
+msgstr "Opţiuni colecţii video"
+
+#: configdialog.cpp:302
+#, fuzzy
+msgid "&Format titles and names"
+msgstr "Pune automat majuscule la autori şi titluri"
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr ""
+
+#: configdialog.cpp:310
+#, fuzzy
+msgid "Grouping Options"
+msgstr "Grupare"
+
+#: configdialog.cpp:313
+#, fuzzy
+msgid "&Group the entries"
+msgstr "Cărţile mele"
+
+#: configdialog.cpp:317
+#, fuzzy
+msgid "Image Options"
+msgstr "Opţiuni generale"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr ""
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr ""
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr ""
+
+#: configdialog.cpp:355
+#, fuzzy
+msgid "Template Options"
+msgstr "Opţiuni generale"
+
+#: configdialog.cpp:369
+#, fuzzy
+msgid "Template:"
+msgstr "Opţiuni generale"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+
+#: configdialog.cpp:380
+#, fuzzy
+msgid "&Preview..."
+msgstr "Nouă"
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr ""
+
+#: configdialog.cpp:398
+#, fuzzy
+msgid "Font Options"
+msgstr "Opţiuni generale"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr ""
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:415
+#, fuzzy
+msgid "Size:"
+msgstr "Semnată"
+
+#: configdialog.cpp:425
+#, fuzzy
+msgid "Color Options"
+msgstr "Opţiuni generale"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr ""
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr ""
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr ""
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr ""
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr ""
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr ""
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr ""
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr ""
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr ""
+
+#: configdialog.cpp:487
+#, fuzzy
+msgid "Delete..."
+msgstr "Titlu"
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr ""
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr ""
+
+#: configdialog.cpp:501
+#, fuzzy
+msgid "Data Source Options"
+msgstr "Opţiuni generale"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr ""
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr ""
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr ""
+
+#: configdialog.cpp:528
+#, fuzzy
+msgid "&New..."
+msgstr "Nouă"
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr ""
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr ""
+
+#: configdialog.cpp:533
+#, fuzzy
+msgid "Click to modify the selected data source."
+msgstr "Şterge carte"
+
+#: configdialog.cpp:536
+#, fuzzy
+msgid "Click to delete the selected data source."
+msgstr "Şterge carte"
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr ""
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr ""
+
+#: configdialog.cpp:1049
+#, fuzzy
+msgid "Delete Template"
+msgstr "Şterge carte"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr ""
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr ""
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr ""
+
+#: loanview.cpp:76
+#, fuzzy
+msgid "Modify Loan..."
+msgstr "Modifică carte"
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr ""
+
+#: collectionfactory.cpp:81
+#, fuzzy
+msgid "My Collection"
+msgstr "Opţiuni colecţii cărţi"
+
+#: collectionfactory.cpp:124
+#, fuzzy
+msgid "Book Collection"
+msgstr "Opţiuni colecţii cărţi"
+
+#: collectionfactory.cpp:126
+#, fuzzy
+msgid "Comic Book Collection"
+msgstr "Opţiuni colecţii cărţi"
+
+#: collectionfactory.cpp:127
+#, fuzzy
+msgid "Video Collection"
+msgstr "Opţiuni colecţii video"
+
+#: collectionfactory.cpp:128
+#, fuzzy
+msgid "Music Collection"
+msgstr "Opţiuni colecţii cărţi"
+
+#: collectionfactory.cpp:129
+#, fuzzy
+msgid "Coin Collection"
+msgstr "Redenumeşte colecţie"
+
+#: collectionfactory.cpp:130
+#, fuzzy
+msgid "Stamp Collection"
+msgstr "Redenumeşte colecţie..."
+
+#: collectionfactory.cpp:131
+#, fuzzy
+msgid "Wine Collection"
+msgstr "Opţiuni colecţii video"
+
+#: collectionfactory.cpp:132
+#, fuzzy
+msgid "Card Collection"
+msgstr "Opţiuni colecţii cărţi"
+
+#: collectionfactory.cpp:133
+#, fuzzy
+msgid "Game Collection"
+msgstr "Redenumeşte colecţie..."
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr ""
+
+#: collectionfactory.cpp:135
+#, fuzzy
+msgid "Board Game Collection"
+msgstr "Redenumeşte colecţie..."
+
+#: collectionfactory.cpp:136
+#, fuzzy
+msgid "Custom Collection"
+msgstr "&Colecţie nouă"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+
+#: exportdialog.cpp:48
+#, fuzzy
+msgid "Export Options"
+msgstr "Opţiuni generale"
+
+#: exportdialog.cpp:53
+#, fuzzy
+msgid "Formatting"
+msgstr "Opţiuni generale"
+
+#: exportdialog.cpp:55
+#, fuzzy
+msgid "Format all fields"
+msgstr "Pune automat majuscule la autori şi titluri"
+
+#: exportdialog.cpp:57
+#, fuzzy
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Dacă bifaţi, iniţialele numelor de autori şi titlurilor vor fi "
+"convertite automat la majuscule."
+
+#: exportdialog.cpp:59
+#, fuzzy
+msgid "Export selected entries only"
+msgstr "Şterge carte"
+
+#: exportdialog.cpp:61
+#, fuzzy
+msgid "If checked, only the currently selected entries will be exported."
+msgstr ""
+"Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+"programului."
+
+#: exportdialog.cpp:64
+#, fuzzy
+msgid "Encoding"
+msgstr "Legare"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr ""
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr ""
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr ""
+
+#: exportdialog.cpp:72
+msgid "Encode the exported file in the local encoding."
+msgstr ""
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr ""
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr ""
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr ""
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr ""
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr ""
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr ""
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr ""
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr ""
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr ""
+
+#: fetchdialog.cpp:138
+#, fuzzy
+msgid "Edit List..."
+msgstr "Ies..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr ""
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr ""
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+
+#: fetchdialog.cpp:192
+#, fuzzy
+msgid "&Add Entry"
+msgstr "Şterge carte"
+
+#: fetchdialog.cpp:196
+#, fuzzy
+msgid "Add the selected entry to the current collection"
+msgstr "Creează un document nou"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr ""
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr ""
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr ""
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr ""
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+#, fuzzy
+msgid "Searching..."
+msgstr "Salvez fişierul..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr ""
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+
+#: fetchdialog.cpp:412
+msgid "No results were found for the following ISBN values:"
+msgstr ""
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr ""
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr ""
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr ""
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr ""
+
+#: fetchdialog.cpp:604
+#, fuzzy
+msgid "&Load From File..."
+msgstr "Imprim..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr ""
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+#, fuzzy
+msgid "Edit Entry"
+msgstr "Şterge carte"
+
+#: entryeditdialog.cpp:52
+#, fuzzy
+msgid "&New Entry"
+msgstr "Şterge carte"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+#, fuzzy
+msgid "Sa&ve Entry"
+msgstr "Şterge carte"
+
+#: entryeditdialog.cpp:77
+#, fuzzy
+msgid "Go to the previous entry in the collection"
+msgstr "Schimbă modul de grupare a colecţiei"
+
+#: entryeditdialog.cpp:82
+#, fuzzy
+msgid "Go to the next entry in the collection"
+msgstr "Schimbă modul de grupare a colecţiei"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr ""
+
+#: entryeditdialog.cpp:317
+#, fuzzy
+msgid "Modify Multiple Entries"
+msgstr "Modifică carte"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr ""
+
+#: entryeditdialog.cpp:456
+#, fuzzy
+msgid "Edit Entries"
+msgstr "Şterge carte"
+
+#: entryeditdialog.cpp:488
+#, fuzzy
+msgid "Sa&ve Entries"
+msgstr "Şterge carte"
+
+#: entryeditdialog.cpp:656
+#, fuzzy
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"Fişierul curent a fost modificat.\n"
+"Doriţi să îl salvaţi?"
+
+#: entryeditdialog.cpp:659
+#, fuzzy
+msgid "Save Entry"
+msgstr "Şterge carte"
+
+#: reportdialog.cpp:53
+#, fuzzy
+msgid "Collection Report"
+msgstr "Bara de colecţii"
+
+#: reportdialog.cpp:60
+#, fuzzy
+msgid "&Report template:"
+msgstr "Imprim..."
+
+#: reportdialog.cpp:83
+#, fuzzy
+msgid "&Generate"
+msgstr "General"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr ""
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr ""
+
+#: tellico_kernel.cpp:287
+#, fuzzy
+msgid "Delete Filter?"
+msgstr "Şterge carte"
+
+#: tellico_kernel.cpp:323
+#, fuzzy
+msgid "New collection name:"
+msgstr "Nume nou colecţie"
+
+#: tellico_kernel.cpp:377
+#, fuzzy
+msgid "Entry 1"
+msgstr "Serie"
+
+#: tellico_kernel.cpp:378
+#, fuzzy
+msgid "Entry 2"
+msgstr "Serie"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr ""
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+#, fuzzy
+msgid "Merge Entries"
+msgstr "Şterge carte"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr ""
+
+#: entryview.cpp:186
+#, fuzzy
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Nu pot deschide fişierul - %1."
+
+#: rc.cpp:6
+#, fuzzy, no-c-format
+msgid "&New"
+msgstr "Nouă"
+
+#: rc.cpp:15
+#, fuzzy, no-c-format
+msgid "&Collection"
+msgstr "Opţiuni colecţii cărţi"
+
+#: rc.cpp:24
+#, fuzzy, no-c-format
+msgid "Collection Toolbar"
+msgstr "Bara de colecţii"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Iulian Ursache"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "iulianu@cs.tuiasi.ro"
+
+#: entrymerger.cpp:35
+#, fuzzy
+msgid "Merging entries..."
+msgstr "Şterge carte"
+
+#: entrymerger.cpp:49
+#, fuzzy
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Şterge carte"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr ""
+
+#: xslt.cpp:3
+#, fuzzy
+msgid "This template is meant for music collections only."
+msgstr "Creează un document nou"
+
+#: xslt.cpp:5
+#, fuzzy
+msgid "Total:"
+msgstr "Total"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr ""
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr ""
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr ""
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr ""
+
+#: xslt.cpp:14 xslt.cpp:43
+#, fuzzy
+msgid "This template is meant for video collections only."
+msgstr "Creează un document nou"
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr ""
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ""
+
+#: xslt.cpp:18
+#, fuzzy
+msgid "Total number of fields:"
+msgstr "Şterge carte"
+
+#: xslt.cpp:19
+#, fuzzy
+msgid "Total number of entries:"
+msgstr "Şterge carte"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+#, fuzzy
+msgid "Generated by Tellico"
+msgstr "General"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr ""
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr ""
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr ""
+
+#: xslt.cpp:27 xslt.cpp:29
+#, fuzzy
+msgid "Loan Date"
+msgstr "Împrumutată"
+
+#: xslt.cpp:28 xslt.cpp:31
+#, fuzzy
+msgid "Note"
+msgstr "Ies..."
+
+#: xslt.cpp:30
+#, fuzzy
+msgid "Due Date"
+msgstr "Data"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr ""
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr ""
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr ""
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr ""
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr ""
+
+#: xslt.cpp:44
+#, fuzzy
+msgid "Search"
+msgstr "Salvez fişierul..."
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr ""
+
+#: z3950.cpp:6
+#, fuzzy
+msgid "Sudoc (France)"
+msgstr "Caută:"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr ""
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr ""
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr ""
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr ""
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr ""
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr ""
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr ""
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr ""
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr ""
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr ""
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr ""
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr ""
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr ""
+
+#, fuzzy
+#~ msgid "GCstar"
+#~ msgstr "Casetă"
+
+#, fuzzy
+#~ msgid "Griffith"
+#~ msgstr "Cadou"
+
+#, fuzzy
+#~ msgid "Comics"
+#~ msgstr "Comentarii"
+
+#, fuzzy
+#~ msgid "Coins"
+#~ msgstr "Comentarii"
+
+#~ msgid "Books"
+#~ msgstr "Cărţi"
+
+#, fuzzy
+#~ msgid "Wines"
+#~ msgstr "Filmele mele"
+
+#~ msgid "Videos"
+#~ msgstr "Filme"
+
+#, fuzzy
+#~ msgid "Games"
+#~ msgstr "Nr. în serie"
+
+#, fuzzy
+#~ msgid "Cards"
+#~ msgstr "Casetă"
+
+#, fuzzy
+#~ msgid "Entries"
+#~ msgstr "Serie"
+
+#, fuzzy
+#~ msgid "Copac"
+#~ msgstr "Comentarii"
+
+#~ msgid "Tellico"
+#~ msgstr "Tellico"
+
+#, fuzzy
+#~ msgid "&Copy Entry"
+#~ msgstr "Şterge carte"
+
+#, fuzzy
+#~ msgid "&Copy Entries"
+#~ msgstr "Şterge carte"
+
+#, fuzzy
+#~ msgid "Scanning CDDB cache files..."
+#~ msgstr "Salvez fişierul..."
+
+#, fuzzy
+#~ msgid "Collection &type: "
+#~ msgstr "Opţiuni colecţii cărţi"
+
+#, fuzzy
+#~ msgid "Save Entries"
+#~ msgstr "Şterge carte"
+
+#, fuzzy
+#~ msgid ""
+#~ "_: Save (Entry Title)\n"
+#~ "Save %1"
+#~ msgstr "Şterge carte"
+
+#~ msgid "Enable/disable the statusbar"
+#~ msgstr "Activează/dezactivează bara de stare"
+
+#, fuzzy
+#~ msgid "Reading files..."
+#~ msgstr "Salvez fişierul..."
+
+#, fuzzy
+#~ msgid "Group by:"
+#~ msgstr "Grupează după:"
+
+#, fuzzy
+#~ msgid "Filter Entry"
+#~ msgstr "Şterge carte"
+
+#, fuzzy
+#~ msgid "Tellico: %1 is due to return %2"
+#~ msgstr "Nu pot deschide fişierul - %1."
+
+#, fuzzy
+#~ msgid "Find Text"
+#~ msgstr "Caută"
+
+#~ msgid "&Find"
+#~ msgstr "&Caută"
+
+#, fuzzy
+#~ msgid "Find"
+#~ msgstr "&Caută"
+
+#, fuzzy
+#~ msgid "If checked, the search string is used as a regular expression."
+#~ msgstr ""
+#~ "Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+#~ "programului."
+
+#, fuzzy
+#~ msgid "Field"
+#~ msgstr "Opţiuni colecţii audio"
+
+#, fuzzy
+#~ msgid "If checked, the search is case-sensitive."
+#~ msgstr ""
+#~ "Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+#~ "programului."
+
+#, fuzzy
+#~ msgid "If checked, the document is searched in reverse."
+#~ msgstr ""
+#~ "Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+#~ "programului."
+
+#, fuzzy
+#~ msgid "If checked, the search is limited to whole words."
+#~ msgstr ""
+#~ "Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+#~ "programului."
+
+#~ msgid "5 - Best"
+#~ msgstr "5 - F. bună"
+
+#~ msgid "4 - Good"
+#~ msgstr "4 - Bună"
+
+#~ msgid "3 - Neutral"
+#~ msgstr "3 - Medie"
+
+#~ msgid "2 - Bad"
+#~ msgstr "2 - Proastă"
+
+#~ msgid "1 - Worst"
+#~ msgstr "1 - F. proastă"
+
+#, fuzzy
+#~ msgid "Delete Entry?"
+#~ msgstr "Şterge carte"
+
+#~ msgid "Warning!"
+#~ msgstr "Atenţie!"
+
+#, fuzzy
+#~ msgid "Search the collection"
+#~ msgstr "Redenumeşte colecţie..."
+
+#, fuzzy
+#~ msgid "Find next match in the collection"
+#~ msgstr "Schimbă modul de grupare a colecţiei"
+
+#, fuzzy
+#~ msgid "Reports"
+#~ msgstr "Ies..."
+
+#~ msgid "Show number of items in group"
+#~ msgstr "Afişează numărul de elemente din grup."
+
+#~ msgid "Video"
+#~ msgstr "Video"
+
+#, fuzzy
+#~ msgid "*.bc .tc|Tellico files (*.tc)"
+#~ msgstr ""
+#~ "*.tc *.bc|Fişiere Tellico (*.tc)\n"
+#~ "*.xml|Fişiere XML (*.xml)\n"
+#~ "*|Toate fişierele"
+
+#, fuzzy
+#~ msgid "If checked, the document is searched from the beginning."
+#~ msgstr ""
+#~ "Dacă bifaţi, ultimul fişier deschis va fi deschis din nou la pornirea "
+#~ "programului."
+
+#, fuzzy
+#~ msgid "<qt>Tellico was unable to open the CD-ROM device - <i>%1</i>.</qt>"
+#~ msgstr "Nu pot deschide fişierul - %1."
+
+#, fuzzy
+#~ msgid "*.ogg|Ogg files (*.ogg)"
+#~ msgstr ""
+#~ "*.tc *.bc|Fişiere Tellico (*.tc)\n"
+#~ "*.xml|Fişiere XML (*.xml)\n"
+#~ "*|Toate fişierele"
+
+#, fuzzy
+#~ msgid "Export images"
+#~ msgstr "Ies..."
+
+#~ msgid ""
+#~ "A comma-separated list of suffixes which might be used in personal names."
+#~ msgstr "O listă de sufixe pentru numele proprii, separate de virgulă."
+
+#, fuzzy
+#~ msgid "A comma-separated list of prefixes which might be used in surnames."
+#~ msgstr "O listă de sufixe pentru numele proprii, separate de virgulă."
+
+#~ msgid "Enable/disable the toolbar"
+#~ msgstr "Activează/dezactivează bara de unelte"
+
+#~ msgid "Show Co&llection ToolBar"
+#~ msgstr "Afişează bara de co&lecţii"
+
+#~ msgid "Enable/disable the collection toolbar"
+#~ msgstr "Activează/dezactivează bara de colecţii"
+
+#, fuzzy
+#~ msgid "*.bcz|Tellico files(*.bcz)"
+#~ msgstr ""
+#~ "*.tc *.bc|Fişiere Tellico (*.tc)\n"
+#~ "*.xml|Fişiere XML (*.xml)\n"
+#~ "*|Toate fişierele"
+
+#, fuzzy
+#~ msgid "List"
+#~ msgstr "Artist"
+
+#, fuzzy
+#~ msgid "Good"
+#~ msgstr "4 - Bună"
+
+#, fuzzy
+#~ msgid "New Entry"
+#~ msgstr "Şterge carte"
+
+#~ msgid "Copying selection to clipboard..."
+#~ msgstr "Copii selecţia în clipboard..."
+
+#~ msgid "Inserting clipboard contents..."
+#~ msgstr "Inserez conţinutul clipboard-ului..."
+
+#~ msgid "Toggling toolbar..."
+#~ msgstr "Comut bara de unelte..."
+
+#~ msgid "Toggling collection toolbar..."
+#~ msgstr "Comut bara de colecţii..."
+
+#~ msgid "Toggle the statusbar..."
+#~ msgstr "Comut bara de stare..."
+
+#, fuzzy
+#~ msgid "Tellico is unable to find a required file - %1.\n"
+#~ msgstr "Nu pot deschide fişierul - %1."
+
+#, fuzzy
+#~ msgid "&New Collection"
+#~ msgstr "&Colecţie nouă"
+
+#, fuzzy
+#~ msgid "BCUnitEditWidget"
+#~ msgstr "Opţiuni colecţii cărţi"
+
+#, fuzzy
+#~ msgid "TextImporter"
+#~ msgstr "Ies..."
+
+#, fuzzy
+#~ msgid "XSLTImporter"
+#~ msgstr "Ies..."
+
+#, fuzzy
+#~ msgid "CSVImporter"
+#~ msgstr "Ies..."
+
+#, fuzzy
+#~ msgid "BibtexImporter"
+#~ msgstr "Ies..."
+
+#, fuzzy
+#~ msgid "BCAttributeWidget"
+#~ msgstr "Opţiuni colecţii cărţi"
+
+#, fuzzy
+#~ msgid "BCTabControl"
+#~ msgstr "Tellico"
+
+#, fuzzy
+#~ msgid "Processing new entries..."
+#~ msgstr "Creez documentul nou..."
+
+#, fuzzy
+#~ msgid "Collection Field in this Column:"
+#~ msgstr "Opţiuni colecţii audio"
+
+#, fuzzy
+#~ msgid "Tellico is unable to find the file - %1."
+#~ msgstr "Nu pot deschide fişierul - %1."
+
+#, fuzzy
+#~ msgid "Tellico is unable to download the file - %1."
+#~ msgstr "Nu pot deschide fişierul - %1."
+
+#, fuzzy
+#~ msgid "These are the available fields in the collection."
+#~ msgstr "Schimbă modul de grupare a colecţiei"
+
+#, fuzzy
+#~ msgid "Read Only"
+#~ msgstr "Gata."
+
+#, fuzzy
+#~ msgid "Text"
+#~ msgstr "Caută"
+
+#, fuzzy
+#~ msgid "Enoding Options"
+#~ msgstr "Grupare"
+
+#, fuzzy
+#~ msgid "Edit Collection Fields..."
+#~ msgstr "Ies..."
+
+#, fuzzy
+#~ msgid "&Create new collection"
+#~ msgstr "Creează un document nou"
+
+#, fuzzy
+#~ msgid "*.txt|Text files (*.txt)"
+#~ msgstr ""
+#~ "*.tc *.bc|Fişiere Tellico (*.tc)\n"
+#~ "*.xml|Fişiere XML (*.xml)\n"
+#~ "*|Toate fişierele"
+
+#~ msgid "New Book"
+#~ msgstr "Carte nouă"
+
+#, fuzzy
+#~ msgid "Delete Books"
+#~ msgstr "Şterge carte"
+
+#, fuzzy
+#~ msgid "Group Books By"
+#~ msgstr "Cărţile mele"
+
+#~ msgid "Configure the options for the application..."
+#~ msgstr "Configurează opţiunile aplicaţiei..."
+
+#~ msgid "CD"
+#~ msgstr "CD"
+
+#, fuzzy
+#~ msgid "&Publishing"
+#~ msgstr "Editare"
+
+#~ msgid "Clear Data"
+#~ msgstr "Curăţă datele"
+
+#~ msgid ""
+#~ "*.tc *.bc|Tellico files (*.tc)\n"
+#~ "*.xml|XML files (*.xml)\n"
+#~ "*|All files"
+#~ msgstr ""
+#~ "*.tc *.bc|Fişiere Tellico (*.tc)\n"
+#~ "*.xml|Fişiere XML (*.xml)\n"
+#~ "*|Toate fişierele"
+
+#, fuzzy
+#~ msgid "Unable to upload file - %1."
+#~ msgstr "Nu pot descărca fişierul - %1."
+
+#, fuzzy
+#~ msgid "Unable to write file - %1."
+#~ msgstr "Nu pot citi fişierul - %1."
+
+#~ msgid ""
+#~ "Unable to find a file needed for printing - %1.\n"
+#~ "Please check your installation."
+#~ msgstr ""
+#~ "Nu găsesc un fişier necesar pentru imprimare - %1.\n"
+#~ "Vă rog verificaţi instalarea."
+
+#, fuzzy
+#~ msgid "Unable to find file - %1."
+#~ msgstr "Nu pot deschide fişierul - %1."
+
+#~ msgid "Unable to download file - %1."
+#~ msgstr "Nu pot descărca fişierul - %1."
+
+#~ msgid "Unable to open file - %1."
+#~ msgstr "Nu pot deschide fişierul - %1."
+
+#~ msgid "Unable to read file - %1."
+#~ msgstr "Nu pot citi fişierul - %1."
+
+#~ msgid "File is not in XML format - %1."
+#~ msgstr "Fişierul nu e în format XML - %1."
+
+#, fuzzy
+#~ msgid "Unable to load file - %1."
+#~ msgstr "Nu pot descărca fişierul - %1."
+
+#, fuzzy
+#~ msgid "File has no syntax version - %1."
+#~ msgstr "Fişierul nu e în format XML - %1."
+
+#~ msgid "8mm"
+#~ msgstr "8mm"
+
+#~ msgid "LaserDisc"
+#~ msgstr "LaserDisc"
+
+#~ msgid "Betamax"
+#~ msgstr "Betamax"
+
+#~ msgid "CDs"
+#~ msgstr "CD-uri"
+
+#~ msgid "%1 %2"
+#~ msgstr "%2 %1"
+
+#, fuzzy
+#~ msgid ""
+#~ "Unable to find a required file - %1.\n"
+#~ "Please check your installation."
+#~ msgstr ""
+#~ "Nu găsesc un fişier necesar pentru imprimare - %1.\n"
+#~ "Vă rog verificaţi instalarea."
diff --git a/po/ru.po b/po/ru.po
new file mode 100644
index 0000000..fcbe9e6
--- /dev/null
+++ b/po/ru.po
@@ -0,0 +1,5178 @@
+# translation of ru.po to Russian
+# Калимуллин Артур <kalimullin@gmail.com>, 2006.
+# Kalimullin Artur <kalimullin@gmail.com>, 2006.
+# Pesotsky Denis <St.MPA3b@gmail.com>, 2008.
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+msgid ""
+msgstr ""
+"Project-Id-Version: ru\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2008-03-21 00:44+0300\n"
+"Last-Translator: Pesotsky Denis <St.MPA3b@gmail.com>\n"
+"Language-Team: Russian <kde-russian@lists.kde.ru>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "<qt>Ошибка записи на канал сервера <b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr "Подсоединение к OpenOffice.org..."
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr "Соединение с OpenOffice.org"
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+"Не удаётся соединиться с OpenOffice.org. Проверьте, запущен ли OpenOffice "
+"Writer, или скорректируйте настройки соединения ниже."
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr "Канал"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr "TCP/IP"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr "Переименовать столбец"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr "Новое название столбца:"
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr "Столбец %1"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr "Переименовать столбец"
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr "Вставить строку"
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr "Удалить строку"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr "Переместить строку выше"
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr "Переместить строку ниже"
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr "Очистить таблицу"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr "Просмотр шаблонов"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Установить"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr "%1:"
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Больше"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Меньше"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Очистить"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Выбрать изображение..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr "Сохранить только ссылку"
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr "Сохранение ссылки возможно только для новых изображений."
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Редактировать %1"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Добавить коллекцию"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Объединить коллекцию"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Заместить коллекцию"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr "Редактировать записи"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "Добавить %1 поле"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Редактировать %1 поле"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Удалить %1 поле"
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr "Добавить записи"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Добавить %1"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Переименовать коллекцию"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Редактировать долг"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Добавить фильтр"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Редактировать фильтр"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Удалить фильтр"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Дать в долг"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Дать в долг %1"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Удалить записи"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Удалить %1"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Упорядочить поля"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Вернуть долги"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Вернуть долг %1"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Общее"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Состояние"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Личное"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Мои марки"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Название"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Описание"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Достоинство"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "Страна"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Год издания"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Цвет"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Scott#"
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr "Супер,Отлично,Хорошо,Нормально,Средне,Плохо"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Оценка"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Аннулировано"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Со следами клея"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Центровка"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Приклеена"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Дата покупки"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Цена покупки"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Место"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Подарок"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Изображение"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Комментарии"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Издательство"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Классификация"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Мои комиксы"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Подзаголовок"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Писатель"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr "Художник"
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Серия"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Издание"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Издательство"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Редакция"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Год издания"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Страницы"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Язык"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Жанр"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Ключевые слова"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very Good,Good,"
+"Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr "Новое,Почти новое,Очень хорошо,Хорошо,Средне,Ниже среднего,Плохо,Очень плохо"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Подписано"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Одолжено"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Обложка"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Мои монеты"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Тип"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Год"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Место чеканки"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Набор монет"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+"Запечатано-65,Запечатано-60,Новое-65,Новое-60,Почти не использовалось-55,"
+"Почти не использовалось-50,Очень хорошо-40,Хорошо-30,Средне-20,Ниже среднего-"
+"12,Удовлетворительно-8,Плохо-4,Очень плохо"
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr "PCGS,NGC,ANACS,ICG,ASA,PCIG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Служба оценки"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "\"Орел\""
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "\"Решка\""
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Мои книги"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Автор"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Твердый переплет"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Мягкий переплет"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "На газетной бумаге"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "Электронная книга"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Журнал"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Дневник"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Переплет"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Год сдачи в печать"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN#"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Международный стандартный номер книги"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN#"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Контрольный номер Библиотеки Конгресса"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr "Переводчик"
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Номер серии"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Новая"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Подержанная"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Прочитана"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Рейтинг"
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr "Мои файлы"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "Имя"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Том"
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr "Папка"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr "Mimetype"
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr "Размер"
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr "Права"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr "Владелец"
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr "Группа"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr "Создан"
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr "Модифицирован"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr "Мета-информация"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Свойство"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Значение"
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr "Значок"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Мои вина"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Производитель"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Название"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Сорт"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Урожай"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Красное вино"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Белое вино"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Игристое вино"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Количество"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Было выпито"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Изображение этикетки"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Другие люди"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Особенности"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Мои фильмы"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr "Blu-ray"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+msgid "HD DVD"
+msgstr "HD DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Носитель"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Год записи"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "G (США),PG (США),PG-13 (США),R (США), U (США)"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Сертификация"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Регион 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Регион 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Регион 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Регион 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Регион 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Регион 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Регион 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Регион 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Регион"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Страна"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Формат"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Роли"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr "Актёр/Актриса"
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr "Роль"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr "Таблица для записи актёров и ролей, которые они играли"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Режиссёр"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Композитор"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Студия"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Языки озвучки"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Языки субтитров"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Аудио треки"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Продолжительность"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "Продолжительность видео (в минутах)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Соотношение сторон"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Широкоэкранное"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Черно-белое"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Цветовой режим"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Режиссёрская версия"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Сюжет фильма"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Личный рейтинг"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Обложка"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "Мои игры"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr "Xbox 360"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr "PlayStation 3"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation 2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr "Nintendo Wii"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr "Linux"
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Платформа"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Год выпуска"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Издательство"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Разработчик"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+"Без рейтинга, Только для взрослых, От 17 лет, Подросткам 13—19 лет, Для "
+"всех, Для детей младшего возраста, Рейтинг ожидается"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "Возрастной рейтинг"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Пройдена"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Мои карточки"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Игрок"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Команда"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Фирма"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Номер карточки"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Тип карточки"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Изображение передней стороны"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Изображение задней стороны"
+
+#: collections/boardgamecollection.cpp:26
+msgid "My Board Games"
+msgstr "Мои настольные игры"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr "Механизм"
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr "Дизайнер"
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr "Количество игроков"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Библиография"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Тип записи"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr "Эти типы записей специфичны для Bibtex. Смотрите документацию Bibtex"
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Ключ Bibtex"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Название книги"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Редактор"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Организация"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Адрес"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr "DOI"
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr "Цифровой идентификатор объекта (Digital Object Identifier)"
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Месяц"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Номер"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Как издавалась"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Часть"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Перекрёстная ссылка"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Резюме"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Заметки"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Моя музыка"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Альбом"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "Компакт-диск"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Кассета"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Винил"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Исполнитель"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Лейбл"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Дорожки"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr "Длина"
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "the"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr.,jr,iii,iv"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,van,der,van der,von"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr "ISBNdb.com"
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "В этом типе коллекций нельзя искать %1"
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Результаты поиска %1: %2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "У этого источника нет опций."
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "База данных Entrez"
+
+#: fetch/entrezfetcher.cpp:485
+msgid "Institution"
+msgstr "Институт"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Ошибка запроса!"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Ошибка поиска соединения %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Синтаксическая ошибка"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Ошибка соединения %1: %2"
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr "Сервер SRU"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Библиотека Конгресса (США)"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr "&Сервер: "
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr "Введите адрес сервера."
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Порт: "
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Введите номер порта сервера. По умолчанию выбран %1"
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr "Путь: "
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr "Введите путь к базе данных, используемой сервером."
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr "Формат: "
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr "Введите формат результатов, используемый сервером."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr "Аудио-поиск Yahoo!"
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "Не получается загрузить изображение обложки."
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr "Ссылка Amazon"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (США)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (Великобритания)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Германия)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Япония)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (Франция)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Канада)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Веб-сервисы Amazon.com"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "Ст&рана"
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "США"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Великобритания"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Германия"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Япония"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "Франция"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Канада"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon.com предоставляет данные из нескольких своих сайтов. Выберите "
+"источник, откуда вы хотите получить данные."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "&Размер изображения: "
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Маленькое изображение"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Среднее изображение"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Большое изображение"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Нет изображения"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"Изображение обложки может быть получено. Но учтите, что слишком много "
+"больших изображений в коллекции могут ухудшить производительность."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "&Associate's ID: "
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr "Associate's ID нужен для доступа ко многим сервисам Amazon.com"
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr "Сервер z39.50"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr "Использовать предустановленный с&ервер:"
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "&База данных: "
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr "Введите название базы данных, используемой сервером."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "&Кодировка:"
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Введите кодировку, используемую сервером z39.50. Скорее всего, вам подойдёт "
+"MARC-8, но также попробуйте ISO-8859-1 или CP1251."
+
+#: fetch/z3950fetcher.cpp:550
+msgid "&Format: "
+msgstr "&Формат: "
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr "Авто-выбор"
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+"Выберите формат данных, используемый сервером z39.50. Tellico попробует "
+"автоматически определить настройки, если отмечен <i>авто-выбор</i>."
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "П&ользователь: "
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Необязательно"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Введите имя пользователя, используемое базой данных z39.50. Для большей "
+"части серверов ничего вводить не нужно."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "Па&роль"
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Введите пароль для доступа к базе данных z39.50. Для больше части "
+"серверов ничего вводить не нужно. Пароль будет сохранен в неизменном виде "
+"конфигурационном файле Tellico."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr "Иллюстратор"
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Внешнее приложение"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "&Тип коллекции: "
+
+#: fetch/execexternalfetcher.cpp:351
+msgid "Set the collection type of the data returned from the external application."
+msgstr "Выберите тип данных коллекции, предоставляемых внешним приложением"
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr "Тип &результата: "
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr "Выберите тип данных результатов, предоставляемых внешним приложением"
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "&Путь к приложению"
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+"Введите путь у приложению, которое должно предоставлять правильный файлы "
+"данных Tellico."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr "Выберите ключи поиска, поддерживаемые источником данных"
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+"Добавьте аргументы, которые могут понадобиться. <b>%1</b> будет заменено "
+"результатом поиска."
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr "Аргументы"
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+msgid "Update"
+msgstr "Обновить"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+"<p>Введите аргументы, которые следует использовать для поиска возможных "
+"обновлений.</p><p>Формат должен быть таким же, как и <i>\"зависимые\"</i> "
+"поля, где значение поля заключено в кавычки, как <i>%{author}</i>. Подробнее "
+"смотрите в документации.</p>"
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Опции источника"
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr "Доступные поля"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "База данных фильмов в Интернете (IMDb)"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Выберите результат IMDb"
+
+#: fetch/imdbfetcher.cpp:581
+msgid "<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+"<qt>Ваш поиск дал несколько результатов. Пожалуйста, выберите один из них.</"
+"qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Выберите результат поиска.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr "Ссылка IMDb"
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Альтернативные названия"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+msgid "IMDB Rating"
+msgstr "Рейтинг IMDb"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Сертификаты"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"IMDb использует различные серверы. Пожалуйста, выберите тот, который вы "
+"хотите использовать."
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr "&Максимальное кол-во актеров:"
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+"Список актёров может содержать много людей. Введите максимальное число "
+"актеров, возвращаемое поиском."
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr "Скачать изображение &обложки"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr "Интернет-магазин книг (ibs.it)"
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Человек"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr "UPC/EAN"
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Ключевые слова"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr "arXiv ID"
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr "Pubmed ID"
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Необработанный запрос"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr "Оригинальный заголовок"
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr "Распространитель"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr "Эпизоды"
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr "arXiv.org"
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr "Для %1 необходим логин и пароль."
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+"CrossRef требует регистрацию для доступа. Прочтите лицензию и <a "
+"href='http://www.crossref.org/requestaccount/'>зарегистрируйтесь</a>. "
+"Введите вашу информацию аккаунта OpenURL ниже."
+
+#: fetch/crossreffetcher.cpp:343
+msgid "&Username: "
+msgstr "П&ользователь: "
+
+#: fetch/crossreffetcher.cpp:348
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+"Введите пароль для доступа к базе данных z39.50. Пароль будет сохранен в "
+"неизменном виде конфигурационном файле Tellico."
+
+#: fetch/crossreffetcher.cpp:354
+msgid "&Password: "
+msgstr "Па&роль: "
+
+#: fetch/gcstarpluginfetcher.cpp:190
+msgid "GCstar Plugin"
+msgstr "Дополнение GCstar"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr "Выберите тип данных коллекции, которые экспортирует дополнение."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr "&Дополнение:"
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr "Выберите дополнение GCStar, используемое для источника данных."
+
+#: fetch/gcstarpluginfetcher.cpp:420
+msgid "Author: "
+msgstr "Автор: "
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr "Аудио-поиск Discogs"
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr "&Ключ API: "
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+"При регистрации на discogs.com вы получаете ключ API для использования их "
+"XML-интерфейса (см. http://www.discogs.com/help/api)."
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr "Ссылка Discogs"
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr "Get Hot New Stuff"
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr "Версия"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr "Загрузки"
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr "Дата выпуска"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+"Это список всего, что возможно загрузить. Установленное ранее отмечено "
+"галочкой, а то, что можно обновить отмечено значком обновления."
+
+#: newstuff/dialog.cpp:137
+msgid "The name and license of the selected item"
+msgstr "Название и лицензия выбранного."
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr "Автор выбранного."
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr "Установить"
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr "Загрузить и установить выбранное."
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+"Загрузить и установить выбранный скрипт. Некоторые скрипты могут потребовать "
+"настройки после установки."
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr "Описание выделенного отображается здесь."
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr "Загрузка информации..."
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Готово."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr "Обновить"
+
+#: newstuff/dialog.cpp:413
+msgid "Installing item..."
+msgstr "Установка...."
+
+#: translators/bibteximporter.cpp:79
+msgid "No valid bibtex entries were found"
+msgstr "Не найдено правильных записей bibtex"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "Не найдено правильных записей bibtex в этом файле - %1"
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Опции Bibtex"
+
+#: translators/bibteximporter.cpp:287
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Использовать кодировку Юникод (UTF-8)"
+
+#: translators/bibteximporter.cpp:288
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Читать файл в Юникоде (UTF-8)"
+
+#: translators/bibteximporter.cpp:289
+msgid "Use user locale (%1) encoding"
+msgstr "Использовать системную кодировку (%1)"
+
+#: translators/bibteximporter.cpp:293
+msgid "Read the imported file in the local encoding."
+msgstr "Читать файл в системной кодировке."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "ZIP-файл Tellico"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Файлы Tellico (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Все файлы"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>Библиотека Alexandria <i>%1</i> уже существует. Любая существующая книга "
+"в этой библиотеке может быть переписана.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "Произошла ошибка считывания XML в строке%1, столбце %2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "Ошибка QT:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Это из будущей версии Tellico."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Вы пытаетесь импортировать информацию из файлов, созданных более ранними "
+"версиями Tellico. Это может привести к потере данных, если вы снова "
+"попытаетесь открыть это старой версией Tellico."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Неизвестно"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "Файл пуст."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "Файл не содержит данных коллекций."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Непрочитанные книги"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Старые фильмы"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "Музыка 80-х"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Избранное"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Сканируются аудио-файлы..."
+
+#: translators/audiofileimporter.cpp:129
+msgid "Bitrate"
+msgstr "Битовый поток"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr "Дорожки (Диск %1)"
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(различ.)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Опции аудио-файла"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Рекурсивный поиск по &папкам"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr "Если отмечено, то поиск будет производиться также и вглубь папок."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr "&Включать местоположение файлов"
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr "Если отмечено, имена файлов каждой дорожки будут добавлены в записи."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr "Включать &битовый поток"
+
+#: translators/audiofileimporter.cpp:353
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr "Если отмечено, битовый поток (битрейт) каждой дорожки будет добавлен в записи."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|Файлы CSV (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "Опции CSV"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Вместе с заголовками столбцов"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr "Если отмечено, то будет добавлена первая строка в качестве заголовка"
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Ограничитель"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"Помимо запятой, другие знаки могут быть использованы в качестве "
+"ограничителей, разделяя записи в файле."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Запятая"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Использовать запятую как разделитель."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Точка с запятой"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Использовать точку с запятой как разделитель."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Табуляция"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Использовать табуляцию как разделитель."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Другой"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Использовать другой разделить."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr "Может быть использован любой другой разделитель (например, двоеточие)."
+
+#: translators/filelistingimporter.cpp:63
+msgid "Scanning files..."
+msgstr "Сканируются файлы..."
+
+#: translators/filelistingimporter.cpp:191
+msgid "File Listing Options"
+msgstr "Опции импорта файлов"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr "Рекурсивный поиск по папкам"
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr "Если отмечено, будет произведен рекурсивный поиск по папкам."
+
+#: translators/filelistingimporter.cpp:198
+msgid "Generate file previews"
+msgstr "Создавать значки файлов"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+"Если отмечено, то будут создаваться значки файлов (например, уменьшенные "
+"копии фотографий)."
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "Архив ONIX"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.zip|Файлы ZIP (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "Опции архива ONIX"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Включать изображения в архив"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr "Если отмечено, то изображения в документе будут включены в ZIP-архив ONIX."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr "<qt>Tellico не удается получить доступ к устройству CD-ROM - <i>%1</i>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+msgid "Select CDDB Entry"
+msgstr "Выбрать запись CDDB"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr "Выберите запись CDDB:"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>Ничего, связанного с этим CD не найдено.</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "<qt>Tellico не удалось завершить сканирование CD.</qt>"
+
+#: translators/freedbimporter.cpp:470
+msgid "Various"
+msgstr "Различ."
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Опции Audio CD"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Прочитать данные с CD-ROM"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Выберите или введите адрес вашего устройства CD-ROM"
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Читать только кешированные файлы CDDB"
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr "Рекурсивно читать данные из всех стандартных папок для кеша CDDB."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr "GCfilms"
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.gcf|Файлы GCfilms (*.gcf)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.gcs|Файлы GCstar (*.gcs)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "Опции XSLT"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "Файл XSLT:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr ""
+"Выберите файл XSLT, который будет использоваться для перевода в формат "
+"Tellico XML."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Опции Alexandria"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr "&Библиотека:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "Bibtexml"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Файлы Bibtexml (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|Файлы XML (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Опции XML (Tellico)"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Включать изображения в файл XML"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Если отмечено, то изображения из документа будут включены в файл XML как "
+"зашифрованные base64 элементы."
+
+#: translators/importer.h:100
+msgid "Loading data..."
+msgstr "Загружаются данные..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr "Загружается %1..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "Bibtex"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Файлы Bibtex (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Увеличить строку для макросов"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Если отмечено, то строка для макросов будет увеличена и записи @string{} "
+"будут записаны"
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Использовать пакет URL"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr "Если отмечено, то любые поля URL будут записаны как \\url."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Пропустить поля без ключа цитирования"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr "Если отмечено, то любые поля без ключа цитирования bebtex будут пропущены."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Стиль цитирования bibtex:"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Связи"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Цитаты"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr "<qt>При экспорте будет использоваться стиль цитирования bibtex.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Выберите тип импортируемой коллекции."
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr "П&ервая строка содержит заголовки полей"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr "Если отмечено, первая строка будет использоваться для заголовков полей."
+
+#: translators/csvimporter.cpp:248
+msgid "&Comma"
+msgstr "&Запятая"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr "&Точка с запятой"
+
+#: translators/csvimporter.cpp:259
+msgid "Ta&b"
+msgstr "Т&абуляция"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr "&Другой:"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "Таблица показывает первые 5 строк файла CSV."
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> button.</"
+"qt>"
+msgstr ""
+"<qt>Вы можете назначить каждому столбцу своё поле. Просто выделите поле, "
+"столбец и нажмите на кнопку <i>Назначить поле</i>.</qt>"
+
+#: translators/csvimporter.cpp:298
+msgid "Co&lumn:"
+msgstr "&Столбец"
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr "Д&анные в этом столбце:"
+
+#: translators/csvimporter.cpp:315
+msgid "&Assign Field"
+msgstr "&Назначить поле"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+"Как минимум одна колонка должна быть присвоена к полю. Только присвоенные "
+"колонки будут импортированы."
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Новое поле"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|Файлы базы данных Pilot (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Показывать столбцы"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "Опции PilotDB"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Установить флаг бэкапа PDA для базы данных"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>Этот файл - не файл данных GCstar.</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Произошла ошибка при чтении XSLT."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "Для импорта нужен правильный файл XSLT."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|Файлы XSL (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|Файлы HTML (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Люди"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(сгруппировано по %1)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "Опции HTML"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Включить заголовки полей"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr ""
+"Если отмечено, то при экспорте в HTML названия полей будут напечатаны как "
+"заголовки таблицы."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Группировать записи"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr "Если отмечено, то записи будут сгруппированы по выделенному полю."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Экспорт каждой записи в отдельный файл"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr "Если отмечено, то каждая запись будет выводиться в отдельный файл."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Не удалось прочитать метаданные из файла PFG."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+"Tellico может загрузить информацию о записях с DOI из CrossRef.org. Для "
+"этого вам необходимо зарегистрироваться на CrossRef и добавить новый "
+"источник данных, использую регистрационную информацию."
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Свойства источника данных"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "Н&азвание источника"
+
+#: fetcherconfigdialog.cpp:79
+msgid "The name identifies the data source and should be unique and informative."
+msgstr ""
+"Название идентифицирует источник данных и должно быть уникальным и "
+"информативным."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "&Тип источника"
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr "Tellico поддерживает различные источники данных."
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr "Заменять пользовательские данные."
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Если отмечено, то обновляемые записи будут заменять любую существующую "
+"информацию."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Любое поле"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "содержит"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "не содержит"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "равно"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "не равно"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "соответствует выражению"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "не соответствует выражению"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Редактировать..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Продвинутый фильтр"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Критерии фильтра"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Соответствует &всему следующему"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Соответствует &любому из следующего"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Название фильтра:"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "С&охранить фильтр"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Простой текст"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Большой текст"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Выбор"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Выбор да/нет"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Таблица"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Зависимость"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Дата"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr "Обновление %1..."
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr "Обновление записей..."
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr "Обновить записи"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr "Обновление <b>%1</b>..."
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr "Выберите результат"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+"<qt><b>%1</b> дал несколько результатов, которые могут соответствовать <b>%"
+"2</b>, текущей записи в коллекции. Выберите правильный результат.</qt>"
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Развернуть все группы"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Свернуть все группы"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Фильтр по группе"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (сортировка по кол-ву)"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Группа"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Опции импорта"
+
+#: importdialog.cpp:62
+msgid "&Replace current collection"
+msgstr "&Заменить текущую коллекцию"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr "Заменить текущую коллекцию содержимым импортируемого файла."
+
+#: importdialog.cpp:65
+msgid "A&ppend to current collection"
+msgstr "&Добавить к текущей коллекции"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Добавить всё содержание импортируемого файла к текущей коллекции. Это "
+"возможно только в том случае, если типы коллекций совпадают."
+
+#: importdialog.cpp:69
+msgid "&Merge with current collection"
+msgstr "&Объединить с текущей коллекцией"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Добавить только те записи, которых нет в текущей коллекции. Возможно только "
+"в том случае, если типы коллекций совпадают."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Импорт"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|Файлы RIS (*.ris)"
+
+#: importdialog.cpp:277
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.gcf|Файлы AMC (*.amc)"
+
+#: importdialog.cpp:281
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdb|Файлы PDF (*.pdb)"
+
+#: importdialog.cpp:285
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.ris|Файлы Referencer (*.ris)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Не удается открыть файл - %1."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Не удается записать файл - %1."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Не удается загрузить файл - %1."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Добавлять информацию можно только из коллекции такого же типа. Никаких "
+"изменений не произведено."
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Объединять информацию можно только с коллекцией такого же типа. Никаких "
+"изменений не произведено."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Не удается загрузить изображение из файла - %1."
+
+#: entryiconview.cpp:287
+msgid "&Sort By"
+msgstr "&Сортировать по"
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Отдать в долг"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "Следующее будет отдано в долг:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "Следующее дано взаймы:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "До&лжник:"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Введите имя человека, которому вы дали долг. Если хотите выбрать человека из "
+"вашей адресной книги, нажмите на кнопку."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "&Дата дачи в долг:"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr "Дата, когда предмет был отдан в долг. По умолчанию используется текущая дата."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "Д&ата возвращения:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"Дата возвращения - это дата, когда долг должны вернуть. Дата истечения срока "
+"долга необязательна, если только вы не хотите внести долг в ваш органайзер."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Заметки:"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "Вы можете добавить кое-какие сведения для себя."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "Д&обавить напоминание."
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"<qt>Если отмечено, запись о долге будет добавлена в календарь KOrganizer</"
+"qt> "
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Создать новую коллекцию"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Новая коллекция &книг"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Создать новую коллекцию книг"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Новая &библиография"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Создать новую библиографию bibtex"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Новая коллекция к&омиксов"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Создать новую коллекцию комиксов"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Новая коллекция &фильмов"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Создать новую коллекцию фильмов"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Новая коллекция &музыки"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Создать новую коллекцию музыки"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Новая коллекция &монет"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Создать новую коллекцию монет"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Новая коллекция ма&рок"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Создать новую коллекцию марок"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Новая коллекция к&арточек"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Создать новую коллекцию карточек"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Новая коллекция &вин"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Создать новую коллекцию вин"
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Новая коллекция &игр"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Создать новую коллекцию игр"
+
+#: mainwindow.cpp:272
+msgid "New Boa&rd Game Collection"
+msgstr "Новая коллекция настольных &игр"
+
+#: mainwindow.cpp:274
+msgid "Create a new board game collection"
+msgstr "Создать новую коллекцию настольных игр"
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr "Новый каталог &файлов"
+
+#: mainwindow.cpp:282
+msgid "Create a new file catalog"
+msgstr "Создать новый каталог файлов"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Новая коллекция (&прочее)"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Создать новую нестандартную коллекцию"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Открыть существующий документ"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Открыть недавно использовавшийся файл"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Сохранить документ"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Сохранить документ в другой файл..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Напечатать содержимое этого документа..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Выйти из программы"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Импортировать коллекцию из других форматов"
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Импорт из файла Tellico..."
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Импортировать из другой коллекции Tellico"
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "Импорт из CSV..."
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Импорт из файла CSV"
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "Импорт из MODS..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Импорт из файла MODS"
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Импорт из файла Alexandria..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Импорт из менеджера коллекций книг Alexandria"
+
+#: mainwindow.cpp:352
+msgid "Import Delicious Library Data..."
+msgstr "Импорт из файла Delicious..."
+
+#: mainwindow.cpp:353
+msgid "Import data from Delicious Library"
+msgstr "Импорт данных из файла Delicious"
+
+#: mainwindow.cpp:359
+msgid "Import Referencer Data..."
+msgstr "Импорт из файла Referencer..."
+
+#: mainwindow.cpp:360
+msgid "Import data from Referencer"
+msgstr "Импортировать данные из Referencer"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Импорт из Bibtex..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Импортировать из файла библиографии bibtex"
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Импорт из Bibtexml..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Импортировать из файла библиографии Bibtexml"
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "Импорт из RIS..."
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Импортировать из файла RIS"
+
+#: mainwindow.cpp:387
+msgid "Import PDF File..."
+msgstr "Импорт из PDF..."
+
+#: mainwindow.cpp:388
+msgid "Import a PDF file"
+msgstr "Импортировать из файла PDF"
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Импорт из данных аудио файла..."
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Импорт из данных тегов аудио файлов"
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Импорт из Audio CD..."
+
+#: mainwindow.cpp:405
+msgid "Import audio CD information"
+msgstr "Импорт информации об Audio CD"
+
+#: mainwindow.cpp:414
+msgid "Import GCstar Data..."
+msgstr "Импорт из файла GCstar..."
+
+#: mainwindow.cpp:415
+msgid "Import a GCstar data file"
+msgstr "Импорт данных из файла GCstar"
+
+#: mainwindow.cpp:421
+msgid "Import Griffith Data..."
+msgstr "Импорт из файла Griffith..."
+
+#: mainwindow.cpp:422
+msgid "Import a Griffith database"
+msgstr "Импортировать из файла Griffith"
+
+#: mainwindow.cpp:428
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Импорт из файла Ant..."
+
+#: mainwindow.cpp:429
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Импортировать из файла менеджера коллекций фильмов Ant"
+
+#: mainwindow.cpp:435
+msgid "Import File Listing..."
+msgstr "Импорт списка фалов..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr "Импортировать информацию о файлах в папке"
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "Импорт из XSLT..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Импорт, используя XSLT"
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Экспорт"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Экспортировать данные коллекции в другой формат"
+
+#: mainwindow.cpp:461
+msgid "Export to XML..."
+msgstr "Экспорт в XML..."
+
+#: mainwindow.cpp:462
+msgid "Export to a Tellico XML file"
+msgstr "Экспорт в XML-файл Tellico"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Экспорт в ZIP..."
+
+#: mainwindow.cpp:469
+msgid "Export to a Tellico Zip file"
+msgstr "Экспорт в сжатый ZIP файл Tellico"
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "Экспорт в HTML..."
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Экспорт в файл HTML"
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "Экспорт в CSV..."
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Экспорт в текстовый файл с разделёнными запятыми данными"
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "Экспорт в PilotDB..."
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Экспортировать в базу данных PilotDB"
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Экспорт в Alexandria..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Экспорт в библиотеку Alexandria"
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Экспорт в Bibtex..."
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Экспорт в файл Bibtex"
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Экспорт в Bibtexml..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Экспорт в файл Bibtexml"
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "Экспорт в ONIX..."
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Экспорт в файл ONIX"
+
+#: mainwindow.cpp:524
+msgid "Export to GCfilms..."
+msgstr "Экспорт в GCfilms..."
+
+#: mainwindow.cpp:525
+msgid "Export to a GCfilms data file"
+msgstr "Экспорт в файл GCfilms"
+
+#: mainwindow.cpp:531
+msgid "Export to GCstar..."
+msgstr "Экспорт в GCStar..."
+
+#: mainwindow.cpp:532
+msgid "Export to a GCstar data file"
+msgstr "Экспорт в файл GCfilms"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "Экспорт в XSLT..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Экспорт, используя XSLT"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Вырезать выделенный текст и поместить его в буфер обмена"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Копировать выделенный текст в буфер обмена"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Вставить содержимое буфера обмена"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Выделить все записи в коллекции"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Отменить выделение записей в коллекции"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Поиск в интернете..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Повести поиск в интернете для создания новой записи в коллекции..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "Продвинутый &фильтр..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Фильтр коллекции"
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&Новая запись..."
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Создать новую запись"
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "&Редактировать запись..."
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Редактировать выделенное записи"
+
+#: controller.cpp:621 mainwindow.cpp:577
+msgid "D&uplicate Entry"
+msgstr "&Дублировать запись"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Копировать выделенные записи"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "&Удалить запись"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Удалить выделенные записи"
+
+#: mainwindow.cpp:585
+msgid "&Merge Entries"
+msgstr "О&бъединить записи"
+
+#: mainwindow.cpp:588
+msgid "Merge the selected entries"
+msgstr "Объединить выделенные записи"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "Создать от&чет..."
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Создать отчет о коллекции"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "&Отдать в долг..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Отдать выделенные записи в долг"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "&Вернуть из долга"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Вернуть из долга выделенные записи"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "&Переименовать коллекцию..."
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Сменить название коллекции"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "По&ля в коллекции"
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Редактировать поля в коллекции"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "Конвертировать в &библиографию"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Конвертировать коллекцию книг в библиографию"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "Строчный &макрос..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Редактировать строчные макросы bibtex"
+
+#: mainwindow.cpp:626
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Копировать данные Bibtex"
+
+#: mainwindow.cpp:627
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Копировать цитаты bibtex в буфер обмена"
+
+#: mainwindow.cpp:632
+msgid "Cite Entry in &LyX"
+msgstr "Сделать ссылку в &LyX"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Сделать ссылку на выделенные записи в LyX"
+
+#: mainwindow.cpp:638
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Сделать ссылку в &OpenOffice.org"
+
+#: mainwindow.cpp:639
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Сделать ссылку на выделенные записи в OpenOffice.org"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, no-c-format
+msgid "&Update Entry"
+msgstr "&Обновить записи"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr "Все источники"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr "Обновить данные записи из всех возможных источников"
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Показать панель &групп"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Показать/скрыть панель просмотра групп"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Скрыть панель &групп"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Показать редактор &записей"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Показать/скрыть редактор записей"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "Скрыть редактор &записей"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Показать &информацию о записи"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Показать/скрыть информацию о записи"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "Скрыть &информацию о записи"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Изменить способ группировки"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "Выбор &групп"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Изменить способ группировки в коллекции"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Фильтр"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Очистить фильтр"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Фильтр..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Группы"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt>Опция <i>\"Группировать записи\"</i> сортирует записи по выбранному полю."
+"</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each entry."
+"</qt>"
+msgstr ""
+"<qt><i>Вид в столбцах</i> показывает значение нескольких полей для каждой "
+"записи</qt>"
+
+#: mainwindow.cpp:831
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Добро пожаловать в Tellico - менеджер коллекций для KDE."
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+"<h3>Tellico - это менеджер коллекций книг, фильмов, музыки или всего "
+"прочего, что вы только можете вообразить.</h3><h3>Новые записи в "
+"вашей коллекции могут быть созданы <a href=\"tc:///coll_new_entry\">вручную</"
+"a> или путём <a href=\"tc:///edit_search_internet\">загрузки данных</a> из "
+"различных интернет-источников.</h3>"
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Создание нового документа..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Открытие файла..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Открыть файл"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Сохранение файла...."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+"<qt><p>Вы пытаетесь сохранить файл с большим количеством изображений. Это "
+"может замедлить скорость работы Tellico и сделает файл очень большим. Вы "
+"хотите сохранить изображения в директории Tellico (в файл будут записаны "
+"только \"текстовые\" данные)?</p></qt>"
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr "Сохранять изображения отдельно"
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr "Сохранять изображения вместе с файлом"
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Сохранение файла под другим именем..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Идёт печать..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"В настоящий момент к коллекции применен фильтр и будут напечатаны только "
+"видимые поля. Продолжить?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Подождите..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Выход..."
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Всего записей: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 отфильтровано; %2 выделено)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 отфильтровано)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 выделено)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Печать %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Страница %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Пожалуйста, проверьте свою инсталляцию."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Импорт данных..."
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Импорт файла"
+
+#: mainwindow.cpp:1864
+msgid "Import Directory"
+msgstr "Импорт каталога"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Экспортирование данных..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Экспорт как"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Строчный макрос"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Макрос"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Строка"
+
+#: mainwindow.cpp:1999
+msgid "Creating citations..."
+msgstr "Идет создание цитат..."
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Фильтры"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter rules."
+"</qt>"
+msgstr ""
+"<qt><i>Вид по фильтру</i> показывает записи согласно примененному фильтру.</"
+"qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Долги"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt><i>Вид должников</i> показывает людей, которые что-то взяли в долг из "
+"вашей коллекции.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr "Обновить данные записи из %1"
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr "Можно импортировать только один файл за раз. Будет импортирован только %1."
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Не удается загрузить изображение - %1."
+
+#: filehandler.cpp:207
+msgid "A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr "Файл под названием \"%1\" уже существует. Вы хотите переписать его?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Переписать файл?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Переписать"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Фильтр (сортировка по кол-ву)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Вы действительно хотите удалить эту запись?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Удалить запись"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Вы действительно хотите удалить эти записи?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Удалить несколько записей"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "&Редактировать записи..."
+
+#: controller.cpp:627
+msgid "D&uplicate Entries"
+msgstr "&Дублировать записи"
+
+#: controller.cpp:628
+msgid "&Update Entries"
+msgstr "&Обновить записи"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "&Удалить записи"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr "Эти вещи уже были отданы в долг."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Календарь по умолчанию"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"В данный момент Tellico поддерживает только календарь, находящийся на "
+"локальном компьютере. Текущий календарь находится не здесь, так что ваши "
+"долги не будут занесены в него."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Текущий календарь"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 возвратил \"%2\""
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(пусто)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - менеджер коллекций для KDE."
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Не открывать ещё раз последний открытый файл"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Импортировать <filename> как файл bibtex"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Импортировать <filename> как файл MODS"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Импортировать <filename> как файл RIS"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Файл для открытия"
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr "Скрипты источников данных"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Пиктограммы"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Автор библиотеки btparse"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr "Примеры кода и вдохновение вообще"
+
+#: main.cpp:50
+msgid "Author of libcsv library"
+msgstr "Автор библиотеки libcsv"
+
+#: main.cpp:52
+msgid "Author of rtf2html library"
+msgstr "Автор библиотеки rtf2html"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Поля коллекции"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Текущие поля"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "&Новое"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Добавить новое поле в коллекцию"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "&Удалить"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Удалить поле из коллекции"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr "Переместить поле вверх на одну позицию."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr "Переместить поле вниз на одну позицию."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Параметры поля"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "Н&азвание:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "Название поля"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "Т&ип:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "Тип коллекции определяет, какие значения могут быть использованы. "
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "<i>Простой текст</i> используется в большинстве случаев."
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "<i>Большой текст</i> используется для записи больших объемов текста. "
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Выбор</i> создает поле для выбора фиксированных значений. "
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr ""
+"<i>Выбор да/нет</i> создает поле для простого установления значения \"да\" "
+"или \"нет\". "
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr "<i>Номер</i> используется для записи числового значения. "
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr "<i>URL</i> используется для записи ссылок, включая ссылки на другие поля."
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr "<i>Таблица</i> создает поле для записи информации в формате таблицы. "
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "<i>Изображение</i> используется для помещения изображений в коллекцию "
+
+#: collectionfieldsdialog.cpp:144
+msgid "A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr "<i>Дата</i> используется для создания полей с днем, месяцем и годом. "
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+"<i>Рейтинг</i> создает поле со звёздочками для определения личного "
+"рейтинга. "
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr "<i>Зависимость</i> создает поле, которое зависит от других полей."
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"<i>Только для чтения</i> - для записи внутренних значений, полезно при "
+"импорте и экспорте."
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "Кат&егория:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr "Категория поля определяет, куда поле будет помещено в редакторе."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "&Описание:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"Описание полезно для сообщения о том, что должно содержать это поле. Для "
+"типа <i>Зависимость</i> описание должно быть такого вида: \"%{year} &{title}"
+"\", где имена полей заменяются согласно вашим нуждам."
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr "&Значение по умолчанию:"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr "<qt>Для новых полей может быть выбрано значение по умолчанию.</qt>"
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr "&Допустимые значения:"
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>Сюда вводятся допустимые значения для поля типа <i>\"Выбор\"</i>. "
+"Значения разделяются запятой (напр. \"Кошка; Собака; Таракан\")</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "Дополнительные &параметры:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "&Установить..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"Дополнительные параметры поля полезны для некоторых специфических вещей. "
+"Например, для соответствующего поля bibtex."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Опции форматирования"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Нет форматирования"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr "Эта опция запрещает автоматическое форматирование."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Разрешить только явное форматирование"
+
+#: collectionfieldsdialog.cpp:231
+msgid "This option allows the field to be capitalized, but not specially formatted."
+msgstr "Эта опция разрешает только автоматическое применение заглавных букв."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Форматировать как заголовок"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Это опция форматирует поля как заголовок, но только если эти опции "
+"установлены глобально."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Форматировать как название"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Эта опция форматирует поля, как заголовки, но только если эти опции "
+"установлены глобально."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Опции поля"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Автоматическое дополнение"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr "Автоматически дополнять до слова (как в OpenOffice.org)"
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Разрешить несколько значений"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Если отмечено, Tellico будет использовать несколько значений из одного поля "
+"при разделении запятыми."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Разрешить группировку"
+
+#: collectionfieldsdialog.cpp:249
+msgid "If checked, this field may be used to group the entries in the group view."
+msgstr "Если выбрано, по этому полю можно будет проводить группировку."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr "Изменить свойства выбранного поля на свойства по умолчанию."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Редактировать поля"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Перемещение значений из поля \"<i>%1</i>\", которое уже существует может "
+"повредить ваши данные. Вы хотите оставить модифицированные данные или "
+"отменить и вернуться к текущим?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Сохранить измененные значения"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Вернуть свойства поля"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Вы действительно хотите вернуть полю <em>\"%1\"</em> свойства, "
+"назначенные по умолчанию?"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Вернуть"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Дополнительные свойства поля"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr "Поле с таким названием уже существует. Пожалуйста, введите другое название."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr "<qt>Эта категория может быть не пустой. Пожалуйста, выберите категорию.</qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different category.</"
+"qt>"
+msgstr ""
+"<qt>Поле не может иметь категории: <em>\"Большой текст\" </em>, <em>\"Таблица"
+"\"</em> или <em>\"Изображение\"</em>. Выберите другую категорию.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"Название поля не может быть таким же, как название категории. Введите "
+"другое название."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr "Рамки рейтинга должны лежать между 1 и 10 и меньший порог должен быть иметь значение ниже большего. Введите другие значения."
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "В таблице может быть максимум десять столбцов."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Текущий файл был изменен.\n"
+"Вы хотите сохранить его?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Не сохраненные изменения"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Выбрать должника"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Настроить Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Общие"
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr "&Открывать файл заново при старте"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program start-"
+"up."
+msgstr "Если отмечено, то последний файл будет заново открываться при старте."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "&Показывать \"совет дня\" при старте"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr "Если отмечено, при запуске программы будет появляться \"совет дня\""
+
+#: configdialog.cpp:213
+msgid "Image Storage Options"
+msgstr "Опции хранения изображений"
+
+#: configdialog.cpp:214
+msgid "Store images in data file"
+msgstr "Хранить изображения в файле данных"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr "Хранить изображения в папке программы"
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr "Хранить изображения в папке с файлом данных"
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+"Изображения могут быть сохранены и в файле Tellico, но это может привести к "
+"потере производительности."
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Опции форматирования"
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr "Автоматическое использование &заглавных букв в именах и названиях"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Если отмечено, каждое слово в именах и названий будет автоматически "
+"начинаться с заглавной буквы."
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr "Автоматическое &форматирование имён и названий"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr "Если отмечено, имена и названия будут автоматически форматироваться."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr "Не ставить з&аглавные буквы:"
+
+#: configdialog.cpp:243
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Список слов, которые не должны начинаться с большой буквы.Значения "
+"должны разделяться точкой с запятой</qt>"
+
+#: configdialog.cpp:249
+msgid "Artic&les:"
+msgstr "Арти&кли:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a semi-colon.</"
+"qt>"
+msgstr ""
+"<qt>Список слов, которые будут рассмотрены как артикли, если они являются "
+"первым словом в названии. Значения должны разделяться точкой с запятой.</qt>"
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr "Личные &обращения: "
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Список личных суффиксов (jr, мл. и т.д.). Значения должны разделяться "
+"точкой с запятой.</qt>"
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr "Приставки фа&милий:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Список приставок фамилий (de, van и т.д.). Значения должны разделяться "
+"точкой с запятой</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Печать"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Опции печати"
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr "&Форматировать имена и названия"
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr "&Включить заголовки полей"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Опции группировки"
+
+#: configdialog.cpp:313
+msgid "&Group the entries"
+msgstr "&Группировать записи"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Опции изображений"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr "Максимальная &ширина изображения:"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Максимальная ширина изображения при отображении. Соотношение сторон "
+"сохраняется."
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr "Максимальная &высота изображения:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Максимальная высота изображения при отображении. Соотношение сторон "
+"сохраняется."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Шаблоны"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Опции шаблонов"
+
+#: configdialog.cpp:369
+msgid "Template:"
+msgstr "Шаблон:"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+"Выберите шаблон для использования в текущем типе коллекций. Не все шаблоны "
+"будут использовать настройки шрифта и цвета."
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr "&Пред-просмотр..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr "Показать пред-просмотр шаблона"
+
+#: configdialog.cpp:398
+msgid "Font Options"
+msgstr "Опции шрифтов"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr "Шрифт:"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr "Этот шрифт используется в просмотре записей."
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr "Размер: "
+
+#: configdialog.cpp:425
+msgid "Color Options"
+msgstr "Опции цветов"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr "Цвет фона:"
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr "Этот цвет используется при просмотре записей."
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr "Цвет текста:"
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr "Цвет подсветки:"
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr "Цвет подсвеченного текста:"
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr "Управление шаблонами"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr "Установить..."
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr "Нажмите для установки шаблона."
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr "Загрузить..."
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr "Нажмите для загрузки дополнительных шаблонов из интернета."
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr "Удалить..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr "Нажмите для выбора и удаления шаблонов."
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Источники данных"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Опции источников данных"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Источник"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr "&Выше"
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+"Приоритет источников данных которые будут использоваться для автоматического "
+"обновления."
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr "&Ниже"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "&Новый..."
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr "Нажмите для создания нового источника данных."
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Редактировать..."
+
+#: configdialog.cpp:533
+msgid "Click to modify the selected data source."
+msgstr "Нажмите для изменения выбранного источника данных."
+
+#: configdialog.cpp:536
+msgid "Click to delete the selected data source."
+msgstr "Нажмите для удаления выбранного источника данных."
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr "Нажмите для загрузки дополнительных источников данных из интернета."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr "*.tar.gz *.tgz|Пакет шаблона (*.tar.gz)"
+
+#: configdialog.cpp:1049
+msgid "Delete Template"
+msgstr "Удалить шаблон"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr "Выберите шаблон для удаления:"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "Должник"
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Вернуть из долга"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Редактировать долг..."
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "Должник (сортировка по кол-ву)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "Моя коллекция"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Коллекция книг"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Коллекция комиксов"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Коллекция фильмов"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Коллекция музыки"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Коллекция монет"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Коллекция марок"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Коллекция вин"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Коллекция карточек"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Коллекция игр"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr "Файловый каталог"
+
+#: collectionfactory.cpp:135
+msgid "Board Game Collection"
+msgstr "Коллекция настольных игр"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Коллекция (проч.)"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's contents.</"
+"qt>"
+msgstr ""
+"<qt><i>Информация о записях</i> показывает информацию о записи в "
+"форматированном виде.</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt><i>\"Изображения\"</i> - это способ показа записей, использую их "
+"изображения (напр., обложки) как пиктограммы</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Опции экспорта"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Форматирование"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Форматировать все поля"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Если отмечено, то значения полей будут автоматически отформатированы "
+"согласно их типам."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Экспорт только выделенных записей"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr "Если отмечено, то экспортированы будут только выделенные записи."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Кодировка"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Юникод (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Экспорт в юникоде (UTF-8)"
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Системная кодировка (%1)"
+
+#: exportdialog.cpp:72
+msgid "Encode the exported file in the local encoding."
+msgstr "Экспорт в системной кодировке."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "&Поиск"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "С&топ"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Поиск в интернете"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Очередь поиска"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr "П&оиск:"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr "Введите значение поиска. Поиск по ISBN должен включать полный ISBN."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Выберите тип поиска"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Нажмите для начала поиска"
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr "&Многократный поиск по ISBN/UPC"
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr "Если отмечено, будет проведен многократный поиск по значениям ISBN или UPC"
+
+#: fetchdialog.cpp:138
+msgid "Edit List..."
+msgstr "Редактировать список..."
+
+#: fetchdialog.cpp:140
+msgid "Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+"Нажмите для открытия окна редактирования текста или редактирования "
+"нескольких значений ISBN"
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "&Источник поиска:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Выберите базу данных для поиска:"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr "Если результаты будут найдены, то они будут добавлены в список."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr "Запись может быть показана здесь до добавления в текущую коллекцию."
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "&Добавить запись"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Добавить запись в текущую коллекцию"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr "Больше результатов"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr "Загрузить ещё результаты из выбранного источника"
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Очистить все поля поиска и результаты"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Отмена поиска..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Поиск..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "Поиск не дал результатов"
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+"Поиск дал 1 результат.\n"
+"Найдено %n."
+
+#: fetchdialog.cpp:412
+msgid "No results were found for the following ISBN values:"
+msgstr "Никаких записей не было найдено по следующим номерам ISBN:"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Загрузка %1..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr "Нет доступных интернет-источников для типа вашей текущей коллекции"
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr "Редактировать значения ISBN/UPC"
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Введите значения ISBN/UPC, по одному в строку.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "&Загрузить из файла..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Загрузить список из текстового файла.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>Поиск по ISBN может содержать максимум 100 значений ISBN. Будут "
+"использованы только 100 первых значений.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Редактировать запись"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Новая запись"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "&Сохранить запись"
+
+#: entryeditdialog.cpp:77
+msgid "Go to the previous entry in the collection"
+msgstr "Вернуться к предыдущей записи в коллекции"
+
+#: entryeditdialog.cpp:82
+msgid "Go to the next entry in the collection"
+msgstr "Перейти к следующей записи в коллекции"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Вы действительно хотите изменить эти записи?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Редактировать несколько записей"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr "Для следующий полей необходимо значение. Хотите продолжить?"
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Редактировать записи"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "&Сохранить записи"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"Текущие записи были изменены.\n"
+"Вы хотите сохранить изменения?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Сохранить запись"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Отчёт коллекции"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "&Шаблон отчета:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "&Создать"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr "Выберите шаблон отчета и нажмите <em>Создать</em>"
+
+#: reportdialog.cpp:108
+msgid "Some reports may take several seconds to generate for large collections."
+msgstr ""
+"Создание отчетов больших коллекций может занять некоторое время (до десятков "
+"секунд)."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Вы действительно хотите удалить этот фильтр?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Удалить фильтр?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Новое название коллекции:"
+
+#: tellico_kernel.cpp:377
+msgid "Entry 1"
+msgstr "Запись 1"
+
+#: tellico_kernel.cpp:378
+msgid "Entry 2"
+msgstr "Запись 2"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr "Для %1 были найдены конфликтующие записи при объединении."
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr "Выберите значение."
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+msgid "Merge Entries"
+msgstr "Объединить записи"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr "Выбрать запись из %1"
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr ""
+"Tellico не удается установить местонахождение листа стилей записей по "
+"умолчанию."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Новая"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Коллекция"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Панель коллекции"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Калимуллин Артур, Песоцкий Денис"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "kalimullin@gmail.com, St.MPA3b@gmail.com"
+
+#: entrymerger.cpp:35
+msgid "Merging entries..."
+msgstr "Объединение записей..."
+
+#: entrymerger.cpp:49
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Всего записей объединено/просканировано: %1"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>...что если книга имеет больше, чем одного автора, то вам следует "
+"разделять\n"
+"точкой с запятой (;). Таким образом, Tellico будет разделять их имена.</p>\n"
+"<p>Любое другое поле также поддерживает эту функцию. Для этого вам следует\n"
+"разделять каждые значения точкой с запятой (;).\n"
+"Например: Пушкин;Гоголь.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>...что вы можете выбрать какие поля следует показывать в списке записей,\n"
+"кликнув правой кнопкой мыши на заголовке \"таблицы\".\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>...что вы можете добавлять, редактировать или удалять поля в коллекции,\n"
+"используя Редактор полей. Кнопки стрелок позволяют вам менять позицию полей "
+"в списке,\n"
+"которая влияет на расстановку в Редакторе записей.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>...что если вы хотите отфильтровать записи по полю \"Выбор да/нет\",\n"
+"то должно использоваться значение \"да\". Например, если вы хотите "
+"посмотреть, какие детективы вы ещё не читали,\n"
+"нажмите кнопку \"Соответствует всему следующему\",\n"
+"установите первое правило на \"Жанр\"\n"
+"\"содержит\" \"Детектив\" (без кавычек) и второе правило на \"Прочитана\" "
+"\"Не содержит\" \"Да\" (без кавычек).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>...что если в быстром фильтре используется символ, не входящий в слова "
+"(напр., ^)\n"
+"текст интерпретируется как регулярное выражение.</p>\n"
+"<p>Например, чтобы посмотреть только книги, которые написали Пушкин и "
+"Гоголь,\n"
+"введите \"Пушкин|Гоголь\" (без кавычек) в поле быстрого фильтра.</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>...что за один раз вы можете отредактировать больше, чем одно поле.\n"
+"Для этого выделите несколько полей, зажимая клавиши Shift или Ctrl.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>...что вы можете конвертировать текущую коллекцию книг в библиографию,\n"
+"которая может быть экспортирована в формат Bibtex или Bibtexml.</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for bibliographies.</"
+"p>\n"
+msgstr ""
+"<p>...что вы можете добавлять, редактировать и удалять строковые макросы для "
+"библиографий.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>...что если более чем одно поле форматируется как \"имя\", то в "
+"коллекцию\n"
+"добавляется дополнительная группа \"Люди\", например, для сортировки и "
+"печати вместе.</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>...что вы можете менять внешний вид, печатаемых отчетов, редактируя\n"
+"файл <tt>tellico-printing.xsl</tt>. Этот файл создает HTML и CSS\n"
+"с такими элементами как шрифт, размер и т.д. </p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>...что вы можете импортировать, используя стандартный\n"
+"лист стилей XSL, на выходе получая правильный файл Tellico XML.</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr "<p>...что двойной щелчок на записи открывает редактор записей.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>...что в любое поле типа \"Большой текст\" вы можете добавлять теги HTML, "
+"такие как \n"
+"&lt;b&gt;жирный шрифт&lt;/b&gt; или &lt;i&gt;курсивный&lt;/i&gt;.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>...что в подробном виде вы можете нажать кнопку буквы на клавиатуре для\n"
+"перехода к записи, начинающейся с этой буквы.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+"<p>...что вы можете использовать \"зависимые\" поля для комбинации\n"
+"нескольких раздельных полей в одно. Просто выберите тип \"зависимый\" \n"
+"и используйте описание вроде \"Значение: %{поле1}%{поле2}\", где %{...}\n"
+"заменяется на значение поля. Это полезно для использование различных\n"
+"полей в одном поле, т.е. для лучшей группировки и для комбинации полей\n"
+"различных типов с приоритетом правильной сортировки. Пример -\n"
+"цифровое поле, после которого идёт текст типа 3b, 14a.</p>\n"
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Альбом"
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr "Этот шаблон предназначен только за музыкальных коллекций."
+
+#: xslt.cpp:5
+msgid "Total:"
+msgstr "Всего:"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr "Изящный"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "По умолчанию"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Компактный"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Видео"
+
+#: xslt.cpp:14 xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr "Этот шаблон предназначен только для коллекций фильмов."
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Резюме группы"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Резюме группы"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Всего полей:"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Всего записей:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+msgid "Generated by Tellico"
+msgstr "Создано Tellico"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Точные значения:"
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Изображения"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Долги"
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Дата дачи в долг"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Заметки"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Дата окончания"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Группы"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Список названий (горизонтальный)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Список названий (вертикальный)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Столбцы"
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "В три столбца"
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr "Поиск"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr "Британская библиотека"
+
+#: z3950.cpp:6
+msgid "Sudoc (France)"
+msgstr "Sudoc (Франция)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr "BIBSYS (Норвегия)"
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr "Итальянская национальная библиотека"
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr "Португальская национальная библиотека"
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr "Национальная библиотека Польши"
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr "Национальная библиотека Канады"
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr "Союз списков Израиля (ULI)"
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr "Национальная библиотека Австралии"
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr "Национальная библиотека Литвы"
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr "Copac (Великобритания и Ирландия)"
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr "BoardGameGeek"
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr "Dark Horse Comics"
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr "Allocine.fr"
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr "Испанское министерство культуры"
+
+msgid ""
+"If checked, all images will be included in the data file, rather than saved "
+"separately in the Tellico data directory. Saving a lot of images in the data "
+"file cause Tellico to run more slowly."
+msgstr ""
+"Если отмечено, то изображения будут сохраняться в файле данных Tellico, "
+"иначе они будут сохраняться отдельно. Сохранение большого числа изображений в "
+"файле может замедлить работу Tellico."
+
diff --git a/po/sv.po b/po/sv.po
new file mode 100644
index 0000000..4ac69b2
--- /dev/null
+++ b/po/sv.po
@@ -0,0 +1,5236 @@
+# translation of sv.po to Svenska
+# translation of sv.po to
+# translation of tellico-sv.po to
+# This file is distributed under the same license as the tellico package.
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+#
+# Karolina Lindqvist <pgd-karolinali@algonet.se>, 2003.
+# Peter Landgren <peter.talken@telia.com>, 2005, 2006, 2007, 2008.
+msgid ""
+msgstr ""
+"Project-Id-Version: sv\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2008-01-30 08:26+0100\n"
+"Last-Translator: Peter Landgren <peter.talken@telia.com>\n"
+"Language-Team: Svenska <sv@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Report-Msgid-Bugs-To: \n"
+"X-Generator: KBabel 1.11.4\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "<qt>Tellico kan inte skriva till server-röret vid <b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr "Ansluter till OpenOffice.org..."
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr "OpenOffice.org-anslutning"
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+"Tellico kunde inte ansluta till OpenOffice.org. Bekräfta "
+"anslutningsinställningarna nedan och att OpenOffice.orgs Writer körs."
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr "Rör"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr "TCP/IP"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr "Byt namn på kolumn"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr "Nytt kolumnnamn:"
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr "Kolumn %1"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr "Byt namn på kolumn..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr "Skjut in rad"
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr "Tabort rad"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr "Flytta rad uppåt"
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr "Flytta rad nedåt"
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr "Rensa tabell"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr "Mallgranskning"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Ställ in"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr "%1:"
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Flera"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Färre"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Rensa"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Välj bild..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr "Spara endast länk"
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr "Att spar länk är bara möjligt för nytillagda bilder."
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Redigera %1"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Utöka samling"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Involvera i samling"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Byt ut samling"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr "Redigera fält"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "Lägg till %1-fält"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Ändra %1-fält"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Ta bort %1-fält"
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr "Lägg till fält"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Lägg till %1"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Byt namn på samlingen"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Ändra lån"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Lägg till filter"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Ändra filter"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Ta bort filter"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Utlåningsposter"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Låna ut %1"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Tag bort poster"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Tag bort %1"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Ordna om fält"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Inlåningsposter"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Inlåning %1"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Allmänt"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Skick"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Personligt"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Mina frimärken"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Titel"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Beskrivning"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Valör"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "Land"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Utgivningsår"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Färg"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Scott#/FACIT#"
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr "Superb, extremt fin, mycket fin, fin, hyfsad, dålig"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Kvalitet"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Stämplat"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Monterat"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Placering/perforering"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Gummerad"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Inköpsdatum"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Inköpspris"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Placering"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Gåva"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Bild"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Kommentarer"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Publicering"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Klassificering"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Mina serietidningar"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Undertitel"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Författare"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr "Artist"
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Serie"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Utgåva"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Förlag"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Utgåva"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Publiceringsår"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Sidor"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Språk"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Stil"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Nyckelord"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr ""
+"Extra fin, nästan extra fin, mycket fin, fin, mycket bra, bra, hyfsad, "
+"dålig"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Signerad"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Utlånad"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Omslag"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Mina mynt"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Typ"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "År"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Präglingsmärke"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Myntsamling"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr ""
+"PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Grading Service"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Framsida"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Baksida"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Mina böcker"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Författare"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Inbunden"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Häftad"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Hårda pärmar"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "E-Bok"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Tidning"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Tidskrift"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Bindning"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Copyrightår"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN#"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Internationellt StandardBokNummer"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN#"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Kongressbibliotekets kontrollnummer"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr "Översättare"
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Seriennummer"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Ny"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Begagnad"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Läst"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Omdöme"
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr "Mina filer"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "Namn"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Volym"
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr "Mapp"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr "Mimetype"
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr "Storlek"
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr "Tillstånd"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr "Ägare"
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr "Grupp"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr "Skapad"
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr "Ändrad"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr "Meta Info"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Egenskap"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Värde"
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr "Ikon"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Mina viner"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Producent"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Appellation/namn"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Varietal"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Årgång"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Rödvin"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Vitt vin"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Mousserande vin"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Mängd"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Dricks senast"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Etikettbild"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Övriga människor"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Kännetecken"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Mina videofilmer"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr "Blu-ray"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+msgid "HD DVD"
+msgstr "HD DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Media"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Produktionsår"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "barntillåtet, 7 år, 11 år, 15 år"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Åldersgräns"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Region 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Region 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Region 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Region 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Region 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Region 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Region 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Region 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Region"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Land"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Format"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Rollista"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr "Skådespelare/skådespelerska"
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr "Roll"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr ""
+"En tabell med rolllistan och vilka skådespelare som har besatt rollerna"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Regissör"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Kompositör"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Studio"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Språkspår"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Textningsspråk"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Ljudspår"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Längd i minuter"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "Längden på videon (i minuter)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Bildformat"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Bredformat"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Svartvit"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Färgläge"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Regissörens klippning"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Handlingen i sammanfattning"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Personligt betyg"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Omslag"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "Mina spel"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr "Xbox 360"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr "PlayStation3"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr "Nintendo Wii"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr "Linux"
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Plattform"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Utgivningsår"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Förlag"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Utvecklare"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr "Inget omdöme, vuxen, tonåring, alla, småbarn, avvaktande"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "ESBR-omdöme"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Färdig"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Mina kort"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Spelare"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Lag"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Märke"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Kortnummer"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Korttyp"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Omslagsbild"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Baksidesbild"
+
+#: collections/boardgamecollection.cpp:26
+msgid "My Board Games"
+msgstr "Mina spel"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr "Mekanism"
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr "Konstruktör"
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr "Antal spelare"
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Bibliografi"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Bibtexposttyp"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr "Dessa posttyper är specifika för bibtex. Se bibtexdokumentation."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Bibtexnyckel"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Boktitel"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Utgivare"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organisation"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Adress"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr "DOI"
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr "Digital objektidentifierare"
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Månad"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Nummer"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Hur publicerad"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Kapitel"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Korsreferens"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Sammandrag"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Anmärkning"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Min musik"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Album"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "CD-skiva"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Kassett"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "LP-skiva"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Artist"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Skivmärke"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Spår"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr "Speltid"
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr ""
+"en,ett,och,som,vid,men,av,för,från,in,i,varken,på,uppe,eller,ut,över,den,"
+"det,till, upp,med"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "den;det;de"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "jr.,jr,iii,iv,dy,dä,sr"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,van,der,van der,von, af"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr "ISBNdb.com"
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 tillåter ej sökning för denna samlingstyp."
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Resultat från %1: %2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "Denna källa har inga alternativ."
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "Entrez Databasen"
+
+#: fetch/entrezfetcher.cpp:485
+msgid "Institution"
+msgstr "Institution"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Förfrågansfel!"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Förbindelsesökningsfel %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Syntaxfel i post"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Förbindelsefel %1: %2"
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr "SRU Server"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "USA's Kongressbibliotek(US)"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr "V&ärd: "
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr "Skriv in värdnamnet på servern."
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Port: "
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Skriv in portnummer på servern. Standardvärdet är %1."
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr "Sökväg: "
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr "Skriv in sökvägen till den databas använd av servern."
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr "Format: "
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr "Skriv in det resultatformatet, som används av servern."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr "Yahoo! ljudsökning"
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "Omslagsbilden kunde inte laddas."
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr "Amazonlänk"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (US)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (Storbritannien)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Tyskland)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japan)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (Frankrike)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Kanada)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Amazon.com's Web-tjänster"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "&Land: "
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "Förenta Staterna"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Storbritannien"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Tyskland"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Japan"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "Frankrike"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Kanada"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon.com lämnar data från många skilda ställen. Välj det som du "
+"önskar utnyttja som denna datakälla."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "&Bildstorlek: "
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Liten Bild"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Medelstor Bild"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Stor Bild"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Ingen Bild"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"Omslagsbilden kan även laddas ner. Emellertid kan för många stora bilder "
+"i samlingen försämra prestanda."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "&Kompanjons ID: "
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+"Kompanjonens id identifierar den person som får tillgång till Amazon.com's "
+"Web-Tjänster, och ingår i alla länkar till Amazon.com."
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr "z39.50-server"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr "Använd förinställd &server:"
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "&Databas: "
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr "Skriv in det databasnamn, som servern använder."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "&Teckenuppsättning: "
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Skriv in den teckenuppsättningskod, som används av z39.50-servern. Det "
+"mest sannolika valet är MARC-8, fastän ISO-8859.1 är rätt vanlig."
+
+#: fetch/z3950fetcher.cpp:550
+msgid "&Format: "
+msgstr "&Format: "
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr "Automatisk upptäckt"
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+"Skriv in det dataformat, som används av z39.50-servern. Tellico kommer att "
+"försöka att automatiskt finna den bästa inställningen om <i>automatisk "
+"upptäckt</i> är valt."
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "&Användare: "
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Alternativ"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Skriv in det autentiseringsanvändarnamn, som används av z39.50-servern. De "
+"flesta servrar behöver inget."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "Lösen&ord: "
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Skriv in det autentiseringslösenord, som används av z39.50-servern. De "
+"flesta servrar behöver inget. Lösenordet kommer att sparas som vanlig text "
+"i Tellicos konfigurationsfil."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr "Illustratör"
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Extern tillämpning"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "Samlings&typ:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+"Bestäm den samlingstypsdata, som lämnas av den externa tillämpningen."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr "&Resultattyp: "
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr ""
+"Bestäm den resultattyp för data, som lämnas av den externa tillämpningen."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "Tillämpnings&sökväg: "
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+"Ställ in sökvägen för den tillämpning, som skall köras och som skall "
+"leverera en för Tellico giltig datafil."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr "Välj de söknycklar, som stöds av datakällan."
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+"Lägg till alla nödvändiga argument. <b>%1</b> kommer att bytas ut av "
+"söktermerna."
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr "Argument"
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+msgid "Update"
+msgstr "Uppdatera"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+"<p>Mata in de argument, som skall användas vid sökning efter tillgängliga "
+"uppdateringar till en post.</p><p>Formatet är detsamma som för "
+"<i>Beroende</i> fält, där fältvärden finns inom klammer, såsom i "
+"<i>%{author}</i>. Se dokumentation för detaljer.</p>"
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Källalternativ"
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr "Tillgängliga fält"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "Internetfilmdatabas"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Välj IMDB-resultat"
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+"<qt>Din sökning gav flera passade svar. Var snäll och välj en nedan.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Välj ett sökresultat.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr "IMDB Länk"
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Alternativa titlar"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+msgid "IMDB Rating"
+msgstr "IMDB omdöme"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Bevis"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"Internetfilmdatabasen använder flera olika servrar. Välj den du vill "
+"använda."
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr "&Maximal rollbesättning: "
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+"Listan med rollinnehavare kan ta med många människor. Sätt maxtalet "
+"erhållet från sökningen."
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr "Ladda ner omslagsb&ild"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr "Internet Bookshop (ibs.it)"
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Författare/Person"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr "UPC/EAN"
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Nyckelord"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr "arXiv ID"
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr "Pubmed ID"
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Grov förfrågan"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr "Originaltitel"
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr "Distributör"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr "Episoder"
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr "arXiv.org"
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr "%1 kräver ett användarnamn och lösenord."
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+"CrossRef kräver ett konto för tillgång. Läs förutsättningarna och "
+"villkor samt <a href='http://www.crossref.org/requestaccount/'>begär ett "
+"konto</a>. Skriv ditt OpenURL kontoinformation nedan."
+
+#: fetch/crossreffetcher.cpp:343
+msgid "&Username: "
+msgstr "&Användarnamn: "
+
+#: fetch/crossreffetcher.cpp:348
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+"Ett användarnamn och ett lösenord krävs för att få tillgång till "
+"CressRef's tjänst. Lösenordet lagras som vanlig text i Tellico's "
+"inställningsfil."
+
+#: fetch/crossreffetcher.cpp:354
+msgid "&Password: "
+msgstr "Lösen&ord: "
+
+#: fetch/gcstarpluginfetcher.cpp:190
+msgid "GCstar Plugin"
+msgstr "GCstar Plugin"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr ""
+"Bestäm samlingstypen för de data, som lämnats av tilläggsprogrammet."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr "&Plugin: "
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr "Välj det GCstar-tilläggsprogram, som använts till datakälla."
+
+#: fetch/gcstarpluginfetcher.cpp:420
+msgid "Author: "
+msgstr "Författare: "
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr "Discogs ljudsökning"
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr "API &nyckel: "
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+"Med ditt discogs.com-konto fick du en API-nyckel att användas för deras "
+"XML-baserade snitt (Se http://www.discogs.com/help/api)."
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr "Discogs Länk"
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr "Hämta nytt aktuellt"
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr "Version"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr "Nerladdningar"
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr "Utgivningsdatum"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+"Detta är en lista över alla poster tillgängliga för nerladdning. "
+"Tidigare installerade poster har en markeringsikon, medan poster, där ny "
+"version är tillgänglig, har en uppdateringsikon."
+
+#: newstuff/dialog.cpp:137
+msgid "The name and license of the selected item"
+msgstr "Namnet och licensen på den valda posten"
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr "Författare till den valda posten"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr "Installera"
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr "Ladda ner och installera den valda mallen."
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+"Ladda ner och installera det valda skriptet. Vissa skript kan behöva "
+"anpassas efter installation."
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr "En beskrivning av den valda posten visas här."
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr "Laddar ner information..."
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Klar."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr "Uppdatera"
+
+#: newstuff/dialog.cpp:413
+msgid "Installing item..."
+msgstr "Installerar post..."
+
+#: translators/bibteximporter.cpp:79
+msgid "No valid bibtex entries were found"
+msgstr "Inga korrekta Bibtex-poster funna"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "Inga korrekta Bibtex-poster funna i filen - %1"
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Bibtex-alternativ"
+
+#: translators/bibteximporter.cpp:287
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Koda i Unicode (UTF-8)"
+
+#: translators/bibteximporter.cpp:288
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Läs den importerade filen i Unicode (UTF-8)."
+
+#: translators/bibteximporter.cpp:289
+msgid "Use user locale (%1) encoding"
+msgstr "Används lokalisering (%1)-kodning"
+
+#: translators/bibteximporter.cpp:293
+msgid "Read the imported file in the local encoding."
+msgstr "Läs den importerade filen i lokal språkkod."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "Tellico-Zip-fil"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Tellico-filer (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Alla filer"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>Ett Alexandria-bibliotek kallat <i>%1</i> finns redan. Vilken som helst "
+"befintlig bok i det biblioteket kan be överskriven.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "Fel i XML, rad %1, kolumn %2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "Felmeddelandet från Qt är:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Det är från en framtida version av Tellico."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Tellico konverterar filen till ett nyare dokumentformat. "
+"Informationsförlust kan inträffa om en äldre version av Tellico används "
+"för att läsa den här filen i framtiden."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Okänd"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "Filen är tom."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "Filen innehåller inga samlingsdata."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Olästa böcker"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Gamla filmer"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "80's Musik"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Favoriter"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Avsöker ljudfiler..."
+
+#: translators/audiofileimporter.cpp:129
+msgid "Bitrate"
+msgstr "Bithastighet"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr "Spår (Skiva %1)"
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(Blandat)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Ljudfilsalternativ"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Rekursiv &mappsökning"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr "Om ikryssad, kommer mappar att sökas rekursivt för ljudfiler."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr "&Inkludera fillagringsplats "
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr "Om ikryssad, läggs filnamnen, för varje spår, till posten."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr "Inkludera &bithastighet"
+
+#: translators/audiofileimporter.cpp:353
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr "Om ikryssad, läggs bithastigheten, för varje spår, till posten."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|CSV-filer (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "CSV-alternativ"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Inkludera fälttitlar som kolumnnamn"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr ""
+"Om ikryssad, kommer en radöverskrift att läggas till med fältnamnen."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Avskiljare"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"Förutom komma, kan andra tecken användas som avskiljare, som separerar "
+"värdena i filen."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Komma"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Använd komma som avskiljare."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Semikolon"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Använd semikolon som avskiljare."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Tabulator"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Använd tabulator som avskiljare."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Övriga"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Använd en sträng som avskiljare."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr ""
+"Vilken sträng som helst, som t. ex. ett kolon, kan användas som avskiljare."
+
+#: translators/filelistingimporter.cpp:63
+msgid "Scanning files..."
+msgstr "Avsöker filer..."
+
+#: translators/filelistingimporter.cpp:191
+msgid "File Listing Options"
+msgstr "Fillistningsalternativ"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr "Rekursiv mappsökning"
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr "Om ikryssad, kommer mappar att sökas rekursivt för alla filer."
+
+#: translators/filelistingimporter.cpp:198
+msgid "Generate file previews"
+msgstr "Generera filförhandsgranskningar"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+"Om ikryssad, genereras förhandsgranskning av filinnehållen, vilket kan "
+"slöa ner mapplistningen."
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "ONIX Arkiv"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.zip|Zip-filer (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "ONIX arkivalternativ"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Inkludera bilder i arkivet"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Om ikryssad, kommer bilderna i dokumentet att inkluderas i det zippade "
+"ONIX-arkivet."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr "<qt>Tellico kunde inte komma åt CD-ROM enheten - <i>%1</i>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+msgid "Select CDDB Entry"
+msgstr "Välj CDDB-post"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr "Välj en CDDB-post:"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>Inga poster funna, som passade CD:n.</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "<qt>Tellico kunde inte slutföra CD uppslagningen. <qt>"
+
+#: translators/freedbimporter.cpp:470
+msgid "Various"
+msgstr "Blandat"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Ljud-CD-alternativ"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Läser data från CD-ROM-enhet"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "Välj eller mata in CD-ROM-enhetens plats."
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Läs endast alla CDDB-cache-filer"
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+"Läs data rekursivt från alla CDDV-cache-filer innehållna i "
+"standard-cacha-mappen."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr "GCfilms"
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.gcf|GCfilms datafiler (*.gcf)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.gcs|GCstar datafiler (*.gcs)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "XSLT-alternativ"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "XSLT-fil:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr ""
+"Välj den XSLT-fil som ska användas för att transformera Tellicos XML-data."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Alexandriaalternativ"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr "&Bibliotek:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "Bibtexml"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Bibtexml-filer (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|XML-filer (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Tellico-XML-alternativ"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Inkludera bilder i XML-dokument"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Om ikryssad, kommer bilderna i dokumentet att inkluderas i XML-strömmen som "
+"base64-kodade element."
+
+#: translators/importer.h:100
+msgid "Loading data..."
+msgstr "Laddar data..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr "Laddar %1..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "Bibtex"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Bibtex-filer (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Expandera strängmakron"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Om ikryssad, kommer strängmakrona att expanderas och inga "
+"@sträng{}-konstruktioner kommer att skrivas ut."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Använd URL-paket"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr "Om ikryssad, kommer URL-fält att skrivas om som en \\url-deklaration."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Hoppa över poster med tomma citatnycklar"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr ""
+"Om ikryssad, kommer alla poster med bibtextcitatnycklar att hoppas över."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Bibtex-citeringstyp:"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Parenteser"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Citationstecken"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"<qt>Citatstilen, som används vid export av bibtex. Alla fältvärden kommer "
+"att omges av antingen parenteser eller citationstecken.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "Välj typ av samling som ska importeras."
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr "&Första raden innehåller fälttitlar"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr "Om ikryssad, används första raden som fälttitlar."
+
+#: translators/csvimporter.cpp:248
+msgid "&Comma"
+msgstr "&Komma"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr "&Semikolon"
+
+#: translators/csvimporter.cpp:259
+msgid "Ta&b"
+msgstr "Ta&bulator"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr "&Övriga:"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "Tabellen ger de första fem raderna i CSV-filen."
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt>Sätt varje kolumn att motsvara ett fält i samlingen genom att välja "
+"en kolumn, markera ett fält och sedan klicka på <i>Sätt-fältknappen.</i> "
+"</qt>"
+
+#: translators/csvimporter.cpp:298
+msgid "Co&lumn:"
+msgstr "Ko&lumn:"
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr "&Datafält i denna kolumn:"
+
+#: translators/csvimporter.cpp:315
+msgid "&Assign Field"
+msgstr "&Tilldelningsfält"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+"Åtminstone en kolumn måste tilldelas ett fält. Endast tilldelade kolumner "
+"kommer att importeras."
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Nytt fält"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|Pilot databasfiler (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Visa kolumner"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "PilotDB-alternativ"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Sätt PDA-backuppflagga för databas"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>Denna fil är ej en giltig GCstar datafil.</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Tellico upptäckte ett fel vid behandlingen av XSLT."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr "En korrekt XSLT-fil behövs för att importera filen."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xml|XSL-filer (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|HTML-filer (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Folk"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(grupperad på %1)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "HTML-alternativ"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Skriv ut fältöverskrifter"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr "Om ikryssad, skrivs fältnamn ut som tabellöverskrifter."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Gruppera posterna"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr "Om ikryssad, kommer posterna att grupperas under utvalt fält."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Exportera enskilda poster som filer"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr "Om ikryssad, kommer enskilda filer att skapas för varje post."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico kunde inte läsa några metadata från PDF-filen."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+"tallico kan ladda ner information om uppgifter med ett DOI från "
+"CrossRef.org. Du måste emellertid skapa ett CrossRef-konto och lägga till "
+"en ny datakälla med din kontoinformation."
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Datakällsegenskaper"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "&Källnamn: "
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr "Namnet identifierar datakällan och bör vara unik och beskrivande."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "Käll &typ: "
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr "Tellico stöder flera olika datakällor."
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr "Uppdatering från källa kommer att skriva över användardata "
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Om ikryssad, kommer uppdaterade poster att skriva över all befintlig "
+"information."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Vilket fält som helst"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "innehåller"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "innehåller inte"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "är lika med"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "är inte lika med"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "matchar reguljärt uttryck"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "matchar inte reguljärt uttryck"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Redigera..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Avancerat filter"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Filterkriteria"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Matchar a&lla följande"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Matchar n&ågon av följande"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Filternamn:"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "&Spara filter"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Enkel text"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Stycke"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Val"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Kryssruta"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Tabell"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Beroende"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Datum"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr "Uppdaterar %1..."
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr "Uppdaterar poster..."
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr "Uppdatera fält"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr "Uppdaterar <b>%1</b>..."
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr "Välj matchning"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+"<qt><b>%1</b> returnerade flera resultat, vilket kunder matcha <b>%2</b>, "
+"aktuell post i samlingen. Välj riktig matchning.</qt>"
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Expandera alla grupper"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Drag ihop alla grupper"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Filtrera genom grupp"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (Sorterat på antal)"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Grupp"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Importalternativ"
+
+#: importdialog.cpp:62
+msgid "&Replace current collection"
+msgstr "&Byt ut nuvarande samling"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr "Byt nuvarande samling med innehållet i den importerade filen."
+
+#: importdialog.cpp:65
+msgid "A&ppend to current collection"
+msgstr "&Lägg till på slutet på nuvarande samling"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Lägg till innehållet i den importerade filen till nuvarande samling. Detta "
+"är endast möjligt då samlingstyperna är lika."
+
+#: importdialog.cpp:69
+msgid "&Merge with current collection"
+msgstr "&Involvera i nuvarande samling"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Lägg till innehållet i den importerade filen till nuvarande samling. Detta "
+"är endast möjligt då samlingstyperna är lika."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Importera"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|RIS-filer (*.ris)"
+
+#: importdialog.cpp:277
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.amc|AMC-datafiler (*.amc)"
+
+#: importdialog.cpp:281
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdf|PDF-filer (*.pdf)"
+
+#: importdialog.cpp:285
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.reflib|Referencer-filer (*.reflib)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico kan inte ladda filen - %1."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico kan inte skriva fil - %1."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico kan inte ladda upp fil - %1."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Endast samlingar med samma typ av fält som det nuvarande kan läggas till. "
+"Inga ändringar görs till nuvarande samling."
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Endast samlingar med samma typ av fält som det nuvarande kan blandas in. "
+"Inga ändringar görs till nuvarande samling."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico kan inte ladda en bild från filen - %1."
+
+#: entryiconview.cpp:287
+msgid "&Sort By"
+msgstr "&Sortera på"
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Lånedialog"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "Följande utlånas:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "Följande är till låns:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "Ut&lånat till:"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Skriv namnet på den person, som lånar av dig. Om du klickar på knappen "
+"kan du välja från din adressbok."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "&Lånedatum:"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+"Utlåningsdatum är det datum som du lånade ut något. Som standard "
+"används dagens datum."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "Återlämningsdat&um:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"Återlämningsdatumet är det datum då återlämning skall ske. Detta datum "
+"krävs inte, såvida du inte vill lägga till lånet till din aktiva "
+"kalender."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Noteringar:"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "Du kan lägga till noteringar om lånet, om du vill."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "Lägg till en påminnelse till den &aktiva kalendern"
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"<qt>Avprickning i denna ruta kommer att lägga till en <em>Att göra</em> "
+"aktivitet till din aktiva kalender, vilken kan betraktas via KOrganizer. "
+"Rutan är bara aktiverad om du sätter ett återlämningsdatum."
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Skapa en ny samling"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Ny &Boksamling"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Skapa en ny boksamling"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Ny B&ibliografi"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Skapa en ny bibtexbibliografi"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Ny &Serietidningsamling"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Skapa en ny serietidningssamling"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Ny &Videosamling"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Skapa en ny videosamling"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Ny &Musiksamling"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Skapa en ny musiksamling"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Ny M&yntsamling"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Skapa en ny myntsamling"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Ny &Frimärksamling"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Skapa en ny frimärksamling"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Ny K&ortsamling"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Skapa en ny kortsamling"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Ny Vi&nsamling"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Skapa en ny vinsamling"
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Ny S&pelsamling"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Skapa en ny spelsamling"
+
+#: mainwindow.cpp:272
+msgid "New Boa&rd Game Collection"
+msgstr "Ny S&pelsamling"
+
+#: mainwindow.cpp:274
+msgid "Create a new board game collection"
+msgstr "Skapa en ny spelsamling"
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr "Ny &Filkatalog"
+
+#: mainwindow.cpp:282
+msgid "Create a new file catalog"
+msgstr "Skapa en ny filkatalog"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Ny &Egensamling"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Skapa en ny egensamling"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Öppna befintligt dokument"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Öppna senaste använda fil"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Spara själva dokumentet"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Spara dokumentet som en annan fil..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Skriv ut innehållet av dokumentet..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Avsluta programmet"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Importera samlingsdata från andra format"
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Importerar Tellico-data..."
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Importera en annan Tellico-datafil"
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "Importerar CSV-data..."
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Importera en CSV-fil"
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "Importerar MODS-data..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Importera en MODS-fil"
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Importerar Alexandria-data..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Importera data från Alexandiaboksamling"
+
+#: mainwindow.cpp:352
+msgid "Import Delicious Library Data..."
+msgstr "Importera Delicious Library Data..."
+
+#: mainwindow.cpp:353
+msgid "Import data from Delicious Library"
+msgstr "Importera data från Delicous-bibliotek"
+
+#: mainwindow.cpp:359
+msgid "Import Referencer Data..."
+msgstr "Importera Referencer Data..."
+
+#: mainwindow.cpp:360
+msgid "Import data from Referencer"
+msgstr "Importera data från Referencer"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Importerra Bibtex-data..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Importera en Bibtex-bibliografifil"
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Importerar Bibtexml-data..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Importera en Bibtexml-bibliografi-fil"
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "Importerar RIS-data..."
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Importera en RIS-referensfil"
+
+#: mainwindow.cpp:387
+msgid "Import PDF File..."
+msgstr "Importera PDF-fil..."
+
+#: mainwindow.cpp:388
+msgid "Import a PDF file"
+msgstr "Importera ena PDF-fil"
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Importerar ljudfilsmetadata..."
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Importera metadata från en ljudfil"
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Importerar ljud-CD-data..."
+
+#: mainwindow.cpp:405
+msgid "Import audio CD information"
+msgstr "Importera ljud-CD-information"
+
+#: mainwindow.cpp:414
+msgid "Import GCstar Data..."
+msgstr "Importera GCstar-data..."
+
+#: mainwindow.cpp:415
+msgid "Import a GCstar data file"
+msgstr "Importera en GCstar datafil"
+
+#: mainwindow.cpp:421
+msgid "Import Griffith Data..."
+msgstr "Importera Griffith Data..."
+
+#: mainwindow.cpp:422
+msgid "Import a Griffith database"
+msgstr "Importera en Griffith-databas"
+
+#: mainwindow.cpp:428
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Importera Ant Movie-katalogdata..."
+
+#: mainwindow.cpp:429
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Importera en Ant Movie-katalogdatafil"
+
+#: mainwindow.cpp:435
+msgid "Import File Listing..."
+msgstr "Importera Fillistor..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr "Importera information om filer i en mapp"
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "Importerar XSL-transformering..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Importera med hjälp av XSL-transformering"
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "E&xportera"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Exportera samlingensdata till andra format"
+
+#: mainwindow.cpp:461
+msgid "Export to XML..."
+msgstr "Exportera till XML..."
+
+#: mainwindow.cpp:462
+msgid "Export to a Tellico XML file"
+msgstr "Exportera till en Tellico-XML-fil"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Exportera till Zip..."
+
+#: mainwindow.cpp:469
+msgid "Export to a Tellico Zip file"
+msgstr "Exportera till en Tellico-Zip-fil"
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "Exporterar till HTML..."
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Exportera till HTML-fil"
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "Exporterar till CSV..."
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Exportera till en kommaseparerad fil"
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "Exporterar till PilotDB..."
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Exportera till PilotDB-databas"
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Exporterar till Alexandria..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Exportera till ett Alexandriabibliotek"
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Exporterar till Bibtex..."
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Exportera till Bibtex-fil"
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Exporterar till Bibtexml..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Exportera till Bibtexml-fil"
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "Exporterar till ONIX..."
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Exportera till en ONIX-fil"
+
+#: mainwindow.cpp:524
+msgid "Export to GCfilms..."
+msgstr "Exportera till GCfilms..."
+
+#: mainwindow.cpp:525
+msgid "Export to a GCfilms data file"
+msgstr "Exportera till GCfilms datafil"
+
+#: mainwindow.cpp:531
+msgid "Export to GCstar..."
+msgstr "Exportera till GCstar..."
+
+#: mainwindow.cpp:532
+msgid "Export to a GCstar data file"
+msgstr "Exportera till en GCstar-datafil"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "Exporterar XSL-transformering..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Exportera med XSL-transformering"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Tar bort vald text och lägger i klippbord"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Kopierar vald text till klippbord"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Infogar klippbordets innehåll"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Markera alla fält i samlingen"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Avmarkera alla fält i samlingen"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Sökning på Internet..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Sök på Internet..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "Avancerat &filter..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Filtrera samlingen"
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&Ny post..."
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Skapa en ny post"
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "&Redigera post..."
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Redigera de valda posterna"
+
+#: controller.cpp:621 mainwindow.cpp:577
+msgid "D&uplicate Entry"
+msgstr "D&uplicera post"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Kopiera valda poster"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "&Tag bort post"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Ta bort valda poster"
+
+#: mainwindow.cpp:585
+msgid "&Merge Entries"
+msgstr "&Slå samman poster"
+
+#: mainwindow.cpp:588
+msgid "Merge the selected entries"
+msgstr "Slå samman de valda posterna"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "&Generera rapporter..."
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Generera samlingsrapporter"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "&Låna ut..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Utlåning av det valda"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "&Inlämning"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Inlämning av det valda"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "&Byt namn på samling..."
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Byt namn på samlingen"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "Samlings&fält..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Ändra samlingsfälten"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "K&onvertera till bibliografi"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Konvertera en boksamling till en bibliografi"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "Sträng&Makron..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Redigera Bibtex strängmakron"
+
+#: mainwindow.cpp:626
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Kopierar Bibtex till kli&ppbord"
+
+#: mainwindow.cpp:627
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Kopierar bibtexcitat till klippbord"
+
+#: mainwindow.cpp:632
+msgid "Cite Entry in &LyX"
+msgstr "Citera post i &Lyx"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Citera valda fält i LyX"
+
+#: mainwindow.cpp:638
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Ci&tera post i OpenOffice.org"
+
+#: mainwindow.cpp:639
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Citera de valda fälten i OpenOffice.org"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, no-c-format
+msgid "&Update Entry"
+msgstr "&Uppdatera post"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr "Alla källor"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr "Uppdatera inmatningspostdata från alla tillgängliga källor"
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Visa gru&ppvy"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Slå på/av gruppvyn"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Göm gru&ppvy"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Visa post&editor"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Slå på/av editorn"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "Göm post&editor"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Visa post&vy"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Slå på/av postvyn"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "G&öm postvy"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Ändra gruppering"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "&Gruppurval"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Ändra gruppering i samlingen"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Filter"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Rensa filter"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Filter här..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Grupper"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt> <i>Gruppvyn</i> sorterar posterna i grupperingar baserat på ett valt "
+"fält.</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt> <i>Kolumnvyn</i> visar värdena av flera fält för varje post.</qt>"
+
+#: mainwindow.cpp:831
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Välkommen till Tellico - samlingshanteraren"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+"<h3>Tellico är ett verktyg som hanterar samlingar av böcker, video, musik, "
+"eller vadhelst du vill katalogisera.</h3><h3>Nya poster kan läggas till din "
+"samling genom <a href=\"tc:///coll_new_entry\">skriva in data manuellt</a> "
+"eller genom <a href=\"tc:///edit_search_internet\">nedladding av data</a> "
+"från olika Internetkällor.</h3>"
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Skapar nytt dokument..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Öppnar fil..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Öppna fil"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Sparar fil..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+"<qt><p>Du sparar en fil med många bilder, vilket orsakar Tellico att gå "
+"påtagligt långsamt. Vill du spara bilderna i Tellicos datamapp för att "
+"förbättra egenskaperna?</p><p>Ditt val kan alltid ändras i "
+"inställningsdialogen.</p></qt>"
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr "Spara bilder separat"
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr "Spara bilder i fil"
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Sparar fil med ett nytt namn..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Skriver ut..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"Samlingen är filtrerad att visa endast en begränsad delmängd av alla "
+"poster. Endast synliga fälten kommer att skrivas ut. Fortsätt?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Bearbetar dokument..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Avslutar..."
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Totalt antal poster: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 filtrerade, %2 valda)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 filtrerade)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 valda)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Skriv ut %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Sida %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Kontrollera installationen."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Importera data..."
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Importera fil"
+
+#: mainwindow.cpp:1864
+msgid "Import Directory"
+msgstr "Importmapp"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Exporterar data..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Exportera som"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Strängmakron"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Makro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Sträng"
+
+#: mainwindow.cpp:1999
+msgid "Creating citations..."
+msgstr "Skapar citat..."
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Filter"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt> <i>Filtervyn</i> visar posterna de poster, som passar vissa "
+"filterregler.</qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Lån"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt> <i>Lånevyn</i> visar en lista på alla människor, som har lånat "
+"från din samling.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr "Uppdatera postdata från %1"
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+"Tellico kan bara importera en fil av denna typ åt gången. Endast %1 kommer "
+"att importeras."
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico kan inte ladda bilden - %1."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+"En fil med namn \"%1\" existerar redan. Är du säker på att du vill skriva "
+"över den?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Skriv över fil?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Skriv över"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Filter (sortera på antal)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Vill du verkligen ta bort denna post?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Tag bort post"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Vill du verkligen ta bort dessa poster?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Ta bort flera poster"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "&Redigera poster..."
+
+#: controller.cpp:627
+msgid "D&uplicate Entries"
+msgstr "D&uplicera poster"
+
+#: controller.cpp:628
+msgid "&Update Entries"
+msgstr "&Uppdatera fält"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "&Tag bort poster"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+"Följande är redan utlånade, men Tellico stöder f. n. inte utlåning av "
+"samma flera gånger. De kommer att tas bort från listan av utlåningsbart."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Standardkalender"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"För tillfället stöder Tellico bara lokala kalenderresurser. Den aktiva "
+"kalendern är fjärrlokaliserad, så dina lån kommer ej att läggas till."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Aktiv kalender"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 skall till att svara \"%2\""
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(tom)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - en samlingshanterare för KDE"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Återöppna inte sist öppnade fil"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Importera <filename> som en bibtex fil"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Importera <filename> com en MODS fil"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Importera <filename> som en RIS fil"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Fil att öppna"
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr "Datakällsskript"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Ikoner"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Upphovsman till btparse-biblioteket"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr "Kodexempel och allmän inspiration"
+
+#: main.cpp:50
+msgid "Author of libcsv library"
+msgstr "Författare till libcsv-biblioteket"
+
+#: main.cpp:52
+msgid "Author of rtf2html library"
+msgstr "Författare till rtf2html-biblioteket"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Samlingsfält"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Nuvarande fält"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "&Nytt"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Lägg till ett nytt fält till samlingen"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "&Tag bort"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Tag bort ett fält från samlingen"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Flytta detta fält upp i listan. Listordningen är viktig för layouten i "
+"posteditorn."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Flytta ned detta fält i listan. Listordningen är viktig för layouten i "
+"posteditorn."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Fältegenskaper"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "&Titel:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "Rubrik för fältet"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "T&yp:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "Fältets typ bestämmer vilka värden som kan användas. "
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "<i>Enkel Text</i> används till de flesta fält. "
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "<i>Stycke</i> är till för stora textblock. "
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Val</i> begränsar fältet till vissa värden. "
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "<i>Kryssruta</i> är till för enkla ja/nej-värden. "
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr "<i>Tal/</i> indikerar att fältet innehåller siffervärden. "
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+"<i>URL</i> är till för fält, som refererar till URL:er, inbegripet "
+"referenser till andra filer. "
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr "En <i>Tabell</i> kan ha eller flera kolumner med värden. "
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "Ett <i>bild</i> -fält innehåller en bild. "
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+"Ett <i>Datum</i> -fält kan användas för värden med dag, månad och år. "
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+"Ett <i>Omdömes</i>-fält utnyttjar stjärnor till att visa omdömesnivån. "
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"Ett <i>Beroende</i> -fält beror på värden i andra fält, och formateras "
+"enligt fältbeskrivningen. "
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"Ett <i>Skrivskyddat</i> fält är till för interna värden, möjligen "
+"användbart till import och export. "
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "Kate&gori:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr "Fältkategorin bestämmer var fältet placeras i editorn."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "Beskr&ivning:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"Beskrivningen är en användbar påminnelse om vilken information som finns "
+"i fältet. För <i>Beroende</i>-fält, är beskrivningen en formatsträng "
+"sådan som \"%{year} %{title}\" där de benämnda fälten byts ut i "
+"strängen."
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr "Stan&dardvärde:"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr "</qt>Ett standardvärde kan tilldelas för nya poster.</qt>"
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr "Ti&llåtna värden:"
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>För <i>Val</i>-fälttypen; det här är de enda tillåtna värden. De "
+"placeras i en kombinationsbox. Det möjliga värdet måste separeras av ett "
+"semikolon, till exempel: \"hund; katt; mus\"</qt> "
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "&Utvidgande egenskaper:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "&Mängd..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"Utvidgande fältegenskaper används för att specificera företeelser såsom "
+"motsvarande bibtex-fält."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Formateringsalternativ"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Ingen formatering"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+"Detta tillval förhindrar ett fält från att bli automatformaterat eller "
+"att automatiskt få stor bokstav."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Automatiskt stor bokstav"
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+"Detta tillval tillåter fältet att få automatisk stor bokstav, men inte "
+"automatiskt formaterat."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Formatera som en rubrik"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Detta tillval ger fältet automatisk formatering och stor bokstav som en "
+"titel men endast om dessa tillval är globalt markerade."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Formatera som ett namn"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Detta tillval ger fältet automatisk formatering och stor bokstav som ett "
+"namn men endast om dessa tillval är globalt markerade."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Fältalternativ"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Aktivera automatkomplettering"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Om ikryssad, används KDEs automatkompletteringsfunktion i redigeringsrutan "
+"för detta fält."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Tillåt flera värden"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Om ikryssad, kommer Tellico att tyda värdena i fältet som flera värden, "
+"åtskilda av semikolon."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Tillåt gruppering"
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Om ikryssad, kan detta fält användas för att gruppera fält i en gruppvy."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr "Återställ det valda fältets egenskaper till standardvärdena."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Ändra fält"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Borttagning av tillåtna värden från <i>%1</i> fältet, som finns nu i "
+"samlingen, kan åstadkomma dataförödelse. Vill du behålla dina "
+"modifierade värdena eller avbryta och återgå till de aktuella?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Behåll modifierade värden"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Återställ fältegenskaper"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Vill du verkligen låta egenskaperna för <em>%1</em> återgå till "
+"standardvärdena?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Återställ"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Utvidgade fältegenskaper"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr "Ett fält med denna rubrik finns redan. Byt rubrik."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr "<qt>kategorin får ej vara tom. Vänligen skriv in en kategori.</qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>Ett fält kan inte vara i samma kategori som ett <em>Stycke</em>, "
+"<em>Tabell</em> eller <em>Bild</em>-fält. Skriv in en annan kategori.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"Ett fält kan inte vara i samma kategori som ett befintlig kategori. Skriv "
+"in en annan rubrik."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+"Området för ett omdömesfält skall ligga mellan 1 och 10 och den undre "
+"gränsen måste vara mindre än den högre. Vänligen skriv in skilda lägre "
+"och högre omdömesgränser."
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "Tabeller är begränsade till maximalt tio kolumner."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Den aktuella filen har ändrats.\n"
+"Vill du spara den?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Osparade ändringar"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Välj låntagare"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Anpassa Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Allmänna inställningar"
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr "Åte&röppna filen vid start"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Om ikryssad, kommer filen som öppnades sist att återöppnas vid start av "
+"programmet."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "Vi&sa \"Dagens tips\" vid uppstart"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr "Om ikryssad, kommer \"Dagens tips\" att visas vid programstart."
+
+#: configdialog.cpp:213
+msgid "Image Storage Options"
+msgstr "Bildlagringsalternativ"
+
+#: configdialog.cpp:214
+msgid "Store images in data file"
+msgstr "Lagra bilder i en datafil"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr "Lagra bilder i en allmän tillämpningsmapp"
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr "Lagra bilder i en mapp, relativt datafilen"
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+"Bilder kan sparas i datafilen själv, vilket gör att Tellico går "
+"långsamt, lagras i Tellicos tillämpningsmapp eller lagras i mapp i på "
+"samma ställe som datafilen."
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Formateringsalternativ"
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr "Automatisk stor första bokstav på &titlar och namn"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Om ikryssad, kommer boktitlar och namn att få stor bokstav automatiskt."
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr "Automat&formatera titlar och namn"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr "Om ikryssat, kommer boktitlar och namn att bli automatformaterade."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr "Ingen automatiskt stor &bokstav:"
+
+#: configdialog.cpp:243
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>En lista med ord, som inte bör omvandlas att inledas med stor bokstav. "
+"Flera värden separeras med ett semikolon.</qt>"
+
+#: configdialog.cpp:249
+msgid "Artic&les:"
+msgstr "Artik&lar:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>En lista med ord som kan betraktas som artiklar om de finns i första "
+"ordet i titeln. Flera värden skall separeras med ett semi-kolon.</qt>"
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr "&Ändelser för personnamn:"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>En lista med ändelser som kan användas i personnamn. Flera värden "
+"skall separeras med ett semikolon.</qt>"
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr "Efternamn&prefix:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>En lista med prefix, som kan användas i efternamn. Flera värden "
+"separeras med ett semikolon.</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Utskrift"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Utskriftsalternativ"
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr "&Formatera titlar och namn"
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr "&Skriv ut fältöverskrifter"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Grupperingsalternativ"
+
+#: configdialog.cpp:313
+msgid "&Group the entries"
+msgstr "&Gruppera posterna"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Bildalternativ"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr "Maximal bild&bredd:"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Den maximala bredden på bilden vid utskrift. Höjd/bredd-förhållandet "
+"behålls."
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr "&Maximal bildhöjd:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Den maximala höjden på bilden vid utskrift. Höjd/bredd-förhållandet "
+"behålls."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Mallar"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Mallalternativ"
+
+#: configdialog.cpp:369
+msgid "Template:"
+msgstr "Mall:"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+"Välj den mall, som används för aktuell typ av samling. Ej alla mallar "
+"kommer att använda teckensnitts- och färginställningarna."
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr "&Granskning..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr "Visa en granskning av mallen"
+
+#: configdialog.cpp:398
+msgid "Font Options"
+msgstr "Teckensnittsalternativ"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr "Teckensnitt:"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr ""
+"Detta teckensnitt är anpassat till den mall, som används i "
+"postgranskningen."
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr "Storlek:"
+
+#: configdialog.cpp:425
+msgid "Color Options"
+msgstr "Färgval"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr "Bakgrunsfärg:"
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr ""
+"Denna färg är anpassat till den mall, som används i postgranskningen."
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr "Textfärg:"
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr "Markeringsfärg:"
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr "Markeringstextfärg:"
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr "Mallhantering"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr "Installera..."
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr "Klicka för att installera en ny mall direkt."
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr "Ladda ner..."
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr "Klicka för att ladda ner ytterligare mallar via Internet."
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr "Tag bort..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr "Klicka för att välja och borttagning av installerade mallar."
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Datakällor"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Datakällsalternativ"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Källa"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr "Flytta &upp"
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+"Datakällornas ordning anger den ordning Tellico använder när poster "
+"uppdateras automatiskt."
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr "Flytta &ner"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "&Ny..."
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr "Klicka för att lägga till en ny datakälla."
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Modifiera..."
+
+#: configdialog.cpp:533
+msgid "Click to modify the selected data source."
+msgstr "Klicka för att redigera den valda datakällan."
+
+#: configdialog.cpp:536
+msgid "Click to delete the selected data source."
+msgstr "Klicka för att ta bort den valda datakällan."
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr "Klicka för att ladda ner ytterligare datakällor via Internet."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr "*.tar.gz *.tgz|mallpaket (*.tar.gz)"
+
+#: configdialog.cpp:1049
+msgid "Delete Template"
+msgstr "Ta bort mall"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr "Välj mall som skall tas bort:"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "Låntagare"
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Inlåning"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Ändra lån..."
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "Låntager (sorterade på antal)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "Min samling"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Boksamling"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Seriesamling"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Videosamling"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Musiksamling"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Myntsamling"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Frimärkssamling"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Vinsamling"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Kortsamling"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Spelsamlingen"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr "Filkatalog"
+
+#: collectionfactory.cpp:135
+msgid "Board Game Collection"
+msgstr "Spelsamling"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Egen samling"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr "<qt> <i>Inmatningsvyn</i> visar en formatterad vy av innehållet.</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt><i>Ikonvyn</i> visar varje post i samlingen eller gruppen genom att "
+"använda en ikon, som kan vara en bild i posten.</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Exportalternativ"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Formatering"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Formatera alla fält"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Om ikryssat, blir boktitlar och namn automatformaterade beroende på deras "
+"formattyp."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Exportera endast valda fält"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr ""
+"Om ikryssad, skrivs aktuella valda fältnamn ut som tabellöverskrifter."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Kodning"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Koda i Unicode (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Koda den exporterade filen i Unicode (UTF-8)."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Koda med användarvald språkkod (%1)"
+
+#: exportdialog.cpp:72
+msgid "Encode the exported file in the local encoding."
+msgstr "Koda den exporterade filen i lokal språkkod."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "&Sök"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "&Stanna"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Internetsökning"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Sökförfrågan"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr "Sö&k:"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+"Mata in ett sökvärde. En ISBN-sökning måste inkludera ett komplett ISBN."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Välj typ av sökning"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Klicka för att starta eller stanna sökningen"
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr "&Mång-ISBN/UPC-sökning"
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr "Kryssa i denna ruta för att söka på flera ISBN- eller UPC-värden."
+
+#: fetchdialog.cpp:138
+msgid "Edit List..."
+msgstr "Redigera lista..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+"Klicka för att öppna en textredigeringsruta till att mata in eller "
+"redigera flera ISBN-värden."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "Sökkä&lla:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Välj databas att söka i"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"När resultat erhålles läggs de till denna lista. Genom att välja en "
+"kommer en fullständiga post att hämtas och visas i vyn nedan."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"En post kan visas här innan den läggs till i den aktuella samlingen genom "
+"att välja den i listan ovan"
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "&Lägg till post"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Lägg till den valda posten till samlingen"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr "Hämta fler resultat"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr "Hämta fler resultat från den aktuella datakällan"
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Rensa alla sök- och resultatfält"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Avbryter sökningen..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Söker..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "Sökningen lämnade inga värden."
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+"Sökningen lämnade 1 resultat.\n"
+"Sökningen lämnade %n resultat."
+
+#: fetchdialog.cpp:412
+msgid "No results were found for the following ISBN values:"
+msgstr "Inga poster fanns för följande ISBN-värden:"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Hämtar %1..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr "Inga Internetkällor är tillgängliga för din aktuella samlingstyp."
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr "Redigera ISBN/UPC-värden"
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr "<qt>Mata in ISBN- eller UPC-värden, ett per rad.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "&Ladda från fil..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Ladda listan från en text fil.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>En ISBN-sökning kan innehålla maximalt 100 ISBN-värden. Endast de "
+"första 100 värdena i din lista kommer att användas.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Redigeringspost"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Ny post"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "&Spara post"
+
+#: entryeditdialog.cpp:77
+msgid "Go to the previous entry in the collection"
+msgstr "Gå till föregående post i samlingen"
+
+#: entryeditdialog.cpp:82
+msgid "Go to the next entry in the collection"
+msgstr "Gå till nästa post i samlingen"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Vill du verkligen redigera dessa poster?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Redigera flera poster"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr "Ett värde krävs för följande fält. Vill du fortsätta?"
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Redigera poster"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "&Spara poster"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"Posten har ändrats.\n"
+"Vill du spara ändringarna?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Spara post"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Samlingsrapport"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "&Rapportmall:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "&Generera"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr "Välj en rapportmall ock klicka på <em>Generera</em>."
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr "Vissa rapporter kan ta flera sekunder att skapa för stora samlingar."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Vill du verkligen ta bort detta filter?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Ta bort filter?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Nytt samlingsnamn:"
+
+#: tellico_kernel.cpp:377
+msgid "Entry 1"
+msgstr "Rad 1"
+
+#: tellico_kernel.cpp:378
+msgid "Entry 2"
+msgstr "Rad 2"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr "Värden i %1 var i konflikt då poster sammanslogs."
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr "Välj vilket värde, som skall behållas."
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+msgid "Merge Entries"
+msgstr "Slå samman poster"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr "Välj värde från %1"
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico kan inte hitta standardpostens stilmall."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Ny"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "N&y samling"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Samlingsverktygsrad"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr ""
+"Karolina Lindqvist \n"
+"Peter Landgren"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr ""
+"pgd-karolinali@algonet.se \n"
+"peter.talken@telia.com"
+
+#: entrymerger.cpp:35
+msgid "Merging entries..."
+msgstr "Slår samman poster..."
+
+#: entrymerger.cpp:49
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Totalt antal avsökta/skannade poster: %1/%2"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>...att om en bok har mer än en författare ska du separera de olika\n"
+"författarnamnen med semikolon, så att Tellico kan förstå namnen\n"
+"och använda dem separat</p>\n"
+"<p>Vilket annat fält som tillåter multipla värden ska matas in på samma\n"
+"sätt, med semikolon (;) som separerar mellan värdena.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>...att du kan ändra vilka fält som visas i listan genom att\n"
+"högerklicka på kolumnrubriken.\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>...att du kan lägga till, redigera eller ändra fält i samlingen genom "
+"att\n"
+"använda fälteditorn. Piltangenterna nedanför fältlistan kan användas "
+"för\n"
+"att ändra positionen på fälten i listan, vilket ändrar placeringen i "
+"posteditorn.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>...att om du vill filtrera på värdet i en kryssruta ska du använda\n"
+"värdet \"true\". Om du till exempel vill filtrera för att visa endast\n"
+"sciencefictionböcker som du inte har läst, ska markera <em>Matchar alla "
+"följande</em>-knappen, sätta första rutan till \"Genre\"\n"
+"\"innehållande\" \"Science fiction\" (inga citeringstecken) och den andra\n"
+"regeln till \"Läst\" \"ska inte innehålla\" \"true\" (inga "
+"citeringstecken).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>...att om en ickebokstav används i Snabbfiltret, kommer texten att\n"
+"tydas som ett reguljärt uttryck.</p>\n"
+"<p>För att visa böcker som är av Weber eller Bujold, till exempel, kan "
+"man\n"
+"söka på \"weber|bujold\" (inga citeringstecken) i filterrutan.</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>...att du kan redigera mer än en post samtidigt, genom att trycka ner\n"
+"Shift- eller Ctrl-tangenten och välja flera fält.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>...att du kan konvertera en existerande boksamling till en bibliografi,\n"
+"som sedan kan exporteras till Bibtex eller Bibtexml-format.</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>...att du kan lägga till, redigera eller ta bort strängmakron för "
+"bibliografier.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>...att om mer än ett fält är formaterad som ett namn, kommer en extra\n"
+"grupp med namnet \"Övriga\" att läggas till samlingen, tillåtande "
+"författare och redigerare\n"
+"att sorteras och skrivas ut tillsammans, till exempel.</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>...att du kan ändra utseendet på utskriften genom att ändra filen "
+"<tt>tellico-printing.xsl</tt>. Filen genererar HTML och CSS-en i stilmallen "
+"bestämmer saker som font, marginaler etc.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>...att du kan importera och exportera med hjälp av en generellt XSL "
+"typmall som ger en korrekt Tellico XML-fil</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr "<p>...att dubbelklicka på en post öppnar postredigeraren.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>...att du kan lägga till HTML taggar till godtyckligt styckefält för "
+"formatering, såsom\n"
+"&lt;b&gt;bold&lt;/b&gt; eller &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>...att i Detaljvy, kan du trycka på en bokstav på\n"
+" tangentbordet för att hoppa till nästa post som börjar med den "
+"bokstaven.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+"<p>...att du kan använda 'Beroende fält' till att kombinera flera "
+"åtskilda fält\n"
+"till ett enda fält. Välj bara typen 'Beroende' och använd en beskrivning\n"
+"liknande \"Värde: %{fielda}%{fieldb}\" där %{...} byts ut mot\n"
+"riktiga fältvärden. Det är användbart till att samla flera värden i "
+"ett\n"
+"enda fält, t. ex. för bättre gruppering och till att kombinera fält av "
+"olika\n"
+"typer genom att samtidigt sortera propert. Se till exempel\n"
+"ett numeriskt fält följt av ett textunderfält med 3b, 14a.</p>\n"
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Album"
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr "Denna mall är till endast för en musiksamling."
+
+#: xslt.cpp:5
+msgid "Total:"
+msgstr "Totalt:"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr "Prydlig"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "Standard"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Kompakt"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Video"
+
+#: xslt.cpp:14 xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr "Denna mall är endast till för en videosamling."
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Gruppsummering"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Gruppsummering"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Totalt antal fält:"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Totalt antal poster:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+msgid "Generated by Tellico"
+msgstr "Genererad av Tellico"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Tydliga värden: "
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Bildlista"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Lånevy"
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Lånedatum"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Anmärkning"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Återlämningsdatum"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Gruppvy"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Titellista (Horisontell)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Titellista (Vertikal)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Kolumnvy"
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "Tre-kolumn"
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr "Sök"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr "The British Library"
+
+#: z3950.cpp:6
+msgid "Sudoc (France)"
+msgstr "Sudoc (Frankrike)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr "BIBSYS (Norge)"
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr "Italienska Nationalbiblioteket"
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr "Portugisiska Nationalbiblioteket"
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr "Polska Nationalbiblioteket"
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr "Kanadensiska Nationalbiblioteket"
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr "Israel Union List"
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr "Australiensiska Nationalbiblioteket"
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr "Litauiska Nationalbiblioteket"
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr "Copac (UK och Irland)"
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr "BoardGameGeek"
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr "Dark Horse Comics"
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr "Allocine.fr"
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr "Spanska Kulturministeriet"
diff --git a/po/tellico.pot b/po/tellico.pot
new file mode 100644
index 0000000..38bcdd6
--- /dev/null
+++ b/po/tellico.pot
@@ -0,0 +1,4942 @@
+# SOME DESCRIPTIVE TITLE.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: ENCODING\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr ""
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr ""
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr ""
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr ""
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr ""
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr ""
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr ""
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr ""
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr ""
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr ""
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr ""
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr ""
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr ""
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr ""
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr ""
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr ""
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr ""
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr ""
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr ""
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr ""
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr ""
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr ""
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr ""
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr ""
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr ""
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr ""
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr ""
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr ""
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr ""
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr ""
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr ""
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr ""
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr ""
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr ""
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr ""
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr ""
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr ""
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr ""
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr ""
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr ""
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr ""
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr ""
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr ""
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr ""
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr ""
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr ""
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr ""
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr ""
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr ""
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr ""
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr ""
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr ""
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr ""
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr ""
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr ""
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr ""
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr ""
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr ""
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr ""
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr ""
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr ""
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr ""
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr ""
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr ""
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr ""
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr ""
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr ""
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr ""
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr ""
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr ""
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr ""
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr ""
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr ""
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr ""
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr ""
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr ""
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr ""
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr ""
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr ""
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr ""
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr ""
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr ""
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr ""
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr ""
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr ""
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr ""
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr ""
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr ""
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr ""
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr ""
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr ""
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr ""
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr ""
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr ""
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr ""
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr ""
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr ""
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr ""
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr ""
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr ""
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr ""
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr ""
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr ""
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr ""
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr ""
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr ""
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr ""
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr ""
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr ""
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr ""
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr ""
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr ""
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr ""
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr ""
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr ""
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr ""
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr ""
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr ""
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr ""
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+msgid "HD DVD"
+msgstr ""
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr ""
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr ""
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr ""
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr ""
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr ""
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr ""
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr ""
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr ""
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr ""
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr ""
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr ""
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr ""
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr ""
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr ""
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr ""
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr ""
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr ""
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr ""
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr ""
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr ""
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr ""
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr ""
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr ""
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr ""
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr ""
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr ""
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr ""
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr ""
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr ""
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr ""
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr ""
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr ""
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr ""
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr ""
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr ""
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr ""
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr ""
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr ""
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr ""
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr ""
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr ""
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr ""
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr ""
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr ""
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr ""
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr ""
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr ""
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr ""
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr ""
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr ""
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr ""
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr ""
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr ""
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr ""
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr ""
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr ""
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr ""
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr ""
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr ""
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr ""
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:26
+msgid "My Board Games"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr ""
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr ""
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr ""
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr ""
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr ""
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr ""
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr ""
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr ""
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr ""
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr ""
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr ""
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr ""
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr ""
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr ""
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr ""
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr ""
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr ""
+
+#: fetch/entrezfetcher.cpp:485
+msgid "Institution"
+msgstr ""
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr ""
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr ""
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr ""
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr ""
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr ""
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr ""
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr ""
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr ""
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr ""
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr ""
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr ""
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr ""
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr ""
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr ""
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:550
+msgid "&Format: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr ""
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr ""
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+msgid "Update"
+msgstr ""
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr ""
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+msgid "IMDB Rating"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr ""
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr ""
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:71
+msgid "UPC/EAN"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr ""
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr ""
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:343
+msgid "&Username: "
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:348
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:354
+msgid "&Password: "
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:190
+msgid "GCstar Plugin"
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:404
+msgid "Set the collection type of the data returned from the plugin."
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:415
+msgid "Select the GCstar plugin used for the data source."
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:420
+msgid "Author: "
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:58
+msgid "Discogs Audio Search"
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr ""
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr ""
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr ""
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr ""
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr ""
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+
+#: newstuff/dialog.cpp:137
+msgid "The name and license of the selected item"
+msgstr ""
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr ""
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr ""
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr ""
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr ""
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr ""
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr ""
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr ""
+
+#: newstuff/dialog.cpp:413
+msgid "Installing item..."
+msgstr ""
+
+#: translators/bibteximporter.cpp:79
+msgid "No valid bibtex entries were found"
+msgstr ""
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr ""
+
+#: translators/bibteximporter.cpp:287
+msgid "Use Unicode (UTF-8) encoding"
+msgstr ""
+
+#: translators/bibteximporter.cpp:288
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr ""
+
+#: translators/bibteximporter.cpp:289
+msgid "Use user locale (%1) encoding"
+msgstr ""
+
+#: translators/bibteximporter.cpp:293
+msgid "Read the imported file in the local encoding."
+msgstr ""
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr ""
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr ""
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr ""
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr ""
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr ""
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr ""
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr ""
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr ""
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr ""
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr ""
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr ""
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr ""
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr ""
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr ""
+
+#: translators/audiofileimporter.cpp:129
+msgid "Bitrate"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr ""
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:353
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr ""
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr ""
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr ""
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr ""
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr ""
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr ""
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr ""
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr ""
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr ""
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr ""
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr ""
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr ""
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr ""
+
+#: translators/filelistingimporter.cpp:63
+msgid "Scanning files..."
+msgstr ""
+
+#: translators/filelistingimporter.cpp:191
+msgid "File Listing Options"
+msgstr ""
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr ""
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+
+#: translators/filelistingimporter.cpp:198
+msgid "Generate file previews"
+msgstr ""
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr ""
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr ""
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr ""
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr ""
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr ""
+
+#: translators/freedbimporter.cpp:196
+msgid "Select CDDB Entry"
+msgstr ""
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr ""
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr ""
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr ""
+
+#: translators/freedbimporter.cpp:470
+msgid "Various"
+msgstr ""
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr ""
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr ""
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr ""
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr ""
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr ""
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr ""
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr ""
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr ""
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr ""
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr ""
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr ""
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr ""
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr ""
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr ""
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr ""
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr ""
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr ""
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr ""
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr ""
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+
+#: translators/importer.h:100
+msgid "Loading data..."
+msgstr ""
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr ""
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr ""
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr ""
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr ""
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr ""
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr ""
+
+#: translators/csvimporter.cpp:248
+msgid "&Comma"
+msgstr ""
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr ""
+
+#: translators/csvimporter.cpp:259
+msgid "Ta&b"
+msgstr ""
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr ""
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr ""
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+
+#: translators/csvimporter.cpp:298
+msgid "Co&lumn:"
+msgstr ""
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr ""
+
+#: translators/csvimporter.cpp:315
+msgid "&Assign Field"
+msgstr ""
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr ""
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr ""
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr ""
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr ""
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr ""
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr ""
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr ""
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr ""
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr ""
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr ""
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr ""
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr ""
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr ""
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr ""
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr ""
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr ""
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr ""
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr ""
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr ""
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr ""
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr ""
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr ""
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr ""
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr ""
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr ""
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr ""
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr ""
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr ""
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr ""
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr ""
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr ""
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr ""
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr ""
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr ""
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr ""
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr ""
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr ""
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr ""
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr ""
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr ""
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr ""
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr ""
+
+#: field.cpp:492
+msgid "Choice"
+msgstr ""
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr ""
+
+#: field.cpp:496
+msgid "Table"
+msgstr ""
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr ""
+
+#: field.cpp:500
+msgid "Date"
+msgstr ""
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr ""
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr ""
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr ""
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr ""
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr ""
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr ""
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr ""
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr ""
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr ""
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr ""
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr ""
+
+#: importdialog.cpp:62
+msgid "&Replace current collection"
+msgstr ""
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr ""
+
+#: importdialog.cpp:65
+msgid "A&ppend to current collection"
+msgstr ""
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+
+#: importdialog.cpp:69
+msgid "&Merge with current collection"
+msgstr ""
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr ""
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr ""
+
+#: importdialog.cpp:277
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr ""
+
+#: importdialog.cpp:281
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr ""
+
+#: importdialog.cpp:285
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr ""
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr ""
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr ""
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr ""
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr ""
+
+#: entryiconview.cpp:287
+msgid "&Sort By"
+msgstr ""
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr ""
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr ""
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr ""
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr ""
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr ""
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr ""
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr ""
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr ""
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr ""
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr ""
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr ""
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr ""
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr ""
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr ""
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr ""
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr ""
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr ""
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr ""
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr ""
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr ""
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr ""
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr ""
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr ""
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr ""
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr ""
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr ""
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr ""
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr ""
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr ""
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr ""
+
+#: mainwindow.cpp:272
+msgid "New Boa&rd Game Collection"
+msgstr ""
+
+#: mainwindow.cpp:274
+msgid "Create a new board game collection"
+msgstr ""
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr ""
+
+#: mainwindow.cpp:282
+msgid "Create a new file catalog"
+msgstr ""
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr ""
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr ""
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr ""
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr ""
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr ""
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr ""
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr ""
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr ""
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr ""
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr ""
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr ""
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr ""
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr ""
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr ""
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr ""
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr ""
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr ""
+
+#: mainwindow.cpp:352
+msgid "Import Delicious Library Data..."
+msgstr ""
+
+#: mainwindow.cpp:353
+msgid "Import data from Delicious Library"
+msgstr ""
+
+#: mainwindow.cpp:359
+msgid "Import Referencer Data..."
+msgstr ""
+
+#: mainwindow.cpp:360
+msgid "Import data from Referencer"
+msgstr ""
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr ""
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr ""
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr ""
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr ""
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr ""
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr ""
+
+#: mainwindow.cpp:387
+msgid "Import PDF File..."
+msgstr ""
+
+#: mainwindow.cpp:388
+msgid "Import a PDF file"
+msgstr ""
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr ""
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr ""
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr ""
+
+#: mainwindow.cpp:405
+msgid "Import audio CD information"
+msgstr ""
+
+#: mainwindow.cpp:414
+msgid "Import GCstar Data..."
+msgstr ""
+
+#: mainwindow.cpp:415
+msgid "Import a GCstar data file"
+msgstr ""
+
+#: mainwindow.cpp:421
+msgid "Import Griffith Data..."
+msgstr ""
+
+#: mainwindow.cpp:422
+msgid "Import a Griffith database"
+msgstr ""
+
+#: mainwindow.cpp:428
+msgid "Import Ant Movie Catalog Data..."
+msgstr ""
+
+#: mainwindow.cpp:429
+msgid "Import an Ant Movie Catalog data file"
+msgstr ""
+
+#: mainwindow.cpp:435
+msgid "Import File Listing..."
+msgstr ""
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr ""
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr ""
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr ""
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr ""
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr ""
+
+#: mainwindow.cpp:461
+msgid "Export to XML..."
+msgstr ""
+
+#: mainwindow.cpp:462
+msgid "Export to a Tellico XML file"
+msgstr ""
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr ""
+
+#: mainwindow.cpp:469
+msgid "Export to a Tellico Zip file"
+msgstr ""
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr ""
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr ""
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr ""
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr ""
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr ""
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr ""
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr ""
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr ""
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr ""
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr ""
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr ""
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr ""
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr ""
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr ""
+
+#: mainwindow.cpp:524
+msgid "Export to GCfilms..."
+msgstr ""
+
+#: mainwindow.cpp:525
+msgid "Export to a GCfilms data file"
+msgstr ""
+
+#: mainwindow.cpp:531
+msgid "Export to GCstar..."
+msgstr ""
+
+#: mainwindow.cpp:532
+msgid "Export to a GCstar data file"
+msgstr ""
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr ""
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr ""
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr ""
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr ""
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr ""
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr ""
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr ""
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr ""
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr ""
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr ""
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr ""
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr ""
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr ""
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr ""
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr ""
+
+#: controller.cpp:621 mainwindow.cpp:577
+msgid "D&uplicate Entry"
+msgstr ""
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr ""
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr ""
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr ""
+
+#: mainwindow.cpp:585
+msgid "&Merge Entries"
+msgstr ""
+
+#: mainwindow.cpp:588
+msgid "Merge the selected entries"
+msgstr ""
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr ""
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr ""
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr ""
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr ""
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr ""
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr ""
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr ""
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr ""
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr ""
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr ""
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr ""
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr ""
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr ""
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr ""
+
+#: mainwindow.cpp:626
+msgid "Copy Bibtex to Cli&pboard"
+msgstr ""
+
+#: mainwindow.cpp:627
+msgid "Copy bibtex citations to the clipboard"
+msgstr ""
+
+#: mainwindow.cpp:632
+msgid "Cite Entry in &LyX"
+msgstr ""
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr ""
+
+#: mainwindow.cpp:638
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr ""
+
+#: mainwindow.cpp:639
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr ""
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, no-c-format
+msgid "&Update Entry"
+msgstr ""
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr ""
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr ""
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr ""
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr ""
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr ""
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr ""
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr ""
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr ""
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr ""
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr ""
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr ""
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr ""
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr ""
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr ""
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr ""
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr ""
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr ""
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr ""
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:831
+msgid "Welcome to the Tellico Collection Manager"
+msgstr ""
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr ""
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr ""
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr ""
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr ""
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr ""
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr ""
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr ""
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr ""
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr ""
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr ""
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr ""
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr ""
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr ""
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr ""
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr ""
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr ""
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr ""
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr ""
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr ""
+
+#: mainwindow.cpp:1864
+msgid "Import Directory"
+msgstr ""
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr ""
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr ""
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr ""
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr ""
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr ""
+
+#: mainwindow.cpp:1999
+msgid "Creating citations..."
+msgstr ""
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr ""
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr ""
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr ""
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr ""
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr ""
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr ""
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr ""
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr ""
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr ""
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr ""
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr ""
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr ""
+
+#: controller.cpp:627
+msgid "D&uplicate Entries"
+msgstr ""
+
+#: controller.cpp:628
+msgid "&Update Entries"
+msgstr ""
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr ""
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr ""
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr ""
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr ""
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr ""
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr ""
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr ""
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr ""
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr ""
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr ""
+
+#: main.cpp:31
+msgid "File to open"
+msgstr ""
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr ""
+
+#: main.cpp:44
+msgid "Icons"
+msgstr ""
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr ""
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr ""
+
+#: main.cpp:50
+msgid "Author of libcsv library"
+msgstr ""
+
+#: main.cpp:52
+msgid "Author of rtf2html library"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr ""
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr ""
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr ""
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr ""
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr ""
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr ""
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr ""
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr ""
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr ""
+
+#: configdialog.cpp:213
+msgid "Image Storage Options"
+msgstr ""
+
+#: configdialog.cpp:214
+msgid "Store images in data file"
+msgstr ""
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr ""
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr ""
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr ""
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr ""
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr ""
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr ""
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr ""
+
+#: configdialog.cpp:243
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+
+#: configdialog.cpp:249
+msgid "Artic&les:"
+msgstr ""
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr ""
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr ""
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr ""
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr ""
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr ""
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr ""
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr ""
+
+#: configdialog.cpp:313
+msgid "&Group the entries"
+msgstr ""
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr ""
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr ""
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr ""
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr ""
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr ""
+
+#: configdialog.cpp:369
+msgid "Template:"
+msgstr ""
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr ""
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr ""
+
+#: configdialog.cpp:398
+msgid "Font Options"
+msgstr ""
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr ""
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr ""
+
+#: configdialog.cpp:425
+msgid "Color Options"
+msgstr ""
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr ""
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr ""
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr ""
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr ""
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr ""
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr ""
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr ""
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr ""
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr ""
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr ""
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr ""
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr ""
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr ""
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr ""
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr ""
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr ""
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr ""
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr ""
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr ""
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr ""
+
+#: configdialog.cpp:533
+msgid "Click to modify the selected data source."
+msgstr ""
+
+#: configdialog.cpp:536
+msgid "Click to delete the selected data source."
+msgstr ""
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr ""
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr ""
+
+#: configdialog.cpp:1049
+msgid "Delete Template"
+msgstr ""
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr ""
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr ""
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr ""
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr ""
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr ""
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr ""
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr ""
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr ""
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr ""
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr ""
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr ""
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr ""
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr ""
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr ""
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr ""
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr ""
+
+#: collectionfactory.cpp:135
+msgid "Board Game Collection"
+msgstr ""
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr ""
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr ""
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr ""
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr ""
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr ""
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr ""
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr ""
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr ""
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr ""
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr ""
+
+#: exportdialog.cpp:72
+msgid "Encode the exported file in the local encoding."
+msgstr ""
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr ""
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr ""
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr ""
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr ""
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr ""
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr ""
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr ""
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr ""
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr ""
+
+#: fetchdialog.cpp:138
+msgid "Edit List..."
+msgstr ""
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr ""
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr ""
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr ""
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr ""
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr ""
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr ""
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr ""
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr ""
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr ""
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr ""
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+
+#: fetchdialog.cpp:412
+msgid "No results were found for the following ISBN values:"
+msgstr ""
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr ""
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr ""
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr ""
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr ""
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr ""
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr ""
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr ""
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr ""
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr ""
+
+#: entryeditdialog.cpp:77
+msgid "Go to the previous entry in the collection"
+msgstr ""
+
+#: entryeditdialog.cpp:82
+msgid "Go to the next entry in the collection"
+msgstr ""
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr ""
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr ""
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr ""
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr ""
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr ""
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr ""
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr ""
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr ""
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr ""
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr ""
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr ""
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr ""
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr ""
+
+#: tellico_kernel.cpp:377
+msgid "Entry 1"
+msgstr ""
+
+#: tellico_kernel.cpp:378
+msgid "Entry 2"
+msgstr ""
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr ""
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+msgid "Merge Entries"
+msgstr ""
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr ""
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr ""
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr ""
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr ""
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr ""
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr ""
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr ""
+
+#: entrymerger.cpp:35
+msgid "Merging entries..."
+msgstr ""
+
+#: entrymerger.cpp:49
+msgid "Total merged/scanned entries: %1/%2"
+msgstr ""
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr ""
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr ""
+
+#: xslt.cpp:5
+msgid "Total:"
+msgstr ""
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr ""
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr ""
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr ""
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr ""
+
+#: xslt.cpp:14 xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr ""
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr ""
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ""
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr ""
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr ""
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+msgid "Generated by Tellico"
+msgstr ""
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr ""
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr ""
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr ""
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr ""
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr ""
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr ""
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr ""
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr ""
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr ""
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr ""
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr ""
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr ""
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr ""
+
+#: z3950.cpp:6
+msgid "Sudoc (France)"
+msgstr ""
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr ""
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr ""
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr ""
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr ""
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr ""
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr ""
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr ""
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr ""
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr ""
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr ""
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr ""
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr ""
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr ""
diff --git a/po/tr.po b/po/tr.po
new file mode 100644
index 0000000..3f29cf0
--- /dev/null
+++ b/po/tr.po
@@ -0,0 +1,5376 @@
+# translation of tellico.po to Türkçe
+#
+# Ali Isingor <isingor@gmail.com>, 2007.
+# Kunter Kutlu <kunterkutlu@gmail.com>, 2007.
+msgid ""
+msgstr ""
+"Project-Id-Version: tellico\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2007-07-03 02:14+0300\n"
+"Last-Translator: Kunter Kutlu <kunterkutlu@gmail.com>\n"
+"Language-Team: Türkçe <tr@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr "<qt>Tellico, sunucu soketi <b>%1</b> iken yazamaz</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr "OpenOffice.org'a Bağlanılıyor..."
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr "OpenOffice.org Bağlantısı"
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+"Tellico OpenOffice.Org a bağlanamadı. Lütfen aşağıdaki bağlantı "
+"ayarlarını ve OpenOffice.Org Kelime İşlemcisinin çalıştığını "
+"onalayınız."
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr "Borulama"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr "TCP/IP"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr "Sütunu Yeniden Adlandır"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr "Yeni sütun adı:"
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr "Sütun %1"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr "Sütunu Yeniden Adlandır..."
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr "Satır Ekle"
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr "Satırı Kaldır"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr "Satırı Yukarı Taşı"
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr "Satırı Aşağı Taşı"
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr "Tabloyu Kaldır"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr "Şablon Önizleme"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Ayarla"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr "%1:"
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Daha Fazla"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Daha Az"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Temizle"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Resim Seçin..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr ""
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr ""
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Değiştir %1"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "İliştirme Kolleksiyonu"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Birleşme Kolleksiyonu"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Değiştirme Kolleksiyonu"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr "Değiştirme Girdileri"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "Ekleme %1 Alanı"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Değiştirme %1 Alanı"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Silme %1 Alanı"
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr "Ekleme Girdileri"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Ekle %1"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Yeniden İsimlendirme Kolleksiyonu"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Kiralamayı Değiştir"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Filitre Ekle"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Filitre Değiştir"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Filitre Sil"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Kontrol Parçaları"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Kontrol %1"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Girdileri Sil"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Sil %1"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Yeniden Düzenleme Alanları"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Kayıt Yaptırma Girdileri"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Kayıt Yap %1"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Genel"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Durum"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Kişisel"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Pullarım"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Başlık"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Özellikler"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Adlandırma"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "Ülke"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Yayın Yılı"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Renk"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Scott#"
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr "Süper,Harika,Çok İyi,İyi,Sıradan,Zayıf"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Derece"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "İptal Edildi"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Tutturulmuş"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Ortalamak"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Yapıştırılmış"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Satın Alma Tarihi"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Satın Alma Fiyatı"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Konum"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Hediye"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Görüntü"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Yorumlar"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Yayınlama"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Sınıflandırma"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Çizgi Romanlarım"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Altbaşlık"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Yazar"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr "Artist"
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Seri"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Sayı"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Yayıncı"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Baskı"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Yayın Yılı"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Sayfa Sayısı"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Dil"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Tür"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Anahtar Kelime"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr "Mükemmel,Mükemmele Yakın,Çok Hoş,Hoş,Çok İyi,İyi,Makul,Zayıf"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "İmzalı"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Ödünç"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Ön Kapak"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Madeni Paralarım"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Tür"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Yılı"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Darphane Damgası"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Madeni Para Dizisi"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+"Dayanıklı-65,Dayanıklı-60,Kullanılmamış-65,Kullanılmamış-60,Nerdeys"
+"e Tedavül Edilmemiş-55,Nerdeyse Tedavül Edilmemiş-50,Harika-40,Çok "
+"Güzel-30,Çok Güzel-20,Güzel-12,Çok İyi-8,İyi-4,Sıradan "
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr "PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Sınıflandırma Servisleri"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "Gözlemleme"
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "Diğer Taraf"
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Kitaplarım"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Yazar"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Ciltli"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "Karton Kapak"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Satılır Karton Kapak"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "E-Kitap"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Dergi"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Gazete"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Ciltleme"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Kopyalama Hakkı Yılı"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN#"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Uluslararası Standart Kitap Numarası"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN#"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr "Kongre Kütüphanesi Kontrol Numarası"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr ""
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Seri Numarası"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Yeni"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Kullanılmış"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Okunmuş"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Puan"
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr "Dosyalarım"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "İsim"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Cilt"
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr "Dizin"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr "Dosya Tipi"
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr "Boyut"
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr "İzinler"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr "Sahip"
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr "Gurup"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr "Yaratıldı"
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr "Değiştirildi"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr "Meta Bilgisi"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Özellik"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Değer"
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr "Simge"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Şaraplarım"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Üreticisi"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Ünvan"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Çeşitsel"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "İmal"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Kırmızı Şarap"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Beyaz Şarap"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Köpüklü Şarap"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Miktar"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "İçen"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Etiket görseli"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Diğer İnsanlar"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Özellikler"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Videolarım"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "DivX"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr ""
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+#, fuzzy
+msgid "HD DVD"
+msgstr "DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Ortam"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Üretim Yılı"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "G (USA),PG (USA),PG - 13 (USA),R (USA),U (USA)"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Sertifikalandırma"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "1. Bölge"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "2. Bölge"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "3. Bölge"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "4. Bölge"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "5. Bölge"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "6. Bölge"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "7. Bölge"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "8. Bölge"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Bölge"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Ülke"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Biçim"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Senaryo"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr "Aktör/Aktris"
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr "Rol"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr "Oyuncu üyelerin, oynadıkları rollerle beraber bir tablosu"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Yönetmen"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Besteci"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Stüdyo"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Dil İzleri"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Altyazı Dilleri"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Ses İzleri"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Çalışma Zamanı"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "Videonun Çalışma Zamanı (Dakikalar ile)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Görüntü Oranı"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Geniş Ekran"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Siyah-Beyaz"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Renk Modu"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Yönetmenin Çıkardıkları"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Tema Özeti"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Kişisel Puan"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Kapak"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "Oyunlarım"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr "Xbox 360"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr "PlayStation3"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr "Nintendo Wii"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr ""
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Platform"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Yayınlanma Yılı"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Yayıncı"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Geliştirici"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+"Sınıflandırılmamış, Sadece Yetişkinler, Erginler, Gençler, Herkes, "
+"Çocuklar, Askıda Olanlar"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "ESRB Sınıflandırması"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Tamamlanmış"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Kartlarım"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Oyuncu"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Takım"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Marka"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Kart Numarası"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Kart Türü"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Cephe Görüntüsü"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Arka Görüntüsü"
+
+#: collections/boardgamecollection.cpp:26
+#, fuzzy
+msgid "My Board Games"
+msgstr "Oyunlarım"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr ""
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Bibliyografya"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Girdi Tipi"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+"Bu birdi çeşitleri bibtex'e özgüdür. Bibtex dökümanlarına gözatın."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Bibtex Anahtarı"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Kitap Adı"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Yayımcı"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Organizasyon"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Adres"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Ay"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Sayı"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Nasıl Yayınlandı"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Bölüm"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Çapraz-Referans"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Özet"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Notlar"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Müziğim"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Albüm"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "Compact Disc"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Kaset"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Taş Plak"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Sanatçı"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Etiket"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Parçalar"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr "Süre"
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr ""
+"bir,ve,gibi,de,ama,tarafından,için,den,iç,içine,yahut,nin,üst,üstüne,v"
+"eya,dış,e,yukarı,ile"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr ""
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr ""
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr ""
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr "ISBNdb.com"
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "%1 bu kolleksiyon tipini aramaya izin vermiyor."
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "%1:%2/%3 den sonuçlar"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "Bu kaynak seçenek içermiyor."
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "Entrez Veri Tabanı"
+
+#: fetch/entrezfetcher.cpp:485
+msgid "Institution"
+msgstr "Kuruluş"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Sorgulama Hatası!"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Bağlantı arama hatası %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Kayıt sözdizimi hatası"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Bağlantı hatası %1: %2"
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr "SRU Sunucusu"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "ABD Kongre Kütüphanesi"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr "Ev&sahibi: "
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr "Sunucunun host adını giriniz."
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Bağlantı Noktası: "
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr "Sunucunun port numarasını girin. Varsayılan %1."
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr "Yol: "
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr "Sunucu tarafından kullanılan veritabanının yolunu girin."
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr "Biçim: "
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr "Sunucu tarafından kullanılan sonuç biçimini girin."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr "Yahoo! Audio İçinde Ara"
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr "Kapak görseli yüklenemedi."
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr "Amazon Linki"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (ABD)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (Britanya)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Almanya)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Japonya)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (Fransa)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Kanada)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Amazon.com Web Hizmetleri"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "&Ülke: "
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "Amerika Birleşik Devletleri"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Birleşik Krallık"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Almanya"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Japonya"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "Fransa"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Kanada"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon.com, birkaç farklı yerel siteden veri tedarik eder. Bu veri "
+"kaynağını kullanmak için istediğiniz birini seçiniz."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "Res&im boyutu: "
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Küçük Resim"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Orta Boy Resim"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Büyük Resim"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Resimsiz"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"Aynı zamanda kapak resimleride indirilebilir. Fakat, kolleksiyon "
+"içerisinde bulunan birçok büyük boyutlu görüntü dosyası performansı "
+"düşürebilir."
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "&Birleşimin ID si: "
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+"Birleşimin ID si Amazon.com web servislerine erişenleri saptar ve bu "
+"Amazon.com sitesindeki herhangi bir bağ içerisine de eklenmiştir."
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr "z39.50 Sunucu"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr "Önceden hazırlanmış &sunucuyu kullan:"
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "Ve&ritabanı: "
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr "Sunucu tarafından kullanılan veritabanı ismini girin."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "Ka&rakter kodlaması: "
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"z39.50 sunucu tarafından kullanılan karakter dizisi kodlamasını girin. "
+"En çok kullanılan seçim ISO-8859-1 le birlikte MARC-8 dir."
+
+#: fetch/z3950fetcher.cpp:550
+msgid "&Format: "
+msgstr "&Biçim: "
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr "Otomatik-Farketme"
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+"z39.50 sunucunun veri düzenini girin. Eğer otomatik farketme seçili ise , "
+"Tellico en iyi ayarları otomatik olarak farketmeye çalışacaktır."
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "K&ullanıcı: "
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Seçimlik"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"z39.50 veritabanı doğrulaması için kullanıcı adını girin. Çoğu "
+"sunucu bir taneye ihtiyaç duymaz."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "Pa&rola: "
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"z39.50 veritabanı doğrulaması için parolayı girin. Çoğu sunucu bir "
+"taneye ihtiyaç duymaz. Parola Tellico konfigurasyon dosyasında metin "
+"olarak kaydedilecektir."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr "Çizer"
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Harici Uygulama"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "Koleksiyon &türü:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr "Dışardaki bir uygulamadan gelen verinin kolleksiyon tipini ayarla."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr "&Sonuç tipi: "
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr "Dışardaki bir uygulamadan gelen verinin sonuç tipini ayarla."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "Uygulama &adresi: "
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+"Uygulamanın, geçerli bir Tellico veri dosyası çıktısı verbilmesi "
+"için adresini ayarla."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr "Veri kaynağı tarafından desteklenen arama anahtarlarını seçiniz."
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+"İhtiyaç duyulabilecek herhangi bir görüşü ekleyiniz. <b>%1</b>, aranan "
+"ifade ile değiştirilecektir."
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr "Görüşler"
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+msgid "Update"
+msgstr "Güncelle"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+#, fuzzy
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+"<p>Hazır güncellemeleri aramak üzere kullanılacak konuları girin.</p> "
+"<p>Düzen, <i>Bağımlı</i> alanlarla aynıdır, bu bağımlı alanların "
+"değerleri ise <i>%{author}</i> gibi bağın içerisnde yer alır. Detaylar "
+"için dökümama bakınız.</p>"
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Kaynak Seçenekleri"
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr "Hazır Alanlar"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "İnternet Film Veritabanı"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "IMDB Sonuçlarını Seçin"
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+"<qt>Aramanız iki benzer sonuç döndürdü. Lütfen aşağıdakilerden "
+"birini seçiniz.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Arama sonuçlarından birini seçin.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr "IMDB Linki"
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Alternatif İsimler"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+msgid "IMDB Rating"
+msgstr "IMDB Puanı"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Onaylamalar"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"İnternet Film Veritabanları, birkaç farklı sunucu kullanır. "
+"İstediğiniz birini kullanmak için seçin."
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr "&En fazla rol alanlar: "
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+"Rol alan üyelerin listesi, birçok insanı içerwbilir. Aramadan dönecek "
+"sonuçların en fazla ne kadar olması gerektiğini ayarlayın."
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr "Kapak resm&ini indir"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr "İnternet Kitapevi (ibs.it)"
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Kişi"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+#, fuzzy
+msgid "UPC/EAN"
+msgstr "UPC"
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Anahtar kelime"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "İşlenmemiş Sorgu"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr "Orjinal Başlık"
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr "Dağıtıcı"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr "Bölümler"
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:343
+#, fuzzy
+msgid "&Username: "
+msgstr "K&ullanıcı: "
+
+#: fetch/crossreffetcher.cpp:348
+#, fuzzy
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+"z39.50 veritabanı doğrulaması için parolayı girin. Çoğu sunucu bir "
+"taneye ihtiyaç duymaz. Parola Tellico konfigurasyon dosyasında metin "
+"olarak kaydedilecektir."
+
+#: fetch/crossreffetcher.cpp:354
+#, fuzzy
+msgid "&Password: "
+msgstr "Pa&rola: "
+
+#: fetch/gcstarpluginfetcher.cpp:190
+#, fuzzy
+msgid "GCstar Plugin"
+msgstr "GCstar"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+#, fuzzy
+msgid "Set the collection type of the data returned from the plugin."
+msgstr "Dışardaki bir uygulamadan gelen verinin kolleksiyon tipini ayarla."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:415
+#, fuzzy
+msgid "Select the GCstar plugin used for the data source."
+msgstr "Veri kaynağı tarafından desteklenen arama anahtarlarını seçiniz."
+
+#: fetch/gcstarpluginfetcher.cpp:420
+#, fuzzy
+msgid "Author: "
+msgstr "Yazar"
+
+#: fetch/discogsfetcher.cpp:58
+#, fuzzy
+msgid "Discogs Audio Search"
+msgstr "Yahoo! Audio İçinde Ara"
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr ""
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr "İstekli Yeni Eleman Edin"
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr "Sürüm"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr "İndirmeler"
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr "Yatın Notları"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+"Bu, indirme için hazır maddelerin yer aldığı bir listedir. Önceden "
+"indirilmiş olan maddelerin başında checkbox simgesi bulunmaktadır, yeni "
+"versiyonları hazır olanlarda ise güncelle simgesi mevcuttur"
+
+#: newstuff/dialog.cpp:137
+msgid "The name and license of the selected item"
+msgstr "Seçili maddenin, isim ve lisansı"
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr "Seçili maddenin yazarı"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr "Kur"
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr "Seçili şablonu indir ve kur."
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+"Seçili scripti indir ve kur. Bazı scriptler kurulduktan sonra "
+"konfigurasyona ihtiyaç duyabilir."
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr "Seçili maddenin bir açıklaması burada gösterilmiştir."
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr "Bilgi indiriliyor..."
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Hazır."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr "Güncelle"
+
+#: newstuff/dialog.cpp:413
+msgid "Installing item..."
+msgstr "Öğe kuruluyor..."
+
+#: translators/bibteximporter.cpp:79
+#, fuzzy
+msgid "No valid bibtex entries were found"
+msgstr "Dosya - %1 içerisinde, geçerli bir bibtext girdisi bulunamadı"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr "Dosya - %1 içerisinde, geçerli bir bibtext girdisi bulunamadı"
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Bibtex Seçenekleri"
+
+#: translators/bibteximporter.cpp:287
+#, fuzzy
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "(UTF-8) Karakter Kodunda Şifrele"
+
+#: translators/bibteximporter.cpp:288
+#, fuzzy
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Dışa aktarılan dosyayı (UTF-8) karakter kodlaması ile şifrele."
+
+#: translators/bibteximporter.cpp:289
+#, fuzzy
+msgid "Use user locale (%1) encoding"
+msgstr "Kullanıcı konumu (%1) de şifrele"
+
+#: translators/bibteximporter.cpp:293
+#, fuzzy
+msgid "Read the imported file in the local encoding."
+msgstr "Dışa aktarılan dosyayı yerel düzende şifrele."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "Tellico Zip Dosyası"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Tellico Dosyaları (*.tc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Tüm Dosyalar"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt><i>%1</i> olarak adlandırılan bir Alexandria Kütüphanesi zaten "
+"mevcut. Bu kütüphanede mevcut olan herhangi bir kitabın üzerine "
+"yazılabilir.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr "%2 sütununda ve %1 sırasında bir XML kodlama hatası mevcut."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "Qt den gelen hata mesajı:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Bu, Tellico'nun gelecek sürümündendir."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Tellico, dosyayı daha yeni bir döküman düzenine çeviriyor. Eğer bu "
+"dosyayı okumada eski bir Tellico sürümü kullanılırsa, veri kaybı "
+"meydana gelebilir."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Bilinmez"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "Dosya boş."
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "Dosya herhangi bir veri kolleksiyonu içermiyor."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Okunmamış Kitaplar"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Eski Filmler"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "80'lerin Müziği"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Favoriler"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Ses dosyaları taranıyor..."
+
+#: translators/audiofileimporter.cpp:129
+#, fuzzy
+msgid "Bitrate"
+msgstr "Bibtex"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(Çeşitli)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Ses Dosyası Seçenekleri"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Yinelemeli &dizin araması"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+"Eğer işaretlendiyse, dizinler, ses dosyaları için yinelemeli olarak "
+"arandı."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr "Dosya konumunu ekley&in"
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr ""
+"Eğer işaretlendiyse, Herbir parçanın dosya ismi, girdi alanlarına "
+"eklenir."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:353
+#, fuzzy
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr ""
+"Eğer işaretlendiyse, Herbir parçanın dosya ismi, girdi alanlarına "
+"eklenir."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|CSV Dosyaları (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "CSV Seçenekleri"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Alan isimlerini, sütun başlıkları olarak ekleyin"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr ""
+"Eğer işaretlendiyse, alan ismiyle beraber, bir başlık satırıda "
+"eklenecektir."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Sınırlayıcı"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"Dosya içerisinde, değerleri ayırmak için, virgüle ilave olarak diğer "
+"karakterlerde sınırlayıcı olarak kullanılabilir."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Virgül"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Sınırlayıcı olarak vir virgül kullan."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Noktalı Virgül"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr "Sınırlayıcı olarak bir noktalı virgül kullan."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Sekme"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr "Sınırlayıcı olarak bir sekme kullan."
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Diğer"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Sınırlayıcı olarak geleneksel bir karaketer dizisi kullan."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr ""
+"İki nokta üst üste gibi geleneksel bir karakter dizisi, sınırlayıcı "
+"olarak kullanılabilir."
+
+#: translators/filelistingimporter.cpp:63
+msgid "Scanning files..."
+msgstr "Dosyalar taranıyor..."
+
+#: translators/filelistingimporter.cpp:191
+msgid "File Listing Options"
+msgstr "Dosya Listeleme Seçenekleri"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr "Yinelemeli dizin araması"
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+"Eğer işaretli ise, klasörler, bütün dosyalar için yinelemeli olarak "
+"aranmıştır."
+
+#: translators/filelistingimporter.cpp:198
+msgid "Generate file previews"
+msgstr "Dosya önizleme oluştur"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+"Eğer işaretli ise, dosya içeriğinin önizlemesi oluşturuldu, bu olay, "
+"dizin listelemesini yavaşlatabilir."
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "ONIX Arşivi"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.zip|Zip Dosyaları (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "ONIX Arşivi Seçenekleri"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Arşivdeki resimleri ekle"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Eğer işaretlenmişse, döküman içerisindeki resimler, ziplenmiş ONIX "
+"arşivine dahil edilecektir."
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr "<qt>Tellico CD-ROM aygıtına erişemedi - <i>%1</i>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+msgid "Select CDDB Entry"
+msgstr "CDDB Girdisi Seçin"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr "Bir CDDB girdisi Seç:"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr "<qt>CD ye eşleşen bir kayıt bulunamadı.</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr "<qt>Tellico, CD aramasını bitiremedi.</qt>"
+
+#: translators/freedbimporter.cpp:470
+msgid "Various"
+msgstr "Çeşitli"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Ses CD'si Seçenekleri"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "CD-ROM aygıtından veri oku"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr "CD-ROM aygıtının konumunu seçin veya giriniz."
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Sadece bütün CDDB önbellek dosyalarını oku"
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr ""
+"Varsayılan önbellek dizininde bulunan CDDB önbellek dosyalarındaki "
+"bütün verileri yinelemeli olarak oku."
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr "GCfilms"
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.gcf|GCfilms Veri Dosyaları (*.gcf)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.gcs|GCstar Veri Dosyaları (*.gcs)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "XSLT Seçenekleri"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "XSLT dosyası:"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr "Tellico XML verilerini dönüştüren XSLT dosyasını seçiniz."
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Alexandria Seçenekleri"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr "&Kütüphane:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "Bibtexml"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Bibtexml Dosyaları (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|XMLDosyaları (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Tellico XML Seçenekleri"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "XML dökümanındaki resim dosyalarını içer"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Eğer işaretliyse, döküman içerisindeki resimler, base64 şifrelenmiş "
+"elementleri olarak XML içine ekleneceklerdir."
+
+#: translators/importer.h:100
+msgid "Loading data..."
+msgstr "Dosya Yükleniyor..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr "Yükleniyor %1..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "Bibtex"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Bibtex Dosyaları (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Karakter dizisi makrolarını genişlet"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Eğer işaretliyse, karakter dizisi makroları genişletilecek ve hiç bir "
+"@string{} girdisi yazılmayacaktır."
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "URL paketlerini kullan"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr ""
+"Eğer işaretliyse, herhagi bir URL alanı, bir \\url ifadesi içinde "
+"saklanır."
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Girdileri, boş alıntı anahtarları ile es geç"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr ""
+"Eğer işaretliyse, bibtex alıntı anahtarı olmayan herhangi bir girdi es "
+"geçilecektir."
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Bibtex Tırnak Stili:"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Bağlar"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Tırnak işareti"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"<qt>Tırnka işareti stili, bibtex dosyasını dışarı aktarırken "
+"kullanılır. Bütün alan değerleri, bağ ve tırnak işaretlerinden "
+"sıyrılır.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr "İçeri aktarılan kolleksiyonun tipini seçiniz."
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr "&ilk Satır, alan etiketini içerir"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr "Eğer işaretli ise, ilk satır alan etiketi olarak kullanılır."
+
+#: translators/csvimporter.cpp:248
+msgid "&Comma"
+msgstr "&virgül"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr "&Noktalı virgül"
+
+#: translators/csvimporter.cpp:259
+msgid "Ta&b"
+msgstr "&Çıkıntı"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr "&Diğer:"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "Tablo, CSV dosyasının ilk beş satırını gösterir."
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt>Koleksiyon içindeki alana uyan her sütunu, bir sütun ve alan seçerek "
+"ayarlayın, sonra <i>Alan Atama</i> tuşuna basın.</qt>"
+
+#: translators/csvimporter.cpp:298
+msgid "Co&lumn:"
+msgstr "&Sütun:"
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr "Bu sütun&da veri alanı:"
+
+#: translators/csvimporter.cpp:315
+msgid "&Assign Field"
+msgstr "&Atama Alanı"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Yeni Alan"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|Pilot Veritabanı Dosyaları (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Sütunları Göster"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "PilotDB Seçenekleri"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Veritabanı için PDA yedekleme etiketi oluştur"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>Dosya, geçerli bir GCstar veri dosyası değil.</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Tellico, XSLT çalışmasında bir hataya rastladı."
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr ""
+"Dosyayı içeri aktarmak için, geçerli bir XSLT dosyasına ihtiyaç var."
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|XSL Dosyaları (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|HTML Dosyaları (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Herkes"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(%1 tarafından guruplandırılmıştır)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "HTML Seçenekleri"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Alan başlıklarını yazdır"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr ""
+"Eğer seçiliyse, alan isimleri, tablo başlıkları olarak yazılacaktır."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Girdileri gurupla"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr ""
+"Eğer seçiliyse, girdiler, seçili alan tarafından guruplandırılacaktır."
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Bireysel girdi dosyalarını dışa aktar"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr ""
+"Eğer işaretliyle, her bir girdi için bireysel dosyalar yaratılacaktır."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+#, fuzzy
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr "Tellico -%1 dosyasından resim dosyası yükleyemiyor."
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Veri Kaynağı Özellikleri"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "&Kaynak adı: "
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr ""
+"İsim, veri kaynağını belirtir ve eşsiz ve açıklayıcı olmalıdır."
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "Kaynak &tipi: "
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr "Tellico birçok farklı veri kaynağını destekler."
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr ""
+"Kaynaktan güncellemeler, kullanıcı verilerinin üzerine yazılacaktır"
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Eğer seçiliyse, girdi güncellemeleri, var olan bilgilerin üzerine "
+"yazılacaktır."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Herhangi Bir Alan"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "İçerir"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "içermez"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "eşit"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "eşit değil"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "regexp ile eşleşir"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "regexp ile eşleşmez"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Düzenle..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "İleri Seviye Filtre"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Filitre Kriterleri"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "İz&leyenleri eşleştir"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "İzle&yenlerden herhangi birini eşleştir"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Filitre adı:"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "&Filitreyi Kaydet"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Basit Metin"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Parağraf"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Seçim"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Seçme Kutusu"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Tablo"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Bağımlı"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Tarih"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr "Güncelliyor %1..."
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr "Girdiler güncelleniyor..."
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr "Girdileri Güncelle"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr "Güncelleniyor <b>%1</b>..."
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr "Eşleştirmeyi Seç"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+"<qt><b>%1</b>, <b>%2</b> ile eşleşebilecek birçok sonuç döndürdü, "
+"girdi şu anda koleksiyonda. Lütfen doğru bir eşleştirme seçiniz.</qt>"
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Bütün Gurupları Genişlet"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Bütün Gurupları Çökert"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Guruba göre Süz"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1 (Hesaba göre Sıralama)"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Gurup"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Seçenekleri İçeri Aktar"
+
+#: importdialog.cpp:62
+msgid "&Replace current collection"
+msgstr "Bu kolleksiyonu yeniden yerleşti&r"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr "Bu koleksiyonu, içeri aktarılan dosyanın içeriği ile değiştir."
+
+#: importdialog.cpp:65
+msgid "A&ppend to current collection"
+msgstr "&Bu kolleksiyonun üzerine ekle"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"İçeri aktarılan dosyanın içeriğini, bu koleksiyonun üzerine ekle. Bu "
+"sadece koleksiyon tipleri uyuştuğunda mümkündür."
+
+#: importdialog.cpp:69
+msgid "&Merge with current collection"
+msgstr "&Bu kolleksiyon ile birleştir"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"İçeri aktarılan dosyanın içeriği ile, bu koleksiyonu birleştir. Bu "
+"sadece koleksiyon tipleri uyuştuğunda mümkündür. Birleşme olması "
+"için, girdilerin kesinlikle uyuşması gerekir."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&İçe Aktar"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|RIS Dosyaları (*.ris)"
+
+#: importdialog.cpp:277
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.amc|AMC Veri Dosyaları (*.amc)"
+
+#: importdialog.cpp:281
+#, fuzzy
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdb|Pilot Veritabanı Dosyaları (*.pdb)"
+
+#: importdialog.cpp:285
+#, fuzzy
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.ris|RIS Dosyaları (*.ris)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico -%1 dosyasını yükleyemiyor."
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico -%1 dosyasına yazamıyor."
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico -%1 dosyasını dışarı yükleyemiyor."
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Sadece, bu koleksiyondaki gibi aynı tipteki verilerden oluşan "
+"koleksiyonlar bir biri üzerine eklenebilir. Bu koleksiyonda hiç bir "
+"değişiklik olmadı."
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Sadece bundaki gibi, aynı tipteki verilerden oluşan koleksiyonlar "
+"birleşebilir. Bu koleksiyonda hiç bir değişiklik olmadı."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr "Tellico -%1 dosyasından resim dosyası yükleyemiyor."
+
+#: entryiconview.cpp:287
+#, fuzzy
+msgid "&Sort By"
+msgstr "&Bağlantı Noktası: "
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Kiralama Diyaloğu"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "İzleyen parçalar gözden geçirildi:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "İzleyen parça kirada:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "Kira&landı:"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Bu parçayı sizden kiralayan kişinin ismini giriniz. Bu tuşa tıklamanız "
+"size adres defterinizden seçmenize olanak verir."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "Kira&lanma zamanı:"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+"Çıkış tarihi, sizin parçayları kiraladığınız tarihtir. Ön "
+"tanımlı olarak, gün olarak bugünün tarihi kullanılır."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "Te&slim tarihi:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"Teslim tarihi, parçaların geri size döndüğü tarihtir. Aktif "
+"takviminize kiralamayı eklemeyi düşünmedikçe gerekli değildir."
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Not:"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr "Kiralama hakkında notlarda ekleyebilirsiniz."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "&Aktif takvime bir hatırlatıcı ekle"
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"<qt>Bu kutucuğu seçmek, KOrganizer ile görebileceğeniz aktif takviminize "
+"<em>Yapmak için</em> öğesini ekler. Bu kutucuk sadece teslim tarihi "
+"ayarlanmışsa aktif olacaktır."
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Yeni koleksiyon yarat"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Yeni Kita&p Koleksiyonu"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Yeni kitap koleksiyonu yarat"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Yen&i Bibliografya"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Yeni bir bibtex bibliyografyası yarat"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Yeni &Çizgi Roman Koleksiyonu"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Yeni çizgi roman koleksiyonu yarat"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Yeni &Video Koleksiyonu"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Yeni video koleksiyonu yarat"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Yeni &Müzik Koleksiyonu"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Yeni müzik koleksiyonu yarat"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Yeni Madeni Para K&oleksiyonu"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Yeni madeni para koleksiyonu yarat"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Yeni Pul Kolek&siyonu"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Yeni pul koleksiyonu yarat"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Yeni K&art Kolleksiyonu"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Yeni bir ticari kart koleksiyonu yarat"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Yeni &Şarap Koleksiyonu"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Yeni şarap koleksiyonu yarat"
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Yeni O&yun Koleksiyonu"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Yeni oyun koleksiyonu yarat"
+
+#: mainwindow.cpp:272
+#, fuzzy
+msgid "New Boa&rd Game Collection"
+msgstr "Yeni O&yun Koleksiyonu"
+
+#: mainwindow.cpp:274
+#, fuzzy
+msgid "Create a new board game collection"
+msgstr "Yeni oyun koleksiyonu yarat"
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr "Yeni Dos&ya Kataloğu"
+
+#: mainwindow.cpp:282
+msgid "Create a new file catalog"
+msgstr "Yeni dosya kataloğu yarat"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Yeni Size &Özel Koleksiyon"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Size özel yeni bir koleksiyon oluştur"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Var olan bir döküman aç"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr "Güncel kullanılan bir dosya aç"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Dökümanı kaydet"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Dökümanı farklı bir dosya olarak kaydet..."
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Dökümanın içeriğini yazdır..."
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Uygulamadan çık"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Diğer Formatlardan veri kolleksiyonu aktar"
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Tellico verisi aktar..."
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Diğer bir Tellico veri dosyasını içe aktar"
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "CSV Verisini İçeri Aktar..."
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Bir CSV dosyasını içeri aktar"
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "MODS Verisini İçeri Aktar..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Bir MODS veri dosyasını içeri aktar"
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Alexandria Verisini İçe Aktar..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Alexandria kitap kolleksiyon yöneticisinden veri aktar"
+
+#: mainwindow.cpp:352
+#, fuzzy
+msgid "Import Delicious Library Data..."
+msgstr "Tellico verisi aktar..."
+
+#: mainwindow.cpp:353
+#, fuzzy
+msgid "Import data from Delicious Library"
+msgstr "Ses dosyalarından meta-veri içeri aktar"
+
+#: mainwindow.cpp:359
+#, fuzzy
+msgid "Import Referencer Data..."
+msgstr "RIS Verisi Aktar..."
+
+#: mainwindow.cpp:360
+#, fuzzy
+msgid "Import data from Referencer"
+msgstr "Bir RIS referans dosyasını içeri aktar"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Bibtex Verisini İçeri Aktar..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Bir bibtex bibliyografya dosyasını içeri aktar"
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Bibtexml Verisini İçeri Aktar..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Bir Bibtexml bibliyografya dosyasını içeri aktar"
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "RIS Verisi Aktar..."
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Bir RIS referans dosyasını içeri aktar"
+
+#: mainwindow.cpp:387
+#, fuzzy
+msgid "Import PDF File..."
+msgstr "Dosya İçeri Aktar"
+
+#: mainwindow.cpp:388
+#, fuzzy
+msgid "Import a PDF file"
+msgstr "Bir CSV dosyasını içeri aktar"
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Ses Dosyası Meta Verilerini İçeri Aktar..."
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Ses dosyalarından meta-veri içeri aktar"
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Ses CD Verisi İçeri Aktar..."
+
+#: mainwindow.cpp:405
+msgid "Import audio CD information"
+msgstr "Ses CD bilgisi içeri aktar"
+
+#: mainwindow.cpp:414
+msgid "Import GCstar Data..."
+msgstr "GCstar Verisi İçeri Aktar..."
+
+#: mainwindow.cpp:415
+msgid "Import a GCstar data file"
+msgstr "Bir GCstar veri dosyası içeri aktar"
+
+#: mainwindow.cpp:421
+#, fuzzy
+msgid "Import Griffith Data..."
+msgstr "GCstar Verisi İçeri Aktar..."
+
+#: mainwindow.cpp:422
+#, fuzzy
+msgid "Import a Griffith database"
+msgstr "Bir PilotDB veritabanına aktar"
+
+#: mainwindow.cpp:428
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Ant Film Katalog Verisini İçeri Aktar..."
+
+#: mainwindow.cpp:429
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Bir Ant Film Katalog Veri Dosyasını İçeri Aktar"
+
+#: mainwindow.cpp:435
+msgid "Import File Listing..."
+msgstr "Dosya Listelemesini İçeri Aktar..."
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr "Bir dizin içindeki dosyalar hakkındaki içeri aktarma bilgisi"
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "XSL Dönüşümünü İçeri Aktar..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Kullanılan bir XSL Dönüşümünü içeri aktar"
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Dışa Aktar"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr "Kolleksiyon verisini, farklı düzenlere aktar"
+
+#: mainwindow.cpp:461
+msgid "Export to XML..."
+msgstr "XML olarak Dışarı Aktar..."
+
+#: mainwindow.cpp:462
+msgid "Export to a Tellico XML file"
+msgstr "Bir Tellico XML dosyasına aktar"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Zip olarak dışa aktar..."
+
+#: mainwindow.cpp:469
+msgid "Export to a Tellico Zip file"
+msgstr "Bir Tellico Zip dosyasına aktar"
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "HTML olarak dışa aktar..."
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Bir HTML dosyasına aktar"
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "CSV olarak dışa aktar..."
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Bir virgülle ayrılmış değerler dosyasına aktar"
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "PilotDB olarak dışarı aktar..."
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Bir PilotDB veritabanına aktar"
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Alexandria olarak dışa aktar..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Bir Alexandria kütüphanesine aktar"
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Bibtex olarak dışa aktar..."
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Bir bibtex dosyasına aktar"
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Bibtexml olarak dışa aktar..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Bir Bibtexml dosyasına aktar"
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "ONIX olarak dışa aktar..."
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Bir ONIX dosyasına aktar"
+
+#: mainwindow.cpp:524
+msgid "Export to GCfilms..."
+msgstr "Gcfilms olarak dışa aktar..."
+
+#: mainwindow.cpp:525
+msgid "Export to a GCfilms data file"
+msgstr "Bir GCfilms veri dosyasına aktar"
+
+#: mainwindow.cpp:531
+#, fuzzy
+msgid "Export to GCstar..."
+msgstr "Gcfilms olarak dışa aktar..."
+
+#: mainwindow.cpp:532
+#, fuzzy
+msgid "Export to a GCstar data file"
+msgstr "Bir GCfilms veri dosyasına aktar"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "XSL Dönüşümünü Dışa Aktar..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Kullanılan bir XSL Dönüşümünü Dışa aktar"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr "Seçili metni kes ve onu panoya koy"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr "Seçili metni panoya kopyala"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Pano içeriğini yapıştır"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Kolleksiyondaki bütün girdileri seç"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr "Kolleksiyondaki bütün girdileri geri bırak"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "İnternette Ara..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "İnterneti ara..."
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "İleri Se&viye Süzgeç..."
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Kolleksiyonu filtrele"
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "Ye&ni Girdi..."
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Yeni bir girdi oluştur"
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "Girdiyi Düz&enle..."
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Seçili girdileri düzenle"
+
+#: controller.cpp:621 mainwindow.cpp:577
+msgid "D&uplicate Entry"
+msgstr "&Girdiyi Çoğalt"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Seçili girdileri kopyala"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "Gir&diyi Sil"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Seçili girdileri sil"
+
+#: mainwindow.cpp:585
+#, fuzzy
+msgid "&Merge Entries"
+msgstr "Gir&dileri Sil"
+
+#: mainwindow.cpp:588
+#, fuzzy
+msgid "Merge the selected entries"
+msgstr "Seçili girdileri sil"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "&Rapor Oluştur..."
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Kolleksiyon raporu oluştur"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "K&ontrol Et..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Seçili öğeleri kontrol et"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "Kayıt G&irişi Yap"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Seçili öğelerin kayıt girişini yap"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "Kolleksiyonu Yeniden İsimlendi&r..."
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Kolleksiyonu yeniden isimlendir"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "Koleksiyon &Alanları..."
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Kolleksiyon alanlarını değiştir"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "&Bibliyografyaya Dönüştür"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr "Bir kitap kolleksiyonunu bibliyografyaya Dönüştür"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "Karakter Dizisi &Makroları..."
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Bibtex karakter dizisi makrolarını düzenle"
+
+#: mainwindow.cpp:626
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Bibtexi &Panoya Kopyala"
+
+#: mainwindow.cpp:627
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Bibtex alıntılarını panoya kopyala"
+
+#: mainwindow.cpp:632
+msgid "Cite Entry in &LyX"
+msgstr "&LyX deki girdiden alıntı yap"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "LyX deki seçili girdilerden alıntı yap"
+
+#: mainwindow.cpp:638
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "OpenOffice.org daki girdilerden alın&tı yap"
+
+#: mainwindow.cpp:639
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "OpenOffice.org daki seçili girdilerden alıntı yap"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, no-c-format
+msgid "&Update Entry"
+msgstr "Girdiyi G&üncelle"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr "Bütün Kaynaklar"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr "Girdi verilerini bütün müsait kaynakları kullanarak güncelle"
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Guru&p Görüntüsünü Göster"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Gurup görünümüne izin ver/geri al"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Guru&p Görünümünü Gizle"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Giriş Düz&enleyicisini Göster"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Düzenleyicisine izin ver/geri al"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "Giriş Düz&enleyicisini Gizle"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Giriş &Görünümünü Göster"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr "Giriş görünümeüne izin ver/geri al"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "Giriş Görünümünü Gi&zle"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Guruplamayı Değiştir"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "&Gurup Seçimi"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Kolleksiyon guruplandırmasını değiştir"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Filtre"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Filtreyi Temizle"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Buradan Süz..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Guruplar"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt><i>Gurup Görünümü</i>, seçili alanlara göre girdileri guruplara "
+"ayırır.</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt><i>Sütun Görünümü</i>, her girdinin bir çok alandaki değerini "
+"gösterir.</qt>"
+
+#: mainwindow.cpp:831
+#, fuzzy
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Tellico - KDE için bir kolleksiyon yöneticisi"
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Yeni doküman yaratılıyor..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Dosyayı açıyor..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Dosya Aç"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Dosya kaydediliyor..."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+"<qt><p>Dosyayı bir çok resimler beraber kaydediyorsunuz, bu Telliconun "
+"önemli ölçüde yavaşlamasına sebep olur. Performansı artıtmak için, "
+"resimleri Telliconun veri dizinine ayrı ayrı kaydetmek ister "
+"misiniz?</p><p>Seçiminiz konfigurasyon diyaloğunda herzaman "
+"değiştirilebilir.</p></qt>"
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr "Resimleri Ayrı Ayrı Kaydet"
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr "Resimleri Dosya İçine Kaydet"
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Dosya yeni bir isimle kaydediliyor..."
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Yazılıyor..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"Koleksiyon, girdilerin sınırlı alt kümelerini göstermek üzere "
+"filtrelenmiştir. Sadece görülebilir girdiler yazdırılmıştır. Devam "
+"edilsin mi?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Döküman işletiliyor..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Çıkılıyor..."
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Toplam girdi: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 filtrelendi; %2 seçildi)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 filtrelendi)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 seçildi)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Yazdır %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Sayfa %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Lütfen kurulumunuzu gözden geçirin."
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Veri içeri aktarılıyor..."
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Dosya İçeri Aktar"
+
+#: mainwindow.cpp:1864
+msgid "Import Directory"
+msgstr "Dizin İçeri Aktar"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Veri dışarı aktarılıyor..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Farklı Dışarı Aktar"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Karakter Dizisi Makroları"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Makro"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Karakter Dizisi"
+
+#: mainwindow.cpp:1999
+msgid "Creating citations..."
+msgstr "Alıntılar Oluşturuluyor..."
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Filtreler"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt><i>Filtre Görünümü</i>, girdilerin belli filtre kurallarına "
+"uğramış haliyle gösterilmesidir.</qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Kiralamalar"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt><i>Kiralama Görünümü</i>, sizin koleksiyonunuzdan parçalar "
+"kiralayan kişilerin bir listesini gösterir.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr "Veri girdisini %1 den güncelle"
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr "Tellico, %1 resimini yükleyemedi."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+"\"%1\" isimli bir dosya zaten mevcut. Üzerine yazmak istediğinizden emin "
+"misiniz?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Dosya Üzerine Yazılsın mı?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Üzerine Yaz"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Filtre (Hesaba Göre Sırala)"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Gerçekten bu girdiyi silmek istiyor musunuz?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Girdiyi Sil"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Gerçekten bu girdileri silmek istiyor musunuz?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Çoklu Girdileri Sil"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "Girdil&eri Düzenle..."
+
+#: controller.cpp:627
+msgid "D&uplicate Entries"
+msgstr "Girdileri Ço&ğalt"
+
+#: controller.cpp:628
+msgid "&Update Entries"
+msgstr "Girdileri G&üncelle"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "Gir&dileri Sil"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr ""
+"Bu parçalar zaten kiralandı, ama Tellico şu anda bir parçanın birçok "
+"kere kiralanmasını desteklemiyor. Bunlar kiralanan parçalar listesinden "
+"kaldırılacaktır."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Öntanımlı Takvim"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"Şu anda, Tellico sadece yerel takvim kaynaklarını destekliyor. Aktif "
+"takvim küçük bir alan için yerelleştirilmiş, bu yüzden, sizin "
+"kiralamalarınız eklenmeyecektir."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Aktif Takvim"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 den dolayo \"%2\" döndürdü"
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(Boş)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - KDE için bir kolleksiyon yöneticisi"
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr "Son açılan dosyayı tekrar açmayın"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "<filename> dosyasını bir bibtex dosyası olarak içeri aktar"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "<filename> dosyasını bir MODS dosyası olarak içeri aktar"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "<filename> dosyasını bir RIS dosyası olarak içeri aktar"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Açılacak dosya"
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr "Veri kaynağı scriptleri"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Simgeler"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Btparse kütüphanesi yazarı"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr "Kod örnekleri ve genel fikir"
+
+#: main.cpp:50
+#, fuzzy
+msgid "Author of libcsv library"
+msgstr "Btparse kütüphanesi yazarı"
+
+#: main.cpp:52
+#, fuzzy
+msgid "Author of rtf2html library"
+msgstr "Btparse kütüphanesi yazarı"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Kolleksiyon Alanları"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Şu Anda Geçerli Alanlar"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "Ye&ni"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Kolleksiyona yeni bir alan ekle"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "&Sil"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Kolleksiyondan bir alan çıkar"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Bu alanı listede yukarı taşı. Bu liste sıralaması, giriş "
+"düzenleyicisinin düzeni için önemlidir."
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Bu alanı listede aşağı taşı. Bu liste sıralaması, giriş "
+"düzenleyicisinin düzeni için önemlidir."
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Alan Özellikleri"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "&Başlık:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "Alanın Başlığı"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "&Tip:"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr "Alanın tipi, hangi değerlerin kullanılabileceğini belirler. "
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr "Çoğu alanlarda <i>Basit Metin</i> kullanılmıştır. "
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr "Büyük metin blokları için <i>Paragraf</i>. "
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr "<i>Seçim</i> bazı kesin değerler için alanı sınırlar. "
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr "<i>Seçme Kutusu</i> basit evet/hayır değeri içindir. "
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr "<i>Numara</i> sayısal değerleri içeren alanları bildirir. "
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+" Alanlar için<i>URL</i>, URL leri ifade eder, bu diğer dosyalar için "
+"yararlanılan kaynakları içerir. "
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr "Bir <i>Tablo</i> bir veya daha fazla sütundaki değerleri tutabilir. "
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr "Bir <i>Resim Dosyası</i> alanı, resimleri tutar. "
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+"Bir <i>Tarih</i> alanı, gün, ay ve yıl değerleri için kullanılabilir. "
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+"Bir <i>Değerlendirme</i> alanı, yıldızlar kullanarak, değerlendirme "
+"sayısını gösterir. "
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"Bir <i>Bağımlılık</i> alanı, diğer alanların değerlerine "
+"bağımlıdır, ve bu alan açıklamasına göre biçimlendirilir. "
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"Bir <i>Sadece Okunabilir</i> alanı, içsel değerler içindir, içeri ve "
+"dışarı aktarmalar için kullanışlı olabilir. "
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "Kate&gori:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr ""
+"Alan Kategorisi, düzenleyici içerisindeki alanların nerede "
+"bulunacağını bildirir."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "Aç&ıklama:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"Açıklama, Alan içerisindeki bilgiyi hatırlatmada kullanışlı bir "
+"özelliktir. <i>Bağımlı</i> alanlar için, isimlendirilmiş alanların, "
+"karakter dizileri ile yer değiştirdiği , \"%{year} %{title}\" gibi "
+"karakter disizi düzenidir."
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr "Ön tanımlı &Değer:"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr "<qt>Bir ön tanımlı değer, yeni girdiler için belirlenebilir.</qt>"
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr "İzin veri&len değerler:"
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt><i>Seçim</i>-tipi alanları için, bunlar izin verilen yegane "
+"değerlerdir. Kombo kutular içerisinde yer alırlar. Gelebilecek değerler, "
+"noktalı virgül ile ayrılmalıdır. Örneğin: \"köpek; kedi; fare\"</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "Ge&nişletilmiş özellikler:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "A&yarla..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"Genişletilmiş alan özellikleri, bir biriyle haberli bibtex alanları "
+"gibi, birşeyleri bilrtmek için kullanılır."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Biçimlendirme Seçenekleri"
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Biçimlendirme yok"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+"Bu seçenek, alanın, otomatik olarak düzenlenmesini veya büyük-küçük "
+"harf düzenlemesini engeller."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Sadece otomatik büyük-harf denetimine izin ver"
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr ""
+"Bu seçenek, alanın büyük-küçük harf düzenlemesine izin verir, ama "
+"özel olarak düzenlenmemiştir."
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Başlık olarak düzenle"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Bu seçenek, alanı, bir başlıkmış gibi, büyük-küçük harf denetimi "
+"yapar ve biçimlendirir, ama sadece o seçenekler ayarlandıysa bu "
+"mümkündür."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "İsim olarak düzenle"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Bu seçenek, alanı, bir isimmiş gibi, büyük-küçük harf denetimi yapar "
+"ve biçimlendirir, ama sadece o seçenekler ayarlandıysa bu mümkündür."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Alan Seçenekleri"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Otomatik tamamlamaya izin ver"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Eğer seçiliyse, bu alan için, metin düzenleme kutucuğundaki KDE "
+"otomatik tamamlama özelliği aktif hale getirilecektir."
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Çoklu değerlere izin ver"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Eğer işaretliyse, Tellico, çoklu değerlere sahip alanların değerlerini "
+"ayrıştıracaktır ve noktali virgül ile ayıracaktır."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Guruplandırmaya izin ver"
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Eğer işaretliyse, bu alan, gurup görünümünde girdilerin "
+"guruplandırılmasında kullanılabilir."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr ""
+"Seçili alanların özelliklerini, ön tanımlı değerlere geri götür."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Alanları Değiştir"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Koleksiyon içinde bulunan <i>%1</i> alanındaki izin verilen "
+"değerlerin kaldırılması, veri bozulmasına neden olabilir. düzenlenmiş "
+"değerleri saklamak mı yoksa şu andaki işlemi iptal edip geri almak mı "
+"istersiniz?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Düzenlenmiş değerleri sakla"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Alan Özelliklerini Geri Döndür"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Gerçekten <em>%1</em> alanının yapılandırmasını geri alıp, "
+"ön tanımlı değerlere döndürülmesini istiyor musunuz?</p></qt>"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Geri döndür"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Genişletilmiş Alan Özellikleri"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr ""
+"Bu başlıkta başka bir alan zaten mevcut. Lütfen başka bir başlık "
+"girin."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr "<qt>Kategori boş olamaz. Lütfen bir kategori giriniz.</qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>Bir alan <em>Paragraf</em>, <em>Tablo</em> veya <em>resim</em> de "
+"olduğu gibi aynı kategoride olmayabilir. Lütfen farklı bir kategori "
+"giriniz.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"Bir alan başlığı, mevcut bir kategori ile aynı olamaz. Lütfen farklı "
+"bir başlık giriniz."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+"Derecelendirme alanı için sınıflandırma 1 ile 10 arasında olmalıdır, "
+"alt sınır, üst sınırdan az olmalıdır. Lütfen farklı alt ve üst "
+"özellikler giriniz."
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr "Tablolar, en fazla on sütun ile sınırlandırılmışlardır."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Bu dosya değiştirildi.\n"
+"Kaydetmek ister misiniz?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Kaydedilmemiş Değişiklikler"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Kiralayan Seç"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Tellicoyu Yapılandır"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Genel Seçenekler"
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr "Dosyayı başlangıçta tek&rar aç"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Eğer işaretliyse, son açılan dosya, program yeniden başlatıldığında "
+"tekrar açılacaktır."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "Başlangıçta \"Günün İpucu\" nu gö&ster"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr ""
+"Eğer seçiliyse, \"Günün İpucu\", program başlatıldığında "
+"gösterilecektir."
+
+#: configdialog.cpp:213
+#, fuzzy
+msgid "Image Storage Options"
+msgstr "Resim Seçenekleri"
+
+#: configdialog.cpp:214
+#, fuzzy
+msgid "Store images in data file"
+msgstr "Veri dosyasındak&i resimleri ekle"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr ""
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr ""
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Düzenleme Seçenekleri"
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr ""
+"Otomatik olarak başlık ve isimlerde büyük-küçük harf dene&timi yap"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Eğer seçiliyse, otomatik olarak, başlık ve isimlerin, büyük-küçük "
+"harf denetimi yapılacaktır."
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr "Ba&şlık ve isimleri otomatik biçimlendir"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr ""
+"Eğer seçiliyse, başlık ve isimler, otomatik olarak biçimlendirilecektir."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr "Büyük-küçük harf dü&zenlemesi yok:"
+
+#: configdialog.cpp:243
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Büyük-küçük harf denetimine uğramaması gereken kelimelerin bir "
+"listesi. Çoklu değerler, noktalı virgül ile ayrılmalıdır.</qt>"
+
+#: configdialog.cpp:249
+msgid "Artic&les:"
+msgstr "Baş&lıklar:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>Eğer başlıktaki ilk kelimeyse, makale olarak düşünülmesi gereken "
+"kelimelerin bir listesi. Çoklu değerler, noktalı virgül ile "
+"ayrılmalıdır.</qt>"
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr "Ki&şisel son ekler:"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Kişisel isimlerde kullanabileceğiniz son eklerin bir listesi. Çoklu "
+"değerler, noktalı virgül ile ayrılmalıdır. </qt>"
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr "So&y isim ön ekleri:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Soy isimlerde kullanabileceğiniz ön eklerin bir listesi. Çoklu "
+"değerler, noktalı virgül ile ayrılmalıdır.</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Yazdırma"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Yazdırma Seçenekleri"
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr "Başlık ve isi&mleri biçimlendir"
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr "Alan başl&ıklarını yazdır"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Guruplandırma Seçenekleri"
+
+#: configdialog.cpp:313
+msgid "&Group the entries"
+msgstr "&Girdileri guruplandır"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Resim Seçenekleri"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr "Resim&lerin alabileceği en fazla genişlik:"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Resimlerin çıktıda alacağı en fazla genişlik. En-boy oranı saklandı."
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr "Resi&mlerin alabileceği en fazla yükseklik:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Resimlerin çıktıda alacağı en fazla yükseklik. En-boy oranı saklandı."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Şablonlar"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Şablon Seçenekleri"
+
+#: configdialog.cpp:369
+msgid "Template:"
+msgstr "Şablon:"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+"Geçerli tipdeki koleksiyonda kullanmak üzere şablon seçiniz. Font ve "
+"renk ayarlarını bütün şablonlar kullanmayacaktır."
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr "&Önizleme..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr "Şablonun bir önizlemesini göster"
+
+#: configdialog.cpp:398
+msgid "Font Options"
+msgstr "Font Seçenekleri"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr "Yazı Tipi:"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr "Bu font, Giriş Görünümü'nde kullanılan şablona geçti."
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr "Büyüklük:"
+
+#: configdialog.cpp:425
+msgid "Color Options"
+msgstr "Renk Seçenekleri"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr "Arkaplan rengi:"
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr "Bu renk, Giriş Görünümü'nde kullanılan şablona geçti."
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr "Metin rengi:"
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr "Parlaklaştırma rengi:"
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr "Parlaklaştırılmış metin rengi:"
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr "Şablonları Yönet"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr "Kur..."
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr "Doğruca yeni bir şablon kurmak için tıklayın."
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr "İndir..."
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr "İnternet üzerinden ek şablonlar indirmek için tıklayın."
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr "Sil..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr "Kurulu şablonları seçip kaldırmak için tıklayın."
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Veri Kaynakları"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Veri Kaynağı Seçenekleri"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Kaynak"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr "Y&ukarı Taşı"
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+"Veri kaynaklarının sıralması, Tellico'nun girdileri otomatik olarak "
+"güncellediği zaman kullandığı sıralamayı belirler."
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr "Aşağı &Taşı"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "Ye&ni..."
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr "Yeni bir veri kaynağı eklemek için tıklayın."
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "De&ğiştir..."
+
+#: configdialog.cpp:533
+msgid "Click to modify the selected data source."
+msgstr "Seçili veri kaynağını değiştirmek için tıklayın."
+
+#: configdialog.cpp:536
+msgid "Click to delete the selected data source."
+msgstr "Seçili veri kaynağını silmek için tıklayın."
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr "İnternet üzerinden ek veri kaynakları indirmek için tıklayın."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr "*.tar.gz *.tgz|Şablon Paketleri (*.tar.gz)"
+
+#: configdialog.cpp:1049
+msgid "Delete Template"
+msgstr "Şablon Sil"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr "Silmek için şablon seçin:"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "Kiralayan"
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Kayıt Gir"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Kira Değiştir..."
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "Kiralayan (Hesaba Göre Sırala)"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "Koleksiyonum"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Kitap Koleksiyonu"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Çizgi Roman Koleksiyonu"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Video Koleksiyonu"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Müzik Koleksiyonu"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Madeni Para Koleksiyonu"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Pul Koleksiyonu"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Şarap Koleksiyonu"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Kart Koleksiyonu"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Oyun Koleksiyonu"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr "Dosya Kataloğu"
+
+#: collectionfactory.cpp:135
+#, fuzzy
+msgid "Board Game Collection"
+msgstr "Oyun Koleksiyonu"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Size Özel Koleksiyon"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+"<qt><i>Girdi Görünümü</i> girdi içeriğinin, biçimlendirilmiş bir "
+"görünümünü gösterir.</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt><i>Simge Görünümü</i>, koleksiyondaki her girdiyi veya gurubu bir "
+"simge kullanarak gösterir, bu girdideki bir resimde olabilir.</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Dışa Aktarma Seçenekleri"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Düzenleme"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Bütün alanları düzenle"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Eğer seçiliyse, alanların değerleri, kendi biçim tiplerine göre "
+"otomatik olarak biçimlendirilecektir."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Sadece seçili girdileri dışa aktar"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr "Eğer seçiliyse, sadece seçili girdiler dışa aktarılacaktır."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Şifreleme"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "(UTF-8) Karakter Kodunda Şifrele"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Dışa aktarılan dosyayı (UTF-8) karakter kodlaması ile şifrele."
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Kullanıcı konumu (%1) de şifrele"
+
+#: exportdialog.cpp:72
+#, fuzzy
+msgid "Encode the exported file in the local encoding."
+msgstr "Dışa aktarılan dosyayı yerel düzende şifrele."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "A&ra"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "D&urdur"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "İnternet Araması"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Arama Sırası"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr "A&ra:"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr "Bir arama değeri girin. Bir ISBN araması, tüm ISBN i içermelidir."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Aramanın tipini seçin"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Aramayı başlat veya durdura tıklayın"
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr "Çoklu ISBN/UPC ara&ması"
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr ""
+"Çoklu ISBN veya UPC değerlerinde arama yapmak için bu kutucuğu "
+"işaretleyin."
+
+#: fetchdialog.cpp:138
+msgid "Edit List..."
+msgstr "Düzenleme Listesi..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+"Çoklu ISBN değerleri girmek veya düzenlemek için, metin düzenleme "
+"kutucuğu aç tuşunu tıklayın."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "Arama ka&ynağı:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Arama yapmak için veritabanı seçin"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"Sonuçlar bulunduğu gibi, bu listeye eklendi. Birini seçmeniz durumunda, "
+"tamamlanmış girdiyle eşleşecek ve aşağıda gösterilecektir."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"Bir girdi, Aşağıdaki listeden seçip, geçerli koleksiyona eklemeden de "
+"burada gösterilebilir"
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "Girdi E&kle"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr "Seçili girdiyi, şu anki koleksiyona ekle"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr "Daha Fazla Sonuç Getir"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr "Şu anki veri kaynağından daha fazla sonuç yakala"
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr "Bütün arama alanlarını ve sonuçlarını temizle"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Arama iptal ediliyor..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Aranıyor..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "Arama herhangi bir sonuç döndürmedi."
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+"Arama 1 sonuç döndürdü.\n"
+"Arama %n sonuç döndürdü."
+
+#: fetchdialog.cpp:412
+#, fuzzy
+msgid "No results were found for the following ISBN values:"
+msgstr "<qt>İzleyen ISBN değerlerinde hiç bir giriş bulunamadı:</qt>"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Alınıyor %1..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr ""
+"Geçerli koleksiyon tipiniz için kullanılabilir herhangi bir internet "
+"kaynağı yok."
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr "ISBN/UPC Değerlerini Düzenle "
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr ""
+"<qt>ISBN veya UPC değerlerini, herbiri bir satıra olmak üzere "
+"giriniz.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "Dosyadan Yük&le..."
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr "<qt>Bir metin dosyasından liste yükle.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>Bir ISBN araması en fazla 100 ISBN değeri döndürür. Sadece "
+"listedeki ilk 100 değer kullanılabilir.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Girdiyi Düzenle"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "Ye&ni Girdi"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "G&irdiyi Kaydet"
+
+#: entryeditdialog.cpp:77
+msgid "Go to the previous entry in the collection"
+msgstr "Koleksiyonda bir önceki girdiye git"
+
+#: entryeditdialog.cpp:82
+msgid "Go to the next entry in the collection"
+msgstr "Koleksiyondaki bir sonraki girdiye git"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Bu girdileri gerçekten değiştirmek istiyor musunuz?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Çoklu Girdileri Değiştir"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr ""
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Girdileri Düzenle"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "G&irdileri Kaydet"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"Bu girdi düzenlendi.\n"
+"Değişiklikleri girmek istiyor musunuz?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Girdiyi Kaydet"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Koleksiyon Raporu"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "&Rapor Şablonu:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "Oluş&tur"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr "Bir rapor şablonu seçin ve <em>Oluştur</em> a tıklayın."
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+"Bazı raporlar, geniş koleksiyonlar oluşturulurken bir kaç saniye "
+"alabilir."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Gerçekten bu filtreyi silmek istiyor musunuz?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Filtreyi Sileyim mi?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Yeni koleksiyon adı:"
+
+#: tellico_kernel.cpp:377
+#, fuzzy
+msgid "Entry 1"
+msgstr "Girdi Tipi"
+
+#: tellico_kernel.cpp:378
+#, fuzzy
+msgid "Entry 2"
+msgstr "Girdi Tipi"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr ""
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+#, fuzzy
+msgid "Merge Entries"
+msgstr "Girdileri Sil"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr ""
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr "Tellico, öntanımlı girdi stilini konumlandıramıyor."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "Ye&ni"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Koleksiyon"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Koleksiyon Araç Çubuğu"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Kunter Kutlu"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "kunterkutlu@gmail.com"
+
+#: entrymerger.cpp:35
+#, fuzzy
+msgid "Merging entries..."
+msgstr "Girdiler güncelleniyor..."
+
+#: entrymerger.cpp:49
+#, fuzzy
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Toplam girdi: %1"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>...Eğer bir kitabın birden fazla yazarı varsa, bunların isimlerini,\n"
+"noktalı virgül ile ayırmalısınız, böylelikle, Tellico bunları "
+"farkeder\n"
+"ve ayrı olarak kullanacağını bilir.</p>\n"
+"<p>Çoklu değer girmeye izin veren diğer alanlarda da, her bir değeri\n"
+"noktalı virgül (;) ile ayırarak aynı yol izlenmelidir.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>...Sütun başlığı üzerinde sağ tıklayarak, liste görünümünde\n"
+"hangi alanların gösterileceğini değiştirebilirsiniz.\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>...Alan düzenleyicisini kullanarak, koleksiyon içindeki alanlara\n"
+"yenilerini ekleyebilir, düzenleyebilir veya değiştirebilirsiniz.\n"
+"Alan listesi altındaki ok tuşları, liste içindeki alanların yerlerini\n"
+"değiştirmekte kullanılır, bu olay, girdi düzenleyicisi içindeki yerini "
+"etkiler.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>...Eğer seçme kutusu alanı vasıtası ile filtreleme yapmak\n"
+"isterseniz, \"doğru\" nun bir değeri kullanılmalıdır. Mesela, sadece\n"
+"okumadığınız bilim kurgu kitaplarını filtrelemek istiyorsanız,\n"
+"<em>İzleyenlerin hepsini eşleştir</em> tuşunu kontrol edin,\n"
+"ilk kuralı \"Tarz\" \"içerir\" \"Bilim Kurgu\" (Tırnaksız) olarak "
+"ayarlanmalı,\n"
+"ve ikinci kural \"Oku\" \"içermeyenleri\" \"Doğru\" (Tırnaksız) olarak "
+"ayarlayın.</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>...Eğer Çabuk Süz de kelime olmayan karakterler kullanılırsa, "
+"metin,\n"
+"düzenli açıklama olarak tercüme edilir.</p>\n"
+" <p>Mesela, sadece Weber veya Bujold'dan kitapları göstermek isterseniz,\n"
+"filtreleme kutusuna \"weber|bujold\" (tırnaksız) yazınız.</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>...Shift veya Ctrl tuşlarına basılı tutup, birden fazla girdi "
+"seçerek, aynı anda\n"
+"birden fazla girdiyi düzenleyebilirsiniz.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>...Sahip olduğunuz bir kitap koleksiyonunu, bir bibliyografyaya\n"
+"çevirebilirsiniz, bu sonradan, bibtex veya Bibtexml biçiminde\n"
+"dışarı aktarılır.</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>...Bibliyografyalar için, karakter dizisi makrolarını, ekleyebilir,\n"
+" düzenleyebilir ve silebilirsiniz.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>...Eğer birden fazla alan, isim olarak biçimlendirildiyse, koleksiyona\n"
+"\"Herkes\" isimli yeni bir gurup eklenecektir, mesela, yazarlar\n"
+"ve düzenleyiciler, beraber sıralanabilecek veya "
+"yazdırılabileceklerdir.</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>...<tt>tellico-printing.xsl</tt> dosyasını değiştirerek, yazdırılan "
+"çıktının\n"
+"görünümünü değiştirebilirsiniz. Dosya HTML ve kenar boşluğu, font, "
+"vb gibi\n"
+"stilleri yöneten CSSi oluşturur.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>...İçeri geniş kapsamlı XSL stil şablonları aktarıp, Geçerli bir\n"
+"Tellico XML dosyası çıkarabilirsiniz.</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+"<p>...Girdiye çift tıklayarak, girdi düzenleyicisini açabilirsiniz.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>...&lt;b&gt;kalın&lt;/b&gt; veya &lt;i&gt;italik&lt;/i&gt; gibi HTML "
+"taglarını\n"
+"herhangi bir paragraf alanına biçimlendirme için ekleyebilirsiniz.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>...Detaylı Görünüm içerisinde, klavyede bir harfe basarak,\n"
+"o harfle başlayan, sıradaki girdiye geçebilirsiniz.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+"<p>...Bağımlı Alanları, çoklu ayrılmış alanları tek bir alanda "
+"birleştirmek için\n"
+"kullanabilirsiniz. Sadece Bağımlı tipini seçin ve, %{...} uygun alan "
+"değeri ile\n"
+"yer değiştirecek \"Değer: %{fielda}%{fieldb}\" benzeri bir açıklama "
+"kullanın.\n"
+"Bu tek bir alandan çoklu değerler edinmek için kullanışlı bir yoldur, "
+"mesela,\n"
+"daha iyi guruplandırma ve, aynı zamanda doğru sıralamayla farklı "
+"türlerin\n"
+"birleştirilmesi iyi bir örnektir. Düşünün mesela, 3b, 14a girdileri "
+"olan bir sayı alanı ve \n"
+"ardından metin alt alanı gibi.</p>\n"
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Albüm"
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr "Bu şablon sadece müzik koleksiyonları için anlam ifade eder."
+
+#: xslt.cpp:5
+msgid "Total:"
+msgstr "Toplam:"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr "Süslü"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "Ön Tanımlı"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Yoğun"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Video"
+
+#: xslt.cpp:14 xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr "Bu şablon, sadece video koleksiyonları için anlam ifade eder."
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Gurup Özeti"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Gurup Özeti"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Toplam alan sayısı:"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Toplam girdi sayısı:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+msgid "Generated by Tellico"
+msgstr "Tellico Tarafından Oluşturuldu"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Farklı değerler: "
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Resim Listesi"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Kiralama Görünümü"
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Kiralama Tarihi"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Not"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Bitiş Tarihi"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Gurup Görünümü"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Başlık Listelemesi (Yatay)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Başlık Listelemesi (Dikey)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Sütun Görünümü"
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "Üçlü Sütun"
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr "Ara"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr "Britanya Kütüphanesi"
+
+#: z3950.cpp:6
+msgid "Sudoc (France)"
+msgstr "Sudoc (Fransa)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr "BIBSYS (Norveç)"
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr "İtalyan Ulusal Kütüphanesi"
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr "Portekiz Ulusal Kütüphanesi"
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr "Polonya Ulusal Kütüphanesi"
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr "Kanada Ulusal Kütüphanesi"
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr "İsrail Birliği Listesi"
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr "Avustralya Ulusal Kütüphanesi"
+
+#: z3950.cpp:22
+#, fuzzy
+msgid "National Library of Lithuania"
+msgstr "Kanada Ulusal Kütüphanesi"
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr ""
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr ""
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr "Dark Horse Comics"
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr "Allocine.fr"
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr "İspanya Kültür Bakanlığı"
+
+#, fuzzy
+#~ msgid "CrossRef"
+#~ msgstr "Çapraz-Referans"
+
+#~ msgid "MODS"
+#~ msgstr "MODS"
+
+#~ msgid "RIS"
+#~ msgstr "RIS"
+
+#~ msgid "GCstar"
+#~ msgstr "GCstar"
+
+#~ msgid "AMC"
+#~ msgstr "AMC"
+
+#, fuzzy
+#~ msgid "Griffith"
+#~ msgstr "Hediye"
+
+#, fuzzy
+#~ msgid "Referencer"
+#~ msgstr "Çapraz-Referans"
+
+#~ msgid "Comics"
+#~ msgstr "Çizgi Roman"
+
+#~ msgid "Stamps"
+#~ msgstr "Pullar"
+
+#~ msgid "Coins"
+#~ msgstr "Madeni Paralar"
+
+#~ msgid "Books"
+#~ msgstr "Kitaplar"
+
+#~ msgid "Wines"
+#~ msgstr "Şaraplar"
+
+#~ msgid "Videos"
+#~ msgstr "Videolar"
+
+#~ msgid "Games"
+#~ msgstr "Oyunlar"
+
+#~ msgid "Cards"
+#~ msgstr "Kartlar"
+
+#~ msgid "Entries"
+#~ msgstr "Girdiler"
+
+#~ msgid "Albums"
+#~ msgstr "Albümler"
+
+#~ msgid ""
+#~ "If checked, all images will be included in the data file, rather than saved "
+#~ "separately in the Tellico data directory. Saving a lot of images in the data "
+#~ "file cause Tellico to run more slowly."
+#~ msgstr ""
+#~ "Eğer işaretliyse, bütün resimler, Tellico veri dizinine ayrı ayrı "
+#~ "kaydedilmeyip, veri dosyasına eklenir. Bir çok resmin, tek bir veri "
+#~ "dosyasında kaydedilmesi ise, Tellico'nun yavaşlamasına neden olur."
+
+#, fuzzy
+#~ msgid "Copac"
+#~ msgstr "Virgül"
+
+#~ msgid "Download.."
+#~ msgstr "İndir.."
diff --git a/po/uk.po b/po/uk.po
new file mode 100644
index 0000000..c04f133
--- /dev/null
+++ b/po/uk.po
@@ -0,0 +1,5624 @@
+# translation of uk.po to Ukrainian
+# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
+# Сергій Дубик <dubyk@library.lviv.ua>, 2007.
+# Serhij Dubyk <dubyk@library.lviv.ua>, 2007.
+msgid ""
+msgstr ""
+"Project-Id-Version: ru\n"
+"POT-Creation-Date: 2008-01-26 10:52-0800\n"
+"PO-Revision-Date: 2007-11-09 01:56+0200\n"
+"Last-Translator: Serhij Dubyk <dubyk@library.lviv.ua>\n"
+"Language-Team: Ukrainian <uk@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.2\n"
+
+#: cite/lyxpipe.cpp:50
+msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
+msgstr ""
+"<qt>Tellico не вдається записати на сервер "
+"<b>%1</b>.</qt>"
+
+#: cite/openoffice.cpp:82
+msgid "Connecting to OpenOffice.org..."
+msgstr "З'єднання з OpenOffice.org..."
+
+#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
+msgid "OpenOffice.org Connection"
+msgstr "З'єднання з OpenOffice.org"
+
+#: cite/openoffice.cpp:179
+msgid ""
+"Tellico was unable to connect to OpenOffice.org. Please verify the "
+"connection settings below, and that OpenOffice.org Writer is currently "
+"running."
+msgstr ""
+"Tellico не вдається з'єднатися з "
+"OpenOffice.org.Перевірте налаштування з'єднання "
+"а такожчи OpenOffice запущений зараз."
+
+#: cite/openoffice.cpp:191
+msgid "Pipe"
+msgstr "Канал"
+
+#: cite/openoffice.cpp:193
+msgid "TCP/IP"
+msgstr "TCP/IP"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "Rename Column"
+msgstr "Перейменувати стовпець"
+
+#: gui/tablefieldwidget.cpp:181
+msgid "New column name:"
+msgstr "Нова назва стовпця:"
+
+#: gui/tablefieldwidget.cpp:206
+#, c-format
+msgid "Column %1"
+msgstr "Стовпець %1"
+
+#: gui/tablefieldwidget.cpp:241 gui/tablefieldwidget.cpp:289
+msgid "Rename Column..."
+msgstr "&Перейменувати стовпець"
+
+#: gui/tablefieldwidget.cpp:274
+msgid "Insert Row"
+msgstr "Вставити рядок"
+
+#: gui/tablefieldwidget.cpp:276
+msgid "Remove Row"
+msgstr "Вилучити рядок"
+
+#: gui/tablefieldwidget.cpp:278
+msgid "Move Row Up"
+msgstr "Перемістити рядок вгору"
+
+#: gui/tablefieldwidget.cpp:283
+msgid "Move Row Down"
+msgstr "Перемістити рядок донизу"
+
+#: gui/tablefieldwidget.cpp:295
+msgid "Clear Table"
+msgstr "Очистити таблицю"
+
+#: gui/previewdialog.cpp:27
+msgid "Template Preview"
+msgstr "Попередній перегляд шаблону"
+
+#: gui/stringmapdialog.cpp:57
+msgid "&Set"
+msgstr "&Встановити"
+
+#: gui/fieldwidget.cpp:101 gui/fieldwidget.cpp:195
+msgid ""
+"_: Edit Label\n"
+"%1:"
+msgstr "%1:"
+
+#: gui/kwidgetlister.cpp:58
+msgid ""
+"_: more widgets\n"
+"More"
+msgstr "Більше"
+
+#: gui/kwidgetlister.cpp:62
+msgid ""
+"_: fewer widgets\n"
+"Fewer"
+msgstr "Менше"
+
+#: gui/kwidgetlister.cpp:69
+msgid ""
+"_: clear widgets\n"
+"Clear"
+msgstr "Очистити"
+
+#: gui/imagewidget.cpp:57
+msgid "Select Image..."
+msgstr "Вибрати зображення..."
+
+#: gui/imagewidget.cpp:63
+msgid "Save link only"
+msgstr ""
+
+#: gui/imagewidget.cpp:162
+msgid "Saving a link is only possible for newly added images."
+msgstr ""
+
+#: commands/modifyentries.cpp:73 commands/updateentries.cpp:50
+#, c-format
+msgid ""
+"_: Modify (Entry Title)\n"
+"Modify %1"
+msgstr "Редагувати %1"
+
+#: commands/collectioncommand.cpp:110
+msgid "Append Collection"
+msgstr "Доповнити зібрання"
+
+#: commands/collectioncommand.cpp:112
+msgid "Merge Collection"
+msgstr "Злити зібрання"
+
+#: commands/collectioncommand.cpp:114
+msgid "Replace Collection"
+msgstr "Замінити зібрання"
+
+#: commands/modifyentries.cpp:72 entryeditdialog.cpp:365
+msgid "Modify Entries"
+msgstr "Редагувати записи"
+
+#: commands/fieldcommand.cpp:104
+msgid "Add %1 Field"
+msgstr "Додати %1 поле"
+
+#: commands/fieldcommand.cpp:106
+msgid "Modify %1 Field"
+msgstr "Редагувати %1 поле"
+
+#: commands/fieldcommand.cpp:108
+msgid "Delete %1 Field"
+msgstr "Вилучити %1 поле"
+
+#: commands/addentries.cpp:50
+msgid "Add Entries"
+msgstr "Додати записи"
+
+#: commands/addentries.cpp:51
+#, c-format
+msgid ""
+"_: Add (Entry Title)\n"
+"Add %1"
+msgstr "Додати %1"
+
+#: commands/renamecollection.cpp:45 tellico_kernel.cpp:323
+msgid "Rename Collection"
+msgstr "Перейменувати зібрання"
+
+#: commands/modifyloans.cpp:75 loandialog.cpp:46
+msgid "Modify Loan"
+msgstr "Редагувати борг"
+
+#: commands/filtercommand.cpp:98
+msgid "Add Filter"
+msgstr "Додати фільтр"
+
+#: commands/filtercommand.cpp:100 filterdialog.cpp:282 filterview.cpp:68
+msgid "Modify Filter"
+msgstr "Редагувати фільтр"
+
+#: commands/filtercommand.cpp:102 filterview.cpp:70
+msgid "Delete Filter"
+msgstr "Вилучити фільтр"
+
+#: commands/addloans.cpp:108
+msgid "Check-out Items"
+msgstr "Дати у борг"
+
+#: commands/addloans.cpp:109
+#, c-format
+msgid ""
+"_: Check-out (Entry Title)\n"
+"Check-out %1"
+msgstr "Віддати у борг %1"
+
+#: commands/removeentries.cpp:48
+msgid "Delete Entries"
+msgstr "Вилучити записи"
+
+#: commands/removeentries.cpp:49
+#, c-format
+msgid ""
+"_: Delete (Entry Title)\n"
+"Delete %1"
+msgstr "Вилучити %1"
+
+#: commands/reorderfields.cpp:54
+msgid "Reorder Fields"
+msgstr "Упорядкувати поля"
+
+#: commands/removeloans.cpp:79
+msgid "Check-in Entries"
+msgstr "Перевірити записи"
+
+#: commands/removeloans.cpp:80
+#, c-format
+msgid ""
+"_: Check-in (Entry Title)\n"
+"Check-in %1"
+msgstr "Повернути борг %1"
+
+#: collectionfactory.cpp:83 collections/bibtexcollection.cpp:24
+#: collections/bibtexcollection.cpp:58 collections/bibtexcollection.cpp:88
+#: collections/boardgamecollection.cpp:19 collections/bookcollection.cpp:19
+#: collections/bookcollection.cpp:40 collections/cardcollection.cpp:19
+#: collections/coincollection.cpp:19 collections/comicbookcollection.cpp:19
+#: collections/filecatalog.cpp:19 collections/gamecollection.cpp:19
+#: collections/musiccollection.cpp:19 collections/stampcollection.cpp:19
+#: collections/videocollection.cpp:19 collections/videocollection.cpp:40
+#: collections/winecollection.cpp:19 configdialog.cpp:198
+#: fetch/imdbfetcher.cpp:689 fetch/imdbfetcher.cpp:948 field.cpp:40
+#: field.cpp:72 translators/gcfilmsimporter.cpp:78
+msgid "General"
+msgstr "Загальне"
+
+#: collections/bookcollection.cpp:143 collections/comicbookcollection.cpp:122
+#: collections/stampcollection.cpp:20
+msgid "Condition"
+msgstr "Стан"
+
+#: collections/boardgamecollection.cpp:20 collections/bookcollection.cpp:22
+#: collections/cardcollection.cpp:20 collections/coincollection.cpp:20
+#: collections/comicbookcollection.cpp:22 collections/gamecollection.cpp:20
+#: collections/musiccollection.cpp:20 collections/stampcollection.cpp:21
+#: collections/videocollection.cpp:22 collections/winecollection.cpp:20
+#: document.cpp:468
+msgid "Personal"
+msgstr "Особисте"
+
+#: collections/stampcollection.cpp:27
+msgid "My Stamps"
+msgstr "Мої марки"
+
+#: collectionfactory.cpp:82 collections/bibtexcollection.cpp:56
+#: collections/boardgamecollection.cpp:37 collections/bookcollection.cpp:39
+#: collections/cardcollection.cpp:37 collections/coincollection.cpp:37
+#: collections/comicbookcollection.cpp:39 collections/gamecollection.cpp:37
+#: collections/musiccollection.cpp:76 collections/stampcollection.cpp:38
+#: collections/videocollection.cpp:39 collections/winecollection.cpp:37
+#: entryupdater.cpp:229 fetch/fetchmanager.cpp:68 fetchdialog.cpp:169
+#: translators/audiofileimporter.cpp:164 translators/tellicoimporter.cpp:439
+msgid "Title"
+msgstr "Заголовок"
+
+#: collections/boardgamecollection.cpp:77 collections/filecatalog.cpp:45
+#: collections/gamecollection.cpp:87 collections/stampcollection.cpp:44
+#: entryupdater.cpp:230 fetchdialog.cpp:170
+msgid "Description"
+msgstr "Опис"
+
+#. TRANSLATORS: denomination refers to the monetary value.
+#: collections/coincollection.cpp:51 collections/stampcollection.cpp:50
+msgid "Denomination"
+msgstr "Вартість"
+
+#: collections/coincollection.cpp:67 collections/comicbookcollection.cpp:94
+#: collections/stampcollection.cpp:55 collections/winecollection.cpp:73
+msgid "Country"
+msgstr "Країна"
+
+#: collections/stampcollection.cpp:61
+msgid "Issue Year"
+msgstr "Рік видання"
+
+#: collections/stampcollection.cpp:66 collections/videocollection.cpp:172
+msgid "Color"
+msgstr "Колір"
+
+#: collections/stampcollection.cpp:71
+msgid "Scott#"
+msgstr "Scott#"
+
+#: collections/stampcollection.cpp:78
+msgid ""
+"_: Stamp grade levels - Superb,Extremely Fine,Very Fine,Fine,Average,Poor\n"
+"Superb,Extremely Fine,Very Fine,Fine,Average,Poor"
+msgstr ""
+"Супер, Відмінно, Добре, Нормально, Погано, "
+"Дуже погано"
+
+#: collections/coincollection.cpp:88 collections/stampcollection.cpp:80
+msgid "Grade"
+msgstr "Оцінка"
+
+#: collections/stampcollection.cpp:85
+msgid "Cancelled"
+msgstr "Звичайна марка"
+
+#. TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge
+#: collections/stampcollection.cpp:90
+msgid "Hinged"
+msgstr "Як медальйон"
+
+#: collections/stampcollection.cpp:95
+msgid "Centering"
+msgstr "Кругла"
+
+#: collections/stampcollection.cpp:100
+msgid "Gummed"
+msgstr "Приклеєна"
+
+#: collections/boardgamecollection.cpp:85 collections/bookcollection.cpp:64
+#: collections/cardcollection.cpp:82 collections/coincollection.cpp:103
+#: collections/comicbookcollection.cpp:126 collections/gamecollection.cpp:99
+#: collections/musiccollection.cpp:86 collections/stampcollection.cpp:105
+#: collections/videocollection.cpp:190 collections/winecollection.cpp:79
+msgid "Purchase Date"
+msgstr "Дата покупки"
+
+#: collections/boardgamecollection.cpp:94 collections/bookcollection.cpp:69
+#: collections/cardcollection.cpp:87 collections/coincollection.cpp:108
+#: collections/comicbookcollection.cpp:131 collections/gamecollection.cpp:108
+#: collections/musiccollection.cpp:95 collections/stampcollection.cpp:110
+#: collections/videocollection.cpp:199 collections/winecollection.cpp:84
+msgid "Purchase Price"
+msgstr "Ціна"
+
+#: collections/cardcollection.cpp:91 collections/coincollection.cpp:112
+#: collections/stampcollection.cpp:114 collections/winecollection.cpp:88
+msgid "Location"
+msgstr "Місце"
+
+#: collections/boardgamecollection.cpp:90 collections/bookcollection.cpp:155
+#: collections/cardcollection.cpp:96 collections/coincollection.cpp:118
+#: collections/comicbookcollection.cpp:139 collections/gamecollection.cpp:104
+#: collections/musiccollection.cpp:91 collections/stampcollection.cpp:120
+#: collections/videocollection.cpp:195 collections/winecollection.cpp:107
+msgid "Gift"
+msgstr "Дарований"
+
+#: collections/stampcollection.cpp:124 field.cpp:497
+msgid "Image"
+msgstr "Зображення"
+
+#: collections/boardgamecollection.cpp:105 collections/bookcollection.cpp:171
+#: collections/cardcollection.cpp:115 collections/coincollection.cpp:128
+#: collections/comicbookcollection.cpp:150 collections/gamecollection.cpp:119
+#: collections/musiccollection.cpp:111 collections/stampcollection.cpp:127
+#: collections/videocollection.cpp:210 collections/winecollection.cpp:114
+msgid "Comments"
+msgstr "Коментарі"
+
+#: collections/bibtexcollection.cpp:25 collections/bookcollection.cpp:20
+#: collections/comicbookcollection.cpp:20 translators/grs1importer.cpp:58
+#: translators/grs1importer.cpp:68 translators/pdfimporter.cpp:174
+#: translators/risimporter.cpp:281
+msgid "Publishing"
+msgstr "Публікація"
+
+#: collections/bookcollection.cpp:21 collections/comicbookcollection.cpp:21
+#: translators/grs1importer.cpp:63 translators/risimporter.cpp:275
+msgid "Classification"
+msgstr "Класифікація"
+
+#: collections/comicbookcollection.cpp:28
+msgid "My Comic Books"
+msgstr "Моя книга коміксів"
+
+#: collections/bookcollection.cpp:45 collections/comicbookcollection.cpp:45
+msgid "Subtitle"
+msgstr "Підзаголовок"
+
+#: collections/comicbookcollection.cpp:50 collections/videocollection.cpp:121
+msgid "Writer"
+msgstr "Письменник"
+
+#: collections/comicbookcollection.cpp:56
+msgid ""
+"_: Comic Book Illustrator\n"
+"Artist"
+msgstr "Художник"
+
+#: collections/bibtexcollection.cpp:200 collections/bookcollection.cpp:132
+#: collections/cardcollection.cpp:71 collections/comicbookcollection.cpp:62
+msgid "Series"
+msgstr "Серія"
+
+#: collections/comicbookcollection.cpp:68
+msgid "Issue"
+msgstr "Видання"
+
+#: collections/bibtexcollection.cpp:120 collections/boardgamecollection.cpp:60
+#: collections/bookcollection.cpp:73 collections/comicbookcollection.cpp:73
+msgid "Publisher"
+msgstr "Видавець"
+
+#: collections/bibtexcollection.cpp:133 collections/bookcollection.cpp:79
+#: collections/comicbookcollection.cpp:79
+msgid "Edition"
+msgstr "Видання"
+
+#: collections/bookcollection.cpp:90 collections/comicbookcollection.cpp:85
+msgid "Publication Year"
+msgstr "Рік видання"
+
+#: collections/bibtexcollection.cpp:140 collections/bookcollection.cpp:105
+#: collections/comicbookcollection.cpp:90
+msgid "Pages"
+msgstr "Кількість сторінок"
+
+#: collections/bookcollection.cpp:115 collections/comicbookcollection.cpp:100
+#: translators/grs1importer.cpp:67
+msgid "Language"
+msgstr "Мова"
+
+#: collections/boardgamecollection.cpp:43 collections/bookcollection.cpp:120
+#: collections/comicbookcollection.cpp:106 collections/gamecollection.cpp:54
+#: collections/musiccollection.cpp:67 collections/videocollection.cpp:67
+msgid "Genre"
+msgstr "Жанр"
+
+#: collections/bibtexcollection.cpp:222 collections/bookcollection.cpp:127
+#: collections/cardcollection.cpp:100 collections/comicbookcollection.cpp:112
+#: collections/musiccollection.cpp:103 fetch/amazonfetcher.cpp:933
+#: translators/grs1importer.cpp:62 translators/risimporter.cpp:273
+msgid "Keywords"
+msgstr "Ключові слова"
+
+#: collections/comicbookcollection.cpp:120
+msgid ""
+"_: Comic book grade levels - Mint,Near Mint,Very Fine,Fine,Very "
+"Good,Good,Fair,Poor\n"
+"Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"
+msgstr ""
+"Супер, Відмінно, Дуже добре, Добре, "
+"Середньо, Нижче середнього, Погано, Дуже "
+"погано"
+
+#: collections/bookcollection.cpp:147 collections/comicbookcollection.cpp:135
+msgid "Signed"
+msgstr "Підписано"
+
+#: collections/boardgamecollection.cpp:98 collections/bookcollection.cpp:159
+#: collections/comicbookcollection.cpp:143 collections/gamecollection.cpp:112
+#: collections/musiccollection.cpp:99 collections/videocollection.cpp:203
+#: document.cpp:466
+msgid "Loaned"
+msgstr "Даний у борг"
+
+#: collections/bookcollection.cpp:168 collections/comicbookcollection.cpp:147
+#: fetch/arxivfetcher.cpp:216 fetch/crossreffetcher.cpp:206
+#: translators/pdfimporter.cpp:204 translators/referencerimporter.cpp:48
+msgid "Front Cover"
+msgstr "Обкладинка"
+
+#: collections/coincollection.cpp:26
+msgid "My Coins"
+msgstr "Мої монети"
+
+#: collections/coincollection.cpp:44 collections/winecollection.cpp:68
+msgid "Type"
+msgstr "Тип"
+
+#: collections/bibtexcollection.cpp:145 collections/cardcollection.cpp:66
+#: collections/coincollection.cpp:56 collections/musiccollection.cpp:62
+msgid "Year"
+msgstr "Рік"
+
+#: collections/coincollection.cpp:61
+msgid "Mint Mark"
+msgstr "Місце чеканки"
+
+#: collections/coincollection.cpp:73
+msgid "Coin Set"
+msgstr "Набір монет"
+
+#: collections/coincollection.cpp:83
+msgid ""
+"_: Coin grade levels - Proof-65,Proof-60,Mint State-65,Mint State-60,Almost "
+"Uncirculated-55,Almost Uncirculated-50,Extremely Fine-40,Very Fine-30,Very "
+"Fine-20,Fine-12,Very Good-8,Good-4,Fair\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Almost Uncirculated-55,Almost "
+"Uncirculated-50,Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,Very "
+"Good-8,Good-4,Fair"
+msgstr ""
+"_: Рівні ґатунку монет - Proof-65,Proof-60,Mint "
+"State-65,Mint State-60,Майже не "
+"розповсюджується-55,Майже не "
+"розповсюджується-50,Надзвичайно "
+"відмінно-40,Дуже відмінно-30,Дуже "
+"відмінно-20,Відмінно-12,Дуже "
+"добре-8,Добре-4,Посередньо\n"
+"Proof-65,Proof-60,Mint State-65,Mint State-60,Майже не "
+"розповсюджується-55,Майже не "
+"розповсюджується-50,Надзвичайно "
+"відмінно-40,Дуже відмінно-30,Дуже "
+"відмінно-20,Відмінно-12,Дуже "
+"добре-8,Добре-4,Посередньо"
+
+#: collections/coincollection.cpp:96
+msgid ""
+"_: Coin grading services - PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+msgstr ""
+"_: Сервіси класифікації монет - "
+"PCGS,NGC,ANACS,ICG,ASA,PCI\n"
+"PCGS,NGC,ANACS,ICG,ASA,PCI"
+
+#: collections/coincollection.cpp:98
+msgid "Grading Service"
+msgstr "Сервіс оцінки"
+
+#: collections/coincollection.cpp:122
+msgid "Obverse"
+msgstr "\"Орел\""
+
+#: collections/coincollection.cpp:125
+msgid "Reverse"
+msgstr "\"Решка\""
+
+#: collections/bookcollection.cpp:28
+msgid "My Books"
+msgstr "Мої книги"
+
+#: collections/bibtexcollection.cpp:79 collections/bookcollection.cpp:50
+msgid "Author"
+msgstr "Автор"
+
+#: collections/bookcollection.cpp:57 translators/alexandriaimporter.cpp:135
+msgid "Hardback"
+msgstr "Тверда палітурка"
+
+#: collections/bookcollection.cpp:57
+msgid "Paperback"
+msgstr "М'яка палітурка"
+
+#: collections/bookcollection.cpp:57
+msgid "Trade Paperback"
+msgstr "Газета"
+
+#: collections/bookcollection.cpp:58
+msgid "E-Book"
+msgstr "Електронна книга"
+
+#: collections/bookcollection.cpp:58
+msgid "Magazine"
+msgstr "Журнал"
+
+#: collections/bibtexcollection.cpp:157 collections/bookcollection.cpp:58
+msgid "Journal"
+msgstr "Щоденник"
+
+#: collections/bookcollection.cpp:59
+msgid "Binding"
+msgstr "Палітурка"
+
+#: collections/bookcollection.cpp:85
+msgid "Copyright Year"
+msgstr "Рік здачі до друку"
+
+#: collections/bibtexcollection.cpp:151 collections/bookcollection.cpp:95
+#: translators/grs1importer.cpp:57 translators/risimporter.cpp:278
+msgid "ISBN#"
+msgstr "ISBN#"
+
+#: collections/bibtexcollection.cpp:154 collections/bookcollection.cpp:97
+#: translators/grs1importer.cpp:59 translators/risimporter.cpp:282
+msgid "International Standard Book Number"
+msgstr "Міжнародний Стандартний Номер Книги"
+
+#: collections/bookcollection.cpp:100
+msgid "LCCN#"
+msgstr "LCCN#"
+
+#: collections/bookcollection.cpp:102
+msgid "Library of Congress Control Number"
+msgstr ""
+"Контрольний Номер Бібліотеки Конгресу"
+
+#: collections/bookcollection.cpp:109
+msgid "Translator"
+msgstr ""
+
+#: collections/bookcollection.cpp:137
+msgid "Series Number"
+msgstr "Номер серії"
+
+#: collections/bookcollection.cpp:142 mainwindow.cpp:185
+msgid "New"
+msgstr "Нова"
+
+#: collections/bookcollection.cpp:142
+msgid "Used"
+msgstr "Вживана"
+
+#: collections/bookcollection.cpp:151
+msgid "Read"
+msgstr "Прочитана"
+
+#: collections/boardgamecollection.cpp:80 collections/bookcollection.cpp:163
+#: collections/musiccollection.cpp:81 collections/winecollection.cpp:102
+#: field.cpp:501 newstuff/dialog.cpp:115
+msgid "Rating"
+msgstr "Рейтинг"
+
+#: collections/filecatalog.cpp:25
+msgid "My Files"
+msgstr "Мої файли"
+
+#: borrowerdialog.cpp:49 collections/filecatalog.cpp:36
+#: newstuff/dialog.cpp:113
+msgid "Name"
+msgstr "Ім'я"
+
+#: collections/bibtexcollection.cpp:227 collections/filecatalog.cpp:41
+#: fetch/entrezfetcher.cpp:400 fetch/entrezfetcher.cpp:487 field.cpp:495
+#: translators/gcfilmsimporter.cpp:77 translators/risimporter.cpp:284
+msgid "URL"
+msgstr "URL"
+
+#: collections/bibtexcollection.cpp:207 collections/filecatalog.cpp:50
+msgid "Volume"
+msgstr "Том"
+
+#: collections/filecatalog.cpp:55
+msgid "Folder"
+msgstr "Тека"
+
+#: collections/filecatalog.cpp:60
+msgid "Mimetype"
+msgstr "Mimetype"
+
+#: collections/filecatalog.cpp:65
+msgid "Size"
+msgstr "Розмір"
+
+#: collections/filecatalog.cpp:69
+msgid "Permissions"
+msgstr "Права"
+
+#: collections/filecatalog.cpp:74
+msgid "Owner"
+msgstr "Власник"
+
+#: collections/filecatalog.cpp:79
+msgid "Group"
+msgstr "Група"
+
+#: collections/filecatalog.cpp:85
+msgid "Created"
+msgstr "Створений"
+
+#: collections/filecatalog.cpp:89
+msgid "Modified"
+msgstr "Редагований"
+
+#: collections/filecatalog.cpp:93
+msgid "Meta Info"
+msgstr "Додаткова інформація"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:95
+msgid "Property"
+msgstr "Властивість"
+
+#: collectionfieldsdialog.cpp:873 collections/filecatalog.cpp:96
+msgid "Value"
+msgstr "Значення"
+
+#: collections/filecatalog.cpp:99
+msgid "Icon"
+msgstr "Значок"
+
+#: collections/winecollection.cpp:26
+msgid "My Wines"
+msgstr "Мої вина"
+
+#: collections/videocollection.cpp:115 collections/winecollection.cpp:43
+msgid "Producer"
+msgstr "Виробник"
+
+#: collections/winecollection.cpp:49
+msgid "Appellation"
+msgstr "Назва"
+
+#: collections/winecollection.cpp:55
+msgid "Varietal"
+msgstr "Сорт"
+
+#: collections/winecollection.cpp:61
+msgid "Vintage"
+msgstr "Урожай"
+
+#: collections/winecollection.cpp:67
+msgid "Red Wine"
+msgstr "Червоне вино"
+
+#: collections/winecollection.cpp:67
+msgid "White Wine"
+msgstr "Біле вино"
+
+#: collections/winecollection.cpp:67
+msgid "Sparkling Wine"
+msgstr "Ігристе вино"
+
+#: collections/cardcollection.cpp:105 collections/winecollection.cpp:93
+msgid "Quantity"
+msgstr "Кількість"
+
+#: collections/winecollection.cpp:97
+msgid "Drink By"
+msgstr "Було випито"
+
+#: collections/winecollection.cpp:111
+msgid "Label Image"
+msgstr "Зображення етикетки"
+
+#: collections/videocollection.cpp:20 fetch/animenfofetcher.cpp:265
+msgid "Other People"
+msgstr "Інші люди"
+
+#: collections/videocollection.cpp:21 fetch/animenfofetcher.cpp:271
+msgid "Features"
+msgstr "Особливості"
+
+#: collections/videocollection.cpp:28
+msgid "My Videos"
+msgstr "Мої відеозаписи"
+
+#: collections/musiccollection.cpp:44 collections/videocollection.cpp:46
+msgid "DVD"
+msgstr "DVD"
+
+#: collections/videocollection.cpp:46
+msgid "VHS"
+msgstr "VHS"
+
+#: collections/videocollection.cpp:46
+msgid "VCD"
+msgstr "VCD"
+
+#: collections/videocollection.cpp:46
+msgid "DivX"
+msgstr "MPEG-4"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:823
+msgid "Blu-ray"
+msgstr "Blu-ray"
+
+#: collections/videocollection.cpp:46 fetch/amazonfetcher.cpp:826
+msgid "HD DVD"
+msgstr "HD DVD"
+
+#: collections/musiccollection.cpp:45 collections/videocollection.cpp:47
+msgid "Medium"
+msgstr "Носій"
+
+#: collections/videocollection.cpp:52
+msgid "Production Year"
+msgstr "Рік запису"
+
+#: collections/videocollection.cpp:60
+msgid ""
+"_: Movie ratings - G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)\n"
+"G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"
+msgstr "G (США),PG (США),PG-13 (США),R (USA), U (США)"
+
+#: collections/videocollection.cpp:62
+msgid "Certification"
+msgstr "Віковий рейтинг"
+
+#: collections/videocollection.cpp:74
+msgid "Region 1"
+msgstr "Регіон 1"
+
+#: collections/videocollection.cpp:75
+msgid "Region 2"
+msgstr "Регіон 2"
+
+#: collections/videocollection.cpp:76
+msgid "Region 3"
+msgstr "Регіон 3"
+
+#: collections/videocollection.cpp:77
+msgid "Region 4"
+msgstr "Регіон 4"
+
+#: collections/videocollection.cpp:78
+msgid "Region 5"
+msgstr "Регіон 5"
+
+#: collections/videocollection.cpp:79
+msgid "Region 6"
+msgstr "Регіон 6"
+
+#: collections/videocollection.cpp:80
+msgid "Region 7"
+msgstr "Регіон 7"
+
+#: collections/videocollection.cpp:81
+msgid "Region 8"
+msgstr "Регіон 8"
+
+#: collections/videocollection.cpp:82
+msgid "Region"
+msgstr "Регіон"
+
+#: collections/videocollection.cpp:87
+msgid "Nationality"
+msgstr "Країна"
+
+#: collections/videocollection.cpp:94
+msgid "NTSC"
+msgstr "NTSC"
+
+#: collections/videocollection.cpp:94
+msgid "PAL"
+msgstr "PAL"
+
+#: collections/videocollection.cpp:94
+msgid "SECAM"
+msgstr "SECAM"
+
+#: collections/videocollection.cpp:95
+msgid "Format"
+msgstr "Формат"
+
+#: collections/videocollection.cpp:100
+msgid "Cast"
+msgstr "Ролі"
+
+#: collections/videocollection.cpp:102 translators/tellicoimporter.cpp:443
+msgid "Actor/Actress"
+msgstr "Актор/Актриса"
+
+#: collections/videocollection.cpp:103 translators/tellicoimporter.cpp:444
+msgid "Role"
+msgstr "Ролі"
+
+#: collections/videocollection.cpp:106
+msgid "A table for the cast members, along with the roles they play"
+msgstr ""
+"Таблиця для запису акторів і ролей, які "
+"вони грали"
+
+#: collections/videocollection.cpp:109
+msgid "Director"
+msgstr "Режисер"
+
+#: collections/videocollection.cpp:127
+msgid "Composer"
+msgstr "Композитор"
+
+#: collections/videocollection.cpp:133
+msgid "Studio"
+msgstr "Студія"
+
+#: collections/videocollection.cpp:139
+msgid "Language Tracks"
+msgstr "Мови"
+
+#: collections/videocollection.cpp:145
+msgid "Subtitle Languages"
+msgstr "Мови субтитрів"
+
+#: collections/videocollection.cpp:151
+msgid "Audio Tracks"
+msgstr "Аудіо треки"
+
+#: collections/videocollection.cpp:157
+msgid "Running Time"
+msgstr "Тривалість"
+
+#: collections/videocollection.cpp:159
+msgid "The running time of the video (in minutes)"
+msgstr "Тривалість відео (у хвилинах)"
+
+#: collections/videocollection.cpp:162
+msgid "Aspect Ratio"
+msgstr "Співвідношення сторін"
+
+#: collections/videocollection.cpp:167 fetch/amazonfetcher.cpp:815
+#: translators/tellicoimporter.cpp:958
+msgid "Widescreen"
+msgstr "Широкоекранний"
+
+#: collections/videocollection.cpp:172
+msgid "Black & White"
+msgstr "Чорно-білий"
+
+#: collections/videocollection.cpp:173
+msgid "Color Mode"
+msgstr "Кольоровий"
+
+#: collections/videocollection.cpp:178 fetch/amazonfetcher.cpp:830
+msgid "Director's Cut"
+msgstr "Режисерська версія"
+
+#: collections/videocollection.cpp:182 fetch/ibsfetcher.cpp:358
+msgid "Plot Summary"
+msgstr "Сюжет фільму"
+
+#: collections/gamecollection.cpp:90 collections/videocollection.cpp:185
+msgid "Personal Rating"
+msgstr "Особистий рейтинг"
+
+#: collections/boardgamecollection.cpp:102 collections/gamecollection.cpp:116
+#: collections/musiccollection.cpp:108 collections/videocollection.cpp:207
+msgid "Cover"
+msgstr "Обкладинка"
+
+#: collections/gamecollection.cpp:26
+msgid "My Games"
+msgstr "Мої ігри"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox 360"
+msgstr "Xbox 360"
+
+#: collections/gamecollection.cpp:44
+msgid "Xbox"
+msgstr "Xbox"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation3"
+msgstr "PlayStation3"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation2"
+msgstr "PlayStation 2"
+
+#: collections/gamecollection.cpp:45
+msgid "PlayStation"
+msgstr "PlayStation"
+
+#: collections/gamecollection.cpp:45
+msgid ""
+"_: PlayStation Portable\n"
+"PSP"
+msgstr "PSP"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo Wii"
+msgstr "Nintendo Wii"
+
+#: collections/gamecollection.cpp:46
+msgid "Nintendo DS"
+msgstr "Nintendo DS"
+
+#: collections/gamecollection.cpp:46
+msgid "GameCube"
+msgstr "GameCube"
+
+#: collections/gamecollection.cpp:46
+msgid "Dreamcast"
+msgstr "Dreamcast"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Advance"
+msgstr "Game Boy Advance"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy Color"
+msgstr "Game Boy Color"
+
+#: collections/gamecollection.cpp:47
+msgid "Game Boy"
+msgstr "Game Boy"
+
+#: collections/gamecollection.cpp:48
+msgid ""
+"_: Windows Platform\n"
+"Windows"
+msgstr "Windows"
+
+#: collections/gamecollection.cpp:48
+msgid "Mac OS"
+msgstr "Mac OS"
+
+#: collections/gamecollection.cpp:48
+msgid "Linux"
+msgstr "Linux"
+
+#: collections/gamecollection.cpp:49
+msgid "Platform"
+msgstr "Платформа"
+
+#: collections/boardgamecollection.cpp:55 collections/gamecollection.cpp:60
+msgid "Release Year"
+msgstr "Рік випуску"
+
+#: collections/gamecollection.cpp:65
+msgid ""
+"_: Games - Publisher\n"
+"Publisher"
+msgstr "Видавництво"
+
+#: collections/gamecollection.cpp:71
+msgid "Developer"
+msgstr "Розробник"
+
+#: collections/gamecollection.cpp:80
+msgid ""
+"_: Video game ratings - Unrated, Adults Only, Mature, Teen, Everyone, Early "
+"Childhood, Pending\n"
+"Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"
+msgstr ""
+"Без рейтингу, Для дорослих, Для підлітків, "
+"Для всіх, Для дітей, Невідомий"
+
+#: collections/gamecollection.cpp:82
+msgid "ESRB Rating"
+msgstr "Віковий рейтинг"
+
+#: collections/gamecollection.cpp:95
+msgid "Completed"
+msgstr "Пройдена"
+
+#: collections/cardcollection.cpp:26
+msgid "My Cards"
+msgstr "Мої карти"
+
+#: collections/cardcollection.cpp:43
+msgid "Player"
+msgstr "Гравець"
+
+#: collections/cardcollection.cpp:49
+msgid "Team"
+msgstr "Команда"
+
+#: collections/cardcollection.cpp:55
+msgid "Brand"
+msgstr "Фірма"
+
+#: collections/cardcollection.cpp:62
+msgid "Card Number"
+msgstr "Номер карти"
+
+#: collections/cardcollection.cpp:77
+msgid "Card Type"
+msgstr "Тип карти"
+
+#: collections/cardcollection.cpp:109
+msgid "Front Image"
+msgstr "Зображення передньої сторони"
+
+#: collections/cardcollection.cpp:112
+msgid "Back Image"
+msgstr "Зображення задньої сторони"
+
+#: collections/boardgamecollection.cpp:26
+#, fuzzy
+msgid "My Board Games"
+msgstr "Мої ігри"
+
+#: collections/boardgamecollection.cpp:49
+msgid "Mechanism"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:66
+msgid "Designer"
+msgstr ""
+
+#: collections/boardgamecollection.cpp:72
+msgid "Number of Players"
+msgstr ""
+
+#: collectionfactory.cpp:125 collections/bibtexcollection.cpp:30
+msgid "Bibliography"
+msgstr "Бібліографія"
+
+#: collections/bibtexcollection.cpp:72
+msgid "Entry Type"
+msgstr "Тип запису"
+
+#: collections/bibtexcollection.cpp:76
+msgid "These entry types are specific to bibtex. See the bibtex documentation."
+msgstr ""
+"Ці типи записів специфічні для bibtex. "
+"Дивіться документацію bibtex."
+
+#: collections/bibtexcollection.cpp:86
+msgid "Bibtex Key"
+msgstr "Ключ bibtex"
+
+#: collections/bibtexcollection.cpp:92
+msgid "Book Title"
+msgstr "Назва книги"
+
+#: collections/bibtexcollection.cpp:98
+msgid "Editor"
+msgstr "Редактор"
+
+#: collections/bibtexcollection.cpp:105
+msgid "Organization"
+msgstr "Організація"
+
+#: collections/bibtexcollection.cpp:127 fetch/srufetcher.cpp:412
+#: fetch/z3950fetcher.cpp:668
+msgid "Address"
+msgstr "Адреса"
+
+#: collections/bibtexcollection.cpp:164 fetch/fetchmanager.cpp:73
+msgid "DOI"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:167
+msgid "Digital Object Identifier"
+msgstr ""
+
+#: collections/bibtexcollection.cpp:172
+msgid "Month"
+msgstr "Місяць"
+
+#: collections/bibtexcollection.cpp:178 field.cpp:494
+msgid "Number"
+msgstr "Номер"
+
+#: collections/bibtexcollection.cpp:183
+msgid "How Published"
+msgstr "Як видавалася"
+
+#: collections/bibtexcollection.cpp:195
+msgid "Chapter"
+msgstr "Частина"
+
+#: collections/bibtexcollection.cpp:212
+msgid "Cross-Reference"
+msgstr "Рекомендації"
+
+#: collections/bibtexcollection.cpp:232 fetch/entrezfetcher.cpp:486
+#: fetch/srufetcher.cpp:413 fetch/z3950fetcher.cpp:669
+#: translators/risimporter.cpp:269
+msgid "Abstract"
+msgstr "Резюме"
+
+#: collections/bibtexcollection.cpp:236
+msgid "Notes"
+msgstr "Замітки"
+
+#: collections/musiccollection.cpp:26
+msgid "My Music"
+msgstr "Мої аудіозаписи"
+
+#: collections/musiccollection.cpp:37
+msgid "Album"
+msgstr "Альбом"
+
+#: collections/musiccollection.cpp:44 translators/freedbimporter.cpp:257
+#: translators/freedbimporter.cpp:375 translators/freedbimporter.cpp:446
+msgid "Compact Disc"
+msgstr "Компакт-диск"
+
+#: collections/musiccollection.cpp:44
+msgid "Cassette"
+msgstr "Аудіокасета"
+
+#: collections/musiccollection.cpp:44
+msgid "Vinyl"
+msgstr "Вінілова пластинка"
+
+#: collections/musiccollection.cpp:50 collections/musiccollection.cpp:77
+#: translators/audiofileimporter.cpp:165 translators/tellicoimporter.cpp:440
+msgid "Artist"
+msgstr "Виконавець"
+
+#: collections/musiccollection.cpp:56
+msgid "Label"
+msgstr "Лейбл"
+
+#: collections/musiccollection.cpp:73
+msgid "Tracks"
+msgstr "Треки"
+
+#: collections/musiccollection.cpp:78 translators/audiofileimporter.cpp:166
+#: translators/tellicoimporter.cpp:441
+msgid "Length"
+msgstr "Довжина"
+
+#: core/tellico_config.cpp:134
+msgid ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+msgstr ""
+"a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,"
+"up,with"
+
+#: core/tellico_config.cpp:137
+msgid "the"
+msgstr "the"
+
+#: core/tellico_config.cpp:140
+msgid "jr.,jr,iii,iv"
+msgstr "мол., ст.,jr.,jr"
+
+#: core/tellico_config.cpp:143
+msgid "de,van,der,van der,von"
+msgstr "de,van,der,van der,von"
+
+#: fetch/isbndbfetcher.cpp:54
+msgid "ISBNdb.com"
+msgstr "ISBNdb.com"
+
+#: fetch/amazonfetcher.cpp:192 fetch/animenfofetcher.cpp:75
+#: fetch/arxivfetcher.cpp:83 fetch/bibsonomyfetcher.cpp:66
+#: fetch/citebasefetcher.cpp:67 fetch/crossreffetcher.cpp:89
+#: fetch/discogsfetcher.cpp:102 fetch/ibsfetcher.cpp:72
+#: fetch/isbndbfetcher.cpp:79 fetch/yahoofetcher.cpp:94
+msgid "%1 does not allow searching for this collection type."
+msgstr "У цьому типі зібрань не можна шукати %1"
+
+#: fetch/amazonfetcher.cpp:562 fetch/isbndbfetcher.cpp:247
+msgid "Results from %1: %2/%3"
+msgstr "Результати від %1: %2/%3"
+
+#: fetch/animenfofetcher.cpp:370 fetch/arxivfetcher.cpp:355
+#: fetch/bibsonomyfetcher.cpp:198 fetch/citebasefetcher.cpp:237
+#: fetch/entrezfetcher.cpp:466 fetch/ibsfetcher.cpp:407
+#: fetch/isbndbfetcher.cpp:342 fetch/yahoofetcher.cpp:392
+msgid "This source has no options."
+msgstr "Немає опцій"
+
+#: fetch/entrezfetcher.cpp:56
+msgid "Entrez Database"
+msgstr "База даних Entrez"
+
+#: fetch/entrezfetcher.cpp:485
+msgid "Institution"
+msgstr "Інститут"
+
+#: fetch/z3950connection.cpp:132
+msgid "Query error!"
+msgstr "Помилка запиту"
+
+#: fetch/z3950connection.cpp:173
+msgid "Connection search error %1: %2"
+msgstr "Помилка з'єднання з пошуком %1: %2"
+
+#: fetch/z3950connection.cpp:250
+msgid "Record syntax error"
+msgstr "Синтаксична помилка"
+
+#: fetch/z3950connection.cpp:345
+msgid "Connection error %1: %2"
+msgstr "Помилка з'єднання %1: %2"
+
+#: fetch/srufetcher.cpp:72
+msgid "SRU Server"
+msgstr "Сервер SRU"
+
+#: fetch/srufetcher.cpp:405 z3950.cpp:2
+msgid "Library of Congress (US)"
+msgstr "Бібліотека Конґресу (США)"
+
+#: fetch/imdbfetcher.cpp:1121 fetch/srufetcher.cpp:428
+#: fetch/z3950fetcher.cpp:504
+msgid "Hos&t: "
+msgstr "&Сервер: "
+
+#: fetch/srufetcher.cpp:435 fetch/z3950fetcher.cpp:510
+msgid "Enter the host name of the server."
+msgstr "Введіть адресу сервера."
+
+#: fetch/srufetcher.cpp:440 fetch/z3950fetcher.cpp:515
+msgid "&Port: "
+msgstr "&Порт"
+
+#: fetch/srufetcher.cpp:445 fetch/z3950fetcher.cpp:520
+#, c-format
+msgid "Enter the port number of the server. The default is %1."
+msgstr ""
+"Введіть номер порту сервера. За "
+"умовчанням вибраний %1"
+
+#: fetch/srufetcher.cpp:450
+msgid "Path: "
+msgstr "Шлях: "
+
+#: fetch/srufetcher.cpp:455
+msgid "Enter the path to the database used by the server."
+msgstr ""
+"Введіть шлях до бази даних, що "
+"використовується на сервері."
+
+#: fetch/srufetcher.cpp:460
+msgid "Format: "
+msgstr "Формат: "
+
+#: fetch/srufetcher.cpp:468
+msgid "Enter the result format used by the server."
+msgstr ""
+"Введіть результуючий формат, що "
+"використовується сервером."
+
+#: fetch/yahoofetcher.cpp:54
+msgid "Yahoo! Audio Search"
+msgstr "Аудіо-пошук Yahoo!"
+
+#: fetch/amazonfetcher.cpp:730 fetch/discogsfetcher.cpp:539
+#: fetch/yahoofetcher.cpp:242
+msgid "The cover image could not be loaded."
+msgstr ""
+"Не виходить завантажити зображення "
+"обкладинки"
+
+#: fetch/amazonfetcher.cpp:53
+msgid "Amazon Link"
+msgstr "Посилання Amazon"
+
+#: fetch/amazonfetcher.cpp:62
+msgid "Amazon (US)"
+msgstr "Amazon (США)"
+
+#: fetch/amazonfetcher.cpp:65
+msgid "Amazon (UK)"
+msgstr "Amazon (UK)"
+
+#: fetch/amazonfetcher.cpp:68
+msgid "Amazon (Germany)"
+msgstr "Amazon (Німеччина)"
+
+#: fetch/amazonfetcher.cpp:71
+msgid "Amazon (Japan)"
+msgstr "Amazon (Японія)"
+
+#: fetch/amazonfetcher.cpp:74
+msgid "Amazon (France)"
+msgstr "Amazon (Франція)"
+
+#: fetch/amazonfetcher.cpp:77
+msgid "Amazon (Canada)"
+msgstr "Amazon (Канада)"
+
+#: fetch/amazonfetcher.cpp:99
+msgid "Amazon.com Web Services"
+msgstr "Сервіси Amazon.com"
+
+#: fetch/amazonfetcher.cpp:848
+msgid "Co&untry: "
+msgstr "&Країна"
+
+#: fetch/amazonfetcher.cpp:851
+msgid "United States"
+msgstr "США"
+
+#: fetch/amazonfetcher.cpp:852
+msgid "United Kingdom"
+msgstr "Великобританія"
+
+#: fetch/amazonfetcher.cpp:853
+msgid "Germany"
+msgstr "Німеччина"
+
+#: fetch/amazonfetcher.cpp:854
+msgid "Japan"
+msgstr "Японія"
+
+#: fetch/amazonfetcher.cpp:855
+msgid "France"
+msgstr "Франція"
+
+#: fetch/amazonfetcher.cpp:856
+msgid "Canada"
+msgstr "Канада"
+
+#: fetch/amazonfetcher.cpp:860
+msgid ""
+"Amazon.com provides data from several different localized sites. Choose the "
+"one you wish to use for this data source."
+msgstr ""
+"Amazon.com надає дані з декількох своїх "
+"сайтів. Виберіть джерело, звідки Ви "
+"хочете отримати дані."
+
+#: fetch/amazonfetcher.cpp:866
+msgid "&Image size: "
+msgstr "&Розмір зображення"
+
+#: fetch/amazonfetcher.cpp:869
+msgid "Small Image"
+msgstr "Маленьке зображення"
+
+#: fetch/amazonfetcher.cpp:870
+msgid "Medium Image"
+msgstr "Середнє зображення"
+
+#: fetch/amazonfetcher.cpp:871
+msgid "Large Image"
+msgstr "Велике зображення"
+
+#: fetch/amazonfetcher.cpp:872
+msgid "No Image"
+msgstr "Немає зображення"
+
+#: fetch/amazonfetcher.cpp:875 fetch/discogsfetcher.cpp:683
+#: fetch/imdbfetcher.cpp:1146
+msgid ""
+"The cover image may be downloaded as well. However, too many large images in "
+"the collection may degrade performance."
+msgstr ""
+"Пам'ятаєте, що багато великих зображень "
+"можуть погіршити зручність в роботі з "
+"програмою"
+
+#: fetch/amazonfetcher.cpp:881
+msgid "&Associate's ID: "
+msgstr "&Associate's ID: "
+
+#: fetch/amazonfetcher.cpp:886
+msgid ""
+"The associate's id identifies the person accessing the Amazon.com Web "
+"Services, and is included in any links to the Amazon.com site."
+msgstr ""
+"'Associate's ID' потрібний для доступу до "
+"багатьох сервісів Amazon.com"
+
+#: fetch/z3950fetcher.cpp:79 fetch/z3950fetcher.cpp:755
+msgid "z39.50 Server"
+msgstr "Сервер z39.50"
+
+#: fetch/z3950fetcher.cpp:494
+msgid "Use preset &server:"
+msgstr ""
+"Використовуйте попередньо заданий "
+"&сервер:"
+
+#: fetch/z3950fetcher.cpp:525
+msgid "&Database: "
+msgstr "&База даних"
+
+#: fetch/z3950fetcher.cpp:530
+msgid "Enter the database name used by the server."
+msgstr ""
+"Введіть назву бази даних, "
+"використовуваної на сервері."
+
+#: fetch/z3950fetcher.cpp:535
+msgid "Ch&aracter set: "
+msgstr "&Кодування:"
+
+#: fetch/z3950fetcher.cpp:544
+msgid ""
+"Enter the character set encoding used by the z39.50 server. The most likely "
+"choice is MARC-8, although ISO-8859-1 is common as well."
+msgstr ""
+"Введіть кодування, використовуване "
+"сервером z39.50. Самий кращий вибір: MARC-8."
+
+#: fetch/z3950fetcher.cpp:550
+msgid "&Format: "
+msgstr "&Формат: "
+
+#: fetch/z3950fetcher.cpp:553
+msgid "Auto-detect"
+msgstr "Авто-визначення"
+
+#: fetch/z3950fetcher.cpp:561
+msgid ""
+"Enter the data format used by the z39.50 server. Tellico will attempt to "
+"automatically detect the best setting if <i>auto-detect</i> is selected."
+msgstr ""
+"Введіть формат даних, використовуваний "
+"z39.50 сервером. Tellico спробує автоматично "
+"виявити краще налаштування, якщо вибрано "
+"<i>авто-визначення</i>."
+
+#: fetch/z3950fetcher.cpp:567
+msgid "&User: "
+msgstr "&Користувач:"
+
+#: fetch/z3950fetcher.cpp:570 fetch/z3950fetcher.cpp:582
+msgid "Optional"
+msgstr "Необов'язково"
+
+#: fetch/z3950fetcher.cpp:573
+msgid ""
+"Enter the authentication user name used by the z39.50 database. Most servers "
+"do not need one."
+msgstr ""
+"Введіть ім'я користувача бази даних z39.50. "
+"Для багатьох серверів нічого вводити не "
+"потрібно."
+
+#: fetch/z3950fetcher.cpp:579
+msgid "Pass&word: "
+msgstr "Па&роль"
+
+#: fetch/z3950fetcher.cpp:586
+msgid ""
+"Enter the authentication password used by the z39.50 database. Most servers "
+"do not need one. The password will be saved in plain text in the Tellico "
+"configuration file."
+msgstr ""
+"Введіть пароль для доступу до бази даних "
+"z39.50. Для багатьох серверів нічого вводити "
+"не потрібно. Пароль буде збережений у "
+"конфігураційному файлі Tellico."
+
+#: fetch/z3950fetcher.cpp:670
+msgid "Illustrator"
+msgstr "Ілюстратор"
+
+#: fetch/execexternalfetcher.cpp:82
+msgid "External Application"
+msgstr "Зовнішні програми"
+
+#: configdialog.cpp:363 fetch/execexternalfetcher.cpp:346
+#: fetch/gcstarpluginfetcher.cpp:398 translators/csvimporter.cpp:226
+msgid "Collection &type:"
+msgstr "&Тип зібрання:"
+
+#: fetch/execexternalfetcher.cpp:351
+msgid ""
+"Set the collection type of the data returned from the external application."
+msgstr ""
+"Виберіть тип зібрання, який експортуєтся "
+"зі зовнішної програми."
+
+#: fetch/execexternalfetcher.cpp:356
+msgid "&Result type: "
+msgstr "&Тип результату: "
+
+#: fetch/execexternalfetcher.cpp:365
+msgid "Set the result type of the data returned from the external application."
+msgstr ""
+"Виберіть тип даних, що повертається "
+"зовнішньою програмою."
+
+#: fetch/execexternalfetcher.cpp:370
+msgid "Application &path: "
+msgstr "&Шлях до програми"
+
+#: fetch/execexternalfetcher.cpp:375
+msgid ""
+"Set the path of the application to run that should output a valid Tellico "
+"data file."
+msgstr ""
+"Введіть шлях до програми, який виводить "
+"правильний файл Tellico."
+
+#: fetch/execexternalfetcher.cpp:380
+msgid "Select the search keys supported by the data source."
+msgstr ""
+"Виберіть ключі пошуку, підтримувані "
+"джерелом даних."
+
+#: fetch/execexternalfetcher.cpp:381
+msgid ""
+"Add any arguments that may be needed. <b>%1</b> will be replaced by the "
+"search term."
+msgstr ""
+"Додайте аргументи, які можуть "
+"знадобитися. <b>%1</b> будуть замінені "
+"результатом пошуку."
+
+#: fetch/execexternalfetcher.cpp:382
+msgid "Arguments"
+msgstr "&Аргументи"
+
+#: fetch/execexternalfetcher.cpp:415 newstuff/dialog.cpp:152
+msgid "Update"
+msgstr "Оновити"
+
+#. TRANSLATORS: Do not translate %{author}.
+#: fetch/execexternalfetcher.cpp:423
+msgid ""
+"<p>Enter the arguments which should be used to search for available updates "
+"to an entry.</p><p>The format is the same as for <i>Dependent</i> fields, "
+"where field values are contained inside braces, such as <i>%{author}</i>. "
+"See the documentation for details.</p>"
+msgstr ""
+"<p>Введіть аргументи, які слід "
+"використовувати для пошуку можливих "
+"оновлень.</p><p>Формат повинен бути таким "
+"же, як і <i>\"залежні\"</i> поля, такі як "
+"<i>%{author}</i>. Докладніше - у документації.</p>"
+
+#: fetch/configwidget.cpp:29
+msgid "Source Options"
+msgstr "Опції джерела"
+
+#: fetch/configwidget.cpp:40
+msgid "Available Fields"
+msgstr "Доступні поля"
+
+#: fetch/imdbfetcher.cpp:89
+msgid "Internet Movie Database"
+msgstr "База даних фільмів у Інтрнеті (IMDB)"
+
+#: fetch/imdbfetcher.cpp:578
+msgid "Select IMDB Result"
+msgstr "Виберіть результат IMDB"
+
+#: fetch/imdbfetcher.cpp:581
+msgid ""
+"<qt>Your search returned multiple matches. Please select one below.</qt>"
+msgstr ""
+"<qt>Ваш пошук дав декілька результатів. "
+"Будь ласка, виберіть один з них.</qt>"
+
+#: fetch/imdbfetcher.cpp:596
+msgid "<qt>Select a search result.</qt>"
+msgstr "<qt>Виберіть результат пошуку.</qt>"
+
+#: fetch/imdbfetcher.cpp:688 fetch/imdbfetcher.cpp:1185
+msgid "IMDB Link"
+msgstr "Посилання IMDB"
+
+#: fetch/animenfofetcher.cpp:260 fetch/imdbfetcher.cpp:746
+#: fetch/imdbfetcher.cpp:1187
+msgid "Alternative Titles"
+msgstr "Альтернативні назви"
+
+#: fetch/imdbfetcher.cpp:947 fetch/imdbfetcher.cpp:1186
+msgid "IMDB Rating"
+msgstr "Рейтинг IMDB"
+
+#: fetch/imdbfetcher.cpp:1065 fetch/imdbfetcher.cpp:1188
+msgid "Certifications"
+msgstr "Сертифікації"
+
+#: fetch/imdbfetcher.cpp:1126
+msgid ""
+"The Internet Movie Database uses several different servers. Choose the one "
+"you wish to use."
+msgstr ""
+"IMDB використовує різні сервери. Будь "
+"ласка, виберіть той, котрий Ви хочете "
+"використовувати."
+
+#: fetch/imdbfetcher.cpp:1132
+msgid "&Maximum cast: "
+msgstr "&Максимальна к-ть акторів:"
+
+#: fetch/imdbfetcher.cpp:1137
+msgid ""
+"The list of cast members may include many people. Set the maximum number "
+"returned from the search."
+msgstr ""
+"Список акторів може містити багато людей. "
+"Введіть максимальне число акторів, що "
+"повертатиметься пошуком."
+
+#: fetch/discogsfetcher.cpp:679 fetch/imdbfetcher.cpp:1142
+msgid "Download cover &image"
+msgstr "Звантажити зображення обкладинки"
+
+#: fetch/ibsfetcher.cpp:47
+msgid "Internet Bookshop (ibs.it)"
+msgstr "Інтернет-магазин книг (ibs.it)"
+
+#: fetch/fetchmanager.cpp:69
+msgid "Person"
+msgstr "Людина"
+
+#: fetch/fetchmanager.cpp:70
+msgid "ISBN"
+msgstr "ISBN"
+
+#: fetch/fetchmanager.cpp:71
+#, fuzzy
+msgid "UPC/EAN"
+msgstr "UPC"
+
+#: fetch/fetchmanager.cpp:72
+msgid "Keyword"
+msgstr "Ключові слова"
+
+#: fetch/fetchmanager.cpp:74 translators/pdfimporter.cpp:173
+msgid "arXiv ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:75
+msgid "Pubmed ID"
+msgstr ""
+
+#: fetch/fetchmanager.cpp:76
+msgid "Raw Query"
+msgstr "Сирий запит"
+
+#: fetch/animenfofetcher.cpp:257
+msgid "Original Title"
+msgstr "Оригінальний заголовок"
+
+#: fetch/animenfofetcher.cpp:264
+msgid "Distributor"
+msgstr "Розповсюджувач"
+
+#: fetch/animenfofetcher.cpp:270
+msgid "Episodes"
+msgstr "Епізоди"
+
+#: fetch/arxivfetcher.cpp:53
+msgid "arXiv.org"
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:83
+msgid "%1 requires a username and password."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:332
+msgid ""
+"CrossRef requires an account for access. Please read the terms and "
+"conditions and <a href='http://www.crossref.org/requestaccount/'>request an "
+"account</a>. Enter your OpenURL account information below."
+msgstr ""
+
+#: fetch/crossreffetcher.cpp:343
+#, fuzzy
+msgid "&Username: "
+msgstr "&Користувач:"
+
+#: fetch/crossreffetcher.cpp:348
+#, fuzzy
+msgid ""
+"A username and password is required to access the CrossRef service. The "
+"password is stored as plain text in the Tellico configuration file."
+msgstr ""
+"Введіть пароль для доступу до бази даних "
+"z39.50. Для багатьох серверів нічого вводити "
+"не потрібно. Пароль буде збережений у "
+"конфігураційному файлі Tellico."
+
+#: fetch/crossreffetcher.cpp:354
+#, fuzzy
+msgid "&Password: "
+msgstr "Па&роль"
+
+#: fetch/gcstarpluginfetcher.cpp:190
+#, fuzzy
+msgid "GCstar Plugin"
+msgstr "GCstar"
+
+#: fetch/gcstarpluginfetcher.cpp:404
+#, fuzzy
+msgid "Set the collection type of the data returned from the plugin."
+msgstr ""
+"Виберіть тип зібрання, який експортуєтся "
+"зі зовнішної програми."
+
+#: fetch/gcstarpluginfetcher.cpp:409
+msgid "&Plugin: "
+msgstr ""
+
+#: fetch/gcstarpluginfetcher.cpp:415
+#, fuzzy
+msgid "Select the GCstar plugin used for the data source."
+msgstr ""
+"Виберіть ключі пошуку, підтримувані "
+"джерелом даних."
+
+#: fetch/gcstarpluginfetcher.cpp:420
+#, fuzzy
+msgid "Author: "
+msgstr "Автор"
+
+#: fetch/discogsfetcher.cpp:58
+#, fuzzy
+msgid "Discogs Audio Search"
+msgstr "Аудіо-пошук Yahoo!"
+
+#: fetch/discogsfetcher.cpp:668
+msgid "API &key: "
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:674
+msgid ""
+"With your discogs.com account you receive an API key for the usage of their "
+"XML-based interface (See http://www.discogs.com/help/api)."
+msgstr ""
+
+#: fetch/discogsfetcher.cpp:718
+msgid "Discogs Link"
+msgstr ""
+
+#: newstuff/dialog.cpp:94
+msgid "Get Hot New Stuff"
+msgstr "Отримайте свіженькі нові матеріали"
+
+#: newstuff/dialog.cpp:114
+msgid "Version"
+msgstr "Версія"
+
+#: newstuff/dialog.cpp:116
+msgid "Downloads"
+msgstr "Звантаження"
+
+#: newstuff/dialog.cpp:117
+msgid "Release Date"
+msgstr "Дата випуску"
+
+#: newstuff/dialog.cpp:121
+msgid ""
+"This is a list of all the items available for download. Previously installed "
+"items have a checkmark icon, while items with new version available have an "
+"update icon"
+msgstr ""
+"Це список усіх елементів, доступних для "
+"звантаження. Заздалегідь встановлені "
+"елементи мають іконку контрольної мітки, "
+"при елементах з новою доступною версією "
+"мають іконку модифікації."
+
+#: newstuff/dialog.cpp:137
+msgid "The name and license of the selected item"
+msgstr "Ім'я та ліцензія вибраного елементу"
+
+#: newstuff/dialog.cpp:140
+msgid "The author of the selected item"
+msgstr "Автор відібраного запису"
+
+#: newstuff/dialog.cpp:142 newstuff/dialog.cpp:396
+msgid "Install"
+msgstr "Встановлення"
+
+#: newstuff/dialog.cpp:161
+msgid "Download and install the selected template."
+msgstr ""
+"Звантажте та встановіть відібраний "
+"шаблон."
+
+#: newstuff/dialog.cpp:164
+msgid ""
+"Download and install the selected script. Some scripts may need to be "
+"configured after being installed."
+msgstr ""
+"Звантажте та встановіть відібраний "
+"сценарій. Деякі сценарії, можливо, "
+"потрібно сконфіґурувати після "
+"встановлення."
+
+#: newstuff/dialog.cpp:194
+msgid "A description of the selected item is shown here."
+msgstr ""
+"Опис відібраного елементу показується "
+"тут."
+
+#: newstuff/dialog.cpp:224
+msgid "Downloading information..."
+msgstr "Звантаження інформації..."
+
+#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
+#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
+#: newstuff/dialog.cpp:324 newstuff/dialog.cpp:434 statusbar.cpp:83
+msgid "Ready."
+msgstr "Готово."
+
+#: newstuff/dialog.cpp:396
+msgid ""
+"_: Update Stuff\n"
+"Update"
+msgstr "Оновити"
+
+#: newstuff/dialog.cpp:413
+msgid "Installing item..."
+msgstr "Встановлення елементу..."
+
+#: translators/bibteximporter.cpp:79
+#, fuzzy
+msgid "No valid bibtex entries were found"
+msgstr ""
+"Не знайдено записів bibtex у цьому файлі - %1"
+
+#: translators/bibteximporter.cpp:96
+#, c-format
+msgid "No valid bibtex entries were found in file - %1"
+msgstr ""
+"Не знайдено записів bibtex у цьому файлі - %1"
+
+#: translators/bibtexexporter.cpp:200 translators/bibteximporter.cpp:286
+msgid "Bibtex Options"
+msgstr "Опції Bibtex"
+
+#: translators/bibteximporter.cpp:287
+#, fuzzy
+msgid "Use Unicode (UTF-8) encoding"
+msgstr "Юнікод (UTF-8)"
+
+#: translators/bibteximporter.cpp:288
+#, fuzzy
+msgid "Read the imported file in Unicode (UTF-8)."
+msgstr "Експорт в юнікоді (UTF-8)"
+
+#: translators/bibteximporter.cpp:289
+#, fuzzy
+msgid "Use user locale (%1) encoding"
+msgstr "Системне кодування (%1)"
+
+#: translators/bibteximporter.cpp:293
+#, fuzzy
+msgid "Read the imported file in the local encoding."
+msgstr "Експорт у системному кодуванні."
+
+#: translators/tellicozipexporter.cpp:35
+msgid "Tellico Zip File"
+msgstr "ZIP-файл Tellico"
+
+#: importdialog.cpp:245 mainwindow.cpp:1101 mainwindow.cpp:1267
+#: translators/tellicozipexporter.cpp:39
+msgid "*.tc *.bc|Tellico Files (*.tc)"
+msgstr "*.tc *.bc|Файли Tellico (*.tc, *bc)"
+
+#: configdialog.cpp:1017 importdialog.cpp:297 mainwindow.cpp:1105
+#: mainwindow.cpp:1269 reportdialog.cpp:195 translators/bibtexexporter.cpp:52
+#: translators/bibtexmlexporter.cpp:40 translators/csvexporter.cpp:44
+#: translators/gcfilmsexporter.cpp:41 translators/htmlexporter.cpp:89
+#: translators/onixexporter.cpp:67 translators/pilotdbexporter.cpp:47
+#: translators/tellicoxmlexporter.cpp:60 translators/tellicozipexporter.cpp:39
+#: translators/xsltexporter.cpp:41 translators/xsltimporter.cpp:105
+msgid "*|All Files"
+msgstr "*|Усі файли"
+
+#: translators/alexandriaexporter.cpp:43
+msgid "Alexandria"
+msgstr "Alexandria"
+
+#: translators/alexandriaexporter.cpp:67
+msgid ""
+"<qt>An Alexandria library called <i>%1</i> already exists. Any existing "
+"books in that library could be overwritten.</qt>"
+msgstr ""
+"<qt>Бібліотека Alexandria <i>%1</i> вже існує. "
+"Будь-яка існуюча книга у цій бібліотеці "
+"буде переписана.</qt>"
+
+#: filehandler.cpp:141 translators/tellicoimporter.cpp:113
+#: translators/xmlimporter.cpp:43 translators/xmlimporter.cpp:60
+msgid "There is an XML parsing error in line %1, column %2."
+msgstr ""
+"Відбулася помилка XML у рядку %1 та стовпці "
+"%2."
+
+#: filehandler.cpp:143 translators/tellicoimporter.cpp:115
+#: translators/xmlimporter.cpp:45 translators/xmlimporter.cpp:62
+msgid "The error message from Qt is:"
+msgstr "Помилка від QT:"
+
+#: translators/tellicoimporter.cpp:152
+msgid "It is from a future version of Tellico."
+msgstr "Це з майбутньої версії Tellico."
+
+#: translators/tellicoimporter.cpp:162
+msgid ""
+"Tellico is converting the file to a more recent document format. Information "
+"loss may occur if an older version of Tellico is used to read this file in "
+"the future."
+msgstr ""
+"Ви намагаєтеся імпортувати інформацію з "
+"файлів, створених ранішими версіями Tellico. "
+"Це може привести до втрати інформації."
+
+#: translators/bibtexhandler.cpp:245 translators/risimporter.cpp:286
+#: translators/risimporter.cpp:290 translators/tellicoimporter.cpp:367
+msgid "Unknown"
+msgstr "Невідомий"
+
+#: translators/tellicoimporter.cpp:777
+msgid "The file is empty."
+msgstr "Файл порожій"
+
+#: translators/tellicoimporter.cpp:795
+msgid "The file contains no collection data."
+msgstr "Файл не містить даних зібрань."
+
+#: translators/tellicoimporter.cpp:940
+msgid "Unread Books"
+msgstr "Непрочитані книги"
+
+#: translators/tellicoimporter.cpp:950
+msgid "Old Movies"
+msgstr "Старі фільми"
+
+#: translators/tellicoimporter.cpp:968
+msgid "80's Music"
+msgstr "Музика 80-х"
+
+#: translators/tellicoimporter.cpp:980
+msgid "Favorites"
+msgstr "Вибране"
+
+#: translators/audiofileimporter.cpp:69
+msgid "Scanning audio files..."
+msgstr "Читаються аудіо-файли..."
+
+#: translators/audiofileimporter.cpp:129
+#, fuzzy
+msgid "Bitrate"
+msgstr "Bibtex"
+
+#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
+msgid "Tracks (Disc %1)"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:189 xslt.cpp:4
+msgid "(Various)"
+msgstr "(змінний)"
+
+#: translators/audiofileimporter.cpp:340
+msgid "Audio File Options"
+msgstr "Опції аудіо-файлів"
+
+#: translators/audiofileimporter.cpp:342
+msgid "Recursive &folder search"
+msgstr "Рекурсивний пошук по теках"
+
+#: translators/audiofileimporter.cpp:343
+msgid "If checked, folders are recursively searched for audio files."
+msgstr ""
+"Якщо відмічено, то пошук аудіо-файлів "
+"проводитиметься по усіх теках."
+
+#: translators/audiofileimporter.cpp:347
+msgid "Include file &location"
+msgstr "&Включати місцеположення файлу"
+
+#: translators/audiofileimporter.cpp:348
+msgid "If checked, the file names for each track are added to the entries."
+msgstr ""
+"Якщо відмічено, то в записі буде додані "
+"назви файлів."
+
+#: translators/audiofileimporter.cpp:352
+msgid "Include &bitrate"
+msgstr ""
+
+#: translators/audiofileimporter.cpp:353
+#, fuzzy
+msgid "If checked, the bitrate for each track is added to the entries."
+msgstr ""
+"Якщо відмічено, то в записі буде додані "
+"назви файлів."
+
+#: translators/csvexporter.cpp:40
+msgid "CSV"
+msgstr "CSV"
+
+#: importdialog.cpp:254 translators/csvexporter.cpp:44
+msgid "*.csv|CSV Files (*.csv)"
+msgstr "*.csv|Файли CSV (*.csv)"
+
+#: translators/csvexporter.cpp:109 translators/csvimporter.cpp:221
+msgid "CSV Options"
+msgstr "Опції CSV"
+
+#: translators/csvexporter.cpp:112
+msgid "Include field titles as column headers"
+msgstr "Разом зі заголовками стовпців"
+
+#: translators/csvexporter.cpp:114
+msgid "If checked, a header row will be added with the field titles."
+msgstr ""
+"Якщо відмічено, то буде доданий перший "
+"рядок як заголовок."
+
+#: translators/csvexporter.cpp:117 translators/csvimporter.cpp:240
+msgid "Delimiter"
+msgstr "Роздільник"
+
+#: translators/csvexporter.cpp:120 translators/csvimporter.cpp:243
+msgid ""
+"In addition to a comma, other characters may be used as a delimiter, "
+"separating each value in the file."
+msgstr ""
+"Виберіть роздільник у файлі CSV, який "
+"визначає границі кожного поля (у "
+"більшості випадків кома)."
+
+#: translators/csvexporter.cpp:124
+msgid "Comma"
+msgstr "Кома"
+
+#: translators/csvexporter.cpp:126 translators/csvimporter.cpp:250
+msgid "Use a comma as the delimiter."
+msgstr "Використовувати кому як роздільник."
+
+#: translators/csvexporter.cpp:130
+msgid "Semicolon"
+msgstr "Крапка з комою"
+
+#: translators/csvexporter.cpp:131 translators/csvimporter.cpp:255
+msgid "Use a semi-colon as the delimiter."
+msgstr ""
+"Використовувати крапку з комою як "
+"роздільник."
+
+#: translators/csvexporter.cpp:135
+msgid "Tab"
+msgstr "Табуляція"
+
+#: translators/csvexporter.cpp:136 translators/csvimporter.cpp:260
+msgid "Use a tab as the delimiter."
+msgstr ""
+"Використовувати \"табуляцію\" як "
+"роздільник"
+
+#: translators/csvexporter.cpp:140
+msgid "Other"
+msgstr "Інший"
+
+#: translators/csvexporter.cpp:141 translators/csvimporter.cpp:265
+msgid "Use a custom string as the delimiter."
+msgstr "Використовувати інший роздільник."
+
+#: translators/csvexporter.cpp:146 translators/csvimporter.cpp:272
+msgid "A custom string, such as a colon, may be used as a delimiter."
+msgstr "Свій роздільник (напр, двокрапка)."
+
+#: translators/filelistingimporter.cpp:63
+msgid "Scanning files..."
+msgstr "Скануються файли..."
+
+#: translators/filelistingimporter.cpp:191
+msgid "File Listing Options"
+msgstr "Опції імпортування файлів"
+
+#: translators/filelistingimporter.cpp:193
+msgid "Recursive folder search"
+msgstr "Рекурсивний пошук по теках"
+
+#: translators/filelistingimporter.cpp:194
+msgid "If checked, folders are recursively searched for all files."
+msgstr ""
+"Якщо відмічено, буде проведений "
+"рекурсивний пошук по теках."
+
+#: translators/filelistingimporter.cpp:198
+msgid "Generate file previews"
+msgstr "Створювати значки файлів"
+
+#: translators/filelistingimporter.cpp:199
+msgid ""
+"If checked, previews of the file contents are generated, which can slow down "
+"the folder listing."
+msgstr ""
+"Якщо відмічено, то створюватимуться "
+"значки файлів (наприклад, зменшена копія "
+"фотографії)."
+
+#: translators/onixexporter.cpp:63
+msgid "ONIX Archive"
+msgstr "Архів ONIX"
+
+#: translators/onixexporter.cpp:67
+msgid "*.zip|Zip Files (*.zip)"
+msgstr "*.zip|Файли ZIP (*.zip)"
+
+#: translators/onixexporter.cpp:176
+msgid "ONIX Archive Options"
+msgstr "Опції архіву ONIX"
+
+#: translators/onixexporter.cpp:179
+msgid "Include images in archive"
+msgstr "Включати зображення в архів"
+
+#: translators/onixexporter.cpp:181
+msgid ""
+"If checked, the images in the document will be included in the zipped ONIX "
+"archive."
+msgstr ""
+"Якщо відмічено, то зображення "
+"стискатимуться у ZIP-архів ONIX"
+
+#: translators/freedbimporter.cpp:84 translators/freedbimporter.cpp:170
+msgid "<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>"
+msgstr ""
+"<qt>Tellico не вдається дістати доступ до "
+"пристрою CD-ROM - <i>%1</i>.</qt>"
+
+#: translators/freedbimporter.cpp:196
+msgid "Select CDDB Entry"
+msgstr "Виберіть результат IMDB"
+
+#: translators/freedbimporter.cpp:197
+msgid "Select a CDDB entry:"
+msgstr "Виберіть результат IMDB:"
+
+#: translators/freedbimporter.cpp:220
+msgid "<qt>No records were found to match the CD.</qt>"
+msgstr ""
+"<qt>По Вашому запиту нічого не знайдено</qt>"
+
+#: translators/freedbimporter.cpp:238
+msgid "<qt>Tellico was unable to complete the CD lookup.</qt>"
+msgstr ""
+"<qt>Tellico не вдалося отримати дані по всьому "
+"диску.</qt>"
+
+#: translators/freedbimporter.cpp:470
+msgid "Various"
+msgstr "Змінний"
+
+#: translators/freedbimporter.cpp:489
+msgid "Audio CD Options"
+msgstr "Опції Audio CD"
+
+#: translators/freedbimporter.cpp:493
+msgid "Read data from CD-ROM device"
+msgstr "Прочитати дані з пристрою CD-ROM"
+
+#: translators/freedbimporter.cpp:496
+msgid "Select or input the CD-ROM device location."
+msgstr ""
+"Виберіть або введіть адресу Вашого "
+"пристрою CD-ROM"
+
+#: translators/freedbimporter.cpp:502
+msgid "Read all CDDB cache files only"
+msgstr "Прочитати тільки файли CDDB"
+
+#: translators/freedbimporter.cpp:503
+msgid ""
+"Read data recursively from all the CDDB cache files contained in the default "
+"cache folders."
+msgstr "Прочитати рекурсивно дані з файлів CDDB"
+
+#: translators/gcfilmsexporter.cpp:37
+msgid "GCfilms"
+msgstr "GCfilms"
+
+#: importdialog.cpp:273 translators/gcfilmsexporter.cpp:41
+msgid "*.gcf|GCfilms Data Files (*.gcf)"
+msgstr "*.gcf|Файли GCfilms(*.gcf)"
+
+#: importdialog.cpp:272 translators/gcfilmsexporter.cpp:43
+msgid "*.gcs|GCstar Data Files (*.gcs)"
+msgstr "*.gcs|Файли GCstar (*.gcs)"
+
+#: translators/xsltexporter.cpp:37
+msgid "XSLT"
+msgstr "XSLT"
+
+#: translators/xsltexporter.cpp:69 translators/xsltimporter.cpp:98
+msgid "XSLT Options"
+msgstr "Опції XSLT"
+
+#: translators/xsltexporter.cpp:74 translators/xsltimporter.cpp:101
+msgid "XSLT file:"
+msgstr "Файл XSLT"
+
+#: translators/xsltexporter.cpp:76
+msgid "Choose the XSLT file used to transform the Tellico XML data."
+msgstr ""
+"Виберіть файл XSLT, який "
+"використовуватиметься для конвертування "
+"у формат Tellico XML"
+
+#: translators/alexandriaimporter.cpp:194
+msgid "Alexandria Options"
+msgstr "Опції Alexandria"
+
+#: translators/alexandriaimporter.cpp:195
+msgid "&Library:"
+msgstr "&Бібліотека:"
+
+#: translators/bibtexmlexporter.cpp:36
+msgid "Bibtexml"
+msgstr "Bibtexml"
+
+#: translators/bibtexmlexporter.cpp:40
+msgid "*.xml|Bibtexml Files (*.xml)"
+msgstr "*.xml|Файли Bibtexml (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:56
+msgid "XML"
+msgstr "XML"
+
+#: importdialog.cpp:246 importdialog.cpp:259 importdialog.cpp:264
+#: mainwindow.cpp:1103 translators/tellicoxmlexporter.cpp:60
+msgid "*.xml|XML Files (*.xml)"
+msgstr "*.xml|Файли XML (*.xml)"
+
+#: translators/tellicoxmlexporter.cpp:480
+msgid "Tellico XML Options"
+msgstr "Опції XML (Tellico)"
+
+#: translators/tellicoxmlexporter.cpp:483
+msgid "Include images in XML document"
+msgstr "Включати зображення у файл XML"
+
+#: translators/tellicoxmlexporter.cpp:485
+msgid ""
+"If checked, the images in the document will be included in the XML stream as "
+"base64 encoded elements."
+msgstr ""
+"Якщо відмічено, то зображення будуть "
+"включені у файл XML"
+
+#: translators/importer.h:100
+msgid "Loading data..."
+msgstr "Завантажуються дані..."
+
+#: translators/importer.h:100
+msgid "Loading %1..."
+msgstr "Завантажується %1..."
+
+#: translators/bibtexexporter.cpp:48
+msgid "Bibtex"
+msgstr "Bibtex"
+
+#: importdialog.cpp:250 translators/bibtexexporter.cpp:52
+msgid "*.bib|Bibtex Files (*.bib)"
+msgstr "*.bib|Файли Bibtex (*.bib)"
+
+#: translators/bibtexexporter.cpp:203
+msgid "Expand string macros"
+msgstr "Збільшити стрічку для макросів"
+
+#: translators/bibtexexporter.cpp:205
+msgid ""
+"If checked, the string macros will be expanded and no @string{} entries will "
+"be written."
+msgstr ""
+"Якщо відмічено, то стрічка для макросів "
+"буде збільшена та записи @string{} будуть "
+"записані"
+
+#: translators/bibtexexporter.cpp:208
+msgid "Use URL package"
+msgstr "Використовувати пакети URL"
+
+#: translators/bibtexexporter.cpp:210
+msgid "If checked, any URL fields will be wrapped in a \\url declaration."
+msgstr ""
+"Якщо відмічено, то будь-які поля URL будуть "
+"записані як //url"
+
+#: translators/bibtexexporter.cpp:213
+msgid "Skip entries with empty citation keys"
+msgstr "Пропустити порожні поля"
+
+#: translators/bibtexexporter.cpp:215
+msgid "If checked, any entries without a bibtex citation key will be skipped."
+msgstr ""
+"Якщо відмічено, то порожні поля будуть "
+"пропущені"
+
+#: translators/bibtexexporter.cpp:219
+msgid "Bibtex quotation style:"
+msgstr "Стиль цитування bibtex:"
+
+#: translators/bibtexexporter.cpp:221 translators/bibtexexporter.cpp:228
+#: translators/bibtexexporter.cpp:259
+msgid "Braces"
+msgstr "Зв'язки"
+
+#: translators/bibtexexporter.cpp:222 translators/bibtexexporter.cpp:230
+msgid "Quotes"
+msgstr "Цитати"
+
+#: translators/bibtexexporter.cpp:223
+msgid ""
+"<qt>The quotation style used when exporting bibtex. All field values will "
+"be escaped with either braces or quotation marks.</qt>"
+msgstr ""
+"<qt>При експорті використовуватиметься "
+"стиль цитування bibtex.</qt>"
+
+#: translators/csvimporter.cpp:229
+msgid "Select the type of collection being imported."
+msgstr ""
+"Виберіть тип зібрання, який буде "
+"імпортований."
+
+#: translators/csvimporter.cpp:235
+msgid "&First row contains field titles"
+msgstr "&Перший рядок містить заголовки полів"
+
+#: translators/csvimporter.cpp:236
+msgid "If checked, the first row is used as field titles."
+msgstr "Перший рядок містить заголовки полів"
+
+#: translators/csvimporter.cpp:248
+msgid "&Comma"
+msgstr "Кома"
+
+#: translators/csvimporter.cpp:254
+msgid "&Semicolon"
+msgstr "Крапка з комою"
+
+#: translators/csvimporter.cpp:259
+msgid "Ta&b"
+msgstr "Табуляція"
+
+#: translators/csvimporter.cpp:264
+msgid "Ot&her:"
+msgstr "Інший:"
+
+#: translators/csvimporter.cpp:289
+msgid "The table shows up to the first five lines of the CSV file."
+msgstr "Таблиця показує перші 5 рядків файлу CSV"
+
+#: translators/csvimporter.cpp:296
+msgid ""
+"<qt>Set each column to correspond to a field in the collection by choosing a "
+"column, selecting the field, then clicking the <i>Assign Field</i> "
+"button.</qt>"
+msgstr ""
+"<qt>Встановіть кожен стовпець у "
+"відповідність полю у зібранні з "
+"допомогою вибору стовпця, вибору поля та "
+"клацанні на кнопці <i>Призначите поле</i></qt>"
+
+#: translators/csvimporter.cpp:298
+msgid "Co&lumn:"
+msgstr "Стовпець"
+
+#: translators/csvimporter.cpp:307
+msgid "&Data field in this column:"
+msgstr "Назва поля в цьому стовпці:"
+
+#: translators/csvimporter.cpp:315
+msgid "&Assign Field"
+msgstr "&Призначити поле"
+
+#: translators/csvimporter.cpp:347
+msgid ""
+"At least one column must be assigned to a field. Only assigned columns will "
+"be imported."
+msgstr ""
+
+#: collectionfieldsdialog.cpp:409 collectionfieldsdialog.cpp:412
+#: translators/csvimporter.cpp:396 translators/csvimporter.cpp:510
+msgid "New Field"
+msgstr "Нове поле"
+
+#: translators/risimporter.cpp:288
+msgid "PDF"
+msgstr "PDF"
+
+#: translators/pilotdbexporter.cpp:43
+msgid "PilotDB"
+msgstr "PilotDB"
+
+#: translators/pilotdbexporter.cpp:47
+msgid "*.pdb|Pilot Database Files (*.pdb)"
+msgstr "*.pdb|Файли бази даних Pilot (*.pdb)"
+
+#: detailedlistview.cpp:67 detailedlistview.cpp:297
+#: translators/pilotdbexporter.cpp:143
+msgid "View Columns"
+msgstr "Показувати стовпці"
+
+#: translators/pilotdbexporter.cpp:210
+msgid "PilotDB Options"
+msgstr "Опції PilotDB"
+
+#: translators/pilotdbexporter.cpp:213 translators/pilotdbexporter.cpp:215
+msgid "Set PDA backup flag for database"
+msgstr "Встановити бекап PDA для бази даних"
+
+#: translators/gcfilmsimporter.cpp:110 translators/gcfilmsimporter.cpp:255
+msgid "<qt>The file is not a valid GCstar data file.</qt>"
+msgstr "<qt>Цей файл не містить даних GCstar.</qt>"
+
+#: mainwindow.cpp:1738 translators/gcfilmsimporter.cpp:248
+#: translators/xsltimporter.cpp:76
+msgid "Tellico encountered an error in XSLT processing."
+msgstr "Відбулася помилка в XSLT"
+
+#: translators/xsltimporter.cpp:64 translators/xsltimporter.cpp:70
+msgid "A valid XSLT file is needed to import the file."
+msgstr ""
+"Для імпорту потрібний правильний файл XSLT"
+
+#: configdialog.cpp:1015 translators/xsltimporter.cpp:104
+msgid "*.xsl|XSL Files (*.xsl)"
+msgstr "*.xsl|Файли XSL (*.xsl)"
+
+#: translators/htmlexporter.cpp:85
+msgid "HTML"
+msgstr "HTML"
+
+#: reportdialog.cpp:195 translators/htmlexporter.cpp:89
+msgid "*.html|HTML Files (*.html)"
+msgstr "*.html|Файли HTML (*.html)"
+
+#: groupview.cpp:479 mainwindow.cpp:1591 mainwindow.cpp:1631
+#: translators/htmlexporter.cpp:316
+msgid "People"
+msgstr "Люди"
+
+#: translators/htmlexporter.cpp:320
+msgid "(grouped by %1)"
+msgstr "(згруповано за %1)"
+
+#: translators/htmlexporter.cpp:465
+msgid "HTML Options"
+msgstr "Опції HTML"
+
+#: translators/htmlexporter.cpp:468
+msgid "Print field headers"
+msgstr "Включити заголовки полів"
+
+#: configdialog.cpp:307 translators/htmlexporter.cpp:469
+msgid "If checked, the field names will be printed as table headers."
+msgstr ""
+"Якщо відмічено, то при експорті в HTML "
+"будуть надруковані заголовки."
+
+#: translators/htmlexporter.cpp:473
+msgid "Group the entries"
+msgstr "Групувати записи"
+
+#: configdialog.cpp:314 translators/htmlexporter.cpp:474
+msgid "If checked, the entries will be grouped by the selected field."
+msgstr ""
+"Якщо відмічено, то записи будуть "
+"згруповані по виділеному полю"
+
+#: translators/htmlexporter.cpp:478
+msgid "Export individual entry files"
+msgstr "Експорт кожного запису в окремий файл"
+
+#: translators/htmlexporter.cpp:479
+msgid "If checked, individual files will be created for each entry."
+msgstr ""
+"Якщо відмічено, то кожен запис "
+"виводитиметься в окремий файл."
+
+#: translators/pdfimporter.cpp:92 translators/pdfimporter.cpp:100
+#, fuzzy
+msgid "Tellico was unable to read any metadata from the PDF file."
+msgstr ""
+"Tellico не вдається завантажити зображення з "
+"файлу - %1"
+
+#: translators/pdfimporter.cpp:231
+msgid ""
+"Tellico is able to download information about entries with a DOI from "
+"CrossRef.org. However, you must create an CrossRef account and add a new "
+"data source with your account information."
+msgstr ""
+
+#: fetcherconfigdialog.cpp:39 fetcherconfigdialog.cpp:49
+msgid "Data Source Properties"
+msgstr "Властивості джерела даних"
+
+#: fetcherconfigdialog.cpp:77
+msgid "&Source name: "
+msgstr "Н&азва джерела"
+
+#: fetcherconfigdialog.cpp:79
+msgid ""
+"The name identifies the data source and should be unique and informative."
+msgstr "Назва джерела"
+
+#: fetcherconfigdialog.cpp:90 fetcherconfigdialog.cpp:94
+msgid "Source &type: "
+msgstr "&Тип джерела"
+
+#: fetcherconfigdialog.cpp:97
+msgid "Tellico supports several different data sources."
+msgstr ""
+"Tellico також підтримує інші джерела даних"
+
+#: fetcherconfigdialog.cpp:111
+msgid "Updating from source should overwrite user data"
+msgstr ""
+"Оновлення від джерела повинне переписати "
+"користувацькі дані"
+
+#: fetcherconfigdialog.cpp:114
+msgid "If checked, updating entries will overwrite any existing information."
+msgstr ""
+"Якщо відмічено, оновлення записів "
+"переписуватиме будь-яку існуючу "
+"інформацію."
+
+#: filterdialog.cpp:60
+msgid "Any Field"
+msgstr "Будь-яке поле"
+
+#: filterdialog.cpp:68
+msgid "contains"
+msgstr "містить"
+
+#: filterdialog.cpp:69
+msgid "does not contain"
+msgstr "не містить"
+
+#: filterdialog.cpp:70
+msgid "equals"
+msgstr "рівно"
+
+#: filterdialog.cpp:71
+msgid "does not equal"
+msgstr "не рівно"
+
+#: filterdialog.cpp:72
+msgid "matches regexp"
+msgstr "відповідає виразу"
+
+#: filterdialog.cpp:73
+msgid "does not match regexp"
+msgstr "не відповідає виразу"
+
+#: filterdialog.cpp:90
+msgid "Edit..."
+msgstr "Редагувати..."
+
+#: filterdialog.cpp:282
+msgid "Advanced Filter"
+msgstr "Просунутий фільтр"
+
+#: filterdialog.cpp:294
+msgid "Filter Criteria"
+msgstr "Критерії фільтру"
+
+#: filterdialog.cpp:300
+msgid "Match a&ll of the following"
+msgstr "Відповідає всьому наступному"
+
+#: filterdialog.cpp:301
+msgid "Match an&y of the following"
+msgstr "Відповідає будь-якому з наступного"
+
+#: filterdialog.cpp:311
+msgid "Filter name:"
+msgstr "Назва фільтру"
+
+#: filterdialog.cpp:319
+msgid "&Save Filter"
+msgstr "&Зберегти фільтр"
+
+#: field.cpp:490
+msgid "Simple Text"
+msgstr "Простий текст"
+
+#: field.cpp:491
+msgid "Paragraph"
+msgstr "Великий текст"
+
+#: field.cpp:492
+msgid "Choice"
+msgstr "Вибір"
+
+#: field.cpp:493
+msgid "Checkbox"
+msgstr "Вибір так/ні"
+
+#: field.cpp:496
+msgid "Table"
+msgstr "Таблиця"
+
+#: field.cpp:498
+msgid "Dependent"
+msgstr "Залежність"
+
+#: field.cpp:500
+msgid "Date"
+msgstr "Дата"
+
+#: entryupdater.cpp:81
+msgid "Updating %1..."
+msgstr "Оновлення %1..."
+
+#: entryupdater.cpp:83
+msgid "Updating entries..."
+msgstr "&Оновлення записів..."
+
+#: entryupdater.cpp:85
+msgid "Update Entries"
+msgstr "Оновити записи"
+
+#: entryupdater.cpp:99
+msgid "Updating <b>%1</b>..."
+msgstr "Оновлення <b>%1</b>..."
+
+#: entryupdater.cpp:209
+msgid "Select Match"
+msgstr "Виберіть результат"
+
+#: entryupdater.cpp:217
+msgid ""
+"<qt><b>%1</b> returned multiple results which could match <b>%2</b>, the "
+"entry currently in the collection. Please select the correct match.</qt>"
+msgstr ""
+"<qt> Пошук дав декілька результатів. "
+"Виберіть той, який необхідний Вам.</qt>"
+
+#: groupview.cpp:252
+msgid "Expand All Groups"
+msgstr "Показувати всі групи"
+
+#: groupview.cpp:254
+msgid "Collapse All Groups"
+msgstr "Прибрати всі групи"
+
+#: groupview.cpp:256
+msgid "Filter by Group"
+msgstr "Фільтр по групі"
+
+#: groupview.cpp:466
+msgid "%1 (Sort by Count)"
+msgstr "%1"
+
+#: groupview.cpp:473
+msgid ""
+"_: Group Name Header\n"
+"Group"
+msgstr "Група"
+
+#: importdialog.cpp:54 importdialog.cpp:60
+msgid "Import Options"
+msgstr "Опції імпорту"
+
+#: importdialog.cpp:62
+msgid "&Replace current collection"
+msgstr "&Замінити поточне зібрання"
+
+#: importdialog.cpp:63
+msgid "Replace the current collection with the contents of the imported file."
+msgstr ""
+"Замінити поточне зібрання вмістом файлу, "
+"що імпортується"
+
+#: importdialog.cpp:65
+msgid "A&ppend to current collection"
+msgstr "&Додати все до поточного зібрання"
+
+#: importdialog.cpp:66
+msgid ""
+"Append the contents of the imported file to the current collection. This is "
+"only possible when the collection types match."
+msgstr ""
+"Додати весь вміст файлу, що імпортується, "
+"до поточного зібрання. Це можливо тільки "
+"у тому випадку, якщо типи зібрань "
+"співпадають."
+
+#: importdialog.cpp:69
+msgid "&Merge with current collection"
+msgstr ""
+"&Додати бракуючі записи до поточного "
+"зібрання"
+
+#: importdialog.cpp:70
+msgid ""
+"Merge the contents of the imported file to the current collection. This is "
+"only possible when the collection types match. Entries must match exactly in "
+"order to be merged."
+msgstr ""
+"Додати лише ті записи, яких немає в "
+"поточному зібранні. Можливо тільки, якщо "
+"типи зібрань співпадають."
+
+#: importdialog.cpp:95 mainwindow.cpp:318 rc.cpp:9
+#, no-c-format
+msgid "&Import"
+msgstr "&Імпорт"
+
+#: importdialog.cpp:268
+msgid "*.ris|RIS Files (*.ris)"
+msgstr "*.ris|Файли RIS (*.ris)"
+
+#: importdialog.cpp:277
+msgid "*.amc|AMC Data Files (*.amc)"
+msgstr "*.amc|Файли даних AMC (*.amc)"
+
+#: importdialog.cpp:281
+#, fuzzy
+msgid "*.pdf|PDF Files (*.pdf)"
+msgstr "*.pdb|Файли бази даних Pilot (*.pdb)"
+
+#: importdialog.cpp:285
+#, fuzzy
+msgid "*.reflib|Referencer Files (*.reflib)"
+msgstr "*.ris|Файли RIS (*.ris)"
+
+#: tellico_strings.cpp:18
+#, c-format
+msgid "Tellico is unable to load the file - %1."
+msgstr "Tellico не вдається відкрити файл - %1"
+
+#: tellico_strings.cpp:19
+#, c-format
+msgid "Tellico is unable to write the file - %1."
+msgstr "Tellico не вдається записати файл - %1"
+
+#: tellico_strings.cpp:20
+#, c-format
+msgid "Tellico is unable to upload the file - %1."
+msgstr "Tellico не вдається завантажити файл - %1"
+
+#: tellico_strings.cpp:21
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"appended. No changes are being made to the current collection."
+msgstr ""
+"Додавати інформацію зі зібрання, що "
+"імпортується, можна тільки у зібрання "
+"такого ж типу."
+
+#: tellico_strings.cpp:24
+msgid ""
+"Only collections with the same type of entries as the current one can be "
+"merged. No changes are being made to the current collection."
+msgstr ""
+"Додавати інформацію зі зібрання, що "
+"імпортується, можна тільки у зібрання "
+"такого ж типу."
+
+#: tellico_strings.cpp:27
+#, c-format
+msgid "Tellico is unable to load an image from the file - %1."
+msgstr ""
+"Tellico не вдається завантажити зображення з "
+"файлу - %1"
+
+#: entryiconview.cpp:287
+#, fuzzy
+msgid "&Sort By"
+msgstr "&Порт"
+
+#: loandialog.cpp:40
+msgid "Loan Dialog"
+msgstr "Віддати у борг"
+
+#: loandialog.cpp:78
+msgid "The following items are being checked out:"
+msgstr "Наступні речі будуть віддані у борг:"
+
+#: loandialog.cpp:84
+msgid "The following item is on-loan:"
+msgstr "Наступні речі не були повернені:"
+
+#: loandialog.cpp:94
+msgid "&Lend to:"
+msgstr "&Віддати у борг (кому):"
+
+#: loandialog.cpp:107
+msgid ""
+"Enter the name of the person borrowing the items from you. Clicking the "
+"button allows you to select from your address book."
+msgstr ""
+"Введіть ім'я людини, якій Ви хочете "
+"віддати у борг. Якщо хочете вибрати "
+"людину з Вашої адресної книги, то "
+"натисніть на кнопку."
+
+#: loandialog.cpp:117
+msgid "&Loan date:"
+msgstr "&Дата дачі у борг:"
+
+#: loandialog.cpp:123
+msgid ""
+"The check-out date is the date that you lent the items. By default, today's "
+"date is used."
+msgstr ""
+"Дата, коли предмет був відданий у борг. По "
+"умовчанню використовується поточна дата."
+
+#: loandialog.cpp:132
+msgid "D&ue date:"
+msgstr "Д&ата закінчення терміну:"
+
+#: loandialog.cpp:139
+msgid ""
+"The due date is when the items are due to be returned. The due date is not "
+"required, unless you want to add the loan to your active calendar."
+msgstr ""
+"Дата закінчення терміну боргу "
+"(необов'язково)"
+
+#: loandialog.cpp:144
+msgid "&Note:"
+msgstr "&Замітки:"
+
+#: loandialog.cpp:150
+msgid "You can add notes about the loan, as well."
+msgstr ""
+"Ви можете додати деякі відомості для себе."
+
+#: loandialog.cpp:154
+msgid "&Add a reminder to the active calendar"
+msgstr "Д&одати нагадування."
+
+#: loandialog.cpp:157
+msgid ""
+"<qt>Checking this box will add a <em>To-do</em> item to your active "
+"calendar, which can be viewed using KOrganizer. The box is only active if "
+"you set a due date."
+msgstr ""
+"<qt>Якщо відмічено, то запис про борг буде "
+"доданий у календар KOrganizer</qt>"
+
+#: mainwindow.cpp:188
+msgid "Create a new collection"
+msgstr "Створити нове зібрання"
+
+#: mainwindow.cpp:192
+msgid "New &Book Collection"
+msgstr "Нове зібрання &книг"
+
+#: mainwindow.cpp:194
+msgid "Create a new book collection"
+msgstr "Створити нове зібрання книг"
+
+#: mainwindow.cpp:200
+msgid "New B&ibliography"
+msgstr "Нова &бібліографія"
+
+#: mainwindow.cpp:202
+msgid "Create a new bibtex bibliography"
+msgstr "Створити нову бібліографію bibtex"
+
+#: mainwindow.cpp:208
+msgid "New &Comic Book Collection"
+msgstr "Нове зібрання к&оміксів"
+
+#: mainwindow.cpp:210
+msgid "Create a new comic book collection"
+msgstr "Створити нове зібрання коміксів"
+
+#: mainwindow.cpp:216
+msgid "New &Video Collection"
+msgstr "Нове зібрання &відео"
+
+#: mainwindow.cpp:218
+msgid "Create a new video collection"
+msgstr "Створити нове зібрання відео"
+
+#: mainwindow.cpp:224
+msgid "New &Music Collection"
+msgstr "Нове зібрання &музики"
+
+#: mainwindow.cpp:226
+msgid "Create a new music collection"
+msgstr "Створити нове зібрання музики"
+
+#: mainwindow.cpp:232
+msgid "New C&oin Collection"
+msgstr "Нове зібрання &монет"
+
+#: mainwindow.cpp:234
+msgid "Create a new coin collection"
+msgstr "Створити нове зібрання монет"
+
+#: mainwindow.cpp:240
+msgid "New &Stamp Collection"
+msgstr "Нове зібрання ма&рок"
+
+#: mainwindow.cpp:242
+msgid "Create a new stamp collection"
+msgstr "Створити нове зібрання марок"
+
+#: mainwindow.cpp:248
+msgid "New C&ard Collection"
+msgstr "Нове зібрання к&арток"
+
+#: mainwindow.cpp:250
+msgid "Create a new trading card collection"
+msgstr "Створити нове зібрання карток"
+
+#: mainwindow.cpp:256
+msgid "New &Wine Collection"
+msgstr "Нове зібрання &вин"
+
+#: mainwindow.cpp:258
+msgid "Create a new wine collection"
+msgstr "Створити нове зібрання вин"
+
+#: mainwindow.cpp:264
+msgid "New &Game Collection"
+msgstr "Нове зібрання &ігор"
+
+#: mainwindow.cpp:266
+msgid "Create a new game collection"
+msgstr "Створити нове зібрання ігор"
+
+#: mainwindow.cpp:272
+#, fuzzy
+msgid "New Boa&rd Game Collection"
+msgstr "Нове зібрання &ігор"
+
+#: mainwindow.cpp:274
+#, fuzzy
+msgid "Create a new board game collection"
+msgstr "Створити нове зібрання ігор"
+
+#: mainwindow.cpp:280
+msgid "New &File Catalog"
+msgstr "Нова &файлова тека"
+
+#: mainwindow.cpp:282
+msgid "Create a new file catalog"
+msgstr "Створити нову файлову теку"
+
+#: mainwindow.cpp:288
+msgid "New C&ustom Collection"
+msgstr "Нове зібрання"
+
+#: mainwindow.cpp:290
+msgid "Create a new custom collection"
+msgstr "Створити нове зібрання"
+
+#: mainwindow.cpp:299
+msgid "Open an existing document"
+msgstr "Відкрити існуючий документ"
+
+#: mainwindow.cpp:301
+msgid "Open a recently used file"
+msgstr ""
+"Відкрити файл, що недавно "
+"використовувався"
+
+#: mainwindow.cpp:303
+msgid "Save the document"
+msgstr "Зберегти документ"
+
+#: mainwindow.cpp:305
+msgid "Save the document as a different file..."
+msgstr "Зберегти документ в інший файл"
+
+#: mainwindow.cpp:307
+msgid "Print the contents of the document..."
+msgstr "Надрукувати вміст цього документа"
+
+#: mainwindow.cpp:309
+msgid "Quit the application"
+msgstr "Вийти з програми"
+
+#: mainwindow.cpp:320
+msgid "Import collection data from other formats"
+msgstr "Імпортувати зібрання з інших форматів"
+
+#: mainwindow.cpp:324
+msgid "Import Tellico Data..."
+msgstr "Імпорт даних Tellico..."
+
+#: mainwindow.cpp:325
+msgid "Import another Tellico data file"
+msgstr "Імпортувати інше зібрання Tellico"
+
+#: mainwindow.cpp:331
+msgid "Import CSV Data..."
+msgstr "Імпорт з CSV..."
+
+#: mainwindow.cpp:332
+msgid "Import a CSV file"
+msgstr "Імпорт з файлу CSV"
+
+#: mainwindow.cpp:338
+msgid "Import MODS Data..."
+msgstr "Імпорт з MODS..."
+
+#: mainwindow.cpp:339
+msgid "Import a MODS data file"
+msgstr "Імпорт з MODS"
+
+#: mainwindow.cpp:345
+msgid "Import Alexandria Data..."
+msgstr "Імпорт з Alexandria..."
+
+#: mainwindow.cpp:346
+msgid "Import data from the Alexandria book collection manager"
+msgstr "Імпорт з менеджера зібрань книг Alexandria"
+
+#: mainwindow.cpp:352
+#, fuzzy
+msgid "Import Delicious Library Data..."
+msgstr "Імпорт даних Tellico..."
+
+#: mainwindow.cpp:353
+#, fuzzy
+msgid "Import data from Delicious Library"
+msgstr "Імпорт з даних тегів аудіо файлів"
+
+#: mainwindow.cpp:359
+#, fuzzy
+msgid "Import Referencer Data..."
+msgstr "Імпорт з RIS..."
+
+#: mainwindow.cpp:360
+#, fuzzy
+msgid "Import data from Referencer"
+msgstr "Імпортувати з RIS"
+
+#: mainwindow.cpp:366
+msgid "Import Bibtex Data..."
+msgstr "Імпорт з Bibtex..."
+
+#: mainwindow.cpp:367
+msgid "Import a bibtex bibliography file"
+msgstr "Імпортувати з bibtex"
+
+#: mainwindow.cpp:373
+msgid "Import Bibtexml Data..."
+msgstr "Імпорт з Bibtexml..."
+
+#: mainwindow.cpp:374
+msgid "Import a Bibtexml bibliography file"
+msgstr "Імпортувати з Bibtexml"
+
+#: mainwindow.cpp:380
+msgid "Import RIS Data..."
+msgstr "Імпорт з RIS..."
+
+#: mainwindow.cpp:381
+msgid "Import an RIS reference file"
+msgstr "Імпортувати з RIS"
+
+#: mainwindow.cpp:387
+#, fuzzy
+msgid "Import PDF File..."
+msgstr "Імпорт файлу"
+
+#: mainwindow.cpp:388
+#, fuzzy
+msgid "Import a PDF file"
+msgstr "Імпорт з файлу CSV"
+
+#: mainwindow.cpp:394
+msgid "Import Audio File Metadata..."
+msgstr "Імпорт з даних аудіо файлу..."
+
+#: mainwindow.cpp:395
+msgid "Import meta-data from audio files"
+msgstr "Імпорт з даних тегів аудіо файлів"
+
+#: mainwindow.cpp:404
+msgid "Import Audio CD Data..."
+msgstr "Імпорт з Audio CD..."
+
+#: mainwindow.cpp:405
+msgid "Import audio CD information"
+msgstr ""
+"Імпорт інформації про Audio CD з бази даних "
+"FreeDB"
+
+#: mainwindow.cpp:414
+msgid "Import GCstar Data..."
+msgstr "Імпорт даних GCstar..."
+
+#: mainwindow.cpp:415
+msgid "Import a GCstar data file"
+msgstr "Імпорт даних з файлу GCstar"
+
+#: mainwindow.cpp:421
+#, fuzzy
+msgid "Import Griffith Data..."
+msgstr "Імпорт даних GCstar..."
+
+#: mainwindow.cpp:422
+#, fuzzy
+msgid "Import a Griffith database"
+msgstr "Експортувати у базу даних PilotDB"
+
+#: mainwindow.cpp:428
+msgid "Import Ant Movie Catalog Data..."
+msgstr "Імпорт даних з каталогу Ant Movie..."
+
+#: mainwindow.cpp:429
+msgid "Import an Ant Movie Catalog data file"
+msgstr "Експорт файлу даних з каталогу Ant Movie"
+
+#: mainwindow.cpp:435
+msgid "Import File Listing..."
+msgstr "Імпорт списку файлів"
+
+#: mainwindow.cpp:436
+msgid "Import information about files in a folder"
+msgstr ""
+"Імпортувати інформацію про файли у теці"
+
+#: mainwindow.cpp:442
+msgid "Import XSL Transform..."
+msgstr "Імпорт з XSLT..."
+
+#: mainwindow.cpp:443
+msgid "Import using an XSL Transform"
+msgstr "Імпорт, використовуючи XSLT"
+
+#: mainwindow.cpp:455 rc.cpp:12
+#, no-c-format
+msgid "&Export"
+msgstr "&Експорт"
+
+#: mainwindow.cpp:457
+msgid "Export the collection data to other formats"
+msgstr ""
+"Експортувати дані зібрання у інший формат"
+
+#: mainwindow.cpp:461
+msgid "Export to XML..."
+msgstr "Експорт у XML..."
+
+#: mainwindow.cpp:462
+msgid "Export to a Tellico XML file"
+msgstr "Експорт у XML"
+
+#: mainwindow.cpp:468
+msgid "Export to Zip..."
+msgstr "Експорт в ZIP..."
+
+#: mainwindow.cpp:469
+msgid "Export to a Tellico Zip file"
+msgstr "Експорт в стиснутий ZIP-файл Tellico"
+
+#: mainwindow.cpp:475
+msgid "Export to HTML..."
+msgstr "Експорт в HTML..."
+
+#: mainwindow.cpp:476
+msgid "Export to an HTML file"
+msgstr "Експорт в HTML"
+
+#: mainwindow.cpp:482
+msgid "Export to CSV..."
+msgstr "Експорт в CSV..."
+
+#: mainwindow.cpp:483
+msgid "Export to a comma-separated values file"
+msgstr "Експорт в CSV"
+
+#: mainwindow.cpp:489
+msgid "Export to PilotDB..."
+msgstr "Експорт в PilotDB..."
+
+#: mainwindow.cpp:490
+msgid "Export to a PilotDB database"
+msgstr "Експортувати у базу даних PilotDB"
+
+#: mainwindow.cpp:496
+msgid "Export to Alexandria..."
+msgstr "Експорт у Alexandria..."
+
+#: mainwindow.cpp:497
+msgid "Export to an Alexandria library"
+msgstr "Експорт у бібліотеку Alexandria"
+
+#: mainwindow.cpp:503
+msgid "Export to Bibtex..."
+msgstr "Експорт у Bibtex..."
+
+#: mainwindow.cpp:504
+msgid "Export to a bibtex file"
+msgstr "Експорт у файл Bibtex"
+
+#: mainwindow.cpp:510
+msgid "Export to Bibtexml..."
+msgstr "Експорт у Bibtexml..."
+
+#: mainwindow.cpp:511
+msgid "Export to a Bibtexml file"
+msgstr "Експорт у файл Bibtexml"
+
+#: mainwindow.cpp:517
+msgid "Export to ONIX..."
+msgstr "Експорт у ONIX..."
+
+#: mainwindow.cpp:518
+msgid "Export to an ONIX file"
+msgstr "Експорт у файл ONIX"
+
+#: mainwindow.cpp:524
+msgid "Export to GCfilms..."
+msgstr "Експорт у GCfilms..."
+
+#: mainwindow.cpp:525
+msgid "Export to a GCfilms data file"
+msgstr "Експорт у GCfilms"
+
+#: mainwindow.cpp:531
+#, fuzzy
+msgid "Export to GCstar..."
+msgstr "Експорт у GCfilms..."
+
+#: mainwindow.cpp:532
+#, fuzzy
+msgid "Export to a GCstar data file"
+msgstr "Експорт у GCfilms"
+
+#: mainwindow.cpp:536
+msgid "Export XSL Transform..."
+msgstr "Експорт у XSLT..."
+
+#: mainwindow.cpp:537
+msgid "Export using an XSL Transform"
+msgstr "Експорт, використовуючи XSLT"
+
+#: mainwindow.cpp:546
+msgid "Cut the selected text and puts it in the clipboard"
+msgstr ""
+"Вирізати виділений текст та помістити "
+"його у буфер обміну"
+
+#: mainwindow.cpp:548
+msgid "Copy the selected text to the clipboard"
+msgstr ""
+"Копіювати виділений текст у буфер обміну"
+
+#: mainwindow.cpp:550
+msgid "Paste the clipboard contents"
+msgstr "Вставити вміст буфера обміну"
+
+#: mainwindow.cpp:552
+msgid "Select all the entries in the collection"
+msgstr "Виділити усі записи у зібранні"
+
+#: mainwindow.cpp:554
+msgid "Deselect all the entries in the collection"
+msgstr ""
+"Відмінити виділення усіх записів у "
+"зібранні"
+
+#: mainwindow.cpp:556
+msgid "Internet Search..."
+msgstr "Пошук в інтернеті..."
+
+#: mainwindow.cpp:559
+msgid "Search the internet..."
+msgstr "Пошук в інтернеті"
+
+#: mainwindow.cpp:561
+msgid "Advanced &Filter..."
+msgstr "Просунутий &фільтр"
+
+#: mainwindow.cpp:564 mainwindow.cpp:719
+msgid "Filter the collection"
+msgstr "Фільтр зібрання"
+
+#: mainwindow.cpp:569
+msgid "&New Entry..."
+msgstr "&Новий запис..."
+
+#: mainwindow.cpp:572
+msgid "Create a new entry"
+msgstr "Створити новий запис"
+
+#: controller.cpp:620 mainwindow.cpp:573
+msgid "&Edit Entry..."
+msgstr "&Редагувати запис..."
+
+#: mainwindow.cpp:576
+msgid "Edit the selected entries"
+msgstr "Редагувати виділені записи"
+
+#: controller.cpp:621 mainwindow.cpp:577
+msgid "D&uplicate Entry"
+msgstr "&Здублювати запис"
+
+#: mainwindow.cpp:580
+msgid "Copy the selected entries"
+msgstr "Копіювати виділені записи"
+
+#: controller.cpp:623 mainwindow.cpp:581
+msgid "&Delete Entry"
+msgstr "&Видалити запис"
+
+#: mainwindow.cpp:584
+msgid "Delete the selected entries"
+msgstr "Видалити виділені записи"
+
+#: mainwindow.cpp:585
+#, fuzzy
+msgid "&Merge Entries"
+msgstr "&Вилучити записи"
+
+#: mainwindow.cpp:588
+#, fuzzy
+msgid "Merge the selected entries"
+msgstr "Видалити виділені записи"
+
+#: mainwindow.cpp:591
+msgid "&Generate Reports..."
+msgstr "Створити звіт..."
+
+#: mainwindow.cpp:594
+msgid "Generate collection reports"
+msgstr "Створити звіт про зібрання"
+
+#: mainwindow.cpp:595
+msgid "Check-&out..."
+msgstr "&Віддати у борг..."
+
+#: mainwindow.cpp:598
+msgid "Check-out the selected items"
+msgstr "Віддати виділені записи у борг"
+
+#: mainwindow.cpp:599
+msgid "Check-&in"
+msgstr "&Повернути з боргу"
+
+#: mainwindow.cpp:602
+msgid "Check-in the selected items"
+msgstr "Повернути з боргу виділені речі"
+
+#: mainwindow.cpp:604
+msgid "&Rename Collection..."
+msgstr "&Перейменувати зібрання"
+
+#: mainwindow.cpp:607
+msgid "Rename the collection"
+msgstr "Перейменувати зібрання"
+
+#: mainwindow.cpp:608
+msgid "Collection &Fields..."
+msgstr "&Поля у зібранні"
+
+#: mainwindow.cpp:611
+msgid "Modify the collection fields"
+msgstr "Редагувати поля у зібранні"
+
+#: mainwindow.cpp:612
+msgid "Convert to &Bibliography"
+msgstr "Конвертувати у бібліографію"
+
+#: mainwindow.cpp:615
+msgid "Convert a book collection to a bibliography"
+msgstr ""
+"Конвертувати зібрання книг у "
+"бібліографію"
+
+#: mainwindow.cpp:616
+msgid "String &Macros..."
+msgstr "Рядок &макросів"
+
+#: mainwindow.cpp:619
+msgid "Edit the bibtex string macros"
+msgstr "Редагувати рядок макросів bibtex"
+
+#: mainwindow.cpp:626
+msgid "Copy Bibtex to Cli&pboard"
+msgstr "Копіювати дані Bibtex у буфер обміну"
+
+#: mainwindow.cpp:627
+msgid "Copy bibtex citations to the clipboard"
+msgstr "Копіювати дані Bibtex в буфер обміну"
+
+#: mainwindow.cpp:632
+msgid "Cite Entry in &LyX"
+msgstr "Зробити посилання в &LyX"
+
+#: mainwindow.cpp:633
+msgid "Cite the selected entries in LyX"
+msgstr "Відправити виділені записи в LyX"
+
+#: mainwindow.cpp:638
+msgid "Ci&te Entry in OpenOffice.org"
+msgstr "Зробити посилання в OpenOffice.org"
+
+#: mainwindow.cpp:639
+msgid "Cite the selected entries in OpenOffice.org"
+msgstr "Відправити виділені записи в OpenOffice.org"
+
+#: controller.cpp:622 mainwindow.cpp:647 rc.cpp:18
+#, no-c-format
+msgid "&Update Entry"
+msgstr "&Оновити записи"
+
+#: mainwindow.cpp:652
+msgid "All Sources"
+msgstr "Всі джерела"
+
+#: mainwindow.cpp:653
+msgid "Update entry data from all available sources"
+msgstr "Оновити дані записів зі всіх джерел."
+
+#: mainwindow.cpp:665
+msgid "Show Grou&p View"
+msgstr "Показати &групи"
+
+#: mainwindow.cpp:668
+msgid "Enable/disable the group view"
+msgstr "Показати/приховати групи"
+
+#: mainwindow.cpp:669
+msgid "Hide Grou&p View"
+msgstr "Приховати &групи"
+
+#: mainwindow.cpp:671
+msgid "Show Entry &Editor"
+msgstr "Показати редактор &полів"
+
+#: mainwindow.cpp:674
+msgid "Enable/disable the editor"
+msgstr "Показати/приховати редактор полів"
+
+#: mainwindow.cpp:675
+msgid "Hide Entry &Editor"
+msgstr "Приховати редактор полів"
+
+#: mainwindow.cpp:677
+msgid "Show Entry &View"
+msgstr "Показати інформацію про записи"
+
+#: mainwindow.cpp:680
+msgid "Enable/disable the entry view"
+msgstr ""
+"Показати/приховати інформацію про записи"
+
+#: mainwindow.cpp:681
+msgid "Hide Entry &View"
+msgstr "Приховати інформацію про записи"
+
+#: mainwindow.cpp:693
+msgid "Change Grouping"
+msgstr "Змінити спосіб угрупування"
+
+#: mainwindow.cpp:697
+msgid "&Group Selection"
+msgstr "Групувати по"
+
+#: mainwindow.cpp:700
+msgid "Change the grouping of the collection"
+msgstr "Змінити спосіб групування у зібранні"
+
+#: filterview.cpp:33 filterview.cpp:85 mainwindow.cpp:702 mainwindow.cpp:717
+msgid "Filter"
+msgstr "Фільтр"
+
+#: mainwindow.cpp:705
+msgid "Clear Filter"
+msgstr "Очистити фільтр"
+
+#: mainwindow.cpp:710
+msgid "Filter here..."
+msgstr "Введіть сюди критерій фільтру..."
+
+#: mainwindow.cpp:768
+msgid "Groups"
+msgstr "Групи"
+
+#: mainwindow.cpp:769
+msgid ""
+"<qt>The <i>Group View</i> sorts the entries into groupings based on a "
+"selected field.</qt>"
+msgstr ""
+"<qt>Опція <i>\"Групувати записи\"</i> сортує "
+"записи за вибраним способом "
+"угрупування.</qt>"
+
+#: mainwindow.cpp:776
+msgid ""
+"<qt>The <i>Column View</i> shows the value of multiple fields for each "
+"entry.</qt>"
+msgstr ""
+"<qt><i>Вигляд в стовпцях</i> показує значення "
+"декілька полів для кожного запису</qt>"
+
+#: mainwindow.cpp:831
+#, fuzzy
+msgid "Welcome to the Tellico Collection Manager"
+msgstr "Tellico - менеджер зібрань для KDE."
+
+#: mainwindow.cpp:833
+msgid ""
+"<h3>Tellico is a tool for managing collections of books, videos, music, and "
+"whatever else you want to catalog.</h3><h3>New entries can be added to your "
+"collection by <a href=\"tc:///coll_new_entry\">entering data manually</a> or "
+"by <a href=\"tc:///edit_search_internet\">downloading data</a> from various "
+"Internet sources.</h3>"
+msgstr ""
+
+#: mainwindow.cpp:1066
+msgid "Creating new document..."
+msgstr "Створення нового документа..."
+
+#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
+msgid "Opening file..."
+msgstr "Відкриття файлу..."
+
+#: mainwindow.cpp:1108
+msgid "Open File"
+msgstr "Відкрити файл"
+
+#: document.cpp:192 mainwindow.cpp:1215
+msgid "Saving file..."
+msgstr "Збереження файлу...."
+
+#: mainwindow.cpp:1226
+msgid ""
+"<qt><p>You are saving a file with many images, which causes Tellico to slow "
+"down significantly. Do you want to save the images separately in Tellico's "
+"data directory to improve performance?</p><p>Your choice can always be "
+"changed in the configuration dialog.</p></qt>"
+msgstr ""
+"<qt><p>Ви намагаєтеся зберегти файл з "
+"великою кількістю зображень. Це може "
+"уповільнити подальше використання Tellico і "
+"зробить файл дуже великим. Чи Ви хочете "
+"зберегти зображення у теці Tellico (у файл "
+"будуть записані тільки \"текстові\" "
+"дані)?</p></qt>"
+
+#: mainwindow.cpp:1231
+msgid "Save Images Separately"
+msgstr "Зберігати зображення окремо"
+
+#: mainwindow.cpp:1232
+msgid "Save Images in File"
+msgstr "Зберігати файл разом із зображеннями"
+
+#: mainwindow.cpp:1265
+msgid "Saving file with a new filename..."
+msgstr "Зберегти файл під іншим ім'ям"
+
+#: mainwindow.cpp:1303 mainwindow.cpp:1353
+msgid "Printing..."
+msgstr "Друк..."
+
+#: mainwindow.cpp:1312
+msgid ""
+"The collection is currently being filtered to show a limited subset of the "
+"entries. Only the visible entries will be printed. Continue?"
+msgstr ""
+"Зараз до зібрання застосований фільтр і "
+"будуть надруковані тільки видимі поля. "
+"Продовжити?"
+
+#: mainwindow.cpp:1337
+msgid "Processing document..."
+msgstr "Почекайте..."
+
+#: mainwindow.cpp:1360
+msgid "Exiting..."
+msgstr "Вихід..."
+
+#: mainwindow.cpp:1498
+#, c-format
+msgid "Total entries: %1"
+msgstr "Всього записів: %1"
+
+#: mainwindow.cpp:1505
+msgid "(%1 filtered; %2 selected)"
+msgstr "(%1 відфільтровано; %2 виділено)"
+
+#: mainwindow.cpp:1508
+msgid "(%1 filtered)"
+msgstr "(%1 відфільтровано)"
+
+#: mainwindow.cpp:1511
+msgid "(%1 selected)"
+msgstr "(%1 виділено)"
+
+#: mainwindow.cpp:1679
+#, c-format
+msgid "Print %1"
+msgstr "Друк %1"
+
+#: mainwindow.cpp:1712
+#, c-format
+msgid "Page %1"
+msgstr "Сторінка %1"
+
+#: entryview.cpp:188 mainwindow.cpp:1739
+msgid "Please check your installation."
+msgstr "Будь ласка, перевірте Вашу інсталяцію"
+
+#: mainwindow.cpp:1849
+msgid "Importing data..."
+msgstr "Імпорт даних..."
+
+#: mainwindow.cpp:1858
+msgid "Import File"
+msgstr "Імпорт файлу"
+
+#: mainwindow.cpp:1864
+msgid "Import Directory"
+msgstr "Імпорт теки"
+
+#: mainwindow.cpp:1885
+msgid "Exporting data..."
+msgstr "Експортування даних..."
+
+#: mainwindow.cpp:1907
+msgid "Export As"
+msgstr "Експортувати як"
+
+#: mainwindow.cpp:1935
+msgid "String Macros"
+msgstr "Рядок макросів"
+
+#: mainwindow.cpp:1936
+msgid "Macro"
+msgstr "Макрос"
+
+#: mainwindow.cpp:1936
+msgid "String"
+msgstr "Рядок"
+
+#: mainwindow.cpp:1999
+msgid "Creating citations..."
+msgstr "Йде створення..."
+
+#: mainwindow.cpp:2104
+msgid "Filters"
+msgstr "Фільтри"
+
+#: mainwindow.cpp:2105
+msgid ""
+"<qt>The <i>Filter View</i> shows the entries which meet certain filter "
+"rules.</qt>"
+msgstr ""
+"<qt><i>Вигляд по фільтру</i> показує записи "
+"згідно застосованому фільтру.</qt>"
+
+#: mainwindow.cpp:2121
+msgid "Loans"
+msgstr "Борги"
+
+#: mainwindow.cpp:2122
+msgid ""
+"<qt>The <i>Loan View</i> shows a list of all the people who have borrowed "
+"items from your collection.</qt>"
+msgstr ""
+"<qt><i>Вид боржників</i> показує людей, які "
+"щось взяли у борг з Вашого зібрання.</qt>"
+
+#: mainwindow.cpp:2255
+#, c-format
+msgid "Update entry data from %1"
+msgstr "Оновити дані запису зі \"%1\""
+
+#: mainwindow.cpp:2274
+msgid ""
+"Tellico can only import one file of this type at a time. Only %1 will be "
+"imported."
+msgstr ""
+
+#: filehandler.cpp:193
+#, c-format
+msgid "Tellico is unable to load the image - %1."
+msgstr ""
+"Tellico не вдається завантажити зображення - "
+"%1."
+
+#: filehandler.cpp:207
+msgid ""
+"A file named \"%1\" already exists. Are you sure you want to overwrite it?"
+msgstr ""
+"Файл під назвою \"%1\" вже існує. Чи Ви "
+"хочете переписати його?"
+
+#: filehandler.cpp:210
+msgid "Overwrite File?"
+msgstr "Переписати файл?"
+
+#: filehandler.cpp:211
+msgid "Overwrite"
+msgstr "Переписати"
+
+#: filterview.cpp:87
+msgid "Filter (Sort by Count)"
+msgstr "Фільтр"
+
+#: controller.cpp:427
+msgid "Do you really want to delete this entry?"
+msgstr "Ви дійсно хочете видалити цей запис?"
+
+#: controller.cpp:429
+msgid "Delete Entry"
+msgstr "Видалити запис"
+
+#: controller.cpp:439
+msgid "Do you really want to delete these entries?"
+msgstr "Ви дійсно хочете видалити ці записи?"
+
+#: controller.cpp:443
+msgid "Delete Multiple Entries"
+msgstr "Видалити декілька записів"
+
+#: controller.cpp:626
+msgid "&Edit Entries..."
+msgstr "&Редагувати записи..."
+
+#: controller.cpp:627
+msgid "D&uplicate Entries"
+msgstr "&Здублювати записи"
+
+#: controller.cpp:628
+msgid "&Update Entries"
+msgstr "&Оновити записи"
+
+#: controller.cpp:629
+msgid "&Delete Entries"
+msgstr "&Вилучити записи"
+
+#: controller.cpp:684
+msgid ""
+"The following items are already loaned, but Tellico does not currently "
+"support lending an item multiple times. They will be removed from the list "
+"of items to lend."
+msgstr "Ці речі вже були віддані у борг."
+
+#: calendarhandler.cpp:167
+msgid "Default Calendar"
+msgstr "Календар за умовчанням"
+
+#: calendarhandler.cpp:175
+msgid ""
+"At the moment, Tellico only supports local calendar resources. The active "
+"calendar is remotely located, so your loans will not be added."
+msgstr ""
+"В даний момент Tellico підтримує тільки свій "
+"календар. Поточний календар знаходиться "
+"не тут, так що Ваші борги не будуть "
+"занесені у нього."
+
+#: calendarhandler.cpp:180
+msgid "Active Calendar"
+msgstr "Поточний календар"
+
+#: calendarhandler.cpp:203
+msgid "Tellico: %1 is due to return \"%2\""
+msgstr "Tellico: %1 повернув \"%2\""
+
+#: collection.cpp:32
+msgid "(Empty)"
+msgstr "(порожньо)"
+
+#: main.cpp:23
+msgid "Tellico - a collection manager for KDE"
+msgstr "Tellico - менеджер зібрань для KDE."
+
+#: main.cpp:27
+msgid "Do not reopen the last open file"
+msgstr ""
+"Не відкривати ще раз останній відкритий "
+"файл"
+
+#: main.cpp:28
+msgid "Import <filename> as a bibtex file"
+msgstr "Імпортувати <filename> як файл bibtex"
+
+#: main.cpp:29
+msgid "Import <filename> as a MODS file"
+msgstr "Імпортувати <filename> як файл MODS"
+
+#: main.cpp:30
+msgid "Import <filename> as a RIS file"
+msgstr "Імпортувати <filename>як файл RIS"
+
+#: main.cpp:31
+msgid "File to open"
+msgstr "Файл для відкриття"
+
+#: main.cpp:42
+msgid "Data source scripts"
+msgstr "Сценарії джерела даних"
+
+#: main.cpp:44
+msgid "Icons"
+msgstr "Піктограми"
+
+#: main.cpp:46
+msgid "Author of btparse library"
+msgstr "Автор бібліотеки btparse"
+
+#: main.cpp:48
+msgid "Code examples and general inspiration"
+msgstr "Приклади коду"
+
+#: main.cpp:50
+#, fuzzy
+msgid "Author of libcsv library"
+msgstr "Автор бібліотеки btparse"
+
+#: main.cpp:52
+#, fuzzy
+msgid "Author of rtf2html library"
+msgstr "Автор бібліотеки btparse"
+
+#: collectionfieldsdialog.cpp:56
+msgid "Collection Fields"
+msgstr "Поля зібрання"
+
+#: collectionfieldsdialog.cpp:68
+msgid "Current Fields"
+msgstr "Поточні поля"
+
+#: collectionfieldsdialog.cpp:84
+msgid ""
+"_: New Field\n"
+"&New"
+msgstr "&Нове поле"
+
+#: collectionfieldsdialog.cpp:86
+msgid "Add a new field to the collection"
+msgstr "Додати нове поле у зібрання"
+
+#: collectionfieldsdialog.cpp:87
+msgid ""
+"_: Delete Field\n"
+"&Delete"
+msgstr "&Вилучити поле"
+
+#: collectionfieldsdialog.cpp:89
+msgid "Remove a field from the collection"
+msgstr "Вилучити поле зі зібрання"
+
+#: collectionfieldsdialog.cpp:98
+msgid ""
+"Move this field up in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr ""
+"Перемістити поле вгору на одну позицію"
+
+#: collectionfieldsdialog.cpp:102
+msgid ""
+"Move this field down in the list. The list order is important for the layout "
+"of the entry editor."
+msgstr "Перемістити поле вниз на одну позицію"
+
+#: collectionfieldsdialog.cpp:112
+msgid "Field Properties"
+msgstr "Параметри поля"
+
+#: collectionfieldsdialog.cpp:119
+msgid "&Title:"
+msgstr "Н&азва:"
+
+#: collectionfieldsdialog.cpp:124
+msgid "The title of the field"
+msgstr "Назва поля"
+
+#: collectionfieldsdialog.cpp:129
+msgid "T&ype:"
+msgstr "Т&ип"
+
+#: collectionfieldsdialog.cpp:135
+msgid "The type of the field determines what values may be used. "
+msgstr ""
+"Тип зібрання визначає, які значення "
+"можуть бути використані: "
+
+#: collectionfieldsdialog.cpp:136
+msgid "<i>Simple Text</i> is used for most fields. "
+msgstr ""
+"<i>Простий текст</i> використовується у "
+"багатьох полях. "
+
+#: collectionfieldsdialog.cpp:137
+msgid "<i>Paragraph</i> is for large text blocks. "
+msgstr ""
+"<i>Великий текст</i> використовується для "
+"запису великих об'ємів тексту. "
+
+#: collectionfieldsdialog.cpp:138
+msgid "<i>Choice</i> limits the field to certain values. "
+msgstr ""
+"<i>Вибір</i> створює поле для вибору "
+"фіксованих значень. "
+
+#: collectionfieldsdialog.cpp:139
+msgid "<i>Checkbox</i> is for a simple yes/no value. "
+msgstr ""
+"<i>Вибір так/ні</i> створює поле для "
+"простого встановлення значення \"так\" або "
+"\"ні\". "
+
+#: collectionfieldsdialog.cpp:140
+msgid "<i>Number</i> indicates that the field contains a numerical value. "
+msgstr ""
+"<i>Номер</i> використовується для запису "
+"числового значення. "
+
+#: collectionfieldsdialog.cpp:141
+msgid ""
+"<i>URL</i> is for fields which refer to URLs, including references to other "
+"files. "
+msgstr ""
+"<i>URL</i> використовується для запису "
+"посилань. "
+
+#: collectionfieldsdialog.cpp:142
+msgid "A <i>Table</i> may hold one or more columns of values. "
+msgstr ""
+"<i>Таблиця</i> створює поле для запису "
+"інформації у форматі таблиці. "
+
+#: collectionfieldsdialog.cpp:143
+msgid "An <i>Image</i> field holds a picture. "
+msgstr ""
+"<i>Зображення</i> використовується для "
+"зберігання зображень у зібранні. "
+
+#: collectionfieldsdialog.cpp:144
+msgid ""
+"A <i>Date</i> field can be used for values with a day, month, and year. "
+msgstr ""
+"<i>Дата</i> використовується для створення "
+"полів з днем, місяцем та роком. "
+
+#: collectionfieldsdialog.cpp:145
+msgid "A <i>Rating</i> field uses stars to show a rating number. "
+msgstr ""
+"<i>Рейтинг</i> створює поле з п'ятьма "
+"зірочками для визначення особистого "
+"рейтингу. "
+
+#: collectionfieldsdialog.cpp:146
+msgid ""
+"A <i>Dependent</i> field depends on the values of other fields, and is "
+"formatted according to the field description. "
+msgstr ""
+"<i>Залежність</i> створює поле, яке залежить "
+"від інших полів."
+
+#: collectionfieldsdialog.cpp:148
+msgid ""
+"A <i>Read Only</i> is for internal values, possibly useful for import and "
+"export. "
+msgstr ""
+"<i>Тільки для читання</i> - для запису "
+"внутрішніх значень, корисних при імпорті "
+"та експорті."
+
+#: collectionfieldsdialog.cpp:157
+msgid "Cate&gory:"
+msgstr "Кат&егорія:"
+
+#: collectionfieldsdialog.cpp:162
+msgid "The field category determines where the field is placed in the editor."
+msgstr ""
+"Категорія поля визначає, куди буде воно "
+"поміщено."
+
+#: collectionfieldsdialog.cpp:179
+msgid "Descr&iption:"
+msgstr "&Опис:"
+
+#. TRANSLATORS: Do not translate %{year} and %{title}.
+#: collectionfieldsdialog.cpp:186
+msgid ""
+"The description is a useful reminder of what information is contained in the "
+"field. For <i>Dependent</i> fields, the description is a format string such "
+"as \"%{year} %{title}\" where the named fields get substituted in the string."
+msgstr ""
+"Опис корисний для повідомлення про те, що "
+"повинно містити це поле. Для типу "
+"<i>Залежність</i> опис повинен бути такого "
+"вигляду: \"%{year} &{title}\", де імена полів "
+"замінюються згідно Вашим потребам."
+
+#: collectionfieldsdialog.cpp:193
+msgid "&Default value:"
+msgstr "&Значення за умовчанням:"
+
+#: collectionfieldsdialog.cpp:198
+msgid "<qt>A default value can be set for new entries.</qt>"
+msgstr ""
+"<qt>Значення за умовчанням може бути "
+"встановлене для нових записів.</qt>"
+
+#: collectionfieldsdialog.cpp:203
+msgid "A&llowed values:"
+msgstr "&Дозволені значення: "
+
+#: collectionfieldsdialog.cpp:208
+msgid ""
+"<qt>For <i>Choice</i>-type fields, these are the only values allowed. They "
+"are placed in a combo box. The possible values have to be separated by a "
+"semi-colon, for example: \"dog; cat; mouse\"</qt>"
+msgstr ""
+"<qt>Сюди вводяться допустимі значення для "
+"поля типу <i>\"Вибір\"</i>. Значення "
+"розділяються комами (напр. \"Кіт; Пес; "
+"Таракан\")</qt>"
+
+#: collectionfieldsdialog.cpp:215
+msgid "Extended &properties:"
+msgstr "&Додаткові параметри:"
+
+#: collectionfieldsdialog.cpp:217
+msgid "&Set..."
+msgstr "&Встановити..."
+
+#: collectionfieldsdialog.cpp:221
+msgid ""
+"Extended field properties are used to specify things such as the "
+"corresponding bibtex field."
+msgstr ""
+"Додаткові параметри поля корисні для "
+"деяких специфічних речей. Наприклад, для "
+"відповідного поля bibtex."
+
+#: collectionfieldsdialog.cpp:226
+msgid "Format Options"
+msgstr "Опції форматування."
+
+#: collectionfieldsdialog.cpp:227
+msgid "No formatting"
+msgstr "Немає форматування"
+
+#: collectionfieldsdialog.cpp:228
+msgid ""
+"This option prevents the field from ever being automatically formatted or "
+"capitalized."
+msgstr ""
+"Ця опція забороняє автоматичне "
+"форматування."
+
+#: collectionfieldsdialog.cpp:230
+msgid "Allow auto-capitalization only"
+msgstr "Дозволити лише явне форматування"
+
+#: collectionfieldsdialog.cpp:231
+msgid ""
+"This option allows the field to be capitalized, but not specially formatted."
+msgstr "Дозволити лише явне форматування"
+
+#: collectionfieldsdialog.cpp:233
+msgid "Format as a title"
+msgstr "Форматувати як заголовок"
+
+#: collectionfieldsdialog.cpp:234
+msgid ""
+"This option capitalizes and formats the field as a title, but only if those "
+"options are globally set."
+msgstr ""
+"Ця опція перетворює у верхній регістр та "
+"форматує поле як заголовок, але тільки "
+"якщо та опція глобально встановлена."
+
+#: collectionfieldsdialog.cpp:236
+msgid "Format as a name"
+msgstr "Форматувати як назву"
+
+#: collectionfieldsdialog.cpp:237
+msgid ""
+"This option capitalizes and formats the field as a name, but only if those "
+"options are globally set."
+msgstr ""
+"Ця опція перетворює у верхній реґістр та "
+"форматує поле як ім'я, але тільки якщо та "
+"опція глобально встановлена."
+
+#: collectionfieldsdialog.cpp:241
+msgid "Field Options"
+msgstr "Опції поля"
+
+#: collectionfieldsdialog.cpp:242
+msgid "Enable auto-completion"
+msgstr "Автоматично доповнювати до слова"
+
+#: collectionfieldsdialog.cpp:243
+msgid ""
+"If checked, KDE auto-completion will be enabled in the text edit box for "
+"this field."
+msgstr ""
+"Автоматично доповнювати до слова (як у "
+"OpenOffice.org)"
+
+#: collectionfieldsdialog.cpp:245
+msgid "Allow multiple values"
+msgstr "Дозволити декілька значень"
+
+#: collectionfieldsdialog.cpp:246
+msgid ""
+"If checked, Tellico will parse the values in the field for multiple values, "
+"separated by a semi-colon."
+msgstr ""
+"Якщо відмічено, то Tellico проаналізує "
+"значення у полі для багатократних "
+"значень, відокремлених крапкою з комою."
+
+#: collectionfieldsdialog.cpp:248
+msgid "Allow grouping"
+msgstr "Дозволити групування"
+
+#: collectionfieldsdialog.cpp:249
+msgid ""
+"If checked, this field may be used to group the entries in the group view."
+msgstr ""
+"Якщо відмічено, то це поле буде "
+"використано для групування записів у "
+"груповому вигляді."
+
+#: collectionfieldsdialog.cpp:263
+msgid "Revert the selected field's properties to the default values."
+msgstr ""
+"Змінити властивості вибраних полів на "
+"властивості за умовчанням."
+
+#: collectionfieldsdialog.cpp:306
+msgid "Modify Fields"
+msgstr "Редагувати поля"
+
+#: collectionfieldsdialog.cpp:320
+msgid ""
+"<qt>Removing allowed values from the <i>%1</i> field which currently exist "
+"in the collection may cause data corruption. Do you want to keep your "
+"modified values or cancel and revert to the current ones?</qt>"
+msgstr ""
+"<qt>Переміщення значень з поля \"<i>%1</i>\", яке "
+"вже існує, може пошкодити Ваші дані. Чи Ви "
+"хочете продовжити?</qt>"
+
+#: collectionfieldsdialog.cpp:325
+msgid "Keep modified values"
+msgstr "Зберігати змінені значення"
+
+#: collectionfieldsdialog.cpp:745
+msgid "Revert Field Properties"
+msgstr "Поміняти властивості поля"
+
+#: collectionfieldsdialog.cpp:746
+msgid ""
+"<qt><p>Do you really want to revert the properties for the <em>%1</em> field "
+"back to their default values?</p></qt>"
+msgstr ""
+"<qt><p>Ви дійсно хочете повернути полю "
+"<em>\"%1\"</em> властивості, призначені за "
+"умовчанням?"
+
+#: collectionfieldsdialog.cpp:749
+msgid "Revert"
+msgstr "Поміняти"
+
+#: collectionfieldsdialog.cpp:872
+msgid "Extended Field Properties"
+msgstr "Додаткові властивості поля"
+
+#: collectionfieldsdialog.cpp:902
+msgid "A field with this title already exists. Please enter a different title."
+msgstr ""
+"Поле з такою назвою вже існує. Будь ласка, "
+"введіть іншу назву."
+
+#: collectionfieldsdialog.cpp:909
+msgid "<qt>The category may not be empty. Please enter a category.</qt>"
+msgstr ""
+"<qt>Ця категорія не порожня. Будь ласка, "
+"виберіть категорію.</qt>"
+
+#: collectionfieldsdialog.cpp:917
+msgid ""
+"<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+"<em>Table</em> or <em>Image</em> field. Please enter a different "
+"category.</qt>"
+msgstr ""
+"<qt>Поле не може мати категорії: <em>\"Великий "
+"текст\" </em>, <em>\"Таблиця\"</em> або "
+"<em>\"Зображення\"</em>. Виберіть іншу "
+"категорію.</qt>"
+
+#: collectionfieldsdialog.cpp:925
+msgid ""
+"A field's title may not be the same as an existing category. Please enter a "
+"different title."
+msgstr ""
+"Назва поля не може бути таким же, як назва "
+"кактегорії. Введіть іншу назву."
+
+#: collectionfieldsdialog.cpp:937
+msgid ""
+"The range for a rating field must be between 1 and 10, and the lower bound "
+"must be less than the higher bound. Please enter different low and high "
+"properties."
+msgstr ""
+"Рейтинг не повинен бути менше 1 та більше "
+"10. Введіть інше значення рейтингу."
+
+#: collectionfieldsdialog.cpp:952
+msgid "Tables are limited to a maximum of ten columns."
+msgstr ""
+"У таблиці може бути максимум десять "
+"стовпців."
+
+#: document.cpp:158
+msgid ""
+"The current file has been modified.\n"
+"Do you want to save it?"
+msgstr ""
+"Поточний файл був змінений.\n"
+"Ви хочете зберегти його?"
+
+#: document.cpp:160 entryeditdialog.cpp:660
+msgid "Unsaved Changes"
+msgstr "Незбережені зміни"
+
+#: borrowerdialog.cpp:42
+msgid "Select Borrower"
+msgstr "Вибрати боржника"
+
+#: configdialog.cpp:103
+msgid "Configure Tellico"
+msgstr "Налаштувати Tellico"
+
+#: configdialog.cpp:198
+msgid "General Options"
+msgstr "Загальне"
+
+#: configdialog.cpp:201
+msgid "&Reopen file at startup"
+msgstr "Відкривати файл знову при запуску"
+
+#: configdialog.cpp:202
+msgid ""
+"If checked, the file that was last open will be re-opened at program "
+"start-up."
+msgstr ""
+"Якщо відмічено, то останній файл знову "
+"відкриватиметься при запуску."
+
+#: configdialog.cpp:207
+msgid "&Show \"Tip of the Day\" at startup"
+msgstr "Показувати \"аррада дня\" при запуску"
+
+#: configdialog.cpp:208
+msgid "If checked, the \"Tip of the Day\" will be shown at program start-up."
+msgstr ""
+"Якщо відмічено, при запуску програми "
+"з'являтиметься \"порада дня\""
+
+#: configdialog.cpp:213
+#, fuzzy
+msgid "Image Storage Options"
+msgstr "Опції зображень"
+
+#: configdialog.cpp:214
+#, fuzzy
+msgid "Store images in data file"
+msgstr "&Включати зображення у файл"
+
+#: configdialog.cpp:215
+msgid "Store images in common application directory"
+msgstr ""
+
+#: configdialog.cpp:216
+msgid "Store images in directory relative to data file"
+msgstr ""
+
+#: configdialog.cpp:217
+msgid ""
+"Images may be saved in the data file itself, which can cause Tellico to run "
+"slowly, stored in the Tellico application directory, or stored in a "
+"directory in the same location as the data file."
+msgstr ""
+
+#: configdialog.cpp:224 configdialog.cpp:299
+msgid "Formatting Options"
+msgstr "Опції форматування"
+
+#: configdialog.cpp:227
+msgid "Auto capitalize &titles and names"
+msgstr ""
+"Автоматичне визначення імен та "
+"заголовків"
+
+#: configdialog.cpp:228
+msgid "If checked, titles and names will be automatically capitalized."
+msgstr ""
+"Автоматичне визначення заголовків та "
+"імен."
+
+#: configdialog.cpp:232
+msgid "Auto &format titles and names"
+msgstr ""
+"Автоматично форматувати заголовки та "
+"імена"
+
+#: configdialog.cpp:233 configdialog.cpp:303
+msgid "If checked, titles and names will be automatically formatted."
+msgstr ""
+"Автоматично форматувати заголовки та "
+"імена."
+
+#: configdialog.cpp:240
+msgid "No capitali&zation:"
+msgstr "Дозволити лише явне форматування:"
+
+#: configdialog.cpp:243
+msgid ""
+"<qt>A list of words which should not be capitalized. Multiple values should "
+"be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Список слів, які не повинні "
+"форматуватися. Значення повинні "
+"розділятися крапкою з комою.</qt>"
+
+#: configdialog.cpp:249
+msgid "Artic&les:"
+msgstr "Артиклі:"
+
+#: configdialog.cpp:252
+msgid ""
+"<qt>A list of words which should be considered as articles if they are the "
+"first word in a title. Multiple values should be separated by a "
+"semi-colon.</qt>"
+msgstr ""
+"<qt>Список слів, які будуть розглянуті як "
+"артиклі. Значення повинні розділятися "
+"крапкою з комою.</qt>"
+
+#: configdialog.cpp:259
+msgid "Personal suffi&xes:"
+msgstr "Особисті &звернення: (мол., ст.,...)"
+
+#: configdialog.cpp:262
+msgid ""
+"<qt>A list of suffixes which might be used in personal names. Multiple "
+"values should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Список особистих суфіксів (jr, мол. і "
+"т.д.). Значення повинні розділятися "
+"крапкою з комою.</qt>"
+
+#: configdialog.cpp:268
+msgid "Surname &prefixes:"
+msgstr "Приставки прізвищ:"
+
+#: configdialog.cpp:271
+msgid ""
+"<qt>A list of prefixes which might be used in surnames. Multiple values "
+"should be separated by a semi-colon.</qt>"
+msgstr ""
+"<qt>Список приставок прізвищ (de, van і т.д.). "
+"Значення повинні розділятися крапкою з "
+"комою</qt>"
+
+#: configdialog.cpp:296
+msgid "Printing"
+msgstr "Друк"
+
+#: configdialog.cpp:296
+msgid "Printing Options"
+msgstr "Опції друку"
+
+#: configdialog.cpp:302
+msgid "&Format titles and names"
+msgstr "&Форматувати імена та назви"
+
+#: configdialog.cpp:306
+msgid "&Print field headers"
+msgstr "Включити заголовки полів"
+
+#: configdialog.cpp:310
+msgid "Grouping Options"
+msgstr "Опції групування"
+
+#: configdialog.cpp:313
+msgid "&Group the entries"
+msgstr "&Групувати записи"
+
+#: configdialog.cpp:317
+msgid "Image Options"
+msgstr "Опції зображень"
+
+#: configdialog.cpp:323
+msgid "Maximum image &width:"
+msgstr "Максимальна ширина зображення:"
+
+#: configdialog.cpp:328
+msgid ""
+"The maximum width of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Максимальна ширина зображення при друці."
+
+#: configdialog.cpp:336
+msgid "&Maximum image height:"
+msgstr "Максимальна висота зображення:"
+
+#: configdialog.cpp:341
+msgid ""
+"The maximum height of the images in the printout. The aspect ration is "
+"preserved."
+msgstr ""
+"Максимальна висота зображення при друці."
+
+#: configdialog.cpp:355
+msgid "Templates"
+msgstr "Шаблони"
+
+#: configdialog.cpp:355
+msgid "Template Options"
+msgstr "Опції шаблонів"
+
+#: configdialog.cpp:369
+msgid "Template:"
+msgstr "Шаблон:"
+
+#: configdialog.cpp:373
+msgid ""
+"Select the template to use for the current type of collections. Not all "
+"templates will use the font and color settings."
+msgstr ""
+"Виберіть шаблон, щоб використовувати для "
+"поточного виду зібрань. Не усі шаблони "
+"використовуватимуть налаштування шрифту "
+"та кольору."
+
+#: configdialog.cpp:380
+msgid "&Preview..."
+msgstr "&Попередній перегляд..."
+
+#: configdialog.cpp:381
+msgid "Show a preview of the template"
+msgstr "Показати попередній перегляд шаблону"
+
+#: configdialog.cpp:398
+msgid "Font Options"
+msgstr "Вибір шрифту"
+
+#: configdialog.cpp:405
+msgid "Font:"
+msgstr "Шрифт:"
+
+#: configdialog.cpp:411
+msgid "This font is passed to the template used in the Entry View."
+msgstr ""
+"Цей шрифт передається шаблону, що "
+"використовується у вигляді запису."
+
+#: configdialog.cpp:415
+msgid "Size:"
+msgstr "Розмір:"
+
+#: configdialog.cpp:425
+msgid "Color Options"
+msgstr "Вибір кольору"
+
+#: configdialog.cpp:432
+msgid "Background color:"
+msgstr "Колір фону:"
+
+#: configdialog.cpp:438
+msgid "This color is passed to the template used in the Entry View."
+msgstr ""
+"Цей колір передається шаблону, що "
+"використовується у вигляді запису."
+
+#: configdialog.cpp:442
+msgid "Text color:"
+msgstr "Колір тексту:"
+
+#: configdialog.cpp:451
+msgid "Highlight color:"
+msgstr "Колір підсвітки:"
+
+#: configdialog.cpp:460
+msgid "Highlighted text color:"
+msgstr "Коліпр підсвітки тексту:"
+
+#: configdialog.cpp:469
+msgid "Manage Templates"
+msgstr "Керування шаблонами"
+
+#: configdialog.cpp:475
+msgid "Install..."
+msgstr "Встановлення..."
+
+#: configdialog.cpp:478
+msgid "Click to install a new template directly."
+msgstr ""
+"Клацніть, щоб встановити новий шаблон "
+"безпосередньо."
+
+#: configdialog.cpp:481 configdialog.cpp:537
+msgid "Download..."
+msgstr "Звантаження..."
+
+#: configdialog.cpp:484
+msgid "Click to download additional templates via the Internet."
+msgstr ""
+"Клацніть, щоб завантажити додаткові "
+"шаблони через Інтернет."
+
+#: configdialog.cpp:487
+msgid "Delete..."
+msgstr "Вилучення..."
+
+#: configdialog.cpp:490
+msgid "Click to select and remove installed templates."
+msgstr ""
+"Клацніть, щоб вибрати та вилучити "
+"встановлені шаблони."
+
+#: configdialog.cpp:501
+msgid "Data Sources"
+msgstr "Джерела даних"
+
+#: configdialog.cpp:501
+msgid "Data Source Options"
+msgstr "Опції джерела даних"
+
+#: configdialog.cpp:506 fetchdialog.cpp:171
+msgid "Source"
+msgstr "Джерело"
+
+#: configdialog.cpp:517
+msgid "Move &Up"
+msgstr "&Вище"
+
+#: configdialog.cpp:519 configdialog.cpp:523
+msgid ""
+"The order of the data sources sets the order that Tellico uses when entries "
+"are automatically updated."
+msgstr ""
+"Порядок джерел даних встановлює порядок "
+"у якому Tellico проводить автоматичне "
+"оновлення записів."
+
+#: configdialog.cpp:521
+msgid "Move &Down"
+msgstr "&Нижче"
+
+#: configdialog.cpp:528
+msgid "&New..."
+msgstr "&Новий"
+
+#: configdialog.cpp:530
+msgid "Click to add a new data source."
+msgstr ""
+"Клацніть, щоб додати нове джерело даних."
+
+#: configdialog.cpp:531
+msgid "&Modify..."
+msgstr "&Редагувати..."
+
+#: configdialog.cpp:533
+msgid "Click to modify the selected data source."
+msgstr ""
+"Клацніть, щоб змінити відібране джерело "
+"даних."
+
+#: configdialog.cpp:536
+msgid "Click to delete the selected data source."
+msgstr ""
+"Клацніть, щоб вилучити відібране джерело "
+"даних."
+
+#: configdialog.cpp:539
+msgid "Click to download additional data sources via the Internet."
+msgstr ""
+"Клацніть, щоб завантажити додаткові "
+"джерела даних через Інтернет."
+
+#: configdialog.cpp:1016
+msgid "*.tar.gz *.tgz|Template Packages (*.tar.gz)"
+msgstr "*.tar.gz *.tgz|Пакунки шаблонів (*.tar.gz)"
+
+#: configdialog.cpp:1049
+msgid "Delete Template"
+msgstr "Вилучити шаблон"
+
+#: configdialog.cpp:1050
+msgid "Select template to delete:"
+msgstr "Виберіть шаблон для вилучення:"
+
+#: loanview.cpp:33 loanview.cpp:91 xslt.cpp:26
+msgid "Borrower"
+msgstr "Боржник"
+
+#: loanview.cpp:74
+msgid "Check-in"
+msgstr "Повернути з боргу"
+
+#: loanview.cpp:76
+msgid "Modify Loan..."
+msgstr "Редагувати борг..."
+
+#: loanview.cpp:93
+msgid "Borrower (Sort by Count)"
+msgstr "Боржники"
+
+#: collectionfactory.cpp:81
+msgid "My Collection"
+msgstr "Моє зібрання"
+
+#: collectionfactory.cpp:124
+msgid "Book Collection"
+msgstr "Зібрання книг"
+
+#: collectionfactory.cpp:126
+msgid "Comic Book Collection"
+msgstr "Зібрання коміксів"
+
+#: collectionfactory.cpp:127
+msgid "Video Collection"
+msgstr "Зібрання відео"
+
+#: collectionfactory.cpp:128
+msgid "Music Collection"
+msgstr "Зібрання музики"
+
+#: collectionfactory.cpp:129
+msgid "Coin Collection"
+msgstr "Зібрання монет"
+
+#: collectionfactory.cpp:130
+msgid "Stamp Collection"
+msgstr "Зібрання марок"
+
+#: collectionfactory.cpp:131
+msgid "Wine Collection"
+msgstr "Зібрання вин"
+
+#: collectionfactory.cpp:132
+msgid "Card Collection"
+msgstr "Зібрання карток"
+
+#: collectionfactory.cpp:133
+msgid "Game Collection"
+msgstr "Зібрання ігор"
+
+#: collectionfactory.cpp:134
+msgid "File Catalog"
+msgstr "Тека файлів"
+
+#: collectionfactory.cpp:135
+#, fuzzy
+msgid "Board Game Collection"
+msgstr "Зібрання ігор"
+
+#: collectionfactory.cpp:136
+msgid "Custom Collection"
+msgstr "Зібрання"
+
+#: viewstack.cpp:29
+msgid ""
+"<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+"contents.</qt>"
+msgstr ""
+"<qt><i>Інформація про записи</i> показує "
+"інформацію про записи у відформатованому "
+"вигляді.</qt>"
+
+#: viewstack.cpp:31
+msgid ""
+"<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+"an icon, which may be an image in the entry.</qt>"
+msgstr ""
+"<qt><i>\"Зображення\"</i> - це спосіб "
+"відображення записів, використовуючи їх "
+"зображення (напр., обкладинка книги)</qt>"
+
+#: exportdialog.cpp:48
+msgid "Export Options"
+msgstr "Опції експорту"
+
+#: exportdialog.cpp:53
+msgid "Formatting"
+msgstr "Форматування"
+
+#: exportdialog.cpp:55
+msgid "Format all fields"
+msgstr "Форматувати усі поля"
+
+#: exportdialog.cpp:57
+msgid ""
+"If checked, the values of the fields will be automatically formatted "
+"according to their format type."
+msgstr ""
+"Якщо відмічено, то значення полів будуть "
+"автоматично відформатовані згідно їх "
+"типів."
+
+#: exportdialog.cpp:59
+msgid "Export selected entries only"
+msgstr "Експорт лише виділених записів"
+
+#: exportdialog.cpp:61
+msgid "If checked, only the currently selected entries will be exported."
+msgstr ""
+"Якщо відмічено, то експортовані будуть "
+"лише виділені записи."
+
+#: exportdialog.cpp:64
+msgid "Encoding"
+msgstr "Кодування"
+
+#: exportdialog.cpp:66
+msgid "Encode in Unicode (UTF-8)"
+msgstr "Юнікод (UTF-8)"
+
+#: exportdialog.cpp:68
+msgid "Encode the exported file in Unicode (UTF-8)."
+msgstr "Експорт в юнікоді (UTF-8)"
+
+#: exportdialog.cpp:69
+msgid "Encode in user locale (%1)"
+msgstr "Системне кодування (%1)"
+
+#: exportdialog.cpp:72
+#, fuzzy
+msgid "Encode the exported file in the local encoding."
+msgstr "Експорт у системному кодуванні."
+
+#: fetchdialog.cpp:65
+msgid "&Search"
+msgstr "&Пошук"
+
+#: fetchdialog.cpp:66
+msgid "&Stop"
+msgstr "&Зупинка"
+
+#: fetchdialog.cpp:86
+msgid "Internet Search"
+msgstr "Пошук по інтернету"
+
+#: fetchdialog.cpp:94
+msgid "Search Query"
+msgstr "Черга пошуку"
+
+#: fetchdialog.cpp:100
+msgid ""
+"_: Start the search\n"
+"S&earch:"
+msgstr ""
+"_: Запуск пошуку\n"
+"&Пошук:"
+
+#: fetchdialog.cpp:104
+msgid "Enter a search value. An ISBN search must include the full ISBN."
+msgstr ""
+"Введіть значення для пошуку. Пошук за "
+"номерами ISBN повинен включати повний ISBN."
+
+#: fetchdialog.cpp:111
+msgid "Choose the type of search"
+msgstr "Виберіть тип пошуку"
+
+#: fetchdialog.cpp:117
+msgid "Click to start or stop the search"
+msgstr "Клацніть щоб почати/зупинити пошук"
+
+#: fetchdialog.cpp:134
+msgid "&Multiple ISBN/UPC search"
+msgstr "&Багатократний пошук по ISBN/UPC"
+
+#: fetchdialog.cpp:135
+msgid "Check this box to search for multiple ISBN or UPC values."
+msgstr ""
+"Якщо відмічено, буде проведений пошук за "
+"багатьма номерами ISBN/UPC."
+
+#: fetchdialog.cpp:138
+msgid "Edit List..."
+msgstr "Редагувати список..."
+
+#: fetchdialog.cpp:140
+msgid ""
+"Click to open a text edit box for entering or editing multiple ISBN values."
+msgstr ""
+"Клацніть щоб відкрилося вікно "
+"редагування тексту для "
+"введення/редагування багатьох номерів ISBN."
+
+#: fetchdialog.cpp:146
+msgid "Search s&ource:"
+msgstr "&Джерело пошуку:"
+
+#: fetchdialog.cpp:154
+msgid "Select the database to search"
+msgstr "Виберіть базу даних для пошуку"
+
+#: fetchdialog.cpp:177
+msgid ""
+"As results are found, they are added to this list. Selecting one will fetch "
+"the complete entry and show it in the view below."
+msgstr ""
+"Якщо результати будуть знайдені, то вони "
+"будуть додані у список."
+
+#: fetchdialog.cpp:185
+msgid ""
+"An entry may be shown here before adding it to the current collection by "
+"selecting it in the list above"
+msgstr ""
+"Запис може бути показаний тут до "
+"додавання у поточне зібрання."
+
+#: fetchdialog.cpp:192
+msgid "&Add Entry"
+msgstr "&Додати запис"
+
+#: fetchdialog.cpp:196
+msgid "Add the selected entry to the current collection"
+msgstr ""
+"Додати вибраний запис у поточне зібрання"
+
+#: fetchdialog.cpp:198
+msgid "Get More Results"
+msgstr "Отримати більше результатів"
+
+#: fetchdialog.cpp:201
+msgid "Fetch more results from the current data source"
+msgstr ""
+"Витягнути більше результатів з поточних "
+"джерел даних"
+
+#: fetchdialog.cpp:205
+msgid "Clear all search fields and results"
+msgstr ""
+"Очистити усі поля та результати пошуку"
+
+#: fetchdialog.cpp:298
+msgid "Cancelling the search..."
+msgstr "Відмінити пошук..."
+
+#: fetchdialog.cpp:313 fetchdialog.cpp:472
+msgid "Searching..."
+msgstr "Пошук..."
+
+#: fetchdialog.cpp:368
+msgid "The search returned no items."
+msgstr "Пошук не дав результатів."
+
+#: fetchdialog.cpp:372
+#, c-format
+msgid ""
+"_n: The search returned 1 item.\n"
+"The search returned %n items."
+msgstr ""
+"_n: Пошук дав 1 результат.\n"
+"Пошук дав %n результатів."
+
+#: fetchdialog.cpp:412
+#, fuzzy
+msgid "No results were found for the following ISBN values:"
+msgstr ""
+"<qt>Жодних записів не було знайдено по "
+"наступних номерах ISBN:</qt>"
+
+#: fetchdialog.cpp:443 fetchdialog.cpp:495
+msgid "Fetching %1..."
+msgstr "Витягнення %1..."
+
+#: fetchdialog.cpp:528 fetchdialog.cpp:708
+msgid "No Internet sources are available for your current collection type."
+msgstr ""
+"Немає доступних інтернет-джерел для "
+"даного типу Ваших поточних зібрань"
+
+#: fetchdialog.cpp:594
+msgid "Edit ISBN/UPC Values"
+msgstr "Редагувати значення ISBN/UPC"
+
+#: fetchdialog.cpp:598
+msgid "<qt>Enter the ISBN or UPC values, one per line.</qt>"
+msgstr ""
+"<qt>Введіть значення номера ISBN чи UPC, по "
+"одному на рядок.</qt>"
+
+#: fetchdialog.cpp:604
+msgid "&Load From File..."
+msgstr "&Завантажити з файлу"
+
+#: fetchdialog.cpp:605
+msgid "<qt>Load the list from a text file.</qt>"
+msgstr ""
+"<qt>Завантажити список з текстового "
+"файлу.</qt>"
+
+#: fetchdialog.cpp:624
+msgid ""
+"<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the first "
+"100 values in your list will be used.</qt>"
+msgstr ""
+"<qt>Пошук за номером ISBN може містити "
+"максимум 100 значень ISBN. Будуть "
+"використані лише 100 перших значень.</qt>"
+
+#: entryeditdialog.cpp:51 entryeditdialog.cpp:382 entryeditdialog.cpp:406
+#: entryeditdialog.cpp:512
+msgid "Edit Entry"
+msgstr "Редагувати запис"
+
+#: entryeditdialog.cpp:52
+msgid "&New Entry"
+msgstr "&Новий запис"
+
+#: entryeditdialog.cpp:66 entryeditdialog.cpp:117 entryeditdialog.cpp:416
+#: entryeditdialog.cpp:540
+msgid "Sa&ve Entry"
+msgstr "&Зберегти запис"
+
+#: entryeditdialog.cpp:77
+msgid "Go to the previous entry in the collection"
+msgstr "Йти до попереднього запису у зібранні"
+
+#: entryeditdialog.cpp:82
+msgid "Go to the next entry in the collection"
+msgstr "Йти до наступного запису у зібранні"
+
+#: entryeditdialog.cpp:315
+msgid "Do you really want to modify these entries?"
+msgstr "Ви дійсно хочете змінити ці записи?"
+
+#: entryeditdialog.cpp:317
+msgid "Modify Multiple Entries"
+msgstr "Редагувати декілька записів"
+
+#: entryeditdialog.cpp:359
+msgid "A value is required for the following fields. Do you want to continue?"
+msgstr ""
+
+#: entryeditdialog.cpp:456
+msgid "Edit Entries"
+msgstr "Редагувати записи"
+
+#: entryeditdialog.cpp:488
+msgid "Sa&ve Entries"
+msgstr "&Зберегти записи"
+
+#: entryeditdialog.cpp:656
+msgid ""
+"The current entry has been modified.\n"
+"Do you want to enter the changes?"
+msgstr ""
+"Поточні записи були змінені.\n"
+"Ви хочете зберегти зміни?"
+
+#: entryeditdialog.cpp:659
+msgid "Save Entry"
+msgstr "Зберегти запис"
+
+#: reportdialog.cpp:53
+msgid "Collection Report"
+msgstr "Звіт зібрання"
+
+#: reportdialog.cpp:60
+msgid "&Report template:"
+msgstr "&Шаблон звіту:"
+
+#: reportdialog.cpp:83
+msgid "&Generate"
+msgstr "&Створити"
+
+#: reportdialog.cpp:107
+msgid "Select a report template and click <em>Generate</em>."
+msgstr ""
+"Виберіть шаблон звіту та натисніть "
+"<em>Створити</em>"
+
+#: reportdialog.cpp:108
+msgid ""
+"Some reports may take several seconds to generate for large collections."
+msgstr ""
+"Створення звітів великих зібрань може "
+"зайняти декілька десятків секунд."
+
+#: tellico_kernel.cpp:285
+msgid "Do you really want to delete this filter?"
+msgstr "Ви дійсно хочете видалити цей фільтр?"
+
+#: tellico_kernel.cpp:287
+msgid "Delete Filter?"
+msgstr "Видалити фільтр?"
+
+#: tellico_kernel.cpp:323
+msgid "New collection name:"
+msgstr "Нова назва зібрання:"
+
+#: tellico_kernel.cpp:377
+#, fuzzy
+msgid "Entry 1"
+msgstr "Тип запису"
+
+#: tellico_kernel.cpp:378
+#, fuzzy
+msgid "Entry 2"
+msgstr "Тип запису"
+
+#: tellico_kernel.cpp:387
+msgid "Conflicting values for %1 were found while merging entries."
+msgstr ""
+
+#: tellico_kernel.cpp:393
+msgid "Please choose which value to keep."
+msgstr ""
+
+#: entrymerger.cpp:33 tellico_kernel.cpp:398
+#, fuzzy
+msgid "Merge Entries"
+msgstr "Вилучити записи"
+
+#: tellico_kernel.cpp:399 tellico_kernel.cpp:400
+#, c-format
+msgid "Select value from %1"
+msgstr ""
+
+#: entryview.cpp:186
+msgid "Tellico is unable to locate the default entry stylesheet."
+msgstr ""
+"Tellico не вдається встановити розташування "
+"умовчальної таблиці стилів записів."
+
+#: rc.cpp:6
+#, no-c-format
+msgid "&New"
+msgstr "&Новий"
+
+#: rc.cpp:15
+#, no-c-format
+msgid "&Collection"
+msgstr "&Зібрання"
+
+#: rc.cpp:24
+#, no-c-format
+msgid "Collection Toolbar"
+msgstr "Панель зібрання"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Сергій Дубик"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "dubyk@library.lviv.ua"
+
+#: entrymerger.cpp:35
+#, fuzzy
+msgid "Merging entries..."
+msgstr "&Оновлення записів..."
+
+#: entrymerger.cpp:49
+#, fuzzy
+msgid "Total merged/scanned entries: %1/%2"
+msgstr "Всього записів: %1"
+
+#: tips.cpp:3
+msgid ""
+"<p>...that if a book has more than one author, you should separate\n"
+"their names by a semi-colon, so that Tellico will know how to split them\n"
+"and use them separately.</p>\n"
+"<p>Any other field which allows multiple values should be entered the\n"
+"same way, with a semi-colon (;) separating each value.</p>\n"
+msgstr ""
+"<p>...що якщо книга має більше, аніж одного "
+"автора, то Вам слід розділяти\n"
+"крапкою з комою (;). У такий спосіб Tellico "
+"розділятиме їх та використовуватиме "
+"окремо.</p>\n"
+"<p>Будь-яке інше поле також підтримує цю "
+"функцію. Для цього вам слід\n"
+"розділяти кожні значення крапкою з комою "
+"(;).\n"
+"Наприклад: Токарчук;Мриглод.</p>\n"
+
+#: tips.cpp:11
+msgid ""
+"<p>...that you can change which fields are shown in the list view by\n"
+"right-clicking on the column header.\n"
+msgstr ""
+"<p>...що Ви можете вибрати які поля слід "
+"показувати у списку записів,\n"
+"клацнувши правою кнопкою миші на "
+"заголовку \"таблиці\".\n"
+
+#: tips.cpp:16
+msgid ""
+"<p>...that you can add, edit, or modify the fields in the collection using\n"
+"the Field Editor. The arrow buttons below the field list can be used to "
+"change the\n"
+"position of the field in the list, which affects the placement in the entry\n"
+"editor.</p>\n"
+msgstr ""
+"<p>...що Ви можете додавати, редагувати або "
+"видаляти поля у зібранні,\n"
+"використовуючи редактор полів. Кнопки "
+"стрілок дозволяють Вам міняти позицію "
+"полів у списку,\n"
+"яка впливає на розстановку у редакторові "
+"записів.</p>\n"
+
+#: tips.cpp:23
+msgid ""
+"<p>...that if you want to filter by a Checkbox field, a value of\n"
+"\"true\" should be used. If you'd like to filter to\n"
+"show only the science fiction books which you've not read, for\n"
+"example, check the <em>Match all of the\n"
+"following</em> button, set the first rule to have \"Genre\"\n"
+"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
+"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
+msgstr ""
+"<p>...що якщо Ви хочете відфільтрувати "
+"записи за полем \"Вибір так/ні\",\n"
+"то повинне використовуватися значення "
+"\"так\". Наприклад, якщо Ви хочете "
+"подивитися, які детективи Ви ще не "
+"читали,\n"
+"натисніть кнопку \"Відповідає всьому "
+"наступному\",\n"
+"встановіть перше правило на \"Жанр\"\n"
+"\"містить\" \"Детектив\" (без лапок) і друге "
+"правило на \"Прочитана\" \"Не містить\" "
+"\"Так\" (без лапок).</p>\n"
+
+#: tips.cpp:33
+msgid ""
+"<p>...that if a non-word character is used in the Quick Filter, the text is\n"
+"interpreted as a regular expression.</p>\n"
+"<p>To show only books which are by Weber or Bujold, for example, then\n"
+"type \"weber|bujold\" (no quotes) in the filter box.</p>\n"
+msgstr ""
+"<p>...що якщо у швидкому фільтрі "
+"використовується символ, що не входить у "
+"слова (напр., ^)\n"
+"то текст інтерпретується як регулярний "
+"вираз.</p>\n"
+"<p>Наприклад, щоб подивитися лише книги, "
+"які написали Франко та Сковорода,\n"
+"введіть \"Франко|Сковорода\" (без лапок) у "
+"полі швидкого фільтру.</p>\n"
+
+#: tips.cpp:40
+msgid ""
+"<p>...that you can edit more than one entry at a time, by holding down\n"
+"the Shift or Ctrl key and selecting multiple entries.</p>\n"
+msgstr ""
+"<p>...що за один раз Ви можете редагувати "
+"більше, ніж одне поле.\n"
+"Для цього відзначте декілька полів, "
+"тримаючи клавіші Shift або Ctrl.</p>\n"
+
+#: tips.cpp:45
+msgid ""
+"<p>...that you can convert an existing book collection to a bibliography,\n"
+"which can then be exported to bibtex or Bibtexml format.</p>\n"
+msgstr ""
+"<p>...що Ви можете конвертувати поточне "
+"зібрання книг у бібліографію,\n"
+"яка може бути експортована у формат Bibtex "
+"або Bibtexml.</p>\n"
+
+#: tips.cpp:50
+msgid ""
+"<p>...that you can add, edit, and delete string macros for "
+"bibliographies.</p>\n"
+msgstr ""
+"<p>...що Ви можете додавати, редагувати та "
+"видаляти стрічкові макроси для "
+"бібліографії.</p>\n"
+
+#: tips.cpp:54
+msgid ""
+"<p>...that if more than one field is formatted as a name, then an "
+"additional\n"
+"group named \"People\" is added to the collection, allowing authors and "
+"editors\n"
+"to be sorted or printed together, for example.</p>\n"
+msgstr ""
+"<p>...що якщо більш ніж одне поле "
+"форматується як \"ім'я\", то у зібрання\n"
+"додається додаткова група \"Люди\", "
+"наприклад, для сортування та друку "
+"разом.</p>\n"
+
+#: tips.cpp:60
+msgid ""
+"<p>...that you can modify the appearance of the printed output by modifying\n"
+"the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the "
+"CSS\n"
+"within the stylesheet governs things like the font, the margins, etc.</p>\n"
+msgstr ""
+"<p>...що Ви можете міняти зовнішній вигляд "
+"друкованих звітів, редагуючи\n"
+"файл <tt>tellico-printing.xsl</tt>. Цей файл створює HTML "
+"та CSS\n"
+"з такими елементами як шрифт, розмір і "
+"т.п.</p>\n"
+
+#: tips.cpp:66
+msgid ""
+"<p>...that you can import using any generic XSL stylesheet which\n"
+"outputs a valid Tellico XML file.</p>\n"
+msgstr ""
+"<p>...що Ви можете імпортувати, "
+"використовуючи будь-яку стандартну\n"
+"таблицю стилів XSL, на виході отримуючи "
+"правильний файл Tellico XML.</p>\n"
+
+#: tips.cpp:71
+msgid "<p>...that double-clicking an entry item opens the Entry Editor.</p>\n"
+msgstr ""
+"<p>...що подвійне клацання на записі "
+"відкриває редактор записів.</p>\n"
+
+#: tips.cpp:75
+msgid ""
+"<p>...that you can add HTML tags to any Paragraph field for formatting, such "
+"as\n"
+"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
+msgstr ""
+"<p>...що в будь-яке поле типу \"Великий "
+"текст\" Ви можете додавати теги HTML, такі як "
+"\n"
+"&lt;b&gt;жирний шрифт&lt;/b&gt; или "
+"&lt;i&gt;курсивний&lt;/i&gt;.</p>\n"
+
+#: tips.cpp:80
+msgid ""
+"<p>...that in the Detailed View, you can press a letter on the\n"
+"keyboard to skip to the next entry that starts with that letter.</p>\n"
+msgstr ""
+"<p>...що в докладному вигляді Ви можете "
+"натиснути кнопку букви на клавіатурі для\n"
+"переходу до запису, що починається з цієї "
+"букви.</p>\n"
+
+#: tips.cpp:85
+msgid ""
+"<p>...that you can use Dependent Fields to combine multiple separated "
+"fields\n"
+"into a single field. Just select the type Dependent and use a description\n"
+"similar to \"Value: %{fielda}%{fieldb}\" where %{...} gets replaced with "
+"the\n"
+"appropriate field value. This is useful to collect multiple values in a\n"
+"single field, e.g. for better grouping, and to combine fields of different\n"
+"types by respecting proper sorting at the same time. Consider for example\n"
+"a number field followed by a text subfield with entries 3b, 14a.</p>\n"
+msgstr ""
+"<p>...що Ви можете використовувати \"залежні "
+"поля\", щоб комбінувати множинні "
+"відокремлені поля\n"
+"у єдине полі. Просто виберіть тип "
+"\"залежність\" та використовуйте опис\n"
+"на зразок \"Значення: %{полеА}%{полеБ}\" де "
+"%{...} замінюється\n"
+"на відповідне значення поля. Це корисно, "
+"щоб зібрати множинні значення у\n"
+"єдине поле, наприклад для кращого "
+"угрупування, і, щоб комбінувати області "
+"різних\n"
+"типів поважаючи належне сортування в той "
+"же час. Розглянте, наприклад,\n"
+"поле номера що завершується текстовим "
+"підполем зі значеннями 3b, 14a.</p>\n"
+
+#: xslt.cpp:2
+msgid ""
+"_: Album XSL Template\n"
+"Album"
+msgstr "Альбом"
+
+#: xslt.cpp:3
+msgid "This template is meant for music collections only."
+msgstr ""
+"Цей шаблон призначений лише за музичних "
+"зібрань."
+
+#: xslt.cpp:5
+msgid "Total:"
+msgstr "&Всього:"
+
+#: xslt.cpp:7
+msgid ""
+"_: Fancy XSL Template\n"
+"Fancy"
+msgstr "Звичайний"
+
+#: xslt.cpp:9
+msgid ""
+"_: Default XSL Template\n"
+"Default"
+msgstr "За умовчанням"
+
+#: xslt.cpp:11
+msgid ""
+"_: Compact XSL Template\n"
+"Compact"
+msgstr "Компактний"
+
+#: xslt.cpp:13
+msgid ""
+"_: Video XSL Template\n"
+"Video"
+msgstr "Відео"
+
+#: xslt.cpp:14 xslt.cpp:43
+msgid "This template is meant for video collections only."
+msgstr ""
+"Цей шаблон призначений тільки для "
+"зібрань фільмів."
+
+#: xslt.cpp:16
+msgid ""
+"_: Group Summary XSL Template\n"
+"Group Summary"
+msgstr "Всього в групі"
+
+#: xslt.cpp:17
+msgid ": Group Summary"
+msgstr ": Всього в групі"
+
+#: xslt.cpp:18
+msgid "Total number of fields:"
+msgstr "Всього полів:"
+
+#: xslt.cpp:19
+msgid "Total number of entries:"
+msgstr "Всього записів:"
+
+#: xslt.cpp:20 xslt.cpp:32 xslt.cpp:46
+msgid "Generated by Tellico"
+msgstr "Створений в Tellico"
+
+#: xslt.cpp:21
+msgid "Distinct values: "
+msgstr "Точні значення:"
+
+#: xslt.cpp:23
+msgid ""
+"_: Image List XSL Template\n"
+"Image List"
+msgstr "Список изображений"
+
+#: xslt.cpp:25
+msgid ""
+"_: Loan View XSL Template\n"
+"Loan View"
+msgstr "Борги"
+
+#: xslt.cpp:27 xslt.cpp:29
+msgid "Loan Date"
+msgstr "Дата дачі у борг"
+
+#: xslt.cpp:28 xslt.cpp:31
+msgid "Note"
+msgstr "Замітки"
+
+#: xslt.cpp:30
+msgid "Due Date"
+msgstr "Дата закінчення боргу:"
+
+#: xslt.cpp:34
+msgid ""
+"_: Group View XSL Template\n"
+"Group View"
+msgstr "Групи"
+
+#: xslt.cpp:36
+msgid ""
+"_: Title Listing (Horizontal) XSL Template\n"
+"Title Listing (Horizontal)"
+msgstr "Список назв (горизонтальний)"
+
+#: xslt.cpp:38
+msgid ""
+"_: Title Listing (Vertical) XSL Template\n"
+"Title Listing (Vertical)"
+msgstr "Список назв (вертикальний)"
+
+#: xslt.cpp:40
+msgid ""
+"_: Column View XSL Template\n"
+"Column View"
+msgstr "Стовпці"
+
+#: xslt.cpp:42
+msgid ""
+"_: Tri-Column XSL Template\n"
+"Tri-Column"
+msgstr "У три стовпці"
+
+#: xslt.cpp:44
+msgid "Search"
+msgstr "Пошук"
+
+#: z3950.cpp:4
+msgid "The British Library"
+msgstr "Британська Бібліотека"
+
+#: z3950.cpp:6
+msgid "Sudoc (France)"
+msgstr "Sudoc (Франція)"
+
+#: z3950.cpp:8
+msgid "BIBSYS (Norway)"
+msgstr "BIBSYS (Норвегія)"
+
+#: z3950.cpp:10
+msgid "Italian National Library"
+msgstr "Італійська Національна Бібліотека"
+
+#: z3950.cpp:12
+msgid "Portuguese National Library"
+msgstr "Португальська Національна Бібліотека"
+
+#: z3950.cpp:14
+msgid "National Library of Poland"
+msgstr "Національна Бібліотека Польщі"
+
+#: z3950.cpp:16
+msgid "National Library of Canada"
+msgstr "Національна Бібліотека Канади"
+
+#: z3950.cpp:18
+msgid "Israel Union List"
+msgstr "Ізраїльський Об'єднаний Список"
+
+#: z3950.cpp:20
+msgid "National Library of Australia"
+msgstr "Національна Бібліотека Австралії"
+
+#: z3950.cpp:22
+msgid "National Library of Lithuania"
+msgstr "Національна Бібліотека Литви"
+
+#: z3950.cpp:24
+msgid "Copac (UK and Ireland)"
+msgstr "Copac (Великобританія та Ірландія)"
+
+#: scripts.cpp:2
+msgid "BoardGameGeek"
+msgstr ""
+
+#: scripts.cpp:4
+msgid "Dark Horse Comics"
+msgstr "Комікси Темного Коня "
+
+#: scripts.cpp:6
+msgid "Allocine.fr"
+msgstr "Allocine.fr"
+
+#: scripts.cpp:8
+msgid "Spanish Ministry of Culture"
+msgstr "Міністерство культури Іспанії"
+
+#, fuzzy
+#~ msgid "CrossRef"
+#~ msgstr "Рекомендації"
+
+#~ msgid "MODS"
+#~ msgstr "MODS"
+
+#~ msgid "RIS"
+#~ msgstr "RIS"
+
+#~ msgid "GCstar"
+#~ msgstr "GCstar"
+
+#~ msgid "AMC"
+#~ msgstr "AMC"
+
+#, fuzzy
+#~ msgid "Griffith"
+#~ msgstr "Дарований"
+
+#, fuzzy
+#~ msgid "Referencer"
+#~ msgstr "Рекомендації"
+
+#~ msgid "Comics"
+#~ msgstr "Комікси"
+
+#~ msgid "Stamps"
+#~ msgstr "Марки"
+
+#~ msgid "Coins"
+#~ msgstr "Монети"
+
+#~ msgid "Books"
+#~ msgstr "Книги"
+
+#~ msgid "Wines"
+#~ msgstr "Вина"
+
+#~ msgid "Videos"
+#~ msgstr "Відео"
+
+#~ msgid "Games"
+#~ msgstr "Ігри"
+
+#~ msgid "Cards"
+#~ msgstr "Карти"
+
+#~ msgid "Entries"
+#~ msgstr "Записи"
+
+#~ msgid "Albums"
+#~ msgstr "Альбоми"
+
+#~ msgid ""
+#~ "If checked, all images will be included in the data file, rather than saved "
+#~ "separately in the Tellico data directory. Saving a lot of images in the data "
+#~ "file cause Tellico to run more slowly."
+#~ msgstr ""
+#~ "Якщо відмічено, то зображення "
+#~ "зберігатимуться у файлі даних Tellico, "
+#~ "інакше вони зберігатимуться окремо у "
+#~ "теці даних. Збереження великого числа "
+#~ "зображень у файлі може сповільнити "
+#~ "роботу Tellico."
+
+#, fuzzy
+#~ msgid "Copac"
+#~ msgstr "Запятая"
+
+#~ msgid "Tellico"
+#~ msgstr "Tellico"
+
+#~ msgid "&Copy Entry"
+#~ msgstr "&Копировать запись"
+
+#~ msgid "&Copy Entries"
+#~ msgstr "&Копировать записи..."
+
+#~ msgid "<qt>Multiple records were found to match the CD.</qt>"
+#~ msgstr ""
+#~ "<qt>Найдено несколько записей по вашему "
+#~ "запросу.</qt>"
+
+#~ msgid "Remo&ve"
+#~ msgstr "&Удалить"
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..8ffd5e4
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,140 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+bin_PROGRAMS = tellico
+
+tellico_SOURCES = borrower.cpp borrowerdialog.cpp \
+ borroweritem.cpp calendarhandler.cpp collection.cpp collectionfactory.cpp \
+ collectionfieldsdialog.cpp configdialog.cpp controller.cpp detailedentryitem.cpp \
+ detailedlistview.cpp document.cpp entry.cpp entryeditdialog.cpp entrygroupitem.cpp \
+ entryiconfactory.cpp entryiconview.cpp entryitem.cpp entrymerger.cpp entryupdater.cpp \
+ entryview.cpp exportdialog.cpp fetchdialog.cpp fetcherconfigdialog.cpp field.cpp \
+ fieldcompletion.cpp filehandler.cpp filter.cpp filterdialog.cpp filteritem.cpp \
+ filterview.cpp groupiterator.cpp groupview.cpp image.cpp imagefactory.cpp \
+ importdialog.cpp isbnvalidator.cpp iso5426converter.cpp iso6937converter.cpp \
+ listviewcomparison.cpp loandialog.cpp loanitem.cpp loanview.cpp main.cpp mainwindow.cpp \
+ progressmanager.cpp reportdialog.cpp statusbar.cpp tellico_kernel.cpp tellico_strings.cpp \
+ tellico_utils.cpp upcvalidator.cpp viewstack.cpp xmphandler.cpp lccnvalidator.cpp
+
+if !USE_LIBBTPARSE
+ LDADD_LIBBTPARSE = ./translators/btparse/libbtparse.a
+endif
+
+if ENABLE_WEBCAM
+ WEBCAMDIR = barcode
+ LDADD_LIBBARCODE = ./barcode/libbarcode.a
+endif
+SUBDIRS = core gui collections translators fetch tests commands \
+ cite newstuff rtf2html $(WEBCAMDIR)
+
+tellico_LDADD = ./core/libcore.a ./cite/libcite.a ./fetch/libfetch.a \
+ ./collections/libcollections.a ./translators/libtranslators.a \
+ ./newstuff/libnewstuff.a ./translators/pilotdb/libpilotdb.a \
+ ./translators/pilotdb/libflatfile/liblibflatfile.a ./gui/libgui.a \
+ ./translators/pilotdb/libpalm/liblibpalm.a ./rtf2html/librtf2html.a \
+ ./commands/libcommands.a -lexslt $(LIB_KFILE) $(LIB_KHTML) $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_QT) \
+ $(LIBSOCKET) $(LIBXSLT_LIBS) $(TAGLIB_LIBS) $(KCDDB_LIBS) $(YAZ_LIBS) $(LIB_KIO) \
+ $(LIB_KABC) $(KCAL_LIBS) $(LDADD_LIBBTPARSE) $(LIB_KNEWSTUFF) $(EXEMPI_LIBS) \
+ $(POPPLER_LIBS) $(LDADD_LIBBARCODE)
+
+EXTRA_DIST = tellicoui.rc tellicorc \
+borrowerdialog.cpp entryiconview.h\
+borrowerdialog.h entryitem.cpp importdialog.cpp \
+borrower.h entryitem.h importdialog.h \
+borroweritem.cpp entryview.cpp isbnvalidator.cpp \
+borroweritem.h entryview.h isbnvalidator.h \
+loanview.cpp exportdialog.cpp \
+loanview.h exportdialog.h \
+collection.cpp fetchdialog.cpp \
+collectionfactory.cpp fetchdialog.h \
+collectionfactory.h fieldcompletion.cpp latin1literal.h \
+collectionfieldsdialog.h collectionfieldsdialog.cpp fieldcompletion.h \
+collection.h field.h main.cpp \
+configdialog.cpp mainwindow.cpp \
+configdialog.h mainwindow.h \
+controller.cpp filehandler.cpp \
+controller.h filehandler.h \
+filter.cpp filterdialog.cpp \
+filterdialog.h reportdialog.cpp \
+filter.h reportdialog.h \
+filteritem.cpp \
+filteritem.h \
+detailedlistview.h detailedlistview.cpp \
+document.cpp tellico_kernel.cpp \
+document.h tellico_kernel.h \
+entry.cpp groupview.cpp tellico_strings.cpp \
+entryeditdialog.cpp groupview.h tellico_strings.h \
+entryeditdialog.h image.cpp tellico_utils.cpp \
+entrygroupitem.cpp imagefactory.cpp tellico_utils.h \
+entrygroupitem.h imagefactory.h viewstack.cpp \
+entry.h image.h viewstack.h \
+entryiconview.cpp loandialog.h \
+loandialog.cpp ptrvector.h borrower.cpp datavectors.h \
+calendarhandler.h calendarhandler.cpp \
+loanitem.h loanitem.cpp groupiterator.h groupiterator.cpp \
+stringset.h observer.h filterview.h filterview.cpp \
+entryiconfactory.h entryiconfactory.cpp \
+tellico_debug.h \
+entryupdater.h entryupdater.cpp \
+detailedentryitem.h detailedentryitem.cpp \
+statusbar.h statusbar.cpp \
+progressmanager.h progressmanager.cpp \
+upcvalidator.h upcvalidator.cpp \
+fetcherconfigdialog.h fetcherconfigdialog.cpp \
+iso5426converter.h iso5426converter.cpp \
+iso6937converter.h iso6937converter.cpp \
+tellico_map.h \
+listviewcomparison.h listviewcomparison.cpp \
+entrymerger.h entrymerger.cpp \
+xmphandler.h xmphandler.cpp \
+lccnvalidator.h lccnvalidator.cpp
+
+####### kdevelop will overwrite this part!!! (end)############
+# These paths are KDE specific. Use them:
+# kde_appsdir Where your application's menu entry (.desktop) should go to.
+# kde_icondir Where your icon should go to - better use KDE_ICON.
+# kde_sounddir Where your sounds should go to.
+# kde_htmldir Where your docs should go to. (contains lang subdirs)
+# kde_datadir Where you install application data. (Use a subdir)
+# kde_locale Where translation files should go to. (contains lang subdirs)
+# kde_cgidir Where cgi-bin executables should go to.
+# kde_confdir Where config files should go to (system-wide ones with default values).
+# kde_mimedir Where mimetypes .desktop files should go to.
+# kde_servicesdir Where services .desktop files should go to.
+# kde_servicetypesdir Where servicetypes .desktop files should go to.
+# kde_toolbardir Where general toolbar icons should go to (deprecated, use KDE_ICON).
+# kde_wallpaperdir Where general wallpapers should go to.
+# kde_templatesdir Where templates for the "New" menu (Konqueror/KDesktop) should go to.
+# kde_bindir Where executables should go to. Use bin_PROGRAMS or bin_SCRIPTS.
+# kde_libdir Where shared libraries should go to. Use lib_LTLIBRARIES.
+# kde_moduledir Where modules (e.g. parts) should go to. Use kde_module_LTLIBRARIES.
+# kde_styledir Where Qt/KDE widget styles should go to (new in KDE 3).
+# kde_designerdir Where Qt Designer plugins should go to (new in KDE 3).
+
+# set the include path for X, qt and KDE
+AM_CPPFLAGS = $(all_includes) \
+ $(LIBXML_CFLAGS) \
+ $(LIBXSLT_CFLAGS) \
+ $(EXEMPI_CFLAGS)
+
+METASOURCES = AUTO
+
+KDE_OPTIONS = noautodist
+
+CLEANFILES = *~ *.loT
+
+# the library search path.
+tellico_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+uidir = $(kde_datadir)/tellico
+ui_DATA = tellicoui.rc
+
+rcdir = $(kde_confdir)
+rc_DATA = tellicorc
+
+messages: rc.cpp
+ @ touch $(podir)/tellico.pot;
+ LIST=`find . -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \
+ if test -n "$$LIST"; then \
+ $(XGETTEXT) --join-existing --add-comments="TRANSLATORS:" $$LIST -o $(podir)/tellico.pot; \
+ fi
+
+#include ../admin/Doxyfile.am
diff --git a/src/barcode/Makefile.am b/src/barcode/Makefile.am
new file mode 100644
index 0000000..df8f8e2
--- /dev/null
+++ b/src/barcode/Makefile.am
@@ -0,0 +1,14 @@
+AM_CPPFLAGS = $(all_includes)
+
+noinst_LIBRARIES = libbarcode.a
+libbarcode_a_SOURCES = barcode.cpp barcode_v4l.cpp
+
+libbarcode_a_METASOURCES = AUTO
+
+KDE_OPTIONS = noautodist
+
+EXTRA_DIST = \
+barcode.h barcode.cpp \
+barcode_v4l.h barcode_v4l.cpp
+
+CLEANFILES = *~ *.loT
diff --git a/src/barcode/barcode.cpp b/src/barcode/barcode.cpp
new file mode 100644
index 0000000..2427f4e
--- /dev/null
+++ b/src/barcode/barcode.cpp
@@ -0,0 +1,877 @@
+/***************************************************************************
+ copyright : (C) 2007 by Sebastian Held
+ email : sebastian.held@gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * ### based on BaToo: http://people.inf.ethz.ch/adelmanr/batoo/ ### *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+// includes code from http://v4l2spec.bytesex.org/spec/a16323.htm
+
+#include <qimage.h>
+#include <qmutex.h>
+#include "barcode.h"
+
+#include <stdlib.h>
+
+using barcodeRecognition::barcodeRecognitionThread;
+using barcodeRecognition::Barcode_EAN13;
+using barcodeRecognition::Decoder_EAN13;
+using barcodeRecognition::MatchMakerResult;
+
+barcodeRecognitionThread::barcodeRecognitionThread()
+{
+ m_stop = false;
+ m_barcode_v4l = new barcode_v4l();
+}
+barcodeRecognitionThread::~barcodeRecognitionThread()
+{
+ delete m_barcode_v4l;
+}
+
+bool barcodeRecognitionThread::isWebcamAvailable()
+{
+ return m_barcode_v4l->isOpen();
+}
+
+void barcodeRecognitionThread::run()
+{
+ bool stop;
+ m_stop_mutex.lock();
+ stop = m_stop;
+ m_stop_mutex.unlock();
+
+ if (!isWebcamAvailable())
+ stop = true;
+
+ Barcode_EAN13 old;
+ while (!stop) {
+ QImage img;
+ m_barcode_img_mutex.lock();
+ if (m_barcode_img.isNull())
+ img = m_barcode_v4l->grab_one2();
+ else {
+ img = m_barcode_img;
+ m_barcode_img = QImage();
+ }
+ m_barcode_img_mutex.unlock();
+
+// //DEBUG
+// img.load( "/home/sebastian/black.png" );
+// m_stop = true;
+// //DEBUG
+
+ if (!img.isNull()) {
+ QImage preview = img.scale( 320, 240, QImage::ScaleMin );
+ emit gotImage( preview );
+ Barcode_EAN13 barcode = recognize( img );
+ if (barcode.isValid() && (old != barcode)) {
+ emit recognized( barcode.toString() );
+ old = barcode;
+ }
+ }
+ msleep( 10 ); // reduce load
+
+ m_stop_mutex.lock();
+ stop = m_stop;
+ m_stop_mutex.unlock();
+ }
+}
+
+void barcodeRecognitionThread::stop()
+{
+ // attention! This function is called from GUI context
+ m_stop_mutex.lock();
+ m_stop = true;
+ m_stop_mutex.unlock();
+}
+
+
+void barcodeRecognitionThread::recognizeBarcode( QImage img )
+{
+ // attention! This function is called from GUI context
+ m_barcode_img_mutex.lock();
+ m_barcode_img = img;
+ m_barcode_img_mutex.unlock();
+}
+
+Barcode_EAN13 barcodeRecognitionThread::recognize( QImage img )
+{
+ // PARAMETERS:
+ int amount_scanlines = 30;
+ int w = img.width();
+ int h = img.height();
+
+ // the array which will contain the result:
+ QValueVector< QValueVector<int> > numbers( amount_scanlines, QValueVector<int>(13,-1) ); // no init in java source!!!!!!!!!
+
+ // generate and initialize the array that will contain all detected
+ // digits at a specific code position:
+ int possible_numbers[10][13][2];
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 13; j++) {
+ possible_numbers[i][j][0] = -1;
+ possible_numbers[i][j][1] = 0;
+ }
+ }
+
+ int successfull_lines = 0;
+
+ // try to detect the barcode along scanlines:
+ for (int i = 0; i < amount_scanlines; i++) {
+ int x1 = 0;
+ int y = (h / amount_scanlines) * i;
+ int x2 = w - 1;
+
+ // try to recognize a barcode along that path:
+ Barcode_EAN13 ean13_code = recognizeCode( img, x1, x2, y );
+ numbers[i] = ean13_code.getNumbers();
+
+ if (ean13_code.isValid()) {
+ successfull_lines++;
+ // add the recognized digits to the array of possible numbers:
+ addNumberToPossibleNumbers( numbers[i], possible_numbers, true );
+ } else {
+ numbers[i] = ean13_code.getNumbers();
+ // add the recognized digits to the array of possible numbers:
+ addNumberToPossibleNumbers(numbers[i], possible_numbers, false);
+ }
+
+#ifdef BarcodeDecoder_DEBUG
+ // show the information that has been recognized along the scanline:
+ qDebug( "Scanline %i result: %s\n", i, ean13_code.toString().latin1() );
+#endif
+ }
+
+ // sort the detected digits at each code position, in accordance to the
+ // amount of their detection:
+ sortDigits(possible_numbers);
+
+#ifdef BarcodeDecoder_DEBUG
+ fprintf( stderr, "detected digits:\n" );
+ printArray( possible_numbers, 0 );
+ fprintf( stderr, "# of their occurence:\n" );
+ printArray( possible_numbers, 1 );
+#endif
+
+ // get the most likely barcode:
+ Barcode_EAN13 code = extractBarcode(possible_numbers);
+
+ return code;
+}
+
+void barcodeRecognitionThread::printArray( int array[10][13][2], int level )
+{
+ for (int i = 0; i < 10; i++) {
+ QCString temp;
+ temp.setNum( i );
+ fprintf( stderr, temp + " : " );
+ for (int j = 0; j < 13; j++) {
+ if (array[i][j][level] == -1)
+ fprintf( stderr, "x " );
+ else {
+ QCString temp;
+ temp.setNum( array[i][j][level] );
+ fprintf( stderr, temp + " " );
+ }
+ }
+ fprintf( stderr, "\n" );
+ }
+}
+
+barcodeRecognition::Barcode_EAN13 barcodeRecognitionThread::recognizeCode( QImage img, int x1, int x2, int y )
+{
+ QValueVector<QRgb> raw_path(x2-x1+1);
+ for (int x=x1; x<=x2; x++)
+ raw_path[x-x1] = img.pixel(x,y);
+ // convert the given path into a string of black and white pixels:
+ QValueVector<int> string = transformPathToBW( raw_path );
+
+ // convert the string of black&white pixels into a list, containing
+ // information about the black and white fields
+ // first indes = field nr.
+ // second index: 0 = color of the field
+ // 1 = field length
+ QValueVector< QValueVector<int> > fields = extractFieldInformation( string );
+
+ // try to recognize a EAN13 code:
+ Barcode_EAN13 barcode = Decoder_EAN13::recognize( fields );
+
+ return barcode;
+}
+
+void barcodeRecognitionThread::addNumberToPossibleNumbers( QValueVector<int> number, int possible_numbers[10][13][2], bool correct_code )
+{
+ int i;
+ bool digit_contained;
+ for (int j = 0; j < 13; j++) {
+ if (number[j] >= 0) {
+ i = 0;
+ digit_contained = false;
+ while ((i < 10) && (possible_numbers[i][j][0] >= 0)) {
+ if (possible_numbers[i][j][0] == number[j]) {
+ digit_contained = true;
+ if (correct_code)
+ possible_numbers[i][j][1] = possible_numbers[i][j][1] + 100;
+ else
+ possible_numbers[i][j][1]++;
+ break;
+ }
+ i++;
+ }
+ if ((i < 10) && (!digit_contained)) {
+ // add new digit:
+ possible_numbers[i][j][0] = number[j];
+ if (correct_code)
+ possible_numbers[i][j][1] = possible_numbers[i][j][1] + 100;
+ else
+ possible_numbers[i][j][1]++;
+ }
+ }
+ }
+}
+
+void barcodeRecognitionThread::sortDigits( int possible_numbers[10][13][2] )
+{
+ int i;
+ int temp_value;
+ int temp_occurence;
+ bool changes;
+
+ for (int j = 0; j < 13; j++) {
+ i = 1;
+ changes = false;
+ while (true) {
+ if ((possible_numbers[i - 1][j][0] >= 0) && (possible_numbers[i][j][0] >= 0)) {
+ if (possible_numbers[i - 1][j][1] < possible_numbers[i][j][1]) {
+ temp_value = possible_numbers[i - 1][j][0];
+ temp_occurence = possible_numbers[i - 1][j][1];
+ possible_numbers[i - 1][j][0] = possible_numbers[i][j][0];
+ possible_numbers[i - 1][j][1] = possible_numbers[i][j][1];
+ possible_numbers[i][j][0] = temp_value;
+ possible_numbers[i][j][1] = temp_occurence;
+
+ changes = true;
+ }
+ }
+
+ if ((possible_numbers[i][j][0] < 0) || (i >= 9)) {
+ if (!changes)
+ break;
+ else {
+ i = 1;
+ changes = false;
+ }
+ } else
+ i++;
+ }
+ }
+}
+
+Barcode_EAN13 barcodeRecognitionThread::extractBarcode( int possible_numbers[10][13][2] )
+{
+ // create and initialize the temporary variables:
+ QValueVector<int> temp_code(13);
+ for (int i = 0; i < 13; i++)
+ temp_code[i] = possible_numbers[0][i][0];
+
+#ifdef Barcode_DEBUG
+ fprintf( stderr, "barcodeRecognitionThread::extractBarcode(): " );
+ for (int i=0; i<13; i++)
+ fprintf( stderr, "%i", temp_code[i] );
+ fprintf( stderr, "\n" );
+#endif
+
+ return Barcode_EAN13(temp_code);
+}
+
+Barcode_EAN13 barcodeRecognitionThread::detectValidBarcode ( int possible_numbers[10][13][2], int max_amount_of_considered_codes )
+{
+ // create and initialize the temporary variables:
+ QValueVector<int> temp_code(13);
+ for ( int i = 0; i < 13; i++ )
+ temp_code[i] = possible_numbers[0][i][0];
+
+ int alternative_amount = 0;
+
+ QValueVector<int> counter( 13 ); // no init in java source!!!
+ int counter_nr = 11;
+
+ // check if there is at least one complete code present:
+ for ( int i = 0; i < 13; i++ ) {
+ // exit and return the "most likely" code parts:
+ if ( temp_code[i] < 0 )
+ return Barcode_EAN13( temp_code );
+ }
+
+ // if there is at least one complete node, try to detect a valid barcode:
+ while ( alternative_amount < max_amount_of_considered_codes ) {
+ // fill the temporary code array with one possible version:
+ for ( int i = 0; i < 13; i++ )
+ temp_code[i] = possible_numbers[counter[i]][i][0];
+
+ alternative_amount++;
+
+ // check if this version represents a valid code:
+ if (isValid( temp_code ))
+ return Barcode_EAN13( temp_code );
+
+ // increment the counters:
+ if ( ( counter[counter_nr] < 9 ) && ( possible_numbers[counter[counter_nr] + 1][counter_nr][0] >= 0 ) ) {
+ // increment the actual counter.
+ counter[counter_nr]++;
+ } else {
+ // check if we have reached the end and no valid barcode has been found:
+ if ( counter_nr == 1 ) {
+ // exit and return the "most likely" code parts:
+ for ( int i = 0; i < 13; i++ )
+ temp_code[i] = possible_numbers[0][i][0];
+ return Barcode_EAN13( temp_code );
+ } else {
+ // reset the actual counter and increment the next one(s):
+ counter[counter_nr] = 0;
+
+ while ( true ) {
+ if ( counter_nr > 2 )
+ counter_nr--;
+ else {
+ for ( int i = 0; i < 13; i++ )
+ temp_code[i] = possible_numbers[0][i][0];
+ return Barcode_EAN13( temp_code );
+ }
+ if ( counter[counter_nr] < 9 ) {
+ counter[counter_nr]++;
+ if ( possible_numbers[counter[counter_nr]][counter_nr][0] < 0 )
+ counter[counter_nr] = 0;
+ else
+ break;
+ } else
+ counter[counter_nr] = 0;
+ }
+ counter_nr = 12;
+ }
+ }
+ }
+
+ for ( int i = 0; i < 13; i++ )
+ temp_code[i] = possible_numbers[0][i][0];
+ return Barcode_EAN13( temp_code );
+}
+
+bool barcodeRecognitionThread::isValid( int numbers[13] )
+{
+ QValueVector<int> temp(13);
+ for (int i=0; i<13; i++)
+ temp[i] = numbers[i];
+ return isValid( temp );
+}
+bool barcodeRecognitionThread::isValid( QValueVector<int> numbers )
+{
+ Q_ASSERT( numbers.count() == 13 );
+ // calculate the checksum of the barcode:
+ int sum1 = numbers[0] + numbers[2] + numbers[4] + numbers[6] + numbers[8] + numbers[10];
+ int sum2 = 3 * (numbers[1] + numbers[3] + numbers[5] + numbers[7] + numbers[9] + numbers[11]);
+ int checksum_value = sum1 + sum2;
+ int checksum_digit = 10 - (checksum_value % 10);
+ if (checksum_digit == 10)
+ checksum_digit = 0;
+
+#ifdef Barcode_DEBUG
+ fprintf( stderr, "barcodeRecognitionThread::isValid(): " );
+ for (int i=0; i<13; i++)
+ fprintf( stderr, "%i", numbers[i] );
+ fprintf( stderr, "\n" );
+#endif
+
+ return (numbers[12] == checksum_digit);
+}
+
+QValueVector<int> barcodeRecognitionThread::transformPathToBW( QValueVector<QRgb> line )
+{
+ int w = line.count();
+ QValueVector<int> bw_line(w,0);
+ bw_line[0] = 255;
+
+ // create greyscale values:
+ QValueVector<int> grey_line(w,0);
+ int average_illumination = 0;
+ for (int x = 0; x < w; x++) {
+ grey_line[x] = (qRed(line.at(x)) + qGreen(line.at(x)) + qBlue(line.at(x))) / 3;
+ average_illumination = average_illumination + grey_line[x];
+ }
+ average_illumination = average_illumination / w;
+
+ // perform the binarization:
+ int range = w / 20;
+
+ // temp values:
+ int moving_sum;
+ int moving_average;
+ int v1_index = -range + 1;
+ int v2_index = range;
+ int v1 = grey_line[0];
+ int v2 = grey_line[range];
+ int current_value;
+ int comparison_value;
+
+ // initialize the moving sum:
+ moving_sum = grey_line[0] * range;
+ for (int i = 0; i < range; i++)
+ moving_sum = moving_sum + grey_line[i];
+
+ // apply the adaptive thresholding algorithm:
+ for (int i = 1; i < w - 1; i++) {
+ if (v1_index > 0) v1 = grey_line[v1_index];
+ if (v2_index < w) v2 = grey_line[v2_index];
+ else v2 = grey_line[w - 1];
+ moving_sum = moving_sum - v1 + v2;
+ moving_average = moving_sum / (range << 1);
+ v1_index++;
+ v2_index++;
+
+ current_value = (grey_line[i - 1] + grey_line[i]) >> 1;
+
+ // decide if the current pixel should be black or white:
+ comparison_value = (3 * moving_average + average_illumination) >> 2;
+ if ((current_value < comparison_value - 3)) bw_line[i] = 0;
+ else bw_line[i] = 255;
+ }
+
+ // filter the values: (remove too small fields)
+
+ if (w >= 640) {
+ for (int x = 1; x < w - 1; x++) {
+ if ((bw_line[x] != bw_line[x - 1]) && (bw_line[x] != bw_line[x + 1])) bw_line[x] = bw_line[x - 1];
+ }
+ }
+
+ QValueVector<int> ret(w,0);
+ for (int i=0; i<w; i++)
+ ret[i] = bw_line[i];
+
+#ifdef Barcode_DEBUG
+ fprintf( stderr, "barcodeRecognitionThread::transformPathToBW(): " );
+ for (int i=0; i<ret.count(); i++)
+ if (bw_line[i] == 0)
+ fprintf( stderr, "0" );
+ else
+ fprintf( stderr, "#" );
+ fprintf( stderr, "\n" );
+#endif
+
+ return ret;
+}
+
+QValueVector< QValueVector<int> > barcodeRecognitionThread::extractFieldInformation( QValueVector<int> string )
+{
+ QValueVector< QValueVector<int> > temp_fields( string.count(), QValueVector<int>(2,0) );
+
+ if (string.count() == 0)
+ return QValueVector< QValueVector<int> >();
+
+ int field_counter = 0;
+ int last_value = string.at(0);
+ int last_fields = 1;
+ for (uint i = 1; i < string.size(); i++) {
+ if ((string.at(i) == last_value) && (i < string.size() - 1)) {
+ last_fields++;
+ } else {
+ // create new field entry:
+ temp_fields[field_counter][0] = last_value;
+ temp_fields[field_counter][1] = last_fields;
+
+ last_value = string.at(i);
+ last_fields = 0;
+ field_counter++;
+ }
+ }
+
+ temp_fields.resize( field_counter );
+
+#ifdef Barcode_DEBUG
+ fprintf( stderr, "barcodeRecognitionThread::extractFieldInformation(): " );
+ for (int i=0; i<temp_fields.count(); i++)
+ fprintf( stderr, "%i,%i ", temp_fields.at(i).at(0), temp_fields.at(i).at(1) );
+ fprintf( stderr, "\n" );
+#endif
+
+ return temp_fields;
+}
+
+//ok
+Barcode_EAN13::Barcode_EAN13()
+{
+ m_numbers.resize(13,-1);
+ m_null = true;
+}
+
+//ok
+Barcode_EAN13::Barcode_EAN13( QValueVector<int> code )
+{
+ setCode( code );
+}
+
+//ok
+void Barcode_EAN13::setCode( QValueVector<int> code )
+{
+ if (code.count() != 13) {
+ m_numbers.clear();
+ m_numbers.resize(13,-1);
+ m_null = true;
+ return;
+ }
+ m_numbers = code;
+ m_null = false;
+}
+
+//ok
+bool Barcode_EAN13::isValid() const
+{
+ if (m_null)
+ return false;
+
+ for (int i = 0; i < 13; i++)
+ if ((m_numbers[i] < 0) || (m_numbers[i] > 9))
+ return false;
+
+ // calculate the checksum of the barcode:
+ int sum1 = m_numbers[0] + m_numbers[2] + m_numbers[4] + m_numbers[6] + m_numbers[8] + m_numbers[10];
+ int sum2 = 3 * (m_numbers[1] + m_numbers[3] + m_numbers[5] + m_numbers[7] + m_numbers[9] + m_numbers[11]);
+ int checksum_value = sum1 + sum2;
+ int checksum_digit = 10 - (checksum_value % 10);
+ if (checksum_digit == 10)
+ checksum_digit = 0;
+
+ return (m_numbers[12] == checksum_digit);
+}
+
+//ok
+QValueVector<int> Barcode_EAN13::getNumbers() const
+{
+ return m_numbers;
+}
+
+//ok
+QString Barcode_EAN13::toString() const
+{
+ QString s;
+ for (int i = 0; i < 13; i++)
+ if ((m_numbers[i] >= 0) && (m_numbers[i] <= 9))
+ s += QString::number(m_numbers[i]);
+ else
+ s += '?';
+ return s;
+}
+
+//ok
+bool Barcode_EAN13::operator!= ( const Barcode_EAN13 &code )
+{
+ if (m_null != code.m_null)
+ return true;
+ if (!m_null)
+ for (int i=0; i<13; i++)
+ if (m_numbers[i] != code.m_numbers[i])
+ return true;
+ return false;
+}
+
+//ok
+Barcode_EAN13 Decoder_EAN13::recognize( QValueVector< QValueVector<int> > fields )
+{
+ // try to extract the encoded information from the field series:
+ QValueVector<int> numbers = decode( fields, 0, fields.count() );
+ Barcode_EAN13 barcode( numbers );
+
+ // return the results:
+ return barcode;
+}
+
+QValueVector<int> Decoder_EAN13::decode( QValueVector< QValueVector<int> > fields, int start_i, int end_i )
+{
+ // determine the length of the path in pixels
+ int length = 0;
+ for (uint i = 0; i < fields.size(); i++)
+ length += fields.at(i).at(1);
+
+ // set the parameters accordingly:
+ int max_start_sentry_bar_differences;
+ int max_unit_length;
+ int min_unit_length;
+
+ if (length <= 800) {
+ max_start_sentry_bar_differences = 6;
+ max_unit_length = 10;
+ min_unit_length = 1;
+ } else {
+ max_start_sentry_bar_differences = 30;
+ max_unit_length = 50;
+ min_unit_length = 1;
+ }
+
+ // consistency checks:
+ if (fields.count() <= 0)
+ return QValueVector<int>();
+ if (start_i > end_i - 3)
+ return QValueVector<int>();
+ if (end_i - start_i < 30)
+ return QValueVector<int>(); // (just a rough value)
+
+ // relevant indexes:
+ int start_sentinel_i;
+ int end_sentinel_i;
+ int left_numbers_i;
+ int middle_guard_i;
+ int right_numbers_i;
+
+ // relevant parameters:
+ float unit_length;
+
+ // results:
+ QValueVector<int> numbers( 13, -1 ); // the java source does no initialization
+
+ // determine the relevant positions:
+
+ // Try to detect the start sentinel (a small black-white-black serie):
+ start_sentinel_i = -1;
+ for (int i = start_i; i < end_i - 56; i++) {
+ if (fields[i][0] == 0) {
+ if ((fields[i][1] >= min_unit_length) && (fields[i][1] <= max_unit_length)) {
+ if ((abs(fields[i][1] - fields[i + 1][1]) <= max_start_sentry_bar_differences)
+ && (abs(fields[i][1] - fields[i + 2][1]) <= max_start_sentry_bar_differences) && (fields[i + 3][1] < fields[i][1] << 3)) {
+ start_sentinel_i = i;
+ break;
+ }
+ }
+ }
+ }
+
+#ifdef Decoder_EAN13_DEBUG
+ fprintf( stderr, "start_sentinal_index: %i\n", start_sentinel_i );
+#endif
+
+ if (start_sentinel_i < 0)
+ return QValueVector<int>();
+
+ // calculate the other positions:
+ left_numbers_i = start_sentinel_i + 3;
+ middle_guard_i = left_numbers_i + 6 * 4;
+ right_numbers_i = middle_guard_i + 5;
+ end_sentinel_i = right_numbers_i + 6 * 4;
+
+ if (end_sentinel_i + 3 > end_i)
+ return QValueVector<int>();
+
+ // calculate the average (pixel) length of a bar that is one unit wide:
+ // (a complete barcode consists out of 95 length units)
+ int temp_length = 0;
+ int field_amount = (end_sentinel_i - start_sentinel_i + 3);
+ for (int i = start_sentinel_i; i < start_sentinel_i + field_amount; i++)
+ temp_length += fields[i][1];
+ unit_length = (float) ((float) temp_length / 95.0f);
+
+#ifdef Decoder_EAN13_DEBUG
+ fprintf( stderr, "unit_width: %f\n", unit_length );
+#endif
+
+ QValueVector< QValueVector<int> > current_number_field( 4, QValueVector<int>(2,0) );
+
+ if (left_numbers_i + 1 > end_i)
+ return QValueVector<int>();
+
+
+ // test the side from which we are reading the barcode:
+ for (int j = 0; j < 4; j++) {
+ current_number_field[j][0] = fields[left_numbers_i + j][0];
+ current_number_field[j][1] = fields[left_numbers_i + j][1];
+ }
+ MatchMakerResult matchMakerResult = recognizeNumber( current_number_field, BOTH_TABLES );
+
+
+ if (matchMakerResult.isEven()) {
+ // we are reading the barcode from the back side:
+
+ // use the already obtained information:
+ numbers[12] = matchMakerResult.getDigit();
+
+ // try to recognize the "right" numbers:
+ int counter = 11;
+ for (int i = left_numbers_i + 4; i < left_numbers_i + 24; i = i + 4) {
+ for (int j = 0; j < 4; j++) {
+ current_number_field[j][0] = fields[i + j][0];
+ current_number_field[j][1] = fields[i + j][1];
+ }
+ matchMakerResult = recognizeNumber(current_number_field, EVEN_TABLE);
+ numbers[counter] = matchMakerResult.getDigit();
+ counter--;
+ }
+
+ bool parity_pattern[6]; // true = even, false = odd
+
+ //(counter has now the value 6)
+
+ // try to recognize the "left" numbers:
+ for (int i = right_numbers_i; i < right_numbers_i + 24; i = i + 4) {
+ for (int j = 0; j < 4; j++) {
+ current_number_field[j][0] = fields[i + j][0];
+ current_number_field[j][1] = fields[i + j][1];
+ }
+ matchMakerResult = recognizeNumber(current_number_field, BOTH_TABLES);
+ numbers[counter] = matchMakerResult.getDigit();
+ parity_pattern[counter-1] = !matchMakerResult.isEven();
+ counter--;
+ }
+
+ // try to determine the system code:
+ matchMakerResult = recognizeSystemCode(parity_pattern);
+ numbers[0] = matchMakerResult.getDigit();
+ } else {
+ // we are reading the barcode from the "correct" side:
+
+ bool parity_pattern[6]; // true = even, false = odd
+
+ // use the already obtained information:
+ numbers[1] = matchMakerResult.getDigit();
+ parity_pattern[0] = matchMakerResult.isEven();
+
+ // try to recognize the left numbers:
+ int counter = 2;
+ for (int i = left_numbers_i + 4; i < left_numbers_i + 24; i = i + 4) {
+ for (int j = 0; j < 4; j++) {
+ current_number_field[j][0] = fields[i + j][0];
+ current_number_field[j][1] = fields[i + j][1];
+ }
+ matchMakerResult = recognizeNumber(current_number_field, BOTH_TABLES);
+ numbers[counter] = matchMakerResult.getDigit();
+ parity_pattern[counter-1] = matchMakerResult.isEven();
+ counter++;
+ }
+
+ // try to determine the system code:
+ matchMakerResult = recognizeSystemCode(parity_pattern);
+ numbers[0] = matchMakerResult.getDigit();
+
+ // try to recognize the right numbers:
+ counter = 0;
+ for (int i = right_numbers_i; i < right_numbers_i + 24; i = i + 4) {
+ for (int j = 0; j < 4; j++) {
+ current_number_field[j][0] = fields[i + j][0];
+ current_number_field[j][1] = fields[i + j][1];
+ }
+ matchMakerResult = recognizeNumber(current_number_field, ODD_TABLE);
+ numbers[counter + 7] = matchMakerResult.getDigit();
+ counter++;
+ }
+ }
+
+ return numbers;
+}
+
+MatchMakerResult Decoder_EAN13::recognizeNumber( QValueVector< QValueVector<int> > fields, int code_table_to_use)
+{
+ // convert the pixel lenghts of the four black&white fields into
+ // normed values that have together a length of 70;
+ int pixel_sum = fields[0][1] + fields[1][1] + fields[2][1] + fields[3][1];
+ int b[4];
+ for (int i = 0; i < 4; i++) {
+ b[i] = round((((float) fields[i][1]) / ((float) pixel_sum)) * 70);
+ }
+
+#ifdef Decoder_EAN13_DEBUG
+ fprintf( stderr, "Recognize Number (code table to use: %i):\n", code_table_to_use );
+ fprintf( stderr, "lengths: %i %i %i %i\n", fields[0][1], fields[1][1], fields[2][1], fields[3][1] );
+ fprintf( stderr, "normed lengths: %i %i %i %i\n", b[0], b[1], b[2], b[3] );
+#endif
+
+ // try to detect the digit that is encoded by the set of four normed bar lenghts:
+ int max_difference_for_acceptance = 60;
+ int temp;
+
+ int even_min_difference = 100000;
+ int even_min_difference_index = 0;
+ int odd_min_difference = 100000;
+ int odd_min_difference_index = 0;
+
+ if ((code_table_to_use == BOTH_TABLES)||(code_table_to_use == EVEN_TABLE)) {
+ QValueVector<int> even_differences(10,0);
+
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 4; j++) {
+ // calculate the differences in the even group:
+ temp = b[j] - code_even[i][j];
+ if (temp < 0)
+ even_differences[i] = even_differences[i] + ((-temp) << 1);
+ else
+ even_differences[i] = even_differences[i] + (temp << 1);
+ }
+ if (even_differences[i] < even_min_difference) {
+ even_min_difference = even_differences[i];
+ even_min_difference_index = i;
+ }
+ }
+ }
+
+ if ((code_table_to_use == BOTH_TABLES) || (code_table_to_use == ODD_TABLE)) {
+ QValueVector<int> odd_differences(10,0);
+
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 4; j++) {
+ // calculate the differences in the odd group:
+ temp = b[j] - code_odd[i][j];
+ if (temp < 0)
+ odd_differences[i] = odd_differences[i] + ((-temp) << 1);
+ else
+ odd_differences[i] = odd_differences[i] + (temp << 1);
+ }
+ if (odd_differences[i] < odd_min_difference) {
+ odd_min_difference = odd_differences[i];
+ odd_min_difference_index = i;
+ }
+ }
+ }
+
+ // select the digit and parity with the lowest difference to the found pattern:
+ if (even_min_difference <= odd_min_difference) {
+ if (even_min_difference < max_difference_for_acceptance)
+ return MatchMakerResult( true, even_min_difference_index );
+ } else {
+ if (odd_min_difference < max_difference_for_acceptance)
+ return MatchMakerResult( false, odd_min_difference_index );
+ }
+
+ return MatchMakerResult( false, -1 );
+}
+
+MatchMakerResult Decoder_EAN13::recognizeSystemCode( bool parity_pattern[6] )
+{
+ // search for a fitting parity pattern:
+ bool fits = false;
+ for (int i = 0; i < 10; i++) {
+ fits = true;
+ for (int j = 0; j < 6; j++) {
+ if (parity_pattern_list[i][j] != parity_pattern[j]) {
+ fits = false;
+ break;
+ }
+ }
+ if (fits)
+ return MatchMakerResult( false, i );
+ }
+
+ return MatchMakerResult( false, -1 );
+}
+
+//ok
+MatchMakerResult::MatchMakerResult( bool even, int digit )
+{
+ m_even = even;
+ m_digit = digit;
+}
+
+#include "barcode.moc"
diff --git a/src/barcode/barcode.h b/src/barcode/barcode.h
new file mode 100644
index 0000000..b8d71bc
--- /dev/null
+++ b/src/barcode/barcode.h
@@ -0,0 +1,135 @@
+/***************************************************************************
+ copyright : (C) 2007 by Sebastian Held
+ email : sebastian.held@gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * ### based on BaToo: http://people.inf.ethz.ch/adelmanr/batoo/ ### *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef BARCODE_H
+#define BARCODE_H
+
+#include <qthread.h>
+#include <qimage.h>
+#include <qvaluevector.h>
+#include <qobject.h>
+#include <qmutex.h>
+#include <math.h>
+
+#include "barcode_v4l.h"
+
+//#define BarcodeDecoder_DEBUG
+//#define Decoder_EAN13_DEBUG
+//#define Barcode_DEBUG
+
+namespace barcodeRecognition {
+ static int code_odd[][4] = { { 30, 20, 10, 10 },
+ { 20, 20, 20, 10 },
+ { 20, 10, 20, 20 },
+ { 10, 40, 10, 10 },
+ { 10, 10, 30, 20 },
+ { 10, 20, 30, 10 },
+ { 10, 10, 10, 40 },
+ { 10, 30, 10, 20 },
+ { 10, 20, 10, 30 },
+ { 30, 10, 10, 20 } };
+
+ static int code_even[][4] = { { 10, 10, 20, 30 },
+ { 10, 20, 20, 20 },
+ { 20, 20, 10, 20 },
+ { 10, 10, 40, 10 },
+ { 20, 30, 10, 10 },
+ { 10, 30, 20, 10 },
+ { 40, 10, 10, 10 },
+ { 20, 10, 30, 10 },
+ { 30, 10, 20, 10 },
+ { 20, 10, 10, 30 } };
+
+ static bool parity_pattern_list[][6] = { { false, false, false, false, false, false },
+ { false, false, true, false, true, true },
+ { false, false, true, true, false, true },
+ { false, false, true, true, true, false },
+ { false, true, false, false, true, true },
+ { false, true, true, false, false, true },
+ { false, true, true, true, false, false },
+ { false, true, false, true, false, true },
+ { false, true, false, true, true, false },
+ { false, true, true, false, true, false } };
+
+ class Barcode_EAN13 {
+ public:
+ Barcode_EAN13();
+ Barcode_EAN13( QValueVector<int> code );
+ bool isNull() const { return m_null; }
+ bool isValid() const;
+ QValueVector<int> getNumbers() const;
+ void setCode( QValueVector<int> code );
+ QString toString() const;
+ bool operator!= ( const Barcode_EAN13 &code );
+ protected:
+ QValueVector<int> m_numbers;
+ bool m_null;
+ };
+
+ class MatchMakerResult {
+ public:
+ MatchMakerResult( bool even, int digit );
+ bool isEven() const {return m_even;}
+ int getDigit() const {return m_digit;}
+ protected:
+ int m_digit;
+ bool m_even;
+ };
+
+ class Decoder_EAN13 {
+ public:
+ enum { BOTH_TABLES = 0, EVEN_TABLE = 1, ODD_TABLE = 2 };
+ static Barcode_EAN13 recognize( QValueVector< QValueVector<int> > fields );
+ static QValueVector<int> decode( QValueVector< QValueVector<int> > fields, int start_i, int end_i );
+ static MatchMakerResult recognizeNumber( QValueVector< QValueVector<int> > fields, int code_table_to_use );
+ static MatchMakerResult recognizeSystemCode( bool parity_pattern[6] );
+ };
+
+ /** \brief this thread handles barcode recognition using webcams
+ * @author Sebastian Held <sebastian.held@gmx.de>
+ */
+ class barcodeRecognitionThread : public QObject, public QThread {
+ Q_OBJECT
+ public:
+ barcodeRecognitionThread();
+ ~barcodeRecognitionThread();
+ virtual void run();
+ void stop();
+ void recognizeBarcode( QImage img );
+ bool isWebcamAvailable();
+ signals:
+ void recognized( QString barcode );
+ void gotImage( QImage &img );
+ protected:
+ volatile bool m_stop;
+ QImage m_barcode_img;
+ QMutex m_stop_mutex, m_barcode_img_mutex;
+ barcode_v4l *m_barcode_v4l;
+
+ Barcode_EAN13 recognize( QImage img );
+ Barcode_EAN13 recognizeCode( QImage img, int x1, int x2, int y );
+ void addNumberToPossibleNumbers( QValueVector<int> number, int possible_numbers[10][13][2], bool correct_code );
+ void sortDigits( int possible_numbers[10][13][2] );
+ Barcode_EAN13 extractBarcode( int possible_numbers[10][13][2] );
+ QValueVector<int> transformPathToBW( QValueVector<QRgb> line);
+ QValueVector< QValueVector<int> > extractFieldInformation( QValueVector<int> string );
+ Barcode_EAN13 detectValidBarcode ( int possible_numbers[10][13][2], int max_amount_of_considered_codes );
+ bool isValid( int numbers[13] );
+ bool isValid( QValueVector<int> numbers );
+ void printArray( int array[10][13][2], int level );
+ };
+}
+
+#endif
diff --git a/src/barcode/barcode_v4l.cpp b/src/barcode/barcode_v4l.cpp
new file mode 100644
index 0000000..f644fe1
--- /dev/null
+++ b/src/barcode/barcode_v4l.cpp
@@ -0,0 +1,538 @@
+/***************************************************************************
+ copyright : (C) 2007 by Sebastian Held
+ email : sebastian.held@gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+// uses code from xawtv: webcam.c (c) 1998-2002 Gerd Knorr
+
+//#include <stdio.h>
+//#include <stdlib.h>
+#include <fcntl.h> /* low-level i/o */
+//#include <unistd.h>
+#include <errno.h>
+//#include <malloc.h>
+//#include <sys/stat.h>
+//#include <sys/types.h>
+//#include <sys/time.h>
+//#include <sys/mman.h>
+#include <sys/ioctl.h>
+//#include <asm/types.h> /* for videodev2.h */
+
+#include "barcode_v4l.h"
+#include "../tellico_debug.h"
+
+using barcodeRecognition::ng_vid_driver;
+using barcodeRecognition::ng_vid_driver_v4l;
+using barcodeRecognition::barcode_v4l;
+using barcodeRecognition::video_converter;
+
+QPtrList<barcodeRecognition::video_converter> barcodeRecognition::ng_vid_driver::m_converter;
+const char *barcodeRecognition::device_cap[] = { "capture", "tuner", "teletext", "overlay", "chromakey", "clipping", "frameram", "scales", "monochrome", 0 };
+const unsigned int barcodeRecognition::ng_vfmt_to_depth[] = {
+ 0, /* unused */
+ 8, /* RGB8 */
+ 8, /* GRAY8 */
+ 16, /* RGB15 LE */
+ 16, /* RGB16 LE */
+ 16, /* RGB15 BE */
+ 16, /* RGB16 BE */
+ 24, /* BGR24 */
+ 32, /* BGR32 */
+ 24, /* RGB24 */
+ 32, /* RGB32 */
+ 16, /* LUT2 */
+ 32, /* LUT4 */
+ 16, /* YUYV */
+ 16, /* YUV422P */
+ 12, /* YUV420P */
+ 0, /* MJPEG */
+ 0, /* JPEG */
+ 16, /* UYVY */
+};
+
+const char* barcodeRecognition::ng_vfmt_to_desc[] = {
+ "none",
+ "8 bit PseudoColor (dithering)",
+ "8 bit StaticGray",
+ "15 bit TrueColor (LE)",
+ "16 bit TrueColor (LE)",
+ "15 bit TrueColor (BE)",
+ "16 bit TrueColor (BE)",
+ "24 bit TrueColor (LE: bgr)",
+ "32 bit TrueColor (LE: bgr-)",
+ "24 bit TrueColor (BE: rgb)",
+ "32 bit TrueColor (BE: -rgb)",
+ "16 bit TrueColor (lut)",
+ "32 bit TrueColor (lut)",
+ "16 bit YUV 4:2:2 (packed, YUYV)",
+ "16 bit YUV 4:2:2 (planar)",
+ "12 bit YUV 4:2:0 (planar)",
+ "MJPEG (AVI)",
+ "JPEG (JFIF)",
+ "16 bit YUV 4:2:2 (packed, UYVY)",
+};
+
+unsigned int barcodeRecognition::ng_yuv_gray[256];
+unsigned int barcodeRecognition::ng_yuv_red[256];
+unsigned int barcodeRecognition::ng_yuv_blue[256];
+unsigned int barcodeRecognition::ng_yuv_g1[256];
+unsigned int barcodeRecognition::ng_yuv_g2[256];
+unsigned int barcodeRecognition::ng_clip[256 + 2 * CLIP];
+
+void barcodeRecognition::ng_color_yuv2rgb_init()
+{
+ int i;
+# define RED_NULL 128
+# define BLUE_NULL 128
+# define LUN_MUL 256
+# define RED_MUL 512
+# define BLUE_MUL 512
+#define GREEN1_MUL (-RED_MUL/2)
+#define GREEN2_MUL (-BLUE_MUL/6)
+#define RED_ADD (-RED_NULL * RED_MUL)
+#define BLUE_ADD (-BLUE_NULL * BLUE_MUL)
+#define GREEN1_ADD (-RED_ADD/2)
+#define GREEN2_ADD (-BLUE_ADD/6)
+
+ /* init Lookup tables */
+ for (i = 0; i < 256; i++) {
+ barcodeRecognition::ng_yuv_gray[i] = i * LUN_MUL >> 8;
+ barcodeRecognition::ng_yuv_red[i] = (RED_ADD + i * RED_MUL) >> 8;
+ barcodeRecognition::ng_yuv_blue[i] = (BLUE_ADD + i * BLUE_MUL) >> 8;
+ barcodeRecognition::ng_yuv_g1[i] = (GREEN1_ADD + i * GREEN1_MUL) >> 8;
+ barcodeRecognition::ng_yuv_g2[i] = (GREEN2_ADD + i * GREEN2_MUL) >> 8;
+ }
+ for (i = 0; i < CLIP; i++)
+ barcodeRecognition::ng_clip[i] = 0;
+ for (; i < CLIP + 256; i++)
+ barcodeRecognition::ng_clip[i] = i - CLIP;
+ for (; i < 2 * CLIP + 256; i++)
+ barcodeRecognition::ng_clip[i] = 255;
+}
+
+
+
+
+
+
+
+
+
+
+
+barcode_v4l::barcode_v4l()
+{
+ m_devname = "/dev/video0";
+ m_grab_width = 640;
+ m_grab_height = 480;
+ m_drv = 0;
+ m_conv = 0;
+
+ barcodeRecognition::ng_color_yuv2rgb_init();
+ //ng_vid_driver::register_video_converter( new barcodeRecognition::yuv422p_to_rgb24() );
+ //ng_vid_driver::register_video_converter( new barcodeRecognition::yuv422_to_rgb24() );
+ ng_vid_driver::register_video_converter( new barcodeRecognition::yuv420p_to_rgb24() );
+
+ grab_init();
+}
+
+barcode_v4l::~barcode_v4l()
+{
+ if (m_drv) {
+ m_drv->close();
+ delete m_drv;
+ }
+}
+
+bool barcode_v4l::isOpen()
+{
+ return m_drv;
+}
+
+QImage barcode_v4l::grab_one2()
+{
+ if (!m_drv) {
+ myDebug() << "no driver/device available" << endl;
+ return QImage();
+ }
+
+ QByteArray *cap;
+ if (!(cap = m_drv->getimage2())) {
+ myDebug() << "capturing image failed" << endl;
+ return QImage();
+ }
+
+ QByteArray *buf;
+ if (m_conv) {
+ buf = new QByteArray( 3*m_fmt.width*m_fmt.height );
+ m_conv->frame( buf, cap, m_fmt_drv );
+ } else {
+ buf = new QByteArray(*cap);
+ }
+ delete cap;
+
+ int depth = 32;
+ QByteArray *buf2 = new QByteArray( depth/8 *m_fmt.width*m_fmt.height );
+ for (uint i=0; i<m_fmt.width*m_fmt.height; i++) {
+ (*buf2)[i*4+0] = buf->at(i*3+2);
+ (*buf2)[i*4+1] = buf->at(i*3+1);
+ (*buf2)[i*4+2] = buf->at(i*3+0);
+ (*buf2)[i*4+3] = 0;
+ }
+ delete buf;
+ QImage *temp = new QImage( (uchar*)buf2->data(), m_fmt.width, m_fmt.height, depth, 0, 0, QImage::LittleEndian );
+ QImage temp2 = temp->copy();
+ delete temp;
+ delete buf2;
+
+ return temp2;
+}
+
+
+
+
+
+
+
+bool barcode_v4l::grab_init()
+{
+ m_drv = ng_vid_driver::createDriver( m_devname );
+ if (!m_drv) {
+ myDebug() << "no grabber device available" << endl;
+ return false;
+ }
+ if (!(m_drv->capabilities() & CAN_CAPTURE)) {
+ myDebug() << "device doesn't support capture" << endl;
+ m_drv->close();
+ delete m_drv;
+ m_drv = 0;
+ return false;
+ }
+
+ /* try native */
+ m_fmt.fmtid = VIDEO_RGB24;
+ m_fmt.width = m_grab_width;
+ m_fmt.height = m_grab_height;
+ if (m_drv->setformat( &m_fmt )) {
+ m_fmt_drv = m_fmt;
+ return true;
+ }
+
+ /* check all available conversion functions */
+ m_fmt.bytesperline = m_fmt.width * ng_vfmt_to_depth[m_fmt.fmtid] / 8;
+ for (int i = 0; i<VIDEO_FMT_COUNT; i++) {
+ video_converter *conv = ng_vid_driver::find_video_converter( VIDEO_RGB24, i );
+ if (!conv)
+ continue;
+
+ m_fmt_drv = m_fmt;
+ m_fmt_drv.fmtid = conv->fmtid_in();
+ m_fmt_drv.bytesperline = 0;
+ if (m_drv->setformat( &m_fmt_drv )) {
+ m_fmt.width = m_fmt_drv.width;
+ m_fmt.height = m_fmt_drv.height;
+ m_conv = conv;
+ //m_conv->init( &m_fmt );
+ return true;
+ }
+ }
+
+ myDebug() << "can't get rgb24 data" << endl;
+ m_drv->close();
+ delete m_drv;
+ m_drv = 0;
+ return false;
+}
+
+
+ng_vid_driver* ng_vid_driver::createDriver( QString device )
+{
+ /* check all grabber drivers */
+ ng_vid_driver *drv = new ng_vid_driver_v4l();
+ if (!drv->open2( device )) {
+ myDebug() << "no v4l device found" << endl;
+ delete drv;
+ drv = 0;
+ }
+
+ return drv;
+}
+
+int ng_vid_driver::xioctl( int fd, int cmd, void *arg )
+{
+ int rc;
+
+ rc = ioctl(fd,cmd,arg);
+ if (rc == 0)
+ return 0;
+ //print_ioctl(stderr,ioctls_v4l1,PREFIX,cmd,arg);
+ qDebug( ": %s\n",(rc == 0) ? "ok" : strerror(errno) );
+ return rc;
+}
+
+
+
+void ng_vid_driver::register_video_converter( video_converter *conv )
+{
+ if (!conv)
+ return;
+
+ m_converter.append( conv );
+}
+
+video_converter *ng_vid_driver::find_video_converter( int out, int in )
+{
+ video_converter *conv;
+ for (conv = m_converter.first(); conv; conv = m_converter.next() )
+ if ((conv->fmtid_in() == in) && (conv->fmtid_out() == out))
+ return conv;
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ng_vid_driver_v4l::ng_vid_driver_v4l()
+{
+ m_name = "v4l";
+ m_drv = 0;
+ m_fd = -1;
+
+ m_use_read = false;
+
+ for (int i=0; i<VIDEO_FMT_COUNT; i++)
+ format2palette[i] = 0;
+ format2palette[VIDEO_RGB08] = VIDEO_PALETTE_HI240;
+ format2palette[VIDEO_GRAY] = VIDEO_PALETTE_GREY;
+ format2palette[VIDEO_RGB15_LE] = VIDEO_PALETTE_RGB555;
+ format2palette[VIDEO_RGB16_LE] = VIDEO_PALETTE_RGB565;
+ format2palette[VIDEO_BGR24] = VIDEO_PALETTE_RGB24;
+ format2palette[VIDEO_BGR32] = VIDEO_PALETTE_RGB32;
+ format2palette[VIDEO_YUYV] = VIDEO_PALETTE_YUV422;
+ format2palette[VIDEO_UYVY] = VIDEO_PALETTE_UYVY;
+ format2palette[VIDEO_YUV422P] = VIDEO_PALETTE_YUV422P;
+ format2palette[VIDEO_YUV420P] = VIDEO_PALETTE_YUV420P;
+}
+
+bool ng_vid_driver_v4l::open2( QString device )
+{
+ /* open device */
+ if ((m_fd = ::open( device.latin1(), O_RDWR )) == -1) {
+ qDebug( "v4l: open %s: %s\n", device.latin1(), strerror(errno) );
+ return false;
+ }
+ if (ioctl( m_fd, VIDIOCGCAP, &m_capability ) == -1) {
+ ::close( m_fd );
+ return false;
+ }
+
+#ifdef Barcode_DEBUG
+ qDebug( "v4l: open: %s (%s)\n", device.latin1(), m_capability.name );
+#endif
+
+ fcntl( m_fd, F_SETFD, FD_CLOEXEC ); // close on exit
+
+#ifdef Barcode_DEBUG
+ myDebug() << " capabilities: " << endl;
+ for (int i = 0; device_cap[i] != NULL; i++)
+ if (m_capability.type & (1 << i))
+ qDebug( " %s", device_cap[i] );
+ qDebug( " size : %dx%d => %dx%d", m_capability.minwidth, m_capability.minheight, m_capability.maxwidth, m_capability.maxheight );
+#endif
+
+#ifdef Barcode_DEBUG
+ fprintf(stderr," v4l: using read() for capture\n");
+#endif
+ m_use_read = true;
+
+ return true;
+}
+
+void ng_vid_driver_v4l::close()
+{
+#ifdef Barcode_DEBUG
+ fprintf(stderr, "v4l: close\n");
+#endif
+
+ if (m_fd != -1)
+ ::close(m_fd);
+ m_fd = -1;
+ return;
+}
+
+int ng_vid_driver_v4l::capabilities()
+{
+ int ret = 0;
+
+ if (m_capability.type & VID_TYPE_OVERLAY)
+ ret |= CAN_OVERLAY;
+ if (m_capability.type & VID_TYPE_CAPTURE)
+ ret |= CAN_CAPTURE;
+ if (m_capability.type & VID_TYPE_TUNER)
+ ret |= CAN_TUNE;
+ if (m_capability.type & VID_TYPE_CHROMAKEY)
+ ret |= NEEDS_CHROMAKEY;
+ return ret;
+}
+
+bool ng_vid_driver_v4l::setformat( ng_video_fmt *fmt )
+{
+ bool rc = false;
+
+#ifdef Barcode_DEBUG
+ fprintf(stderr,"v4l: setformat\n");
+#endif
+ if (m_use_read) {
+ rc = read_setformat( fmt );
+ } else {
+ Q_ASSERT( false );
+ }
+
+ m_fmt = *fmt;
+
+ return rc;
+}
+
+
+
+
+
+bool ng_vid_driver_v4l::read_setformat( ng_video_fmt *fmt )
+{
+ xioctl( m_fd, VIDIOCGCAP, &m_capability );
+ if (fmt->width > static_cast<uint>(m_capability.maxwidth))
+ fmt->width = m_capability.maxwidth;
+ if (fmt->height > static_cast<uint>(m_capability.maxheight))
+ fmt->height = m_capability.maxheight;
+ fmt->bytesperline = fmt->width * ng_vfmt_to_depth[fmt->fmtid] / 8;
+
+ xioctl( m_fd, VIDIOCGPICT, &m_pict );
+ m_pict.depth = ng_vfmt_to_depth[fmt->fmtid];
+ m_pict.palette = GETELEM(format2palette,fmt->fmtid,0);
+ m_pict.brightness = 20000;
+ if (-1 == xioctl( m_fd, VIDIOCSPICT, &m_pict ))
+ return false;
+
+ xioctl( m_fd, VIDIOCGWIN, &m_win);
+ m_win.width = m_fmt.width;
+ m_win.height = m_fmt.height;
+ m_win.clipcount = 0;
+ if (-1 == xioctl( m_fd, VIDIOCSWIN, &m_win ))
+ return false;
+
+ return true;
+}
+
+QByteArray* ng_vid_driver_v4l::getimage2()
+{
+#ifdef Barcode_DEBUG
+ myDebug() << "v4l: getimage2" << endl;
+#endif
+
+ return read_getframe2();
+}
+
+
+QByteArray* ng_vid_driver_v4l::read_getframe2()
+{
+ QByteArray* buf;
+ int size;
+
+ size = m_fmt.bytesperline * m_fmt.height;
+ buf = new QByteArray( size );
+ if (size != read( m_fd, buf->data(), size )) {
+ delete( buf );
+ return 0;
+ }
+ return buf;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#define GRAY(val) barcodeRecognition::ng_yuv_gray[val]
+#define RED(gray,red) ng_clip[ CLIP + gray + barcodeRecognition::ng_yuv_red[red] ]
+#define GREEN(gray,red,blue) ng_clip[ CLIP + gray + barcodeRecognition::ng_yuv_g1[red] + \
+ barcodeRecognition::ng_yuv_g2[blue] ]
+#define BLUE(gray,blue) ng_clip[ CLIP + gray + barcodeRecognition::ng_yuv_blue[blue] ]
+
+void barcodeRecognition::yuv420p_to_rgb24::frame( QByteArray *out, const QByteArray *in, const ng_video_fmt fmt )
+{
+ unsigned char *y, *u, *v, *d;
+ unsigned char *us,*vs;
+ unsigned char *dp;
+ unsigned int i,j;
+ int gray;
+
+ dp = (unsigned char*)out->data();
+ y = (unsigned char*)in->data();
+ u = y + fmt.width * fmt.height;
+ v = u + fmt.width * fmt.height / 4;
+
+ for (i = 0; i < fmt.height; i++) {
+ d = dp;
+ us = u; vs = v;
+ for (j = 0; j < fmt.width; j+= 2) {
+ gray = GRAY(*y);
+ *(d++) = RED(gray,*v);
+ *(d++) = GREEN(gray,*v,*u);
+ *(d++) = BLUE(gray,*u);
+ y++;
+ gray = GRAY(*y);
+ *(d++) = RED(gray,*v);
+ *(d++) = GREEN(gray,*v,*u);
+ *(d++) = BLUE(gray,*u);
+ y++; u++; v++;
+ }
+ if (0 == (i % 2)) {
+ u = us; v = vs;
+ }
+ dp += 3*fmt.width;
+ }
+}
diff --git a/src/barcode/barcode_v4l.h b/src/barcode/barcode_v4l.h
new file mode 100644
index 0000000..f0cde90
--- /dev/null
+++ b/src/barcode/barcode_v4l.h
@@ -0,0 +1,184 @@
+/***************************************************************************
+ copyright : (C) 2007 by Sebastian Held
+ email : sebastian.held@gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef BARCODE_V4L_H
+#define BARCODE_V4L_H
+
+#define GETELEM(array,index,default) \
+ (index < sizeof(array)/sizeof(array[0]) ? array[index] : default)
+
+/*
+ * Taken from xawtv-3.5.9 source 8/15/01 by George Staikos <staikos@kde.org>
+ */
+#ifdef __STRICT_ANSI__
+#undef __STRICT_ANSI__
+#define FOO__STRICT_ANSI__
+#endif
+#include <asm/types.h>
+#ifdef FOO__STRICT_ANSI__
+#define __STRICT_ANSI__ 1
+#undef FOO__STRICT_ANSI__
+#endif
+
+//#include <linux/videodev2.h>
+#include <linux/videodev.h>
+
+#include <qstring.h>
+#include <qimage.h>
+
+namespace barcodeRecognition {
+
+struct ng_video_fmt {
+ unsigned int fmtid; /* VIDEO_* */
+ unsigned int width;
+ unsigned int height;
+ unsigned int bytesperline; /* zero for compressed formats */
+};
+enum { CAN_OVERLAY=1, CAN_CAPTURE=2, CAN_TUNE=4, NEEDS_CHROMAKEY=8 };
+enum { VIDEO_NONE=0, VIDEO_RGB08, VIDEO_GRAY, VIDEO_RGB15_LE, VIDEO_RGB16_LE,
+ VIDEO_RGB15_BE, VIDEO_RGB16_BE, VIDEO_BGR24, VIDEO_BGR32, VIDEO_RGB24,
+ VIDEO_RGB32, VIDEO_LUT2, VIDEO_LUT4, VIDEO_YUYV, VIDEO_YUV422P,
+ VIDEO_YUV420P, VIDEO_MJPEG, VIDEO_JPEG, VIDEO_UYVY, VIDEO_FMT_COUNT };
+extern const char *device_cap[];
+extern const unsigned int ng_vfmt_to_depth[];
+extern const char* ng_vfmt_to_desc[];
+
+/* lookup tables */
+#define CLIP 320
+extern unsigned int ng_yuv_gray[256];
+extern unsigned int ng_yuv_red[256];
+extern unsigned int ng_yuv_blue[256];
+extern unsigned int ng_yuv_g1[256];
+extern unsigned int ng_yuv_g2[256];
+extern unsigned int ng_clip[256 + 2 * CLIP];
+void ng_color_yuv2rgb_init();
+
+
+
+class video_converter
+{
+public:
+ video_converter() {;}
+ virtual ~video_converter() {;}
+ virtual void init( ng_video_fmt* ) {;}
+ virtual void exit() {;}
+ virtual void frame( QByteArray*, const QByteArray*, ng_video_fmt ) {;}
+ int fmtid_in() {return m_fmtid_in;}
+ int fmtid_out() {return m_fmtid_out;}
+protected:
+ int m_fmtid_in, m_fmtid_out;
+};
+
+class yuv422p_to_rgb24 : public video_converter
+{
+public:
+ yuv422p_to_rgb24() {m_fmtid_in=VIDEO_YUV422P; m_fmtid_out=VIDEO_RGB24;}
+ virtual void frame( QByteArray *, const QByteArray *, ng_video_fmt ) {;}
+};
+class yuv422_to_rgb24 : public video_converter
+{
+public:
+ yuv422_to_rgb24() {m_fmtid_in=VIDEO_YUYV; m_fmtid_out=VIDEO_RGB24;}
+ virtual void frame( QByteArray *, const QByteArray *, ng_video_fmt ) {;}
+};
+class yuv420p_to_rgb24 : public video_converter
+{
+public:
+ yuv420p_to_rgb24() {m_fmtid_in=VIDEO_YUV420P; m_fmtid_out=VIDEO_RGB24;}
+ virtual void frame( QByteArray *, const QByteArray *, ng_video_fmt );
+};
+
+class ng_vid_driver
+{
+public:
+ static ng_vid_driver *createDriver( QString device );
+ static int xioctl( int fd, int cmd, void *arg );
+
+ /* open/close */
+ virtual bool open2( QString device ) = 0;
+ virtual void close() = 0;
+
+ /* attributes */
+ virtual QString get_devname() {return m_name;}
+ virtual int capabilities() = 0;
+
+ /* capture */
+ virtual bool setformat( ng_video_fmt *fmt ) = 0;
+ virtual QByteArray* getimage2() = 0; /* single image */
+
+ // video converter
+ static void register_video_converter( video_converter *conv );
+ static video_converter *find_video_converter( int out, int in );
+
+protected:
+ QString m_name;
+ static QPtrList<video_converter> m_converter;
+};
+
+
+class barcode_v4l
+{
+public:
+ barcode_v4l();
+ ~barcode_v4l();
+ QImage grab_one2();
+ bool isOpen();
+
+protected:
+ bool grab_init();
+
+ QString m_devname;
+ int m_grab_width, m_grab_height;
+ ng_vid_driver *m_drv;
+ ng_video_fmt m_fmt, m_fmt_drv;
+ video_converter *m_conv;
+
+};
+
+
+class ng_vid_driver_v4l : public ng_vid_driver
+{
+public:
+ ng_vid_driver_v4l();
+
+ /* open/close */
+ //virtual bool open( QString device );
+ virtual bool open2( QString device );
+ virtual void close();
+
+ /* attributes */
+ virtual int capabilities();
+
+ /* capture */
+ virtual bool setformat( ng_video_fmt *fmt );
+ //virtual ng_video_buf* getimage(); /* single image */
+ virtual QByteArray* getimage2(); /* single image */
+
+protected:
+ bool read_setformat( ng_video_fmt *fmt );
+ QByteArray* read_getframe2();
+ void *m_drv;
+ int m_fd;
+ video_capability m_capability;
+ video_picture m_pict;
+ video_window m_win;
+
+ /* capture */
+ bool m_use_read;
+ ng_video_fmt m_fmt;
+
+ unsigned short format2palette[VIDEO_FMT_COUNT];
+};
+
+} // namespace
+#endif
diff --git a/src/borrower.cpp b/src/borrower.cpp
new file mode 100644
index 0000000..2e3fa0b
--- /dev/null
+++ b/src/borrower.cpp
@@ -0,0 +1,75 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "borrower.h"
+#include "entry.h"
+#include "tellico_utils.h"
+
+using Tellico::Data::Loan;
+using Tellico::Data::Borrower;
+
+Loan::Loan(Data::EntryPtr entry, const QDate& loanDate, const QDate& dueDate, const QString& note)
+ : KShared(), m_uid(Tellico::uid()), m_borrower(0), m_entry(entry), m_loanDate(loanDate), m_dueDate(dueDate),
+ m_note(note), m_inCalendar(false) {
+}
+
+Loan::Loan(const Loan& other) : KShared(other), m_uid(Tellico::uid()), m_borrower(other.m_borrower),
+ m_entry(other.m_entry), m_loanDate(other.m_loanDate), m_dueDate(other.m_dueDate),
+ m_note(other.m_note), m_inCalendar(false) {
+}
+
+Tellico::Data::BorrowerPtr Loan::borrower() const {
+ return m_borrower;
+}
+
+Tellico::Data::EntryPtr Loan::entry() const {
+ return m_entry;
+}
+
+Borrower::Borrower(const QString& name_, const QString& uid_)
+ : KShared(), m_name(name_), m_uid(uid_) {
+}
+
+Borrower::Borrower(const Borrower& b)
+ : KShared(b), m_name(b.m_name), m_uid(b.m_uid), m_loans(b.m_loans) {
+}
+
+Borrower& Borrower::operator=(const Borrower& other_) {
+ if(this == &other_) return *this;
+
+ static_cast<KShared&>(*this) = static_cast<const KShared&>(other_);
+ m_name = other_.m_name;
+ m_uid = other_.m_uid;
+ m_loans = other_.m_loans;
+ return *this;
+}
+
+Tellico::Data::LoanPtr Borrower::loan(Data::ConstEntryPtr entry_) {
+ for(LoanVec::Iterator it = m_loans.begin(); it != m_loans.end(); ++it) {
+ if(it->entry() == entry_) {
+ return it;
+ }
+ }
+ return 0;
+}
+
+void Borrower::addLoan(Data::LoanPtr loan_) {
+ if(loan_) {
+ m_loans.append(loan_);
+ loan_->setBorrower(this);
+ }
+}
+
+bool Borrower::removeLoan(Data::LoanPtr loan_) {
+ return m_loans.remove(loan_);
+}
diff --git a/src/borrower.h b/src/borrower.h
new file mode 100644
index 0000000..049badf
--- /dev/null
+++ b/src/borrower.h
@@ -0,0 +1,95 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_BORROWER_H
+#define TELLICO_BORROWER_H
+
+#include "datavectors.h"
+
+#include <ksharedptr.h>
+
+#include <qdatetime.h>
+
+namespace Tellico {
+ namespace Data {
+
+class Loan : public KShared {
+
+public:
+ Loan(Data::EntryPtr entry, const QDate& loanDate, const QDate& dueDate, const QString& note);
+ Loan(const Loan& other);
+
+ Data::BorrowerPtr borrower() const;
+ void setBorrower(Data::BorrowerPtr b) { m_borrower = b; }
+
+ const QString& uid() const { return m_uid; }
+ void setUID(const QString& uid) { m_uid = uid; }
+
+ Data::EntryPtr entry() const;
+
+ const QDate& loanDate() const { return m_loanDate; }
+
+ const QDate& dueDate() const { return m_dueDate; }
+ void setDueDate(const QDate& date) { m_dueDate = date; }
+
+ const QString& note() const { return m_note; }
+ void setNote(const QString& text) { m_note = text; }
+
+ bool inCalendar() const { return m_inCalendar; }
+ void setInCalendar(bool inCalendar) { m_inCalendar = inCalendar; }
+
+private:
+ Loan& operator=(const Loan&);
+
+ QString m_uid;
+ Data::BorrowerPtr m_borrower;
+ Data::EntryPtr m_entry;
+ QDate m_loanDate;
+ QDate m_dueDate;
+ QString m_note;
+ bool m_inCalendar;
+};
+
+typedef KSharedPtr<Loan> LoanPtr;
+typedef Vector<Loan> LoanVec;
+typedef LoanVec::Iterator LoanVecIt;
+
+/**
+ * @author Robby Stephenson
+ */
+class Borrower : public KShared {
+
+public:
+ Borrower(const QString& name, const QString& uid);
+ Borrower(const Borrower& other);
+ Borrower& operator=(const Borrower& other);
+
+ const QString& uid() const { return m_uid; }
+ const QString& name() const { return m_name; }
+ const LoanVec& loans() const { return m_loans; }
+ bool isEmpty() const { return m_loans.isEmpty(); }
+ int count() const { return m_loans.count(); }
+
+ Data::LoanPtr loan(Data::ConstEntryPtr entry);
+ void addLoan(Data::LoanPtr loan);
+ bool removeLoan(Data::LoanPtr loan);
+
+private:
+ QString m_name;
+ QString m_uid; // uid used by KABC
+ LoanVec m_loans;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/borrowerdialog.cpp b/src/borrowerdialog.cpp
new file mode 100644
index 0000000..4346b6b
--- /dev/null
+++ b/src/borrowerdialog.cpp
@@ -0,0 +1,136 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "borrowerdialog.h"
+#include "document.h"
+#include "collection.h"
+
+#include <klocale.h>
+#include <klineedit.h>
+#include <kabc/addressee.h>
+#include <kabc/stdaddressbook.h>
+#include <kiconloader.h>
+
+#include <qlayout.h>
+
+using Tellico::BorrowerDialog;
+
+BorrowerDialog::Item::Item(KListView* parent_, const KABC::Addressee& add_)
+ : KListViewItem(parent_), m_uid(add_.uid()) {
+ setText(0, add_.realName());
+ setPixmap(0, SmallIcon(QString::fromLatin1("kaddressbook")));
+}
+
+BorrowerDialog::Item::Item(KListView* parent_, const Data::Borrower& bor_)
+ : KListViewItem(parent_), m_uid(bor_.uid()) {
+ setText(0, bor_.name());
+ setPixmap(0, SmallIcon(QString::fromLatin1("tellico")));
+}
+
+// default button is going to be used as a print button, so it's separated
+BorrowerDialog::BorrowerDialog(QWidget* parent_, const char* name_/*=0*/)
+ : KDialogBase(parent_, name_, true, i18n("Select Borrower"), Ok|Cancel) {
+ QWidget* mainWidget = new QWidget(this, "BorrowerDialog mainWidget");
+ setMainWidget(mainWidget);
+ QVBoxLayout* topLayout = new QVBoxLayout(mainWidget, 0, KDialog::spacingHint());
+
+ m_listView = new KListView(mainWidget);
+ topLayout->addWidget(m_listView);
+ m_listView->addColumn(i18n("Name"));
+ m_listView->setFullWidth(true);
+ connect(m_listView, SIGNAL(doubleClicked(QListViewItem*)), SLOT(slotOk()));
+ connect(m_listView, SIGNAL(selectionChanged(QListViewItem*)), SLOT(updateEdit(QListViewItem*)));
+
+ m_lineEdit = new KLineEdit(mainWidget);
+ topLayout->addWidget(m_lineEdit);
+ connect(m_lineEdit->completionObject(), SIGNAL(match(const QString&)),
+ SLOT(selectItem(const QString&)));
+ m_lineEdit->setFocus();
+ m_lineEdit->completionObject()->setIgnoreCase(true);
+
+ KABC::AddressBook* abook = KABC::StdAddressBook::self(true);
+ connect(abook, SIGNAL(addressBookChanged(AddressBook*)),
+ SLOT(slotLoadAddressBook()));
+ connect(abook, SIGNAL(loadingFinished(Resource*)),
+ SLOT(slotLoadAddressBook()));
+ slotLoadAddressBook();
+
+ setMinimumWidth(400);
+}
+
+void BorrowerDialog::slotLoadAddressBook() {
+ m_listView->clear();
+ m_itemDict.clear();
+ m_lineEdit->completionObject()->clear();
+
+ const KABC::AddressBook* const abook = KABC::StdAddressBook::self(true);
+ for(KABC::AddressBook::ConstIterator it = abook->begin(), end = abook->end();
+ it != end; ++it) {
+ // skip people with no name
+ if((*it).realName().isEmpty()) {
+ continue;
+ }
+ Item* item = new Item(m_listView, *it);
+ m_itemDict.insert((*it).realName(), item);
+ m_lineEdit->completionObject()->addItem((*it).realName());
+ }
+
+ // add current borrowers, too
+ const Data::BorrowerVec& borrowers = Data::Document::self()->collection()->borrowers();
+ for(Data::BorrowerVec::ConstIterator it = borrowers.constBegin(); it != borrowers.constEnd(); ++it) {
+ if(m_itemDict[it->name()]) {
+ continue; // if an item already exists with this name
+ }
+ Item* item = new Item(m_listView, *it);
+ m_itemDict.insert(it->name(), item);
+ m_lineEdit->completionObject()->addItem(it->name());
+ }
+ m_listView->setSorting(0, true);
+ m_listView->sort();
+}
+
+void BorrowerDialog::selectItem(const QString& str_) {
+ if(str_.isEmpty()) {
+ return;
+ }
+
+ QListViewItem* item = m_itemDict.find(str_);
+ if(item) {
+ m_listView->blockSignals(true);
+ m_listView->setSelected(item, true);
+ m_listView->ensureItemVisible(item);
+ m_listView->blockSignals(false);
+ }
+}
+
+void BorrowerDialog::updateEdit(QListViewItem* item_) {
+ m_lineEdit->setText(item_->text(0));
+ m_lineEdit->setSelection(0, item_->text(0).length());
+ m_uid = static_cast<Item*>(item_)->uid();
+}
+
+Tellico::Data::BorrowerPtr BorrowerDialog::borrower() {
+ return new Data::Borrower(m_lineEdit->text(), m_uid);
+}
+
+// static
+Tellico::Data::BorrowerPtr BorrowerDialog::getBorrower(QWidget* parent_) {
+ BorrowerDialog dlg(parent_);
+
+ if(dlg.exec() == QDialog::Accepted) {
+ return dlg.borrower();
+ }
+ return 0;
+}
+
+#include "borrowerdialog.moc"
diff --git a/src/borrowerdialog.h b/src/borrowerdialog.h
new file mode 100644
index 0000000..2ad2684
--- /dev/null
+++ b/src/borrowerdialog.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef BORROWERDIALOG_H
+#define BORROWERDIALOG_H
+
+class KLineEdit;
+
+#include "borrower.h"
+
+#include <kdialogbase.h>
+
+#include <klistview.h>
+#include <qdict.h>
+
+namespace KABC {
+ class Addressee;
+}
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class BorrowerDialog : public KDialogBase {
+Q_OBJECT
+
+public:
+ static Data::BorrowerPtr getBorrower(QWidget* parent);
+
+private slots:
+ void selectItem(const QString& name);
+ void updateEdit(QListViewItem* item);
+ void slotLoadAddressBook();
+
+private:
+ /**
+ * The constructor sets up the dialog.
+ *
+ * @param parent A pointer to the parent widget
+ * @param name The widget name
+ */
+ BorrowerDialog(QWidget* parent, const char* name=0);
+ Data::BorrowerPtr borrower();
+
+ QString m_uid;
+ KListView* m_listView;
+ KLineEdit* m_lineEdit;
+ QDict<KListViewItem> m_itemDict;
+
+class Item : public KListViewItem {
+public:
+ Item(KListView* parent, const KABC::Addressee& addressee);
+ Item(KListView* parent, const Data::Borrower& borrower);
+ const QString& uid() const { return m_uid; }
+
+private:
+ QString m_uid;
+};
+
+};
+
+} // end namespace
+#endif
diff --git a/src/borroweritem.cpp b/src/borroweritem.cpp
new file mode 100644
index 0000000..0a9ee51
--- /dev/null
+++ b/src/borroweritem.cpp
@@ -0,0 +1,40 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "borroweritem.h"
+#include "borrower.h"
+#include "entry.h"
+
+#include "kiconloader.h"
+
+using Tellico::BorrowerItem;
+
+BorrowerItem::BorrowerItem(GUI::ListView* parent_, Data::BorrowerPtr borrower_)
+ : GUI::CountedItem(parent_), m_borrower(borrower_) {
+ setText(0, borrower_->name());
+ setPixmap(0, SmallIcon(QString::fromLatin1("kaddressbook")));
+}
+
+int BorrowerItem::count() const {
+ return m_borrower ? m_borrower->count() : GUI::CountedItem::count();
+}
+
+Tellico::Data::EntryVec BorrowerItem::entries() const {
+ Data::EntryVec entries;
+ for(Data::LoanVec::ConstIterator loan = m_borrower->loans().begin(); loan != m_borrower->loans().end(); ++loan) {
+ if(!entries.contains(loan->entry())) {
+ entries.append(loan->entry());
+ }
+ }
+ return entries;
+}
diff --git a/src/borroweritem.h b/src/borroweritem.h
new file mode 100644
index 0000000..ad0b7d6
--- /dev/null
+++ b/src/borroweritem.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_BORROWERITEM_H
+#define TELLICO_BORROWERITEM_H
+
+#include "gui/counteditem.h"
+#include "datavectors.h"
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class BorrowerItem : public GUI::CountedItem {
+public:
+ BorrowerItem(GUI::ListView* parent, Data::BorrowerPtr filter);
+
+ virtual bool isBorrowerItem() const { return true; }
+ Data::BorrowerPtr borrower() { return m_borrower; }
+
+ virtual int count() const;
+ virtual Data::EntryVec entries() const;
+
+private:
+ Data::BorrowerPtr m_borrower;
+};
+
+}
+
+#endif
diff --git a/src/calendarhandler.cpp b/src/calendarhandler.cpp
new file mode 100644
index 0000000..c8953fd
--- /dev/null
+++ b/src/calendarhandler.cpp
@@ -0,0 +1,251 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "calendarhandler.h"
+#include "entry.h"
+#include "tellico_kernel.h"
+#include "tellico_debug.h"
+
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kconfig.h>
+
+#ifdef USE_KCAL
+#include <libkcal/calendarresources.h>
+#include <libkcal/todo.h>
+#include <libkcal/resourcelocal.h>
+// #include <libkcal/resourceremote.h> // this file is moving around, API differences
+#endif
+
+// needed for ::readlink
+#include <unistd.h>
+#include <limits.h>
+
+// most of this code came from konsolekalendar in kdepim
+
+using Tellico::CalendarHandler;
+
+void CalendarHandler::addLoans(Data::LoanVec loans_) {
+#ifdef USE_KCAL
+ addLoans(loans_, 0);
+#else
+ Q_UNUSED(loans_);
+#endif
+}
+
+#ifdef USE_KCAL
+void CalendarHandler::addLoans(Data::LoanVec loans_, KCal::CalendarResources* resources_) {
+ if(loans_.isEmpty()) {
+ return;
+ }
+
+ KCal::CalendarResources* calendarResources;
+ if(resources_) {
+ calendarResources = resources_;
+ } else {
+ calendarResources = new KCal::CalendarResources(timezone());
+ calendarResources->readConfig();
+ calendarResources->load();
+ if(!checkCalendar(calendarResources)) {
+ return;
+ }
+ }
+
+ for(Data::LoanVec::Iterator loan = loans_.begin(); loan != loans_.end(); ++loan) {
+ // only add loans with a due date
+ if(loan->dueDate().isNull()) {
+ continue;
+ }
+
+ KCal::Todo* todo = new KCal::Todo();
+ populateTodo(todo, loan);
+
+ calendarResources->addTodo(todo);
+ loan->setInCalendar(true);
+ }
+ calendarResources->save();
+ // don't close if a pointer was passed
+ if(!resources_) {
+ calendarResources->close();
+ calendarResources->deleteLater();
+ }
+}
+#endif
+
+void CalendarHandler::modifyLoans(Data::LoanVec loans_) {
+#ifndef USE_KCAL
+ Q_UNUSED(loans_);
+ return;
+#else
+ if(loans_.isEmpty()) {
+ return;
+ }
+
+ KCal::CalendarResources calendarResources(timezone());
+ calendarResources.readConfig();
+ if(!checkCalendar(&calendarResources)) {
+ return;
+ }
+ calendarResources.load();
+
+ for(Data::LoanVec::Iterator loan = loans_.begin(); loan != loans_.end(); ++loan) {
+ KCal::Todo* todo = calendarResources.todo(loan->uid());
+ if(!todo) {
+// myDebug() << "couldn't find existing todo, adding a new todo" << endl;
+ Data::LoanVec newLoans;
+ newLoans.append(loan);
+ addLoans(newLoans, &calendarResources); // add loan
+ continue;
+ }
+ if(loan->dueDate().isNull()) {
+ myDebug() << "removing todo" << endl;
+ calendarResources.deleteIncidence(todo);
+ continue;
+ }
+
+ populateTodo(todo, loan);
+ todo->updated();
+
+ loan->setInCalendar(true);
+ }
+ calendarResources.save();
+ calendarResources.close();
+#endif
+}
+
+void CalendarHandler::removeLoans(Data::LoanVec loans_) {
+#ifndef USE_KCAL
+ Q_UNUSED(loans_);
+ return;
+#else
+ if(loans_.isEmpty()) {
+ return;
+ }
+
+ KCal::CalendarResources calendarResources(timezone());
+ calendarResources.readConfig();
+ if(!checkCalendar(&calendarResources)) {
+ return;
+ }
+ calendarResources.load();
+
+ for(Data::LoanVec::Iterator loan = loans_.begin(); loan != loans_.end(); ++loan) {
+ KCal::Todo* todo = calendarResources.todo(loan->uid());
+ if(todo) {
+ // maybe this is too much, we could just set the todo as done
+ calendarResources.deleteIncidence(todo);
+ }
+ }
+ calendarResources.save();
+ calendarResources.close();
+#endif
+}
+
+#ifdef USE_KCAL
+bool CalendarHandler::checkCalendar(KCal::CalendarResources* resources) {
+ KCal::CalendarResourceManager* manager = resources->resourceManager();
+ if(manager->isEmpty()) {
+ kdWarning() << "Tellico::CalendarHandler::checkCalendar() - adding default calendar" << endl;
+ KConfig config(QString::fromLatin1("korganizerrc"));
+ config.setGroup("General");
+ QString fileName = config.readPathEntry("Active Calendar");
+
+ QString resourceName;
+ KCal::ResourceCalendar* defaultResource = 0;
+ if(fileName.isEmpty()) {
+ fileName = locateLocal("appdata", QString::fromLatin1("std.ics"));
+ resourceName = i18n("Default Calendar");
+ defaultResource = new KCal::ResourceLocal(fileName);
+ } else {
+ KURL url = KURL::fromPathOrURL(fileName);
+ if(url.isLocalFile()) {
+ defaultResource = new KCal::ResourceLocal(url.path());
+ } else {
+// defaultResource = new KCal::ResourceRemote(url);
+ Kernel::self()->sorry(i18n("At the moment, Tellico only supports local calendar resources. "
+ "The active calendar is remotely located, so your loans will not "
+ "be added."));
+ return false;
+ }
+ resourceName = i18n("Active Calendar");
+ }
+
+ defaultResource->setResourceName(resourceName);
+
+ manager->add(defaultResource);
+ manager->setStandardResource(defaultResource);
+ }
+ return true;
+}
+
+void CalendarHandler::populateTodo(KCal::Todo* todo_, Data::LoanPtr loan_) {
+ if(!todo_ || !loan_) {
+ return;
+ }
+
+ todo_->setUid(loan_->uid());
+
+ todo_->setDtStart(loan_->loanDate());
+ todo_->setHasStartDate(true);
+ todo_->setDtDue(loan_->dueDate());
+ todo_->setHasDueDate(true);
+ QString person = loan_->borrower()->name();
+ QString summary = i18n("Tellico: %1 is due to return \"%2\"").arg(person).arg(loan_->entry()->title());
+ todo_->setSummary(summary);
+ QString note = loan_->note();
+ if(note.isEmpty()) {
+ note = summary;
+ }
+ todo_->setDescription(note);
+ todo_->setSecrecy(KCal::Incidence::SecrecyPrivate); // private by default
+
+ todo_->clearAttendees();
+ // not adding email of borrower for now, but request RSVP?
+ KCal::Attendee* attendee = new KCal::Attendee(loan_->borrower()->name(),
+ QString::null, false /*rsvp*/,
+ KCal::Attendee::NeedsAction,
+ KCal::Attendee::ReqParticipant,
+ loan_->borrower()->uid());
+ todo_->addAttendee(attendee);
+
+ todo_->clearAlarms();
+ KCal::Alarm* alarm = todo_->newAlarm();
+ alarm->setDisplayAlarm(summary);
+ alarm->setEnabled(true);
+}
+
+// taken from kpimprefs.cpp
+QString CalendarHandler::timezone() {
+ QString zone;
+
+ KConfig korgcfg(locate(QString::fromLatin1("config"), QString::fromLatin1("korganizerrc")));
+ korgcfg.setGroup("Time & Date");
+ QString tz(korgcfg.readEntry("TimeZoneId"));
+ if(!tz.isEmpty()) {
+ zone = tz;
+ } else {
+ char zonefilebuf[PATH_MAX];
+
+ int len = ::readlink("/etc/localtime", zonefilebuf, PATH_MAX);
+ if(len > 0 && len < PATH_MAX) {
+ zone = QString::fromLocal8Bit(zonefilebuf, len);
+ zone = zone.mid(zone.find(QString::fromLatin1("zoneinfo/")) + 9);
+ } else {
+ tzset();
+ zone = tzname[0];
+ }
+ }
+ return zone;
+}
+
+#endif
diff --git a/src/calendarhandler.h b/src/calendarhandler.h
new file mode 100644
index 0000000..5e01b62
--- /dev/null
+++ b/src/calendarhandler.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_CALENDARHANDLER_H
+#define TELLICO_CALENDARHANDLER_H
+
+#include <config.h>
+#include "borrower.h"
+
+#include <kdeversion.h>
+
+// libkcal is not binary compatible between versions
+// for now, just support KDE 3.4 and higher
+#if defined(HAVE_KCAL) && KDE_IS_VERSION(3,3,90)
+#define USE_KCAL
+#endif
+
+namespace KCal {
+ class CalendarResources;
+ class Todo;
+}
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class CalendarHandler {
+public:
+ static void addLoans(Data::LoanVec loans);
+ static void modifyLoans(Data::LoanVec loans);
+ static void removeLoans(Data::LoanVec loans);
+
+private:
+ static QString timezone();
+
+#ifdef USE_KCAL
+ // helper function
+ static void addLoans(Data::LoanVec loans, KCal::CalendarResources* resources);
+ static bool checkCalendar(KCal::CalendarResources* resources);
+ static void populateTodo(KCal::Todo* todo, Data::LoanPtr loan);
+#endif
+};
+
+} // end namespace
+
+#endif
diff --git a/src/cite/Makefile.am b/src/cite/Makefile.am
new file mode 100644
index 0000000..74e7c81
--- /dev/null
+++ b/src/cite/Makefile.am
@@ -0,0 +1,20 @@
+AM_CPPFLAGS = $(all_includes)
+METASOURCES = AUTO
+KDE_OPTIONS = noautodist
+CLEANFILES = *~ *.loT
+noinst_LIBRARIES = libcite.a
+libcite_a_SOURCES = lyxpipe.cpp actionmanager.cpp clipboard.cpp openoffice.cpp
+
+EXTRA_DIST = \
+actionmanager.h actionmanager.cpp \
+lyxpipe.h lyxpipe.cpp \
+actionmanager.h actionmanager.cpp \
+openoffice.h openoffice.cpp \
+clipboard.h clipboard.cpp \
+handler.h
+
+OOO_SUBDIR = ooo
+
+if WITH_OOO
+SUBDIRS = $(OOO_SUBDIR)
+endif
diff --git a/src/cite/actionmanager.cpp b/src/cite/actionmanager.cpp
new file mode 100644
index 0000000..905f81a
--- /dev/null
+++ b/src/cite/actionmanager.cpp
@@ -0,0 +1,85 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "actionmanager.h"
+#include "lyxpipe.h"
+#include "clipboard.h"
+#include "openoffice.h"
+#include "../entry.h"
+#include "../tellico_debug.h"
+
+using Tellico::Cite::ActionManager;
+
+ActionManager::ActionManager* ActionManager::self() {
+ static ActionManager self;
+ return &self;
+}
+
+ActionManager::ActionManager() : m_action(0) {
+}
+
+ActionManager::~ActionManager() {
+ delete m_action;
+}
+
+bool ActionManager::connect(CiteAction action_) {
+ if(m_action && m_action->type() == action_) {
+ return m_action->connect();
+ } else if(m_action) {
+ delete m_action;
+ m_action = 0;
+ }
+
+ switch(action_) {
+ case Cite::CiteClipboard:
+ m_action = new Clipboard();
+ break;
+
+ case Cite::CiteLyxpipe:
+ m_action = new Lyxpipe();
+ break;
+
+ case Cite::CiteOpenOffice:
+ m_action = new OpenOffice();
+ break;
+ }
+ return m_action ? m_action->connect() : false;
+}
+
+bool ActionManager::cite(CiteAction action_, Data::EntryVec entries_) {
+ if(entries_.isEmpty()) {
+ myDebug() << "ActionManager::cite() - no entries to cite" << endl;
+ return false;
+ }
+ if(m_action && m_action->type() != action_) {
+ delete m_action;
+ m_action = 0;
+ }
+ if(!m_action && !connect(action_)) {
+ myDebug() << "ActionManager::cite() - unable to connect" << endl;
+ return false;
+ }
+ if(!m_action) {
+ myDebug() << "ActionManager::cite() - no action found" << endl;
+ return false;
+ }
+
+ return m_action->cite(entries_);
+}
+
+bool ActionManager::isEnabled(CiteAction action_) {
+ if(action_ == CiteOpenOffice) {
+ return OpenOffice::hasLibrary();
+ }
+ return true;
+}
diff --git a/src/cite/actionmanager.h b/src/cite/actionmanager.h
new file mode 100644
index 0000000..fd6ffd1
--- /dev/null
+++ b/src/cite/actionmanager.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_CITE_ACTIONMANAGER_H
+#define TELLICO_CITE_ACTIONMANAGER_H
+
+#include "../datavectors.h"
+#include "handler.h"
+
+namespace Tellico {
+ namespace Cite {
+
+enum CiteAction {
+ CiteClipboard,
+ CiteLyxpipe,
+ CiteOpenOffice
+};
+
+/**
+ * @author Robby Stephenson
+ */
+class Action {
+public:
+ Action() {}
+ virtual ~Action() {}
+
+ virtual CiteAction type() const = 0;
+ virtual bool connect() { return true; }
+ virtual bool cite(Data::EntryVec entries) = 0;
+ virtual State state() const { return Success; }
+};
+
+/**
+ * @author Robby Stephenson
+ */
+class ActionManager {
+public:
+ static ActionManager* self();
+ ~ActionManager();
+
+ bool cite(CiteAction action, Data::EntryVec entries);
+ static bool isEnabled(CiteAction action);
+
+private:
+ ActionManager();
+ bool connect(CiteAction action);
+
+ Action* m_action;
+};
+
+ }
+}
+
+#endif
diff --git a/src/cite/clipboard.cpp b/src/cite/clipboard.cpp
new file mode 100644
index 0000000..9b98b89
--- /dev/null
+++ b/src/cite/clipboard.cpp
@@ -0,0 +1,51 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "clipboard.h"
+#include "../collection.h"
+#include "../translators/bibtexhandler.h"
+
+#include <klocale.h>
+
+#include <qapplication.h>
+#include <qclipboard.h>
+
+using Tellico::Cite::Clipboard;
+
+Clipboard::Clipboard() : Action() {
+}
+
+bool Clipboard::cite(Data::EntryVec entries_) {
+ if(entries_.isEmpty()) {
+ return false;
+ }
+
+ Data::CollPtr coll = entries_.front()->collection();
+ if(!coll || coll->type() != Data::Collection::Bibtex) {
+ return false;
+ }
+
+ QString s = QString::fromLatin1("\\cite{");
+ for(Data::EntryVecIt it = entries_.begin(); it != entries_.end(); ++it) {
+ s += BibtexHandler::bibtexKey(it.data());
+ if(!it.nextEnd()) {
+ s += QString::fromLatin1(", ");
+ }
+ }
+ s += '}';
+
+ QClipboard *cb = QApplication::clipboard();
+ cb->setText(s, QClipboard::Clipboard);
+ return true;
+}
+
diff --git a/src/cite/clipboard.h b/src/cite/clipboard.h
new file mode 100644
index 0000000..153f02f
--- /dev/null
+++ b/src/cite/clipboard.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_CITE_CLIPBOARD_H
+#define TELLICO_CITE_CLIPBOARD_H
+
+#include "actionmanager.h"
+
+namespace Tellico {
+ namespace Cite {
+
+/**
+ * @author Robby Stephenson
+*/
+class Clipboard : public Action {
+public:
+ Clipboard();
+
+ virtual CiteAction type() const { return CiteClipboard; }
+ virtual bool cite(Data::EntryVec entries);
+};
+
+ }
+}
+
+#endif
diff --git a/src/cite/handler.h b/src/cite/handler.h
new file mode 100644
index 0000000..d03a3e7
--- /dev/null
+++ b/src/cite/handler.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_CITE_HANDLER_H
+#define TELLICO_CITE_HANDLER_H
+
+#include <map>
+#include <string>
+
+namespace Tellico {
+ namespace Cite {
+
+enum State {
+ NoConnection,
+ NoDocument,
+ NoCitation,
+ Success
+};
+
+typedef std::map<std::string, std::string> Map;
+
+/**
+ * @author Robby Stephenson
+ */
+class Handler {
+public:
+ Handler() {}
+ virtual ~Handler() {}
+
+ virtual bool connect() = 0;
+ virtual bool cite(Map& s) = 0;
+ virtual State state() const = 0;
+
+ // really specific to ooo
+ void setHost(const char* host) { m_host = host; }
+ const std::string& host() const { return m_host; }
+ void setPort(int port) { m_port = port; }
+ int port() const { return m_port; }
+ void setPipe(const char* pipe) { m_pipe = pipe; }
+ const std::string& pipe() const { return m_pipe; }
+
+private:
+ std::string m_host;
+ int m_port;
+ std::string m_pipe;
+};
+
+ }
+}
+
+#endif
diff --git a/src/cite/lyxpipe.cpp b/src/cite/lyxpipe.cpp
new file mode 100644
index 0000000..6075324
--- /dev/null
+++ b/src/cite/lyxpipe.cpp
@@ -0,0 +1,92 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "lyxpipe.h"
+#include "../collection.h"
+#include "../translators/bibtexhandler.h"
+#include "../tellico_kernel.h"
+#include "../core/tellico_config.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+
+#include <qfile.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+using Tellico::Cite::Lyxpipe;
+
+Lyxpipe::Lyxpipe() : Action() {
+}
+
+bool Lyxpipe::cite(Data::EntryVec entries_) {
+ if(entries_.isEmpty()) {
+ return false;
+ }
+
+ Data::CollPtr coll = entries_.front()->collection();
+ if(!coll || coll->type() != Data::Collection::Bibtex) {
+ myDebug() << "Lyxpipe::cite() - collection must be a bibliography!" << endl;
+ return false;
+ }
+
+ QString lyxpipe = Config::lyxpipe();
+ lyxpipe += QString::fromLatin1(".in");
+// myDebug() << "Lyxpipe::cite() - " << lyxpipe << endl;
+
+ QString errorStr = i18n("<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>").arg(lyxpipe);
+
+ QFile file(lyxpipe);
+ if(!file.exists()) {
+ Kernel::self()->sorry(errorStr);
+ return false;
+ }
+
+ int pipeFd = ::open(QFile::encodeName(lyxpipe), O_WRONLY);
+ if(!file.open(IO_WriteOnly, pipeFd)) {
+ Kernel::self()->sorry(errorStr);
+ ::close(pipeFd);
+ return false;
+ }
+
+ QString output;
+ QTextStream ts(&file);
+ for(Data::EntryVecIt it = entries_.begin(); it != entries_.end(); ++it) {
+ QString s = BibtexHandler::bibtexKey(it.data());
+ if(s.isEmpty()) {
+ continue;
+ }
+ output += s;
+ if(!it.nextEnd() && !output.isEmpty()) {
+ // pybliographer uses comma-space, and pyblink expects the space there
+ output += QString::fromLatin1(", ");
+ }
+ }
+ if(output.isEmpty()) {
+ myDebug() << "Lyxpipe::cite() - no available bibtex keys!" << endl;
+ return false;
+ }
+
+// ts << "LYXSRV:tellico:hello\n";
+ ts << "LYXCMD:tellico:citation-insert:";
+ ts << output.local8Bit();
+ ts << "\n";
+// ts << "LYXSRV:tellico:bye\n";
+ file.flush();
+ file.close();
+ ::close(pipeFd);
+ return true;
+}
diff --git a/src/cite/lyxpipe.h b/src/cite/lyxpipe.h
new file mode 100644
index 0000000..da738ae
--- /dev/null
+++ b/src/cite/lyxpipe.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : $EMAIL
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_CITE_LYXPIPE_H
+#define TELLICO_CITE_LYXPIPE_H
+
+#include "actionmanager.h"
+
+namespace Tellico {
+ namespace Cite {
+
+/**
+ * @author Robby Stephenson
+ */
+class Lyxpipe : public Action {
+public:
+ Lyxpipe();
+
+ virtual CiteAction type() const { return CiteClipboard; }
+ virtual bool cite(Data::EntryVec entries);
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/cite/ooo/Makefile.am b/src/cite/ooo/Makefile.am
new file mode 100644
index 0000000..ff11fca
--- /dev/null
+++ b/src/cite/ooo/Makefile.am
@@ -0,0 +1,88 @@
+METASOURCES = AUTO
+
+KDE_CXXFLAGS = $(USE_EXCEPTIONS)
+KDE_OPTIONS = noautodist
+
+COMID=gcc3
+CPPULIB=-luno_cppu
+CPPUHELPERLIB=-luno_cppuhelper$(COMID)
+SALLIB=-luno_sal
+SALHELPERLIB=-luno_salhelper$(COMID)
+# REGLIB=-lreg
+
+# Where the UNO includes will be generated
+INCDIR = $(srcdir)/.include
+UNODIR = $(INCDIR)/uno
+
+# OpenOffice.org additional includes and libraries
+# might have to be adjusted for other architectures
+OFFICE_includes = -I$(INCDIR) -I$(UNODIR) -DUNX -DGCC -DLINUX -DCPPU_ENV=$(COMID) -DOSL_DEBUG_LEVEL=0
+OFFICE_libraries = $(CPPULIB) $(CPPUHELPERLIB) $(SALLIB) $(SALHELPERLIB)
+
+AM_CPPFLAGS = $(all_includes) $(OFFICE_SDK_includes) $(OFFICE_includes)
+
+kde_module_LTLIBRARIES = tellico_ooo.la
+
+tellico_ooo_la_SOURCES = ooohandler.cpp interface.cpp
+tellico_ooo_la_LDFLAGS = -module $(KDE_PLUGIN) $(KDE_RPATH) \
+ $(all_libraries) $(OFFICE_libraries)
+tellico_ooo_la_LIBADD = $(OFFICE_libadd)
+
+EXTRA_DIST = ooohandler.h ooohandler.cpp \
+ interface.h interface.cpp
+
+CLEANFILES = *~ *.loT
+
+# Clean target for the generated stuff
+clean-local:
+ rm -rf $(UNODIR) $(INCDIR) $(CLEANFILES)
+
+UNOTYPES := \
+ com.sun.star.uno.XComponentContext \
+ com.sun.star.lang.XMultiServiceFactory \
+ com.sun.star.lang.XSingleComponentFactory \
+ com.sun.star.lang.XComponent \
+ com.sun.star.lang.XServiceInfo \
+ com.sun.star.bridge.XUnoUrlResolver \
+ com.sun.star.frame.XDesktop \
+ com.sun.star.frame.XComponentLoader \
+ com.sun.star.text.ControlCharacter \
+ com.sun.star.text.XDocumentIndexesSupplier \
+ com.sun.star.text.XDocumentIndex \
+ com.sun.star.text.XTextDocument \
+ com.sun.star.text.XTextField \
+ com.sun.star.text.XTextViewCursor \
+ com.sun.star.text.XTextViewCursorSupplier \
+ com.sun.star.text.BibliographyDataType \
+ com.sun.star.container.XIndexAccess \
+ com.sun.star.container.XHierarchicalNameAccess \
+ com.sun.star.registry.XSimpleRegistry \
+ com.sun.star.beans.XPropertySet \
+ com.sun.star.sdbc.XRow \
+ com.sun.star.sdbc.XRowSet \
+ com.sun.star.sdbc.XResultSetMetaDataSupplier \
+ com.sun.star.sdbc.XResultSetUpdate \
+ com.sun.star.sdbc.XRowUpdate \
+ com.sun.star.sdbc.SQLException \
+ com.sun.star.sdb.CommandType \
+ com.sun.star.document.XEventListener \
+ com.sun.star.document.XEventBroadcaster \
+ com.sun.star.uno.XWeak \
+ com.sun.star.uno.XAggregation \
+ com.sun.star.lang.XTypeProvider
+
+
+UNOHPPFILES = $(foreach t,$(UNOTYPES),$(UNODIR)/$(subst .,/,$(t)).hpp)
+
+interface.o: $(UNOHPPFILES) $(INCDIR)
+
+$(INCDIR):
+ mkdir -p $(INCDIR)
+
+$(UNODIR):
+ mkdir -p $(UNODIR)
+
+$(UNOHPPFILES): $(UNODIR)
+ $(CPPUMAKER) -Gc -BUCR -O$(UNODIR) $(foreach t,$(UNOTYPES),-T$(t)) \
+ $(OFFICE_registry)
+
diff --git a/src/cite/ooo/interface.cpp b/src/cite/ooo/interface.cpp
new file mode 100644
index 0000000..383ed1e
--- /dev/null
+++ b/src/cite/ooo/interface.cpp
@@ -0,0 +1,430 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "interface.h"
+
+#include <cppuhelper/bootstrap.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/bridge/XUnoUrlResolver.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/text/ControlCharacter.hpp>
+#include <com/sun/star/text/XDocumentIndexesSupplier.hpp>
+#include <com/sun/star/text/XDocumentIndex.hpp>
+#include <com/sun/star/text/XTextField.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+#include <com/sun/star/text/BibliographyDataType.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/sdbc/XResultSetUpdate.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XRowUpdate.hpp>
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/document/XEventBroadcaster.hpp>
+
+#include <iostream>
+
+#define DEBUG(s) std::cout << s << std::endl
+#define OUSTR(s) ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+#define OU2O(s) OUStringToOString(s, RTL_TEXTENCODING_ASCII_US)
+#define O2OU(s) OStringToOUString(s.c_str(), RTL_TEXTENCODING_UTF8)
+
+using Tellico::Cite::OOOHandler;
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace rtl;
+using namespace cppu;
+
+namespace Tellico {
+ namespace Cite {
+ typedef cppu::WeakImplHelper1<document::XEventListener> EventListenerHelper;
+ }
+}
+
+class OOOHandler::Interface::EventListener : public cppu::WeakImplHelper1<document::XEventListener> {
+public:
+ EventListener(OOOHandler::Interface* i) : EventListenerHelper(), m_interface(i) {}
+ virtual void SAL_CALL disposing(const lang::EventObject&) throw(RuntimeException) {
+ DEBUG("Document is being disposed");
+ m_interface->disconnect();
+ }
+ virtual void SAL_CALL notifyEvent(const document::EventObject&) throw(RuntimeException) {
+// std::cout << "Event: " << rtl::OUStringToOString(aEvent.EventName,RTL_TEXTENCODING_ISO_8859_1).getStr() << std::endl;
+ }
+private:
+ OOOHandler::Interface* m_interface;
+};
+
+OOOHandler::Interface::Interface() : m_listener(0) {
+}
+
+OOOHandler::Interface::~Interface() {
+ delete m_listener;
+ m_listener = 0;
+}
+
+bool OOOHandler::Interface::isConnected() const {
+ return m_gsmgr.is();
+}
+
+bool OOOHandler::Interface::connect(const std::string& host_, int port_, const std::string& pipe_) {
+ if(isConnected()) {
+ return true;
+ }
+
+ // create the initial component context
+ Reference<uno::XComponentContext> context;
+ try {
+ context = defaultBootstrap_InitialComponentContext();
+ } catch(Exception& e) {
+ OString o = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ std::cout << "Unable to get initial component context: " << o << std::endl;
+ return false;
+ } catch(...) {
+ DEBUG("Unable to get initial component context.");
+ return false;
+ }
+
+ // retrieve the servicemanager from the context
+ Reference<lang::XMultiComponentFactory> rServiceManager;
+ try {
+ rServiceManager = context->getServiceManager();
+ } catch(...) {
+ DEBUG("Unable to get initial service manager.");
+ return false;
+ }
+
+ // instantiate a sample service with the servicemanager.
+ OUString s = OUString::createFromAscii("com.sun.star.bridge.UnoUrlResolver");
+ Reference<uno::XInterface> rInstance;
+ try {
+ rInstance = rServiceManager->createInstanceWithContext(s, context);
+ } catch(...) {
+ DEBUG("Unable to get initial instance.");
+ return false;
+ }
+
+ // Query for the XUnoUrlResolver interface
+ Reference<bridge::XUnoUrlResolver> rResolver(rInstance, UNO_QUERY);
+ if(!rResolver.is()) {
+ DEBUG("Error: Couldn't instantiate com.sun.star.bridge.UnoUrlResolver service");
+ return false;
+ }
+
+ // "uno:socket,host=%s,port=%s;urp;StarOffice.ComponentContext"%(host,port)
+ // "uno:pipe,name=%s;urp;StarOffice.ComponentContext"%pipe
+ if(pipe_.empty()) {
+ s = OUSTR("socket,host=") + O2OU(host_) + OUSTR(",port=") + OUString::valueOf((sal_Int32)port_);
+ } else {
+ s = OUSTR("pipe,name=") + O2OU(pipe_);
+ }
+ std::cout << "Connection string: " << OU2O(s) << std::endl;
+ s = OUSTR("uno:") + s + OUSTR(";urp;StarOffice.ServiceManager");
+
+ try {
+ rInstance = rResolver->resolve(s);
+ if(!rInstance.is()) {
+ DEBUG("StarOffice.ServiceManager is not exported from remote counterpart");
+ return false;
+ }
+
+ m_gsmgr = Reference<lang::XMultiServiceFactory>(rInstance, UNO_QUERY);
+ if(m_gsmgr.is()) {
+ DEBUG("Connected successfully to office");
+ } else {
+ DEBUG("XMultiServiceFactory interface is not exported");
+ }
+ } catch(Exception& e) {
+ std::cout << "Error: " << OU2O(e.Message) << std::endl;
+ } catch(...) {
+ DEBUG("Unable to resolve connection.");
+ return false;
+ }
+ return m_gsmgr.is();
+}
+
+bool OOOHandler::Interface::disconnect() {
+ m_gsmgr = 0;
+ m_dsmgr = 0;
+ m_doc = 0;
+ m_bib = 0;
+ m_cursor = 0;
+ return true;
+}
+
+bool OOOHandler::Interface::createDocument() {
+ if(!m_gsmgr.is()) {
+ return false;
+ }
+
+ if(m_doc.is()) {
+ return true;
+ }
+
+ // get the desktop service using createInstance, returns an XInterface type
+ Reference<uno::XInterface> xInstance = m_gsmgr->createInstance(OUString::createFromAscii("com.sun.star.frame.Desktop"));
+ Reference<frame::XDesktop> desktop(xInstance, UNO_QUERY);
+
+ Reference<lang::XComponent> writer = desktop->getCurrentComponent();
+ Reference<lang::XServiceInfo> info(writer, UNO_QUERY);
+ if(info.is() && info->getImplementationName() == OUString::createFromAscii("SwXTextDocument")) {
+ DEBUG("Document already open");
+ } else {
+ DEBUG("Opening a new document");
+ //query for the XComponentLoader interface
+ Reference<frame::XComponentLoader> rComponentLoader(desktop, UNO_QUERY);
+ if(!rComponentLoader.is()){
+ DEBUG("XComponentloader failed to instantiate");
+ return 0;
+ }
+
+ //get an instance of the OOowriter document
+ writer = rComponentLoader->loadComponentFromURL(OUSTR("private:factory/swriter"),
+ OUSTR("_default"),
+ 0,
+ Sequence<beans::PropertyValue>());
+ }
+
+ //Manage many events with EventListener
+ Reference<document::XEventBroadcaster> eventBroadcast(writer, UNO_QUERY);
+ m_listener = new EventListener(this);
+ Reference<document::XEventListener> xEventListener = static_cast<document::XEventListener*>(m_listener);
+ eventBroadcast->addEventListener(xEventListener);
+
+ Reference<frame::XController> controller = Reference<frame::XModel>(writer, UNO_QUERY)->getCurrentController();
+ m_cursor = Reference<text::XTextViewCursorSupplier>(controller, UNO_QUERY)->getViewCursor();
+ m_doc = Reference<text::XTextDocument>(writer, UNO_QUERY);
+ if(m_doc.is()) {
+ m_dsmgr = Reference<lang::XMultiServiceFactory>(m_doc, UNO_QUERY);
+ }
+ return m_doc.is();
+}
+
+bool OOOHandler::Interface::updateBibliography() {
+ if(!m_bib.is()) {
+ createBibliography();
+ if(!m_bib.is()) {
+ DEBUG("ERROR: could not create or find bibliography index");
+ return false;
+ }
+ }
+
+ m_bib->update();
+ return true;
+}
+
+void OOOHandler::Interface::createBibliography() {
+ Reference<container::XIndexAccess> indexes(Reference<text::XDocumentIndexesSupplier>(m_doc, UNO_QUERY)->getDocumentIndexes(), UNO_QUERY);
+ for(int i = 0; i < indexes->getCount(); ++i) {
+ Reference<lang::XServiceInfo> info(indexes->getByIndex(i), UNO_QUERY);
+ if(info->supportsService(OUSTR("com.sun.star.text.Bibliography"))) {
+ DEBUG("Found existing bibliography...");
+ m_bib = Reference<text::XDocumentIndex>(indexes->getByIndex(i), UNO_QUERY);
+ break;
+ }
+ }
+
+ if(!m_bib.is()) {
+ DEBUG("Creating new bibliography...");
+ Reference<text::XText> text = m_doc->getText();
+ Reference<text::XTextRange> textRange(text->createTextCursor(), UNO_QUERY);
+ Reference<text::XTextCursor> cursor(textRange, UNO_QUERY);
+ cursor->gotoEnd(false);
+ text->insertControlCharacter(textRange, text::ControlCharacter::PARAGRAPH_BREAK, false);
+ m_bib = Reference<text::XDocumentIndex>(m_dsmgr->createInstance(OUSTR("com.sun.star.text.Bibliography")), UNO_QUERY);
+ Reference<text::XTextContent> textContent(m_bib, UNO_QUERY);
+ text->insertTextContent(textRange, textContent, false);
+ }
+}
+
+bool OOOHandler::Interface::insertCitations(Cite::Map& fields) {
+ Reference<text::XTextField> entry(m_dsmgr->createInstance(OUString::createFromAscii("com.sun.star.text.TextField.Bibliography")), UNO_QUERY);
+ if(!entry.is()) {
+ DEBUG("Interface::insertCitation - can't create TextField");
+ return false;
+ }
+ Sequence<beans::PropertyValue> values(fields.size());
+ int i = 0;
+ for(Cite::Map::iterator it = fields.begin(); it != fields.end(); ++it, ++i) {
+ values[i] = propValue(it->first, it->second);
+ std::cout << "Setting " << OU2O(values[i].Name) << " = " << it->second << std::endl;
+ }
+ Reference<beans::XPropertySet>(entry, UNO_QUERY)->setPropertyValue(OUSTR("Fields"), Any(values));
+
+ Reference<text::XText> text = m_doc->getText();
+ Reference<text::XTextCursor> cursor = text->createTextCursorByRange(Reference<text::XTextRange>(m_cursor, UNO_QUERY));
+ Reference<text::XTextRange> textRange(cursor, UNO_QUERY);
+ Reference<text::XTextContent> textContent(entry, UNO_QUERY);
+ text->insertTextContent(textRange, textContent, false);
+ return true;
+}
+
+beans::PropertyValue OOOHandler::Interface::propValue(const std::string& field, const std::string& value) {
+ return beans::PropertyValue(O2OU(field), 0, fieldValue(field, value), beans::PropertyState_DIRECT_VALUE);
+}
+
+uno::Any OOOHandler::Interface::fieldValue(const std::string& field, const std::string& value) {
+ if(field == "BibiliographicType" || field == "BibliographicType") { // in case the typo gets fixed
+ return typeValue(value);
+ }
+ return Any(O2OU(value));
+}
+
+uno::Any OOOHandler::Interface::typeValue(const std::string& value) {
+ if(value == "article") {
+ return Any(text::BibliographyDataType::ARTICLE);
+ } else if(value == "book") {
+ return Any(text::BibliographyDataType::BOOK);
+ } else if(value == "booklet") {
+ return Any(text::BibliographyDataType::BOOKLET);
+ } else if(value == "conference") {
+ return Any(text::BibliographyDataType::CONFERENCE);
+ } else if(value == "inbook") {
+ return Any(text::BibliographyDataType::INBOOK);
+ } else if(value == "incollection") {
+ return Any(text::BibliographyDataType::INCOLLECTION);
+ } else if(value == "inproceedings") {
+ return Any(text::BibliographyDataType::INPROCEEDINGS);
+ } else if(value == "journal") {
+ return Any(text::BibliographyDataType::JOURNAL);
+ } else if(value == "manual") {
+ return Any(text::BibliographyDataType::MANUAL);
+ } else if(value == "mastersthesis") {
+ return Any(text::BibliographyDataType::MASTERSTHESIS);
+ } else if(value == "misc") {
+ return Any(text::BibliographyDataType::MISC);
+ } else if(value == "phdthesis") {
+ return Any(text::BibliographyDataType::PHDTHESIS);
+ } else if(value == "proceedings") {
+ return Any(text::BibliographyDataType::PROCEEDINGS);
+ } else if(value == "techreport") {
+ return Any(text::BibliographyDataType::TECHREPORT);
+ } else if(value == "unpublished") {
+ return Any(text::BibliographyDataType::UNPUBLISHED);
+ } else {
+ // periodical ?
+ return Any(text::BibliographyDataType::BOOK);
+ }
+}
+
+bool OOOHandler::Interface::insertRecords(Cite::Map& fields) {
+ Reference<uno::XInterface> interface;
+ try {
+ interface = m_gsmgr->createInstance(OUString::createFromAscii("com.sun.star.sdb.RowSet"));
+ } catch(Exception& e) {
+ std::cout << "Error: " << OU2O(e.Message) << std::endl;
+ }
+ if(!interface.is()) {
+ DEBUG("Could not create rowset interface");
+ return false;
+ }
+
+ Reference<sdbc::XRowSet> rowSet(interface, UNO_QUERY);
+ if(!rowSet.is()) {
+ DEBUG("Could not create rowset interface");
+ return false;
+ }
+
+ Reference<beans::XPropertySet> props(rowSet, UNO_QUERY);
+ props->setPropertyValue(OUSTR("DataSourceName"), Any(OUSTR("Bibliography")));
+ props->setPropertyValue(OUSTR("CommandType"), Any(sdb::CommandType::COMMAND));
+ OUString s = OUSTR("SELECT COUNT(*) FROM \"biblio\" WHERE identifier='") + O2OU(fields["Identifier"]) + OUSTR("'");
+ props->setPropertyValue(OUSTR("Command"), Any(s));
+
+ try {
+ rowSet->execute();
+ } catch(sdbc::SQLException& e) {
+ DEBUG(OU2O(s));
+ DEBUG(OUSTR("SQL error - ") + e.SQLState);
+ return false;
+ } catch(Exception& e) {
+ DEBUG(OU2O(s));
+ DEBUG(OUSTR("General error - ") + e.Message);
+ return false;
+ }
+
+ Reference<sdbc::XRow> row(rowSet, UNO_QUERY);
+ int count = 0;
+ if(rowSet->next()) {
+ count = row->getString(1).toInt32();
+ }
+
+ if(count > 0) {
+ DEBUG("Found existing bibliographic entries, updating...");
+ } else {
+ DEBUG("Inserting new bibliographic entry...");
+ }
+
+ s = OUSTR("SELECT * FROM \"biblio\"");
+ if(count > 0) {
+ s += OUSTR(" WHERE identifier='") + O2OU(fields["Identifier"]) + OUSTR("'");
+ }
+ props->setPropertyValue(OUSTR("Command"), Any(s));
+
+ try {
+ rowSet->execute();
+ } catch(sdbc::SQLException& e) {
+ DEBUG(OU2O(s));
+ DEBUG(OUSTR("SQL error(2) - ") + e.SQLState);
+ return false;
+ } catch(Exception& e) {
+ DEBUG(OU2O(s));
+ DEBUG(OUSTR("General error(2) - ") + e.Message);
+ return false;
+ }
+
+ Reference<sdbc::XResultSet> resultSet(rowSet, UNO_QUERY);
+ Reference<sdbc::XResultSetMetaDataSupplier> mdSupplier(resultSet, UNO_QUERY);
+ Reference<sdbc::XResultSetMetaData> metaData = mdSupplier->getMetaData();
+
+ Reference<sdbc::XRowUpdate> rowUpdate(rowSet, UNO_QUERY);
+ Reference<sdbc::XResultSetUpdate> update(rowSet, UNO_QUERY);
+ if(count > 0) {
+ resultSet->last();
+ } else {
+ update->moveToInsertRow();
+ }
+
+ const long colCount = metaData->getColumnCount();
+ // column numbers start with 1
+ for(long i = 1; i <= colCount; ++i) {
+ std::string s = OU2O(metaData->getColumnName(i)).getStr();
+ std::string value = fields[s];
+ if(!value.empty()) {
+ std::cout << "column " << i << ": " << OU2O(metaData->getColumnName(i)) << "..." << std::endl;
+ std::cout << s << " = " << value << std::endl;
+ try {
+ rowUpdate->updateString(i, O2OU(value));
+ } catch(sdbc::SQLException& e) {
+ DEBUG(OUSTR("SQL error(3) - ") + e.SQLState);
+ } catch(Exception& e) {
+ DEBUG(OUSTR("General error(3) - ") + e.Message);
+ }
+ }
+ }
+ if(count > 0) {
+ update->updateRow();
+ } else {
+ update->insertRow();
+ }
+
+ Reference<lang::XComponent>(rowSet, UNO_QUERY)->dispose();
+ return true;
+}
diff --git a/src/cite/ooo/interface.h b/src/cite/ooo/interface.h
new file mode 100644
index 0000000..c1a0f33
--- /dev/null
+++ b/src/cite/ooo/interface.h
@@ -0,0 +1,62 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_CITE_OOOHANDLER_INTERFACE_H
+#define TELLICO_CITE_OOOHANDLER_INTERFACE_H
+
+#include "ooohandler.h"
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/text/XDocumentIndex.hpp>
+#include <com/sun/star/text/XTextViewCursor.hpp>
+
+namespace Tellico {
+ namespace Cite {
+
+class OOOHandler::Interface {
+ friend class OOOHandler;
+
+ Interface();
+ ~Interface();
+
+ bool isConnected() const;
+ bool connect(const std::string& host, int port, const std::string& pipe);
+ bool disconnect();
+ bool createDocument();
+ bool updateBibliography();
+ bool insertCitations(Cite::Map& fields);
+ bool insertRecords(Cite::Map& fields);
+
+private:
+ void createBibliography();
+ com::sun::star::beans::PropertyValue propValue(const std::string& field, const std::string& value);
+ com::sun::star::uno::Any fieldValue(const std::string& field, const std::string& value);
+ com::sun::star::uno::Any typeValue(const std::string& value);
+
+ // global service manager
+ com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory> m_gsmgr;
+ // document service manager
+ com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory> m_dsmgr;
+ com::sun::star::uno::Reference<com::sun::star::text::XTextDocument> m_doc;
+ com::sun::star::uno::Reference<com::sun::star::text::XDocumentIndex> m_bib;
+ com::sun::star::uno::Reference<com::sun::star::text::XTextViewCursor> m_cursor;
+
+ class EventListener;
+ EventListener* m_listener;
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/cite/ooo/ooohandler.cpp b/src/cite/ooo/ooohandler.cpp
new file mode 100644
index 0000000..1741896
--- /dev/null
+++ b/src/cite/ooo/ooohandler.cpp
@@ -0,0 +1,159 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "ooohandler.h"
+#include "interface.h"
+
+#include <iostream>
+
+extern "C" {
+ Tellico::Cite::Handler* handler() {
+ return new Tellico::Cite::OOOHandler();
+ }
+}
+
+using Tellico::Cite::OOOHandler;
+Tellico::Cite::Map OOOHandler::s_fieldsMap;
+
+/*
+QString OOOHandler::OUString2Q(const rtl::OUString& str) {
+ const uint len = str.getLength();
+ QChar* uni = new QChar[len + 1];
+
+ const sal_Unicode* ouPtr = str.getStr();
+ const sal_Unicode* ouEnd = ouPtr + len;
+ QChar* qPtr = uni;
+
+ while (ouPtr != ouEnd) {
+ *(qPtr++) = *(ouPtr++);
+ }
+
+ *qPtr = 0;
+
+ QString ret(uni, len);
+ delete[] uni;
+
+ return ret;
+}
+
+rtl::OUString OOOHandler::QString2OU(const QString& str) {
+ const uint len = str.length();
+ sal_Unicode* uni = new sal_Unicode[len + 1];
+
+ const QChar* qPtr = str.unicode();
+ const QChar* qEnd = qPtr + len;
+ sal_Unicode* uPtr = uni;
+
+ while (qPtr != qEnd) {
+ *(uPtr++) = (*(qPtr++)).unicode();
+ }
+
+ *uPtr = 0;
+
+ rtl::OUString ret(uni, len);
+ delete[] uni;
+
+ return ret;
+}
+*/
+
+void OOOHandler::buildFieldsMap() {
+// s_fieldsMap["entry-type"] = "BibliographicType";
+ s_fieldsMap["entry-type"] = "BibiliographicType"; // typo in OpenOffice
+ s_fieldsMap["key"] = "Identifier";
+ s_fieldsMap["title"] = "Title";
+ s_fieldsMap["author"] = "Author";
+ s_fieldsMap["booktitle"] = "Booktitle";
+ s_fieldsMap["address"] = "Address";
+ s_fieldsMap["chapter"] = "Chapter";
+ s_fieldsMap["edition"] = "Edition";
+ s_fieldsMap["editor"] = "Editor";
+ s_fieldsMap["organization"] = "Organizations"; // OOO has an 's'
+ s_fieldsMap["publisher"] = "Publisher";
+ s_fieldsMap["pages"] = "Pages";
+ s_fieldsMap["howpublished"] = "Howpublished";
+ s_fieldsMap["institution"] = "Institution";
+ s_fieldsMap["journal"] = "Journal";
+ s_fieldsMap["month"] = "Month";
+ s_fieldsMap["number"] = "Number";
+ s_fieldsMap["note"] = "Note";
+ s_fieldsMap["annote"] = "Annote";
+ s_fieldsMap["series"] = "Series";
+ s_fieldsMap["volume"] = "Volume";
+ s_fieldsMap["year"] = "Year";
+ s_fieldsMap["url"] = "URL";
+ s_fieldsMap["isbn"] = "ISBN";
+}
+
+OOOHandler::OOOHandler() : Handler(), m_interface(0), m_state(NoConnection) {
+}
+
+Tellico::Cite::State OOOHandler::state() const {
+ // possibly the write got closed underneath us
+ if(m_state != NoConnection && m_interface && !m_interface->isConnected()) {
+ m_state = NoConnection;
+ }
+ return m_state;
+}
+
+bool OOOHandler::connect() {
+ if(!m_interface) {
+ m_interface = new Interface();
+ }
+
+ if(!m_interface->connect(host(), port(), pipe())) {
+ return false;
+ }
+
+ if(!m_interface->createDocument()) {
+ m_state = NoDocument;
+ return false;
+ }
+
+ m_state = NoCitation;
+ return true;
+}
+
+bool OOOHandler::cite(Map& fields) {
+ if(!m_interface && !connect()) {
+ return false;
+ }
+ Cite::Map newFields = convertFields(fields);
+ // the ooo interface can insert records in the database, but the citations in the
+ // document ARE NOT linked to them, meaning they aren't updated by changing the database
+ // the user has to manually edit each entry
+ bool success = m_interface->insertCitations(newFields) && m_interface->updateBibliography();
+// bool success = m_interface->insertRecords(newFields);
+ if(success) {
+ m_state = Success;
+// m_interface->disconnect();
+// m_state = NoConnection;
+ }
+ return success;
+}
+
+Tellico::Cite::Map OOOHandler::convertFields(Cite::Map& fields) {
+ if(s_fieldsMap.empty()) {
+ buildFieldsMap();
+ }
+
+ Cite::Map values;
+ for(Cite::Map::iterator it = s_fieldsMap.begin(); it != s_fieldsMap.end(); ++it) {
+ std::string value = fields[it->first];
+ if(!value.empty()) {
+ values[it->second] = value;
+ }
+ }
+
+ return values;
+}
diff --git a/src/cite/ooo/ooohandler.h b/src/cite/ooo/ooohandler.h
new file mode 100644
index 0000000..fd7f308
--- /dev/null
+++ b/src/cite/ooo/ooohandler.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_CITE_OOOHANDLER_H
+#define TELLICO_CITE_OOOHANDLER_H
+
+#include "../handler.h"
+
+namespace rtl {
+ class OUString;
+}
+
+namespace Tellico {
+ namespace Cite {
+
+/**
+ * @author Robby Stephenson
+ */
+class OOOHandler : public Handler {
+public:
+ OOOHandler();
+
+ virtual State state() const;
+ virtual bool connect();
+ virtual bool cite(Cite::Map& fields);
+
+private:
+// static QString OUString2Q(const rtl::OUString& str);
+// static rtl::OUString QString2OU(const QString& str);
+ static Cite::Map s_fieldsMap;
+ static void buildFieldsMap();
+
+ Cite::Map convertFields(Cite::Map& values);
+
+ class Interface;
+ Interface* m_interface;
+ // mutable since I want to change it inside state()
+ mutable State m_state;
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/cite/openoffice.cpp b/src/cite/openoffice.cpp
new file mode 100644
index 0000000..ced8b13
--- /dev/null
+++ b/src/cite/openoffice.cpp
@@ -0,0 +1,267 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "openoffice.h"
+#include "handler.h"
+#include "../collections/bibtexcollection.h"
+#include "../entry.h"
+#include "../tellico_utils.h"
+#include "../latin1literal.h"
+#include "../statusbar.h"
+#include "../tellico_kernel.h"
+#include "../tellico_debug.h"
+
+#include <klibloader.h>
+#include <kdialogbase.h>
+#include <knuminput.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <klineedit.h>
+#include <kiconloader.h>
+#include <klocale.h>
+
+#include <qiconset.h>
+#include <qlayout.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include <qfile.h>
+#include <qvgroupbox.h>
+
+using Tellico::Cite::OpenOffice;
+
+class OpenOffice::Private {
+ friend class OpenOffice;
+
+ Private() : handler(0), port(-1) {
+ KLibrary* library = Tellico::openLibrary(QString::fromLatin1("tellico_ooo"));
+ if(library) {
+ void* func = library->symbol("handler");
+ if(func) {
+ handler = ((Handler* (*)())func)();
+ }
+ }
+ }
+
+ Handler* handler;
+ // empty pipe string indicates tcp should be used
+ QString host;
+ int port;
+ QString pipe;
+};
+
+OpenOffice::OpenOffice() : Action(), d(new Private()) {
+}
+
+OpenOffice::~OpenOffice() {
+ delete d;
+}
+
+Tellico::Cite::State OpenOffice::state() const {
+ if(!d->handler) {
+ return NoConnection;
+ }
+ return d->handler->state();
+}
+
+bool OpenOffice::connect() {
+ if(!d->handler) {
+ myDebug() << "OpenOffice::connect() - unable to open OpenOffice.org plugin" << endl;
+ return false;
+ }
+
+ StatusBar::self()->setStatus(i18n("Connecting to OpenOffice.org..."));
+
+ if(d->port == -1) {
+ KConfigGroup config(kapp->config(), "OpenOffice.org");
+ d->host = config.readEntry("Host", QString::fromLatin1("localhost"));
+ d->port = config.readNumEntry("Port", 2083);
+ d->pipe = config.readPathEntry("Pipe");
+ // the ooohandler will depend on pipe.isEmpty() to indicate the port should be used
+ d->handler->setHost(d->host);
+ d->handler->setPort(d->port);
+ if(!d->pipe.isEmpty()) {
+ d->handler->setPipe(QFile::encodeName(d->pipe));
+ }
+ }
+
+ bool success = d->handler->connect();
+ bool needInput = !success;
+ while(needInput) {
+ switch(state()) {
+ case NoConnection:
+ myDebug() << "OpenOffice::connect() - NoConnection" << endl;
+ // try to reconnect
+ if(connectionDialog()) {
+ success = d->handler->connect();
+ needInput = !success;
+ } else {
+ needInput = false;
+ }
+ break;
+ case NoDocument:
+ myDebug() << "OpenOffice::connect() - NoDocument" << endl;
+ break;
+ default:
+ myDebug() << "OpenOffice::connect() - weird state" << endl;
+ break;
+ }
+ }
+ StatusBar::self()->clearStatus();
+ return success;
+}
+
+bool OpenOffice::cite(Data::EntryVec entries_) {
+ if(!connect()) {
+ myDebug() << "OpenOffice::cite() - can't connect to OpenOffice" << endl;
+ return false;
+ }
+ if(entries_.isEmpty()) {
+ myDebug() << "OpenOffice::cite() - no entries" << endl;
+ return false;
+ }
+
+ Data::CollPtr coll = entries_.front()->collection();
+ if(!coll || coll->type() != Data::Collection::Bibtex) {
+ myDebug() << "OpenOffice::cite() - not a bibtex collection" << endl;
+ return false;
+ }
+
+ const QString bibtex = QString::fromLatin1("bibtex");
+ Data::FieldVec vec = coll->fields();
+ for(Data::EntryVecIt entry = entries_.begin(); entry != entries_.end(); ++entry) {
+ Cite::Map values;
+ for(Data::FieldVec::Iterator it = vec.begin(); it != vec.end(); ++it) {
+ QString bibtexField = it->property(bibtex);
+ if(!bibtexField.isEmpty()) {
+ QString s = entry->field(it->name());
+ if(!s.isEmpty()) {
+ values[bibtexField] = s.utf8(); // always utf8
+ }
+ } else if(it->name() == Latin1Literal("isbn")) {
+ // OOO includes ISBN
+ QString s = entry->field(it->name());
+ if(!s.isEmpty()) {
+ values[it->name()] = s.utf8();
+ }
+ }
+ }
+ d->handler->cite(values);
+ }
+ return true;
+}
+
+bool OpenOffice::connectionDialog() {
+ KDialogBase dlg(Kernel::self()->widget(), "ooo connection dialog",
+ true, i18n("OpenOffice.org Connection"),
+ KDialogBase::Ok|KDialogBase::Cancel|KDialogBase::Help);
+
+ dlg.setHelp(QString::fromLatin1("openoffice-org"));
+
+ QWidget* widget = new QWidget(&dlg);
+ QBoxLayout* topLayout = new QVBoxLayout(widget, KDialog::spacingHint());
+ dlg.setMainWidget(widget);
+ // is there a better way to do a multi-line label than to insert newlines in the text?
+ QBoxLayout* blay = new QHBoxLayout(topLayout);
+ QLabel* l = new QLabel(widget);
+ l->setPixmap(DesktopIcon(QString::fromLatin1("ooo_writer"), 64));
+ blay->addWidget(l);
+ l = new QLabel(widget);
+ l->setText(i18n("Tellico was unable to connect to OpenOffice.org. "
+ "Please verify the connection settings below, and "
+ "that OpenOffice.org Writer is currently running."));
+ l->setTextFormat(Qt::RichText);
+ blay->addWidget(l);
+ blay->setStretchFactor(l, 10);
+
+ QVGroupBox* gbox = new QVGroupBox(i18n("OpenOffice.org Connection"), widget);
+ topLayout->addWidget(gbox);
+
+ QWidget* w2 = new QWidget(gbox);
+ QGridLayout* gl = new QGridLayout(w2, 2, 3, 0 /*margin*/, KDialog::spacingHint());
+ QRadioButton* radioPipe = new QRadioButton(i18n("Pipe"), w2);
+ gl->addWidget(radioPipe, 0, 0);
+ QRadioButton* radioTCP = new QRadioButton(i18n("TCP/IP"), w2);
+ gl->addWidget(radioTCP, 1, 0);
+ QButtonGroup* btnGroup = new QButtonGroup();
+ btnGroup->setRadioButtonExclusive(true);
+ btnGroup->insert(radioPipe, 0);
+ btnGroup->insert(radioTCP, 1);
+
+ KLineEdit* pipeEdit = new KLineEdit(w2);
+ pipeEdit->setText(d->pipe);
+ gl->addMultiCellWidget(pipeEdit, 0, 0, 1, 2);
+ pipeEdit->connect(radioPipe, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
+
+ KLineEdit* hostEdit = new KLineEdit(w2);
+ hostEdit->setText(d->host);
+ gl->addWidget(hostEdit, 1, 1);
+ hostEdit->connect(radioTCP, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
+ KIntSpinBox* portSpin = new KIntSpinBox(w2);
+ portSpin->setMaxValue(99999);
+ portSpin->setValue(d->port);
+ gl->addWidget(portSpin, 1, 2);
+ portSpin->connect(radioTCP, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
+
+ if(d->pipe.isEmpty()) {
+ radioTCP->setChecked(true);
+ hostEdit->setEnabled(true);
+ portSpin->setEnabled(true);
+ pipeEdit->setEnabled(false);
+ } else {
+ radioPipe->setChecked(true);
+ hostEdit->setEnabled(false);
+ portSpin->setEnabled(false);
+ pipeEdit->setEnabled(true);
+ }
+ topLayout->addStretch(10);
+
+ if(dlg.exec() != QDialog::Accepted) {
+ return false;
+ }
+
+ int p = d->port;
+ QString h = d->host;
+ QString s;
+ if(radioTCP->isChecked()) {
+ h = hostEdit->text();
+ if(h.isEmpty()) {
+ h = QString::fromLatin1("localhost");
+ }
+ p = portSpin->value();
+ } else {
+ s = pipeEdit->text();
+ }
+ d->host = h;
+ d->port = p;
+ d->pipe = s;
+
+ if(!d->host.isEmpty()) {
+ d->handler->setHost(d->host);
+ }
+ d->handler->setPort(d->port);
+ if(!d->pipe.isEmpty()) {
+ d->handler->setPipe(QFile::encodeName(d->pipe));
+ }
+
+ KConfigGroup config(kapp->config(), "OpenOffice.org");
+ config.writeEntry("Host", d->host);
+ config.writeEntry("Port", d->port);
+ config.writePathEntry("Pipe", d->pipe);
+ return true;
+}
+
+bool OpenOffice::hasLibrary() {
+ QString path = KLibLoader::findLibrary("tellico_ooo");
+ if(!path.isEmpty()) myDebug() << "OpenOffice::hasLibrary() - Found OOo plugin: " << path << endl;
+ return !path.isEmpty();
+}
diff --git a/src/cite/openoffice.h b/src/cite/openoffice.h
new file mode 100644
index 0000000..a5204ac
--- /dev/null
+++ b/src/cite/openoffice.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_CITE_OPENOFFICE_H
+#define TELLICO_CITE_OPENOFFICE_H
+
+#include "actionmanager.h"
+
+namespace Tellico {
+ namespace Cite {
+
+/**
+ * @author Robby Stephenson
+ */
+class OpenOffice : public Action {
+public:
+ OpenOffice();
+ ~OpenOffice();
+
+ virtual CiteAction type() const { return CiteOpenOffice; }
+
+ virtual bool connect();
+ virtual bool cite(Data::EntryVec entries);
+ virtual State state() const;
+
+ static bool hasLibrary();
+
+private:
+ bool connectionDialog();
+ class Private;
+ Private* d;
+};
+
+ }
+}
+
+#endif
diff --git a/src/collection.cpp b/src/collection.cpp
new file mode 100644
index 0000000..c6f77ca
--- /dev/null
+++ b/src/collection.cpp
@@ -0,0 +1,915 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "collection.h"
+#include "field.h"
+#include "entry.h"
+#include "tellico_debug.h"
+#include "latin1literal.h"
+#include "tellico_utils.h"
+#include "controller.h"
+#include "collectionfactory.h"
+#include "stringset.h"
+#include "tellico_kernel.h"
+
+#include <klocale.h>
+
+#include <qregexp.h>
+#include <qvaluestack.h>
+
+using Tellico::Data::Collection;
+
+const char* Collection::s_emptyGroupTitle = I18N_NOOP("(Empty)");
+const QString Collection::s_peopleGroupName = QString::fromLatin1("_people");
+
+Collection::Collection(const QString& title_)
+ : QObject(), KShared(), m_nextEntryId(0), m_title(title_), m_entryIdDict(997)
+ , m_trackGroups(false) {
+ m_entryGroupDicts.setAutoDelete(true);
+
+ m_id = getID();
+}
+
+Collection::~Collection() {
+}
+
+QString Collection::typeName() const {
+ return CollectionFactory::typeName(type());
+}
+
+bool Collection::addFields(FieldVec list_) {
+ bool success = true;
+ for(FieldVec::Iterator it = list_.begin(); it != list_.end(); ++it) {
+ success &= addField(it);
+ }
+ return success;
+}
+
+bool Collection::addField(FieldPtr field_) {
+ if(!field_) {
+ return false;
+ }
+
+ // this essentially checks for duplicates
+ if(hasField(field_->name())) {
+ myDebug() << "Collection::addField() - replacing " << field_->name() << endl;
+ removeField(fieldByName(field_->name()), true);
+ }
+
+ // it's not sufficient to merely check the new field
+ if(dependentFieldHasRecursion(field_)) {
+ field_->setDescription(QString());
+ }
+
+ m_fields.append(field_);
+ if(field_->formatFlag() == Field::FormatName) {
+ m_peopleFields.append(field_); // list of people attributes
+ if(m_peopleFields.count() > 1) {
+ // the second time that a person field is added, add a "pseudo-group" for people
+ if(m_entryGroupDicts.find(s_peopleGroupName) == 0) {
+ EntryGroupDict* d = new EntryGroupDict();
+ d->setAutoDelete(true);
+ m_entryGroupDicts.insert(s_peopleGroupName, d);
+ m_entryGroups.prepend(s_peopleGroupName);
+ }
+ }
+ }
+ m_fieldNameDict.insert(field_->name(), field_);
+ m_fieldTitleDict.insert(field_->title(), field_);
+ m_fieldNames << field_->name();
+ m_fieldTitles << field_->title();
+ if(field_->type() == Field::Image) {
+ m_imageFields.append(field_);
+ }
+
+ if(!field_->category().isEmpty() && m_fieldCategories.findIndex(field_->category()) == -1) {
+ m_fieldCategories << field_->category();
+ }
+
+ if(field_->flags() & Field::AllowGrouped) {
+ // m_entryGroupsDicts autoDeletes each QDict when the Collection d'tor is called
+ EntryGroupDict* dict = new EntryGroupDict();
+ dict->setAutoDelete(true);
+ m_entryGroupDicts.insert(field_->name(), dict);
+ // cache the possible groups of entries
+ m_entryGroups << field_->name();
+ }
+
+ if(m_defaultGroupField.isEmpty() && field_->flags() & Field::AllowGrouped) {
+ m_defaultGroupField = field_->name();
+ }
+
+ // refresh all dependent fields, in case one references this new one
+ for(FieldVec::Iterator it = m_fields.begin(); it != m_fields.end(); ++it) {
+ if(it->type() == Field::Dependent) {
+ emit signalRefreshField(it);
+ }
+ }
+
+ return true;
+}
+
+bool Collection::mergeField(FieldPtr newField_) {
+ if(!newField_) {
+ return false;
+ }
+
+ FieldPtr currField = fieldByName(newField_->name());
+ if(!currField) {
+ // does not exist in current collection, add it
+ Data::FieldPtr f = new Field(*newField_);
+ bool success = addField(f);
+ Controller::self()->addedField(this, f);
+ return success;
+ }
+
+ if(newField_->type() == Field::Table2) {
+ newField_->setType(Data::Field::Table);
+ newField_->setProperty(QString::fromLatin1("columns"), QChar('2'));
+ }
+
+ // the original field type is kept
+ if(currField->type() != newField_->type()) {
+ myDebug() << "Collection::mergeField() - skipping, field type mismatch for " << currField->title() << endl;
+ return false;
+ }
+
+ // if field is a Choice, then make sure all values are there
+ if(currField->type() == Field::Choice && currField->allowed() != newField_->allowed()) {
+ QStringList allowed = currField->allowed();
+ const QStringList& newAllowed = newField_->allowed();
+ for(QStringList::ConstIterator it = newAllowed.begin(); it != newAllowed.end(); ++it) {
+ if(allowed.findIndex(*it) == -1) {
+ allowed.append(*it);
+ }
+ }
+ currField->setAllowed(allowed);
+ }
+
+ // don't change original format flags
+ // don't change original category
+ // add new description if current is empty
+ if(currField->description().isEmpty()) {
+ currField->setDescription(newField_->description());
+ if(dependentFieldHasRecursion(currField)) {
+ currField->setDescription(QString());
+ }
+ }
+
+ // if new field has additional extended properties, add those
+ for(StringMap::ConstIterator it = newField_->propertyList().begin(); it != newField_->propertyList().end(); ++it) {
+ const QString propName = it.key();
+ const QString currValue = currField->property(propName);
+ if(currValue.isEmpty()) {
+ currField->setProperty(propName, it.data());
+ } else if (it.data() != currValue) {
+ if(currField->type() == Field::URL && propName == Latin1Literal("relative")) {
+ kdWarning() << "Collection::mergeField() - relative URL property does not match for " << currField->name() << endl;
+ } else if((currField->type() == Field::Table && propName == Latin1Literal("columns"))
+ || (currField->type() == Field::Rating && propName == Latin1Literal("maximum"))) {
+ bool ok;
+ uint currNum = Tellico::toUInt(currValue, &ok);
+ uint newNum = Tellico::toUInt(it.data(), &ok);
+ if(newNum > currNum) { // bigger values
+ currField->setProperty(propName, QString::number(newNum));
+ }
+ } else if(currField->type() == Field::Rating && propName == Latin1Literal("minimum")) {
+ bool ok;
+ uint currNum = Tellico::toUInt(currValue, &ok);
+ uint newNum = Tellico::toUInt(it.data(), &ok);
+ if(newNum < currNum) { // smaller values
+ currField->setProperty(propName, QString::number(newNum));
+ }
+ }
+ }
+ }
+
+ // combine flags
+ currField->setFlags(currField->flags() | newField_->flags());
+ return true;
+}
+
+// be really careful with these field pointers, try not to call too many other functions
+// which may depend on the field list
+bool Collection::modifyField(FieldPtr newField_) {
+ if(!newField_) {
+ return false;
+ }
+// myDebug() << "Collection::modifyField() - " << newField_->name() << endl;
+
+// the field name never changes
+ const QString fieldName = newField_->name();
+ FieldPtr oldField = fieldByName(fieldName);
+ if(!oldField) {
+ myDebug() << "Collection::modifyField() - no field named " << fieldName << endl;
+ return false;
+ }
+
+ // update name dict
+ m_fieldNameDict.replace(fieldName, newField_);
+
+ // update titles
+ const QString oldTitle = oldField->title();
+ const QString newTitle = newField_->title();
+ if(oldTitle == newTitle) {
+ m_fieldTitleDict.replace(newTitle, newField_);
+ } else {
+ m_fieldTitleDict.remove(oldTitle);
+ m_fieldTitles.remove(oldTitle);
+ m_fieldTitleDict.insert(newTitle, newField_);
+ m_fieldTitles.append(newTitle);
+ }
+
+ // now replace the field pointer in the list
+ FieldVec::Iterator it = m_fields.find(oldField);
+ if(it != m_fields.end()) {
+ m_fields.insert(it, newField_);
+ m_fields.remove(oldField);
+ } else {
+ myDebug() << "Collection::modifyField() - no index found!" << endl;
+ return false;
+ }
+
+ // update category list.
+ if(oldField->category() != newField_->category()) {
+ m_fieldCategories.clear();
+ for(FieldVec::Iterator it = m_fields.begin(); it != m_fields.end(); ++it) {
+ // add category if it's not in the list yet
+ if(!it->category().isEmpty() && !m_fieldCategories.contains(it->category())) {
+ m_fieldCategories += it->category();
+ }
+ }
+ }
+
+ if(dependentFieldHasRecursion(newField_)) {
+ newField_->setDescription(QString());
+ }
+
+ // keep track of if the entry groups will need to be reset
+ bool resetGroups = false;
+
+ // if format is different, go ahead and invalidate all formatted entry values
+ if(oldField->formatFlag() != newField_->formatFlag()) {
+ // invalidate cached format strings of all entry attributes of this name
+ for(EntryVecIt it = m_entries.begin(); it != m_entries.end(); ++it) {
+ it->invalidateFormattedFieldValue(fieldName);
+ }
+ resetGroups = true;
+ }
+
+ // check to see if the people "pseudo-group" needs to be updated
+ // only if only one of the two is a name
+ bool wasPeople = oldField->formatFlag() == Field::FormatName;
+ bool isPeople = newField_->formatFlag() == Field::FormatName;
+ if(wasPeople) {
+ m_peopleFields.remove(oldField);
+ if(!isPeople) {
+ resetGroups = true;
+ }
+ }
+ if(isPeople) {
+ // if there's more than one people field and no people dict exists yet, add it
+ if(m_peopleFields.count() > 1 && m_entryGroupDicts.find(s_peopleGroupName) == 0) {
+ EntryGroupDict* d = new EntryGroupDict();
+ d->setAutoDelete(true);
+ m_entryGroupDicts.insert(s_peopleGroupName, d);
+ // put it at the top of the list
+ m_entryGroups.prepend(s_peopleGroupName);
+ }
+ m_peopleFields.append(newField_);
+ if(!wasPeople) {
+ resetGroups = true;
+ }
+ }
+
+ bool wasGrouped = oldField->flags() & Field::AllowGrouped;
+ bool isGrouped = newField_->flags() & Field::AllowGrouped;
+ if(wasGrouped) {
+ if(!isGrouped) {
+ // in order to keep list in the same order, don't remove unless new field is not groupable
+ m_entryGroups.remove(fieldName);
+ m_entryGroupDicts.remove(fieldName);
+ myDebug() << "Collection::modifyField() - no longer grouped: " << fieldName << endl;
+ resetGroups = true;
+ } else {
+ // don't do this, it wipes out the old groups!
+// m_entryGroupDicts.replace(fieldName, new EntryGroupDict());
+ }
+ } else if(isGrouped) {
+ EntryGroupDict* d = new EntryGroupDict();
+ d->setAutoDelete(true);
+ m_entryGroupDicts.insert(fieldName, d);
+ if(!wasGrouped) {
+ // cache the possible groups of entries
+ m_entryGroups << fieldName;
+ }
+ resetGroups = true;
+ }
+
+ if(oldField->type() == Field::Image) {
+ m_imageFields.remove(oldField);
+ }
+ if(newField_->type() == Field::Image) {
+ m_imageFields.append(newField_);
+ }
+
+ if(resetGroups) {
+ myLog() << "Collection::modifyField() - invalidating groups" << endl;
+ invalidateGroups();
+ }
+
+ // now to update all entries if the field is a dependent and the description changed
+ if(newField_->type() == Field::Dependent && oldField->description() != newField_->description()) {
+ emit signalRefreshField(newField_);
+ }
+
+ return true;
+}
+
+bool Collection::removeField(const QString& name_, bool force_) {
+ return removeField(fieldByName(name_), force_);
+}
+
+// force allows me to force the deleting of the title field if I need to
+bool Collection::removeField(FieldPtr field_, bool force_/*=false*/) {
+ if(!field_ || !m_fields.contains(field_)) {
+ if(field_) {
+ myDebug() << "Collection::removeField - false: " << field_->name() << endl;
+ }
+ return false;
+ }
+// myDebug() << "Collection::removeField() - name = " << field_->name() << endl;
+
+ // can't delete the title field
+ if((field_->flags() & Field::NoDelete) && !force_) {
+ return false;
+ }
+
+ bool success = true;
+ if(field_->formatFlag() == Field::FormatName) {
+ success &= m_peopleFields.remove(field_);
+ }
+
+ if(field_->type() == Field::Image) {
+ success &= m_imageFields.remove(field_);
+ }
+ success &= m_fieldNameDict.remove(field_->name());
+ success &= m_fieldTitleDict.remove(field_->title());
+ success &= m_fieldNames.remove(field_->name());
+ success &= m_fieldTitles.remove(field_->title());
+
+ if(fieldsByCategory(field_->category()).count() == 1) {
+ success &= m_fieldCategories.remove(field_->category());
+ }
+
+ for(EntryVecIt it = m_entries.begin(); it != m_entries.end(); ++it) {
+ // setting the fields to an empty string removes the value from the entry's list
+ it->setField(field_, QString::null);
+ }
+
+ if(field_->flags() & Field::AllowGrouped) {
+ success &= m_entryGroupDicts.remove(field_->name());
+ success &= m_entryGroups.remove(field_->name());
+ if(field_->name() == m_defaultGroupField) {
+ setDefaultGroupField(m_entryGroups[0]);
+ }
+ }
+
+ success &= m_fields.remove(field_);
+
+ // refresh all dependent fields, rather lazy, but there's
+ // likely to be weird effects when checking dependent fields
+ // while removing one, so refresh all of them
+ for(FieldVec::Iterator it = m_fields.begin(); it != m_fields.end(); ++it) {
+ if(it->type() == Field::Dependent) {
+ emit signalRefreshField(it);
+ }
+ }
+
+ return success;
+}
+
+void Collection::reorderFields(const FieldVec& list_) {
+// assume the lists have the same pointers!
+ m_fields = list_;
+
+ // also reset category list, since the order may have changed
+ m_fieldCategories.clear();
+ for(FieldVec::Iterator it = m_fields.begin(); it != m_fields.end(); ++it) {
+ if(!it->category().isEmpty() && !m_fieldCategories.contains(it->category())) {
+ m_fieldCategories << it->category();
+ }
+ }
+}
+
+void Collection::addEntries(EntryVec entries_) {
+ if(entries_.isEmpty()) {
+ return;
+ }
+
+ for(EntryVec::Iterator entry = entries_.begin(); entry != entries_.end(); ++entry) {
+ bool foster = false;
+ if(this != entry->collection()) {
+ entry->setCollection(this);
+ foster = true;
+ }
+
+ m_entries.append(entry);
+// myDebug() << "Collection::addEntries() - added entry (" << entry->title() << ")" << endl;
+
+ if(entry->id() >= m_nextEntryId) {
+ m_nextEntryId = entry->id() + 1;
+ } else if(entry->id() == -1) {
+ entry->setId(m_nextEntryId);
+ ++m_nextEntryId;
+ } else if(m_entryIdDict.find(entry->id())) {
+ if(!foster) {
+ myDebug() << "Collection::addEntries() - the collection already has an entry with id = " << entry->id() << endl;
+ }
+ entry->setId(m_nextEntryId);
+ ++m_nextEntryId;
+ }
+ m_entryIdDict.insert(entry->id(), entry.data());
+ }
+ if(m_trackGroups) {
+ populateCurrentDicts(entries_);
+ }
+}
+
+void Collection::removeEntriesFromDicts(EntryVec entries_) {
+ PtrVector<EntryGroup> modifiedGroups;
+ for(EntryVecIt entry = entries_.begin(); entry != entries_.end(); ++entry) {
+ // need a copy of the vector since it gets changed
+ PtrVector<EntryGroup> groups = entry->groups();
+ for(PtrVector<EntryGroup>::Iterator group = groups.begin(); group != groups.end(); ++group) {
+ if(entry->removeFromGroup(group.ptr()) && !modifiedGroups.contains(group.ptr())) {
+ modifiedGroups.push_back(group.ptr());
+ }
+ if(group->isEmpty() && !m_groupsToDelete.contains(group.ptr())) {
+ m_groupsToDelete.push_back(group.ptr());
+ }
+ }
+ }
+ emit signalGroupsModified(this, modifiedGroups);
+}
+
+// this function gets called whenever an entry is modified. Its purpose is to keep the
+// groupDicts current. It first removes the entry from every group to which it belongs,
+// then it repopulates the dicts with the entry's fields
+void Collection::updateDicts(EntryVec entries_) {
+ if(entries_.isEmpty()) {
+ return;
+ }
+
+ removeEntriesFromDicts(entries_);
+ populateCurrentDicts(entries_);
+ cleanGroups();
+}
+
+bool Collection::removeEntries(EntryVec vec_) {
+ if(vec_.isEmpty()) {
+ return false;
+ }
+
+// myDebug() << "Collection::deleteEntry() - deleted entry - " << entry_->title() << endl;
+ removeEntriesFromDicts(vec_);
+ bool success = true;
+ for(EntryVecIt entry = vec_.begin(); entry != vec_.end(); ++entry) {
+ m_entryIdDict.remove(entry->id());
+ success &= m_entries.remove(entry);
+ }
+ cleanGroups();
+ return success;
+}
+
+Tellico::Data::FieldVec Collection::fieldsByCategory(const QString& cat_) {
+#ifndef NDEBUG
+ if(m_fieldCategories.findIndex(cat_) == -1) {
+ myDebug() << "Collection::fieldsByCategory() - '" << cat_ << "' is not in category list" << endl;
+ }
+#endif
+ if(cat_.isEmpty()) {
+ myDebug() << "Collection::fieldsByCategory() - empty category!" << endl;
+ return FieldVec();
+ }
+
+ FieldVec list;
+ for(FieldVec::Iterator it = m_fields.begin(); it != m_fields.end(); ++it) {
+ if(it->category() == cat_) {
+ list.append(it);
+ }
+ }
+ return list;
+}
+
+const QString& Collection::fieldNameByTitle(const QString& title_) const {
+ if(title_.isEmpty()) {
+ return QString::null;
+ }
+ FieldPtr f = fieldByTitle(title_);
+ if(!f) { // might happen in MainWindow::saveCollectionOptions
+ return QString::null;
+ }
+ return f->name();
+}
+
+const QString& Collection::fieldTitleByName(const QString& name_) const {
+ if(name_.isEmpty()) {
+ return QString::null;
+ }
+ FieldPtr f = fieldByName(name_);
+ if(!f) {
+ kdWarning() << "Collection::fieldTitleByName() - no field named " << name_ << endl;
+ return QString::null;
+ }
+ return f->title();
+}
+
+QStringList Collection::valuesByFieldName(const QString& name_) const {
+ if(name_.isEmpty()) {
+ return QStringList();
+ }
+ bool multiple = (fieldByName(name_)->flags() & Field::AllowMultiple);
+
+ StringSet values;
+ for(EntryVec::ConstIterator it = m_entries.begin(); it != m_entries.end(); ++it) {
+ if(multiple) {
+ values.add(it->fields(name_, false));
+ } else {
+ values.add(it->field(name_));
+ }
+ } // end entry loop
+
+ return values.toList();
+}
+
+Tellico::Data::FieldPtr Collection::fieldByName(const QString& name_) const {
+ return m_fieldNameDict.isEmpty() ? 0 : name_.isEmpty() ? 0 : m_fieldNameDict.find(name_);
+}
+
+Tellico::Data::FieldPtr Collection::fieldByTitle(const QString& title_) const {
+ return m_fieldTitleDict.isEmpty() ? 0 : title_.isEmpty() ? 0 : m_fieldTitleDict.find(title_);
+}
+
+bool Collection::hasField(const QString& name_) const {
+ return fieldByName(name_) != 0;
+}
+
+bool Collection::isAllowed(const QString& key_, const QString& value_) const {
+ // empty string is always allowed
+ if(value_.isEmpty()) {
+ return true;
+ }
+
+ // find the field with a name of 'key_'
+ FieldPtr field = fieldByName(key_);
+
+ // if the type is not multiple choice or if value_ is allowed, return true
+ if(field && (field->type() != Field::Choice || field->allowed().findIndex(value_) > -1)) {
+ return true;
+ }
+
+ return false;
+}
+
+Tellico::Data::EntryGroupDict* Collection::entryGroupDictByName(const QString& name_) {
+// myDebug() << "Collection::entryGroupDictByName() - " << name_ << endl;
+ if(name_.isEmpty()) {
+ return 0;
+ }
+ EntryGroupDict* dict = m_entryGroupDicts.isEmpty() ? 0 : m_entryGroupDicts.find(name_);
+ if(dict && dict->isEmpty()) {
+ GUI::CursorSaver cs;
+ const bool b = signalsBlocked();
+ // block signals so all the group created/modified signals don't fire
+ blockSignals(true);
+ populateDict(dict, name_, m_entries);
+ blockSignals(b);
+ }
+ return dict;
+}
+
+void Collection::populateDict(EntryGroupDict* dict_, const QString& fieldName_, EntryVec entries_) {
+// myDebug() << "Collection::populateDict() - " << fieldName_ << endl;
+ bool isBool = hasField(fieldName_) && fieldByName(fieldName_)->type() == Field::Bool;
+
+ PtrVector<EntryGroup> modifiedGroups;
+ for(EntryVecIt entry = entries_.begin(); entry != entries_.end(); ++entry) {
+ QStringList groups = entryGroupNamesByField(entry, fieldName_);
+ for(QStringList::ConstIterator groupIt = groups.begin(); groupIt != groups.end(); ++groupIt) {
+ // find the group for this group name
+ // bool fields used the field title
+ QString groupTitle = *groupIt;
+ if(isBool && groupTitle != i18n(s_emptyGroupTitle)) {
+ groupTitle = fieldTitleByName(fieldName_);
+ }
+ EntryGroup* group = dict_->find(groupTitle);
+ // if the group doesn't exist, create it
+ if(!group) {
+ group = new EntryGroup(groupTitle, fieldName_);
+ dict_->insert(groupTitle, group);
+ } else if(group->isEmpty()) {
+ // if it's empty, then it was added to the vector of groups to delete
+ // remove it from that vector now that we're adding to it
+ m_groupsToDelete.remove(group);
+ }
+ if(entry->addToGroup(group)) {
+ modifiedGroups.push_back(group);
+ }
+ } // end group loop
+ } // end entry loop
+ emit signalGroupsModified(this, modifiedGroups);
+}
+
+void Collection::populateCurrentDicts(EntryVec entries_) {
+ if(m_entryGroupDicts.isEmpty()) {
+ return;
+ }
+
+ // special case when adding an entry to a new empty collection
+ // there are no existing non-empty groups
+ bool allEmpty = true;
+
+ // iterate over all the possible groupDicts
+ // for each dict, get the value of that field for the entry
+ // if multiple values are allowed, split the value and then insert the
+ // entry pointer into the dict for each value
+ QDictIterator<EntryGroupDict> dictIt(m_entryGroupDicts);
+ for( ; dictIt.current(); ++dictIt) {
+ // only populate if it's not empty, since they are
+ // populated on demand
+ if(!dictIt.current()->isEmpty()) {
+ populateDict(dictIt.current(), dictIt.currentKey(), entries_);
+ allEmpty = false;
+ }
+ }
+
+ if(allEmpty) {
+ // need to populate the current group dict
+ const QString group = Controller::self()->groupBy();
+ EntryGroupDict* dict = m_entryGroupDicts[group];
+ if(dict) {
+ populateDict(dict, group, entries_);
+ }
+ }
+}
+
+// return a string list for all the groups that the entry belongs to
+// for a given field. Normally, this would just be splitting the entry's value
+// for the field, but if the field name is the people pseudo-group, then it gets
+// a bit more complicated
+QStringList Collection::entryGroupNamesByField(EntryPtr entry_, const QString& fieldName_) {
+ if(fieldName_ != s_peopleGroupName) {
+ return entry_->groupNamesByFieldName(fieldName_);
+ }
+
+ StringSet values;
+ for(FieldVec::Iterator it = m_peopleFields.begin(); it != m_peopleFields.end(); ++it) {
+ values.add(entry_->groupNamesByFieldName(it->name()));
+ }
+ values.remove(i18n(s_emptyGroupTitle));
+ return values.toList();
+}
+
+void Collection::invalidateGroups() {
+ QDictIterator<EntryGroupDict> dictIt(m_entryGroupDicts);
+ for( ; dictIt.current(); ++dictIt) {
+ dictIt.current()->clear();
+ }
+
+ // populateDicts() will make signals that the group view is connected to, block those
+ blockSignals(true);
+ for(EntryVecIt it = m_entries.begin(); it != m_entries.end(); ++it) {
+ it->invalidateFormattedFieldValue();
+ it->clearGroups();
+ }
+ blockSignals(false);
+}
+
+Tellico::Data::EntryPtr Collection::entryById(long id_) {
+ return m_entryIdDict[id_];
+}
+
+void Collection::addBorrower(Data::BorrowerPtr borrower_) {
+ if(!borrower_) {
+ return;
+ }
+ m_borrowers.append(borrower_);
+}
+
+void Collection::addFilter(FilterPtr filter_) {
+ if(!filter_) {
+ return;
+ }
+
+ m_filters.append(filter_);
+}
+
+bool Collection::removeFilter(FilterPtr filter_) {
+ if(!filter_) {
+ return false;
+ }
+
+ // TODO: test for success
+ m_filters.remove(filter_);
+ return true;
+}
+
+void Collection::clear() {
+ // since the collection holds a pointer to each entry and each entry
+ // hold a pointer to the collection, and they're both sharedptrs,
+ // neither will ever get deleted, unless the collection removes
+ // all held pointers, specifically to entries
+ m_fields.clear();
+ m_peopleFields.clear();
+ m_imageFields.clear();
+ m_fieldNameDict.clear();
+ m_fieldTitleDict.clear();
+
+ m_entries.clear();
+ m_entryIdDict.clear();
+ m_entryGroupDicts.clear();
+ m_groupsToDelete.clear();
+ m_filters.clear();
+ m_borrowers.clear();
+}
+
+void Collection::cleanGroups() {
+ for(PtrVector<EntryGroup>::Iterator it = m_groupsToDelete.begin(); it != m_groupsToDelete.end(); ++it) {
+ EntryGroupDict* dict = entryGroupDictByName(it->fieldName());
+ if(!dict) {
+ continue;
+ }
+ dict->remove(it->groupName());
+ }
+ m_groupsToDelete.clear();
+}
+
+bool Collection::dependentFieldHasRecursion(FieldPtr field_) {
+ if(!field_ || field_->type() != Field::Dependent) {
+ return false;
+ }
+
+ StringSet fieldNamesFound;
+ fieldNamesFound.add(field_->name());
+ QValueStack<FieldPtr> fieldsToCheck;
+ fieldsToCheck.push(field_);
+ while(!fieldsToCheck.isEmpty()) {
+ FieldPtr f = fieldsToCheck.pop();
+ const QStringList depFields = f->dependsOn();
+ for(QStringList::ConstIterator it = depFields.begin(); it != depFields.end(); ++it) {
+ if(fieldNamesFound.has(*it)) {
+ // we have recursion
+ return true;
+ }
+ fieldNamesFound.add(*it);
+ FieldPtr f = fieldByName(*it);
+ if(!f) {
+ f = fieldByTitle(*it);
+ }
+ if(f) {
+ fieldsToCheck.push(f);
+ }
+ }
+ }
+ return false;
+}
+
+int Collection::sameEntry(Data::EntryPtr entry1_, Data::EntryPtr entry2_) const {
+ if(!entry1_ || !entry2_) {
+ return 0;
+ }
+ // used to just return 0, but we really want a default generic implementation
+ // that specific collections can override.
+
+ // start with twice the title score
+ // and since the minimum is > 10, then need more than just a perfect title match
+ int res = 2*Entry::compareValues(entry1_, entry2_, QString::fromLatin1("title"), this);
+ // then add score for each field
+ FieldVec fields = entry1_->collection()->fields();
+ for(Data::FieldVecIt it = fields.begin(); it != fields.end(); ++it) {
+ res += Entry::compareValues(entry1_, entry2_, it->name(), this);
+ }
+ return res;
+}
+
+// static
+// merges values from e2 into e1
+bool Collection::mergeEntry(EntryPtr e1, EntryPtr e2, bool overwrite_, bool askUser_) {
+ if(!e1 || !e2) {
+ myDebug() << "Collection::mergeEntry() - bad entry pointer" << endl;
+ return false;
+ }
+ bool ret = true;
+ FieldVec fields = e1->collection()->fields();
+ for(FieldVec::Iterator field = fields.begin(); field != fields.end(); ++field) {
+ if(e2->field(field).isEmpty()) {
+ continue;
+ }
+// myLog() << "Collection::mergeEntry() - reading field: " << field->name() << endl;
+ if(overwrite_ || e1->field(field).isEmpty()) {
+// myLog() << e1->title() << ": updating field(" << field->name() << ") to " << e2->field(field->name()) << endl;
+ e1->setField(field, e2->field(field));
+ ret = true;
+ } else if(e1->field(field) == e2->field(field)) {
+ continue;
+ } else if(field->type() == Field::Para) {
+ // for paragraph fields, concatenate the values, if they're not equal
+ e1->setField(field, e1->field(field) + QString::fromLatin1("<br/><br/>") + e2->field(field));
+ ret = true;
+ } else if(field->type() == Field::Table) {
+ // if field F is a table-type field (album tracks, files, etc.), merge rows (keep their position)
+ // if e1's F val in [row i, column j] empty, replace with e2's val at same position
+ // if different (non-empty) vals at same position, CONFLICT!
+ const QString sep = QString::fromLatin1("::");
+ QStringList vals1 = e1->fields(field, false);
+ QStringList vals2 = e2->fields(field, false);
+ while(vals1.count() < vals2.count()) {
+ vals1 += QString();
+ }
+ for(uint i = 0; i < vals2.count(); ++i) {
+ if(vals2[i].isEmpty()) {
+ continue;
+ }
+ if(vals1[i].isEmpty()) {
+ vals1[i] = vals2[i];
+ ret = true;
+ } else {
+ QStringList parts1 = QStringList::split(sep, vals1[i], true);
+ QStringList parts2 = QStringList::split(sep, vals2[i], true);
+ bool changedPart = false;
+ while(parts1.count() < parts2.count()) {
+ parts1 += QString();
+ }
+ for(uint j = 0; j < parts2.count(); ++j) {
+ if(parts2[j].isEmpty()) {
+ continue;
+ }
+ if(parts1[j].isEmpty()) {
+ parts1[j] = parts2[j];
+ changedPart = true;
+ } else if(askUser_ && parts1[j] != parts2[j]) {
+ int ret = Kernel::self()->askAndMerge(e1, e2, field, parts1[j], parts2[j]);
+ if(ret == 0) {
+ return false; // we got cancelled
+ }
+ if(ret == 1) {
+ parts1[j] = parts2[j];
+ changedPart = true;
+ }
+ }
+ }
+ if(changedPart) {
+ vals1[i] = parts1.join(sep);
+ ret = true;
+ }
+ }
+ }
+ if(ret) {
+ e1->setField(field, vals1.join(QString::fromLatin1("; ")));
+ }
+ } else if(field->flags() & Data::Field::AllowMultiple) {
+ // if field F allows multiple values and not a Table (see above case),
+ // e1's F values = (e1's F values) U (e2's F values) (union)
+ // replace e1's field with union of e1's and e2's values for this field
+ QStringList items1 = e1->fields(field, false);
+ QStringList items2 = e2->fields(field, false);
+ for(QStringList::ConstIterator it = items2.begin(); it != items2.end(); ++it) {
+ // possible to have one value formatted and the other one not...
+ if(!items1.contains(*it) && !items1.contains(Field::format(*it, field->formatFlag()))) {
+ items1.append(*it);
+ }
+ }
+// not sure if I think it should be sorted or not
+// items1.sort();
+ e1->setField(field, items1.join(QString::fromLatin1("; ")));
+ ret = true;
+ } else if(askUser_ && e1->field(field) != e2->field(field)) {
+ int ret = Kernel::self()->askAndMerge(e1, e2, field);
+ if(ret == 0) {
+ return false; // we got cancelled
+ }
+ if(ret == 1) {
+ e1->setField(field, e2->field(field));
+ }
+ }
+ }
+ return ret;
+}
+
+long Collection::getID() {
+ static long id = 0;
+ return ++id;
+}
+
+#include "collection.moc"
diff --git a/src/collection.h b/src/collection.h
new file mode 100644
index 0000000..b7dae1f
--- /dev/null
+++ b/src/collection.h
@@ -0,0 +1,394 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef COLLECTION_H
+#define COLLECTION_H
+
+#include "field.h"
+#include "entry.h"
+#include "filter.h"
+#include "borrower.h"
+#include "datavectors.h"
+
+#include <ksharedptr.h>
+
+#include <qstringlist.h>
+#include <qptrlist.h>
+#include <qstring.h>
+#include <qdict.h>
+#include <qintdict.h>
+#include <qobject.h>
+
+namespace Tellico {
+ namespace Data {
+ class EntryGroup;
+ typedef QDict<EntryGroup> EntryGroupDict;
+
+/**
+ * The Collection class is the primary data object, holding a
+ * list of fields and entries.
+ *
+ * A collection holds entries of a single type, whether it be books, CDs, or whatever.
+ * It has a list of attributes which apply for the whole collection. A unique id value
+ * identifies each collection object.
+ *
+ * @see Entry
+ * @see Field
+ *
+ * @author Robby Stephenson
+ */
+class Collection : public QObject, public KShared {
+Q_OBJECT
+
+public:
+ enum Type {
+ Base = 1,
+ Book = 2,
+ Video = 3,
+ Album = 4,
+ Bibtex = 5,
+ ComicBook = 6,
+ Wine = 7,
+ Coin = 8,
+ Stamp = 9,
+ Card = 10,
+ Game = 11,
+ File = 12,
+ BoardGame = 13
+ // if you want to add custom collection types, use a number sure to be unique like 101
+ };
+
+ /**
+ * The constructor is only used to create custom collections. It adds a title field,
+ * in the "General" group. The iconName is set to be the typeName;
+ *
+ * @param title The title of the collection itself
+ * @param entryTitle The title of the entries, which can be translated
+ */
+ explicit Collection(const QString& title);
+ /**
+ */
+ virtual ~Collection();
+
+ /**
+ * Returns the type of the collection.
+ *
+ * @return The type
+ */
+ virtual Type type() const { return Base; }
+ /**
+ * Returns the id of the collection.
+ *
+ * @return The id
+ */
+ long id() const { return m_id; }
+ /**
+ * Returns the name of the collection.
+ *
+ * @return The name
+ */
+ const QString& title() const { return m_title; }
+ /**
+ * Sets the title of the collection.
+ *
+ * @param title The new collection title
+ */
+ void setTitle(const QString& title) { m_title = title; }
+ /**
+ * Returns the name of the entries in the collection, e.g. "book".
+ * Not translated.
+ *
+ * @return The type name
+ */
+ QString typeName() const;
+ /**
+ * Returns a reference to the list of all the entries in the collection.
+ *
+ * @return The list of entries
+ */
+ const EntryVec& entries() const { return m_entries; }
+ /**
+ * Returns a reference to the list of the collection attributes.
+ *
+ * @return The list of fields
+ */
+ const FieldVec& fields() const { return m_fields; }
+ EntryPtr entryById(long id);
+ /**
+ * Returns a reference to the list of the collection's people fields.
+ *
+ * @return The list of fields
+ */
+ const FieldVec& peopleFields() const { return m_peopleFields; }
+ /**
+ * Returns a reference to the list of the collection's image fields.
+ *
+ * @return The list of fields
+ */
+ const FieldVec& imageFields() const { return m_imageFields; }
+ /**
+ * Returns a reference to the list of field groups. This value is cached rather
+ * than generated with each call, so the method should be fairly fast.
+ *
+ * @return The list of group names
+ */
+ const QStringList& fieldCategories() const { return m_fieldCategories; }
+ /**
+ * Returns the name of the field used to group the entries by default.
+ *
+ * @return The field name
+ */
+ const QString& defaultGroupField() const { return m_defaultGroupField; }
+ /**
+ * Sets the name of the default field used to group the entries.
+ *
+ * @param name The name of the field
+ */
+ void setDefaultGroupField(const QString& name) { m_defaultGroupField = name; }
+ /**
+ * Returns the number of entries in the collection.
+ *
+ * @return The number of entries
+ */
+ size_t entryCount() const { return m_entries.count(); }
+ /**
+ * Adds a entry to the collection. The collection takes ownership of the entry object.
+ *
+ * @param entry A pointer to the entry
+ */
+ void addEntries(EntryVec entries);
+ /**
+ * Updates the dicts that include the entry.
+ *
+ * @param entry A pointer to the entry
+ */
+ void updateDicts(EntryVec entries);
+ /**
+ * Deletes a entry from the collection.
+ *
+ * @param entry The pointer to the entry
+ * @return A boolean indicating if the entry was in the collection and was deleted
+ */
+ bool removeEntries(EntryVec entries);
+ /**
+ * Adds a whole list of attributes. It's gotta be virtual since it calls
+ * @ref addField, which is virtual.
+ *
+ * @param list List of attributes to add
+ * @return A boolean indicating if the field was added or not
+ */
+ virtual bool addFields(FieldVec list);
+ /**
+ * Adds an field to the collection, unless an field with that name
+ * already exists. The collection takes ownership of the field object.
+ *
+ * @param field A pointer to the field
+ * @return A boolean indicating if the field was added or not
+ */
+ virtual bool addField(FieldPtr field);
+ virtual bool mergeField(FieldPtr field);
+ virtual bool modifyField(FieldPtr field);
+ virtual bool removeField(FieldPtr field, bool force=false);
+ virtual bool removeField(const QString& name, bool force=false);
+ void reorderFields(const FieldVec& list);
+
+ // the reason this is not static is so I can call it from a collection pointer
+ // it also gets virtualized for different collection types
+ // the return values should be compared against the GOOD and PERFECT
+ // static match constants in this class
+ virtual int sameEntry(Data::EntryPtr, Data::EntryPtr) const;
+
+ /**
+ * Determines whether or not a certain value is allowed for an field.
+ *
+ * @param key The name of the field
+ * @param value The desired value
+ * @return A boolean indicating if the value is an allowed value for that field
+ */
+ bool isAllowed(const QString& key, const QString& value) const;
+ /**
+ * Returns a list of all the field names.
+ *
+ * @return The list of names
+ */
+ const QStringList& fieldNames() const { return m_fieldNames; }
+ /**
+ * Returns a list of all the field titles.
+ *
+ * @return The list of titles
+ */
+ const QStringList& fieldTitles() const { return m_fieldTitles; }
+ /**
+ * Returns the title of an field, given its name.
+ *
+ * @param name The field name
+ * @return The field title
+ */
+ const QString& fieldTitleByName(const QString& name) const;
+ /**
+ * Returns the name of an field, given its title.
+ *
+ * @param title The field title
+ * @return The field name
+ */
+ const QString& fieldNameByTitle(const QString& title) const;
+ /**
+ * Returns a list of the values of a given field for every entry
+ * in the collection. The values in the list are not repeated. Attribute
+ * values which contain ";" are split into separate values. Since this method
+ * iterates over all the entries, for large collections, it is expensive.
+ *
+ * @param name The name of the field
+ * @return The list of values
+ */
+ QStringList valuesByFieldName(const QString& name) const;
+ /**
+ * Returns a list of all the fields in a given category.
+ *
+ * @param category The name of the category
+ * @return The field list
+ */
+ FieldVec fieldsByCategory(const QString& category);
+ /**
+ * Returns a pointer to an field given its name. If none is found, a NULL pointer
+ * is returned.
+ *
+ * @param name The field name
+ * @return The field pointer
+ */
+ FieldPtr fieldByName(const QString& name) const;
+ /**
+ * Returns a pointer to an field given its title. If none is found, a NULL pointer
+ * is returned. This lookup is slower than by name.
+ *
+ * @param title The field title
+ * @return The field pointer
+ */
+ FieldPtr fieldByTitle(const QString& title) const;
+ /**
+ * Returns @p true if the collection contains a field named @ref name;
+ */
+ bool hasField(const QString& name) const;
+ /**
+ * Returns a list of all the possible entry groups. This value is cached rather
+ * than generated with each call, so the method should be fairly fast.
+ *
+ * @return The list of groups
+ */
+ const QStringList& entryGroups() const { return m_entryGroups; }
+ /**
+ * Returns a pointer to a dict of all the entries grouped by
+ * a certain field
+ *
+ * @param name The name of the field by which the entries are grouped
+ * @return The list of group names
+ */
+ EntryGroupDict* entryGroupDictByName(const QString& name);
+ /**
+ * Invalidates all group names in the collection.
+ */
+ void invalidateGroups();
+ /**
+ * Returns true if the collection contains at least one Image field.
+ *
+ * @return Returns true if the collection contains at least one Image field;
+ */
+ bool hasImages() const { return !m_imageFields.isEmpty(); }
+
+ void setTrackGroups(bool b) { m_trackGroups = b; }
+
+ void addBorrower(Data::BorrowerPtr borrower);
+ const BorrowerVec& borrowers() const { return m_borrowers; }
+ /**
+ * Clears all vectors which contain shared ptrs
+ */
+ void clear();
+
+ void addFilter(FilterPtr filter);
+ bool removeFilter(FilterPtr filter);
+ const FilterVec& filters() const { return m_filters; }
+
+ static bool mergeEntry(EntryPtr entry1, EntryPtr entry2, bool overwrite, bool askUser=false);
+ /**
+ * The string used for empty values. This forces consistency.
+ */
+ static const char* s_emptyGroupTitle;
+ /**
+ * The string used for the people pseudo-group. This forces consistency.
+ */
+ static const QString s_peopleGroupName;
+
+ // these are the values that should be compared against
+ // the result from sameEntry()
+ static const int ENTRY_GOOD_MATCH = 10;
+ static const int ENTRY_PERFECT_MATCH = 20;
+
+signals:
+ void signalGroupsModified(Tellico::Data::CollPtr coll, PtrVector<Tellico::Data::EntryGroup> groups);
+ void signalRefreshField(Tellico::Data::FieldPtr field);
+
+private:
+ QStringList entryGroupNamesByField(EntryPtr entry, const QString& fieldName);
+ void removeEntriesFromDicts(EntryVec entries);
+ void populateDict(EntryGroupDict* dict, const QString& fieldName, EntryVec entries);
+ void populateCurrentDicts(EntryVec entries);
+ void cleanGroups();
+ bool dependentFieldHasRecursion(FieldPtr field);
+
+ /*
+ * Gets the preferred ID of the collection. Currently, it just gets incremented as
+ * new collections are created.
+ */
+ static long getID();
+
+ /**
+ * The copy constructor is private, to ensure that it's never used.
+ */
+ Collection(const Collection& coll);
+ /**
+ * The assignment operator is private, to ensure that it's never used.
+ */
+ Collection operator=(const Collection& coll);
+
+ long m_id;
+ long m_nextEntryId;
+ QString m_title;
+ QString m_typeName;
+ QString m_iconName;
+ QString m_defaultGroupField;
+
+ FieldVec m_fields;
+ FieldVec m_peopleFields; // keep separate list of people fields
+ FieldVec m_imageFields; // keep track of image fields
+ QDict<Field> m_fieldNameDict;
+ QDict<Field> m_fieldTitleDict;
+ QStringList m_fieldCategories;
+ QStringList m_fieldNames;
+ QStringList m_fieldTitles;
+
+ EntryVec m_entries;
+ QIntDict<Entry> m_entryIdDict;
+
+ QDict<EntryGroupDict> m_entryGroupDicts;
+ QStringList m_entryGroups;
+ PtrVector<EntryGroup> m_groupsToDelete;
+
+ FilterVec m_filters;
+ BorrowerVec m_borrowers;
+
+ bool m_trackGroups : 1;
+};
+
+ } // end namespace
+} //end namespace
+#endif
diff --git a/src/collectionfactory.cpp b/src/collectionfactory.cpp
new file mode 100644
index 0000000..25f9d6f
--- /dev/null
+++ b/src/collectionfactory.cpp
@@ -0,0 +1,210 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "collectionfactory.h"
+#include "collections/bookcollection.h"
+#include "collections/bibtexcollection.h"
+#include "collections/musiccollection.h"
+#include "collections/videocollection.h"
+#include "collections/comicbookcollection.h"
+#include "collections/coincollection.h"
+#include "collections/stampcollection.h"
+#include "collections/cardcollection.h"
+#include "collections/winecollection.h"
+#include "collections/gamecollection.h"
+#include "collections/filecatalog.h"
+#include "collections/boardgamecollection.h"
+#include "field.h"
+#include "tellico_debug.h"
+
+#include <klocale.h>
+
+using Tellico::CollectionFactory;
+
+// static
+Tellico::Data::CollPtr CollectionFactory::collection(int type_, bool addFields_) {
+ switch(type_) {
+ case Data::Collection::Book:
+ return new Data::BookCollection(addFields_);
+
+ case Data::Collection::Video:
+ return new Data::VideoCollection(addFields_);
+
+ case Data::Collection::Album:
+ return new Data::MusicCollection(addFields_);
+
+ case Data::Collection::Bibtex:
+ return new Data::BibtexCollection(addFields_);
+
+ case Data::Collection::Coin:
+ return new Data::CoinCollection(addFields_);
+
+ case Data::Collection::Card:
+ return new Data::CardCollection(addFields_);
+
+ case Data::Collection::Stamp:
+ return new Data::StampCollection(addFields_);
+
+ case Data::Collection::Wine:
+ return new Data::WineCollection(addFields_);
+
+ case Data::Collection::ComicBook:
+ return new Data::ComicBookCollection(addFields_);
+
+ case Data::Collection::Game:
+ return new Data::GameCollection(addFields_);
+
+ case Data::Collection::File:
+ return new Data::FileCatalog(addFields_);
+
+ case Data::Collection::BoardGame:
+ return new Data::BoardGameCollection(addFields_);
+
+ case Data::Collection::Base:
+ break;
+
+ default:
+ kdWarning() << "CollectionFactory::collection() - collection type not implemented: " << type_ << endl;
+ // fall through
+ }
+
+ Data::CollPtr c = new Data::Collection(i18n("My Collection"));
+ Data::FieldPtr f = new Data::Field(QString::fromLatin1("title"), i18n("Title"));
+ f->setCategory(i18n("General"));
+ f->setFlags(Data::Field::NoDelete);
+ f->setFormatFlag(Data::Field::FormatTitle);
+ c->addField(f);
+ return c;
+}
+
+// static
+Tellico::Data::CollPtr CollectionFactory::collection(const QString& typeName_, bool addFields_) {
+ if(typeName_ == typeName(Data::Collection::Book)) {
+ return new Data::BookCollection(addFields_);
+ } else if(typeName_ == typeName(Data::Collection::Album)) {
+ return new Data::MusicCollection(addFields_);
+ } else if(typeName_ == typeName(Data::Collection::Video)) {
+ return new Data::VideoCollection(addFields_);
+ } else if(typeName_ == typeName(Data::Collection::Bibtex)) {
+ return new Data::BibtexCollection(addFields_);
+ } else if(typeName_ == typeName(Data::Collection::Bibtex)) {
+ return new Data::ComicBookCollection(addFields_);
+ } else if(typeName_ == typeName(Data::Collection::ComicBook)) {
+ return new Data::CardCollection(addFields_);
+ } else if(typeName_ == typeName(Data::Collection::Coin)) {
+ return new Data::CoinCollection(addFields_);
+ } else if(typeName_ == typeName(Data::Collection::Stamp)) {
+ return new Data::StampCollection(addFields_);
+ } else if(typeName_ == typeName(Data::Collection::Wine)) {
+ return new Data::WineCollection(addFields_);
+ } else if(typeName_ == typeName(Data::Collection::Game)) {
+ return new Data::GameCollection(addFields_);
+ } else if(typeName_ == typeName(Data::Collection::File)) {
+ return new Data::FileCatalog(addFields_);
+ } else if(typeName_ == typeName(Data::Collection::BoardGame)) {
+ return new Data::BoardGameCollection(addFields_);
+ } else {
+ kdWarning() << "CollectionFactory::collection() - collection type not implemented: " << typeName_ << endl;
+ return 0;
+ }
+}
+
+Tellico::CollectionNameMap CollectionFactory::nameMap() {
+ CollectionNameMap map;
+ map[Data::Collection::Book] = i18n("Book Collection");
+ map[Data::Collection::Bibtex] = i18n("Bibliography");
+ map[Data::Collection::ComicBook] = i18n("Comic Book Collection");
+ map[Data::Collection::Video] = i18n("Video Collection");
+ map[Data::Collection::Album] = i18n("Music Collection");
+ map[Data::Collection::Coin] = i18n("Coin Collection");
+ map[Data::Collection::Stamp] = i18n("Stamp Collection");
+ map[Data::Collection::Wine] = i18n("Wine Collection");
+ map[Data::Collection::Card] = i18n("Card Collection");
+ map[Data::Collection::Game] = i18n("Game Collection");
+ map[Data::Collection::File] = i18n("File Catalog");
+ map[Data::Collection::BoardGame] = i18n("Board Game Collection");
+ map[Data::Collection::Base] = i18n("Custom Collection");
+ return map;
+}
+
+QString CollectionFactory::typeName(int type_) {
+ switch(type_) {
+ case Data::Collection::Book:
+ return QString::fromLatin1("book");
+ break;
+
+ case Data::Collection::Video:
+ return QString::fromLatin1("video");
+ break;
+
+ case Data::Collection::Album:
+ return QString::fromLatin1("album");
+ break;
+
+ case Data::Collection::Bibtex:
+ return QString::fromLatin1("bibtex");
+ break;
+
+ case Data::Collection::ComicBook:
+ return QString::fromLatin1("comic");
+ break;
+
+ case Data::Collection::Wine:
+ return QString::fromLatin1("wine");
+ break;
+
+ case Data::Collection::Coin:
+ return QString::fromLatin1("coin");
+ break;
+
+ case Data::Collection::Stamp:
+ return QString::fromLatin1("stamp");
+ break;
+
+ case Data::Collection::Card:
+ return QString::fromLatin1("card");
+ break;
+
+ case Data::Collection::Game:
+ return QString::fromLatin1("game");
+ break;
+
+ case Data::Collection::File:
+ return QString::fromLatin1("file");
+ break;
+
+ case Data::Collection::BoardGame:
+ return QString::fromLatin1("boardgame");
+ break;
+
+ case Data::Collection::Base:
+ return QString::fromLatin1("entry");
+ break;
+
+ default:
+ kdWarning() << "CollectionFactory::collection() - collection type not implemented: " << type_ << endl;
+ return QString::fromLatin1("entry");
+ break;
+ }
+}
+
+bool CollectionFactory::isDefaultField(int type_, const QString& name_) {
+ Data::CollPtr coll = collection(type_, true);
+ Data::FieldVec fields = coll->fields();
+ for(Data::FieldVec::Iterator field = fields.begin(); field != fields.end(); ++field) {
+ if(field->name() == name_) {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/src/collectionfactory.h b/src/collectionfactory.h
new file mode 100644
index 0000000..72d42b1
--- /dev/null
+++ b/src/collectionfactory.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef COLLECTIONFACTORY_H
+#define COLLECTIONFACTORY_H
+
+#include "datavectors.h"
+
+#include <qmap.h>
+
+namespace Tellico {
+
+typedef QMap<int, QString> CollectionNameMap;
+
+/**
+ * A factory class for dealing with the different types of collections.
+ *
+ * @author Robby Stephenson
+ */
+class CollectionFactory {
+public:
+ static Data::CollPtr collection(int type, bool addFields);
+ static Data::CollPtr collection(const QString& typeName, bool addFields);
+ static CollectionNameMap nameMap();
+ static QString typeName(int type);
+ static bool isDefaultField(int type, const QString& name);
+};
+
+} // end namespace
+#endif
diff --git a/src/collectionfieldsdialog.cpp b/src/collectionfieldsdialog.cpp
new file mode 100644
index 0000000..cc9aede
--- /dev/null
+++ b/src/collectionfieldsdialog.cpp
@@ -0,0 +1,1036 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "collectionfieldsdialog.h"
+#include "collection.h"
+#include "field.h"
+#include "collectionfactory.h"
+#include "gui/stringmapdialog.h"
+#include "tellico_kernel.h"
+#include "translators/tellico_xml.h"
+#include "tellico_utils.h"
+#include "tellico_debug.h"
+
+#include <klocale.h>
+#include <kcombobox.h>
+#include <klineedit.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kpushbutton.h>
+#include <kaccelmanager.h>
+
+#include <qgroupbox.h>
+#include <qlayout.h>
+#include <qhbox.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include <qcheckbox.h>
+#include <qregexp.h>
+#include <qwhatsthis.h>
+#include <qtimer.h>
+
+using Tellico::FieldListBox;
+using Tellico::CollectionFieldsDialog;
+
+FieldListBox::FieldListBox(QListBox* listbox_, Data::FieldPtr field_)
+ : GUI::ListBoxText(listbox_, field_->title()), m_field(field_) {
+}
+
+FieldListBox::FieldListBox(QListBox* listbox_, Data::FieldPtr field_, QListBoxItem* after_)
+ : GUI::ListBoxText(listbox_, field_->title(), after_), m_field(field_) {
+}
+
+CollectionFieldsDialog::CollectionFieldsDialog(Data::CollPtr coll_, QWidget* parent_, const char* name_/*=0*/)
+ : KDialogBase(parent_, name_, false, i18n("Collection Fields"), Help|Default|Ok|Apply|Cancel, Ok, false),
+ m_coll(coll_),
+ m_defaultCollection(0),
+ m_currentField(0),
+ m_modified(false),
+ m_updatingValues(false),
+ m_reordered(false),
+ m_oldIndex(-1) {
+ QWidget* page = new QWidget(this);
+ setMainWidget(page);
+ QHBoxLayout* topLayout = new QHBoxLayout(page, 0, KDialog::spacingHint());
+
+ QGroupBox* fieldsGroup = new QGroupBox(1, Qt::Horizontal, i18n("Current Fields"), page);
+ topLayout->addWidget(fieldsGroup, 1);
+ m_fieldsBox = new QListBox(fieldsGroup);
+ m_fieldsBox->setMinimumWidth(150);
+
+ Data::FieldVec fields = m_coll->fields();
+ for(Data::FieldVec::Iterator it = fields.begin(); it != fields.end(); ++it) {
+ // ignore ReadOnly
+ if(it->type() != Data::Field::ReadOnly) {
+ (void) new FieldListBox(m_fieldsBox, it);
+ }
+ }
+ connect(m_fieldsBox, SIGNAL(highlighted(int)), SLOT(slotHighlightedChanged(int)));
+
+ QHBox* hb1 = new QHBox(fieldsGroup);
+ hb1->setSpacing(KDialog::spacingHint());
+ m_btnNew = new KPushButton(i18n("New Field", "&New"), hb1);
+ m_btnNew->setIconSet(BarIcon(QString::fromLatin1("filenew"), KIcon::SizeSmall));
+ QWhatsThis::add(m_btnNew, i18n("Add a new field to the collection"));
+ m_btnDelete = new KPushButton(i18n("Delete Field", "&Delete"), hb1);
+ m_btnDelete->setIconSet(BarIconSet(QString::fromLatin1("editdelete"), KIcon::SizeSmall));
+ QWhatsThis::add(m_btnDelete, i18n("Remove a field from the collection"));
+
+ connect(m_btnNew, SIGNAL(clicked()), SLOT(slotNew()) );
+ connect(m_btnDelete, SIGNAL(clicked()), SLOT(slotDelete()));
+
+ QHBox* hb2 = new QHBox(fieldsGroup);
+ hb2->setSpacing(KDialog::spacingHint());
+ m_btnUp = new KPushButton(hb2);
+ m_btnUp->setPixmap(BarIcon(QString::fromLatin1("up"), KIcon::SizeSmall));
+ QWhatsThis::add(m_btnUp, i18n("Move this field up in the list. The list order is important "
+ "for the layout of the entry editor."));
+ m_btnDown = new KPushButton(hb2);
+ m_btnDown->setPixmap(BarIcon(QString::fromLatin1("down"), KIcon::SizeSmall));
+ QWhatsThis::add(m_btnDown, i18n("Move this field down in the list. The list order is important "
+ "for the layout of the entry editor."));
+
+ connect(m_btnUp, SIGNAL(clicked()), SLOT(slotMoveUp()) );
+ connect(m_btnDown, SIGNAL(clicked()), SLOT(slotMoveDown()));
+
+ QVBox* vbox = new QVBox(page);
+ vbox->setSpacing(KDialog::spacingHint());
+ topLayout->addWidget(vbox, 2);
+
+ QGroupBox* propGroup = new QGroupBox(1, Qt::Horizontal, i18n("Field Properties"), vbox);
+
+ QWidget* grid = new QWidget(propGroup);
+ // (parent, nrows, ncols, margin, spacing)
+ QGridLayout* layout = new QGridLayout(grid, 4, 4, 0, KDialog::spacingHint());
+
+ int row = -1;
+ QLabel* label = new QLabel(i18n("&Title:"), grid);
+ layout->addWidget(label, ++row, 0);
+ m_titleEdit = new KLineEdit(grid);
+ layout->addWidget(m_titleEdit, row, 1);
+ label->setBuddy(m_titleEdit);
+ QString whats = i18n("The title of the field");
+ QWhatsThis::add(label, whats);
+ QWhatsThis::add(m_titleEdit, whats);
+ connect(m_titleEdit, SIGNAL(textChanged(const QString&)), SLOT(slotModified()));
+
+ label = new QLabel(i18n("T&ype:"), grid);
+ layout->addWidget(label, row, 2);
+ m_typeCombo = new KComboBox(grid);
+ layout->addWidget(m_typeCombo, row, 3);
+ label->setBuddy(m_typeCombo);
+ whats = QString::fromLatin1("<qt>");
+ whats += i18n("The type of the field determines what values may be used. ");
+ whats += i18n("<i>Simple Text</i> is used for most fields. ");
+ whats += i18n("<i>Paragraph</i> is for large text blocks. ");
+ whats += i18n("<i>Choice</i> limits the field to certain values. ");
+ whats += i18n("<i>Checkbox</i> is for a simple yes/no value. ");
+ whats += i18n("<i>Number</i> indicates that the field contains a numerical value. ");
+ whats += i18n("<i>URL</i> is for fields which refer to URLs, including references to other files. ");
+ whats += i18n("A <i>Table</i> may hold one or more columns of values. ");
+ whats += i18n("An <i>Image</i> field holds a picture. ");
+ whats += i18n("A <i>Date</i> field can be used for values with a day, month, and year. ");
+ whats += i18n("A <i>Rating</i> field uses stars to show a rating number. ");
+ whats += i18n("A <i>Dependent</i> field depends on the values of other "
+ "fields, and is formatted according to the field description. ");
+ whats += i18n("A <i>Read Only</i> is for internal values, possibly useful for import and export. ");
+ whats += QString::fromLatin1("</qt>");
+ QWhatsThis::add(label, whats);
+ QWhatsThis::add(m_typeCombo, whats);
+ // the typeTitles match the fieldMap().values() but in a better order
+ m_typeCombo->insertStringList(Data::Field::typeTitles());
+ connect(m_typeCombo, SIGNAL(activated(int)), SLOT(slotModified()));
+ connect(m_typeCombo, SIGNAL(activated(const QString&)), SLOT(slotTypeChanged(const QString&)));
+
+ label = new QLabel(i18n("Cate&gory:"), grid);
+ layout->addWidget(label, ++row, 0);
+ m_catCombo = new KComboBox(true, grid);
+ layout->addWidget(m_catCombo, row, 1);
+ label->setBuddy(m_catCombo);
+ whats = i18n("The field category determines where the field is placed in the editor.");
+ QWhatsThis::add(label, whats);
+ QWhatsThis::add(m_catCombo, whats);
+
+ // I don't want to include the categories for singleCategory fields
+ QStringList cats;
+ const QStringList allCats = m_coll->fieldCategories();
+ for(QStringList::ConstIterator it = allCats.begin(); it != allCats.end(); ++it) {
+ Data::FieldVec fields = m_coll->fieldsByCategory(*it);
+ if(!fields.isEmpty() && !fields.begin()->isSingleCategory()) {
+ cats.append(*it);
+ }
+ }
+ m_catCombo->insertStringList(cats);
+ m_catCombo->setDuplicatesEnabled(false);
+ connect(m_catCombo, SIGNAL(textChanged(const QString&)), SLOT(slotModified()));
+
+ label = new QLabel(i18n("Descr&iption:"), grid);
+ layout->addWidget(label, ++row, 0);
+ m_descEdit = new KLineEdit(grid);
+ m_descEdit->setMinimumWidth(150);
+ layout->addMultiCellWidget(m_descEdit, row, row, 1, 3);
+ label->setBuddy(m_descEdit);
+ /* TRANSLATORS: Do not translate %{year} and %{title}. */
+ whats = i18n("The description is a useful reminder of what information is contained in the "
+ "field. For <i>Dependent</i> fields, the description is a format string such as "
+ "\"%{year} %{title}\" where the named fields get substituted in the string.");
+ QWhatsThis::add(label, whats);
+ QWhatsThis::add(m_descEdit, whats);
+ connect(m_descEdit, SIGNAL(textChanged(const QString&)), SLOT(slotModified()));
+
+ label = new QLabel(i18n("&Default value:"), grid);
+ layout->addWidget(label, ++row, 0);
+ m_defaultEdit = new KLineEdit(grid);
+ layout->addMultiCellWidget(m_defaultEdit, row, row, 1, 3);
+ label->setBuddy(m_defaultEdit);
+ whats = i18n("<qt>A default value can be set for new entries.</qt>");
+ QWhatsThis::add(label, whats);
+ QWhatsThis::add(m_defaultEdit, whats);
+ connect(m_defaultEdit, SIGNAL(textChanged(const QString&)), SLOT(slotModified()));
+
+ label = new QLabel(i18n("A&llowed values:"), grid);
+ layout->addWidget(label, ++row, 0);
+ m_allowEdit = new KLineEdit(grid);
+ layout->addMultiCellWidget(m_allowEdit, row, row, 1, 3);
+ label->setBuddy(m_allowEdit);
+ whats = i18n("<qt>For <i>Choice</i>-type fields, these are the only values allowed. They are "
+ "placed in a combo box. The possible values have to be separated by a semi-colon, "
+ "for example: \"dog; cat; mouse\"</qt>");
+ QWhatsThis::add(label, whats);
+ QWhatsThis::add(m_allowEdit, whats);
+ connect(m_allowEdit, SIGNAL(textChanged(const QString&)), SLOT(slotModified()));
+
+ label = new QLabel(i18n("Extended &properties:"), grid);
+ layout->addWidget(label, ++row, 0);
+ m_btnExtended = new KPushButton(i18n("&Set..."), grid);
+ m_btnExtended->setIconSet(BarIcon(QString::fromLatin1("bookmark"), KIcon::SizeSmall));
+ layout->addWidget(m_btnExtended, row, 1);
+ label->setBuddy(m_btnExtended);
+ whats = i18n("Extended field properties are used to specify things such as the corresponding bibtex field.");
+ QWhatsThis::add(label, whats);
+ QWhatsThis::add(m_btnExtended, whats);
+ connect(m_btnExtended, SIGNAL(clicked()), SLOT(slotShowExtendedProperties()));
+
+ QButtonGroup* bg = new QButtonGroup(1, Qt::Horizontal, i18n("Format Options"), vbox);
+ m_formatNone = new QRadioButton(i18n("No formatting"), bg);
+ QWhatsThis::add(m_formatNone, i18n("This option prevents the field from ever being "
+ "automatically formatted or capitalized."));
+ m_formatPlain = new QRadioButton(i18n("Allow auto-capitalization only"), bg);
+ QWhatsThis::add(m_formatPlain, i18n("This option allows the field to be capitalized, but "
+ "not specially formatted."));
+ m_formatTitle = new QRadioButton(i18n("Format as a title"), bg);
+ QWhatsThis::add(m_formatTitle, i18n("This option capitalizes and formats the field as a "
+ "title, but only if those options are globally set."));
+ m_formatName = new QRadioButton(i18n("Format as a name"), bg);
+ QWhatsThis::add(m_formatName, i18n("This option capitalizes and formats the field as a "
+ "name, but only if those options are globally set."));
+ connect(bg, SIGNAL(clicked(int)), SLOT(slotModified()));
+
+ QGroupBox* optionsGroup = new QGroupBox(1, Qt::Horizontal, i18n("Field Options"), vbox);
+ m_complete = new QCheckBox(i18n("Enable auto-completion"), optionsGroup);
+ QWhatsThis::add(m_complete, i18n("If checked, KDE auto-completion will be enabled in the "
+ "text edit box for this field."));
+ m_multiple = new QCheckBox(i18n("Allow multiple values"), optionsGroup);
+ QWhatsThis::add(m_multiple, i18n("If checked, Tellico will parse the values in the field "
+ "for multiple values, separated by a semi-colon."));
+ m_grouped = new QCheckBox(i18n("Allow grouping"), optionsGroup);
+ QWhatsThis::add(m_grouped, i18n("If checked, this field may be used to group the entries in "
+ "the group view."));
+ connect(m_complete, SIGNAL(clicked()), SLOT(slotModified()));
+ connect(m_multiple, SIGNAL(clicked()), SLOT(slotModified()));
+ connect(m_grouped, SIGNAL(clicked()), SLOT(slotModified()));
+
+ // need to stretch at bottom
+ vbox->setStretchFactor(new QWidget(vbox), 1);
+ KAcceleratorManager::manage(vbox);
+
+ // keep a default collection
+ m_defaultCollection = CollectionFactory::collection(m_coll->type(), true);
+
+ QWhatsThis::add(actionButton(KDialogBase::Default),
+ i18n("Revert the selected field's properties to the default values."));
+
+ enableButtonOK(false);
+ enableButtonApply(false);
+
+ setHelp(QString::fromLatin1("fields-dialog"));
+
+ // initially the m_typeCombo is populated with all types, but as soon as something is
+ // selected in the fields box, the combo box is cleared and filled with the allowable
+ // new types. The problem is that when more types are added, the size of the combo box
+ // doesn't change. So when everything is laid out, the combo box needs to have all the
+ // items there.
+ QTimer::singleShot(0, this, SLOT(slotSelectInitial()));
+}
+
+CollectionFieldsDialog::~CollectionFieldsDialog() {
+}
+
+void CollectionFieldsDialog::slotSelectInitial() {
+ m_fieldsBox->setSelected(0, true);
+}
+
+void CollectionFieldsDialog::slotOk() {
+ updateField();
+ if(!checkValues()) {
+ return;
+ }
+
+ applyChanges();
+ accept();
+}
+
+void CollectionFieldsDialog::slotApply() {
+ updateField();
+ if(!checkValues()) {
+ return;
+ }
+
+ applyChanges();
+}
+
+void CollectionFieldsDialog::applyChanges() {
+// start a command group, "Modify" is a generic term here since the commands could be add, modify, or delete
+ Kernel::self()->beginCommandGroup(i18n("Modify Fields"));
+
+ Data::FieldPtr field;
+ for(Data::FieldVec::Iterator it = m_copiedFields.begin(); it != m_copiedFields.end(); ++it) {
+ field = it;
+ // check for Choice fields with removed values to warn user
+ if(field->type() == Data::Field::Choice || field->type() == Data::Field::Rating) {
+ QStringList oldValues = m_coll->fieldByName(field->name())->allowed();
+ QStringList newValues = field->allowed();
+ for(QStringList::ConstIterator vIt = oldValues.begin(); vIt != oldValues.end(); ++vIt) {
+ if(newValues.contains(*vIt)) {
+ continue;
+ }
+ int ret = KMessageBox::warningContinueCancel(this,
+ i18n("<qt>Removing allowed values from the <i>%1</i> field which "
+ "currently exist in the collection may cause data corruption. "
+ "Do you want to keep your modified values or cancel and revert "
+ "to the current ones?</qt>").arg(field->title()),
+ QString::null,
+ i18n("Keep modified values"));
+ if(ret != KMessageBox::Continue) {
+ if(field->type() == Data::Field::Choice) {
+ field->setAllowed(oldValues);
+ } else { // rating field
+ Data::FieldPtr oldField = m_coll->fieldByName(field->name());
+ field->setProperty(QString::fromLatin1("minimum"), oldField->property(QString::fromLatin1("minimum")));
+ field->setProperty(QString::fromLatin1("maximum"), oldField->property(QString::fromLatin1("maximum")));
+ }
+ }
+ break;
+ }
+ }
+ Kernel::self()->modifyField(field);
+ }
+
+ for(Data::FieldVec::Iterator it = m_newFields.begin(); it != m_newFields.end(); ++it) {
+ Kernel::self()->addField(it);
+ }
+
+ // set all text not to be colored, and get new list
+ Data::FieldVec fields;
+ for(QListBoxItem* item = m_fieldsBox->firstItem(); item; item = item->next()) {
+ static_cast<FieldListBox*>(item)->setColored(false);
+ if(m_reordered) {
+ Data::FieldPtr field = static_cast<FieldListBox*>(item)->field();
+ if(field) {
+ fields.append(field);
+ }
+ }
+ }
+
+ // if reordering fields, need to add ReadOnly fields since they were not shown
+ if(m_reordered) {
+ Data::FieldVec allFields = m_coll->fields();
+ for(Data::FieldVec::Iterator it = allFields.begin(); it != allFields.end(); ++it) {
+ if(it->type() == Data::Field::ReadOnly) {
+ fields.append(it);
+ }
+ }
+ }
+
+ if(fields.count() > 0) {
+ Kernel::self()->reorderFields(fields);
+ }
+
+ // commit command group
+ Kernel::self()->endCommandGroup();
+
+ // now clear copied fields
+ m_copiedFields.clear();
+ // clear new ones, too
+ m_newFields.clear();
+
+ m_currentField = static_cast<FieldListBox*>(m_fieldsBox->selectedItem())->field();
+
+ // the field type might have changed, so need to update the type combo list with possible values
+ if(m_currentField) {
+ // set the updating flag since the values are changing and slots are firing
+ // but we don't care about UI indications of changes
+ bool wasUpdating = m_updatingValues;
+ m_updatingValues = true;
+ QString currType = m_typeCombo->currentText();
+ m_typeCombo->clear();
+ m_typeCombo->insertStringList(newTypesAllowed(m_currentField->type()));
+ m_typeCombo->setCurrentItem(currType);
+ // description might have been changed for dependent fields
+ m_descEdit->setText(m_currentField->description());
+ m_updatingValues = wasUpdating;
+ }
+ enableButtonApply(false);
+}
+
+void CollectionFieldsDialog::slotNew() {
+ // first update the current one with all the values from the edit widgets
+ updateField();
+
+ // next check old values
+ if(!checkValues()) {
+ return;
+ }
+
+ QString name = QString::fromLatin1("custom") + QString::number(m_newFields.count()+1);
+ int count = m_newFields.count() + 1;
+ QString title = i18n("New Field") + QString::fromLatin1(" %1").arg(count);
+ while(m_fieldsBox->findItem(title)) {
+ ++count;
+ title = i18n("New Field") + QString::fromLatin1(" %1").arg(count);
+ }
+
+ Data::FieldPtr field = new Data::Field(name, title);
+ m_newFields.append(field);
+// myDebug() << "CollectionFieldsDialog::slotNew() - adding new field " << title << endl;
+
+ m_currentField = field;
+
+ FieldListBox* box = new FieldListBox(m_fieldsBox, field);
+ m_fieldsBox->setSelected(box, true);
+ box->setColored(true);
+ m_fieldsBox->ensureCurrentVisible();
+ slotModified();
+ m_titleEdit->setFocus();
+ m_titleEdit->selectAll();
+}
+
+void CollectionFieldsDialog::slotDelete() {
+ if(!m_currentField) {
+ return;
+ }
+
+ if(m_newFields.contains(m_currentField)) {
+ // remove field from vector before deleting item containing field
+ m_newFields.remove(m_currentField);
+ m_fieldsBox->removeItem(m_fieldsBox->currentItem());
+ m_fieldsBox->setSelected(m_fieldsBox->currentItem(), true);
+ m_fieldsBox->ensureCurrentVisible();
+ m_currentField = static_cast<FieldListBox*>(m_fieldsBox->selectedItem())->field(); // KShared gets auto-deleted
+ return;
+ }
+
+ bool success = Kernel::self()->removeField(m_currentField);
+ if(success) {
+ emit signalCollectionModified();
+ m_fieldsBox->removeItem(m_fieldsBox->currentItem());
+ m_fieldsBox->setSelected(m_fieldsBox->currentItem(), true);
+ m_fieldsBox->ensureCurrentVisible();
+ m_currentField = static_cast<FieldListBox*>(m_fieldsBox->selectedItem())->field();
+ enableButtonOK(true);
+ }
+}
+
+void CollectionFieldsDialog::slotTypeChanged(const QString& type_) {
+ Data::Field::Type type = Data::Field::Undef;
+ const Data::Field::FieldMap fieldMap = Data::Field::typeMap();
+ for(Data::Field::FieldMap::ConstIterator it = fieldMap.begin(); it != fieldMap.end(); ++it) {
+ if(it.data() == type_) {
+ type = it.key();
+ break;
+ }
+ }
+ if(type == Data::Field::Undef) {
+ kdWarning() << "CollectionFieldsDialog::slotTypeChanged() - type name not recognized: " << type_ << endl;
+ type = Data::Field::Line;
+ }
+
+ // only choice types gets allowed values
+ m_allowEdit->setEnabled(type == Data::Field::Choice);
+
+ // paragraphs, tables, and images are their own category
+ bool isCategory = (type == Data::Field::Para || type == Data::Field::Table ||
+ type == Data::Field::Table2 || type == Data::Field::Image);
+ m_catCombo->setEnabled(!isCategory);
+
+ // formatting is only applicable when the type is simple text or a table
+ bool isText = (type == Data::Field::Line || type == Data::Field::Table ||
+ type == Data::Field::Table2);
+ // formatNone is the default
+ m_formatPlain->setEnabled(isText);
+ m_formatName->setEnabled(isText);
+ m_formatTitle->setEnabled(isText);
+
+ // multiple is only applicable for simple text and number
+ isText = (type == Data::Field::Line || type == Data::Field::Number);
+ m_multiple->setEnabled(isText);
+
+ // completion is only applicable for simple text, number, and URL
+ isText = (isText || type == Data::Field::URL);
+ m_complete->setEnabled(isText);
+
+ // grouping is not possible with paragraphs or images
+ m_grouped->setEnabled(type != Data::Field::Para && type != Data::Field::Image);
+}
+
+void CollectionFieldsDialog::slotHighlightedChanged(int index_) {
+// myDebug() << "CollectionFieldsDialog::slotHighlightedChanged() - " << index_ << endl;
+
+ // use this instead of blocking signals everywhere
+ m_updatingValues = true;
+
+ // first update the current one with all the values from the edit widgets
+ updateField();
+
+ // next check old values
+ if(!checkValues()) {
+ m_fieldsBox->blockSignals(true);
+ m_fieldsBox->setSelected(m_oldIndex, true);
+ m_fieldsBox->blockSignals(false);
+ m_updatingValues = false;
+ return;
+ }
+ m_oldIndex = index_;
+
+ m_btnUp->setEnabled(index_ > 0);
+ m_btnDown->setEnabled(index_ < static_cast<int>(m_fieldsBox->count())-1);
+
+ FieldListBox* item = dynamic_cast<FieldListBox*>(m_fieldsBox->item(index_));
+ if(!item) {
+ return;
+ }
+
+ // need to get a pointer to the field with the new values to insert
+ Data::FieldPtr field = item->field();
+ if(!field) {
+ myDebug() << "CollectionFieldsDialog::slotHighlightedChanged() - no field found!" << endl;
+ return;
+ }
+
+ m_titleEdit->setText(field->title());
+
+ // type is limited to certain types, unless it's a new field
+ m_typeCombo->clear();
+ if(m_newFields.contains(field)) {
+ m_typeCombo->insertStringList(newTypesAllowed(Data::Field::Undef));
+ } else {
+ m_typeCombo->insertStringList(newTypesAllowed(field->type()));
+ }
+ // if the current name is not there, then this will change the list!
+ const Data::Field::FieldMap& fieldMap = Data::Field::typeMap();
+ m_typeCombo->setCurrentText(fieldMap[field->type()]);
+ slotTypeChanged(fieldMap[field->type()]); // just setting the text doesn't emit the activated signal
+
+ if(field->type() == Data::Field::Choice) {
+ m_allowEdit->setText(field->allowed().join(QString::fromLatin1("; ")));
+ } else {
+ m_allowEdit->clear();
+ }
+
+ m_catCombo->setCurrentText(field->category()); // have to do this here
+ m_descEdit->setText(field->description());
+ m_defaultEdit->setText(field->defaultValue());
+
+ switch(field->formatFlag()) {
+ case Data::Field::FormatNone:
+ case Data::Field::FormatDate: // as yet unimplemented
+ m_formatNone->setChecked(true);
+ break;
+
+ case Data::Field::FormatPlain:
+ m_formatPlain->setChecked(true);
+ break;
+
+ case Data::Field::FormatTitle:
+ m_formatTitle->setChecked(true);
+ break;
+
+ case Data::Field::FormatName:
+ m_formatName->setChecked(true);
+ break;
+
+ default:
+ kdWarning() << "CollectionFieldsDialog::slotHighlightedChanged() - no format type!" << endl;
+ break;
+ }
+
+ int flags = field->flags();
+ m_complete->setChecked(flags & Data::Field::AllowCompletion);
+ m_multiple->setChecked(flags & Data::Field::AllowMultiple);
+ m_grouped->setChecked(flags & Data::Field::AllowGrouped);
+
+ m_btnDelete->setEnabled(!(flags & Data::Field::NoDelete));
+
+ // default button is enabled only if default collection contains the field
+ if(m_defaultCollection) {
+ bool hasField = m_defaultCollection->hasField(field->name());
+ actionButton(KDialogBase::Default)->setEnabled(hasField);
+ }
+
+ m_currentField = field;
+ m_updatingValues = false;
+}
+
+void CollectionFieldsDialog::updateField() {
+// myDebug() << "CollectionFieldsDialog::updateField()" << endl;
+ Data::FieldPtr field = m_currentField;
+ if(!field || !m_modified) {
+ return;
+ }
+
+ // only update name if it's one of the new ones
+ if(m_newFields.contains(field)) {
+ // name needs to be a valid XML element name
+ QString name = XML::elementName(m_titleEdit->text().lower());
+ if(name.isEmpty()) { // might end up with empty string
+ name = QString::fromLatin1("custom") + QString::number(m_newFields.count()+1);
+ }
+ while(m_coll->hasField(name)) { // ensure name uniqueness
+ name += QString::fromLatin1("-new");
+ }
+ field->setName(name);
+ }
+
+ const QString title = m_titleEdit->text().simplifyWhiteSpace();
+ updateTitle(title);
+
+ const Data::Field::FieldMap& fieldMap = Data::Field::typeMap();
+ for(Data::Field::FieldMap::ConstIterator it = fieldMap.begin(); it != fieldMap.end(); ++it) {
+ if(it.data() == m_typeCombo->currentText()) {
+ field->setType(it.key());
+ break;
+ }
+ }
+
+ if(field->type() == Data::Field::Choice) {
+ const QRegExp rx(QString::fromLatin1("\\s*;\\s*"));
+ field->setAllowed(QStringList::split(rx, m_allowEdit->text()));
+ field->setProperty(QString::fromLatin1("minimum"), QString::null);
+ field->setProperty(QString::fromLatin1("maximum"), QString::null);
+ } else if(field->type() == Data::Field::Rating) {
+ QString v = field->property(QString::fromLatin1("minimum"));
+ if(v.isEmpty()) {
+ field->setProperty(QString::fromLatin1("minimum"), QString::number(1));
+ }
+ v = field->property(QString::fromLatin1("maximum"));
+ if(v.isEmpty()) {
+ field->setProperty(QString::fromLatin1("maximum"), QString::number(5));
+ }
+ }
+
+ if(field->isSingleCategory()) {
+ field->setCategory(field->title());
+ } else {
+ QString category = m_catCombo->currentText().simplifyWhiteSpace();
+ field->setCategory(category);
+ m_catCombo->setCurrentItem(category, true); // if it doesn't exist, it's added
+ }
+
+ field->setDescription(m_descEdit->text());
+ field->setDefaultValue(m_defaultEdit->text());
+
+ if(m_formatTitle->isChecked()) {
+ field->setFormatFlag(Data::Field::FormatTitle);
+ } else if(m_formatName->isChecked()) {
+ field->setFormatFlag(Data::Field::FormatName);
+ } else if(m_formatPlain->isChecked()) {
+ field->setFormatFlag(Data::Field::FormatPlain);
+ } else {
+ field->setFormatFlag(Data::Field::FormatNone);
+ }
+
+ int flags = 0;
+ if(m_complete->isChecked()) {
+ flags |= Data::Field::AllowCompletion;
+ }
+ if(m_grouped->isChecked()) {
+ flags |= Data::Field::AllowGrouped;
+ }
+ if(m_multiple->isChecked()) {
+ flags |= Data::Field::AllowMultiple;
+ }
+ field->setFlags(flags);
+
+ m_modified = false;
+}
+
+// The purpose here is to first set the modified flag. Then, if the field being edited is one
+// that exists in the collection already, a deep copy needs to be made.
+void CollectionFieldsDialog::slotModified() {
+// myDebug() << "CollectionFieldsDialog::slotModified()" << endl;
+ // if I'm just updating the values, I don't care
+ if(m_updatingValues) {
+ return;
+ }
+
+ m_modified = true;
+
+ enableButtonOK(true);
+ enableButtonApply(true);
+
+ if(!m_currentField) {
+ myDebug() << "CollectionFieldsDialog::slotModified() - no current field!" << endl;
+ m_currentField = static_cast<FieldListBox*>(m_fieldsBox->selectedItem())->field();
+ }
+
+ // color the text
+ static_cast<FieldListBox*>(m_fieldsBox->selectedItem())->setColored(true);
+
+ // check if copy exists already
+ if(m_copiedFields.contains(m_currentField)) {
+ return;
+ }
+
+ // or, check if is a new field, in which case no copy is needed
+ // check if copy exists already
+ if(m_newFields.contains(m_currentField)) {
+ return;
+ }
+
+ m_currentField = new Data::Field(*m_currentField);
+ m_copiedFields.append(m_currentField);
+ static_cast<FieldListBox*>(m_fieldsBox->selectedItem())->setField(m_currentField);
+}
+
+void CollectionFieldsDialog::updateTitle(const QString& title_) {
+// myDebug() << "CollectionFieldsDialog::updateTitle()" << endl;
+ if(m_currentField && m_currentField->title() != title_) {
+ m_fieldsBox->blockSignals(true);
+ FieldListBox* oldItem = findItem(m_fieldsBox, m_currentField);
+ if(!oldItem) {
+ return;
+ }
+ oldItem->setText(title_);
+ // will always be colored since it's new
+ oldItem->setColored(true);
+ m_fieldsBox->triggerUpdate(true);
+
+ m_currentField->setTitle(title_);
+ m_fieldsBox->blockSignals(false);
+ }
+}
+
+void CollectionFieldsDialog::slotDefault() {
+ if(!m_currentField) {
+ return;
+ }
+
+ Data::FieldPtr defaultField = m_defaultCollection->fieldByName(m_currentField->name());
+ if(!defaultField) {
+ return;
+ }
+
+ QString caption = i18n("Revert Field Properties");
+ QString text = i18n("<qt><p>Do you really want to revert the properties for the <em>%1</em> "
+ "field back to their default values?</p></qt>").arg(m_currentField->title());
+ QString dontAsk = QString::fromLatin1("RevertFieldProperties");
+ int ret = KMessageBox::warningContinueCancel(this, text, caption, i18n("Revert"), dontAsk);
+ if(ret != KMessageBox::Continue) {
+ return;
+ }
+
+ // now update all values with default
+ m_updatingValues = true;
+ m_titleEdit->setText(defaultField->title());
+
+ const Data::Field::FieldMap& fieldMap = Data::Field::typeMap();
+ m_typeCombo->setCurrentText(fieldMap[defaultField->type()]);
+ slotTypeChanged(fieldMap[defaultField->type()]); // just setting the text doesn't emit the activated signal
+
+ if(defaultField->type() == Data::Field::Choice) {
+ m_allowEdit->setText(defaultField->allowed().join(QString::fromLatin1("; ")));
+ } else {
+ m_allowEdit->clear();
+ }
+
+ m_catCombo->setCurrentText(defaultField->category()); // have to do this here
+ m_descEdit->setText(defaultField->description());
+ m_defaultEdit->setText(defaultField->defaultValue());
+
+ switch(defaultField->formatFlag()) {
+ case Data::Field::FormatNone:
+ case Data::Field::FormatDate:
+ m_formatNone->setChecked(true);
+ break;
+
+ case Data::Field::FormatPlain:
+ m_formatPlain->setChecked(true);
+ break;
+
+ case Data::Field::FormatTitle:
+ m_formatTitle->setChecked(true);
+ break;
+
+ case Data::Field::FormatName:
+ m_formatName->setChecked(true);
+ break;
+
+ default:
+ break;
+ }
+
+ int flags = defaultField->flags();
+ m_complete->setChecked(flags & Data::Field::AllowCompletion);
+ m_multiple->setChecked(flags & Data::Field::AllowMultiple);
+ m_grouped->setChecked(flags & Data::Field::AllowGrouped);
+
+ m_btnDelete->setEnabled(!(defaultField->flags() & Data::Field::NoDelete));
+
+// m_titleEdit->setFocus();
+// m_titleEdit->selectAll();
+
+ m_updatingValues = false;
+ slotModified();
+}
+
+void CollectionFieldsDialog::slotMoveUp() {
+ QListBoxItem* item = m_fieldsBox->selectedItem();
+ if(item) {
+ FieldListBox* prev = static_cast<FieldListBox*>(item->prev()); // could be 0
+ if(prev) {
+ FieldListBox* newPrev = new FieldListBox(m_fieldsBox, prev->field(), item);
+ newPrev->setColored(prev->isColored());
+ delete prev;
+ m_fieldsBox->ensureCurrentVisible();
+ // since the current one doesn't get re-highlighted, need to highlighted doesn't get emitted
+ slotHighlightedChanged(m_fieldsBox->currentItem());
+ }
+ }
+ m_reordered = true;
+ // don't call slotModified() since that creates a deep copy.
+ m_modified = true;
+
+ enableButtonOK(true);
+ enableButtonApply(true);
+}
+
+void CollectionFieldsDialog::slotMoveDown() {
+ FieldListBox* item = dynamic_cast<FieldListBox*>(m_fieldsBox->selectedItem());
+ if(item) {
+ QListBoxItem* next = item->next(); // could be 0
+ if(next) {
+ FieldListBox* newItem = new FieldListBox(m_fieldsBox, item->field(), next);
+ newItem->setColored(item->isColored());
+ delete item;
+ m_fieldsBox->setSelected(newItem, true);
+ m_fieldsBox->ensureCurrentVisible();
+ }
+ }
+ m_reordered = true;
+ // don't call slotModified() since that creates a deep copy.
+ m_modified = true;
+
+ enableButtonOK(true);
+ enableButtonApply(true);
+}
+
+Tellico::FieldListBox* CollectionFieldsDialog::findItem(const QListBox* box_, Data::FieldPtr field_) {
+// myDebug() << "CollectionFieldsDialog::findItem()" << endl;
+ for(QListBoxItem* item = box_->firstItem(); item; item = item->next()) {
+ FieldListBox* textItem = static_cast<FieldListBox*>(item);
+ if(textItem->field() == field_) {
+ return textItem;
+ }
+ }
+ return 0;
+}
+
+bool CollectionFieldsDialog::slotShowExtendedProperties() {
+ if(!m_currentField) {
+ return false;
+ }
+
+ // the default value is included in properties, but it has a
+ // separate edit box
+ QString dv = m_currentField->defaultValue();
+ StringMap props = m_currentField->propertyList();
+ props.remove(QString::fromLatin1("default"));
+
+ StringMapDialog dlg(props, this, "ExtendedPropertiesDialog", true);
+ dlg.setCaption(i18n("Extended Field Properties"));
+ dlg.setLabels(i18n("Property"), i18n("Value"));
+ if(dlg.exec() == QDialog::Accepted) {
+ props = dlg.stringMap();
+ if(!dv.isEmpty()) {
+ props.insert(QString::fromLatin1("default"), dv);
+ }
+ m_currentField->setPropertyList(props);
+ slotModified();
+ return true;
+ }
+ return false;
+}
+
+bool CollectionFieldsDialog::checkValues() {
+ if(!m_currentField) {
+ return true;
+ }
+
+ const QString title = m_currentField->title();
+ // find total number of boxes with this title in case multiple new ones with same title were added
+ int titleCount = 0;
+ for(uint i = 0; i < m_fieldsBox->count(); ++i) {
+ if(m_fieldsBox->item(i)->text() == title) {
+ ++titleCount;
+ }
+ }
+ if((m_coll->fieldByTitle(title) && m_coll->fieldNameByTitle(title) != m_currentField->name()) ||
+ titleCount > 1) {
+ // already have a field with this title
+ KMessageBox::sorry(this, i18n("A field with this title already exists. Please enter a different title."));
+ m_titleEdit->selectAll();
+ return false;
+ }
+
+ const QString category = m_currentField->category();
+ if(category.isEmpty()) {
+ KMessageBox::sorry(this, i18n("<qt>The category may not be empty. Please enter a category.</qt>"));
+ m_catCombo->lineEdit()->selectAll();
+ return false;
+ }
+
+ Data::FieldVec fields = m_coll->fieldsByCategory(category);
+ if(!fields.isEmpty() && fields.begin()->isSingleCategory() && fields.begin()->name() != m_currentField->name()) {
+ // can't have this category, cause it conflicts with a single-category field
+ KMessageBox::sorry(this, i18n("<qt>A field may not be in the same category as a <em>Paragraph</em>, "
+ "<em>Table</em> or <em>Image</em> field. Please enter a different category.</qt>"));
+ m_catCombo->lineEdit()->selectAll();
+ return false;
+ }
+
+ // the combobox is disabled for single-category fields
+ if(!m_catCombo->isEnabled() && m_coll->fieldByTitle(title) && m_coll->fieldNameByTitle(title) != m_currentField->name()) {
+ KMessageBox::sorry(this, i18n("A field's title may not be the same as an existing category. "
+ "Please enter a different title."));
+ m_titleEdit->selectAll();
+ return false;
+ }
+
+ // check for rating values outside bounds
+ if(m_currentField->type() == Data::Field::Rating) {
+ bool ok; // ok to ignore this here
+ int low = Tellico::toUInt(m_currentField->property(QString::fromLatin1("minimum")), &ok);
+ int high = Tellico::toUInt(m_currentField->property(QString::fromLatin1("maximum")), &ok);
+ while(low < 1 || low > 9 || high < 1 || high > 10 || low >= high) {
+ KMessageBox::sorry(this, i18n("The range for a rating field must be between 1 and 10, "
+ "and the lower bound must be less than the higher bound. "
+ "Please enter different low and high properties."));
+ if(slotShowExtendedProperties()) {
+ low = Tellico::toUInt(m_currentField->property(QString::fromLatin1("minimum")), &ok);
+ high = Tellico::toUInt(m_currentField->property(QString::fromLatin1("maximum")), &ok);
+ } else {
+ return false;
+ }
+ }
+ } else if(m_currentField->type() == Data::Field::Table) {
+ bool ok; // ok to ignore this here
+ int ncols = Tellico::toUInt(m_currentField->property(QString::fromLatin1("columns")), &ok);
+ // also enforced in GUI::TableFieldWidget
+ if(ncols > 10) {
+ KMessageBox::sorry(this, i18n("Tables are limited to a maximum of ten columns."));
+ m_currentField->setProperty(QString::fromLatin1("columns"), QString::fromLatin1("10"));
+ }
+ }
+
+ return true;
+}
+
+// only certain type changes are allowed
+QStringList CollectionFieldsDialog::newTypesAllowed(int type_ /*=0*/) {
+ // Undef means return all
+ if(type_ == Data::Field::Undef) {
+ return Data::Field::typeTitles();
+ }
+
+ const Data::Field::FieldMap& fieldMap = Data::Field::typeMap();
+
+ QStringList newTypes;
+ switch(type_) {
+ case Data::Field::Line: // might not work if converted to a number or URL, but ok
+ case Data::Field::Number:
+ case Data::Field::URL:
+ newTypes += fieldMap[Data::Field::Line];
+ newTypes += fieldMap[Data::Field::Para];
+ newTypes += fieldMap[Data::Field::Number];
+ newTypes += fieldMap[Data::Field::URL];
+ newTypes += fieldMap[Data::Field::Table];
+ break;
+
+ case Data::Field::Date:
+ newTypes += fieldMap[Data::Field::Line];
+ newTypes += fieldMap[Data::Field::Date];
+ break;
+
+ case Data::Field::Bool: // doesn't really make sense, but can't hurt
+ newTypes += fieldMap[Data::Field::Line];
+ newTypes += fieldMap[Data::Field::Para];
+ newTypes += fieldMap[Data::Field::Bool];
+ newTypes += fieldMap[Data::Field::Number];
+ newTypes += fieldMap[Data::Field::URL];
+ newTypes += fieldMap[Data::Field::Table];
+ break;
+
+ case Data::Field::Choice:
+ newTypes += fieldMap[Data::Field::Line];
+ newTypes += fieldMap[Data::Field::Para];
+ newTypes += fieldMap[Data::Field::Choice];
+ newTypes += fieldMap[Data::Field::Number];
+ newTypes += fieldMap[Data::Field::URL];
+ newTypes += fieldMap[Data::Field::Table];
+ newTypes += fieldMap[Data::Field::Rating];
+ break;
+
+ case Data::Field::Table: // not really a good idea since the "::" will be exposed, but allow it
+ case Data::Field::Table2:
+ newTypes += fieldMap[Data::Field::Line];
+ newTypes += fieldMap[Data::Field::Number];
+ newTypes += fieldMap[Data::Field::Table];
+ break;
+
+ case Data::Field::Para:
+ newTypes += fieldMap[Data::Field::Line];
+ newTypes += fieldMap[Data::Field::Para];
+ break;
+
+ case Data::Field::Rating:
+ newTypes += fieldMap[Data::Field::Choice];
+ newTypes += fieldMap[Data::Field::Rating];
+ break;
+
+ // these can never be changed
+ case Data::Field::Image:
+ case Data::Field::Dependent:
+ newTypes = fieldMap[static_cast<Data::Field::Type>(type_)];
+ break;
+
+ default:
+ myDebug() << "CollectionFieldsDialog::newTypesAllowed() - no match for " << type_ << endl;
+ newTypes = Data::Field::typeTitles();
+ break;
+ }
+ return newTypes;
+}
+
+#include "collectionfieldsdialog.moc"
diff --git a/src/collectionfieldsdialog.h b/src/collectionfieldsdialog.h
new file mode 100644
index 0000000..cad0492
--- /dev/null
+++ b/src/collectionfieldsdialog.h
@@ -0,0 +1,127 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef COLLECTIONFIELDSDIALOG_H
+#define COLLECTIONFIELDSDIALOG_H
+
+class KComboBox;
+class KLineEdit;
+class KPushButton;
+
+class QRadioButton;
+class QCheckBox;
+class QPainter;
+
+#include "datavectors.h"
+#include "gui/listboxtext.h"
+
+#include <kdialogbase.h>
+
+#include <qmap.h>
+
+namespace Tellico {
+ namespace Data {
+ class Collection;
+ }
+
+class FieldListBox : public GUI::ListBoxText {
+public:
+ FieldListBox(QListBox* listbox, Data::FieldPtr field);
+ FieldListBox(QListBox* listbox, Data::FieldPtr field, QListBoxItem* after);
+
+ Data::FieldPtr field() const { return m_field; }
+ void setField(Data::FieldPtr field) { m_field = field; }
+
+private:
+ Data::FieldPtr m_field;
+};
+
+/**
+ * @author Robby Stephenson
+ */
+class CollectionFieldsDialog : public KDialogBase {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor sets up the dialog.
+ *
+ * @param coll A pointer to the collection parent of all the attributes
+ * @param parent A pointer to the parent widget
+ * @param name The widget name
+ */
+ CollectionFieldsDialog(Data::CollPtr coll, QWidget* parent, const char* name=0);
+ ~CollectionFieldsDialog();
+
+signals:
+ void signalCollectionModified();
+
+protected slots:
+ virtual void slotOk();
+ virtual void slotApply();
+ virtual void slotDefault();
+
+private slots:
+ void slotNew();
+ void slotDelete();
+ void slotMoveUp();
+ void slotMoveDown();
+ void slotTypeChanged(const QString& type);
+ void slotHighlightedChanged(int index);
+ void slotModified();
+ bool slotShowExtendedProperties();
+ void slotSelectInitial();
+
+private:
+ void applyChanges();
+ void updateField();
+ void updateTitle(const QString& title);
+ bool checkValues();
+ FieldListBox* findItem(const QListBox* box, Data::FieldPtr field);
+ QStringList newTypesAllowed(int type);
+
+ Data::CollPtr m_coll;
+ Data::CollPtr m_defaultCollection;
+ Data::FieldVec m_copiedFields;
+ Data::FieldVec m_newFields;
+ Data::FieldPtr m_currentField;
+ bool m_modified;
+ bool m_updatingValues;
+ bool m_reordered;
+ int m_oldIndex;
+
+ QListBox* m_fieldsBox;
+ KPushButton* m_btnNew;
+ KPushButton* m_btnDelete;
+ KPushButton* m_btnUp;
+ KPushButton* m_btnDown;
+
+ KLineEdit* m_titleEdit;
+ KComboBox* m_typeCombo;
+ KLineEdit* m_allowEdit;
+ KLineEdit* m_defaultEdit;
+ KComboBox* m_catCombo;
+ KLineEdit* m_descEdit;
+ KPushButton* m_btnExtended;
+
+ QRadioButton* m_formatNone;
+ QRadioButton* m_formatPlain;
+ QRadioButton* m_formatTitle;
+ QRadioButton* m_formatName;
+ QCheckBox* m_complete;
+ QCheckBox* m_multiple;
+ QCheckBox* m_grouped;
+};
+
+} // end namespace
+#endif
diff --git a/src/collections/Makefile.am b/src/collections/Makefile.am
new file mode 100644
index 0000000..21543d0
--- /dev/null
+++ b/src/collections/Makefile.am
@@ -0,0 +1,32 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+noinst_LIBRARIES = libcollections.a
+
+AM_CPPFLAGS = $(all_includes)
+
+libcollections_a_METASOURCES = AUTO
+
+libcollections_a_SOURCES = winecollection.cpp stampcollection.cpp \
+ comicbookcollection.cpp cardcollection.cpp coincollection.cpp \
+ bibtexcollection.cpp musiccollection.cpp videocollection.cpp \
+ bookcollection.cpp gamecollection.cpp filecatalog.cpp \
+ boardgamecollection.cpp
+
+####### kdevelop will overwrite this part!!! (end)############
+
+KDE_OPTIONS = noautodist
+
+CLEANFILES = *~ *.loT
+
+EXTRA_DIST = \
+bookcollection.cpp bookcollection.h \
+videocollection.cpp videocollection.h \
+musiccollection.cpp musiccollection.h \
+bibtexcollection.cpp bibtexcollection.h \
+coincollection.cpp coincollection.h \
+cardcollection.cpp cardcollection.h \
+comicbookcollection.cpp comicbookcollection.h \
+stampcollection.cpp stampcollection.h \
+winecollection.cpp winecollection.h \
+gamecollection.h gamecollection.cpp \
+filecatalog.h filecatalog.cpp \
+boardgamecollection.h boardgamecollection.cpp
diff --git a/src/collections/bibtexcollection.cpp b/src/collections/bibtexcollection.cpp
new file mode 100644
index 0000000..f069cc9
--- /dev/null
+++ b/src/collections/bibtexcollection.cpp
@@ -0,0 +1,400 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "bibtexcollection.h"
+#include "../latin1literal.h"
+#include "../document.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+
+using Tellico::Data::BibtexCollection;
+
+namespace {
+ static const char* bibtex_general = I18N_NOOP("General");
+ static const char* bibtex_publishing = I18N_NOOP("Publishing");
+ static const char* bibtex_misc = I18N_NOOP("Miscellaneous");
+}
+
+BibtexCollection::BibtexCollection(bool addFields_, const QString& title_ /*=null*/)
+ : Collection(title_.isEmpty() ? i18n("Bibliography") : title_) {
+ if(addFields_) {
+ addFields(defaultFields());
+ }
+ setDefaultGroupField(QString::fromLatin1("author"));
+
+ // Bibtex has some default macros for the months
+ addMacro(QString::fromLatin1("jan"), QString::null);
+ addMacro(QString::fromLatin1("feb"), QString::null);
+ addMacro(QString::fromLatin1("mar"), QString::null);
+ addMacro(QString::fromLatin1("apr"), QString::null);
+ addMacro(QString::fromLatin1("may"), QString::null);
+ addMacro(QString::fromLatin1("jun"), QString::null);
+ addMacro(QString::fromLatin1("jul"), QString::null);
+ addMacro(QString::fromLatin1("aug"), QString::null);
+ addMacro(QString::fromLatin1("sep"), QString::null);
+ addMacro(QString::fromLatin1("oct"), QString::null);
+ addMacro(QString::fromLatin1("nov"), QString::null);
+ addMacro(QString::fromLatin1("dec"), QString::null);
+}
+
+Tellico::Data::FieldVec BibtexCollection::defaultFields() {
+ FieldVec list;
+ FieldPtr field;
+
+/******************* General ****************************/
+ field = new Field(QString::fromLatin1("title"), i18n("Title"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("title"));
+ field->setCategory(i18n("General"));
+ field->setFlags(Field::NoDelete);
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ QStringList types;
+ types << QString::fromLatin1("article") << QString::fromLatin1("book")
+ << QString::fromLatin1("booklet") << QString::fromLatin1("inbook")
+ << QString::fromLatin1("incollection") << QString::fromLatin1("inproceedings")
+ << QString::fromLatin1("manual") << QString::fromLatin1("mastersthesis")
+ << QString::fromLatin1("misc") << QString::fromLatin1("phdthesis")
+ << QString::fromLatin1("proceedings") << QString::fromLatin1("techreport")
+ << QString::fromLatin1("unpublished") << QString::fromLatin1("periodical")
+ << QString::fromLatin1("conference");
+ field = new Field(QString::fromLatin1("entry-type"), i18n("Entry Type"), types);
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("entry-type"));
+ field->setCategory(i18n(bibtex_general));
+ field->setFlags(Field::AllowGrouped | Field::NoDelete);
+ field->setDescription(i18n("These entry types are specific to bibtex. See the bibtex documentation."));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("author"), i18n("Author"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("author"));
+ field->setCategory(i18n(bibtex_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatName);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("bibtex-key"), i18n("Bibtex Key"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("key"));
+ field->setCategory(i18n("General"));
+ field->setFlags(Field::NoDelete);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("booktitle"), i18n("Book Title"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("booktitle"));
+ field->setCategory(i18n(bibtex_general));
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("editor"), i18n("Editor"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("editor"));
+ field->setCategory(i18n(bibtex_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatName);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("organization"), i18n("Organization"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("organization"));
+ field->setCategory(i18n(bibtex_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+// field = new Field(QString::fromLatin1("institution"), i18n("Institution"));
+// field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("institution"));
+// field->setCategory(i18n(bibtex_general));
+// field->setFlags(Field::AllowDelete);
+// field->setFormatFlag(Field::FormatTitle);
+// list.append(field);
+
+/******************* Publishing ****************************/
+ field = new Field(QString::fromLatin1("publisher"), i18n("Publisher"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("publisher"));
+ field->setCategory(i18n(bibtex_publishing));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("address"), i18n("Address"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("address"));
+ field->setCategory(i18n(bibtex_publishing));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("edition"), i18n("Edition"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("edition"));
+ field->setCategory(i18n(bibtex_publishing));
+ field->setFlags(Field::AllowCompletion);
+ list.append(field);
+
+ // don't make it a nuumber, it could have latex processing commands in it
+ field = new Field(QString::fromLatin1("pages"), i18n("Pages"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("pages"));
+ field->setCategory(i18n(bibtex_publishing));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("year"), i18n("Year"), Field::Number);
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("year"));
+ field->setCategory(i18n(bibtex_publishing));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("isbn"), i18n("ISBN#"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("isbn"));
+ field->setCategory(i18n(bibtex_publishing));
+ field->setDescription(i18n("International Standard Book Number"));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("journal"), i18n("Journal"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("journal"));
+ field->setCategory(i18n(bibtex_publishing));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("doi"), i18n("DOI"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("doi"));
+ field->setCategory(i18n(bibtex_publishing));
+ field->setDescription(i18n("Digital Object Identifier"));
+ list.append(field);
+
+ // could make this a string list, but since bibtex import could have funky values
+ // keep it an editbox
+ field = new Field(QString::fromLatin1("month"), i18n("Month"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("month"));
+ field->setCategory(i18n(bibtex_publishing));
+ field->setFlags(Field::AllowCompletion);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("number"), i18n("Number"), Field::Number);
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("number"));
+ field->setCategory(i18n(bibtex_publishing));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("howpublished"), i18n("How Published"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("howpublished"));
+ field->setCategory(i18n(bibtex_publishing));
+ list.append(field);
+
+// field = new Field(QString::fromLatin1("school"), i18n("School"));
+// field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("school"));
+// field->setCategory(i18n(bibtex_publishing));
+// field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+// list.append(field);
+
+/******************* Classification ****************************/
+ field = new Field(QString::fromLatin1("chapter"), i18n("Chapter"), Field::Number);
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("chapter"));
+ field->setCategory(i18n(bibtex_misc));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("series"), i18n("Series"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("series"));
+ field->setCategory(i18n(bibtex_misc));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("volume"), i18n("Volume"), Field::Number);
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("volume"));
+ field->setCategory(i18n(bibtex_misc));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("crossref"), i18n("Cross-Reference"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("crossref"));
+ field->setCategory(i18n(bibtex_misc));
+ list.append(field);
+
+// field = new Field(QString::fromLatin1("annote"), i18n("Annotation"));
+// field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("annote"));
+// field->setCategory(i18n(bibtex_misc));
+// list.append(field);
+
+ field = new Field(QString::fromLatin1("keyword"), i18n("Keywords"));
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("keywords"));
+ field->setCategory(i18n(bibtex_misc));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("url"), i18n("URL"), Field::URL);
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("url"));
+ field->setCategory(i18n(bibtex_misc));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("abstract"), i18n("Abstract"), Data::Field::Para);
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("abstract"));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("note"), i18n("Notes"), Field::Para);
+ field->setProperty(QString::fromLatin1("bibtex"), QString::fromLatin1("note"));
+ list.append(field);
+
+ return list;
+}
+
+bool BibtexCollection::addField(FieldPtr field_) {
+ if(!field_) {
+ return false;
+ }
+// myDebug() << "BibtexCollection::addField()" << endl;
+ bool success = Collection::addField(field_);
+ if(success) {
+ QString bibtex = field_->property(QString::fromLatin1("bibtex"));
+ if(!bibtex.isEmpty()) {
+ m_bibtexFieldDict.insert(bibtex, field_);
+ }
+ }
+ return success;
+}
+
+bool BibtexCollection::modifyField(FieldPtr newField_) {
+ if(!newField_) {
+ return false;
+ }
+// myDebug() << "BibtexCollection::modifyField()" << endl;
+ bool success = Collection::modifyField(newField_);
+ FieldPtr oldField = fieldByName(newField_->name());
+ QString oldBibtex = oldField->property(QString::fromLatin1("bibtex"));
+ QString newBibtex = newField_->property(QString::fromLatin1("bibtex"));
+ if(!oldBibtex.isEmpty()) {
+ success &= m_bibtexFieldDict.remove(oldBibtex);
+ }
+ if(!newBibtex.isEmpty()) {
+ oldField->setProperty(QString::fromLatin1("bibtex"), newBibtex);
+ m_bibtexFieldDict.insert(newBibtex, oldField);
+ }
+ return success;
+}
+
+bool BibtexCollection::deleteField(FieldPtr field_, bool force_) {
+ if(!field_) {
+ return false;
+ }
+// myDebug() << "BibtexCollection::deleteField()" << endl;
+ bool success = true;
+ QString bibtex = field_->property(QString::fromLatin1("bibtex"));
+ if(!bibtex.isEmpty()) {
+ success &= m_bibtexFieldDict.remove(bibtex);
+ }
+ return success && Collection::removeField(field_, force_);
+}
+
+Tellico::Data::FieldPtr BibtexCollection::fieldByBibtexName(const QString& bibtex_) const {
+ return m_bibtexFieldDict.isEmpty() ? 0 : m_bibtexFieldDict.find(bibtex_);
+}
+
+// same as BookCollection::sameEntry()
+int BibtexCollection::sameEntry(Data::EntryPtr entry1_, Data::EntryPtr entry2_) const {
+ // equal isbn's or lccn's are easy, give it a weight of 100
+ if(Entry::compareValues(entry1_, entry2_, QString::fromLatin1("isbn"), this) > 0 ||
+ Entry::compareValues(entry1_, entry2_, QString::fromLatin1("lccn"), this) > 0 ||
+ Entry::compareValues(entry1_, entry2_, QString::fromLatin1("doi"), this) > 0 ||
+ Entry::compareValues(entry1_, entry2_, QString::fromLatin1("pmid"), this) > 0 ||
+ Entry::compareValues(entry1_, entry2_, QString::fromLatin1("arxiv"), this) > 0) {
+ return 100; // good match
+ }
+ int res = 3*Entry::compareValues(entry1_, entry2_, QString::fromLatin1("title"), this);
+// if(res == 0) {
+// myDebug() << "BookCollection::sameEntry() - different titles for " << entry1_->title() << " vs. "
+// << entry2_->title() << endl;
+// }
+ res += Entry::compareValues(entry1_, entry2_, QString::fromLatin1("author"), this);
+ res += Entry::compareValues(entry1_, entry2_, QString::fromLatin1("cr_year"), this);
+ res += Entry::compareValues(entry1_, entry2_, QString::fromLatin1("pub_year"), this);
+ res += Entry::compareValues(entry1_, entry2_, QString::fromLatin1("binding"), this);
+ return res;
+}
+
+// static
+Tellico::Data::CollPtr BibtexCollection::convertBookCollection(CollPtr coll_) {
+ const QString bibtex = QString::fromLatin1("bibtex");
+ KSharedPtr<BibtexCollection> coll = new BibtexCollection(false, coll_->title());
+ FieldVec fields = coll_->fields();
+ for(FieldVec::Iterator fIt = fields.begin(); fIt != fields.end(); ++fIt) {
+ FieldPtr field = new Data::Field(*fIt);
+
+ // if it already has a bibtex property, skip it
+ if(!field->property(bibtex).isEmpty()) {
+ coll->addField(field);
+ continue;
+ }
+
+ // be sure to set bibtex property before adding it though
+ QString name = field->name();
+ // this first group has bibtex field names the same as their own field name
+ if(name == Latin1Literal("title")
+ || name == Latin1Literal("author")
+ || name == Latin1Literal("editor")
+ || name == Latin1Literal("edition")
+ || name == Latin1Literal("publisher")
+ || name == Latin1Literal("isbn")
+ || name == Latin1Literal("lccn")
+ || name == Latin1Literal("url")
+ || name == Latin1Literal("language")
+ || name == Latin1Literal("pages")
+ || name == Latin1Literal("series")) {
+ field->setProperty(bibtex, name);
+ } else if(name == Latin1Literal("series_num")) {
+ field->setProperty(bibtex, QString::fromLatin1("number"));
+ } else if(name == Latin1Literal("pur_price")) {
+ field->setProperty(bibtex, QString::fromLatin1("price"));
+ } else if(name == Latin1Literal("cr_year")) {
+ field->setProperty(bibtex, QString::fromLatin1("year"));
+ } else if(name == Latin1Literal("bibtex-id")) {
+ field->setProperty(bibtex, QString::fromLatin1("key"));
+ } else if(name == Latin1Literal("keyword")) {
+ field->setProperty(bibtex, QString::fromLatin1("keywords"));
+ } else if(name == Latin1Literal("comments")) {
+ field->setProperty(bibtex, QString::fromLatin1("note"));
+ }
+ coll->addField(field);
+ }
+
+ // also need to add required fields
+ FieldVec vec = defaultFields();
+ for(FieldVec::Iterator it = vec.begin(); it != vec.end(); ++it) {
+ if(!coll->hasField(it->name()) && (it->flags() & Field::NoDelete)) {
+ // but don't add a Bibtex Key if there's already a bibtex-id
+ if(it->property(bibtex) != Latin1Literal("key")
+ || !coll->hasField(QString::fromLatin1("bibtex-id"))) {
+ coll->addField(it);
+ }
+ }
+ }
+
+ // set the entry-type to book
+ FieldPtr field = coll->fieldByBibtexName(QString::fromLatin1("entry-type"));
+ QString entryTypeName;
+ if(field) {
+ entryTypeName = field->name();
+ } else {
+ kdWarning() << "BibtexCollection::convertBookCollection() - there must be an entry type field" << endl;
+ }
+
+ EntryVec newEntries;
+ for(EntryVec::ConstIterator entryIt = coll_->entries().begin(); entryIt != coll_->entries().end(); ++entryIt) {
+ Data::EntryPtr entry = new Entry(*entryIt);
+ entry->setCollection(coll.data());
+ if(!entryTypeName.isEmpty()) {
+ entry->setField(entryTypeName, QString::fromLatin1("book"));
+ }
+ newEntries.append(entry);
+ }
+ coll->addEntries(newEntries);
+
+ // now need to make sure all images are transferred
+ Document::self()->loadAllImagesNow();
+
+ return coll.data();
+}
+
+#include "bibtexcollection.moc"
diff --git a/src/collections/bibtexcollection.h b/src/collections/bibtexcollection.h
new file mode 100644
index 0000000..628cc37
--- /dev/null
+++ b/src/collections/bibtexcollection.h
@@ -0,0 +1,70 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef BIBTEXCOLLECTION_H
+#define BIBTEXCOLLECTION_H
+
+#include "../collection.h"
+
+namespace Tellico {
+ namespace Data {
+
+/**
+ * A collection specifically for bibliographies, in Bibtex format.
+ *
+ * It has the following standard attributes:
+ * @li Title
+ *
+ * @author Robby Stephenson
+ */
+class BibtexCollection : public Collection {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor
+ *
+ * @param addFields A boolean indicating whether the default attributes should be added
+ * @param title The title of the collection
+ */
+ BibtexCollection(bool addFields, const QString& title = QString::null);
+ /**
+ */
+ virtual ~BibtexCollection() {}
+
+ virtual Type type() const { return Bibtex; }
+ virtual bool addField(FieldPtr field);
+ virtual bool modifyField(FieldPtr field);
+ virtual bool deleteField(FieldPtr field, bool force=false);
+
+ FieldPtr fieldByBibtexName(const QString& name) const;
+ const QString& preamble() const { return m_preamble; }
+ void setPreamble(const QString& preamble) { m_preamble = preamble; }
+ const StringMap& macroList() const { return m_macros; }
+ void setMacroList(StringMap map) { m_macros = map; }
+ void addMacro(const QString& key, const QString& value) { m_macros.insert(key, value); }
+
+ virtual int sameEntry(Data::EntryPtr entry1, Data::EntryPtr entry2) const;
+
+ static FieldVec defaultFields();
+ static CollPtr convertBookCollection(CollPtr coll);
+
+private:
+ QDict<Field> m_bibtexFieldDict;
+ QString m_preamble;
+ StringMap m_macros;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/collections/boardgamecollection.cpp b/src/collections/boardgamecollection.cpp
new file mode 100644
index 0000000..4899e0e
--- /dev/null
+++ b/src/collections/boardgamecollection.cpp
@@ -0,0 +1,112 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson, Steve Beattie
+ email : robby@periapsis.org, sbeattie@suse.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "boardgamecollection.h"
+
+#include <klocale.h>
+
+namespace {
+ static const char* boardgame_general = I18N_NOOP("General");
+ static const char* boardgame_personal = I18N_NOOP("Personal");
+}
+
+using Tellico::Data::BoardGameCollection;
+
+BoardGameCollection::BoardGameCollection(bool addFields_, const QString& title_ /*=null*/)
+ : Collection(title_.isEmpty() ? i18n("My Board Games") : title_) {
+ if(addFields_) {
+ addFields(defaultFields());
+ }
+ setDefaultGroupField(QString::fromLatin1("genre"));
+}
+
+Tellico::Data::FieldVec BoardGameCollection::defaultFields() {
+ FieldVec list;
+ FieldPtr field;
+
+ field = new Field(QString::fromLatin1("title"), i18n("Title"));
+ field->setCategory(i18n(boardgame_general));
+ field->setFlags(Field::NoDelete);
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("genre"), i18n("Genre"));
+ field->setCategory(i18n(boardgame_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("mechanism"), i18n("Mechanism"));
+ field->setCategory(i18n(boardgame_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("year"), i18n("Release Year"), Field::Number);
+ field->setCategory(i18n(boardgame_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("publisher"), i18n("Publisher"));
+ field->setCategory(i18n(boardgame_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("designer"), i18n("Designer"));
+ field->setCategory(i18n(boardgame_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("num-player"), i18n("Number of Players"), Field::Number);
+ field->setCategory(i18n(boardgame_general));
+ field->setFlags(Field::AllowMultiple | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("description"), i18n("Description"), Field::Para);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("rating"), i18n("Rating"), Field::Rating);
+ field->setCategory(i18n(boardgame_personal));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_date"), i18n("Purchase Date"));
+ field->setCategory(i18n(boardgame_personal));
+ field->setFormatFlag(Field::FormatDate);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("gift"), i18n("Gift"), Field::Bool);
+ field->setCategory(i18n(boardgame_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_price"), i18n("Purchase Price"));
+ field->setCategory(i18n(boardgame_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("loaned"), i18n("Loaned"), Field::Bool);
+ field->setCategory(i18n(boardgame_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("cover"), i18n("Cover"), Field::Image);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("comments"), i18n("Comments"), Field::Para);
+ field->setCategory(i18n(boardgame_personal));
+ list.append(field);
+
+ return list;
+}
+
+#include "boardgamecollection.moc"
diff --git a/src/collections/boardgamecollection.h b/src/collections/boardgamecollection.h
new file mode 100644
index 0000000..642fc31
--- /dev/null
+++ b/src/collections/boardgamecollection.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson, Steve Beattie
+ email : robby@periapsis.org, sbeattie@suse.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef BOARDGAMECOLLECTION_H
+#define BOARDGAMECOLLECTION_H
+
+#include "../collection.h"
+
+namespace Tellico {
+ namespace Data {
+
+/**
+ * A collection for board (not bored) games.
+ */
+class BoardGameCollection : public Collection {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor
+ *
+ * @param addFields Whether to add the default attributes
+ * @param title The title of the collection
+ */
+ BoardGameCollection(bool addFields, const QString& title = QString::null);
+
+ virtual Type type() const { return BoardGame; }
+
+ static FieldVec defaultFields();
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/collections/bookcollection.cpp b/src/collections/bookcollection.cpp
new file mode 100644
index 0000000..0137156
--- /dev/null
+++ b/src/collections/bookcollection.cpp
@@ -0,0 +1,202 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "bookcollection.h"
+
+#include <klocale.h>
+
+namespace {
+ static const char* book_general = I18N_NOOP("General");
+ static const char* book_publishing = I18N_NOOP("Publishing");
+ static const char* book_classification = I18N_NOOP("Classification");
+ static const char* book_personal = I18N_NOOP("Personal");
+}
+
+using Tellico::Data::BookCollection;
+
+BookCollection::BookCollection(bool addFields_, const QString& title_ /*=null*/)
+ : Collection(title_.isEmpty() ? i18n("My Books") : title_) {
+ if(addFields_) {
+ addFields(defaultFields());
+ }
+ setDefaultGroupField(QString::fromLatin1("author"));
+}
+
+Tellico::Data::FieldVec BookCollection::defaultFields() {
+ FieldVec list;
+ FieldPtr field;
+
+ field = new Field(QString::fromLatin1("title"), i18n("Title"));
+ field->setCategory(i18n("General"));
+ field->setFlags(Field::NoDelete);
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("subtitle"), i18n("Subtitle"));
+ field->setCategory(i18n(book_general));
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("author"), i18n("Author"));
+ field->setCategory(i18n(book_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatName);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("editor"), i18n("Editor"));
+ field->setCategory(i18n(book_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatName);
+ list.append(field);
+
+ QStringList binding;
+ binding << i18n("Hardback") << i18n("Paperback") << i18n("Trade Paperback")
+ << i18n("E-Book") << i18n("Magazine") << i18n("Journal");
+ field = new Field(QString::fromLatin1("binding"), i18n("Binding"), binding);
+ field->setCategory(i18n(book_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_date"), i18n("Purchase Date"));
+ field->setCategory(i18n(book_general));
+ field->setFormatFlag(Field::FormatDate);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_price"), i18n("Purchase Price"));
+ field->setCategory(i18n(book_general));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("publisher"), i18n("Publisher"));
+ field->setCategory(i18n(book_publishing));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("edition"), i18n("Edition"));
+ field->setCategory(i18n(book_publishing));
+ field->setFlags(Field::AllowCompletion);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("cr_year"), i18n("Copyright Year"), Field::Number);
+ field->setCategory(i18n(book_publishing));
+ field->setFlags(Field::AllowGrouped | Field::AllowMultiple);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pub_year"), i18n("Publication Year"), Field::Number);
+ field->setCategory(i18n(book_publishing));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("isbn"), i18n("ISBN#"));
+ field->setCategory(i18n(book_publishing));
+ field->setDescription(i18n("International Standard Book Number"));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("lccn"), i18n("LCCN#"));
+ field->setCategory(i18n(book_publishing));
+ field->setDescription(i18n("Library of Congress Control Number"));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pages"), i18n("Pages"), Field::Number);
+ field->setCategory(i18n(book_publishing));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("translator"), i18n("Translator"));
+ field->setCategory(i18n(book_publishing));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatName);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("language"), i18n("Language"));
+ field->setCategory(i18n(book_publishing));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped | Field::AllowMultiple);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("genre"), i18n("Genre"));
+ field->setCategory(i18n(book_classification));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ list.append(field);
+
+ // in document versions < 3, this was "keywords" and not "keyword"
+ // but the title didn't change, only the name
+ field = new Field(QString::fromLatin1("keyword"), i18n("Keywords"));
+ field->setCategory(i18n(book_classification));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("series"), i18n("Series"));
+ field->setCategory(i18n(book_classification));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("series_num"), i18n("Series Number"), Field::Number);
+ field->setCategory(i18n(book_classification));
+ list.append(field);
+
+ QStringList cond;
+ cond << i18n("New") << i18n("Used");
+ field = new Field(QString::fromLatin1("condition"), i18n("Condition"), cond);
+ field->setCategory(i18n(book_classification));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("signed"), i18n("Signed"), Field::Bool);
+ field->setCategory(i18n(book_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("read"), i18n("Read"), Field::Bool);
+ field->setCategory(i18n(book_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("gift"), i18n("Gift"), Field::Bool);
+ field->setCategory(i18n(book_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("loaned"), i18n("Loaned"), Field::Bool);
+ field->setCategory(i18n(book_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("rating"), i18n("Rating"), Field::Rating);
+ field->setCategory(i18n(book_personal));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("cover"), i18n("Front Cover"), Field::Image);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("comments"), i18n("Comments"), Field::Para);
+ field->setCategory(i18n(book_personal));
+ list.append(field);
+
+ return list;
+}
+
+int BookCollection::sameEntry(Data::EntryPtr entry1_, Data::EntryPtr entry2_) const {
+ // equal isbn's or lccn's are easy, give it a weight of 100
+ if(Entry::compareValues(entry1_, entry2_, QString::fromLatin1("isbn"), this) > 0 ||
+ Entry::compareValues(entry1_, entry2_, QString::fromLatin1("lccn"), this) > 0) {
+ return 100; // good match
+ }
+ int res = 3*Entry::compareValues(entry1_, entry2_, QString::fromLatin1("title"), this);
+// if(res == 0) {
+// myDebug() << "BookCollection::sameEntry() - different titles for " << entry1_->title() << " vs. "
+// << entry2_->title() << endl;
+// }
+ res += 2*Entry::compareValues(entry1_, entry2_, QString::fromLatin1("author"), this);
+ res += Entry::compareValues(entry1_, entry2_, QString::fromLatin1("cr_year"), this);
+ res += Entry::compareValues(entry1_, entry2_, QString::fromLatin1("pub_year"), this);
+ res += Entry::compareValues(entry1_, entry2_, QString::fromLatin1("binding"), this);
+ return res;
+}
+
+#include "bookcollection.moc"
diff --git a/src/collections/bookcollection.h b/src/collections/bookcollection.h
new file mode 100644
index 0000000..0236dd6
--- /dev/null
+++ b/src/collections/bookcollection.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef BOOKCOLLECTION_H
+#define BOOKCOLLECTION_H
+
+#include "../collection.h"
+
+namespace Tellico {
+ namespace Data {
+
+/**
+ * A collection for books.
+ *
+ * It has the following standard attributes:
+ * @li Title
+ * @li Subtitle
+ * @li Author
+ * @li Binding
+ * @li Purchase Date
+ * @li Purchase Price
+ * @li Publisher
+ * @li Edition
+ * @li Copyright Year
+ * @li Publication Year
+ * @li ISBN Number
+ * @li Library of Congress Catalog Number
+ * @li Pages
+ * @li Language
+ * @li Genre
+ * @li Keywords
+ * @li Series
+ * @li Series Number
+ * @li Condition
+ * @li Signed
+ * @li Read
+ * @li Gift
+ * @li Loaned
+ * @li Rating
+ * @li Comments
+ *
+ * @author Robby Stephenson
+ */
+class BookCollection : public Collection {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor
+ *
+ * @param addFields Whether to add the default attributes
+ * @param title The title of the collection
+ */
+ BookCollection(bool addFields, const QString& title = QString::null);
+
+ virtual Type type() const { return Book; }
+ virtual int sameEntry(Data::EntryPtr entry1, Data::EntryPtr entry2) const;
+
+ static FieldVec defaultFields();
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/collections/cardcollection.cpp b/src/collections/cardcollection.cpp
new file mode 100644
index 0000000..c29ad7f
--- /dev/null
+++ b/src/collections/cardcollection.cpp
@@ -0,0 +1,121 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "cardcollection.h"
+
+#include <klocale.h>
+
+namespace {
+ static const char* card_general = I18N_NOOP("General");
+ static const char* card_personal = I18N_NOOP("Personal");
+}
+
+using Tellico::Data::CardCollection;
+
+CardCollection::CardCollection(bool addFields_, const QString& title_ /*=null*/)
+ : Collection(title_.isEmpty() ? i18n("My Cards") : title_) {
+ if(addFields_) {
+ addFields(defaultFields());
+ }
+ setDefaultGroupField(QString::fromLatin1("series"));
+}
+
+Tellico::Data::FieldVec CardCollection::defaultFields() {
+ FieldVec list;
+ FieldPtr field;
+
+ field = new Field(QString::fromLatin1("title"), i18n("Title"), Field::Dependent);
+ field->setCategory(i18n(card_general));
+ field->setDescription(QString::fromLatin1("%{year} %{brand} %{player}"));
+ field->setFlags(Field::NoDelete);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("player"), i18n("Player"));
+ field->setCategory(i18n(card_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatName);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("team"), i18n("Team"));
+ field->setCategory(i18n(card_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("brand"), i18n("Brand"));
+ field->setCategory(i18n(card_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ // might not be totally numeric!
+ field = new Field(QString::fromLatin1("number"), i18n("Card Number"));
+ field->setCategory(i18n(card_general));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("year"), i18n("Year"), Field::Number);
+ field->setCategory(i18n(card_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("series"), i18n("Series"));
+ field->setCategory(i18n(card_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("type"), i18n("Card Type"));
+ field->setCategory(i18n(card_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_date"), i18n("Purchase Date"));
+ field->setCategory(i18n(card_personal));
+ field->setFormatFlag(Field::FormatDate);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_price"), i18n("Purchase Price"));
+ field->setCategory(i18n(card_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("location"), i18n("Location"));
+ field->setCategory(i18n(card_personal));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("gift"), i18n("Gift"), Field::Bool);
+ field->setCategory(i18n(card_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("keyword"), i18n("Keywords"));
+ field->setCategory(i18n(card_personal));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("quantity"), i18n("Quantity"), Field::Number);
+ field->setCategory(i18n(card_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("front"), i18n("Front Image"), Field::Image);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("back"), i18n("Back Image"), Field::Image);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("comments"), i18n("Comments"), Field::Para);
+ list.append(field);
+
+ return list;
+}
+
+#include "cardcollection.moc"
diff --git a/src/collections/cardcollection.h b/src/collections/cardcollection.h
new file mode 100644
index 0000000..61fd2b0
--- /dev/null
+++ b/src/collections/cardcollection.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef CARDCOLLECTION_H
+#define CARDCOLLECTION_H
+
+#include "../collection.h"
+
+namespace Tellico {
+ namespace Data {
+
+/**
+ * A collection for sports cards.
+ *
+ * It has the following standard attributes:
+ * @li Title
+ *
+ * @author Robby Stephenson
+ */
+class CardCollection : public Collection {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor
+ *
+ * @param addFields A boolean indicating whether the default attributes should be added
+ * @param title The title of the collection
+ */
+ CardCollection(bool addFields, const QString& title = QString::null);
+
+ virtual Type type() const { return Card; }
+
+ static FieldVec defaultFields();
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/collections/coincollection.cpp b/src/collections/coincollection.cpp
new file mode 100644
index 0000000..1cd2ec0
--- /dev/null
+++ b/src/collections/coincollection.cpp
@@ -0,0 +1,135 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "coincollection.h"
+
+#include <klocale.h>
+
+namespace {
+ static const char* coin_general = I18N_NOOP("General");
+ static const char* coin_personal = I18N_NOOP("Personal");
+}
+
+using Tellico::Data::CoinCollection;
+
+CoinCollection::CoinCollection(bool addFields_, const QString& title_ /*=null*/)
+ : Collection(title_.isEmpty() ? i18n("My Coins") : title_) {
+ if(addFields_) {
+ addFields(defaultFields());
+ }
+ setDefaultGroupField(QString::fromLatin1("denomination"));
+}
+
+Tellico::Data::FieldVec CoinCollection::defaultFields() {
+ FieldVec list;
+ FieldPtr field;
+
+ field = new Field(QString::fromLatin1("title"), i18n("Title"), Field::Dependent);
+ field->setCategory(i18n(coin_general));
+ // not i18n()
+ field->setDescription(QString::fromLatin1("%{year}%{mintmark} %{type} %{denomination}"));
+ field->setFlags(Field::NoDelete);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("type"), i18n("Type"));
+ field->setCategory(i18n(coin_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ /* TRANSLATORS: denomination refers to the monetary value. */
+ field = new Field(QString::fromLatin1("denomination"), i18n("Denomination"));
+ field->setCategory(i18n(coin_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("year"), i18n("Year"), Field::Number);
+ field->setCategory(i18n(coin_general));
+ field->setFlags(Field::AllowMultiple | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("mintmark"), i18n("Mint Mark"));
+ field->setCategory(i18n(coin_general));
+ field->setFlags(Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("country"), i18n("Country"));
+ field->setCategory(i18n(coin_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("set"), i18n("Coin Set"), Field::Bool);
+ field->setCategory(i18n(coin_general));
+ list.append(field);
+
+ QStringList grade = QStringList::split(QRegExp(QString::fromLatin1("\\s*,\\s*")),
+ i18n("Coin grade levels - "
+ "Proof-65,Proof-60,Mint State-65,Mint State-60,"
+ "Almost Uncirculated-55,Almost Uncirculated-50,"
+ "Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,"
+ "Very Good-8,Good-4,Fair",
+ "Proof-65,Proof-60,Mint State-65,Mint State-60,"
+ "Almost Uncirculated-55,Almost Uncirculated-50,"
+ "Extremely Fine-40,Very Fine-30,Very Fine-20,Fine-12,"
+ "Very Good-8,Good-4,Fair"),
+ false);
+ field = new Field(QString::fromLatin1("grade"), i18n("Grade"), grade);
+ field->setCategory(i18n(coin_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ QStringList service = QStringList::split(QRegExp(QString::fromLatin1("\\s*,\\s*")),
+ i18n("Coin grading services - "
+ "PCGS,NGC,ANACS,ICG,ASA,PCI",
+ "PCGS,NGC,ANACS,ICG,ASA,PCI"),
+ false);
+ field = new Field(QString::fromLatin1("service"), i18n("Grading Service"), service);
+ field->setCategory(i18n(coin_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_date"), i18n("Purchase Date"));
+ field->setCategory(i18n(coin_personal));
+ field->setFormatFlag(Field::FormatDate);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_price"), i18n("Purchase Price"));
+ field->setCategory(i18n(coin_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("location"), i18n("Location"));
+ field->setCategory(i18n(coin_personal));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("gift"), i18n("Gift"), Field::Bool);
+ field->setCategory(i18n(coin_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("obverse"), i18n("Obverse"), Field::Image);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("reverse"), i18n("Reverse"), Field::Image);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("comments"), i18n("Comments"), Field::Para);
+ field->setCategory(i18n(coin_personal));
+ list.append(field);
+
+ return list;
+}
+
+#include "coincollection.moc"
diff --git a/src/collections/coincollection.h b/src/collections/coincollection.h
new file mode 100644
index 0000000..d22937d
--- /dev/null
+++ b/src/collections/coincollection.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef COINCOLLECTION_H
+#define COINCOLLECTION_H
+
+#include "../collection.h"
+
+namespace Tellico {
+ namespace Data {
+
+/**
+ * A collection for coins.
+ *
+ * It has the following standard attributes:
+ * @li Title
+ *
+ * @author Robby Stephenson
+ */
+class CoinCollection : public Collection {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor
+ *
+ * @param addFields Whether to add the default attributes
+ * @param title The title of the collection
+ */
+ CoinCollection(bool addFields, const QString& title = QString::null);
+
+ virtual Type type() const { return Coin; }
+
+ static FieldVec defaultFields();
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/collections/comicbookcollection.cpp b/src/collections/comicbookcollection.cpp
new file mode 100644
index 0000000..30e1ef0
--- /dev/null
+++ b/src/collections/comicbookcollection.cpp
@@ -0,0 +1,157 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "comicbookcollection.h"
+
+#include <klocale.h>
+
+namespace {
+ static const char* comic_general = I18N_NOOP("General");
+ static const char* comic_publishing = I18N_NOOP("Publishing");
+ static const char* comic_classification = I18N_NOOP("Classification");
+ static const char* comic_personal = I18N_NOOP("Personal");
+}
+
+using Tellico::Data::ComicBookCollection;
+
+ComicBookCollection::ComicBookCollection(bool addFields_, const QString& title_ /*=null*/)
+ : Collection(title_.isEmpty() ? i18n("My Comic Books") : title_) {
+ if(addFields_) {
+ addFields(defaultFields());
+ }
+ setDefaultGroupField(QString::fromLatin1("series"));
+}
+
+Tellico::Data::FieldVec ComicBookCollection::defaultFields() {
+ FieldVec list;
+ FieldPtr field;
+
+ field = new Field(QString::fromLatin1("title"), i18n("Title"));
+ field->setCategory(i18n(comic_general));
+ field->setFlags(Field::NoDelete);
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("subtitle"), i18n("Subtitle"));
+ field->setCategory(i18n(comic_general));
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("writer"), i18n("Writer"));
+ field->setCategory(i18n(comic_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatName);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("artist"), i18n("Comic Book Illustrator", "Artist"));
+ field->setCategory(i18n(comic_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatName);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("series"), i18n("Series"));
+ field->setCategory(i18n(comic_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("issue"), i18n("Issue"), Field::Number);
+ field->setCategory(i18n(comic_general));
+ field->setFlags(Field::AllowMultiple);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("publisher"), i18n("Publisher"));
+ field->setCategory(i18n(comic_publishing));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("edition"), i18n("Edition"));
+ field->setCategory(i18n(comic_publishing));
+ field->setFlags(Field::AllowCompletion);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pub_year"), i18n("Publication Year"), Field::Number);
+ field->setCategory(i18n(comic_publishing));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pages"), i18n("Pages"), Field::Number);
+ field->setCategory(i18n(comic_publishing));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("country"), i18n("Country"));
+ field->setCategory(i18n(comic_publishing));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped | Field::AllowMultiple);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("language"), i18n("Language"));
+ field->setCategory(i18n(comic_publishing));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped | Field::AllowMultiple);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("genre"), i18n("Genre"));
+ field->setCategory(i18n(comic_classification));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("keyword"), i18n("Keywords"));
+ field->setCategory(i18n(comic_classification));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ list.append(field);
+
+ QStringList cond = QStringList::split(QRegExp(QString::fromLatin1("\\s*,\\s*")),
+ i18n("Comic book grade levels - "
+ "Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor",
+ "Mint,Near Mint,Very Fine,Fine,Very Good,Good,Fair,Poor"),
+ false);
+ field = new Field(QString::fromLatin1("condition"), i18n("Condition"), cond);
+ field->setCategory(i18n(comic_classification));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_date"), i18n("Purchase Date"));
+ field->setCategory(i18n(comic_personal));
+ field->setFormatFlag(Field::FormatDate);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_price"), i18n("Purchase Price"));
+ field->setCategory(i18n(comic_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("signed"), i18n("Signed"), Field::Bool);
+ field->setCategory(i18n(comic_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("gift"), i18n("Gift"), Field::Bool);
+ field->setCategory(i18n(comic_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("loaned"), i18n("Loaned"), Field::Bool);
+ field->setCategory(i18n(comic_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("cover"), i18n("Front Cover"), Field::Image);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("comments"), i18n("Comments"), Field::Para);
+ field->setCategory(i18n(comic_personal));
+ list.append(field);
+
+ return list;
+}
+
+#include "comicbookcollection.moc"
diff --git a/src/collections/comicbookcollection.h b/src/collections/comicbookcollection.h
new file mode 100644
index 0000000..36302c2
--- /dev/null
+++ b/src/collections/comicbookcollection.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef COMICBOOKCOLLECTION_H
+#define COMICBOOKCOLLECTION_H
+
+#include "../collection.h"
+
+namespace Tellico {
+ namespace Data {
+
+/**
+ * A collection for comic books.
+ *
+ * It has the following standard attributes:
+ * @li Title
+ *
+ * @author Robby Stephenson
+ */
+class ComicBookCollection : public Collection {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor
+ *
+ * @param title The title of the collection
+ */
+ ComicBookCollection(bool addFields, const QString& title = QString::null);
+
+ virtual Type type() const { return ComicBook; }
+
+ static FieldVec defaultFields();
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/collections/filecatalog.cpp b/src/collections/filecatalog.cpp
new file mode 100644
index 0000000..8d375be
--- /dev/null
+++ b/src/collections/filecatalog.cpp
@@ -0,0 +1,105 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@priapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "filecatalog.h"
+
+#include <klocale.h>
+
+namespace {
+ static const char* file_general = I18N_NOOP("General");
+}
+
+using Tellico::Data::FileCatalog;
+
+FileCatalog::FileCatalog(bool addFields_, const QString& title_ /*=null*/)
+ : Collection(title_.isEmpty() ? i18n("My Files") : title_) {
+ if(addFields_) {
+ addFields(defaultFields());
+ }
+ setDefaultGroupField(QString::fromLatin1("volume"));
+}
+
+Tellico::Data::FieldVec FileCatalog::defaultFields() {
+ FieldVec list;
+ FieldPtr field;
+
+ field = new Field(QString::fromLatin1("title"), i18n("Name"));
+ field->setCategory(i18n(file_general));
+ field->setFlags(Field::NoDelete);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("url"), i18n("URL"), Field::URL);
+ field->setCategory(i18n(file_general));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("description"), i18n("Description"));
+ field->setCategory(i18n(file_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("volume"), i18n("Volume"));
+ field->setCategory(i18n(file_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("folder"), i18n("Folder"));
+ field->setCategory(i18n(file_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("mimetype"), i18n("Mimetype"));
+ field->setCategory(i18n(file_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("size"), i18n("Size"));
+ field->setCategory(i18n(file_general));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("permissions"), i18n("Permissions"));
+ field->setCategory(i18n(file_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("owner"), i18n("Owner"));
+ field->setCategory(i18n(file_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("group"), i18n("Group"));
+ field->setCategory(i18n(file_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ // these dates are string fields, not dates, since the time is included
+ field = new Field(QString::fromLatin1("created"), i18n("Created"));
+ field->setCategory(i18n(file_general));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("modified"), i18n("Modified"));
+ field->setCategory(i18n(file_general));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("metainfo"), i18n("Meta Info"), Field::Table);
+ field->setProperty(QString::fromLatin1("columns"), QChar('2'));
+ field->setProperty(QString::fromLatin1("column1"), i18n("Property"));
+ field->setProperty(QString::fromLatin1("column2"), i18n("Value"));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("icon"), i18n("Icon"), Field::Image);
+ list.append(field);
+
+ return list;
+}
+
+#include "filecatalog.moc"
diff --git a/src/collections/filecatalog.h b/src/collections/filecatalog.h
new file mode 100644
index 0000000..aa7a82c
--- /dev/null
+++ b/src/collections/filecatalog.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_DATA_FILECATALOG_H
+#define TELLICO_DATA_FILECATALOG_H
+
+#include "../collection.h"
+
+namespace Tellico {
+ namespace Data {
+
+/**
+ * @author Robby Stephenson
+ */
+class FileCatalog : public Collection {
+Q_OBJECT
+
+public:
+ FileCatalog(bool addFields, const QString& title = QString::null);
+
+ virtual Type type() const { return File; }
+
+ static FieldVec defaultFields();
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/collections/gamecollection.cpp b/src/collections/gamecollection.cpp
new file mode 100644
index 0000000..b93176f
--- /dev/null
+++ b/src/collections/gamecollection.cpp
@@ -0,0 +1,126 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "gamecollection.h"
+
+#include <klocale.h>
+
+namespace {
+ static const char* game_general = I18N_NOOP("General");
+ static const char* game_personal = I18N_NOOP("Personal");
+}
+
+using Tellico::Data::GameCollection;
+
+GameCollection::GameCollection(bool addFields_, const QString& title_ /*=null*/)
+ : Collection(title_.isEmpty() ? i18n("My Games") : title_) {
+ if(addFields_) {
+ addFields(defaultFields());
+ }
+ setDefaultGroupField(QString::fromLatin1("platform"));
+}
+
+Tellico::Data::FieldVec GameCollection::defaultFields() {
+ FieldVec list;
+ FieldPtr field;
+
+ field = new Field(QString::fromLatin1("title"), i18n("Title"));
+ field->setCategory(i18n(game_general));
+ field->setFlags(Field::NoDelete);
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ QStringList platform;
+ platform << i18n("Xbox 360") << i18n("Xbox")
+ << i18n("PlayStation3") << i18n("PlayStation2") << i18n("PlayStation") << i18n("PlayStation Portable", "PSP")
+ << i18n("Nintendo Wii") << i18n("Nintendo DS") << i18n("GameCube") << i18n("Dreamcast")
+ << i18n("Game Boy Advance") << i18n("Game Boy Color") << i18n("Game Boy")
+ << i18n("Windows Platform", "Windows") << i18n("Mac OS") << i18n("Linux");
+ field = new Field(QString::fromLatin1("platform"), i18n("Platform"), platform);
+ field->setCategory(i18n(game_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("genre"), i18n("Genre"));
+ field->setCategory(i18n(game_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("year"), i18n("Release Year"), Field::Number);
+ field->setCategory(i18n(game_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("publisher"), i18n("Games - Publisher", "Publisher"));
+ field->setCategory(i18n(game_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("developer"), i18n("Developer"));
+ field->setCategory(i18n(game_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ QStringList cert = QStringList::split(QRegExp(QString::fromLatin1("\\s*,\\s*")),
+ i18n("Video game ratings - "
+ "Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending",
+ "Unrated, Adults Only, Mature, Teen, Everyone, Early Childhood, Pending"),
+ false);
+ field = new Field(QString::fromLatin1("certification"), i18n("ESRB Rating"), cert);
+ field->setCategory(i18n(game_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("description"), i18n("Description"), Field::Para);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("rating"), i18n("Personal Rating"), Field::Rating);
+ field->setCategory(i18n(game_personal));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("completed"), i18n("Completed"), Field::Bool);
+ field->setCategory(i18n(game_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_date"), i18n("Purchase Date"));
+ field->setCategory(i18n(game_personal));
+ field->setFormatFlag(Field::FormatDate);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("gift"), i18n("Gift"), Field::Bool);
+ field->setCategory(i18n(game_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_price"), i18n("Purchase Price"));
+ field->setCategory(i18n(game_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("loaned"), i18n("Loaned"), Field::Bool);
+ field->setCategory(i18n(game_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("cover"), i18n("Cover"), Field::Image);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("comments"), i18n("Comments"), Field::Para);
+ field->setCategory(i18n(game_personal));
+ list.append(field);
+
+ return list;
+}
+
+#include "gamecollection.moc"
diff --git a/src/collections/gamecollection.h b/src/collections/gamecollection.h
new file mode 100644
index 0000000..7d6ce92
--- /dev/null
+++ b/src/collections/gamecollection.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef GAMECOLLECTION_H
+#define GAMECOLLECTION_H
+
+#include "../collection.h"
+
+namespace Tellico {
+ namespace Data {
+
+/**
+ * A collection for games.
+ */
+class GameCollection : public Collection {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor
+ *
+ * @param addFields Whether to add the default attributes
+ * @param title The title of the collection
+ */
+ GameCollection(bool addFields, const QString& title = QString::null);
+
+ virtual Type type() const { return Game; }
+
+ static FieldVec defaultFields();
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/collections/musiccollection.cpp b/src/collections/musiccollection.cpp
new file mode 100644
index 0000000..d3c0445
--- /dev/null
+++ b/src/collections/musiccollection.cpp
@@ -0,0 +1,132 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "musiccollection.h"
+
+#include <klocale.h>
+
+namespace {
+ static const char* music_general = I18N_NOOP("General");
+ static const char* music_personal = I18N_NOOP("Personal");
+}
+
+using Tellico::Data::MusicCollection;
+
+MusicCollection::MusicCollection(bool addFields_, const QString& title_ /*=null*/)
+ : Collection(title_.isEmpty() ? i18n("My Music") : title_) {
+ if(addFields_) {
+ addFields(defaultFields());
+ }
+ setDefaultGroupField(QString::fromLatin1("artist"));
+}
+
+Tellico::Data::FieldVec MusicCollection::defaultFields() {
+ FieldVec list;
+ FieldPtr field;
+
+ field = new Field(QString::fromLatin1("title"), i18n("Album"));
+ field->setCategory(i18n(music_general));
+ field->setFlags(Field::NoDelete | Field::AllowCompletion);
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ QStringList media;
+ media << i18n("Compact Disc") << i18n("DVD") << i18n("Cassette") << i18n("Vinyl");
+ field = new Field(QString::fromLatin1("medium"), i18n("Medium"), media);
+ field->setCategory(i18n(music_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("artist"), i18n("Artist"));
+ field->setCategory(i18n(music_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped | Field::AllowMultiple);
+ field->setFormatFlag(Field::FormatTitle); // don't use FormatName
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("label"), i18n("Label"));
+ field->setCategory(i18n(music_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped | Field::AllowMultiple);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("year"), i18n("Year"), Field::Number);
+ field->setCategory(i18n(music_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("genre"), i18n("Genre"));
+ field->setCategory(i18n(music_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("track"), i18n("Tracks"), Field::Table);
+ field->setFormatFlag(Field::FormatTitle);
+ field->setProperty(QString::fromLatin1("columns"), QChar('3'));
+ field->setProperty(QString::fromLatin1("column1"), i18n("Title"));
+ field->setProperty(QString::fromLatin1("column2"), i18n("Artist"));
+ field->setProperty(QString::fromLatin1("column3"), i18n("Length"));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("rating"), i18n("Rating"), Field::Rating);
+ field->setCategory(i18n(music_personal));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_date"), i18n("Purchase Date"));
+ field->setCategory(i18n(music_personal));
+ field->setFormatFlag(Field::FormatDate);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("gift"), i18n("Gift"), Field::Bool);
+ field->setCategory(i18n(music_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_price"), i18n("Purchase Price"));
+ field->setCategory(i18n(music_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("loaned"), i18n("Loaned"), Field::Bool);
+ field->setCategory(i18n(music_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("keyword"), i18n("Keywords"));
+ field->setCategory(i18n(music_personal));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("cover"), i18n("Cover"), Field::Image);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("comments"), i18n("Comments"), Field::Para);
+ field->setCategory(i18n(music_personal));
+ list.append(field);
+
+ return list;
+}
+
+int MusicCollection::sameEntry(Data::EntryPtr entry1_, Data::EntryPtr entry2_) const {
+ // not enough for title to be equal, must also have another field
+ int res = 2*Entry::compareValues(entry1_, entry2_, QString::fromLatin1("title"), this);
+// if(res == 0) {
+// myDebug() << "MusicCollection::sameEntry() - different titles for " << entry1_->title() << " vs. "
+// << entry2_->title() << endl;
+// }
+ res += 2*Entry::compareValues(entry1_, entry2_, QString::fromLatin1("artist"), this);
+ res += Entry::compareValues(entry1_, entry2_, QString::fromLatin1("year"), this);
+ res += Entry::compareValues(entry1_, entry2_, QString::fromLatin1("label"), this);
+ res += Entry::compareValues(entry1_, entry2_, QString::fromLatin1("medium"), this);
+ return res;
+}
+
+#include "musiccollection.moc"
diff --git a/src/collections/musiccollection.h b/src/collections/musiccollection.h
new file mode 100644
index 0000000..ddada5b
--- /dev/null
+++ b/src/collections/musiccollection.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef MUSICCOLLECTION_H
+#define MUSICCOLLECTION_H
+
+#include "../collection.h"
+
+namespace Tellico {
+ namespace Data {
+
+/**
+ * A collection for music, like CD's and cassettes.
+ *
+ * It has the following standard attributes:
+ * @li Title
+ * @li Artist
+ * @li Album
+ * @li Year
+ * @li Genre
+ * @li Comments
+ *
+ * @author Robby Stephenson
+ */
+class MusicCollection : public Collection {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor
+ *
+ * @param addFields Whether to add the default attributes
+ * @param title The title of the collection
+ */
+ MusicCollection(bool addFields, const QString& title = QString::null);
+
+ virtual Type type() const { return Album; }
+ virtual int sameEntry(Data::EntryPtr, Data::EntryPtr) const;
+
+ static FieldVec defaultFields();
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/collections/stampcollection.cpp b/src/collections/stampcollection.cpp
new file mode 100644
index 0000000..c26da9a
--- /dev/null
+++ b/src/collections/stampcollection.cpp
@@ -0,0 +1,133 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "stampcollection.h"
+
+#include <klocale.h>
+
+namespace {
+ static const char* stamp_general = I18N_NOOP("General");
+ static const char* stamp_condition = I18N_NOOP("Condition");
+ static const char* stamp_personal = I18N_NOOP("Personal");
+}
+
+using Tellico::Data::StampCollection;
+
+StampCollection::StampCollection(bool addFields_, const QString& title_ /*=null*/)
+ : Collection(title_.isEmpty() ? i18n("My Stamps") : title_) {
+ if(addFields_) {
+ addFields(defaultFields());
+ }
+ setDefaultGroupField(QString::fromLatin1("denomination"));
+}
+
+Tellico::Data::FieldVec StampCollection::defaultFields() {
+ FieldVec list;
+ FieldPtr field;
+
+ field = new Field(QString::fromLatin1("title"), i18n("Title"), Field::Dependent);
+ field->setCategory(i18n(stamp_general));
+ field->setDescription(QString::fromLatin1("%{year} %{description} %{denomination}"));
+ field->setFlags(Field::NoDelete);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("description"), i18n("Description"));
+ field->setCategory(i18n(stamp_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("denomination"), i18n("Denomination"));
+ field->setCategory(i18n(stamp_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("country"), i18n("Country"));
+ field->setCategory(i18n(stamp_general));
+ field->setFormatFlag(Field::FormatPlain);
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("year"), i18n("Issue Year"), Field::Number);
+ field->setCategory(i18n(stamp_general));
+ field->setFlags(Field::AllowMultiple | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("color"), i18n("Color"));
+ field->setCategory(i18n(stamp_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("scott"), i18n("Scott#"));
+ field->setCategory(i18n(stamp_general));
+ list.append(field);
+
+ QStringList grade = QStringList::split(QRegExp(QString::fromLatin1("\\s*,\\s*")),
+ i18n("Stamp grade levels - "
+ "Superb,Extremely Fine,Very Fine,Fine,Average,Poor",
+ "Superb,Extremely Fine,Very Fine,Fine,Average,Poor"),
+ false);
+ field = new Field(QString::fromLatin1("grade"), i18n("Grade"), grade);
+ field->setCategory(i18n(stamp_condition));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("cancelled"), i18n("Cancelled"), Field::Bool);
+ field->setCategory(i18n(stamp_condition));
+ list.append(field);
+
+ /* TRANSLATORS: See http://en.wikipedia.org/wiki/Stamp_hinge */
+ field = new Field(QString::fromLatin1("hinged"), i18n("Hinged"));
+ field->setCategory(i18n(stamp_condition));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("centering"), i18n("Centering"));
+ field->setCategory(i18n(stamp_condition));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("gummed"), i18n("Gummed"));
+ field->setCategory(i18n(stamp_condition));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_date"), i18n("Purchase Date"));
+ field->setCategory(i18n(stamp_personal));
+ field->setFormatFlag(Field::FormatDate);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_price"), i18n("Purchase Price"));
+ field->setCategory(i18n(stamp_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("location"), i18n("Location"));
+ field->setCategory(i18n(stamp_personal));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("gift"), i18n("Gift"), Field::Bool);
+ field->setCategory(i18n(stamp_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("image"), i18n("Image"), Field::Image);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("comments"), i18n("Comments"), Field::Para);
+ list.append(field);
+
+ return list;
+}
+
+#include "stampcollection.moc"
diff --git a/src/collections/stampcollection.h b/src/collections/stampcollection.h
new file mode 100644
index 0000000..8b81623
--- /dev/null
+++ b/src/collections/stampcollection.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef STAMPCOLLECTION_H
+#define STAMPCOLLECTION_H
+
+#include "../collection.h"
+
+namespace Tellico {
+ namespace Data {
+
+/**
+ * A stamp collection.
+ *
+ * It has the following standard attributes:
+ * @li Title
+ * @li Description
+ * @li Denomination
+ * @li Country
+ * @li Year
+ * @li Color
+ * @li Scott
+ * @li Grade
+ * @li Cancelled
+ * @li Hinged
+ * @li Centering
+ * @li Gummed
+ * @li Pur_date
+ * @li Pur_price
+ * @li Location
+ * @li Gift
+ * @li Image
+ * @li Comments
+ *
+ * @author Robby Stephenson
+ */
+class StampCollection : public Collection {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor
+ *
+ * @param addFields A boolean indicating whether the default attributes should be added
+ * @param title The title of the collection
+ */
+ StampCollection(bool addFields, const QString& title = QString::null);
+
+ virtual Type type() const { return Stamp; }
+
+ static FieldVec defaultFields();
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/collections/videocollection.cpp b/src/collections/videocollection.cpp
new file mode 100644
index 0000000..ad83b5f
--- /dev/null
+++ b/src/collections/videocollection.cpp
@@ -0,0 +1,236 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "videocollection.h"
+
+#include <klocale.h>
+
+namespace {
+ static const char* video_general = I18N_NOOP("General");
+ static const char* video_people = I18N_NOOP("Other People");
+ static const char* video_features = I18N_NOOP("Features");
+ static const char* video_personal = I18N_NOOP("Personal");
+}
+
+using Tellico::Data::VideoCollection;
+
+VideoCollection::VideoCollection(bool addFields_, const QString& title_ /*=null*/)
+ : Collection(title_.isEmpty() ? i18n("My Videos") : title_) {
+ if(addFields_) {
+ addFields(defaultFields());
+ }
+ setDefaultGroupField(QString::fromLatin1("genre"));
+}
+
+Tellico::Data::FieldVec VideoCollection::defaultFields() {
+ FieldVec list;
+ FieldPtr field;
+
+ field = new Field(QString::fromLatin1("title"), i18n("Title"));
+ field->setCategory(i18n("General"));
+ field->setFlags(Field::NoDelete);
+ field->setFormatFlag(Field::FormatTitle);
+ list.append(field);
+
+ QStringList media;
+ media << i18n("DVD") << i18n("VHS") << i18n("VCD") << i18n("DivX") << i18n("Blu-ray") << i18n("HD DVD");
+ field = new Field(QString::fromLatin1("medium"), i18n("Medium"), media);
+ field->setCategory(i18n(video_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("year"), i18n("Production Year"), Field::Number);
+ field->setCategory(i18n(video_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ QStringList cert = QStringList::split(QRegExp(QString::fromLatin1("\\s*,\\s*")),
+ i18n("Movie ratings - "
+ "G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)",
+ "G (USA),PG (USA),PG-13 (USA),R (USA), U (USA)"),
+ false);
+ field = new Field(QString::fromLatin1("certification"), i18n("Certification"), cert);
+ field->setCategory(i18n(video_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("genre"), i18n("Genre"));
+ field->setCategory(i18n(video_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ QStringList region;
+ region << i18n("Region 1")
+ << i18n("Region 2")
+ << i18n("Region 3")
+ << i18n("Region 4")
+ << i18n("Region 5")
+ << i18n("Region 6")
+ << i18n("Region 7")
+ << i18n("Region 8");
+ field = new Field(QString::fromLatin1("region"), i18n("Region"), region);
+ field->setCategory(i18n(video_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("nationality"), i18n("Nationality"));
+ field->setCategory(i18n(video_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ QStringList format;
+ format << i18n("NTSC") << i18n("PAL") << i18n("SECAM");
+ field = new Field(QString::fromLatin1("format"), i18n("Format"), format);
+ field->setCategory(i18n(video_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("cast"), i18n("Cast"), Field::Table);
+ field->setProperty(QString::fromLatin1("columns"), QChar('2'));
+ field->setProperty(QString::fromLatin1("column1"), i18n("Actor/Actress"));
+ field->setProperty(QString::fromLatin1("column2"), i18n("Role"));
+ field->setFormatFlag(Field::FormatName);
+ field->setFlags(Field::AllowGrouped);
+ field->setDescription(i18n("A table for the cast members, along with the roles they play"));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("director"), i18n("Director"));
+ field->setCategory(i18n(video_people));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatName);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("producer"), i18n("Producer"));
+ field->setCategory(i18n(video_people));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatName);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("writer"), i18n("Writer"));
+ field->setCategory(i18n(video_people));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatName);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("composer"), i18n("Composer"));
+ field->setCategory(i18n(video_people));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatName);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("studio"), i18n("Studio"));
+ field->setCategory(i18n(video_people));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("language"), i18n("Language Tracks"));
+ field->setCategory(i18n(video_features));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("subtitle"), i18n("Subtitle Languages"));
+ field->setCategory(i18n(video_features));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("audio-track"), i18n("Audio Tracks"));
+ field->setCategory(i18n(video_features));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("running-time"), i18n("Running Time"), Field::Number);
+ field->setCategory(i18n(video_features));
+ field->setDescription(i18n("The running time of the video (in minutes)"));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("aspect-ratio"), i18n("Aspect Ratio"));
+ field->setCategory(i18n(video_features));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("widescreen"), i18n("Widescreen"), Field::Bool);
+ field->setCategory(i18n(video_features));
+ list.append(field);
+
+ QStringList color;
+ color << i18n("Color") << i18n("Black & White");
+ field = new Field(QString::fromLatin1("color"), i18n("Color Mode"), color);
+ field->setCategory(i18n(video_features));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("directors-cut"), i18n("Director's Cut"), Field::Bool);
+ field->setCategory(i18n(video_features));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("plot"), i18n("Plot Summary"), Field::Para);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("rating"), i18n("Personal Rating"), Field::Rating);
+ field->setCategory(i18n(video_personal));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_date"), i18n("Purchase Date"));
+ field->setCategory(i18n(video_personal));
+ field->setFormatFlag(Field::FormatDate);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("gift"), i18n("Gift"), Field::Bool);
+ field->setCategory(i18n(video_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_price"), i18n("Purchase Price"));
+ field->setCategory(i18n(video_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("loaned"), i18n("Loaned"), Field::Bool);
+ field->setCategory(i18n(video_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("keyword"), i18n("Keywords"));
+ field->setCategory(i18n(video_personal));
+ field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("cover"), i18n("Cover"), Field::Image);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("comments"), i18n("Comments"), Field::Para);
+ list.append(field);
+
+ return list;
+}
+
+int VideoCollection::sameEntry(Data::EntryPtr entry1_, Data::EntryPtr entry2_) const {
+ // not enough for title to be equal, must also have another field
+ // ever possible for a studio to do two movies with identical titles?
+ int res = 3*Entry::compareValues(entry1_, entry2_, QString::fromLatin1("title"), this);
+// if(res == 0) {
+// myDebug() << "VideoCollection::sameEntry() - different titles for " << entry1_->title() << " vs. "
+// << entry2_->title() << endl;
+// }
+ res += Entry::compareValues(entry1_, entry2_, QString::fromLatin1("year"), this);
+ res += Entry::compareValues(entry1_, entry2_, QString::fromLatin1("director"), this);
+ res += Entry::compareValues(entry1_, entry2_, QString::fromLatin1("studio"), this);
+ res += Entry::compareValues(entry1_, entry2_, QString::fromLatin1("medium"), this);
+ return res;
+}
+
+#include "videocollection.moc"
diff --git a/src/collections/videocollection.h b/src/collections/videocollection.h
new file mode 100644
index 0000000..58f729c
--- /dev/null
+++ b/src/collections/videocollection.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef VIDEOCOLLECTION_H
+#define VIDEOCOLLECTION_H
+
+#include "../collection.h"
+
+namespace Tellico {
+ namespace Data {
+
+/**
+ * A collection for videos.
+ *
+ * It has the following standard attributes:
+ * @li Title
+ * @li Year
+ * @li Genre
+ * @li Medium
+ * @li Comments
+ *
+ * @author Robby Stephenson
+ */
+class VideoCollection : public Collection {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor
+ *
+ * @param addFields Whether to add the default attributes
+ * @param title The title of the collection
+ */
+ VideoCollection(bool addFields, const QString& title = QString::null);
+
+ virtual Type type() const { return Video; }
+ virtual int sameEntry(Data::EntryPtr, Data::EntryPtr) const;
+
+ static FieldVec defaultFields();
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/collections/winecollection.cpp b/src/collections/winecollection.cpp
new file mode 100644
index 0000000..31bc5d0
--- /dev/null
+++ b/src/collections/winecollection.cpp
@@ -0,0 +1,120 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "winecollection.h"
+
+#include <klocale.h>
+
+namespace {
+ static const char* wine_general = I18N_NOOP("General");
+ static const char* wine_personal = I18N_NOOP("Personal");
+}
+
+using Tellico::Data::WineCollection;
+
+WineCollection::WineCollection(bool addFields_, const QString& title_ /*=null*/)
+ : Collection(title_.isEmpty() ? i18n("My Wines") : title_) {
+ if(addFields_) {
+ addFields(defaultFields());
+ }
+ setDefaultGroupField(QString::fromLatin1("type"));
+}
+
+Tellico::Data::FieldVec WineCollection::defaultFields() {
+ FieldVec list;
+ FieldPtr field;
+
+ field = new Field(QString::fromLatin1("title"), i18n("Title"), Field::Dependent);
+ field->setCategory(i18n(wine_general));
+ field->setDescription(QString::fromLatin1("%{vintage} %{producer} %{varietal}"));
+ field->setFlags(Field::NoDelete);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("producer"), i18n("Producer"));
+ field->setCategory(i18n(wine_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("appellation"), i18n("Appellation"));
+ field->setCategory(i18n(wine_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("varietal"), i18n("Varietal"));
+ field->setCategory(i18n(wine_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("vintage"), i18n("Vintage"), Field::Number);
+ field->setCategory(i18n(wine_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ QStringList type;
+ type << i18n("Red Wine") << i18n("White Wine") << i18n("Sparkling Wine");
+ field = new Field(QString::fromLatin1("type"), i18n("Type"), type);
+ field->setCategory(i18n(wine_general));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("country"), i18n("Country"));
+ field->setCategory(i18n(wine_general));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ field->setFormatFlag(Field::FormatPlain);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_date"), i18n("Purchase Date"));
+ field->setCategory(i18n(wine_personal));
+ field->setFormatFlag(Field::FormatDate);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("pur_price"), i18n("Purchase Price"));
+ field->setCategory(i18n(wine_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("location"), i18n("Location"));
+ field->setCategory(i18n(wine_personal));
+ field->setFlags(Field::AllowCompletion | Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("quantity"), i18n("Quantity"), Field::Number);
+ field->setCategory(i18n(wine_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("drink-by"), i18n("Drink By"), Field::Number);
+ field->setCategory(i18n(wine_personal));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("rating"), i18n("Rating"), Field::Rating);
+ field->setCategory(i18n(wine_personal));
+ field->setFlags(Field::AllowGrouped);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("gift"), i18n("Gift"), Field::Bool);
+ field->setCategory(i18n(wine_personal));
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("label"), i18n("Label Image"), Field::Image);
+ list.append(field);
+
+ field = new Field(QString::fromLatin1("comments"), i18n("Comments"), Field::Para);
+ list.append(field);
+
+ return list;
+}
+
+#include "winecollection.moc"
diff --git a/src/collections/winecollection.h b/src/collections/winecollection.h
new file mode 100644
index 0000000..236a9cd
--- /dev/null
+++ b/src/collections/winecollection.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef WINECOLLECTION_H
+#define WINECOLLECTION_H
+
+#include "../collection.h"
+
+namespace Tellico {
+ namespace Data {
+
+/**
+ * A wine collection.
+ *
+ * It has the following standard attributes:
+ * @li Title
+ * @li Artist
+ * @li Album
+ * @li Year
+ * @li Genre
+ * @li Comments
+ *
+ * @author Robby Stephenson
+ */
+class WineCollection : public Collection {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor
+ *
+ * @param addFields A boolean indicating whether the default attributes should be added
+ * @param title The title of the collection
+ */
+ WineCollection(bool addFields, const QString& title = QString::null);
+
+ virtual Type type() const { return Wine; }
+
+ static FieldVec defaultFields();
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/commands/Makefile.am b/src/commands/Makefile.am
new file mode 100644
index 0000000..95147c2
--- /dev/null
+++ b/src/commands/Makefile.am
@@ -0,0 +1,29 @@
+AM_CPPFLAGS = $(all_includes)
+
+noinst_LIBRARIES = libcommands.a
+libcommands_a_SOURCES = \
+ addentries.cpp modifyentries.cpp removeentries.cpp \
+ addloans.cpp modifyloans.cpp removeloans.cpp \
+ fieldcommand.cpp filtercommand.cpp reorderfields.cpp \
+ group.cpp collectioncommand.cpp renamecollection.cpp \
+ updateentries.cpp
+
+libcommands_a_METASOURCES = AUTO
+KDE_OPTIONS = noautodist
+EXTRA_DIST = \
+ addentries.h addentries.cpp \
+ modifyentries.h modifyentries.cpp \
+ removeentries.h removeentries.cpp \
+ addloans.h addloans.cpp \
+ modifyloans.h modifyloans.cpp \
+ removeloans.h removeloans.cpp \
+ fieldcommand.h fieldcommand.cpp \
+ filtercommand.h filtercommand.cpp \
+ reorderfields.h reorderfields.cpp \
+ group.h group.cpp \
+ collectioncommand.h collectioncommand.cpp \
+ renamecollection.h renamecollection.cpp \
+ updateentries.h updateentries.cpp
+
+
+CLEANFILES = *~
diff --git a/src/commands/addentries.cpp b/src/commands/addentries.cpp
new file mode 100644
index 0000000..6cd7636
--- /dev/null
+++ b/src/commands/addentries.cpp
@@ -0,0 +1,64 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "addentries.h"
+#include "../collection.h"
+#include "../controller.h"
+#include "../datavectors.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+
+using Tellico::Command::AddEntries;
+
+AddEntries::AddEntries(Data::CollPtr coll_, const Data::EntryVec& entries_)
+ : KCommand()
+ , m_coll(coll_)
+ , m_entries(entries_)
+{
+}
+
+void AddEntries::execute() {
+ if(!m_coll || m_entries.isEmpty()) {
+ return;
+ }
+
+ m_coll->addEntries(m_entries);
+ // now check for default values
+ Data::FieldVec fields = m_coll->fields();
+ for(Data::FieldVec::Iterator field = fields.begin(); field != fields.end(); ++field) {
+ const QString defaultValue = field->defaultValue();
+ if(!defaultValue.isEmpty()) {
+ for(Data::EntryVec::Iterator entry = m_entries.begin(); entry != m_entries.end(); ++entry) {
+ if(entry->field(field).isEmpty()) {
+ entry->setField(field->name(), defaultValue);
+ }
+ }
+ }
+ }
+ Controller::self()->addedEntries(m_entries);
+}
+
+void AddEntries::unexecute() {
+ if(!m_coll || m_entries.isEmpty()) {
+ return;
+ }
+
+ m_coll->removeEntries(m_entries);
+ Controller::self()->removedEntries(m_entries);
+}
+
+QString AddEntries::name() const {
+ return m_entries.count() > 1 ? i18n("Add Entries")
+ : i18n("Add (Entry Title)", "Add %1").arg(m_entries.begin()->title());
+}
diff --git a/src/commands/addentries.h b/src/commands/addentries.h
new file mode 100644
index 0000000..54d8e29
--- /dev/null
+++ b/src/commands/addentries.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_ADDENTRIES_H
+#define TELLICO_ADDENTRIES_H
+
+#include "../datavectors.h"
+
+#include <kcommand.h>
+
+namespace Tellico {
+ namespace Command {
+
+/**
+ * @author Robby Stephenson
+ */
+class AddEntries : public KCommand {
+
+public:
+ AddEntries(Data::CollPtr coll, const Data::EntryVec& entries);
+
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString name() const;
+
+private:
+ Data::CollPtr m_coll;
+ Data::EntryVec m_entries;
+};
+
+ } // end namespace
+}
+
+#endif
diff --git a/src/commands/addloans.cpp b/src/commands/addloans.cpp
new file mode 100644
index 0000000..dab67d7
--- /dev/null
+++ b/src/commands/addloans.cpp
@@ -0,0 +1,110 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "addloans.h"
+#include "../document.h"
+#include "../entry.h"
+#include "../collection.h"
+#include "../controller.h"
+#include "../calendarhandler.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+
+using Tellico::Command::AddLoans;
+
+AddLoans::AddLoans(Data::BorrowerPtr borrower_, Data::LoanVec loans_, bool addToCalendar_)
+ : KCommand()
+ , m_borrower(borrower_)
+ , m_loans(loans_)
+ , m_addedLoanField(false)
+ , m_addToCalendar(addToCalendar_)
+{
+}
+
+void AddLoans::execute() {
+ if(!m_borrower || m_loans.isEmpty()) {
+ return;
+ }
+
+ // if the borrower is empty, assume it's getting added, otherwise it's being modified
+ bool wasEmpty = m_borrower->isEmpty();
+
+ // if there's no loaned field, we'll add one
+ bool loanExisted = m_loans.begin()->entry()->collection()->hasField(QString::fromLatin1("loaned"));
+ m_addedLoanField = false; // assume we didn't add the field yet
+
+ // add the loans to the borrower
+ for(Data::LoanVec::Iterator loan = m_loans.begin(); loan != m_loans.end(); ++loan) {
+ m_borrower->addLoan(loan);
+ Data::Document::self()->checkOutEntry(loan->entry());
+ Data::EntryVec vec;
+ vec.append(loan->entry());
+ Controller::self()->modifiedEntries(vec);
+ }
+ if(!loanExisted) {
+ Data::CollPtr c = m_loans.begin()->entry()->collection();
+ Data::FieldPtr f = c->fieldByName(QString::fromLatin1("loaned"));
+ if(f) {
+ // notify everything that a new field was added
+ Controller::self()->addedField(c, f);
+ m_addedLoanField = true;
+ }
+ }
+ if(m_addToCalendar) {
+ CalendarHandler::addLoans(m_loans);
+ }
+ if(wasEmpty) {
+ m_loans.begin()->entry()->collection()->addBorrower(m_borrower);
+ Controller::self()->addedBorrower(m_borrower);
+ } else {
+ // don't have to do anything to the document, it just holds a pointer
+ myDebug() << "AddLoansCommand::execute() - modifying an existing borrower! " << endl;
+ Controller::self()->modifiedBorrower(m_borrower);
+ }
+}
+
+void AddLoans::unexecute() {
+ if(!m_borrower) {
+ return;
+ }
+
+ // remove the loans from the borrower
+ for(Data::LoanVec::Iterator loan = m_loans.begin(); loan != m_loans.end(); ++loan) {
+ m_borrower->removeLoan(loan);
+ Data::Document::self()->checkInEntry(loan->entry());
+ Data::EntryVec vec;
+ vec.append(loan->entry());
+ Controller::self()->modifiedEntries(vec);
+ }
+ if(m_addedLoanField) {
+ Data::CollPtr c = m_loans.begin()->entry()->collection();
+ Data::FieldPtr f = c->fieldByName(QString::fromLatin1("loaned"));
+ if(f) {
+ c->removeField(f);
+ Controller::self()->removedField(c, f);
+ }
+ }
+ if(m_addToCalendar) {
+ CalendarHandler::removeLoans(m_loans);
+ }
+ // the borrower object is kept in the document, it's just empty
+ // it won't get saved in the document file
+ // here, just notify everybody that it changed
+ Controller::self()->modifiedBorrower(m_borrower);
+}
+
+QString AddLoans::name() const {
+ return m_loans.count() > 1 ? i18n("Check-out Items")
+ : i18n("Check-out (Entry Title)", "Check-out %1").arg(m_loans.begin()->entry()->title());
+}
diff --git a/src/commands/addloans.h b/src/commands/addloans.h
new file mode 100644
index 0000000..b80cbc3
--- /dev/null
+++ b/src/commands/addloans.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_ADDLOANS_H
+#define TELLICO_ADDLOANS_H
+
+#include "../borrower.h"
+#include "../datavectors.h"
+
+#include <kcommand.h>
+
+namespace Tellico {
+ namespace Command {
+
+/**
+ * @author Robby Stephenson
+ */
+class AddLoans : public KCommand {
+
+public:
+ AddLoans(Data::BorrowerPtr borrower, Data::LoanVec loans, bool addToCalendar);
+
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString name() const;
+
+private:
+ Data::BorrowerPtr m_borrower;
+ Data::LoanVec m_loans;
+ bool m_addedLoanField : 1;
+ bool m_addToCalendar : 1;
+};
+
+ } // end namespace
+}
+
+#endif
diff --git a/src/commands/collectioncommand.cpp b/src/commands/collectioncommand.cpp
new file mode 100644
index 0000000..8955ea0
--- /dev/null
+++ b/src/commands/collectioncommand.cpp
@@ -0,0 +1,126 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "collectioncommand.h"
+#include "../collection.h"
+#include "../document.h"
+#include "../controller.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+
+using Tellico::Command::CollectionCommand;
+
+CollectionCommand::CollectionCommand(Mode mode_, Data::CollPtr origColl_, Data::CollPtr newColl_)
+ : KCommand()
+ , m_mode(mode_)
+ , m_origColl(origColl_)
+ , m_newColl(newColl_)
+ , m_cleanup(DoNothing)
+{
+#ifndef NDEBUG
+// just some sanity checking
+ if(m_origColl == 0 || m_newColl == 0) {
+ myDebug() << "CollectionCommand() - null collection pointer" << endl;
+ }
+#endif
+}
+
+CollectionCommand::~CollectionCommand() {
+ switch(m_cleanup) {
+ case ClearOriginal:
+ m_origColl->clear();
+ break;
+ case ClearNew:
+ m_newColl->clear();
+ break;
+ default:
+ break;
+ }
+}
+
+void CollectionCommand::execute() {
+ if(!m_origColl || !m_newColl) {
+ return;
+ }
+
+ switch(m_mode) {
+ case Append:
+ copyFields();
+ Data::Document::self()->appendCollection(m_newColl);
+ Controller::self()->slotCollectionModified(m_origColl);
+ break;
+
+ case Merge:
+ copyFields();
+ m_mergePair = Data::Document::self()->mergeCollection(m_newColl);
+ Controller::self()->slotCollectionModified(m_origColl);
+ break;
+
+ case Replace:
+ // replaceCollection() makes the URL = "Unknown"
+ m_origURL = Data::Document::self()->URL();
+ Data::Document::self()->replaceCollection(m_newColl);
+ Controller::self()->slotCollectionDeleted(m_origColl);
+ Controller::self()->slotCollectionAdded(m_newColl);
+ m_cleanup = ClearOriginal;
+ break;
+ }
+}
+
+void CollectionCommand::unexecute() {
+ if(!m_origColl || !m_newColl) {
+ return;
+ }
+
+ switch(m_mode) {
+ case Append:
+ Data::Document::self()->unAppendCollection(m_newColl, m_origFields);
+ Controller::self()->slotCollectionModified(m_origColl);
+ break;
+
+ case Merge:
+ Data::Document::self()->unMergeCollection(m_newColl, m_origFields, m_mergePair);
+ Controller::self()->slotCollectionModified(m_origColl);
+ break;
+
+ case Replace:
+ Data::Document::self()->replaceCollection(m_origColl);
+ Data::Document::self()->setURL(m_origURL);
+ Controller::self()->slotCollectionDeleted(m_newColl);
+ Controller::self()->slotCollectionAdded(m_origColl);
+ m_cleanup = ClearNew;
+ break;
+ }
+}
+
+QString CollectionCommand::name() const {
+ switch(m_mode) {
+ case Append:
+ return i18n("Append Collection");
+ case Merge:
+ return i18n("Merge Collection");
+ case Replace:
+ return i18n("Replace Collection");
+ }
+ // hush warnings
+ return QString::null;
+}
+
+void CollectionCommand::copyFields() {
+ m_origFields.clear();
+ Data::FieldVec fieldsToCopy = m_origColl->fields();
+ for(Data::FieldVec::Iterator field = fieldsToCopy.begin(); field != fieldsToCopy.end(); ++field) {
+ m_origFields.append(new Data::Field(*field));
+ }
+}
diff --git a/src/commands/collectioncommand.h b/src/commands/collectioncommand.h
new file mode 100644
index 0000000..ad0b2f4
--- /dev/null
+++ b/src/commands/collectioncommand.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_COLLECTIONCOMMAND_H
+#define TELLICO_COLLECTIONCOMMAND_H
+
+#include "../datavectors.h"
+
+#include <kcommand.h>
+#include <kurl.h>
+
+namespace Tellico {
+ namespace Command {
+
+/**
+ * @author Robby Stephenson
+ */
+class CollectionCommand : public KCommand {
+public:
+ enum Mode {
+ Append,
+ Merge,
+ Replace
+ };
+
+ CollectionCommand(Mode mode, Data::CollPtr currentColl, Data::CollPtr newColl);
+ ~CollectionCommand();
+
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString name() const;
+
+private:
+ void copyFields();
+
+ Mode m_mode;
+ Data::CollPtr m_origColl;
+ Data::CollPtr m_newColl;
+
+ KURL m_origURL;
+ Data::FieldVec m_origFields;
+ Data::MergePair m_mergePair;
+ // for the Replace case, the collection that got replaced needs to be cleared
+ enum CleanupMode {
+ DoNothing, ClearOriginal, ClearNew
+ };
+ CleanupMode m_cleanup;
+};
+
+ } // end namespace
+}
+
+#endif
diff --git a/src/commands/fieldcommand.cpp b/src/commands/fieldcommand.cpp
new file mode 100644
index 0000000..6902e15
--- /dev/null
+++ b/src/commands/fieldcommand.cpp
@@ -0,0 +1,112 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "fieldcommand.h"
+#include "../collection.h"
+#include "../controller.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+
+using Tellico::Command::FieldCommand;
+
+FieldCommand::FieldCommand(Mode mode_, Data::CollPtr coll_,
+ Data::FieldPtr activeField_, Data::FieldPtr oldField_/*=0*/)
+ : KCommand()
+ , m_mode(mode_)
+ , m_coll(coll_)
+ , m_activeField(activeField_)
+ , m_oldField(oldField_)
+{
+ if(!m_coll) {
+ myDebug() << "FieldCommand() - null collection pointer" << endl;
+ } else if(!m_activeField) {
+ myDebug() << "FieldCommand() - null active field pointer" << endl;
+ }
+#ifndef NDEBUG
+// just some sanity checking
+ if(m_mode == FieldAdd && m_oldField != 0) {
+ myDebug() << "FieldCommand() - adding field, but pointers are wrong" << endl;
+ } else if(m_mode == FieldModify && m_oldField == 0) {
+ myDebug() << "FieldCommand() - modifying field, but pointers are wrong" << endl;
+ } else if(m_mode == FieldRemove && m_oldField != 0) {
+ myDebug() << "FieldCommand() - removing field, but pointers are wrong" << endl;
+ }
+#endif
+}
+
+void FieldCommand::execute() {
+ if(!m_coll || !m_activeField) {
+ return;
+ }
+
+ switch(m_mode) {
+ case FieldAdd:
+ // if there's currently a field in the collection with the same name, it will get overwritten
+ // so save a pointer to it here, the collection should not delete it
+ m_oldField = m_coll->fieldByName(m_activeField->name());
+ m_coll->addField(m_activeField);
+ Controller::self()->addedField(m_coll, m_activeField);
+ break;
+
+ case FieldModify:
+ m_coll->modifyField(m_activeField);
+ Controller::self()->modifiedField(m_coll, m_oldField, m_activeField);
+ break;
+
+ case FieldRemove:
+ m_coll->removeField(m_activeField);
+ Controller::self()->removedField(m_coll, m_activeField);
+ break;
+ }
+}
+
+void FieldCommand::unexecute() {
+ if(!m_coll || !m_activeField) {
+ return;
+ }
+
+ switch(m_mode) {
+ case FieldAdd:
+ m_coll->removeField(m_activeField);
+ Controller::self()->removedField(m_coll, m_activeField);
+ if(m_oldField) {
+ m_coll->addField(m_oldField);
+ Controller::self()->addedField(m_coll, m_oldField);
+ }
+ break;
+
+ case FieldModify:
+ m_coll->modifyField(m_oldField);
+ Controller::self()->modifiedField(m_coll, m_activeField, m_oldField);
+ break;
+
+ case FieldRemove:
+ m_coll->addField(m_activeField);
+ Controller::self()->addedField(m_coll, m_activeField);
+ break;
+ }
+}
+
+QString FieldCommand::name() const {
+ switch(m_mode) {
+ case FieldAdd:
+ return i18n("Add %1 Field").arg(m_activeField->title());
+ case FieldModify:
+ return i18n("Modify %1 Field").arg(m_activeField->title());
+ case FieldRemove:
+ return i18n("Delete %1 Field").arg(m_activeField->title());
+ }
+ // hush warnings
+ return QString::null;
+}
diff --git a/src/commands/fieldcommand.h b/src/commands/fieldcommand.h
new file mode 100644
index 0000000..0e5706f
--- /dev/null
+++ b/src/commands/fieldcommand.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FIELDCOMMAND_H
+#define TELLICO_FIELDCOMMAND_H
+
+#include "../datavectors.h"
+
+#include <kcommand.h>
+
+namespace Tellico {
+ namespace Command {
+
+/**
+ * @author Robby Stephenson
+ */
+class FieldCommand : public KCommand {
+
+public:
+ enum Mode {
+ FieldAdd,
+ FieldModify,
+ FieldRemove
+ };
+
+ FieldCommand(Mode mode, Data::CollPtr coll, Data::FieldPtr activeField, Data::FieldPtr oldField=0);
+
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString name() const;
+
+private:
+ Mode m_mode;
+ Data::CollPtr m_coll;
+ Data::FieldPtr m_activeField;
+ Data::FieldPtr m_oldField;
+};
+
+ } // end namespace
+}
+
+#endif
diff --git a/src/commands/filtercommand.cpp b/src/commands/filtercommand.cpp
new file mode 100644
index 0000000..ba205e5
--- /dev/null
+++ b/src/commands/filtercommand.cpp
@@ -0,0 +1,106 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "filtercommand.h"
+#include "../document.h"
+#include "../collection.h"
+#include "../controller.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+
+using Tellico::Command::FilterCommand;
+
+FilterCommand::FilterCommand(Mode mode_, FilterPtr activeFilter_, FilterPtr oldFilter_/*=0*/)
+ : KCommand()
+ , m_mode(mode_)
+ , m_activeFilter(activeFilter_)
+ , m_oldFilter(oldFilter_)
+{
+ if(!m_activeFilter) {
+ myDebug() << "FilterCommand() - null active filter pointer" << endl;
+ }
+#ifndef NDEBUG
+// just some sanity checking
+ if(m_mode == FilterAdd && m_oldFilter != 0) {
+ myDebug() << "FilterCommand() - adding field, but pointers are wrong" << endl;
+ } else if(m_mode == FilterModify && m_oldFilter == 0) {
+ myDebug() << "FilterCommand() - modifying field, but pointers are wrong" << endl;
+ } else if(m_mode == FilterRemove && m_oldFilter != 0) {
+ myDebug() << "FilterCommand() - removing field, but pointers are wrong" << endl;
+ }
+#endif
+}
+
+void FilterCommand::execute() {
+ if(!m_activeFilter) {
+ return;
+ }
+
+ switch(m_mode) {
+ case FilterAdd:
+ Data::Document::self()->collection()->addFilter(m_activeFilter);
+ Controller::self()->addedFilter(m_activeFilter);
+ break;
+
+ case FilterModify:
+ Data::Document::self()->collection()->removeFilter(m_oldFilter);
+ Controller::self()->removedFilter(m_oldFilter);
+ Data::Document::self()->collection()->addFilter(m_activeFilter);
+ Controller::self()->addedFilter(m_activeFilter);
+ break;
+
+ case FilterRemove:
+ Data::Document::self()->collection()->removeFilter(m_activeFilter);
+ Controller::self()->removedFilter(m_activeFilter);
+ break;
+ }
+}
+
+void FilterCommand::unexecute() {
+ if(!m_activeFilter) {
+ return;
+ }
+
+ switch(m_mode) {
+ case FilterAdd:
+ Data::Document::self()->collection()->removeFilter(m_activeFilter);
+ Controller::self()->removedFilter(m_activeFilter);
+ break;
+
+ case FilterModify:
+ Data::Document::self()->collection()->removeFilter(m_activeFilter);
+ Controller::self()->removedFilter(m_activeFilter);
+ Data::Document::self()->collection()->addFilter(m_oldFilter);
+ Controller::self()->addedFilter(m_oldFilter);
+ break;
+
+ case FilterRemove:
+ Data::Document::self()->collection()->addFilter(m_activeFilter);
+ Controller::self()->addedFilter(m_activeFilter);
+ break;
+ }
+}
+
+QString FilterCommand::name() const {
+ switch(m_mode) {
+ case FilterAdd:
+ return i18n("Add Filter");
+ case FilterModify:
+ return i18n("Modify Filter");
+ case FilterRemove:
+ return i18n("Delete Filter");
+ }
+ // hush warnings
+ return QString::null;
+}
diff --git a/src/commands/filtercommand.h b/src/commands/filtercommand.h
new file mode 100644
index 0000000..93aa629
--- /dev/null
+++ b/src/commands/filtercommand.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FILTERCOMMAND_H
+#define TELLICO_FILTERCOMMAND_H
+
+#include "../datavectors.h"
+
+#include <kcommand.h>
+
+namespace Tellico {
+ namespace Command {
+
+/**
+ * @author Robby Stephenson
+ */
+class FilterCommand : public KCommand {
+
+public:
+ enum Mode {
+ FilterAdd,
+ FilterModify,
+ FilterRemove
+ };
+
+ FilterCommand(Mode mode, FilterPtr activeFilter, FilterPtr oldFilter=0);
+
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString name() const;
+
+private:
+ Mode m_mode;
+ FilterPtr m_activeFilter;
+ FilterPtr m_oldFilter;
+};
+
+ } // end namespace
+}
+
+#endif
diff --git a/src/commands/group.cpp b/src/commands/group.cpp
new file mode 100644
index 0000000..fd9cd76
--- /dev/null
+++ b/src/commands/group.cpp
@@ -0,0 +1,23 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "group.h"
+
+using Tellico::Command::Group;
+
+QString Group::name() const {
+ if(m_commands.count() == 1) {
+ return m_commands.getFirst()->name();
+ }
+ return KMacroCommand::name();
+}
diff --git a/src/commands/group.h b/src/commands/group.h
new file mode 100644
index 0000000..dc87bf9
--- /dev/null
+++ b/src/commands/group.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_COMMAND_GROUP_H
+#define TELLICO_COMMAND_GROUP_H
+
+#include <kcommand.h>
+
+namespace Tellico {
+ namespace Command {
+
+/**
+ * @author Robby Stephenson
+ */
+class Group : public KMacroCommand {
+
+public:
+ Group(const QString& name) : KMacroCommand(name) {}
+
+ virtual QString name() const;
+
+ bool isEmpty() const { return m_commands.count() == 0; }
+};
+
+ } // end namespace
+}
+
+#endif
diff --git a/src/commands/modifyentries.cpp b/src/commands/modifyentries.cpp
new file mode 100644
index 0000000..895348e
--- /dev/null
+++ b/src/commands/modifyentries.cpp
@@ -0,0 +1,88 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "modifyentries.h"
+#include "../collection.h"
+#include "../controller.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+
+using Tellico::Command::ModifyEntries;
+
+ModifyEntries::ModifyEntries(Data::CollPtr coll_, const Data::EntryVec& oldEntries_, const Data::EntryVec& newEntries_)
+ : KCommand()
+ , m_coll(coll_)
+ , m_oldEntries(oldEntries_)
+ , m_entries(newEntries_)
+ , m_needToSwap(false)
+{
+#ifndef NDEBUG
+ if(m_oldEntries.count() != m_entries.count()) {
+ kdWarning() << "ModifyEntriesCommand() - unequal number of entries" << endl;
+ }
+#endif
+}
+
+void ModifyEntries::execute() {
+ if(!m_coll || m_entries.isEmpty()) {
+ return;
+ }
+ if(m_needToSwap) {
+ swapValues();
+ m_needToSwap = false;
+ }
+ // loans expose a field named "loaned", and the user might modify that without
+ // checking in the loan, so verify that. Heavy-handed, yes...
+ const QString loaned = QString::fromLatin1("loaned");
+ bool hasLoanField = m_coll->hasField(loaned);
+ for(Data::EntryVecIt entry = m_entries.begin(); hasLoanField && entry != m_entries.end(); ++entry) {
+ if(entry->field(loaned).isEmpty()) {
+ Data::EntryVec notLoaned;
+ notLoaned.append(entry);
+ Controller::self()->slotCheckIn(notLoaned);
+ }
+ }
+ m_coll->updateDicts(m_entries);
+ Controller::self()->modifiedEntries(m_entries);
+}
+
+void ModifyEntries::unexecute() {
+ if(!m_coll || m_entries.isEmpty()) {
+ return;
+ }
+ swapValues();
+ m_needToSwap = true;
+ m_coll->updateDicts(m_entries);
+ Controller::self()->modifiedEntries(m_entries);
+ //TODO: need to tell edit dialog that it's not modified
+}
+
+QString ModifyEntries::name() const {
+ return m_entries.count() > 1 ? i18n("Modify Entries")
+ : i18n("Modify (Entry Title)", "Modify %1").arg(m_entries.begin()->title());
+}
+
+void ModifyEntries::swapValues() {
+ // since things like the detailedlistview and the entryiconview hold pointers to the entries
+ // can't just call Controller::modifiedEntry() on the old pointers
+ for(size_t i = 0; i < m_entries.count(); ++i) {
+ // need to swap entry values, not just pointers
+ // the id gets reset when copying, so need to keep it
+ long id = m_entries.at(i)->id();
+ Data::Entry tmp(*m_entries.at(i)); // tmp id becomes -1
+ *m_entries.at(i) = *m_oldEntries.at(i); // id becomes -1
+ m_entries.at(i)->setId(id); // id becomes what was originally
+ *m_oldEntries.at(i) = tmp; // id becomes -1
+ }
+}
diff --git a/src/commands/modifyentries.h b/src/commands/modifyentries.h
new file mode 100644
index 0000000..4dfbda1
--- /dev/null
+++ b/src/commands/modifyentries.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_MODIFYENTRIES_H
+#define TELLICO_MODIFYENTRIES_H
+
+#include "../datavectors.h"
+
+#include <kcommand.h>
+
+namespace Tellico {
+ namespace Command {
+
+/**
+ * @author Robby Stephenson
+ */
+class ModifyEntries : public KCommand {
+
+public:
+ ModifyEntries(Data::CollPtr coll, const Data::EntryVec& oldEntries, const Data::EntryVec& newEntries);
+
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString name() const;
+
+private:
+ void swapValues();
+
+ Data::CollPtr m_coll;
+ Data::EntryVec m_oldEntries;
+ Data::EntryVec m_entries;
+ bool m_needToSwap : 1;
+};
+
+ } // end namespace
+}
+
+#endif
diff --git a/src/commands/modifyloans.cpp b/src/commands/modifyloans.cpp
new file mode 100644
index 0000000..f8976e4
--- /dev/null
+++ b/src/commands/modifyloans.cpp
@@ -0,0 +1,76 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "modifyloans.h"
+#include "../document.h"
+#include "../entry.h"
+#include "../controller.h"
+#include "../calendarhandler.h"
+
+#include <klocale.h>
+
+using Tellico::Command::ModifyLoans;
+
+ModifyLoans::ModifyLoans(Data::LoanPtr oldLoan_, Data::LoanPtr newLoan_, bool addToCalendar_)
+ : KCommand()
+ , m_oldLoan(oldLoan_)
+ , m_newLoan(newLoan_)
+ , m_addToCalendar(addToCalendar_)
+{
+}
+
+void ModifyLoans::execute() {
+ if(!m_oldLoan || !m_newLoan) {
+ return;
+ }
+
+ Data::BorrowerPtr b = m_oldLoan->borrower();
+ b->removeLoan(m_oldLoan);
+ b->addLoan(m_newLoan);
+ Controller::self()->modifiedBorrower(b);
+
+ if(m_addToCalendar && !m_oldLoan->inCalendar()) {
+ Data::LoanVec loans;
+ loans.append(m_newLoan);
+ CalendarHandler::addLoans(loans);
+ } else if(!m_addToCalendar && m_oldLoan->inCalendar()) {
+ Data::LoanVec loans;
+ loans.append(m_newLoan); // CalendarHandler checks via uid
+ CalendarHandler::removeLoans(loans);
+ }
+}
+
+void ModifyLoans::unexecute() {
+ if(!m_oldLoan || !m_newLoan) {
+ return;
+ }
+
+ Data::BorrowerPtr b = m_oldLoan->borrower();
+ b->removeLoan(m_newLoan);
+ b->addLoan(m_oldLoan);
+ Controller::self()->modifiedBorrower(b);
+
+ if(m_addToCalendar && !m_oldLoan->inCalendar()) {
+ Data::LoanVec loans;
+ loans.append(m_newLoan);
+ CalendarHandler::removeLoans(loans);
+ } else if(!m_addToCalendar && m_oldLoan->inCalendar()) {
+ Data::LoanVec loans;
+ loans.append(m_oldLoan);
+ CalendarHandler::addLoans(loans);
+ }
+}
+
+QString ModifyLoans::name() const {
+ return i18n("Modify Loan");
+}
diff --git a/src/commands/modifyloans.h b/src/commands/modifyloans.h
new file mode 100644
index 0000000..6f531ce
--- /dev/null
+++ b/src/commands/modifyloans.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_MODIFYLOANS_H
+#define TELLICO_MODIFYLOANS_H
+
+#include "../borrower.h"
+
+#include <kcommand.h>
+
+namespace Tellico {
+ namespace Command {
+
+/**
+ * @author Robby Stephenson
+ */
+class ModifyLoans : public KCommand {
+
+public:
+ ModifyLoans(Data::LoanPtr oldLoan, Data::LoanPtr newLoan, bool addToCalendar);
+
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString name() const;
+
+private:
+ Data::LoanPtr m_oldLoan;
+ Data::LoanPtr m_newLoan;
+ bool m_addToCalendar : 1;
+};
+
+ } // end namespace
+}
+
+#endif
diff --git a/src/commands/removeentries.cpp b/src/commands/removeentries.cpp
new file mode 100644
index 0000000..8d77fb6
--- /dev/null
+++ b/src/commands/removeentries.cpp
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "removeentries.h"
+#include "../collection.h"
+#include "../controller.h"
+
+#include <klocale.h>
+
+using Tellico::Command::RemoveEntries;
+
+RemoveEntries::RemoveEntries(Data::CollPtr coll_, const Data::EntryVec& entries_)
+ : KCommand()
+ , m_coll(coll_)
+ , m_entries(entries_)
+{
+}
+
+void RemoveEntries::execute() {
+ if(!m_coll || m_entries.isEmpty()) {
+ return;
+ }
+
+ m_coll->removeEntries(m_entries);
+ Controller::self()->removedEntries(m_entries);
+}
+
+void RemoveEntries::unexecute() {
+ if(!m_coll || m_entries.isEmpty()) {
+ return;
+ }
+
+ m_coll->addEntries(m_entries);
+ Controller::self()->addedEntries(m_entries);
+}
+
+QString RemoveEntries::name() const {
+ return m_entries.count() > 1 ? i18n("Delete Entries")
+ : i18n("Delete (Entry Title)", "Delete %1").arg(m_entries.begin()->title());
+}
diff --git a/src/commands/removeentries.h b/src/commands/removeentries.h
new file mode 100644
index 0000000..71c5ed4
--- /dev/null
+++ b/src/commands/removeentries.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_REMOVEENTRIES_H
+#define TELLICO_REMOVEENTRIES_H
+
+#include "../datavectors.h"
+
+#include <kcommand.h>
+
+namespace Tellico {
+ namespace Command {
+
+/**
+ * @author Robby Stephenson
+ */
+class RemoveEntries : public KCommand {
+
+public:
+ RemoveEntries(Data::CollPtr coll, const Data::EntryVec& entries);
+
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString name() const;
+
+private:
+ Data::CollPtr m_coll;
+ Data::EntryVec m_entries;
+};
+
+ } // end namespace
+}
+
+#endif
diff --git a/src/commands/removeloans.cpp b/src/commands/removeloans.cpp
new file mode 100644
index 0000000..5ceadc9
--- /dev/null
+++ b/src/commands/removeloans.cpp
@@ -0,0 +1,81 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "removeloans.h"
+#include "../document.h"
+#include "../entry.h"
+#include "../controller.h"
+#include "../calendarhandler.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+
+using Tellico::Command::RemoveLoans;
+
+RemoveLoans::RemoveLoans(Data::LoanVec loans_)
+ : KCommand()
+ , m_loans(loans_)
+{
+}
+
+void RemoveLoans::execute() {
+ if(m_loans.isEmpty()) {
+ return;
+ }
+
+ // not all of the loans might be in the calendar
+ Data::LoanVec calLoans;
+ // remove the loans from the borrowers
+ for(Data::LoanVec::Iterator loan = m_loans.begin(); loan != m_loans.end(); ++loan) {
+ if(loan->inCalendar()) {
+ calLoans.append(loan);
+ }
+ loan->borrower()->removeLoan(loan);
+ Data::Document::self()->checkInEntry(loan->entry());
+ Data::EntryVec vec;
+ vec.append(loan->entry());
+ Controller::self()->modifiedEntries(vec);
+ Controller::self()->modifiedBorrower(loan->borrower());
+ }
+ if(!calLoans.isEmpty()) {
+ CalendarHandler::removeLoans(calLoans);
+ }
+}
+
+void RemoveLoans::unexecute() {
+ if(m_loans.isEmpty()) {
+ return;
+ }
+
+ // not all of the loans might be in the calendar
+ Data::LoanVec calLoans;
+ for(Data::LoanVec::Iterator loan = m_loans.begin(); loan != m_loans.end(); ++loan) {
+ if(loan->inCalendar()) {
+ calLoans.append(loan);
+ }
+ loan->borrower()->addLoan(loan);
+ Data::Document::self()->checkOutEntry(loan->entry());
+ Data::EntryVec vec;
+ vec.append(loan->entry());
+ Controller::self()->modifiedEntries(vec);
+ Controller::self()->modifiedBorrower(loan->borrower());
+ }
+ if(!calLoans.isEmpty()) {
+ CalendarHandler::addLoans(calLoans);
+ }
+}
+
+QString RemoveLoans::name() const {
+ return m_loans.count() > 1 ? i18n("Check-in Entries")
+ : i18n("Check-in (Entry Title)", "Check-in %1").arg(m_loans.begin()->entry()->title());
+}
diff --git a/src/commands/removeloans.h b/src/commands/removeloans.h
new file mode 100644
index 0000000..5b578b7
--- /dev/null
+++ b/src/commands/removeloans.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_REMOVELOANS_H
+#define TELLICO_REMOVELOANS_H
+
+#include "../borrower.h"
+
+#include <kcommand.h>
+
+namespace Tellico {
+ namespace Command {
+
+/**
+ * @author Robby Stephenson
+ */
+class RemoveLoans : public KCommand {
+
+public:
+ RemoveLoans(Data::LoanVec loans);
+
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString name() const;
+
+private:
+ Data::LoanVec m_loans;
+};
+
+ } // end namespace
+}
+
+#endif
diff --git a/src/commands/renamecollection.cpp b/src/commands/renamecollection.cpp
new file mode 100644
index 0000000..b2fcc39
--- /dev/null
+++ b/src/commands/renamecollection.cpp
@@ -0,0 +1,46 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "renamecollection.h"
+#include "../document.h"
+#include "../collection.h"
+
+#include <klocale.h>
+
+using Tellico::Command::RenameCollection;
+
+RenameCollection::RenameCollection(Data::CollPtr coll_, const QString& newTitle_)
+ : KCommand()
+ , m_coll(coll_)
+ , m_newTitle(newTitle_)
+{
+}
+
+void RenameCollection::execute() {
+ if(!m_coll) {
+ return;
+ }
+ m_oldTitle = m_coll->title();
+ Data::Document::self()->renameCollection(m_newTitle);
+}
+
+void RenameCollection::unexecute() {
+ if(!m_coll) {
+ return;
+ }
+ Data::Document::self()->renameCollection(m_oldTitle);
+}
+
+QString RenameCollection::name() const {
+ return i18n("Rename Collection");
+}
diff --git a/src/commands/renamecollection.h b/src/commands/renamecollection.h
new file mode 100644
index 0000000..bdbb64c
--- /dev/null
+++ b/src/commands/renamecollection.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_RENAMECOLLECTION_H
+#define TELLICO_RENAMECOLLECTION_H
+
+#include "../datavectors.h"
+
+#include <kcommand.h>
+
+namespace Tellico {
+ namespace Command {
+
+/**
+@author Robby Stephenson
+*/
+class RenameCollection : public KCommand {
+public:
+ RenameCollection(Data::CollPtr coll, const QString& newTitle);
+
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString name() const;
+
+private:
+ Data::CollPtr m_coll;
+ QString m_oldTitle;
+ QString m_newTitle;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/commands/reorderfields.cpp b/src/commands/reorderfields.cpp
new file mode 100644
index 0000000..0c9f7fe
--- /dev/null
+++ b/src/commands/reorderfields.cpp
@@ -0,0 +1,55 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "reorderfields.h"
+#include "../collection.h"
+#include "../controller.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+
+using Tellico::Command::ReorderFields;
+
+ReorderFields::ReorderFields(Data::CollPtr coll_, const Data::FieldVec& oldFields_,
+ const Data::FieldVec& newFields_)
+ : KCommand()
+ , m_coll(coll_)
+ , m_oldFields(oldFields_)
+ , m_newFields(newFields_)
+{
+ if(!m_coll) {
+ myDebug() << "ReorderFieldsCommand() - null collection pointer" << endl;
+ } else if(m_oldFields.count() != m_newFields.count()) {
+ myDebug() << "ReorderFieldsCommand() - unequal number of fields" << endl;
+ }
+}
+
+void ReorderFields::execute() {
+ if(!m_coll) {
+ return;
+ }
+ m_coll->reorderFields(m_newFields);
+ Controller::self()->reorderedFields(m_coll);
+}
+
+void ReorderFields::unexecute() {
+ if(!m_coll) {
+ return;
+ }
+ m_coll->reorderFields(m_oldFields);
+ Controller::self()->reorderedFields(m_coll);
+}
+
+QString ReorderFields::name() const {
+ return i18n("Reorder Fields");
+}
diff --git a/src/commands/reorderfields.h b/src/commands/reorderfields.h
new file mode 100644
index 0000000..6a59050
--- /dev/null
+++ b/src/commands/reorderfields.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_REORDERFIELDS_H
+#define TELLICO_REORDERFIELDS_H
+
+#include "../datavectors.h"
+
+#include <kcommand.h>
+
+namespace Tellico {
+ namespace Command {
+
+/**
+ * @author Robby Stephenson
+ */
+class ReorderFields : public KCommand {
+
+public:
+ ReorderFields(Data::CollPtr coll, const Data::FieldVec& oldFields, const Data::FieldVec& newFields);
+
+ virtual void execute();
+ virtual void unexecute();
+ virtual QString name() const;
+
+private:
+ Data::CollPtr m_coll;
+ Data::FieldVec m_oldFields;
+ Data::FieldVec m_newFields;
+};
+
+ } // end namespace
+}
+
+#endif
diff --git a/src/commands/updateentries.cpp b/src/commands/updateentries.cpp
new file mode 100644
index 0000000..cb2f850
--- /dev/null
+++ b/src/commands/updateentries.cpp
@@ -0,0 +1,94 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "updateentries.h"
+#include "fieldcommand.h"
+#include "modifyentries.h"
+#include "../collection.h"
+#include "../tellico_kernel.h"
+#include "../document.h"
+
+#include <klocale.h>
+
+using Tellico::Command::UpdateEntries;
+
+namespace Tellico {
+ namespace Command {
+
+class MergeEntries : public KCommand {
+public:
+ MergeEntries(Data::EntryPtr currEntry_, Data::EntryPtr newEntry_, bool overWrite_) : KCommand()
+ , m_oldEntry(new Data::Entry(*currEntry_)) {
+ // we merge the entries here instead of in execute() because this
+ // command is never called without also calling ModifyEntries()
+ // which takes care of copying the entry values
+ Data::Collection::mergeEntry(currEntry_, newEntry_, overWrite_);
+ }
+
+ virtual void execute() {} // does nothing
+ virtual void unexecute() {} // does nothing
+ virtual QString name() const { return QString(); }
+ Data::EntryPtr oldEntry() const { return m_oldEntry; }
+
+private:
+ Data::EntryPtr m_oldEntry;
+};
+ }
+}
+
+UpdateEntries::UpdateEntries(Data::CollPtr coll_, Data::EntryPtr oldEntry_, Data::EntryPtr newEntry_, bool overWrite_)
+ : Group(i18n("Modify (Entry Title)", "Modify %1").arg(newEntry_->title()))
+ , m_coll(coll_)
+ , m_oldEntry(oldEntry_)
+ , m_newEntry(newEntry_)
+ , m_overWrite(overWrite_)
+{
+}
+
+void UpdateEntries::execute() {
+ if(isEmpty()) {
+ // add commands
+ // do this here instead of the constructor because several UpdateEntries may be in one command
+ // and I don't want to add new fields multiple times
+
+ QPair<Data::FieldVec, Data::FieldVec> p = Kernel::self()->mergeFields(m_coll,
+ m_newEntry->collection()->fields(),
+ m_newEntry);
+ Data::FieldVec modifiedFields = p.first;
+ Data::FieldVec addedFields = p.second;
+
+ for(Data::FieldVec::Iterator field = modifiedFields.begin(); field != modifiedFields.end(); ++field) {
+ if(m_coll->hasField(field->name())) {
+ addCommand(new FieldCommand(FieldCommand::FieldModify, m_coll,
+ field, m_coll->fieldByName(field->name())));
+ }
+ }
+
+ for(Data::FieldVec::Iterator field = addedFields.begin(); field != addedFields.end(); ++field) {
+ addCommand(new FieldCommand(FieldCommand::FieldAdd, m_coll, field));
+ }
+
+ // MergeEntries copies values from m_newEntry into m_oldEntry
+ // m_oldEntry is in the current collection
+ // m_newEntry isn't...
+ MergeEntries* cmd = new MergeEntries(m_oldEntry, m_newEntry, m_overWrite);
+ addCommand(cmd);
+ // cmd->oldEntry() returns a copy of m_oldEntry before values were merged
+ // m_oldEntry has new values
+ // in the ModifyEntries command, the second entry should be owned by the current
+ // collection and contain the updated values
+ // the first one is not owned by current collection
+ addCommand(new ModifyEntries(m_coll, cmd->oldEntry(), m_oldEntry));
+ }
+ Group::execute();
+}
diff --git a/src/commands/updateentries.h b/src/commands/updateentries.h
new file mode 100644
index 0000000..feb80e7
--- /dev/null
+++ b/src/commands/updateentries.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_UPDATEENTRIES_H
+#define TELLICO_UPDATEENTRIES_H
+
+#include "group.h"
+#include "../datavectors.h"
+
+namespace Tellico {
+ namespace Command {
+
+/**
+ * @author Robby Stephenson
+ */
+class UpdateEntries : public Group {
+
+public:
+ UpdateEntries(Data::CollPtr coll, Data::EntryPtr oldEntry, Data::EntryPtr newEntry, bool overWrite);
+
+ virtual void execute();
+
+private:
+ Data::CollPtr m_coll;
+ Data::EntryPtr m_oldEntry;
+ Data::EntryPtr m_newEntry;
+ bool m_overWrite : 1;
+};
+
+ } // end namespace
+}
+
+#endif
diff --git a/src/configdialog.cpp b/src/configdialog.cpp
new file mode 100644
index 0000000..e05766d
--- /dev/null
+++ b/src/configdialog.cpp
@@ -0,0 +1,1060 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "configdialog.h"
+#include "field.h"
+#include "collection.h"
+#include "collectionfactory.h"
+#include "fetch/execexternalfetcher.h"
+#include "fetch/fetchmanager.h"
+#include "fetch/configwidget.h"
+#include "controller.h"
+#include "fetcherconfigdialog.h"
+#include "tellico_kernel.h"
+#include "latin1literal.h"
+#include "tellico_utils.h"
+#include "core/tellico_config.h"
+#include "imagefactory.h"
+#include "gui/combobox.h"
+#include "gui/previewdialog.h"
+#include "newstuff/dialog.h"
+#include "../tellico_debug.h"
+
+#include <klineedit.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kstandarddirs.h>
+#include <knuminput.h>
+#include <kpushbutton.h>
+#include <kiconloader.h>
+#include <ksortablevaluelist.h>
+#include <kaccelmanager.h>
+#include <khtmlview.h>
+#include <kfiledialog.h>
+#include <kinputdialog.h>
+#include <kfontcombo.h>
+#include <kcolorcombo.h>
+
+#include <qsize.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qptrlist.h>
+#include <qpixmap.h>
+#include <qgrid.h>
+#include <qwhatsthis.h>
+#include <qregexp.h>
+#include <qhgroupbox.h>
+#include <qvgroupbox.h>
+#include <qpushbutton.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qfileinfo.h>
+#include <qradiobutton.h>
+#include <qvbuttongroup.h>
+
+namespace {
+ static const int CONFIG_MIN_WIDTH = 640;
+ static const int CONFIG_MIN_HEIGHT = 420;
+}
+
+using Tellico::SourceListViewItem;
+using Tellico::ConfigDialog;
+
+SourceListViewItem::SourceListViewItem(KListView* parent_, const GeneralFetcherInfo& info_,
+ const QString& groupName_)
+ : KListViewItem(parent_, info_.name), m_info(info_),
+ m_configGroup(groupName_), m_newSource(groupName_.isNull()), m_fetcher(0) {
+ QPixmap pix = Fetch::Manager::fetcherIcon(info_.type);
+ if(!pix.isNull()) {
+ setPixmap(0, pix);
+ }
+}
+
+SourceListViewItem::SourceListViewItem(KListView* parent_, QListViewItem* after_,
+ const GeneralFetcherInfo& info_, const QString& groupName_)
+ : KListViewItem(parent_, after_, info_.name), m_info(info_),
+ m_configGroup(groupName_), m_newSource(groupName_.isNull()), m_fetcher(0) {
+ QPixmap pix = Fetch::Manager::fetcherIcon(info_.type);
+ if(!pix.isNull()) {
+ setPixmap(0, pix);
+ }
+}
+
+void SourceListViewItem::setFetcher(Fetch::Fetcher::Ptr fetcher) {
+ m_fetcher = fetcher;
+ QPixmap pix = Fetch::Manager::fetcherIcon(fetcher.data());
+ if(!pix.isNull()) {
+ setPixmap(0, pix);
+ }
+}
+
+ConfigDialog::ConfigDialog(QWidget* parent_, const char* name_/*=0*/)
+ : KDialogBase(IconList, i18n("Configure Tellico"), Help|Ok|Apply|Cancel|Default,
+ Ok, parent_, name_, true, false)
+ , m_modifying(false)
+ , m_okClicked(false) {
+ setupGeneralPage();
+ setupPrintingPage();
+ setupTemplatePage();
+ setupFetchPage();
+
+ updateGeometry();
+ QSize s = sizeHint();
+ resize(QMAX(s.width(), CONFIG_MIN_WIDTH), QMAX(s.height(), CONFIG_MIN_HEIGHT));
+
+ // purely for asthetics make all widgets line up
+ QPtrList<QWidget> widgets;
+ widgets.append(m_fontCombo);
+ widgets.append(m_fontSizeInput);
+ widgets.append(m_baseColorCombo);
+ widgets.append(m_textColorCombo);
+ widgets.append(m_highBaseColorCombo);
+ widgets.append(m_highTextColorCombo);
+ int w = 0;
+ for(QPtrListIterator<QWidget> it(widgets); it.current(); ++it) {
+ it.current()->polish();
+ w = QMAX(w, it.current()->sizeHint().width());
+ }
+ for(QPtrListIterator<QWidget> it(widgets); it.current(); ++it) {
+ it.current()->setMinimumWidth(w);
+ }
+
+ enableButtonOK(false);
+ enableButtonApply(false);
+
+ setHelp(QString::fromLatin1("general-options"));
+ connect(this, SIGNAL(aboutToShowPage(QWidget*)), SLOT(slotUpdateHelpLink(QWidget*)));
+}
+
+ConfigDialog::~ConfigDialog() {
+ for(QPtrListIterator<Fetch::ConfigWidget> it(m_newStuffConfigWidgets); it.current(); ++it) {
+ it.current()->removed();
+ }
+}
+
+void ConfigDialog::slotUpdateHelpLink(QWidget* w_) {
+ switch(pageIndex(w_)) {
+ case 0:
+ setHelp(QString::fromLatin1("general-options"));
+ break;
+
+ case 1:
+ setHelp(QString::fromLatin1("printing-options"));
+ break;
+
+ case 2:
+ setHelp(QString::fromLatin1("template-options"));
+ break;
+
+ case 3:
+ setHelp(QString::fromLatin1("internet-sources-options"));
+ break;
+
+ default:
+ break;
+ }
+}
+
+void ConfigDialog::slotOk() {
+ m_okClicked = true;
+ slotApply();
+ accept();
+ m_okClicked = false;
+}
+
+void ConfigDialog::slotApply() {
+ emit signalConfigChanged();
+ enableButtonApply(false);
+}
+
+void ConfigDialog::slotDefault() {
+ // only change the defaults on the active page
+ Config::self()->useDefaults(true);
+ switch(activePageIndex()) {
+ case 0:
+ readGeneralConfig(); break;
+ case 1:
+ readPrintingConfig(); break;
+ case 2:
+ readTemplateConfig(); break;
+ }
+ Config::self()->useDefaults(false);
+ slotModified();
+}
+
+void ConfigDialog::setupGeneralPage() {
+ QPixmap pix = DesktopIcon(QString::fromLatin1("tellico"), KIcon::SizeMedium);
+ QFrame* frame = addPage(i18n("General"), i18n("General Options"), pix);
+ QVBoxLayout* l = new QVBoxLayout(frame, KDialog::marginHint(), KDialog::spacingHint());
+
+ m_cbOpenLastFile = new QCheckBox(i18n("&Reopen file at startup"), frame);
+ QWhatsThis::add(m_cbOpenLastFile, i18n("If checked, the file that was last open "
+ "will be re-opened at program start-up."));
+ l->addWidget(m_cbOpenLastFile);
+ connect(m_cbOpenLastFile, SIGNAL(clicked()), SLOT(slotModified()));
+
+ m_cbShowTipDay = new QCheckBox(i18n("&Show \"Tip of the Day\" at startup"), frame);
+ QWhatsThis::add(m_cbShowTipDay, i18n("If checked, the \"Tip of the Day\" will be "
+ "shown at program start-up."));
+ l->addWidget(m_cbShowTipDay);
+ connect(m_cbShowTipDay, SIGNAL(clicked()), SLOT(slotModified()));
+
+ QButtonGroup* imageGroup = new QVButtonGroup(i18n("Image Storage Options"), frame);
+ m_rbImageInFile = new QRadioButton(i18n("Store images in data file"), imageGroup);
+ m_rbImageInAppDir = new QRadioButton(i18n("Store images in common application directory"), imageGroup);
+ m_rbImageInLocalDir = new QRadioButton(i18n("Store images in directory relative to data file"), imageGroup);
+ QWhatsThis::add(imageGroup, i18n("Images may be saved in the data file itself, which can "
+ "cause Tellico to run slowly, stored in the Tellico "
+ "application directory, or stored in a directory in the "
+ "same location as the data file."));
+ l->addWidget(imageGroup);
+ connect(imageGroup, SIGNAL(clicked(int)), SLOT(slotModified()));
+
+ QVGroupBox* formatGroup = new QVGroupBox(i18n("Formatting Options"), frame);
+ l->addWidget(formatGroup);
+
+ m_cbCapitalize = new QCheckBox(i18n("Auto capitalize &titles and names"), formatGroup);
+ QWhatsThis::add(m_cbCapitalize, i18n("If checked, titles and names will "
+ "be automatically capitalized."));
+ connect(m_cbCapitalize, SIGNAL(clicked()), SLOT(slotModified()));
+
+ m_cbFormat = new QCheckBox(i18n("Auto &format titles and names"), formatGroup);
+ QWhatsThis::add(m_cbFormat, i18n("If checked, titles and names will "
+ "be automatically formatted."));
+ connect(m_cbFormat, SIGNAL(clicked()), SLOT(slotModified()));
+
+ QGrid* g1 = new QGrid(2, formatGroup);
+ g1->setSpacing(5);
+
+ QLabel* lab = new QLabel(i18n("No capitali&zation:"), g1);
+ m_leCapitals = new KLineEdit(g1);
+ lab->setBuddy(m_leCapitals);
+ QString whats = i18n("<qt>A list of words which should not be capitalized. Multiple values "
+ "should be separated by a semi-colon.</qt>");
+ QWhatsThis::add(lab, whats);
+ QWhatsThis::add(m_leCapitals, whats);
+ connect(m_leCapitals, SIGNAL(textChanged(const QString&)), SLOT(slotModified()));
+
+ lab = new QLabel(i18n("Artic&les:"), g1);
+ m_leArticles = new KLineEdit(g1);
+ lab->setBuddy(m_leArticles);
+ whats = i18n("<qt>A list of words which should be considered as articles "
+ "if they are the first word in a title. Multiple values "
+ "should be separated by a semi-colon.</qt>");
+ QWhatsThis::add(lab, whats);
+ QWhatsThis::add(m_leArticles, whats);
+ connect(m_leArticles, SIGNAL(textChanged(const QString&)), SLOT(slotModified()));
+
+ lab = new QLabel(i18n("Personal suffi&xes:"), g1);
+ m_leSuffixes = new KLineEdit(g1);
+ lab->setBuddy(m_leSuffixes);
+ whats = i18n("<qt>A list of suffixes which might be used in personal names. Multiple values "
+ "should be separated by a semi-colon.</qt>");
+ QWhatsThis::add(lab, whats);
+ QWhatsThis::add(m_leSuffixes, whats);
+ connect(m_leSuffixes, SIGNAL(textChanged(const QString&)), SLOT(slotModified()));
+
+ lab = new QLabel(i18n("Surname &prefixes:"), g1);
+ m_lePrefixes = new KLineEdit(g1);
+ lab->setBuddy(m_lePrefixes);
+ whats = i18n("<qt>A list of prefixes which might be used in surnames. Multiple values "
+ "should be separated by a semi-colon.</qt>");
+ QWhatsThis::add(lab, whats);
+ QWhatsThis::add(m_lePrefixes, whats);
+ connect(m_lePrefixes, SIGNAL(textChanged(const QString&)), SLOT(slotModified()));
+
+ // stretch to fill lower area
+ l->addStretch(1);
+}
+
+void ConfigDialog::setupPrintingPage() {
+ // SuSE changed the icon name on me
+ QPixmap pix;
+ KIconLoader* loader = KGlobal::iconLoader();
+ if(loader) {
+ pix = loader->loadIcon(QString::fromLatin1("printer1"), KIcon::Desktop, KIcon::SizeMedium,
+ KIcon::DefaultState, 0, true /*canReturnNull */);
+ if(pix.isNull()) {
+ pix = loader->loadIcon(QString::fromLatin1("printer2"), KIcon::Desktop, KIcon::SizeMedium,
+ KIcon::DefaultState, 0, true /*canReturnNull */);
+ }
+ if(pix.isNull()) {
+ pix = loader->loadIcon(QString::fromLatin1("print_printer"), KIcon::Desktop, KIcon::SizeMedium);
+ }
+ }
+ QFrame* frame = addPage(i18n("Printing"), i18n("Printing Options"), pix);
+ QVBoxLayout* l = new QVBoxLayout(frame, KDialog::marginHint(), KDialog::spacingHint());
+
+ QVGroupBox* formatOptions = new QVGroupBox(i18n("Formatting Options"), frame);
+ l->addWidget(formatOptions);
+
+ m_cbPrintFormatted = new QCheckBox(i18n("&Format titles and names"), formatOptions);
+ QWhatsThis::add(m_cbPrintFormatted, i18n("If checked, titles and names will be automatically formatted."));
+ connect(m_cbPrintFormatted, SIGNAL(clicked()), SLOT(slotModified()));
+
+ m_cbPrintHeaders = new QCheckBox(i18n("&Print field headers"), formatOptions);
+ QWhatsThis::add(m_cbPrintHeaders, i18n("If checked, the field names will be printed as table headers."));
+ connect(m_cbPrintHeaders, SIGNAL(clicked()), SLOT(slotModified()));
+
+ QHGroupBox* groupOptions = new QHGroupBox(i18n("Grouping Options"), frame);
+ l->addWidget(groupOptions);
+
+ m_cbPrintGrouped = new QCheckBox(i18n("&Group the entries"), groupOptions);
+ QWhatsThis::add(m_cbPrintGrouped, i18n("If checked, the entries will be grouped by the selected field."));
+ connect(m_cbPrintGrouped, SIGNAL(clicked()), SLOT(slotModified()));
+
+ QVGroupBox* imageOptions = new QVGroupBox(i18n("Image Options"), frame);
+ l->addWidget(imageOptions);
+
+ QGrid* grid = new QGrid(3, imageOptions);
+ grid->setSpacing(5);
+
+ QLabel* lab = new QLabel(i18n("Maximum image &width:"), grid);
+ m_imageWidthBox = new KIntSpinBox(0, 999, 1, 50, 10, grid);
+ m_imageWidthBox->setSuffix(QString::fromLatin1(" px"));
+ lab->setBuddy(m_imageWidthBox);
+ (void) new QWidget(grid);
+ QString whats = i18n("The maximum width of the images in the printout. The aspect ration is preserved.");
+ QWhatsThis::add(lab, whats);
+ QWhatsThis::add(m_imageWidthBox, whats);
+ connect(m_imageWidthBox, SIGNAL(valueChanged(int)), SLOT(slotModified()));
+ // QSpinBox doesn't emit valueChanged if you edit the value with
+ // the lineEdit until you change the keyboard focus
+ connect(m_imageWidthBox->child("qt_spinbox_edit"), SIGNAL(textChanged(const QString&)), SLOT(slotModified()));
+
+ lab = new QLabel(i18n("&Maximum image height:"), grid);
+ m_imageHeightBox = new KIntSpinBox(0, 999, 1, 50, 10, grid);
+ m_imageHeightBox->setSuffix(QString::fromLatin1(" px"));
+ lab->setBuddy(m_imageHeightBox);
+ (void) new QWidget(grid);
+ whats = i18n("The maximum height of the images in the printout. The aspect ration is preserved.");
+ QWhatsThis::add(lab, whats);
+ QWhatsThis::add(m_imageHeightBox, whats);
+ connect(m_imageHeightBox, SIGNAL(valueChanged(int)), SLOT(slotModified()));
+ // QSpinBox doesn't emit valueChanged if you edit the value with
+ // the lineEdit until you change the keyboard focus
+ connect(m_imageHeightBox->child("qt_spinbox_edit"), SIGNAL(textChanged(const QString&)), SLOT(slotModified()));
+
+ // stretch to fill lower area
+ l->addStretch(1);
+}
+
+void ConfigDialog::setupTemplatePage() {
+ QPixmap pix = DesktopIcon(QString::fromLatin1("looknfeel"), KIcon::SizeMedium);
+ QFrame* frame = addPage(i18n("Templates"), i18n("Template Options"), pix);
+ QVBoxLayout* l = new QVBoxLayout(frame, KDialog::marginHint(), KDialog::spacingHint());
+
+ QGridLayout* gridLayout = new QGridLayout(l);
+ gridLayout->setSpacing(KDialogBase::spacingHint());
+
+ int row = -1;
+ // so I can reuse an i18n string, a plain label can't have an '&'
+ QLabel* lab = new QLabel(i18n("Collection &type:").remove('&'), frame);
+ gridLayout->addWidget(lab, ++row, 0);
+ const int collType = Kernel::self()->collectionType();
+ lab = new QLabel(CollectionFactory::nameMap()[collType], frame);
+ gridLayout->addMultiCellWidget(lab, row, row, 1, 2);
+
+ lab = new QLabel(i18n("Template:"), frame);
+ m_templateCombo = new GUI::ComboBox(frame);
+ connect(m_templateCombo, SIGNAL(activated(int)), SLOT(slotModified()));
+ lab->setBuddy(m_templateCombo);
+ QString whats = i18n("Select the template to use for the current type of collections. "
+ "Not all templates will use the font and color settings.");
+ QWhatsThis::add(lab, whats);
+ QWhatsThis::add(m_templateCombo, whats);
+ gridLayout->addWidget(lab, ++row, 0);
+ gridLayout->addWidget(m_templateCombo, row, 1);
+
+ KPushButton* btn = new KPushButton(i18n("&Preview..."), frame);
+ QWhatsThis::add(btn, i18n("Show a preview of the template"));
+ btn->setIconSet(SmallIconSet(QString::fromLatin1("viewmag")));
+ gridLayout->addWidget(btn, row, 2);
+ connect(btn, SIGNAL(clicked()), SLOT(slotShowTemplatePreview()));
+
+ // so the button is squeezed small
+ gridLayout->setColStretch(0, 10);
+ gridLayout->setColStretch(1, 10);
+
+ loadTemplateList();
+
+// QLabel* l1 = new QLabel(i18n("The options below will be passed to the template, but not "
+// "all templates will use them. Some fonts and colors may be "
+// "specified directly in the template."), frame);
+// l1->setTextFormat(Qt::RichText);
+// l->addWidget(l1);
+
+ QGroupBox* fontGroup = new QGroupBox(0, Qt::Vertical, i18n("Font Options"), frame);
+ l->addWidget(fontGroup);
+
+ row = -1;
+ QGridLayout* fontLayout = new QGridLayout(fontGroup->layout());
+ fontLayout->setSpacing(KDialogBase::spacingHint());
+
+ lab = new QLabel(i18n("Font:"), fontGroup);
+ fontLayout->addWidget(lab, ++row, 0);
+ m_fontCombo = new KFontCombo(fontGroup);
+ fontLayout->addWidget(m_fontCombo, row, 1);
+ connect(m_fontCombo, SIGNAL(activated(int)), SLOT(slotModified()));
+ lab->setBuddy(m_fontCombo);
+ whats = i18n("This font is passed to the template used in the Entry View.");
+ QWhatsThis::add(lab, whats);
+ QWhatsThis::add(m_fontCombo, whats);
+
+ fontLayout->addWidget(new QLabel(i18n("Size:"), fontGroup), ++row, 0);
+ m_fontSizeInput = new KIntNumInput(fontGroup);
+ m_fontSizeInput->setRange(5, 30); // 30 is same max as konq config
+ m_fontSizeInput->setSuffix(QString::fromLatin1("pt"));
+ fontLayout->addWidget(m_fontSizeInput, row, 1);
+ connect(m_fontSizeInput, SIGNAL(valueChanged(int)), SLOT(slotModified()));
+ lab->setBuddy(m_fontSizeInput);
+ QWhatsThis::add(lab, whats);
+ QWhatsThis::add(m_fontSizeInput, whats);
+
+ QGroupBox* colGroup = new QGroupBox(0, Qt::Vertical, i18n("Color Options"), frame);
+ l->addWidget(colGroup);
+
+ row = -1;
+ QGridLayout* colLayout = new QGridLayout(colGroup->layout());
+ colLayout->setSpacing(KDialogBase::spacingHint());
+
+ lab = new QLabel(i18n("Background color:"), colGroup);
+ colLayout->addWidget(lab, ++row, 0);
+ m_baseColorCombo = new KColorCombo(colGroup);
+ colLayout->addWidget(m_baseColorCombo, row, 1);
+ connect(m_baseColorCombo, SIGNAL(activated(int)), SLOT(slotModified()));
+ lab->setBuddy(m_baseColorCombo);
+ whats = i18n("This color is passed to the template used in the Entry View.");
+ QWhatsThis::add(lab, whats);
+ QWhatsThis::add(m_baseColorCombo, whats);
+
+ lab = new QLabel(i18n("Text color:"), colGroup);
+ colLayout->addWidget(lab, ++row, 0);
+ m_textColorCombo = new KColorCombo(colGroup);
+ colLayout->addWidget(m_textColorCombo, row, 1);
+ connect(m_textColorCombo, SIGNAL(activated(int)), SLOT(slotModified()));
+ lab->setBuddy(m_textColorCombo);
+ QWhatsThis::add(lab, whats);
+ QWhatsThis::add(m_textColorCombo, whats);
+
+ lab = new QLabel(i18n("Highlight color:"), colGroup);
+ colLayout->addWidget(lab, ++row, 0);
+ m_highBaseColorCombo = new KColorCombo(colGroup);
+ colLayout->addWidget(m_highBaseColorCombo, row, 1);
+ connect(m_highBaseColorCombo, SIGNAL(activated(int)), SLOT(slotModified()));
+ lab->setBuddy(m_highBaseColorCombo);
+ QWhatsThis::add(lab, whats);
+ QWhatsThis::add(m_highBaseColorCombo, whats);
+
+ lab = new QLabel(i18n("Highlighted text color:"), colGroup);
+ colLayout->addWidget(lab, ++row, 0);
+ m_highTextColorCombo = new KColorCombo(colGroup);
+ colLayout->addWidget(m_highTextColorCombo, row, 1);
+ connect(m_highTextColorCombo, SIGNAL(activated(int)), SLOT(slotModified()));
+ lab->setBuddy(m_highTextColorCombo);
+ QWhatsThis::add(lab, whats);
+ QWhatsThis::add(m_highTextColorCombo, whats);
+
+ QVGroupBox* groupBox = new QVGroupBox(i18n("Manage Templates"), frame);
+ l->addWidget(groupBox);
+
+ QHBox* box1 = new QHBox(groupBox);
+ box1->setSpacing(KDialog::spacingHint());
+
+ KPushButton* b1 = new KPushButton(i18n("Install..."), box1);
+ b1->setIconSet(SmallIconSet(QString::fromLatin1("add")));
+ connect(b1, SIGNAL(clicked()), SLOT(slotInstallTemplate()));
+ whats = i18n("Click to install a new template directly.");
+ QWhatsThis::add(b1, whats);
+
+ KPushButton* b2 = new KPushButton(i18n("Download..."), box1);
+ b2->setIconSet(SmallIconSet(QString::fromLatin1("knewstuff")));
+ connect(b2, SIGNAL(clicked()), SLOT(slotDownloadTemplate()));
+ whats = i18n("Click to download additional templates via the Internet.");
+ QWhatsThis::add(b2, whats);
+
+ KPushButton* b3 = new KPushButton(i18n("Delete..."), box1);
+ b3->setIconSet(SmallIconSet(QString::fromLatin1("remove")));
+ connect(b3, SIGNAL(clicked()), SLOT(slotDeleteTemplate()));
+ whats = i18n("Click to select and remove installed templates.");
+ QWhatsThis::add(b3, whats);
+
+ // stretch to fill lower area
+ l->addStretch(1);
+
+ KAcceleratorManager::manage(frame);
+}
+
+void ConfigDialog::setupFetchPage() {
+ QPixmap pix = DesktopIcon(QString::fromLatin1("network"), KIcon::SizeMedium);
+ QFrame* frame = addPage(i18n("Data Sources"), i18n("Data Source Options"), pix);
+ QHBoxLayout* l = new QHBoxLayout(frame, KDialog::marginHint(), KDialog::spacingHint());
+
+ QVBoxLayout* leftLayout = new QVBoxLayout(l);
+ m_sourceListView = new KListView(frame);
+ m_sourceListView->addColumn(i18n("Source"));
+ m_sourceListView->setResizeMode(QListView::LastColumn);
+ m_sourceListView->setSorting(-1); // no sorting
+ m_sourceListView->setSelectionMode(QListView::Single);
+ leftLayout->addWidget(m_sourceListView, 1);
+ connect(m_sourceListView, SIGNAL(selectionChanged(QListViewItem*)), SLOT(slotSelectedSourceChanged(QListViewItem*)));
+ connect(m_sourceListView, SIGNAL(doubleClicked(QListViewItem*, const QPoint&, int)), SLOT(slotModifySourceClicked()));
+
+ QHBox* hb = new QHBox(frame);
+ leftLayout->addWidget(hb);
+ hb->setSpacing(KDialog::spacingHint());
+ m_moveUpSourceBtn = new KPushButton(i18n("Move &Up"), hb);
+ m_moveUpSourceBtn->setIconSet(SmallIconSet(QString::fromLatin1("up")));
+ QWhatsThis::add(m_moveUpSourceBtn, i18n("The order of the data sources sets the order "
+ "that Tellico uses when entries are automatically updated."));
+ m_moveDownSourceBtn = new KPushButton(i18n("Move &Down"), hb);
+ m_moveDownSourceBtn->setIconSet(SmallIconSet(QString::fromLatin1("down")));
+ QWhatsThis::add(m_moveDownSourceBtn, i18n("The order of the data sources sets the order "
+ "that Tellico uses when entries are automatically updated."));
+
+ // these icons are rather arbitrary, but seem to vaguely fit
+ QVBoxLayout* vlay = new QVBoxLayout(l);
+ KPushButton* newSourceBtn = new KPushButton(i18n("&New..."), frame);
+ newSourceBtn->setIconSet(SmallIconSet(QString::fromLatin1("filenew")));
+ QWhatsThis::add(newSourceBtn, i18n("Click to add a new data source."));
+ m_modifySourceBtn = new KPushButton(i18n("&Modify..."), frame);
+ m_modifySourceBtn->setIconSet(SmallIconSet(QString::fromLatin1("network")));
+ QWhatsThis::add(m_modifySourceBtn, i18n("Click to modify the selected data source."));
+ m_removeSourceBtn = new KPushButton(i18n("&Delete"), frame);
+ m_removeSourceBtn->setIconSet(SmallIconSet(QString::fromLatin1("remove")));
+ QWhatsThis::add(m_removeSourceBtn, i18n("Click to delete the selected data source."));
+ m_newStuffBtn = new KPushButton(i18n("Download..."), frame);
+ m_newStuffBtn->setIconSet(SmallIconSet(QString::fromLatin1("knewstuff")));
+ QWhatsThis::add(m_newStuffBtn, i18n("Click to download additional data sources via the Internet."));
+
+#if !KDE_IS_VERSION(3,3,90)
+ // only available in KDE 3.4 and up
+ m_newStuffBtn->setEnabled(false);
+#endif
+
+ vlay->addWidget(newSourceBtn);
+ vlay->addWidget(m_modifySourceBtn);
+ vlay->addWidget(m_removeSourceBtn);
+ // separate newstuff button from the rest
+ vlay->addSpacing(2 * KDialog::spacingHint());
+ vlay->addWidget(m_newStuffBtn);
+ vlay->addStretch(1);
+
+ connect(newSourceBtn, SIGNAL(clicked()), SLOT(slotNewSourceClicked()));
+ connect(m_modifySourceBtn, SIGNAL(clicked()), SLOT(slotModifySourceClicked()));
+ connect(m_moveUpSourceBtn, SIGNAL(clicked()), SLOT(slotMoveUpSourceClicked()));
+ connect(m_moveDownSourceBtn, SIGNAL(clicked()), SLOT(slotMoveDownSourceClicked()));
+ connect(m_removeSourceBtn, SIGNAL(clicked()), SLOT(slotRemoveSourceClicked()));
+ connect(m_newStuffBtn, SIGNAL(clicked()), SLOT(slotNewStuffClicked()));
+
+ KAcceleratorManager::manage(frame);
+}
+
+void ConfigDialog::readConfiguration() {
+ m_modifying = true;
+
+ readGeneralConfig();
+ readPrintingConfig();
+ readTemplateConfig();
+ readFetchConfig();
+
+ m_modifying = false;
+}
+
+void ConfigDialog::readGeneralConfig() {
+ m_cbShowTipDay->setChecked(Config::showTipOfDay());
+ m_cbOpenLastFile->setChecked(Config::reopenLastFile());
+ switch(Config::imageLocation()) {
+ case Config::ImagesInFile: m_rbImageInFile->setChecked(true); break;
+ case Config::ImagesInAppDir: m_rbImageInAppDir->setChecked(true); break;
+ case Config::ImagesInLocalDir: m_rbImageInLocalDir->setChecked(true); break;
+ }
+
+ bool autoCapitals = Config::autoCapitalization();
+ m_cbCapitalize->setChecked(autoCapitals);
+
+ bool autoFormat = Config::autoFormat();
+ m_cbFormat->setChecked(autoFormat);
+
+ const QRegExp comma(QString::fromLatin1("\\s*,\\s*"));
+ const QString semicolon = QString::fromLatin1("; ");
+
+ m_leCapitals->setText(Config::noCapitalizationString().replace(comma, semicolon));
+ m_leArticles->setText(Config::articlesString().replace(comma, semicolon));
+ m_leSuffixes->setText(Config::nameSuffixesString().replace(comma, semicolon));
+ m_lePrefixes->setText(Config::surnamePrefixesString().replace(comma, semicolon));
+}
+
+void ConfigDialog::readPrintingConfig() {
+ m_cbPrintHeaders->setChecked(Config::printFieldHeaders());
+ m_cbPrintFormatted->setChecked(Config::printFormatted());
+ m_cbPrintGrouped->setChecked(Config::printGrouped());
+ m_imageWidthBox->setValue(Config::maxImageWidth());
+ m_imageHeightBox->setValue(Config::maxImageHeight());
+}
+
+void ConfigDialog::readTemplateConfig() {
+ // entry template selection
+ const int collType = Kernel::self()->collectionType();
+ QString file = Config::templateName(collType);
+ file.replace('_', ' ');
+ QString fileContext = file + QString::fromLatin1(" XSL Template");
+ m_templateCombo->setCurrentItem(i18n(fileContext.utf8(), file.utf8()));
+
+ m_fontCombo->setCurrentFont(Config::templateFont(collType).family());
+ m_fontSizeInput->setValue(Config::templateFont(collType).pointSize());
+ m_baseColorCombo->setColor(Config::templateBaseColor(collType));
+ m_textColorCombo->setColor(Config::templateTextColor(collType));
+ m_highBaseColorCombo->setColor(Config::templateHighlightedBaseColor(collType));
+ m_highTextColorCombo->setColor(Config::templateHighlightedTextColor(collType));
+}
+
+void ConfigDialog::readFetchConfig() {
+ m_sourceListView->clear();
+ m_configWidgets.clear();
+
+ Fetch::FetcherVec fetchers = Fetch::Manager::self()->fetchers();
+ for(Fetch::FetcherVec::Iterator it = fetchers.begin(); it != fetchers.end(); ++it) {
+ GeneralFetcherInfo info(it->type(), it->source(), it->updateOverwrite());
+ SourceListViewItem* item = new SourceListViewItem(m_sourceListView, m_sourceListView->lastItem(), info);
+ item->setFetcher(it.data());
+ // grab the config widget, taking ownership
+ Fetch::ConfigWidget* cw = it->configWidget(this);
+ if(cw) { // might return 0 when no widget available for fetcher type
+ m_configWidgets.insert(item, cw);
+ // there's weird layout bug if it's not hidden
+ cw->hide();
+ }
+ kapp->processEvents();
+ }
+
+ if(m_sourceListView->childCount() == 0) {
+ m_modifySourceBtn->setEnabled(false);
+ m_removeSourceBtn->setEnabled(false);
+ } else {
+ // go ahead and select the first one
+ m_sourceListView->setSelected(m_sourceListView->firstChild(), true);
+ }
+}
+
+void ConfigDialog::saveConfiguration() {
+ Config::setShowTipOfDay(m_cbShowTipDay->isChecked());
+
+ int imageLocation;
+ if(m_rbImageInFile->isChecked()) {
+ imageLocation = Config::ImagesInFile;
+ } else if(m_rbImageInAppDir->isChecked()) {
+ imageLocation = Config::ImagesInAppDir;
+ } else {
+ imageLocation = Config::ImagesInLocalDir;
+ }
+ Config::setImageLocation(imageLocation);
+ Config::setReopenLastFile(m_cbOpenLastFile->isChecked());
+
+ Config::setAutoCapitalization(m_cbCapitalize->isChecked());
+ Config::setAutoFormat(m_cbFormat->isChecked());
+
+ const QRegExp semicolon(QString::fromLatin1("\\s*;\\s*"));
+ const QChar comma = ',';
+
+ Config::setNoCapitalizationString(m_leCapitals->text().replace(semicolon, comma));
+ Config::setArticlesString(m_leArticles->text().replace(semicolon, comma));
+ Data::Field::articlesUpdated();
+ Config::setNameSuffixesString(m_leSuffixes->text().replace(semicolon, comma));
+ Config::setSurnamePrefixesString(m_lePrefixes->text().replace(semicolon, comma));
+
+ Config::setPrintFieldHeaders(m_cbPrintHeaders->isChecked());
+ Config::setPrintFormatted(m_cbPrintFormatted->isChecked());
+ Config::setPrintGrouped(m_cbPrintGrouped->isChecked());
+ Config::setMaxImageWidth(m_imageWidthBox->value());
+ Config::setMaxImageHeight(m_imageHeightBox->value());
+
+ // entry template selection
+ const int collType = Kernel::self()->collectionType();
+ Config::setTemplateName(collType, m_templateCombo->currentData().toString());
+ QFont font(m_fontCombo->currentFont(), m_fontSizeInput->value());
+ Config::setTemplateFont(collType, font);
+ Config::setTemplateBaseColor(collType, m_baseColorCombo->color());
+ Config::setTemplateTextColor(collType, m_textColorCombo->color());
+ Config::setTemplateHighlightedBaseColor(collType, m_highBaseColorCombo->color());
+ Config::setTemplateHighlightedTextColor(collType, m_highTextColorCombo->color());
+
+ // first, tell config widgets they got deleted
+ for(QPtrListIterator<Fetch::ConfigWidget> it(m_removedConfigWidgets); it.current(); ++it) {
+ it.current()->removed();
+ }
+ m_removedConfigWidgets.clear();
+
+ KConfig* masterConfig = KGlobal::config();
+
+ bool reloadFetchers = false;
+ int count = 0; // start group numbering at 0
+ for(QListViewItemIterator it(m_sourceListView); it.current(); ++it, ++count) {
+ SourceListViewItem* item = static_cast<SourceListViewItem*>(it.current());
+ Fetch::ConfigWidget* cw = m_configWidgets[item];
+ if(!cw || (!cw->shouldSave() && !item->isNewSource())) {
+ continue;
+ }
+ m_newStuffConfigWidgets.removeRef(cw);
+ QString group = QString::fromLatin1("Data Source %1").arg(count);
+ // in case we later change the order, clear the group now
+ masterConfig->deleteGroup(group);
+ KConfigGroup configGroup(masterConfig, group);
+ configGroup.writeEntry("Name", item->text(0));
+ configGroup.writeEntry("Type", item->fetchType());
+ configGroup.writeEntry("UpdateOverwrite", item->updateOverwrite());
+ cw->saveConfig(configGroup);
+ item->setNewSource(false);
+ // in case the ordering changed
+ item->setConfigGroup(group);
+ reloadFetchers = true;
+ }
+ // now update total number of sources
+ KConfigGroup sourceGroup(masterConfig, "Data Sources");
+ sourceGroup.writeEntry("Sources Count", count);
+ // and purge old config groups
+ QString group = QString::fromLatin1("Data Source %1").arg(count);
+ while(masterConfig->hasGroup(group)) {
+ masterConfig->deleteGroup(group);
+ ++count;
+ group = QString::fromLatin1("Data Source %1").arg(count);
+ }
+
+ masterConfig->sync();
+ Config::writeConfig();
+
+ QString s = m_sourceListView->selectedItem() ? m_sourceListView->selectedItem()->text(0) : QString();
+ if(reloadFetchers) {
+ Fetch::Manager::self()->loadFetchers();
+ Controller::self()->updatedFetchers();
+ // reload fetcher items if OK was not clicked
+ // meaning apply was clicked
+ if(!m_okClicked) {
+ readFetchConfig();
+ if(!s.isEmpty()) {
+ for(QListViewItemIterator it(m_sourceListView); it.current(); ++it) {
+ if(it.current()->text(0) == s) {
+ m_sourceListView->setSelected(it.current(), true);
+ m_sourceListView->ensureItemVisible(it.current());
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+void ConfigDialog::slotModified() {
+ if(m_modifying) {
+ return;
+ }
+ enableButtonOK(true);
+ enableButtonApply(true);
+}
+
+void ConfigDialog::slotNewSourceClicked() {
+ FetcherConfigDialog dlg(this);
+ if(dlg.exec() != QDialog::Accepted) {
+ return;
+ }
+
+ Fetch::Type type = dlg.sourceType();
+ if(type == Fetch::Unknown) {
+ return;
+ }
+
+ GeneralFetcherInfo info(type, dlg.sourceName(), dlg.updateOverwrite());
+ SourceListViewItem* item = new SourceListViewItem(m_sourceListView, m_sourceListView->lastItem(), info);
+ m_sourceListView->ensureItemVisible(item);
+ m_sourceListView->setSelected(item, true);
+ Fetch::ConfigWidget* cw = dlg.configWidget();
+ if(cw) {
+ cw->setAccepted(true);
+ cw->slotSetModified();
+ cw->reparent(this, QPoint()); // keep the config widget around
+ m_configWidgets.insert(item, cw);
+ }
+ m_modifySourceBtn->setEnabled(true);
+ m_removeSourceBtn->setEnabled(true);
+ slotModified(); // toggle apply button
+}
+
+void ConfigDialog::slotModifySourceClicked() {
+ SourceListViewItem* item = static_cast<SourceListViewItem*>(m_sourceListView->selectedItem());
+ if(!item) {
+ return;
+ }
+
+ Fetch::ConfigWidget* cw = 0;
+ if(m_configWidgets.contains(item)) {
+ cw = m_configWidgets[item];
+ }
+ if(!cw) {
+ // no config widget for this one
+ // might be because support was compiled out
+ myDebug() << "ConfigDialog::slotModifySourceClicked() - no config widget for source " << item->text(0) << endl;
+ return;
+ }
+ FetcherConfigDialog dlg(item->text(0), item->fetchType(), item->updateOverwrite(), cw, this);
+
+ if(dlg.exec() == QDialog::Accepted) {
+ cw->setAccepted(true); // mark to save
+ QString newName = dlg.sourceName();
+ if(newName != item->text(0)) {
+ item->setText(0, newName);
+ cw->slotSetModified();
+ }
+ item->setUpdateOverwrite(dlg.updateOverwrite());
+ slotModified(); // toggle apply button
+ }
+ cw->reparent(this, QPoint()); // keep the config widget around
+}
+
+void ConfigDialog::slotRemoveSourceClicked() {
+ SourceListViewItem* item = static_cast<SourceListViewItem*>(m_sourceListView->selectedItem());
+ if(!item) {
+ return;
+ }
+
+ Fetch::ConfigWidget* cw = m_configWidgets[item];
+ if(cw) {
+ m_removedConfigWidgets.append(cw);
+ // it gets deleted by the parent
+ }
+ m_configWidgets.remove(item);
+ delete item;
+ m_sourceListView->setSelected(m_sourceListView->currentItem(), true);
+ slotModified(); // toggle apply button
+}
+
+void ConfigDialog::slotMoveUpSourceClicked() {
+ QListViewItem* item = m_sourceListView->selectedItem();
+ if(!item) {
+ return;
+ }
+ SourceListViewItem* prev = static_cast<SourceListViewItem*>(item->itemAbove()); // could be 0
+ if(prev) {
+ GeneralFetcherInfo info(prev->fetchType(), prev->text(0), prev->updateOverwrite());
+ SourceListViewItem* newItem = new SourceListViewItem(m_sourceListView, item, info, prev->configGroup());
+ newItem->setFetcher(prev->fetcher());
+ Fetch::ConfigWidget* cw = m_configWidgets[prev];
+ m_configWidgets.remove(prev);
+ m_configWidgets.insert(newItem, cw);
+ delete prev;
+ slotModified(); // toggle apply button
+ slotSelectedSourceChanged(item);
+ }
+}
+
+void ConfigDialog::slotMoveDownSourceClicked() {
+ SourceListViewItem* item = static_cast<SourceListViewItem*>(m_sourceListView->selectedItem());
+ if(!item) {
+ return;
+ }
+ QListViewItem* next = item->nextSibling(); // could be 0
+ if(next) {
+ GeneralFetcherInfo info(item->fetchType(), item->text(0), item->updateOverwrite());
+ SourceListViewItem* newItem = new SourceListViewItem(m_sourceListView, next, info, item->configGroup());
+ newItem->setFetcher(item->fetcher());
+ Fetch::ConfigWidget* cw = m_configWidgets[item];
+ m_configWidgets.remove(item);
+ m_configWidgets.insert(newItem, cw);
+ delete item;
+ slotModified(); // toggle apply button
+ m_sourceListView->setSelected(newItem, true);
+ }
+}
+
+void ConfigDialog::slotSelectedSourceChanged(QListViewItem* item_) {
+ m_moveUpSourceBtn->setEnabled(item_ && item_->itemAbove());
+ m_moveDownSourceBtn->setEnabled(item_ && item_->nextSibling());
+}
+
+void ConfigDialog::slotNewStuffClicked() {
+ NewStuff::Dialog dlg(NewStuff::DataScript, this);
+ dlg.exec();
+
+ QPtrList<NewStuff::DataSourceInfo> infoList = dlg.dataSourceInfo();
+ for(QPtrListIterator<NewStuff::DataSourceInfo> it(infoList); it.current(); ++it) {
+ const NewStuff::DataSourceInfo& info = *it.current();
+ Fetch::ExecExternalFetcher::ConfigWidget* cw = 0;
+ SourceListViewItem* item = 0;
+
+ // yes, this is checking if item exists
+ if(info.isUpdate && (item = findItem(info.sourceExec))) {
+ m_sourceListView->setSelected(item, true);
+ cw = dynamic_cast<Fetch::ExecExternalFetcher::ConfigWidget*>(m_configWidgets[item]);
+ } else {
+ cw = new Fetch::ExecExternalFetcher::ConfigWidget(this);
+ m_newStuffConfigWidgets.append(cw);
+
+ GeneralFetcherInfo fetchInfo(Fetch::ExecExternal, info.sourceName, false);
+ item = new SourceListViewItem(m_sourceListView, m_sourceListView->lastItem(), fetchInfo);
+ m_configWidgets.insert(item, cw);
+ }
+
+ if(!cw) {
+ continue;
+ }
+
+ KConfig spec(info.specFile, false, false);
+ cw->readConfig(&spec);
+ cw->slotSetModified();
+ cw->setAccepted(true);
+
+ if(item) {
+ m_sourceListView->setSelected(item, true);
+ m_sourceListView->ensureItemVisible(item);
+ }
+ }
+
+ if(infoList.count() > 0) {
+ m_modifySourceBtn->setEnabled(true);
+ m_removeSourceBtn->setEnabled(true);
+ slotModified(); // toggle apply button
+ }
+}
+
+Tellico::SourceListViewItem* ConfigDialog::findItem(const QString& path_) const {
+ if(path_.isEmpty()) {
+ kdWarning() << "ConfigDialog::findItem() - empty path" << endl;
+ return 0;
+ }
+
+ // this is a bit ugly, loop over all items, find the execexternal one
+ // that matches the path
+ for(QListViewItemIterator it(m_sourceListView); it.current(); ++it) {
+ SourceListViewItem* item = static_cast<SourceListViewItem*>(it.current());
+ if(item->fetchType() != Fetch::ExecExternal) {
+ continue;
+ }
+ Fetch::ExecExternalFetcher* f = dynamic_cast<Fetch::ExecExternalFetcher*>(item->fetcher().data());
+ if(f && f->execPath() == path_) {
+ return item;
+ }
+ }
+ myDebug() << "ConfigDialog::findItem() - no matching item found" << endl;
+ return 0;
+}
+
+void ConfigDialog::slotShowTemplatePreview() {
+ GUI::PreviewDialog* dlg = new GUI::PreviewDialog(this);
+
+ const QString templateName = m_templateCombo->currentData().toString();
+ dlg->setXSLTFile(templateName + QString::fromLatin1(".xsl"));
+
+ StyleOptions options;
+ options.fontFamily = m_fontCombo->currentFont();
+ options.fontSize = m_fontSizeInput->value();
+ options.baseColor = m_baseColorCombo->color();
+ options.textColor = m_textColorCombo->color();
+ options.highlightedTextColor = m_highTextColorCombo->color();
+ options.highlightedBaseColor = m_highBaseColorCombo->color();
+ dlg->setXSLTOptions(options);
+
+ Data::CollPtr c = CollectionFactory::collection(Kernel::self()->collectionType(), true);
+ Data::EntryPtr e = new Data::Entry(c);
+ for(Data::FieldVec::ConstIterator f = c->fields().begin(); f != c->fields().end(); ++f) {
+ if(f->name() == Latin1Literal("title")) {
+ e->setField(f->name(), m_templateCombo->currentText());
+ } else if(f->type() == Data::Field::Image) {
+ continue;
+ } else if(f->type() == Data::Field::Choice) {
+ e->setField(f->name(), f->allowed().front());
+ } else if(f->type() == Data::Field::Number) {
+ e->setField(f->name(), QString::fromLatin1("1"));
+ } else if(f->type() == Data::Field::Bool) {
+ e->setField(f->name(), QString::fromLatin1("true"));
+ } else if(f->type() == Data::Field::Rating) {
+ e->setField(f->name(), QString::fromLatin1("5"));
+ } else {
+ e->setField(f->name(), f->title());
+ }
+ }
+
+ dlg->showEntry(e);
+ dlg->show();
+ // dlg gets deleted by itself
+ // the finished() signal is connected in its constructor to delayedDestruct
+}
+
+void ConfigDialog::loadTemplateList() {
+ QStringList files = KGlobal::dirs()->findAllResources("appdata", QString::fromLatin1("entry-templates/*.xsl"),
+ false, true);
+ KSortableValueList<QString, QString> templates;
+ for(QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) {
+ QFileInfo fi(*it);
+ QString file = fi.fileName().section('.', 0, -2);
+ QString name = file;
+ name.replace('_', ' ');
+ QString title = i18n((name + QString::fromLatin1(" XSL Template")).utf8(), name.utf8());
+ templates.insert(title, file);
+ }
+ templates.sort();
+
+ QString s = m_templateCombo->currentText();
+ m_templateCombo->clear();
+ for(KSortableValueList<QString, QString>::iterator it2 = templates.begin(); it2 != templates.end(); ++it2) {
+ m_templateCombo->insertItem((*it2).index(), (*it2).value());
+ }
+ m_templateCombo->setCurrentItem(s);
+}
+
+void ConfigDialog::slotInstallTemplate() {
+ QString filter = i18n("*.xsl|XSL Files (*.xsl)") + '\n';
+ filter += i18n("*.tar.gz *.tgz|Template Packages (*.tar.gz)") + '\n';
+ filter += i18n("*|All Files");
+
+ KURL u = KFileDialog::getOpenURL(QString::null, filter, this);
+ if(u.isEmpty() || !u.isValid()) {
+ return;
+ }
+
+ NewStuff::Manager man(this);
+ if(man.installTemplate(u)) {
+ loadTemplateList();
+ }
+}
+
+void ConfigDialog::slotDownloadTemplate() {
+ NewStuff::Dialog dlg(NewStuff::EntryTemplate, this);
+ dlg.exec();
+ loadTemplateList();
+}
+
+void ConfigDialog::slotDeleteTemplate() {
+ QDir dir(Tellico::saveLocation(QString::fromLatin1("entry-templates/")));
+ dir.setNameFilter(QString::fromLatin1("*.xsl"));
+ dir.setFilter(QDir::Files | QDir::Writable);
+ QStringList files = dir.entryList();
+ QMap<QString, QString> nameFileMap;
+ for(QStringList::Iterator it = files.begin(); it != files.end(); ++it) {
+ (*it).truncate((*it).length()-4); // remove ".xsl"
+ QString name = (*it);
+ name.replace('_', ' ');
+ nameFileMap.insert(name, *it);
+ }
+ bool ok;
+ QString name = KInputDialog::getItem(i18n("Delete Template"),
+ i18n("Select template to delete:"),
+ nameFileMap.keys(), 0, false, &ok, this);
+ if(ok && !name.isEmpty()) {
+ QString file = nameFileMap[name];
+ NewStuff::Manager man(this);
+ man.removeTemplate(file);
+ loadTemplateList();
+ }
+}
+
+#include "configdialog.moc"
diff --git a/src/configdialog.h b/src/configdialog.h
new file mode 100644
index 0000000..64b5dbf
--- /dev/null
+++ b/src/configdialog.h
@@ -0,0 +1,226 @@
+/****************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef CONFIGDIALOG_H
+#define CONFIGDIALOG_H
+
+#include "fetch/fetcher.h"
+
+#include <kdialogbase.h>
+#include <klistview.h>
+
+class KConfig;
+class KLineEdit;
+class KIntSpinBox;
+class KPushButton;
+class KIntNumInput;
+class KFontCombo;
+class KColorCombo;
+
+class QCheckBox;
+class QRadioButton;
+
+namespace Tellico {
+ class SourceListViewItem;
+ namespace Fetch {
+ class ConfigWidget;
+ }
+ namespace GUI {
+ class ComboBox;
+ }
+
+/**
+ * The configuration dialog class allows the user to change the global application
+ * preferences.
+ *
+ * @author Robby Stephenson
+ */
+class ConfigDialog : public KDialogBase {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor sets up the Tabbed dialog pages.
+ *
+ * @param parent A pointer to the parent widget
+ * @param name The widget name
+ */
+ ConfigDialog(QWidget* parent, const char* name=0);
+ virtual ~ConfigDialog();
+
+ /**
+ * Reads the current configuration. Only the options which are not saved somewhere
+ * else are read at this point.
+ *
+ * @param config A pointer to the KConfig object
+ */
+ void readConfiguration();
+ /**
+ * Saves the configuration. @ref KConfigBase::sync is called. This method is called
+ * from the main Tellico object.
+ *
+ * @param config A pointer to the KConfig object
+ */
+ void saveConfiguration();
+
+signals:
+ /**
+ * Emitted whenever the Ok or Apply button is clicked.
+ */
+ void signalConfigChanged();
+
+private slots:
+ /**
+ * Called when anything gets changed
+ */
+ void slotModified();
+ /**
+ * Called when the Ok button is clicked.
+ */
+ void slotOk();
+ /**
+ * Called when the Apply button is clicked.
+ */
+ void slotApply();
+ /**
+ * Called when the Default button is clicked.
+ */
+ void slotDefault();
+ /**
+ * Update the help link for a page.
+ *
+ QCheckBox* m_cbWriteImagesInFile; * @param w The page
+ */
+ void slotUpdateHelpLink(QWidget* w);
+ /**
+ * Create a new Internet source
+ */
+ void slotNewSourceClicked();
+ /**
+ * Modify a Internet source
+ */
+ void slotModifySourceClicked();
+ /**
+ * Remove a Internet source
+ */
+ void slotRemoveSourceClicked();
+ void slotSelectedSourceChanged(QListViewItem* item);
+ void slotMoveUpSourceClicked();
+ void slotMoveDownSourceClicked();
+ void slotNewStuffClicked();
+ void slotShowTemplatePreview();
+ void slotInstallTemplate();
+ void slotDownloadTemplate();
+ void slotDeleteTemplate();
+
+private:
+ /**
+ * Sets-up the page for the general options.
+ */
+ void setupGeneralPage();
+ void readGeneralConfig();
+ /**
+ * Sets-up the page for printing options.
+ */
+ void setupPrintingPage();
+ void readPrintingConfig();
+ /**
+ * Sets-up the page for template options.
+ */
+ void setupTemplatePage();
+ void readTemplateConfig();
+ void setupFetchPage();
+ /**
+ * Load fetcher config
+ */
+ void readFetchConfig();
+
+ SourceListViewItem* findItem(const QString& path) const;
+ void loadTemplateList();
+
+ bool m_modifying;
+ bool m_okClicked;
+
+ QRadioButton* m_rbImageInFile;
+ QRadioButton* m_rbImageInAppDir;
+ QRadioButton* m_rbImageInLocalDir;
+ QCheckBox* m_cbOpenLastFile;
+ QCheckBox* m_cbShowTipDay;
+ QCheckBox* m_cbCapitalize;
+ QCheckBox* m_cbFormat;
+ KLineEdit* m_leCapitals;
+ KLineEdit* m_leArticles;
+ KLineEdit* m_leSuffixes;
+ KLineEdit* m_lePrefixes;
+
+ QCheckBox* m_cbPrintHeaders;
+ QCheckBox* m_cbPrintFormatted;
+ QCheckBox* m_cbPrintGrouped;
+ KIntSpinBox* m_imageWidthBox;
+ KIntSpinBox* m_imageHeightBox;
+
+ GUI::ComboBox* m_templateCombo;
+ KPushButton* m_previewButton;
+ KFontCombo* m_fontCombo;
+ KIntNumInput* m_fontSizeInput;
+ KColorCombo* m_baseColorCombo;
+ KColorCombo* m_textColorCombo;
+ KColorCombo* m_highBaseColorCombo;
+ KColorCombo* m_highTextColorCombo;
+
+ KListView* m_sourceListView;
+ QMap<SourceListViewItem*, Fetch::ConfigWidget*> m_configWidgets;
+ QPtrList<Fetch::ConfigWidget> m_newStuffConfigWidgets;
+ QPtrList<Fetch::ConfigWidget> m_removedConfigWidgets;
+ KPushButton* m_modifySourceBtn;
+ KPushButton* m_moveUpSourceBtn;
+ KPushButton* m_moveDownSourceBtn;
+ KPushButton* m_removeSourceBtn;
+ KPushButton* m_newStuffBtn;
+};
+
+class GeneralFetcherInfo {
+public:
+ GeneralFetcherInfo(Fetch::Type t, const QString& n, bool o) : type(t), name(n), updateOverwrite(o) {}
+ Fetch::Type type;
+ QString name;
+ bool updateOverwrite : 1;
+};
+
+class SourceListViewItem : public KListViewItem {
+public:
+ SourceListViewItem(KListView* parent, const GeneralFetcherInfo& info,
+ const QString& groupName = QString::null);
+
+ SourceListViewItem(KListView* parent, QListViewItem* after,
+ const GeneralFetcherInfo& info, const QString& groupName = QString::null);
+
+ void setConfigGroup(const QString& s) { m_configGroup = s; }
+ const QString& configGroup() const { return m_configGroup; }
+ const Fetch::Type& fetchType() const { return m_info.type; }
+ void setUpdateOverwrite(bool b) { m_info.updateOverwrite = b; }
+ bool updateOverwrite() const { return m_info.updateOverwrite; }
+ void setNewSource(bool b) { m_newSource = b; }
+ bool isNewSource() const { return m_newSource; }
+ void setFetcher(Fetch::Fetcher::Ptr fetcher);
+ Fetch::Fetcher::Ptr fetcher() const { return m_fetcher; }
+
+private:
+ GeneralFetcherInfo m_info;
+ QString m_configGroup;
+ bool m_newSource : 1;
+ Fetch::Fetcher::Ptr m_fetcher;
+};
+
+} // end namespace
+#endif
diff --git a/src/controller.cpp b/src/controller.cpp
new file mode 100644
index 0000000..1b3e29b
--- /dev/null
+++ b/src/controller.cpp
@@ -0,0 +1,762 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "controller.h"
+#include "mainwindow.h"
+#include "groupview.h"
+#include "detailedlistview.h"
+#include "entryeditdialog.h"
+#include "viewstack.h"
+#include "entryview.h"
+#include "entryiconview.h"
+#include "entry.h"
+#include "field.h"
+#include "filter.h"
+#include "filterdialog.h"
+#include "tellico_kernel.h"
+#include "latin1literal.h"
+#include "collection.h"
+#include "document.h"
+#include "borrower.h"
+#include "filterview.h"
+#include "loanview.h"
+#include "entryitem.h"
+#include "gui/tabcontrol.h"
+#include "calendarhandler.h"
+#include "tellico_debug.h"
+#include "groupiterator.h"
+#include "tellico_utils.h"
+#include "entryupdater.h"
+#include "entrymerger.h"
+
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kaction.h>
+#include <ktoolbarbutton.h>
+
+#include <qpopupmenu.h>
+
+using Tellico::Controller;
+
+Controller* Controller::s_self = 0;
+
+Controller::Controller(MainWindow* parent_, const char* name_)
+ : QObject(parent_, name_), m_mainWindow(parent_), m_working (false), m_widgetWithSelection(0) {
+}
+
+void Controller::addObserver(Observer* obs) {
+ m_observers.push_back(obs);
+}
+
+void Controller::removeObserver(Observer* obs) {
+ m_observers.remove(obs);
+}
+
+Tellico::GroupIterator Controller::groupIterator() const {
+ return GroupIterator(m_mainWindow->m_groupView);
+}
+
+QString Controller::groupBy() const {
+ return m_mainWindow->m_groupView->groupBy();
+}
+
+QStringList Controller::expandedGroupBy() const {
+ QStringList g = groupBy();
+ // special case for pseudo-group
+ if(g[0] == Data::Collection::s_peopleGroupName) {
+ g.clear();
+ Data::FieldVec fields = Data::Document::self()->collection()->peopleFields();
+ for(Data::FieldVec::Iterator it = fields.begin(); it != fields.end(); ++it) {
+ g << it->name();
+ }
+ }
+ // special case for no groups
+ if(g[0].isEmpty()) {
+ g.clear();
+ }
+ return g;
+}
+
+QStringList Controller::sortTitles() const {
+ QStringList list;
+ list << m_mainWindow->m_detailedView->sortColumnTitle1();
+ list << m_mainWindow->m_detailedView->sortColumnTitle2();
+ list << m_mainWindow->m_detailedView->sortColumnTitle3();
+ return list;
+}
+
+QStringList Controller::visibleColumns() const {
+ return m_mainWindow->m_detailedView->visibleColumns();
+}
+
+Tellico::Data::EntryVec Controller::visibleEntries() {
+ return m_mainWindow->m_detailedView->visibleEntries();
+}
+
+void Controller::slotCollectionAdded(Data::CollPtr coll_) {
+// myDebug() << "Controller::slotCollectionAdded()" << endl;
+ // at start-up, this might get called too early, so check and bail
+ if(!m_mainWindow->m_groupView) {
+ return;
+ }
+
+ // do this first because the group view will need it later
+ m_mainWindow->readCollectionOptions(coll_);
+ m_mainWindow->slotUpdateToolbarIcons();
+ m_mainWindow->updateEntrySources(); // has to be called before all the addCollection()
+ // calls in the widgets since they may want menu updates
+
+// blockAllSignals(true);
+ m_mainWindow->m_detailedView->addCollection(coll_);
+ m_mainWindow->m_groupView->addCollection(coll_);
+ m_mainWindow->m_editDialog->setLayout(coll_);
+ if(!coll_->filters().isEmpty()) {
+ m_mainWindow->addFilterView();
+ m_mainWindow->m_filterView->addCollection(coll_);
+ m_mainWindow->m_viewTabs->setTabBarHidden(false);
+ }
+ if(!coll_->borrowers().isEmpty()) {
+ m_mainWindow->addLoanView();
+ m_mainWindow->m_loanView->addCollection(coll_);
+ m_mainWindow->m_viewTabs->setTabBarHidden(false);
+ }
+// blockAllSignals(false);
+
+ m_mainWindow->slotStatusMsg(i18n("Ready."));
+
+ m_selectedEntries.clear();
+ m_mainWindow->slotEntryCount();
+
+ emit collectionAdded(coll_->type());
+
+ updateActions();
+
+ connect(coll_, SIGNAL(signalGroupsModified(Tellico::Data::CollPtr, PtrVector<Tellico::Data::EntryGroup>)),
+ m_mainWindow->m_groupView, SLOT(slotModifyGroups(Tellico::Data::CollPtr, PtrVector<Tellico::Data::EntryGroup>)));
+
+ connect(coll_, SIGNAL(signalRefreshField(Tellico::Data::FieldPtr)),
+ this, SLOT(slotRefreshField(Tellico::Data::FieldPtr)));
+}
+
+void Controller::slotCollectionModified(Data::CollPtr coll_) {
+ // easiest thing is to signal collection deleted, then added?
+ // FIXME: Signals for delete collection and then added are yucky
+ slotCollectionDeleted(coll_);
+ slotCollectionAdded(coll_);
+}
+
+void Controller::slotCollectionDeleted(Data::CollPtr coll_) {
+// myDebug() << "Controller::slotCollectionDeleted()" << endl;
+
+ blockAllSignals(true);
+ m_mainWindow->saveCollectionOptions(coll_);
+ m_mainWindow->m_groupView->removeCollection(coll_);
+ if(m_mainWindow->m_filterView) {
+ m_mainWindow->m_filterView->clear();
+ }
+ if(m_mainWindow->m_loanView) {
+ m_mainWindow->m_loanView->clear();
+ }
+ m_mainWindow->m_detailedView->removeCollection(coll_);
+ m_mainWindow->m_viewStack->clear();
+ blockAllSignals(false);
+
+ // disconnect all signals from the collection
+ // this is needed because the Collection::appendCollection() and mergeCollection()
+ // functions signal collection deleted then added for the same collection
+ coll_->disconnect();
+}
+
+void Controller::addedEntries(Data::EntryVec entries_) {
+ blockAllSignals(true);
+ for(ObserverVec::Iterator it = m_observers.begin(); it != m_observers.end(); ++it) {
+ it->addEntries(entries_);
+ }
+ m_mainWindow->slotQueueFilter();
+ blockAllSignals(false);
+}
+
+void Controller::modifiedEntries(Data::EntryVec entries_) {
+ // when a new document is being loaded, loans are added to borrowers, which
+ // end up calling Entry::checkIn() which called Document::saveEntry() which calls here
+ // ignore that
+ if(!m_mainWindow->m_initialized) {
+ return;
+ }
+ blockAllSignals(true);
+ for(ObserverVec::Iterator it = m_observers.begin(); it != m_observers.end(); ++it) {
+ it->modifyEntries(entries_);
+ }
+ m_mainWindow->m_viewStack->entryView()->slotRefresh(); // special case
+ m_mainWindow->slotQueueFilter();
+ blockAllSignals(false);
+}
+
+void Controller::removedEntries(Data::EntryVec entries_) {
+ blockAllSignals(true);
+ for(ObserverVec::Iterator it = m_observers.begin(); it != m_observers.end(); ++it) {
+ it->removeEntries(entries_);
+ }
+ for(Data::EntryVecIt it = entries_.begin(); it != entries_.end(); ++it) {
+ m_selectedEntries.remove(it);
+ m_currentEntries.remove(it);
+ }
+ if(m_currentEntries.isEmpty()) {
+ m_mainWindow->m_viewStack->entryView()->clear();
+ }
+ m_mainWindow->slotEntryCount();
+ m_mainWindow->slotQueueFilter();
+ blockAllSignals(false);
+}
+
+void Controller::addedField(Data::CollPtr coll_, Data::FieldPtr field_) {
+ for(ObserverVec::Iterator it = m_observers.begin(); it != m_observers.end(); ++it) {
+ it->addField(coll_, field_);
+ }
+ m_mainWindow->m_viewStack->refresh();
+ m_mainWindow->slotUpdateCollectionToolBar(coll_);
+ m_mainWindow->slotQueueFilter();
+}
+
+void Controller::removedField(Data::CollPtr coll_, Data::FieldPtr field_) {
+// myDebug() << "Controller::removedField() - " << field_->name() << endl;
+ for(ObserverVec::Iterator it = m_observers.begin(); it != m_observers.end(); ++it) {
+ it->removeField(coll_, field_);
+ }
+ m_mainWindow->m_viewStack->refresh();
+ m_mainWindow->slotUpdateCollectionToolBar(coll_);
+ m_mainWindow->slotQueueFilter();
+}
+
+void Controller::modifiedField(Data::CollPtr coll_, Data::FieldPtr oldField_, Data::FieldPtr newField_) {
+ for(ObserverVec::Iterator it = m_observers.begin(); it != m_observers.end(); ++it) {
+ it->modifyField(coll_, oldField_, newField_);
+ }
+ m_mainWindow->m_viewStack->refresh();
+ m_mainWindow->slotUpdateCollectionToolBar(coll_);
+ m_mainWindow->slotQueueFilter();
+}
+
+void Controller::reorderedFields(Data::CollPtr coll_) {
+ m_mainWindow->m_editDialog->setLayout(coll_);
+ m_mainWindow->m_detailedView->reorderFields(coll_->fields());
+ m_mainWindow->slotUpdateCollectionToolBar(coll_);
+ m_mainWindow->m_viewStack->refresh();
+}
+
+void Controller::slotClearSelection() {
+ if(m_working) {
+ return;
+ }
+
+ m_working = true;
+ blockAllSignals(true);
+
+ m_mainWindow->m_detailedView->clearSelection();
+ m_mainWindow->m_groupView->clearSelection();
+ if(m_mainWindow->m_loanView) {
+ m_mainWindow->m_loanView->clearSelection();
+ }
+// m_mainWindow->m_editDialog->clear(); let this stay
+// m_mainWindow->m_viewStack->clear(); let this stay
+
+ blockAllSignals(false);
+
+ m_selectedEntries.clear();
+ updateActions();
+ m_mainWindow->slotEntryCount();
+ m_working = false;
+}
+
+void Controller::slotUpdateSelection(QWidget* widget_, const Data::EntryVec& entries_) {
+ if(m_working) {
+ return;
+ }
+ m_working = true;
+
+ if(widget_) {
+ m_widgetWithSelection = widget_;
+ }
+// myDebug() << "Controller::slotUpdateSelection() entryList - " << entries_.count() << endl;
+
+ blockAllSignals(true);
+// in the list view and group view, if entries are selected in one, clear selection in other
+ if(m_widgetWithSelection != m_mainWindow->m_detailedView) {
+ m_mainWindow->m_detailedView->clearSelection();
+ }
+ if(m_widgetWithSelection != m_mainWindow->m_groupView) {
+ m_mainWindow->m_groupView->clearSelection();
+ }
+ if(m_mainWindow->m_filterView && m_widgetWithSelection != m_mainWindow->m_filterView) {
+ m_mainWindow->m_filterView->clearSelection();
+ }
+ if(m_mainWindow->m_loanView && m_widgetWithSelection != m_mainWindow->m_loanView) {
+ m_mainWindow->m_loanView->clearSelection();
+ }
+ if(m_widgetWithSelection != m_mainWindow->m_editDialog) {
+ m_mainWindow->m_editDialog->setContents(entries_);
+ }
+ // only show first one
+ if(m_widgetWithSelection && m_widgetWithSelection != m_mainWindow->m_viewStack->iconView()) {
+ if(entries_.count() > 1) {
+ m_mainWindow->m_viewStack->showEntries(entries_);
+ } else if(entries_.count() > 0) {
+ m_mainWindow->m_viewStack->showEntry(entries_[0]);
+ }
+ }
+ blockAllSignals(false);
+
+ m_selectedEntries = entries_;
+ updateActions();
+ m_mainWindow->slotEntryCount();
+ m_working = false;
+}
+
+void Controller::slotGoPrevEntry() {
+ goEntrySibling(PrevEntry);
+}
+
+void Controller::slotGoNextEntry() {
+ goEntrySibling(NextEntry);
+}
+
+void Controller::goEntrySibling(EntryDirection dir_) {
+ // if there are currently multiple selected, then do nothing
+ if(m_selectedEntries.count() != 1) {
+ return;
+ }
+ // find the widget that has an entry selected
+ GUI::ListView* view = ::qt_cast<GUI::ListView*>(m_widgetWithSelection);
+ if(!view) {
+ return;
+ }
+
+ GUI::ListViewItemList items = view->selectedItems();
+ if(items.count() != 1) {
+ return;
+ }
+ GUI::ListViewItem* item = items.first();
+ if(item->isEntryItem()) {
+ bool looped = false;
+ // check sanity
+ if(m_selectedEntries.front() != static_cast<EntryItem*>(item)->entry()) {
+ myDebug() << "Controller::slotGoNextEntry() - entries don't match!" << endl;
+ }
+ GUI::ListViewItem* nextItem = static_cast<GUI::ListViewItem*>(dir_ == PrevEntry
+ ? item->itemAbove()
+ : item->itemBelow());
+ if(!nextItem) {
+ // cycle through
+ nextItem = static_cast<GUI::ListViewItem*>(dir_ == PrevEntry
+ ? view->lastItem()
+ : view->firstChild());
+ looped = true;
+ }
+ while(!nextItem->isVisible()) {
+ nextItem = static_cast<GUI::ListViewItem*>(dir_ == PrevEntry
+ ? nextItem->itemAbove()
+ : nextItem->itemBelow());
+ }
+ while(nextItem && !nextItem->isEntryItem()) {
+ nextItem->setOpen(true); // have to be open to find the next one
+ nextItem = static_cast<GUI::ListViewItem*>(dir_ == PrevEntry
+ ? nextItem->itemAbove()
+ : nextItem->itemBelow());
+ if(!nextItem && !looped) {
+ // cycle through
+ nextItem = static_cast<GUI::ListViewItem*>(dir_ == PrevEntry
+ ? view->lastItem()
+ : view->firstChild());
+ looped = true;
+ }
+ }
+ if(nextItem) {
+ Data::EntryPtr e = static_cast<EntryItem*>(nextItem)->entry();
+ view->blockSignals(true);
+ view->setSelected(item, false);
+ view->setSelected(nextItem, true);
+ view->ensureItemVisible(nextItem);
+ view->blockSignals(false);
+ slotUpdateSelection(view, e);
+ }
+ }
+}
+
+void Controller::slotUpdateCurrent(const Data::EntryVec& entries_) {
+ if(m_working) {
+ return;
+ }
+ m_working = true;
+
+ blockAllSignals(true);
+ m_mainWindow->m_viewStack->showEntries(entries_);
+ blockAllSignals(false);
+
+ m_currentEntries = entries_;
+ m_working = false;
+}
+
+void Controller::slotUpdateSelectedEntries(const QString& source_) {
+ if(m_selectedEntries.isEmpty()) {
+ return;
+ }
+
+ // it deletes itself when done
+ // signal mapper strings can't be empty, "_all" is set in mainwindow
+ if(source_.isEmpty() || source_ == Latin1Literal("_all")) {
+ new EntryUpdater(m_selectedEntries.front()->collection(), m_selectedEntries, this);
+ } else {
+ new EntryUpdater(source_, m_selectedEntries.front()->collection(), m_selectedEntries, this);
+ }
+}
+
+void Controller::slotDeleteSelectedEntries() {
+ if(m_selectedEntries.isEmpty()) {
+ return;
+ }
+
+ m_working = true;
+
+ // confirm delete
+ if(m_selectedEntries.count() == 1) {
+ QString str = i18n("Do you really want to delete this entry?");
+ QString dontAsk = QString::fromLatin1("DeleteEntry");
+ int ret = KMessageBox::warningContinueCancel(Kernel::self()->widget(), str, i18n("Delete Entry"),
+ KGuiItem(i18n("&Delete"), QString::fromLatin1("editdelete")), dontAsk);
+ if(ret != KMessageBox::Continue) {
+ return;
+ }
+ } else {
+ QStringList names;
+ for(Data::EntryVecIt entry = m_selectedEntries.begin(); entry != m_selectedEntries.end(); ++entry) {
+ names += entry->title();
+ }
+ QString str = i18n("Do you really want to delete these entries?");
+ // historically called DeleteMultipleBooks, don't change
+ QString dontAsk = QString::fromLatin1("DeleteMultipleBooks");
+ int ret = KMessageBox::warningContinueCancelList(Kernel::self()->widget(), str, names,
+ i18n("Delete Multiple Entries"),
+ KGuiItem(i18n("&Delete"), QString::fromLatin1("editdelete")), dontAsk);
+ if(ret != KMessageBox::Continue) {
+ return;
+ }
+ }
+
+ GUI::CursorSaver cs;
+ Kernel::self()->removeEntries(m_selectedEntries);
+ updateActions();
+
+ m_working = false;
+
+ // special case, the detailed list view selects the next item, so handle that
+// Data::EntryList newList;
+// for(GUI::ListViewItemListIt it(m_mainWindow->m_detailedView->selectedItems()); it.current(); ++it) {
+// newList.append(static_cast<EntryItem*>(it.current())->entry());
+// }
+// slotUpdateSelection(m_mainWindow->m_detailedView, newList);
+ slotClearSelection();
+}
+
+void Controller::slotMergeSelectedEntries() {
+ // merge requires at least 2 entries
+ if(m_selectedEntries.count() < 2) {
+ return;
+ }
+
+ new EntryMerger(m_selectedEntries, this);
+}
+
+void Controller::slotRefreshField(Data::FieldPtr field_) {
+// myDebug() << "Controller::slotRefreshField()" << endl;
+ // group view only needs to refresh if it's the title
+ if(field_->name() == Latin1Literal("title")) {
+ m_mainWindow->m_groupView->populateCollection();
+ }
+ m_mainWindow->m_detailedView->slotRefresh();
+ m_mainWindow->m_viewStack->refresh();
+}
+
+void Controller::slotCopySelectedEntries() {
+ if(m_selectedEntries.isEmpty()) {
+ return;
+ }
+
+ // keep copy of selected entries
+ Data::EntryVec old = m_selectedEntries;
+
+ GUI::CursorSaver cs;
+ // need to create copies
+ Data::EntryVec entries;
+ for(Data::EntryVecIt it = m_selectedEntries.begin(); it != m_selectedEntries.end(); ++it) {
+ entries.append(new Data::Entry(*it));
+ }
+ Kernel::self()->addEntries(entries, false);
+ slotUpdateSelection(0, old);
+}
+
+void Controller::blockAllSignals(bool block_) const {
+// sanity check
+ if(!m_mainWindow->m_initialized) {
+ return;
+ }
+ m_mainWindow->m_detailedView->blockSignals(block_);
+ m_mainWindow->m_groupView->blockSignals(block_);
+ if(m_mainWindow->m_loanView) {
+ m_mainWindow->m_loanView->blockSignals(block_);
+ }
+ if(m_mainWindow->m_filterView) {
+ m_mainWindow->m_filterView->blockSignals(block_);
+ }
+ m_mainWindow->m_editDialog->blockSignals(block_);
+ m_mainWindow->m_viewStack->iconView()->blockSignals(block_);
+}
+
+void Controller::slotUpdateFilter(FilterPtr filter_) {
+// myDebug() << "Controller::slotUpdateFilter()" << endl;
+ blockAllSignals(true);
+
+ // the view takes over ownership of the filter
+ if(filter_ && !filter_->isEmpty()) {
+ // clear the icon view selection only
+ // the detailed view takes care of itself
+ m_mainWindow->m_viewStack->iconView()->clearSelection();
+ m_selectedEntries.clear();
+ }
+ updateActions();
+
+ m_mainWindow->m_detailedView->setFilter(filter_); // takes ownership
+
+ blockAllSignals(false);
+
+ m_mainWindow->slotEntryCount();
+}
+
+void Controller::editEntry(Data::EntryPtr) const {
+ m_mainWindow->slotShowEntryEditor();
+}
+
+void Controller::plugCollectionActions(QPopupMenu* popup_) {
+ if(!popup_) {
+ return;
+ }
+
+ m_mainWindow->action("coll_rename_collection")->plug(popup_);
+ m_mainWindow->action("coll_fields")->plug(popup_);
+ m_mainWindow->action("change_entry_grouping")->plug(popup_);
+}
+
+void Controller::plugEntryActions(QPopupMenu* popup_) {
+ if(!popup_) {
+ return;
+ }
+
+// m_mainWindow->m_newEntry->plug(popup_);
+ m_mainWindow->m_editEntry->plug(popup_);
+ m_mainWindow->m_copyEntry->plug(popup_);
+ m_mainWindow->m_deleteEntry->plug(popup_);
+ m_mainWindow->m_mergeEntry->plug(popup_);
+ m_mainWindow->m_updateEntryMenu->plug(popup_);
+ // there's a bug in KActionMenu with KXMLGUIFactory::plugActionList
+ // pluging the menu action isn't enough to have the popup get populated
+ plugUpdateMenu(popup_);
+ popup_->insertSeparator();
+ m_mainWindow->m_checkOutEntry->plug(popup_);
+}
+
+void Controller::plugUpdateMenu(QPopupMenu* popup_) {
+ QPopupMenu* updatePopup = 0;
+ const uint count = popup_->count();
+ for(uint i = 0; i < count; ++i) {
+ QMenuItem* item = popup_->findItem(popup_->idAt(i));
+ if(item && item->text() == m_mainWindow->m_updateEntryMenu->text()) {
+ updatePopup = item->popup();
+ break;
+ }
+ }
+
+ if(!updatePopup) {
+ return;
+ }
+
+ // I can't figure out why the actions get duplicated, but they do
+ // so clear them all
+ m_mainWindow->m_updateAll->unplug(updatePopup);
+ for(QPtrListIterator<KAction> it(m_mainWindow->m_fetchActions); it.current(); ++it) {
+ it.current()->unplug(updatePopup);
+ }
+
+ // clear separator, too
+ updatePopup->clear();
+
+ m_mainWindow->m_updateAll->plug(updatePopup);
+ updatePopup->insertSeparator();
+ for(QPtrListIterator<KAction> it(m_mainWindow->m_fetchActions); it.current(); ++it) {
+ it.current()->plug(updatePopup);
+ }
+}
+
+void Controller::updateActions() const {
+ bool emptySelection = m_selectedEntries.isEmpty();
+ m_mainWindow->stateChanged(QString::fromLatin1("empty_selection"),
+ emptySelection ? KXMLGUIClient::StateNoReverse : KXMLGUIClient::StateReverse);
+ for(QPtrListIterator<KAction> it(m_mainWindow->m_fetchActions); it.current(); ++it) {
+ it.current()->setEnabled(!emptySelection);
+ }
+ //only enable citation items when it's a bibliography
+ bool isBibtex = Kernel::self()->collectionType() == Data::Collection::Bibtex;
+ if(isBibtex) {
+ m_mainWindow->action("cite_clipboard")->setEnabled(!emptySelection);
+ m_mainWindow->action("cite_lyxpipe")->setEnabled(!emptySelection);
+ m_mainWindow->action("cite_openoffice")->setEnabled(!emptySelection);
+ }
+ m_mainWindow->m_checkInEntry->setEnabled(canCheckIn());
+
+ if(m_selectedEntries.count() < 2) {
+ m_mainWindow->m_editEntry->setText(i18n("&Edit Entry..."));
+ m_mainWindow->m_copyEntry->setText(i18n("D&uplicate Entry"));
+ m_mainWindow->m_updateEntryMenu->setText(i18n("&Update Entry"));
+ m_mainWindow->m_deleteEntry->setText(i18n("&Delete Entry"));
+ m_mainWindow->m_mergeEntry->setEnabled(false);
+ } else {
+ m_mainWindow->m_editEntry->setText(i18n("&Edit Entries..."));
+ m_mainWindow->m_copyEntry->setText(i18n("D&uplicate Entries"));
+ m_mainWindow->m_updateEntryMenu->setText(i18n("&Update Entries"));
+ m_mainWindow->m_deleteEntry->setText(i18n("&Delete Entries"));
+ m_mainWindow->m_mergeEntry->setEnabled(true);
+ }
+}
+
+void Controller::addedBorrower(Data::BorrowerPtr borrower_) {
+ m_mainWindow->addLoanView(); // just in case
+ for(ObserverVec::Iterator it = m_observers.begin(); it != m_observers.end(); ++it) {
+ it->addBorrower(borrower_);
+ }
+ m_mainWindow->m_viewTabs->setTabBarHidden(false);
+}
+
+void Controller::modifiedBorrower(Data::BorrowerPtr borrower_) {
+ for(ObserverVec::Iterator it = m_observers.begin(); it != m_observers.end(); ++it) {
+ it->modifyBorrower(borrower_);
+ }
+ hideTabs();
+}
+
+void Controller::addedFilter(FilterPtr filter_) {
+ m_mainWindow->addFilterView(); // just in case
+ for(ObserverVec::Iterator it = m_observers.begin(); it != m_observers.end(); ++it) {
+ it->addFilter(filter_);
+ }
+ m_mainWindow->m_viewTabs->setTabBarHidden(false);
+}
+
+void Controller::removedFilter(FilterPtr filter_) {
+ for(ObserverVec::Iterator it = m_observers.begin(); it != m_observers.end(); ++it) {
+ it->removeFilter(filter_);
+ }
+ hideTabs();
+}
+
+void Controller::slotCheckOut() {
+ if(m_selectedEntries.isEmpty()) {
+ return;
+ }
+
+ Data::EntryVec loanedEntries = m_selectedEntries;
+
+ // check to see if any of the entries are already on-loan, and warn user
+ QMap<QString, Data::EntryPtr> alreadyLoaned;
+ const Data::BorrowerVec& borrowers = Data::Document::self()->collection()->borrowers();
+ for(Data::BorrowerVec::ConstIterator it = borrowers.begin(); it != borrowers.end(); ++it) {
+ const Data::LoanVec& loans = it->loans();
+ for(Data::LoanVec::ConstIterator it2 = loans.begin(); it2 != loans.end(); ++it2) {
+ if(m_selectedEntries.contains(it2->entry())) {
+ alreadyLoaned.insert(it2->entry()->title(), it2->entry());
+ }
+ }
+ }
+ if(!alreadyLoaned.isEmpty()) {
+ KMessageBox::informationList(Kernel::self()->widget(),
+ i18n("The following items are already loaned, but Tellico "
+ "does not currently support lending an item multiple "
+ "times. They will be removed from the list of items "
+ "to lend."),
+ alreadyLoaned.keys());
+ QMapConstIterator<QString, Data::EntryPtr> it = alreadyLoaned.constBegin();
+ QMapConstIterator<QString, Data::EntryPtr> end = alreadyLoaned.constEnd();
+ for( ; it != end; ++it) {
+ loanedEntries.remove(it.data());
+ }
+ if(loanedEntries.isEmpty()) {
+ return;
+ }
+ }
+
+ if(Kernel::self()->addLoans(loanedEntries)) {
+ m_mainWindow->m_checkInEntry->setEnabled(true);
+ }
+}
+
+void Controller::slotCheckIn() {
+ slotCheckIn(m_selectedEntries);
+}
+
+void Controller::slotCheckIn(const Data::EntryVec& entries_) {
+ if(entries_.isEmpty()) {
+ return;
+ }
+
+ Data::LoanVec loans;
+ for(Data::EntryVec::ConstIterator it = entries_.begin(); it != entries_.end(); ++it) {
+ // these have to be in the loop since if a borrower gets empty
+ // it will be deleted, so the vector could change, for every entry iterator
+ Data::BorrowerVec vec = Data::Document::self()->collection()->borrowers();
+ // vec.end() must be in the loop, do NOT cache the value, it could change!
+ for(Data::BorrowerVec::Iterator bIt = vec.begin(); bIt != vec.end(); ++bIt) {
+ Data::LoanPtr l = bIt->loan(it.data());
+ if(l) {
+ loans.append(l);
+ // assume it's only loaned once
+ break;
+ }
+ }
+ }
+
+ if(Kernel::self()->removeLoans(loans)) {
+ m_mainWindow->m_checkInEntry->setEnabled(false);
+ }
+ hideTabs();
+}
+
+void Controller::hideTabs() const {
+ if((!m_mainWindow->m_filterView || m_mainWindow->m_filterView->childCount() == 0) &&
+ (!m_mainWindow->m_loanView || m_mainWindow->m_loanView->childCount() == 0)) {
+ m_mainWindow->m_viewTabs->showPage(m_mainWindow->m_groupView);
+ m_mainWindow->m_viewTabs->setTabBarHidden(true);
+ }
+}
+
+inline
+bool Controller::canCheckIn() const {
+ for(Data::EntryVec::ConstIterator entry = m_selectedEntries.begin(); entry != m_selectedEntries.end(); ++entry) {
+ if(entry->field(QString::fromLatin1("loaned")) == Latin1Literal("true")) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void Controller::updatedFetchers() {
+ m_mainWindow->updateEntrySources();
+}
+
+#include "controller.moc"
diff --git a/src/controller.h b/src/controller.h
new file mode 100644
index 0000000..58c3917
--- /dev/null
+++ b/src/controller.h
@@ -0,0 +1,175 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICOCONTROLLER_H
+#define TELLICOCONTROLLER_H
+
+class QPopupMenu;
+
+namespace Tellico {
+ class MainWindow;
+ class GroupView;
+ class GroupIterator;
+ namespace Data {
+ class Collection;
+ }
+}
+
+#include "entry.h"
+
+#include <qobject.h>
+
+namespace Tellico {
+class Observer;
+
+/**
+ * @author Robby Stephenson
+ */
+class Controller : public QObject {
+Q_OBJECT
+
+public:
+ static Controller* self() { return s_self; }
+ /**
+ * Initializes the singleton. Should just be called once, from Tellico::MainWindow
+ */
+ static void init(MainWindow* parent, const char* name=0) {
+ if(!s_self) s_self = new Controller(parent, name);
+ }
+
+ const Data::EntryVec& selectedEntries() const { return m_selectedEntries; }
+ Data::EntryVec visibleEntries();
+
+ void editEntry(Data::EntryPtr) const;
+ void hideTabs() const;
+ /**
+ * Plug the default collection actions into a widget
+ */
+ void plugCollectionActions(QPopupMenu* popup);
+ /**
+ * Plug the default entry actions into a widget
+ */
+ void plugEntryActions(QPopupMenu* popup);
+ void updateActions() const;
+
+ GroupIterator groupIterator() const;
+ /**
+ * Returns the name of the field being used to group the entries.
+ * That field name may not be an actual field in the collection, since
+ * pseudo-groups like _people exist.
+ */
+ QString groupBy() const;
+ /**
+ * Returns a list of the fields being used to group the entries.
+ * For ordinary fields, the list has a single item, the field name.
+ * For the pseudo-group _people, all the people fields are included.
+ */
+ QStringList expandedGroupBy() const;
+ /**
+ * Returns a list of the titles of the fields being used to sort the entries in the detailed column view.
+ */
+ QStringList sortTitles() const;
+ /**
+ * Returns the title of the fields currently visible in the detailed column view.
+ */
+ QStringList visibleColumns() const;
+
+ void addObserver(Observer* obs);
+ void removeObserver(Observer* obs);
+
+ void addedField(Data::CollPtr coll, Data::FieldPtr field);
+ void modifiedField(Data::CollPtr coll, Data::FieldPtr oldField, Data::FieldPtr newField);
+ void removedField(Data::CollPtr coll, Data::FieldPtr field);
+
+ void addedEntries(Data::EntryVec entries);
+ void modifiedEntries(Data::EntryVec entries);
+ void removedEntries(Data::EntryVec entries);
+
+ void addedBorrower(Data::BorrowerPtr borrower);
+ void modifiedBorrower(Data::BorrowerPtr borrower);
+
+ void addedFilter(FilterPtr filter);
+ void removedFilter(FilterPtr filter);
+
+ void reorderedFields(Data::CollPtr coll);
+ void updatedFetchers();
+
+public slots:
+ /**
+ * When a collection is added to the document, certain actions need to be taken
+ * by the parent app. The collection toolbar is updated, the entry count is set, and
+ * the collection's modified signal is connected to the @ref GroupView widget.
+ *
+ * @param coll A pointer to the collection being added
+ */
+ void slotCollectionAdded(Tellico::Data::CollPtr coll);
+ void slotCollectionModified(Tellico::Data::CollPtr coll);
+ /**
+ * Removes a collection from all the widgets
+ *
+ * @param coll A pointer to the collection being added
+ */
+ void slotCollectionDeleted(Tellico::Data::CollPtr coll);
+ void slotRefreshField(Tellico::Data::FieldPtr field);
+
+ void slotClearSelection();
+ /**
+ * Updates the widgets when entries are selected.
+ *
+ * param widget A pointer to the widget where the entries were selected
+ * @param widget The widget doing the selecting, if NULL, then use previous
+ * @param entries The list of selected entries
+ */
+ void slotUpdateSelection(QWidget* widget, const Tellico::Data::EntryVec& entries);
+ void slotUpdateCurrent(const Tellico::Data::EntryVec& entries);
+ void slotCopySelectedEntries();
+ void slotUpdateSelectedEntries(const QString& source);
+ void slotDeleteSelectedEntries();
+ void slotMergeSelectedEntries();
+ void slotUpdateFilter(Tellico::FilterPtr filter);
+ void slotCheckOut();
+ void slotCheckIn();
+ void slotCheckIn(const Data::EntryVec& entries);
+ void slotGoPrevEntry();
+ void slotGoNextEntry();
+
+signals:
+ void collectionAdded(int collType);
+
+private:
+ static Controller* s_self;
+ Controller(MainWindow* parent, const char* name);
+
+ void blockAllSignals(bool block) const;
+ bool canCheckIn() const;
+ void plugUpdateMenu(QPopupMenu* popup);
+ enum EntryDirection { PrevEntry, NextEntry };
+ void goEntrySibling(EntryDirection dir);
+
+ MainWindow* m_mainWindow;
+
+ bool m_working;
+
+ typedef PtrVector<Tellico::Observer> ObserverVec;
+ ObserverVec m_observers;
+
+ /**
+ * Keep track of the selected entries so that a top-level delete has something for reference
+ */
+ Data::EntryVec m_selectedEntries;
+ Data::EntryVec m_currentEntries;
+ QWidget* m_widgetWithSelection;
+};
+
+} // end namespace
+#endif
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
new file mode 100644
index 0000000..2d61d84
--- /dev/null
+++ b/src/core/Makefile.am
@@ -0,0 +1,27 @@
+AM_CPPFLAGS = $(all_includes)
+
+noinst_LIBRARIES = libcore.a
+libcore_a_SOURCES = dcopinterface.cpp dcopinterface.skel drophandler.cpp \
+ netaccess.cpp tellico_config.cpp tellico_config.kcfgc tellico_config_addons.cpp
+
+libcore_a_METASOURCES = AUTO
+
+KDE_OPTIONS = noautodist
+
+EXTRA_DIST = \
+tellico_config.kcfg tellico_config.kcfgc \
+tellico_config_addons.h tellico_config_addons.cpp \
+dcopinterface.h dcopinterface.cpp \
+netaccess.h netaccess.cpp \
+drophandler.h drophandler.cpp \
+tellico-rename.upd tellico.upd \
+tellico-1-3-update.pl
+
+kde_kcfg_DATA = tellico_config.kcfg
+
+updatedir = $(kde_datadir)/kconf_update
+update_DATA = tellico-rename.upd tellico.upd
+update_SCRIPTS = tellico-1-3-update.pl
+
+CLEANFILES = *~ *.loT tellico_config.h tellico_config.cpp
+
diff --git a/src/core/dcopinterface.cpp b/src/core/dcopinterface.cpp
new file mode 100644
index 0000000..f375b6b
--- /dev/null
+++ b/src/core/dcopinterface.cpp
@@ -0,0 +1,171 @@
+/***************************************************************************
+ copyright : (C) 2004-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "dcopinterface.h"
+#include "../latin1literal.h"
+#include "../controller.h"
+#include "../tellico_kernel.h"
+#include "../document.h"
+#include "../collection.h"
+#include "../translators/bibtexhandler.h"
+
+using Tellico::ApplicationInterface;
+using Tellico::CollectionInterface;
+
+Tellico::Import::Action ApplicationInterface::actionType(const QString& actionName) {
+ QString name = actionName.lower();
+ if(name == Latin1Literal("append")) {
+ return Import::Append;
+ } else if(name == Latin1Literal("merge")) {
+ return Import::Merge;
+ }
+ return Import::Replace;
+}
+
+QValueList<long> ApplicationInterface::selectedEntries() const {
+ QValueList<long> ids;
+ Data::EntryVec entries = Controller::self()->selectedEntries();
+ for(Data::EntryVecIt entry = entries.begin(); entry != entries.end(); ++entry) {
+ ids << entry->id();
+ }
+ return ids;
+}
+
+QValueList<long> ApplicationInterface::filteredEntries() const {
+ QValueList<long> ids;
+ Data::EntryVec entries = Controller::self()->visibleEntries();
+ for(Data::EntryVecIt entry = entries.begin(); entry != entries.end(); ++entry) {
+ ids << entry->id();
+ }
+ return ids;
+}
+
+long CollectionInterface::addEntry() {
+ Data::CollPtr coll = Data::Document::self()->collection();
+ if(!coll) {
+ return -1;
+ }
+ Data::EntryPtr entry = new Data::Entry(coll);
+ Kernel::self()->addEntries(entry, false);
+ return entry->id();
+}
+
+bool CollectionInterface::removeEntry(long id_) {
+ Data::CollPtr coll = Data::Document::self()->collection();
+ if(!coll) {
+ return false;
+ }
+ Data::EntryPtr entry = coll->entryById(id_);
+ if(!entry) {
+ return false;
+ }
+ Kernel::self()->removeEntries(entry);
+ return coll->entryById(id_) == 0;
+}
+
+QStringList CollectionInterface::values(const QString& fieldName_) const {
+ QStringList results;
+ Data::CollPtr coll = Data::Document::self()->collection();
+ if(!coll) {
+ return results;
+ }
+ Data::FieldPtr field = coll->fieldByName(fieldName_);
+ if(!field) {
+ field = coll->fieldByTitle(fieldName_);
+ }
+ if(!field) {
+ return results;
+ }
+ Data::EntryVec entries = Controller::self()->selectedEntries();
+ for(Data::EntryVecIt entry = entries.begin(); entry != entries.end(); ++entry) {
+ results += entry->fields(field, false);
+ }
+ return results;
+}
+
+QStringList CollectionInterface::values(long id_, const QString& fieldName_) const {
+ QStringList results;
+ Data::CollPtr coll = Data::Document::self()->collection();
+ if(!coll) {
+ return results;
+ }
+ Data::FieldPtr field = coll->fieldByName(fieldName_);
+ if(!field) {
+ field = coll->fieldByTitle(fieldName_);
+ }
+ if(!field) {
+ return results;
+ }
+ Data::EntryPtr entry = coll->entryById(id_);
+ if(entry) {
+ results += entry->fields(field, false);
+ }
+ return results;
+}
+
+QStringList CollectionInterface::bibtexKeys() const {
+ Data::CollPtr coll = Data::Document::self()->collection();
+ if(!coll || coll->type() != Data::Collection::Bibtex) {
+ return QStringList();
+ }
+ return BibtexHandler::bibtexKeys(Controller::self()->selectedEntries());
+}
+
+QString CollectionInterface::bibtexKey(long id_) const {
+ Data::CollPtr coll = Data::Document::self()->collection();
+ if(!coll || coll->type() != Data::Collection::Bibtex) {
+ return QString();
+ }
+ Data::EntryPtr entry = coll->entryById(id_);
+ if(!entry) {
+ return QString();
+ }
+ return BibtexHandler::bibtexKeys(entry).first();
+}
+
+bool CollectionInterface::setFieldValue(long id_, const QString& fieldName_, const QString& value_) {
+ Data::CollPtr coll = Data::Document::self()->collection();
+ if(!coll) {
+ return false;
+ }
+ Data::EntryPtr entry = coll->entryById(id_);
+ if(!entry) {
+ return false;
+ }
+ Data::EntryPtr oldEntry = new Data::Entry(*entry);
+ if(!entry->setField(fieldName_, value_)) {
+ return false;
+ }
+ Kernel::self()->modifyEntries(oldEntry, entry);
+ return true;
+}
+
+bool CollectionInterface::addFieldValue(long id_, const QString& fieldName_, const QString& value_) {
+ Data::CollPtr coll = Data::Document::self()->collection();
+ if(!coll) {
+ return false;
+ }
+ Data::EntryPtr entry = coll->entryById(id_);
+ if(!entry) {
+ return false;
+ }
+ Data::EntryPtr oldEntry = new Data::Entry(*entry);
+ QStringList values = entry->fields(fieldName_, false);
+ QStringList newValues = values;
+ newValues << value_;
+ if(!entry->setField(fieldName_, newValues.join(QString::fromLatin1("; ")))) {
+ return false;
+ }
+ Kernel::self()->modifyEntries(oldEntry, entry);
+ return true;
+}
diff --git a/src/core/dcopinterface.h b/src/core/dcopinterface.h
new file mode 100644
index 0000000..018de80
--- /dev/null
+++ b/src/core/dcopinterface.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+ copyright : (C) 2004-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_DCOPINTERFACE_H
+#define TELLICO_DCOPINTERFACE_H
+
+#include "../translators/translators.h"
+
+#include <dcopobject.h>
+#include <kurl.h>
+
+#include <qstringlist.h> // used in generated dcopinterface_skel.cpp
+
+namespace Tellico {
+
+class ApplicationInterface : public DCOPObject {
+K_DCOP
+k_dcop:
+ bool importTellico(const QString& file, const QString& action)
+ { return importFile(Import::TellicoXML, KURL::fromPathOrURL(file), actionType(action)); }
+ bool importBibtex(const QString& file, const QString& action)
+ { return importFile(Import::Bibtex, KURL::fromPathOrURL(file), actionType(action)); }
+ bool importMODS(const QString& file, const QString& action)
+ { return importFile(Import::MODS, KURL::fromPathOrURL(file), actionType(action)); }
+ bool importRIS(const QString& file, const QString& action)
+ { return importFile(Import::RIS, KURL::fromPathOrURL(file), actionType(action)); }
+
+ bool exportXML(const QString& file)
+ { return exportCollection(Export::TellicoXML, KURL::fromPathOrURL(file)); }
+ bool exportZip(const QString& file)
+ { return exportCollection(Export::TellicoZip, KURL::fromPathOrURL(file)); }
+ bool exportBibtex(const QString& file)
+ { return exportCollection(Export::Bibtex, KURL::fromPathOrURL(file)); }
+ bool exportHTML(const QString& file)
+ { return exportCollection(Export::HTML, KURL::fromPathOrURL(file)); }
+ bool exportCSV(const QString& file)
+ { return exportCollection(Export::CSV, KURL::fromPathOrURL(file)); }
+ bool exportPilotDB(const QString& file)
+ { return exportCollection(Export::PilotDB, KURL::fromPathOrURL(file)); }
+
+ QValueList<long> selectedEntries() const;
+ QValueList<long> filteredEntries() const;
+
+ virtual void openFile(const QString& file) = 0;
+ virtual void setFilter(const QString& text) = 0;
+ virtual bool showEntry(long id) = 0;
+
+protected:
+ ApplicationInterface() : DCOPObject("tellico") {}
+ virtual bool importFile(Import::Format format, const KURL& url, Import::Action action) = 0;
+ virtual bool exportCollection(Export::Format format, const KURL& url) = 0;
+
+private:
+ Import::Action actionType(const QString& actionName);
+};
+
+class CollectionInterface : public DCOPObject {
+K_DCOP
+k_dcop:
+ CollectionInterface() : DCOPObject("collection") {}
+
+ long addEntry();
+ bool removeEntry(long entryID);
+
+ QStringList values(const QString& fieldName) const;
+ QStringList values(long entryID, const QString& fieldName) const;
+ QStringList bibtexKeys() const;
+ QString bibtexKey(long entryID) const;
+
+ bool setFieldValue(long entryID, const QString& fieldName, const QString& value);
+ bool addFieldValue(long entryID, const QString& fieldName, const QString& value);
+};
+
+} // end namespace
+#endif
diff --git a/src/core/dcopinterface_skel.cpp b/src/core/dcopinterface_skel.cpp
new file mode 100644
index 0000000..9edf4ad
--- /dev/null
+++ b/src/core/dcopinterface_skel.cpp
@@ -0,0 +1,374 @@
+/****************************************************************************
+**
+** DCOP Skeleton generated by dcopidl2cpp from dcopinterface.kidl
+**
+** WARNING! All changes made in this file will be lost!
+**
+*****************************************************************************/
+
+#include "./dcopinterface.h"
+
+#include <kdatastream.h>
+#include <qasciidict.h>
+
+namespace Tellico {
+
+static const int ApplicationInterface_fhash = 17;
+static const char* const ApplicationInterface_ftable[16][3] = {
+ { "bool", "importTellico(QString,QString)", "importTellico(QString file,QString action)" },
+ { "bool", "importBibtex(QString,QString)", "importBibtex(QString file,QString action)" },
+ { "bool", "importMODS(QString,QString)", "importMODS(QString file,QString action)" },
+ { "bool", "importRIS(QString,QString)", "importRIS(QString file,QString action)" },
+ { "bool", "exportXML(QString)", "exportXML(QString file)" },
+ { "bool", "exportZip(QString)", "exportZip(QString file)" },
+ { "bool", "exportBibtex(QString)", "exportBibtex(QString file)" },
+ { "bool", "exportHTML(QString)", "exportHTML(QString file)" },
+ { "bool", "exportCSV(QString)", "exportCSV(QString file)" },
+ { "bool", "exportPilotDB(QString)", "exportPilotDB(QString file)" },
+ { "QValueList<long int>", "selectedEntries()", "selectedEntries()" },
+ { "QValueList<long int>", "filteredEntries()", "filteredEntries()" },
+ { "void", "openFile(QString)", "openFile(QString file)" },
+ { "void", "setFilter(QString)", "setFilter(QString text)" },
+ { "bool", "showEntry(long int)", "showEntry(long int id)" },
+ { 0, 0, 0 }
+};
+static const int ApplicationInterface_ftable_hiddens[15] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+};
+
+bool ApplicationInterface::process(const QCString &fun, const QByteArray &data, QCString& replyType, QByteArray &replyData)
+{
+ static QAsciiDict<int>* fdict = 0;
+ if ( !fdict ) {
+ fdict = new QAsciiDict<int>( ApplicationInterface_fhash, true, false );
+ for ( int i = 0; ApplicationInterface_ftable[i][1]; i++ )
+ fdict->insert( ApplicationInterface_ftable[i][1], new int( i ) );
+ }
+ int* fp = fdict->find( fun );
+ switch ( fp?*fp:-1) {
+ case 0: { // bool importTellico(QString,QString)
+ QString arg0;
+ QString arg1;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ if (arg.atEnd()) return false;
+ arg >> arg1;
+ replyType = ApplicationInterface_ftable[0][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << importTellico(arg0, arg1 );
+ } break;
+ case 1: { // bool importBibtex(QString,QString)
+ QString arg0;
+ QString arg1;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ if (arg.atEnd()) return false;
+ arg >> arg1;
+ replyType = ApplicationInterface_ftable[1][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << importBibtex(arg0, arg1 );
+ } break;
+ case 2: { // bool importMODS(QString,QString)
+ QString arg0;
+ QString arg1;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ if (arg.atEnd()) return false;
+ arg >> arg1;
+ replyType = ApplicationInterface_ftable[2][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << importMODS(arg0, arg1 );
+ } break;
+ case 3: { // bool importRIS(QString,QString)
+ QString arg0;
+ QString arg1;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ if (arg.atEnd()) return false;
+ arg >> arg1;
+ replyType = ApplicationInterface_ftable[3][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << importRIS(arg0, arg1 );
+ } break;
+ case 4: { // bool exportXML(QString)
+ QString arg0;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ replyType = ApplicationInterface_ftable[4][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << exportXML(arg0 );
+ } break;
+ case 5: { // bool exportZip(QString)
+ QString arg0;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ replyType = ApplicationInterface_ftable[5][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << exportZip(arg0 );
+ } break;
+ case 6: { // bool exportBibtex(QString)
+ QString arg0;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ replyType = ApplicationInterface_ftable[6][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << exportBibtex(arg0 );
+ } break;
+ case 7: { // bool exportHTML(QString)
+ QString arg0;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ replyType = ApplicationInterface_ftable[7][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << exportHTML(arg0 );
+ } break;
+ case 8: { // bool exportCSV(QString)
+ QString arg0;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ replyType = ApplicationInterface_ftable[8][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << exportCSV(arg0 );
+ } break;
+ case 9: { // bool exportPilotDB(QString)
+ QString arg0;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ replyType = ApplicationInterface_ftable[9][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << exportPilotDB(arg0 );
+ } break;
+ case 10: { // QValueList<long int> selectedEntries()
+ replyType = ApplicationInterface_ftable[10][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << selectedEntries( );
+ } break;
+ case 11: { // QValueList<long int> filteredEntries()
+ replyType = ApplicationInterface_ftable[11][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << filteredEntries( );
+ } break;
+ case 12: { // void openFile(QString)
+ QString arg0;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ replyType = ApplicationInterface_ftable[12][0];
+ openFile(arg0 );
+ } break;
+ case 13: { // void setFilter(QString)
+ QString arg0;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ replyType = ApplicationInterface_ftable[13][0];
+ setFilter(arg0 );
+ } break;
+ case 14: { // bool showEntry(long int)
+ long int arg0;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ replyType = ApplicationInterface_ftable[14][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << showEntry(arg0 );
+ } break;
+ default:
+ return DCOPObject::process( fun, data, replyType, replyData );
+ }
+ return true;
+}
+
+QCStringList ApplicationInterface::interfaces()
+{
+ QCStringList ifaces = DCOPObject::interfaces();
+ ifaces += "Tellico::ApplicationInterface";
+ return ifaces;
+}
+
+QCStringList ApplicationInterface::functions()
+{
+ QCStringList funcs = DCOPObject::functions();
+ for ( int i = 0; ApplicationInterface_ftable[i][2]; i++ ) {
+ if (ApplicationInterface_ftable_hiddens[i])
+ continue;
+ QCString func = ApplicationInterface_ftable[i][0];
+ func += ' ';
+ func += ApplicationInterface_ftable[i][2];
+ funcs << func;
+ }
+ return funcs;
+}
+
+} // namespace
+
+#include <kdatastream.h>
+#include <qasciidict.h>
+
+namespace Tellico {
+
+static const int CollectionInterface_fhash = 11;
+static const char* const CollectionInterface_ftable[9][3] = {
+ { "long int", "addEntry()", "addEntry()" },
+ { "bool", "removeEntry(long int)", "removeEntry(long int entryID)" },
+ { "QStringList", "values(QString)", "values(QString fieldName)" },
+ { "QStringList", "values(long int,QString)", "values(long int entryID,QString fieldName)" },
+ { "QStringList", "bibtexKeys()", "bibtexKeys()" },
+ { "QString", "bibtexKey(long int)", "bibtexKey(long int entryID)" },
+ { "bool", "setFieldValue(long int,QString,QString)", "setFieldValue(long int entryID,QString fieldName,QString value)" },
+ { "bool", "addFieldValue(long int,QString,QString)", "addFieldValue(long int entryID,QString fieldName,QString value)" },
+ { 0, 0, 0 }
+};
+static const int CollectionInterface_ftable_hiddens[8] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+};
+
+bool CollectionInterface::process(const QCString &fun, const QByteArray &data, QCString& replyType, QByteArray &replyData)
+{
+ static QAsciiDict<int>* fdict = 0;
+ if ( !fdict ) {
+ fdict = new QAsciiDict<int>( CollectionInterface_fhash, true, false );
+ for ( int i = 0; CollectionInterface_ftable[i][1]; i++ )
+ fdict->insert( CollectionInterface_ftable[i][1], new int( i ) );
+ }
+ int* fp = fdict->find( fun );
+ switch ( fp?*fp:-1) {
+ case 0: { // long int addEntry()
+ replyType = CollectionInterface_ftable[0][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << addEntry( );
+ } break;
+ case 1: { // bool removeEntry(long int)
+ long int arg0;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ replyType = CollectionInterface_ftable[1][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << removeEntry(arg0 );
+ } break;
+ case 2: { // QStringList values(QString)
+ QString arg0;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ replyType = CollectionInterface_ftable[2][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << values(arg0 );
+ } break;
+ case 3: { // QStringList values(long int,QString)
+ long int arg0;
+ QString arg1;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ if (arg.atEnd()) return false;
+ arg >> arg1;
+ replyType = CollectionInterface_ftable[3][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << values(arg0, arg1 );
+ } break;
+ case 4: { // QStringList bibtexKeys()
+ replyType = CollectionInterface_ftable[4][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << bibtexKeys( );
+ } break;
+ case 5: { // QString bibtexKey(long int)
+ long int arg0;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ replyType = CollectionInterface_ftable[5][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << bibtexKey(arg0 );
+ } break;
+ case 6: { // bool setFieldValue(long int,QString,QString)
+ long int arg0;
+ QString arg1;
+ QString arg2;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ if (arg.atEnd()) return false;
+ arg >> arg1;
+ if (arg.atEnd()) return false;
+ arg >> arg2;
+ replyType = CollectionInterface_ftable[6][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << setFieldValue(arg0, arg1, arg2 );
+ } break;
+ case 7: { // bool addFieldValue(long int,QString,QString)
+ long int arg0;
+ QString arg1;
+ QString arg2;
+ QDataStream arg( data, IO_ReadOnly );
+ if (arg.atEnd()) return false;
+ arg >> arg0;
+ if (arg.atEnd()) return false;
+ arg >> arg1;
+ if (arg.atEnd()) return false;
+ arg >> arg2;
+ replyType = CollectionInterface_ftable[7][0];
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << addFieldValue(arg0, arg1, arg2 );
+ } break;
+ default:
+ return DCOPObject::process( fun, data, replyType, replyData );
+ }
+ return true;
+}
+
+QCStringList CollectionInterface::interfaces()
+{
+ QCStringList ifaces = DCOPObject::interfaces();
+ ifaces += "Tellico::CollectionInterface";
+ return ifaces;
+}
+
+QCStringList CollectionInterface::functions()
+{
+ QCStringList funcs = DCOPObject::functions();
+ for ( int i = 0; CollectionInterface_ftable[i][2]; i++ ) {
+ if (CollectionInterface_ftable_hiddens[i])
+ continue;
+ QCString func = CollectionInterface_ftable[i][0];
+ func += ' ';
+ func += CollectionInterface_ftable[i][2];
+ funcs << func;
+ }
+ return funcs;
+}
+
+} // namespace
+
diff --git a/src/core/drophandler.cpp b/src/core/drophandler.cpp
new file mode 100644
index 0000000..e27df9d
--- /dev/null
+++ b/src/core/drophandler.cpp
@@ -0,0 +1,101 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "drophandler.h"
+#include "../mainwindow.h"
+#include "../tellico_kernel.h"
+#include "../tellico_debug.h"
+
+#include <kurldrag.h>
+#include <kmimetype.h>
+
+using Tellico::DropHandler;
+
+DropHandler::DropHandler(QObject* parent_) : QObject(parent_) {
+}
+
+DropHandler::~DropHandler() {
+}
+
+// assume the object is always the main window, that's the
+// only object with this event filter
+bool DropHandler::eventFilter(QObject* obj_, QEvent* ev_) {
+ Q_UNUSED(obj_);
+ if(ev_->type() == QEvent::DragEnter) {
+ return dragEnter(static_cast<QDragEnterEvent*>(ev_));
+ } else if(ev_->type() == QEvent::Drop) {
+ return drop(static_cast<QDropEvent*>(ev_));
+ }
+ return false;
+}
+
+bool DropHandler::dragEnter(QDragEnterEvent* event_) {
+ bool accept = KURLDrag::canDecode(event_) || QTextDrag::canDecode(event_);
+ if(accept) {
+ event_->accept(accept);
+ }
+ return accept;
+}
+
+bool DropHandler::drop(QDropEvent* event_) {
+ KURL::List urls;
+ QString text;
+
+ if(KURLDrag::decode(event_, urls)) {
+ } else if(QTextDrag::decode(event_, text) && !text.isEmpty()) {
+ urls << KURL(text);
+ }
+ return !urls.isEmpty() && handleURL(urls);
+}
+
+bool DropHandler::handleURL(const KURL::List& urls_) {
+ bool hasUnknown = false;
+ KURL::List tc, pdf, bib, ris;
+ for(KURL::List::ConstIterator it = urls_.begin(); it != urls_.end(); ++it) {
+ KMimeType::Ptr ptr = KMimeType::findByURL(*it);
+ if(ptr->is(QString::fromLatin1("application/x-tellico"))) {
+ tc << *it;
+ } else if(ptr->is(QString::fromLatin1("application/pdf"))) {
+ pdf << *it;
+ } else if(ptr->is(QString::fromLatin1("text/x-bibtex")) ||
+ ptr->is(QString::fromLatin1("application/x-bibtex"))) {
+ bib << *it;
+ } else if(ptr->is(QString::fromLatin1("application/x-research-info-systems"))) {
+ ris << *it;
+ } else {
+ myDebug() << "DropHandler::handleURL() - unrecognized type: " << ptr->name() << " (" << *it << ")" << endl;
+ hasUnknown = true;
+ }
+ }
+ MainWindow* mainWindow = ::qt_cast<MainWindow*>(Kernel::self()->widget());
+ if(!mainWindow) {
+ myDebug() << "DropHandler::handleURL() - no main window!" << endl;
+ return !hasUnknown;
+ }
+ if(!tc.isEmpty()) {
+ mainWindow->importFile(Import::TellicoXML, tc);
+ }
+ if(!pdf.isEmpty()) {
+ mainWindow->importFile(Import::PDF, pdf);
+ }
+ if(!bib.isEmpty()) {
+ mainWindow->importFile(Import::Bibtex, bib);
+ }
+ if(!ris.isEmpty()) {
+ mainWindow->importFile(Import::RIS, ris);
+ }
+ // any unknown urls get passed
+ return !hasUnknown;
+}
+
+#include "drophandler.moc"
diff --git a/src/core/drophandler.h b/src/core/drophandler.h
new file mode 100644
index 0000000..ac4d146
--- /dev/null
+++ b/src/core/drophandler.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_DROPHANDLER_H
+#define TELLICO_DROPHANDLER_H
+
+#include <qobject.h>
+#include <kurl.h>
+
+namespace Tellico {
+
+class DropHandler : public QObject {
+Q_OBJECT
+
+public:
+ DropHandler(QObject* parent);
+ ~DropHandler();
+
+protected:
+ bool eventFilter(QObject* object, QEvent* event);
+
+private:
+ bool dragEnter(QDragEnterEvent* event);
+ bool drop(QDropEvent* event);
+ bool handleURL(const KURL::List& urls);
+};
+
+}
+#endif
diff --git a/src/core/netaccess.cpp b/src/core/netaccess.cpp
new file mode 100644
index 0000000..77b6554
--- /dev/null
+++ b/src/core/netaccess.cpp
@@ -0,0 +1,100 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "netaccess.h"
+#include "../tellico_kernel.h"
+#include "../tellico_debug.h"
+
+#include <kdeversion.h>
+#include <kio/job.h>
+#include <kio/netaccess.h>
+#include <kio/scheduler.h>
+#include <kio/previewjob.h>
+#include <ktempfile.h>
+
+#include <qapplication.h>
+#include <qfile.h>
+
+#include <unistd.h> // for unlink()
+
+using Tellico::NetAccess;
+
+QStringList* NetAccess::s_tmpFiles = 0;
+
+bool NetAccess::download(const KURL& url_, QString& target_, QWidget* window_) {
+ if(url_.isLocalFile()) {
+ return KIO::NetAccess::download(url_, target_, window_);
+ }
+
+// if(!KIO::NetAccess::exists(url_, true, window_)) {
+// myDebug() << "NetAccess::download() - does not exist: " << url_ << endl;
+// return false;
+// }
+
+ if(target_.isEmpty()) {
+ KTempFile tmpFile;
+ target_ = tmpFile.name();
+ if(!s_tmpFiles) {
+ s_tmpFiles = new QStringList;
+ }
+ s_tmpFiles->append(target_);
+ }
+
+ KURL dest;
+ dest.setPath(target_);
+
+ KIO::Job* job = KIO::file_copy(url_, dest, -1, true /*overwrite*/, false /*resume*/, false /*showProgress*/);
+ return KIO::NetAccess::synchronousRun(job, window_);
+}
+
+void NetAccess::removeTempFile(const QString& name_) {
+ if(!s_tmpFiles) {
+ return;
+ }
+ if(s_tmpFiles->contains(name_)) {
+ ::unlink(QFile::encodeName(name_));
+ s_tmpFiles->remove(name_);
+ }
+}
+
+QPixmap NetAccess::filePreview(const KURL& url, int size) {
+ NetAccess netaccess;
+
+ KURL::List list;
+ list.append(url);
+ KIO::Job* previewJob = KIO::filePreview(list, size, size);
+ connect(previewJob, SIGNAL(gotPreview(const KFileItem*, const QPixmap&)),
+ &netaccess, SLOT(slotPreview(const KFileItem*, const QPixmap&)));
+
+ KIO::NetAccess::synchronousRun(previewJob, Kernel::self()->widget());
+ return netaccess.m_preview;
+}
+
+QPixmap NetAccess::filePreview(KFileItem* item, int size) {
+ NetAccess netaccess;
+
+ KFileItemList list;
+ list.append(item);
+ KIO::Job* previewJob = KIO::filePreview(list, size, size);
+ connect(previewJob, SIGNAL(gotPreview(const KFileItem*, const QPixmap&)),
+ &netaccess, SLOT(slotPreview(const KFileItem*, const QPixmap&)));
+
+ KIO::NetAccess::synchronousRun(previewJob, Kernel::self()->widget());
+ return netaccess.m_preview;
+}
+
+void NetAccess::slotPreview(const KFileItem*, const QPixmap& pix_) {
+ m_preview = pix_;
+}
+
+#include "netaccess.moc"
diff --git a/src/core/netaccess.h b/src/core/netaccess.h
new file mode 100644
index 0000000..df11e0d
--- /dev/null
+++ b/src/core/netaccess.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_NETACCESS_H
+#define TELLICO_NETACCESS_H
+
+#include <qobject.h>
+#include <qpixmap.h>
+
+class KURL;
+class KFileItem;
+namespace KIO {
+ class Job;
+}
+
+namespace Tellico {
+
+class NetAccess : public QObject {
+Q_OBJECT
+
+public:
+ static bool download(const KURL& u, QString& target, QWidget* window);
+ static void removeTempFile(const QString& name);
+ static QPixmap filePreview(const KURL& fileName, int size=196);
+ static QPixmap filePreview(KFileItem* item, int size=196);
+
+private slots:
+ void slotPreview(const KFileItem* item, const QPixmap& pix);
+
+private:
+ static QStringList* s_tmpFiles;
+
+ QPixmap m_preview;
+};
+
+}
+#endif
diff --git a/src/core/tellico-1-3-update.pl b/src/core/tellico-1-3-update.pl
new file mode 100644
index 0000000..9e5ad3b
--- /dev/null
+++ b/src/core/tellico-1-3-update.pl
@@ -0,0 +1,24 @@
+#!/usr/bin/env perl
+
+my $input;
+my $oldvalue;
+
+while( $input = <STDIN> )
+{
+ chop $input;
+
+ if( $input =~ /^Write Images In File\=(.*)/)
+ {
+ $oldvalue=$1;
+ if( $oldvalue eq "true" )
+ {
+ print "Image Location=ImagesInFile\n";
+ }
+ else
+ {
+ print "Image Location=ImageAppDir\n";
+ }
+ }
+}
+
+print "# DELETE [General Options]Write Images In File\n";
diff --git a/src/core/tellico-rename.upd b/src/core/tellico-rename.upd
new file mode 100644
index 0000000..5e3cb11
--- /dev/null
+++ b/src/core/tellico-rename.upd
@@ -0,0 +1,4 @@
+# move old bookcaserc file to tellicorc
+Id=tellico-rename
+File=bookcaserc,tellicorc
+AllGroups
diff --git a/src/core/tellico.upd b/src/core/tellico.upd
new file mode 100644
index 0000000..18d4220
--- /dev/null
+++ b/src/core/tellico.upd
@@ -0,0 +1,26 @@
+#
+# config updates for Tellico 0.14
+#
+Id=tellico-0.14
+File=tellicorc
+#
+Group=General Options
+RemoveKey=Geometry
+RemoveKey=Main Window Splitter Sizes
+RemoveKey=Show Count
+RemoveKey=Show Detail Widget
+RemoveKey=Show Toolbar
+RemoveKey=ToolBarPos
+#
+Group=Printing
+RemoveKey=Print Grouped Attribute
+RemoveKey=Print Fields - book
+#
+Group=ExportOptions
+Key=FormatAttributes,FormatFields
+#
+# config updates for Tellico 1.3
+Id=tellico-1.3
+File=tellicorc
+Options=overwrite
+Script=tellico-1-3-update.pl,perl
diff --git a/src/core/tellico_config.cpp b/src/core/tellico_config.cpp
new file mode 100644
index 0000000..f2050f0
--- /dev/null
+++ b/src/core/tellico_config.cpp
@@ -0,0 +1,455 @@
+// This file is generated by kconfig_compiler from tellico_config.kcfg.
+// All changes you do to this file will be lost.
+
+#include "tellico_config.h"
+
+#include <kstaticdeleter.h>
+
+using namespace Tellico;
+
+Config *Config::mSelf = 0;
+static KStaticDeleter<Config> staticConfigDeleter;
+
+Config *Config::self()
+{
+ if ( !mSelf ) {
+ staticConfigDeleter.setObject( mSelf, new Config() );
+ mSelf->readConfig();
+ }
+
+ return mSelf;
+}
+
+Config::Config( )
+ : KConfigSkeleton( QString::fromLatin1( "tellicorc" ) )
+{
+ mSelf = this;
+ setCurrentGroup( QString::fromLatin1( "TipOfDay" ) );
+
+ KConfigSkeleton::ItemBool *itemShowTipOfDay;
+ itemShowTipOfDay = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "RunOnStart" ), mShowTipOfDay, true );
+ addItem( itemShowTipOfDay, QString::fromLatin1( "showTipOfDay" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Main Window Options" ) );
+
+ QValueList<int> defaultMainSplitterSizes;
+
+ KConfigSkeleton::ItemIntList *itemMainSplitterSizes;
+ itemMainSplitterSizes = new KConfigSkeleton::ItemIntList( currentGroup(), QString::fromLatin1( "Main Splitter Sizes" ), mMainSplitterSizes, defaultMainSplitterSizes );
+ addItem( itemMainSplitterSizes, QString::fromLatin1( "MainSplitterSizes" ) );
+ QValueList<int> defaultSecondarySplitterSizes;
+
+ KConfigSkeleton::ItemIntList *itemSecondarySplitterSizes;
+ itemSecondarySplitterSizes = new KConfigSkeleton::ItemIntList( currentGroup(), QString::fromLatin1( "Secondary Splitter Sizes" ), mSecondarySplitterSizes, defaultSecondarySplitterSizes );
+ addItem( itemSecondarySplitterSizes, QString::fromLatin1( "SecondarySplitterSizes" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Detailed View Options" ) );
+
+ KConfigSkeleton::ItemInt *itemMaxPixmapWidth;
+ itemMaxPixmapWidth = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "MaxPixmapWidth" ), mMaxPixmapWidth, 50 );
+ addItem( itemMaxPixmapWidth, QString::fromLatin1( "MaxPixmapWidth" ) );
+ KConfigSkeleton::ItemInt *itemMaxPixmapHeight;
+ itemMaxPixmapHeight = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "MaxPixmapHeight" ), mMaxPixmapHeight, 50 );
+ addItem( itemMaxPixmapHeight, QString::fromLatin1( "MaxPixmapHeight" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Group View Options" ) );
+
+ KConfigSkeleton::ItemInt *itemGroupViewSortColumn;
+ itemGroupViewSortColumn = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "SortColumn" ), mGroupViewSortColumn, 0 );
+ addItem( itemGroupViewSortColumn, QString::fromLatin1( "groupViewSortColumn" ) );
+ KConfigSkeleton::ItemBool *itemGroupViewSortAscending;
+ itemGroupViewSortAscending = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "SortAscending" ), mGroupViewSortAscending, true );
+ addItem( itemGroupViewSortAscending, QString::fromLatin1( "groupViewSortAscending" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Filter View Options" ) );
+
+ KConfigSkeleton::ItemInt *itemFilterViewSortColumn;
+ itemFilterViewSortColumn = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "SortColumn" ), mFilterViewSortColumn, 0 );
+ addItem( itemFilterViewSortColumn, QString::fromLatin1( "filterViewSortColumn" ) );
+ KConfigSkeleton::ItemBool *itemFilterViewSortAscending;
+ itemFilterViewSortAscending = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "SortAscending" ), mFilterViewSortAscending, true );
+ addItem( itemFilterViewSortAscending, QString::fromLatin1( "filterViewSortAscending" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Loan View Options" ) );
+
+ KConfigSkeleton::ItemInt *itemLoanViewSortColumn;
+ itemLoanViewSortColumn = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "SortColumn" ), mLoanViewSortColumn, 0 );
+ addItem( itemLoanViewSortColumn, QString::fromLatin1( "loanViewSortColumn" ) );
+ KConfigSkeleton::ItemBool *itemLoanViewSortAscending;
+ itemLoanViewSortAscending = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "SortAscending" ), mLoanViewSortAscending, true );
+ addItem( itemLoanViewSortAscending, QString::fromLatin1( "loanViewSortAscending" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Export Options - Bibtex" ) );
+
+ KConfigSkeleton::ItemBool *itemUseBraces;
+ itemUseBraces = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "Use Braces" ), mUseBraces, true );
+ addItem( itemUseBraces, QString::fromLatin1( "UseBraces" ) );
+
+ setCurrentGroup( QString::fromLatin1( "General Options" ) );
+
+ KConfigSkeleton::ItemBool *itemShowGroupWidget;
+ itemShowGroupWidget = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "Show Group Widget" ), mShowGroupWidget, true );
+ addItem( itemShowGroupWidget, QString::fromLatin1( "ShowGroupWidget" ) );
+ KConfigSkeleton::ItemBool *itemShowEditWidget;
+ itemShowEditWidget = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "Show Edit Widget" ), mShowEditWidget, false );
+ addItem( itemShowEditWidget, QString::fromLatin1( "ShowEditWidget" ) );
+ KConfigSkeleton::ItemBool *itemShowEntryView;
+ itemShowEntryView = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "Show Entry View" ), mShowEntryView, true );
+ addItem( itemShowEntryView, QString::fromLatin1( "ShowEntryView" ) );
+ QValueList<KConfigSkeleton::ItemEnum::Choice> valuesImageLocation;
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "ImagesInFile" );
+ valuesImageLocation.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "ImagesInAppDir" );
+ valuesImageLocation.append( choice );
+ }
+ {
+ KConfigSkeleton::ItemEnum::Choice choice;
+ choice.name = QString::fromLatin1( "ImagesInLocalDir" );
+ valuesImageLocation.append( choice );
+ }
+ KConfigSkeleton::ItemEnum *itemImageLocation;
+ itemImageLocation = new KConfigSkeleton::ItemEnum( currentGroup(), QString::fromLatin1( "Image Location" ), mImageLocation, valuesImageLocation, ImagesInFile );
+ addItem( itemImageLocation, QString::fromLatin1( "ImageLocation" ) );
+ KConfigSkeleton::ItemBool *itemAskWriteImagesInFile;
+ itemAskWriteImagesInFile = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "Ask Write Images In File" ), mAskWriteImagesInFile, true );
+ addItem( itemAskWriteImagesInFile, QString::fromLatin1( "AskWriteImagesInFile" ) );
+ KConfigSkeleton::ItemBool *itemReopenLastFile;
+ itemReopenLastFile = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "Reopen Last File" ), mReopenLastFile, true );
+ addItem( itemReopenLastFile, QString::fromLatin1( "ReopenLastFile" ) );
+ KConfigSkeleton::ItemBool *itemAutoCapitalization;
+ itemAutoCapitalization = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "Auto Capitalization" ), mAutoCapitalization, true );
+ addItem( itemAutoCapitalization, QString::fromLatin1( "AutoCapitalization" ) );
+ KConfigSkeleton::ItemBool *itemAutoFormat;
+ itemAutoFormat = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "Auto Format" ), mAutoFormat, true );
+ addItem( itemAutoFormat, QString::fromLatin1( "AutoFormat" ) );
+ KConfigSkeleton::ItemString *itemLastOpenFile;
+ itemLastOpenFile = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Last Open File" ), mLastOpenFile );
+ addItem( itemLastOpenFile, QString::fromLatin1( "LastOpenFile" ) );
+ KConfigSkeleton::ItemString *itemNoCapitalizationString;
+ itemNoCapitalizationString = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "No Capitalization" ), mNoCapitalizationString, i18n("a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,up,with") );
+ addItem( itemNoCapitalizationString, QString::fromLatin1( "noCapitalizationString" ) );
+ KConfigSkeleton::ItemString *itemArticlesString;
+ itemArticlesString = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Articles" ), mArticlesString, i18n("the") );
+ addItem( itemArticlesString, QString::fromLatin1( "articlesString" ) );
+ KConfigSkeleton::ItemString *itemNameSuffixesString;
+ itemNameSuffixesString = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Name Suffixes" ), mNameSuffixesString, i18n("jr.,jr,iii,iv") );
+ addItem( itemNameSuffixesString, QString::fromLatin1( "nameSuffixesString" ) );
+ KConfigSkeleton::ItemString *itemSurnamePrefixesString;
+ itemSurnamePrefixesString = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Surname Prefixes" ), mSurnamePrefixesString, i18n("de,van,der,van der,von") );
+ addItem( itemSurnamePrefixesString, QString::fromLatin1( "surnamePrefixesString" ) );
+ KConfigSkeleton::ItemInt *itemMaxIconSize;
+ itemMaxIconSize = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "Max Icon Size" ), mMaxIconSize, 96 );
+ addItem( itemMaxIconSize, QString::fromLatin1( "MaxIconSize" ) );
+ KConfigSkeleton::ItemInt *itemImageCacheSize;
+ itemImageCacheSize = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "Image Cache Size" ), mImageCacheSize, (10 * 1024 * 1024) );
+ addItem( itemImageCacheSize, QString::fromLatin1( "ImageCacheSize" ) );
+ KConfigSkeleton::ItemUInt *itemMaxCustomURLSettings;
+ itemMaxCustomURLSettings = new KConfigSkeleton::ItemUInt( currentGroup(), QString::fromLatin1( "Max Custom URL Settings" ), mMaxCustomURLSettings, 9 );
+ addItem( itemMaxCustomURLSettings, QString::fromLatin1( "MaxCustomURLSettings" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Printing" ) );
+
+ KConfigSkeleton::ItemBool *itemPrintFieldHeaders;
+ itemPrintFieldHeaders = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "Print Field Headers" ), mPrintFieldHeaders, true );
+ addItem( itemPrintFieldHeaders, QString::fromLatin1( "PrintFieldHeaders" ) );
+ KConfigSkeleton::ItemBool *itemPrintFormatted;
+ itemPrintFormatted = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "Print Formatted" ), mPrintFormatted, true );
+ addItem( itemPrintFormatted, QString::fromLatin1( "PrintFormatted" ) );
+ KConfigSkeleton::ItemBool *itemPrintGrouped;
+ itemPrintGrouped = new KConfigSkeleton::ItemBool( currentGroup(), QString::fromLatin1( "Print Grouped" ), mPrintGrouped, true );
+ addItem( itemPrintGrouped, QString::fromLatin1( "PrintGrouped" ) );
+ KConfigSkeleton::ItemInt *itemMaxImageWidth;
+ itemMaxImageWidth = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "Max Image Width" ), mMaxImageWidth, 50 );
+ addItem( itemMaxImageWidth, QString::fromLatin1( "MaxImageWidth" ) );
+ KConfigSkeleton::ItemInt *itemMaxImageHeight;
+ itemMaxImageHeight = new KConfigSkeleton::ItemInt( currentGroup(), QString::fromLatin1( "Max Image Height" ), mMaxImageHeight, 50 );
+ addItem( itemMaxImageHeight, QString::fromLatin1( "MaxImageHeight" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Options - book" ) );
+
+ KConfigSkeleton::ItemString *itemTemplateBook;
+ itemTemplateBook = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Entry Template" ), mTemplateBook, QString::fromLatin1( "Fancy" ) );
+ addItem( itemTemplateBook, QString::fromLatin1( "templateBook" ) );
+ KConfigSkeleton::ItemFont *itemFontBook;
+ itemFontBook = new KConfigSkeleton::ItemFont( currentGroup(), QString::fromLatin1( "Template Font" ), mFontBook, KGlobalSettings::generalFont() );
+ addItem( itemFontBook, QString::fromLatin1( "fontBook" ) );
+ KConfigSkeleton::ItemColor *itemBaseColorBook;
+ itemBaseColorBook = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Base Color" ), mBaseColorBook, KGlobalSettings::baseColor() );
+ addItem( itemBaseColorBook, QString::fromLatin1( "baseColorBook" ) );
+ KConfigSkeleton::ItemColor *itemTextColorBook;
+ itemTextColorBook = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Text Color" ), mTextColorBook, KGlobalSettings::textColor() );
+ addItem( itemTextColorBook, QString::fromLatin1( "textColorBook" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedBaseColorBook;
+ itemHighlightedBaseColorBook = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlight Color" ), mHighlightedBaseColorBook, KGlobalSettings::highlightColor() );
+ addItem( itemHighlightedBaseColorBook, QString::fromLatin1( "highlightedBaseColorBook" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedTextColorBook;
+ itemHighlightedTextColorBook = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlighted Text Color" ), mHighlightedTextColorBook, KGlobalSettings::highlightedTextColor() );
+ addItem( itemHighlightedTextColorBook, QString::fromLatin1( "highlightedTextColorBook" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Options - video" ) );
+
+ KConfigSkeleton::ItemString *itemTemplateVideo;
+ itemTemplateVideo = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Entry Template" ), mTemplateVideo, QString::fromLatin1( "Video" ) );
+ addItem( itemTemplateVideo, QString::fromLatin1( "templateVideo" ) );
+ KConfigSkeleton::ItemFont *itemFontVideo;
+ itemFontVideo = new KConfigSkeleton::ItemFont( currentGroup(), QString::fromLatin1( "Template Font" ), mFontVideo, KGlobalSettings::generalFont() );
+ addItem( itemFontVideo, QString::fromLatin1( "fontVideo" ) );
+ KConfigSkeleton::ItemColor *itemBaseColorVideo;
+ itemBaseColorVideo = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Base Color" ), mBaseColorVideo, KGlobalSettings::baseColor() );
+ addItem( itemBaseColorVideo, QString::fromLatin1( "baseColorVideo" ) );
+ KConfigSkeleton::ItemColor *itemTextColorVideo;
+ itemTextColorVideo = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Text Color" ), mTextColorVideo, KGlobalSettings::textColor() );
+ addItem( itemTextColorVideo, QString::fromLatin1( "textColorVideo" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedBaseColorVideo;
+ itemHighlightedBaseColorVideo = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlight Color" ), mHighlightedBaseColorVideo, KGlobalSettings::highlightColor() );
+ addItem( itemHighlightedBaseColorVideo, QString::fromLatin1( "highlightedBaseColorVideo" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedTextColorVideo;
+ itemHighlightedTextColorVideo = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlighted Text Color" ), mHighlightedTextColorVideo, KGlobalSettings::highlightedTextColor() );
+ addItem( itemHighlightedTextColorVideo, QString::fromLatin1( "highlightedTextColorVideo" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Options - album" ) );
+
+ KConfigSkeleton::ItemString *itemTemplateAlbum;
+ itemTemplateAlbum = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Entry Template" ), mTemplateAlbum, QString::fromLatin1( "Album" ) );
+ addItem( itemTemplateAlbum, QString::fromLatin1( "templateAlbum" ) );
+ KConfigSkeleton::ItemFont *itemFontAlbum;
+ itemFontAlbum = new KConfigSkeleton::ItemFont( currentGroup(), QString::fromLatin1( "Template Font" ), mFontAlbum, KGlobalSettings::generalFont() );
+ addItem( itemFontAlbum, QString::fromLatin1( "fontAlbum" ) );
+ KConfigSkeleton::ItemColor *itemBaseColorAlbum;
+ itemBaseColorAlbum = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Base Color" ), mBaseColorAlbum, KGlobalSettings::baseColor() );
+ addItem( itemBaseColorAlbum, QString::fromLatin1( "baseColorAlbum" ) );
+ KConfigSkeleton::ItemColor *itemTextColorAlbum;
+ itemTextColorAlbum = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Text Color" ), mTextColorAlbum, KGlobalSettings::textColor() );
+ addItem( itemTextColorAlbum, QString::fromLatin1( "textColorAlbum" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedBaseColorAlbum;
+ itemHighlightedBaseColorAlbum = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlight Color" ), mHighlightedBaseColorAlbum, KGlobalSettings::highlightColor() );
+ addItem( itemHighlightedBaseColorAlbum, QString::fromLatin1( "highlightedBaseColorAlbum" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedTextColorAlbum;
+ itemHighlightedTextColorAlbum = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlighted Text Color" ), mHighlightedTextColorAlbum, KGlobalSettings::highlightedTextColor() );
+ addItem( itemHighlightedTextColorAlbum, QString::fromLatin1( "highlightedTextColorAlbum" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Options - bibtex" ) );
+
+ KConfigSkeleton::ItemPath *itemLyxpipe;
+ itemLyxpipe = new KConfigSkeleton::ItemPath( currentGroup(), QString::fromLatin1( "lyxpipe" ), mLyxpipe, QString::fromLatin1( "$HOME/.lyx/lyxpipe" ) );
+ addItem( itemLyxpipe, QString::fromLatin1( "lyxpipe" ) );
+ KConfigSkeleton::ItemString *itemTemplateBibtex;
+ itemTemplateBibtex = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Entry Template" ), mTemplateBibtex, QString::fromLatin1( "Fancy" ) );
+ addItem( itemTemplateBibtex, QString::fromLatin1( "templateBibtex" ) );
+ KConfigSkeleton::ItemFont *itemFontBibtex;
+ itemFontBibtex = new KConfigSkeleton::ItemFont( currentGroup(), QString::fromLatin1( "Template Font" ), mFontBibtex, KGlobalSettings::generalFont() );
+ addItem( itemFontBibtex, QString::fromLatin1( "fontBibtex" ) );
+ KConfigSkeleton::ItemColor *itemBaseColorBibtex;
+ itemBaseColorBibtex = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Base Color" ), mBaseColorBibtex, KGlobalSettings::baseColor() );
+ addItem( itemBaseColorBibtex, QString::fromLatin1( "baseColorBibtex" ) );
+ KConfigSkeleton::ItemColor *itemTextColorBibtex;
+ itemTextColorBibtex = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Text Color" ), mTextColorBibtex, KGlobalSettings::textColor() );
+ addItem( itemTextColorBibtex, QString::fromLatin1( "textColorBibtex" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedBaseColorBibtex;
+ itemHighlightedBaseColorBibtex = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlight Color" ), mHighlightedBaseColorBibtex, KGlobalSettings::highlightColor() );
+ addItem( itemHighlightedBaseColorBibtex, QString::fromLatin1( "highlightedBaseColorBibtex" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedTextColorBibtex;
+ itemHighlightedTextColorBibtex = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlighted Text Color" ), mHighlightedTextColorBibtex, KGlobalSettings::highlightedTextColor() );
+ addItem( itemHighlightedTextColorBibtex, QString::fromLatin1( "highlightedTextColorBibtex" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Options - comic" ) );
+
+ KConfigSkeleton::ItemString *itemTemplateComicBook;
+ itemTemplateComicBook = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Entry Template" ), mTemplateComicBook, QString::fromLatin1( "Fancy" ) );
+ addItem( itemTemplateComicBook, QString::fromLatin1( "templateComicBook" ) );
+ KConfigSkeleton::ItemFont *itemFontComicBook;
+ itemFontComicBook = new KConfigSkeleton::ItemFont( currentGroup(), QString::fromLatin1( "Template Font" ), mFontComicBook, KGlobalSettings::generalFont() );
+ addItem( itemFontComicBook, QString::fromLatin1( "fontComicBook" ) );
+ KConfigSkeleton::ItemColor *itemBaseColorComicBook;
+ itemBaseColorComicBook = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Base Color" ), mBaseColorComicBook, KGlobalSettings::baseColor() );
+ addItem( itemBaseColorComicBook, QString::fromLatin1( "baseColorComicBook" ) );
+ KConfigSkeleton::ItemColor *itemTextColorComicBook;
+ itemTextColorComicBook = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Text Color" ), mTextColorComicBook, KGlobalSettings::textColor() );
+ addItem( itemTextColorComicBook, QString::fromLatin1( "textColorComicBook" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedBaseColorComicBook;
+ itemHighlightedBaseColorComicBook = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlight Color" ), mHighlightedBaseColorComicBook, KGlobalSettings::highlightColor() );
+ addItem( itemHighlightedBaseColorComicBook, QString::fromLatin1( "highlightedBaseColorComicBook" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedTextColorComicBook;
+ itemHighlightedTextColorComicBook = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlighted Text Color" ), mHighlightedTextColorComicBook, KGlobalSettings::highlightedTextColor() );
+ addItem( itemHighlightedTextColorComicBook, QString::fromLatin1( "highlightedTextColorComicBook" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Options - wine" ) );
+
+ KConfigSkeleton::ItemString *itemTemplateWine;
+ itemTemplateWine = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Entry Template" ), mTemplateWine, QString::fromLatin1( "Fancy" ) );
+ addItem( itemTemplateWine, QString::fromLatin1( "templateWine" ) );
+ KConfigSkeleton::ItemFont *itemFontWine;
+ itemFontWine = new KConfigSkeleton::ItemFont( currentGroup(), QString::fromLatin1( "Template Font" ), mFontWine, KGlobalSettings::generalFont() );
+ addItem( itemFontWine, QString::fromLatin1( "fontWine" ) );
+ KConfigSkeleton::ItemColor *itemBaseColorWine;
+ itemBaseColorWine = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Base Color" ), mBaseColorWine, KGlobalSettings::baseColor() );
+ addItem( itemBaseColorWine, QString::fromLatin1( "baseColorWine" ) );
+ KConfigSkeleton::ItemColor *itemTextColorWine;
+ itemTextColorWine = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Text Color" ), mTextColorWine, KGlobalSettings::textColor() );
+ addItem( itemTextColorWine, QString::fromLatin1( "textColorWine" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedBaseColorWine;
+ itemHighlightedBaseColorWine = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlight Color" ), mHighlightedBaseColorWine, KGlobalSettings::highlightColor() );
+ addItem( itemHighlightedBaseColorWine, QString::fromLatin1( "highlightedBaseColorWine" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedTextColorWine;
+ itemHighlightedTextColorWine = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlighted Text Color" ), mHighlightedTextColorWine, KGlobalSettings::highlightedTextColor() );
+ addItem( itemHighlightedTextColorWine, QString::fromLatin1( "highlightedTextColorWine" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Options - coin" ) );
+
+ KConfigSkeleton::ItemString *itemTemplateCoin;
+ itemTemplateCoin = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Entry Template" ), mTemplateCoin, QString::fromLatin1( "Fancy" ) );
+ addItem( itemTemplateCoin, QString::fromLatin1( "templateCoin" ) );
+ KConfigSkeleton::ItemFont *itemFontCoin;
+ itemFontCoin = new KConfigSkeleton::ItemFont( currentGroup(), QString::fromLatin1( "Template Font" ), mFontCoin, KGlobalSettings::generalFont() );
+ addItem( itemFontCoin, QString::fromLatin1( "fontCoin" ) );
+ KConfigSkeleton::ItemColor *itemBaseColorCoin;
+ itemBaseColorCoin = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Base Color" ), mBaseColorCoin, KGlobalSettings::baseColor() );
+ addItem( itemBaseColorCoin, QString::fromLatin1( "baseColorCoin" ) );
+ KConfigSkeleton::ItemColor *itemTextColorCoin;
+ itemTextColorCoin = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Text Color" ), mTextColorCoin, KGlobalSettings::textColor() );
+ addItem( itemTextColorCoin, QString::fromLatin1( "textColorCoin" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedBaseColorCoin;
+ itemHighlightedBaseColorCoin = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlight Color" ), mHighlightedBaseColorCoin, KGlobalSettings::highlightColor() );
+ addItem( itemHighlightedBaseColorCoin, QString::fromLatin1( "highlightedBaseColorCoin" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedTextColorCoin;
+ itemHighlightedTextColorCoin = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlighted Text Color" ), mHighlightedTextColorCoin, KGlobalSettings::highlightedTextColor() );
+ addItem( itemHighlightedTextColorCoin, QString::fromLatin1( "highlightedTextColorCoin" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Options - stamp" ) );
+
+ KConfigSkeleton::ItemString *itemTemplateStamp;
+ itemTemplateStamp = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Entry Template" ), mTemplateStamp, QString::fromLatin1( "Fancy" ) );
+ addItem( itemTemplateStamp, QString::fromLatin1( "templateStamp" ) );
+ KConfigSkeleton::ItemFont *itemFontStamp;
+ itemFontStamp = new KConfigSkeleton::ItemFont( currentGroup(), QString::fromLatin1( "Template Font" ), mFontStamp, KGlobalSettings::generalFont() );
+ addItem( itemFontStamp, QString::fromLatin1( "fontStamp" ) );
+ KConfigSkeleton::ItemColor *itemBaseColorStamp;
+ itemBaseColorStamp = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Base Color" ), mBaseColorStamp, KGlobalSettings::baseColor() );
+ addItem( itemBaseColorStamp, QString::fromLatin1( "baseColorStamp" ) );
+ KConfigSkeleton::ItemColor *itemTextColorStamp;
+ itemTextColorStamp = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Text Color" ), mTextColorStamp, KGlobalSettings::textColor() );
+ addItem( itemTextColorStamp, QString::fromLatin1( "textColorStamp" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedBaseColorStamp;
+ itemHighlightedBaseColorStamp = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlight Color" ), mHighlightedBaseColorStamp, KGlobalSettings::highlightColor() );
+ addItem( itemHighlightedBaseColorStamp, QString::fromLatin1( "highlightedBaseColorStamp" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedTextColorStamp;
+ itemHighlightedTextColorStamp = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlighted Text Color" ), mHighlightedTextColorStamp, KGlobalSettings::highlightedTextColor() );
+ addItem( itemHighlightedTextColorStamp, QString::fromLatin1( "highlightedTextColorStamp" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Options - card" ) );
+
+ KConfigSkeleton::ItemString *itemTemplateCard;
+ itemTemplateCard = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Entry Template" ), mTemplateCard, QString::fromLatin1( "Fancy" ) );
+ addItem( itemTemplateCard, QString::fromLatin1( "templateCard" ) );
+ KConfigSkeleton::ItemFont *itemFontCard;
+ itemFontCard = new KConfigSkeleton::ItemFont( currentGroup(), QString::fromLatin1( "Template Font" ), mFontCard, KGlobalSettings::generalFont() );
+ addItem( itemFontCard, QString::fromLatin1( "fontCard" ) );
+ KConfigSkeleton::ItemColor *itemBaseColorCard;
+ itemBaseColorCard = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Base Color" ), mBaseColorCard, KGlobalSettings::baseColor() );
+ addItem( itemBaseColorCard, QString::fromLatin1( "baseColorCard" ) );
+ KConfigSkeleton::ItemColor *itemTextColorCard;
+ itemTextColorCard = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Text Color" ), mTextColorCard, KGlobalSettings::textColor() );
+ addItem( itemTextColorCard, QString::fromLatin1( "textColorCard" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedBaseColorCard;
+ itemHighlightedBaseColorCard = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlight Color" ), mHighlightedBaseColorCard, KGlobalSettings::highlightColor() );
+ addItem( itemHighlightedBaseColorCard, QString::fromLatin1( "highlightedBaseColorCard" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedTextColorCard;
+ itemHighlightedTextColorCard = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlighted Text Color" ), mHighlightedTextColorCard, KGlobalSettings::highlightedTextColor() );
+ addItem( itemHighlightedTextColorCard, QString::fromLatin1( "highlightedTextColorCard" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Options - game" ) );
+
+ KConfigSkeleton::ItemString *itemTemplateGame;
+ itemTemplateGame = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Entry Template" ), mTemplateGame, QString::fromLatin1( "Fancy" ) );
+ addItem( itemTemplateGame, QString::fromLatin1( "templateGame" ) );
+ KConfigSkeleton::ItemFont *itemFontGame;
+ itemFontGame = new KConfigSkeleton::ItemFont( currentGroup(), QString::fromLatin1( "Template Font" ), mFontGame, KGlobalSettings::generalFont() );
+ addItem( itemFontGame, QString::fromLatin1( "fontGame" ) );
+ KConfigSkeleton::ItemColor *itemBaseColorGame;
+ itemBaseColorGame = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Base Color" ), mBaseColorGame, KGlobalSettings::baseColor() );
+ addItem( itemBaseColorGame, QString::fromLatin1( "baseColorGame" ) );
+ KConfigSkeleton::ItemColor *itemTextColorGame;
+ itemTextColorGame = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Text Color" ), mTextColorGame, KGlobalSettings::textColor() );
+ addItem( itemTextColorGame, QString::fromLatin1( "textColorGame" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedBaseColorGame;
+ itemHighlightedBaseColorGame = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlight Color" ), mHighlightedBaseColorGame, KGlobalSettings::highlightColor() );
+ addItem( itemHighlightedBaseColorGame, QString::fromLatin1( "highlightedBaseColorGame" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedTextColorGame;
+ itemHighlightedTextColorGame = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlighted Text Color" ), mHighlightedTextColorGame, KGlobalSettings::highlightedTextColor() );
+ addItem( itemHighlightedTextColorGame, QString::fromLatin1( "highlightedTextColorGame" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Options - file" ) );
+
+ KConfigSkeleton::ItemString *itemTemplateFile;
+ itemTemplateFile = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Entry Template" ), mTemplateFile, QString::fromLatin1( "Fancy" ) );
+ addItem( itemTemplateFile, QString::fromLatin1( "templateFile" ) );
+ KConfigSkeleton::ItemFont *itemFontFile;
+ itemFontFile = new KConfigSkeleton::ItemFont( currentGroup(), QString::fromLatin1( "Template Font" ), mFontFile, KGlobalSettings::generalFont() );
+ addItem( itemFontFile, QString::fromLatin1( "fontFile" ) );
+ KConfigSkeleton::ItemColor *itemBaseColorFile;
+ itemBaseColorFile = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Base Color" ), mBaseColorFile, KGlobalSettings::baseColor() );
+ addItem( itemBaseColorFile, QString::fromLatin1( "baseColorFile" ) );
+ KConfigSkeleton::ItemColor *itemTextColorFile;
+ itemTextColorFile = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Text Color" ), mTextColorFile, KGlobalSettings::textColor() );
+ addItem( itemTextColorFile, QString::fromLatin1( "textColorFile" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedBaseColorFile;
+ itemHighlightedBaseColorFile = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlight Color" ), mHighlightedBaseColorFile, KGlobalSettings::highlightColor() );
+ addItem( itemHighlightedBaseColorFile, QString::fromLatin1( "highlightedBaseColorFile" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedTextColorFile;
+ itemHighlightedTextColorFile = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlighted Text Color" ), mHighlightedTextColorFile, KGlobalSettings::highlightedTextColor() );
+ addItem( itemHighlightedTextColorFile, QString::fromLatin1( "highlightedTextColorFile" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Options - boardgame" ) );
+
+ KConfigSkeleton::ItemString *itemTemplateBoardGame;
+ itemTemplateBoardGame = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Entry Template" ), mTemplateBoardGame, QString::fromLatin1( "Fancy" ) );
+ addItem( itemTemplateBoardGame, QString::fromLatin1( "templateBoardGame" ) );
+ KConfigSkeleton::ItemFont *itemFontBoardGame;
+ itemFontBoardGame = new KConfigSkeleton::ItemFont( currentGroup(), QString::fromLatin1( "Template Font" ), mFontBoardGame, KGlobalSettings::generalFont() );
+ addItem( itemFontBoardGame, QString::fromLatin1( "fontBoardGame" ) );
+ KConfigSkeleton::ItemColor *itemBaseColorBoardGame;
+ itemBaseColorBoardGame = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Base Color" ), mBaseColorBoardGame, KGlobalSettings::baseColor() );
+ addItem( itemBaseColorBoardGame, QString::fromLatin1( "baseColorBoardGame" ) );
+ KConfigSkeleton::ItemColor *itemTextColorBoardGame;
+ itemTextColorBoardGame = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Text Color" ), mTextColorBoardGame, KGlobalSettings::textColor() );
+ addItem( itemTextColorBoardGame, QString::fromLatin1( "textColorBoardGame" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedBaseColorBoardGame;
+ itemHighlightedBaseColorBoardGame = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlight Color" ), mHighlightedBaseColorBoardGame, KGlobalSettings::highlightColor() );
+ addItem( itemHighlightedBaseColorBoardGame, QString::fromLatin1( "highlightedBaseColorBoardGame" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedTextColorBoardGame;
+ itemHighlightedTextColorBoardGame = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlighted Text Color" ), mHighlightedTextColorBoardGame, KGlobalSettings::highlightedTextColor() );
+ addItem( itemHighlightedTextColorBoardGame, QString::fromLatin1( "highlightedTextColorBoardGame" ) );
+
+ setCurrentGroup( QString::fromLatin1( "Options - entry" ) );
+
+ KConfigSkeleton::ItemString *itemTemplateBase;
+ itemTemplateBase = new KConfigSkeleton::ItemString( currentGroup(), QString::fromLatin1( "Entry Template" ), mTemplateBase, QString::fromLatin1( "Fancy" ) );
+ addItem( itemTemplateBase, QString::fromLatin1( "templateBase" ) );
+ KConfigSkeleton::ItemFont *itemFontBase;
+ itemFontBase = new KConfigSkeleton::ItemFont( currentGroup(), QString::fromLatin1( "Template Font" ), mFontBase, KGlobalSettings::generalFont() );
+ addItem( itemFontBase, QString::fromLatin1( "fontBase" ) );
+ KConfigSkeleton::ItemColor *itemBaseColorBase;
+ itemBaseColorBase = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Base Color" ), mBaseColorBase, KGlobalSettings::baseColor() );
+ addItem( itemBaseColorBase, QString::fromLatin1( "baseColorBase" ) );
+ KConfigSkeleton::ItemColor *itemTextColorBase;
+ itemTextColorBase = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Text Color" ), mTextColorBase, KGlobalSettings::textColor() );
+ addItem( itemTextColorBase, QString::fromLatin1( "textColorBase" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedBaseColorBase;
+ itemHighlightedBaseColorBase = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlight Color" ), mHighlightedBaseColorBase, KGlobalSettings::highlightColor() );
+ addItem( itemHighlightedBaseColorBase, QString::fromLatin1( "highlightedBaseColorBase" ) );
+ KConfigSkeleton::ItemColor *itemHighlightedTextColorBase;
+ itemHighlightedTextColorBase = new KConfigSkeleton::ItemColor( currentGroup(), QString::fromLatin1( "Template Highlighted Text Color" ), mHighlightedTextColorBase, KGlobalSettings::highlightedTextColor() );
+ addItem( itemHighlightedTextColorBase, QString::fromLatin1( "highlightedTextColorBase" ) );
+}
+
+Config::~Config()
+{
+ if ( mSelf == this )
+ staticConfigDeleter.setObject( mSelf, 0, false );
+}
+
diff --git a/src/core/tellico_config.kcfg b/src/core/tellico_config.kcfg
new file mode 100644
index 0000000..8b4ed39
--- /dev/null
+++ b/src/core/tellico_config.kcfg
@@ -0,0 +1,477 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+
+<kcfgfile name="tellicorc"/>
+<include>klocale.h</include>
+
+<group name="TipOfDay">
+ <entry key="RunOnStart" type="Bool" name="showTipOfDay">
+ <default>true</default>
+ </entry>
+</group>
+
+<group name="Main Window Options">
+ <entry key="Main Splitter Sizes" type="IntList"/>
+ <entry key="Secondary Splitter Sizes" type="IntList"/>
+</group>
+
+<group name="Detailed View Options">
+ <entry key="MaxPixmapWidth" type="Int">
+ <default>50</default>
+ </entry>
+ <entry key="MaxPixmapHeight" type="Int">
+ <default>50</default>
+ </entry>
+</group>
+
+<group name="Group View Options">
+ <entry key="SortColumn" type="Int" name="groupViewSortColumn">
+ <default>0</default>
+ </entry>
+ <entry key="SortAscending" type="Bool" name="groupViewSortAscending">
+ <default>true</default>
+ </entry>
+</group>
+
+<group name="Filter View Options">
+ <entry key="SortColumn" type="Int" name="filterViewSortColumn">
+ <default>0</default>
+ </entry>
+ <entry key="SortAscending" type="Bool" name="filterViewSortAscending">
+ <default>true</default>
+ </entry>
+</group>
+
+<group name="Loan View Options">
+ <entry key="SortColumn" type="Int" name="loanViewSortColumn">
+ <default>0</default>
+ </entry>
+ <entry key="SortAscending" type="Bool" name="loanViewSortAscending">
+ <default>true</default>
+ </entry>
+</group>
+
+<group name="Export Options - Bibtex">
+ <entry key="Use Braces" type="Bool">
+ <default>true</default>
+ </entry>
+</group>
+
+<group name="General Options">
+ <entry key="Show Group Widget" type="Bool">
+ <default>true</default>
+ </entry>
+ <entry key="Show Edit Widget" type="Bool">
+ <default>false</default>
+ </entry>
+ <entry key="Show Entry View" type="Bool">
+ <default>true</default>
+ </entry>
+ <entry key="Image Location" type="Enum">
+ <choices>
+ <choice name="ImagesInFile"/>
+ <choice name="ImagesInAppDir"/>
+ <choice name="ImagesInLocalDir"/>
+ </choices>
+ <default>ImagesInFile</default>
+ </entry>
+ <entry key="Ask Write Images In File" type="Bool">
+ <default>true</default>
+ </entry>
+ <entry key="Reopen Last File" type="Bool">
+ <default>true</default>
+ </entry>
+ <entry key="Auto Capitalization" type="Bool">
+ <default>true</default>
+ </entry>
+ <entry key="Auto Format" type="Bool">
+ <default>true</default>
+ </entry>
+ <entry key="Last Open File" type="String"/>
+ <entry key="No Capitalization" name="noCapitalizationString" type="String">
+ <default code="true">i18n("a,an,and,as,at,but,by,for,from,in,into,nor,of,off,on,onto,or,out,over,the,to,up,with")</default>
+ </entry>
+ <entry key="Articles" name="articlesString" type="String">
+ <default code="true">i18n("the")</default>
+ </entry>
+ <entry key="Name Suffixes" name="nameSuffixesString" type="String">
+ <default code="true">i18n("jr.,jr,iii,iv")</default>
+ </entry>
+ <entry key="Surname Prefixes" name="surnamePrefixesString" type="String">
+ <default code="true">i18n("de,van,der,van der,von")</default>
+ </entry>
+ <entry key="Max Icon Size" type="Int">
+ <default>96</default>
+ </entry>
+ <entry key="Image Cache Size" type="Int">
+ <default code="true">(10 * 1024 * 1024)</default>
+ </entry>
+ <entry key="Max Custom URL Settings" type="UInt">
+ <default>9</default>
+ </entry>
+</group>
+
+<group name="Printing">
+ <entry key="Print Field Headers" type="Bool">
+ <default>true</default>
+ </entry>
+ <entry key="Print Formatted" type="Bool">
+ <default>true</default>
+ </entry>
+ <entry key="Print Grouped" type="Bool">
+ <default>true</default>
+ </entry>
+ <entry key="Max Image Width" type="Int">
+ <default>50</default>
+ </entry>
+ <entry key="Max Image Height" type="Int">
+ <default>50</default>
+ </entry>
+</group>
+
+<group name="Options - book">
+ <entry key="Entry Template" type="String" name="templateBook">
+ <default>Fancy</default>
+ </entry>
+ <entry key="Template Font" type="Font" name="fontBook">
+ <label>Template font</label>
+ <default code="true">KGlobalSettings::generalFont()</default>
+ </entry>
+ <entry key="Template Base Color" type="Color" name="baseColorBook">
+ <label>Template background color</label>
+ <default code="true">KGlobalSettings::baseColor()</default>
+ </entry>
+ <entry key="Template Text Color" type="Color" name="textColorBook">
+ <label>Template text color</label>
+ <default code="true">KGlobalSettings::textColor()</default>
+ </entry>
+ <entry key="Template Highlight Color" type="Color" name="highlightedBaseColorBook">
+ <label>Template highlight color</label>
+ <default code="true">KGlobalSettings::highlightColor()</default>
+ </entry>
+ <entry key="Template Highlighted Text Color" type="Color" name="highlightedTextColorBook">
+ <label>Template highlighted text color</label>
+ <default code="true">KGlobalSettings::highlightedTextColor()</default>
+ </entry>
+</group>
+
+<group name="Options - video">
+ <entry key="Entry Template" type="String" name="templateVideo">
+ <default>Video</default>
+ </entry>
+ <entry key="Template Font" type="Font" name="fontVideo">
+ <label>Template font</label>
+ <default code="true">KGlobalSettings::generalFont()</default>
+ </entry>
+ <entry key="Template Base Color" type="Color" name="baseColorVideo">
+ <label>Template background color</label>
+ <default code="true">KGlobalSettings::baseColor()</default>
+ </entry>
+ <entry key="Template Text Color" type="Color" name="textColorVideo">
+ <label>Template text color</label>
+ <default code="true">KGlobalSettings::textColor()</default>
+ </entry>
+ <entry key="Template Highlight Color" type="Color" name="highlightedBaseColorVideo">
+ <label>Template highlight color</label>
+ <default code="true">KGlobalSettings::highlightColor()</default>
+ </entry>
+ <entry key="Template Highlighted Text Color" type="Color" name="highlightedTextColorVideo">
+ <label>Template highlighted text color</label>
+ <default code="true">KGlobalSettings::highlightedTextColor()</default>
+ </entry>
+</group>
+
+<group name="Options - album">
+ <entry key="Entry Template" type="String" name="templateAlbum">
+ <default>Album</default>
+ </entry>
+ <entry key="Template Font" type="Font" name="fontAlbum">
+ <label>Template font</label>
+ <default code="true">KGlobalSettings::generalFont()</default>
+ </entry>
+ <entry key="Template Base Color" type="Color" name="baseColorAlbum">
+ <label>Template background color</label>
+ <default code="true">KGlobalSettings::baseColor()</default>
+ </entry>
+ <entry key="Template Text Color" type="Color" name="textColorAlbum">
+ <label>Template text color</label>
+ <default code="true">KGlobalSettings::textColor()</default>
+ </entry>
+ <entry key="Template Highlight Color" type="Color" name="highlightedBaseColorAlbum">
+ <label>Template highlight color</label>
+ <default code="true">KGlobalSettings::highlightColor()</default>
+ </entry>
+ <entry key="Template Highlighted Text Color" type="Color" name="highlightedTextColorAlbum">
+ <label>Template highlighted text color</label>
+ <default code="true">KGlobalSettings::highlightedTextColor()</default>
+ </entry>
+</group>
+
+<group name="Options - bibtex">
+ <entry key="lyxpipe" type="Path">
+ <default>$HOME/.lyx/lyxpipe</default>
+ </entry>
+ <entry key="Entry Template" type="String" name="templateBibtex">
+ <default>Fancy</default>
+ </entry>
+ <entry key="Template Font" type="Font" name="fontBibtex">
+ <label>Template font</label>
+ <default code="true">KGlobalSettings::generalFont()</default>
+ </entry>
+ <entry key="Template Base Color" type="Color" name="baseColorBibtex">
+ <label>Template background color</label>
+ <default code="true">KGlobalSettings::baseColor()</default>
+ </entry>
+ <entry key="Template Text Color" type="Color" name="textColorBibtex">
+ <label>Template text color</label>
+ <default code="true">KGlobalSettings::textColor()</default>
+ </entry>
+ <entry key="Template Highlight Color" type="Color" name="highlightedBaseColorBibtex">
+ <label>Template highlight color</label>
+ <default code="true">KGlobalSettings::highlightColor()</default>
+ </entry>
+ <entry key="Template Highlighted Text Color" type="Color" name="highlightedTextColorBibtex">
+ <label>Template highlighted text color</label>
+ <default code="true">KGlobalSettings::highlightedTextColor()</default>
+ </entry>
+</group>
+
+<group name="Options - comic">
+ <entry key="Entry Template" type="String" name="templateComicBook">
+ <default>Fancy</default>
+ </entry>
+ <entry key="Template Font" type="Font" name="fontComicBook">
+ <label>Template font</label>
+ <default code="true">KGlobalSettings::generalFont()</default>
+ </entry>
+ <entry key="Template Base Color" type="Color" name="baseColorComicBook">
+ <label>Template background color</label>
+ <default code="true">KGlobalSettings::baseColor()</default>
+ </entry>
+ <entry key="Template Text Color" type="Color" name="textColorComicBook">
+ <label>Template text color</label>
+ <default code="true">KGlobalSettings::textColor()</default>
+ </entry>
+ <entry key="Template Highlight Color" type="Color" name="highlightedBaseColorComicBook">
+ <label>Template highlight color</label>
+ <default code="true">KGlobalSettings::highlightColor()</default>
+ </entry>
+ <entry key="Template Highlighted Text Color" type="Color" name="highlightedTextColorComicBook">
+ <label>Template highlighted text color</label>
+ <default code="true">KGlobalSettings::highlightedTextColor()</default>
+ </entry>
+</group>
+
+<group name="Options - wine">
+ <entry key="Entry Template" type="String" name="templateWine">
+ <default>Fancy</default>
+ </entry>
+ <entry key="Template Font" type="Font" name="fontWine">
+ <label>Template font</label>
+ <default code="true">KGlobalSettings::generalFont()</default>
+ </entry>
+ <entry key="Template Base Color" type="Color" name="baseColorWine">
+ <label>Template background color</label>
+ <default code="true">KGlobalSettings::baseColor()</default>
+ </entry>
+ <entry key="Template Text Color" type="Color" name="textColorWine">
+ <label>Template text color</label>
+ <default code="true">KGlobalSettings::textColor()</default>
+ </entry>
+ <entry key="Template Highlight Color" type="Color" name="highlightedBaseColorWine">
+ <label>Template highlight color</label>
+ <default code="true">KGlobalSettings::highlightColor()</default>
+ </entry>
+ <entry key="Template Highlighted Text Color" type="Color" name="highlightedTextColorWine">
+ <label>Template highlighted text color</label>
+ <default code="true">KGlobalSettings::highlightedTextColor()</default>
+ </entry>
+</group>
+
+<group name="Options - coin">
+ <entry key="Entry Template" type="String" name="templateCoin">
+ <default>Fancy</default>
+ </entry>
+ <entry key="Template Font" type="Font" name="fontCoin">
+ <label>Template font</label>
+ <default code="true">KGlobalSettings::generalFont()</default>
+ </entry>
+ <entry key="Template Base Color" type="Color" name="baseColorCoin">
+ <label>Template background color</label>
+ <default code="true">KGlobalSettings::baseColor()</default>
+ </entry>
+ <entry key="Template Text Color" type="Color" name="textColorCoin">
+ <label>Template text color</label>
+ <default code="true">KGlobalSettings::textColor()</default>
+ </entry>
+ <entry key="Template Highlight Color" type="Color" name="highlightedBaseColorCoin">
+ <label>Template highlight color</label>
+ <default code="true">KGlobalSettings::highlightColor()</default>
+ </entry>
+ <entry key="Template Highlighted Text Color" type="Color" name="highlightedTextColorCoin">
+ <label>Template highlighted text color</label>
+ <default code="true">KGlobalSettings::highlightedTextColor()</default>
+ </entry>
+</group>
+
+<group name="Options - stamp">
+ <entry key="Entry Template" type="String" name="templateStamp">
+ <default>Fancy</default>
+ </entry>
+ <entry key="Template Font" type="Font" name="fontStamp">
+ <label>Template font</label>
+ <default code="true">KGlobalSettings::generalFont()</default>
+ </entry>
+ <entry key="Template Base Color" type="Color" name="baseColorStamp">
+ <label>Template background color</label>
+ <default code="true">KGlobalSettings::baseColor()</default>
+ </entry>
+ <entry key="Template Text Color" type="Color" name="textColorStamp">
+ <label>Template text color</label>
+ <default code="true">KGlobalSettings::textColor()</default>
+ </entry>
+ <entry key="Template Highlight Color" type="Color" name="highlightedBaseColorStamp">
+ <label>Template highlight color</label>
+ <default code="true">KGlobalSettings::highlightColor()</default>
+ </entry>
+ <entry key="Template Highlighted Text Color" type="Color" name="highlightedTextColorStamp">
+ <label>Template highlighted text color</label>
+ <default code="true">KGlobalSettings::highlightedTextColor()</default>
+ </entry>
+</group>
+
+<group name="Options - card">
+ <entry key="Entry Template" type="String" name="templateCard">
+ <default>Fancy</default>
+ </entry>
+ <entry key="Template Font" type="Font" name="fontCard">
+ <label>Template font</label>
+ <default code="true">KGlobalSettings::generalFont()</default>
+ </entry>
+ <entry key="Template Base Color" type="Color" name="baseColorCard">
+ <label>Template background color</label>
+ <default code="true">KGlobalSettings::baseColor()</default>
+ </entry>
+ <entry key="Template Text Color" type="Color" name="textColorCard">
+ <label>Template text color</label>
+ <default code="true">KGlobalSettings::textColor()</default>
+ </entry>
+ <entry key="Template Highlight Color" type="Color" name="highlightedBaseColorCard">
+ <label>Template highlight color</label>
+ <default code="true">KGlobalSettings::highlightColor()</default>
+ </entry>
+ <entry key="Template Highlighted Text Color" type="Color" name="highlightedTextColorCard">
+ <label>Template highlighted text color</label>
+ <default code="true">KGlobalSettings::highlightedTextColor()</default>
+ </entry>
+</group>
+
+<group name="Options - game">
+ <entry key="Entry Template" type="String" name="templateGame">
+ <default>Fancy</default>
+ </entry>
+ <entry key="Template Font" type="Font" name="fontGame">
+ <label>Template font</label>
+ <default code="true">KGlobalSettings::generalFont()</default>
+ </entry>
+ <entry key="Template Base Color" type="Color" name="baseColorGame">
+ <label>Template background color</label>
+ <default code="true">KGlobalSettings::baseColor()</default>
+ </entry>
+ <entry key="Template Text Color" type="Color" name="textColorGame">
+ <label>Template text color</label>
+ <default code="true">KGlobalSettings::textColor()</default>
+ </entry>
+ <entry key="Template Highlight Color" type="Color" name="highlightedBaseColorGame">
+ <label>Template highlight color</label>
+ <default code="true">KGlobalSettings::highlightColor()</default>
+ </entry>
+ <entry key="Template Highlighted Text Color" type="Color" name="highlightedTextColorGame">
+ <label>Template highlighted text color</label>
+ <default code="true">KGlobalSettings::highlightedTextColor()</default>
+ </entry>
+</group>
+
+<group name="Options - file">
+ <entry key="Entry Template" type="String" name="templateFile">
+ <default>Fancy</default>
+ </entry>
+ <entry key="Template Font" type="Font" name="fontFile">
+ <label>Template font</label>
+ <default code="true">KGlobalSettings::generalFont()</default>
+ </entry>
+ <entry key="Template Base Color" type="Color" name="baseColorFile">
+ <label>Template background color</label>
+ <default code="true">KGlobalSettings::baseColor()</default>
+ </entry>
+ <entry key="Template Text Color" type="Color" name="textColorFile">
+ <label>Template text color</label>
+ <default code="true">KGlobalSettings::textColor()</default>
+ </entry>
+ <entry key="Template Highlight Color" type="Color" name="highlightedBaseColorFile">
+ <label>Template highlight color</label>
+ <default code="true">KGlobalSettings::highlightColor()</default>
+ </entry>
+ <entry key="Template Highlighted Text Color" type="Color" name="highlightedTextColorFile">
+ <label>Template highlighted text color</label>
+ <default code="true">KGlobalSettings::highlightedTextColor()</default>
+ </entry>
+</group>
+
+<group name="Options - boardgame">
+ <entry key="Entry Template" type="String" name="templateBoardGame">
+ <default>Fancy</default>
+ </entry>
+ <entry key="Template Font" type="Font" name="fontBoardGame">
+ <label>Template font</label>
+ <default code="true">KGlobalSettings::generalFont()</default>
+ </entry>
+ <entry key="Template Base Color" type="Color" name="baseColorBoardGame">
+ <label>Template background color</label>
+ <default code="true">KGlobalSettings::baseColor()</default>
+ </entry>
+ <entry key="Template Text Color" type="Color" name="textColorBoardGame">
+ <label>Template text color</label>
+ <default code="true">KGlobalSettings::textColor()</default>
+ </entry>
+ <entry key="Template Highlight Color" type="Color" name="highlightedBaseColorBoardGame">
+ <label>Template highlight color</label>
+ <default code="true">KGlobalSettings::highlightColor()</default>
+ </entry>
+ <entry key="Template Highlighted Text Color" type="Color" name="highlightedTextColorBoardGame">
+ <label>Template highlighted text color</label>
+ <default code="true">KGlobalSettings::highlightedTextColor()</default>
+ </entry>
+</group>
+
+<group name="Options - entry">
+ <entry key="Entry Template" type="String" name="templateBase">
+ <default>Fancy</default>
+ </entry>
+ <entry key="Template Font" type="Font" name="fontBase">
+ <label>Template font</label>
+ <default code="true">KGlobalSettings::generalFont()</default>
+ </entry>
+ <entry key="Template Base Color" type="Color" name="baseColorBase">
+ <label>Template background color</label>
+ <default code="true">KGlobalSettings::baseColor()</default>
+ </entry>
+ <entry key="Template Text Color" type="Color" name="textColorBase">
+ <label>Template text color</label>
+ <default code="true">KGlobalSettings::textColor()</default>
+ </entry>
+ <entry key="Template Highlight Color" type="Color" name="highlightedBaseColorBase">
+ <label>Template highlight color</label>
+ <default code="true">KGlobalSettings::highlightColor()</default>
+ </entry>
+ <entry key="Template Highlighted Text Color" type="Color" name="highlightedTextColorBase">
+ <label>Template highlighted text color</label>
+ <default code="true">KGlobalSettings::highlightedTextColor()</default>
+ </entry>
+</group>
+
+</kcfg>
diff --git a/src/core/tellico_config.kcfgc b/src/core/tellico_config.kcfgc
new file mode 100644
index 0000000..7cf7c9c
--- /dev/null
+++ b/src/core/tellico_config.kcfgc
@@ -0,0 +1,9 @@
+# Code generation options for kconfig_compiler
+File=tellico_config.kcfg
+ClassName=Config
+NameSpace=Tellico
+Singleton=true
+Mutators=true
+MemberVariables=private
+CustomAdditions=true
+GlobalEnums=true
diff --git a/src/core/tellico_config_addons.cpp b/src/core/tellico_config_addons.cpp
new file mode 100644
index 0000000..9b388d5
--- /dev/null
+++ b/src/core/tellico_config_addons.cpp
@@ -0,0 +1,171 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "tellico_config.h"
+#include "../collection.h"
+
+#define COLL Data::Collection::
+#define CLASS Config::
+#define P1 (
+#define P2 )
+#define CASE1(a,b) case COLL b: return CLASS a ## b P1 P2;
+#define CASE2(a,b,c) case COLL b: CLASS a ## b P1 c P2; break;
+#define GET(name,type) \
+ CASE1(name,type)
+#define SET(name,type,value) \
+ CASE2(name,type,value)
+#define ALL_GET(name) \
+ GET(name, Base) \
+ GET(name, Book) \
+ GET(name, Video) \
+ GET(name, Album) \
+ GET(name, Bibtex) \
+ GET(name, ComicBook) \
+ GET(name, Wine) \
+ GET(name, Coin) \
+ GET(name, Stamp) \
+ GET(name, Card) \
+ GET(name, Game) \
+ GET(name, File) \
+ GET(name, BoardGame)
+#define ALL_SET(name,value) \
+ SET(name, Base, value) \
+ SET(name, Book, value) \
+ SET(name, Video, value) \
+ SET(name, Album, value) \
+ SET(name, Bibtex, value) \
+ SET(name, ComicBook, value) \
+ SET(name, Wine, value) \
+ SET(name, Coin, value) \
+ SET(name, Stamp, value) \
+ SET(name, Card, value) \
+ SET(name, Game, value) \
+ SET(name, File, value) \
+ SET(name, BoardGame, value)
+
+namespace {
+ static const QRegExp commaSplit = QRegExp(QString::fromLatin1("\\s*,\\s*"));
+}
+
+using Tellico::Config;
+
+void Config::deleteAndReset() {
+ delete mSelf;
+ mSelf = 0;
+}
+
+QStringList Config::noCapitalizationList() {
+ return QStringList::split(commaSplit, Config::noCapitalizationString());
+}
+
+QStringList Config::articleList() {
+ return QStringList::split(commaSplit, Config::articlesString());
+}
+
+QStringList Config::nameSuffixList() {
+ return QStringList::split(commaSplit, Config::nameSuffixesString());
+}
+
+QStringList Config::surnamePrefixList() {
+ return QStringList::split(commaSplit, Config::surnamePrefixesString());
+}
+
+
+QString Config::templateName(int type_) {
+ switch(type_) {
+ ALL_GET(template);
+ }
+ return QString();
+}
+
+QFont Config::templateFont(int type_) {
+ switch(type_) {
+ ALL_GET(font);
+ }
+ return QFont();
+}
+
+QColor Config::templateBaseColor(int type_) {
+ switch(type_) {
+ ALL_GET(baseColor)
+ }
+ return QColor();
+}
+
+QColor Config::templateTextColor(int type_) {
+ switch(type_) {
+ ALL_GET(textColor)
+ }
+ return QColor();
+}
+
+QColor Config::templateHighlightedBaseColor(int type_) {
+ switch(type_) {
+ ALL_GET(highlightedBaseColor)
+ }
+ return QColor();
+}
+
+QColor Config::templateHighlightedTextColor(int type_) {
+ switch(type_) {
+ ALL_GET(highlightedTextColor)
+ }
+ return QColor();
+}
+
+void Config::setTemplateName(int type_, const QString& name_) {
+ switch(type_) {
+ ALL_SET(setTemplate,name_)
+ }
+}
+
+void Config::setTemplateFont(int type_, const QFont& font_) {
+ switch(type_) {
+ ALL_SET(setFont,font_)
+ }
+}
+
+void Config::setTemplateBaseColor(int type_, const QColor& color_) {
+ switch(type_) {
+ ALL_SET(setBaseColor,color_)
+ }
+}
+
+void Config::setTemplateTextColor(int type_, const QColor& color_) {
+ switch(type_) {
+ ALL_SET(setTextColor,color_)
+ }
+}
+
+void Config::setTemplateHighlightedBaseColor(int type_, const QColor& color_) {
+ switch(type_) {
+ ALL_SET(setHighlightedBaseColor,color_)
+ }
+}
+
+void Config::setTemplateHighlightedTextColor(int type_, const QColor& color_) {
+ switch(type_) {
+ ALL_SET(setHighlightedTextColor,color_)
+ }
+}
+
+#undef COLL
+#undef CLASS
+#undef P1
+#undef P2
+#undef CASE1
+#undef CASE2
+#undef GET
+#undef SET
+#undef ALL_GET
+#undef ALL_SET
diff --git a/src/core/tellico_config_addons.h b/src/core/tellico_config_addons.h
new file mode 100644
index 0000000..7573257
--- /dev/null
+++ b/src/core/tellico_config_addons.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+// this file gets included by tellico_config.h
+
+public:
+ static void deleteAndReset();
+
+ static QStringList noCapitalizationList();
+ static QStringList articleList();
+ static QStringList nameSuffixList();
+ static QStringList surnamePrefixList();
+
+ static QString templateName(int type);
+ static QFont templateFont(int type);
+ static QColor templateBaseColor(int type);
+ static QColor templateTextColor(int type);
+ static QColor templateHighlightedBaseColor(int type);
+ static QColor templateHighlightedTextColor(int type);
+
+ static void setTemplateName(int type, const QString& name);
+ static void setTemplateFont(int type, const QFont& font);
+ static void setTemplateBaseColor(int type, const QColor& color);
+ static void setTemplateTextColor(int type, const QColor& color);
+ static void setTemplateHighlightedBaseColor(int type, const QColor& color);
+ static void setTemplateHighlightedTextColor(int type, const QColor& color);
diff --git a/src/datavectors.h b/src/datavectors.h
new file mode 100644
index 0000000..9dd8257
--- /dev/null
+++ b/src/datavectors.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef DATA_VECTORS_H
+#define DATA_VECTORS_H
+
+#include "ptrvector.h"
+
+#include <qmap.h>
+#include <qpair.h>
+
+#include <ksharedptr.h>
+
+namespace Tellico {
+ typedef QMap<QString, QString> StringMap;
+
+ class Filter;
+ typedef KSharedPtr<Filter> FilterPtr;
+ typedef Vector<Filter> FilterVec;
+
+ namespace Data {
+ class Collection;
+ typedef KSharedPtr<Collection> CollPtr;
+ typedef KSharedPtr<const Collection> ConstCollPtr;
+ typedef Vector<Collection> CollVec;
+
+ class Field;
+ typedef KSharedPtr<Field> FieldPtr;
+ typedef KSharedPtr<const Field> ConstFieldPtr;
+ typedef Vector<Field> FieldVec;
+ typedef FieldVec::Iterator FieldVecIt;
+// typedef Vector<ConstFieldPtr> ConstFieldVec;
+
+ class Entry;
+ typedef KSharedPtr<Entry> EntryPtr;
+ typedef KSharedPtr<const Entry> ConstEntryPtr;
+ typedef Vector<Entry> EntryVec;
+ typedef EntryVec::Iterator EntryVecIt;
+ typedef Vector<const Entry> ConstEntryVec;
+ // complicated, I know
+ // first item is a vector of all entries that got added in the merge process
+ // second item is a pair of entries that had their track field modified
+ // since a music collection is the only one that would actually merge entries
+ typedef QValueVector< QPair<EntryPtr, QString> > PairVector;
+ typedef QPair<Data::EntryVec, PairVector> MergePair;
+
+ class Borrower;
+ typedef KSharedPtr<Borrower> BorrowerPtr;
+ typedef Vector<Borrower> BorrowerVec;
+ }
+}
+
+#endif
diff --git a/src/detailedentryitem.cpp b/src/detailedentryitem.cpp
new file mode 100644
index 0000000..0a71f25
--- /dev/null
+++ b/src/detailedentryitem.cpp
@@ -0,0 +1,127 @@
+/***************************************************************************
+ copyright : (C) 2005-2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "detailedentryitem.h"
+#include "detailedlistview.h"
+#include "collection.h"
+#include "entry.h"
+#include "tellico_utils.h"
+#include "latin1literal.h"
+
+#include <klocale.h>
+#include <kstringhandler.h>
+
+#include <qpainter.h>
+#include <qheader.h>
+#include <qdatetime.h>
+#include <qtimer.h>
+
+namespace {
+ static const short ENTRY_MAX_MINUTES_MESSAGE = 5;
+}
+
+using Tellico::DetailedEntryItem;
+
+DetailedEntryItem::DetailedEntryItem(DetailedListView* parent_, Data::EntryPtr entry_)
+ : EntryItem(parent_, entry_), m_state(Normal), m_time(0), m_timer(0) {
+}
+
+DetailedEntryItem::~DetailedEntryItem() {
+ delete m_time;
+ m_time = 0;
+ delete m_timer;
+ m_timer = 0;
+}
+
+void DetailedEntryItem::setState(State state_) {
+ if(m_state == state_) {
+ return;
+ }
+ m_state = state_;
+
+ if(m_state == Normal) {
+ delete m_time;
+ m_time = 0;
+ delete m_timer;
+ m_timer = 0;
+ } else {
+ if(!m_time) {
+ m_time = new QTime;
+ }
+ m_time->start();
+
+ if(!m_timer) {
+ m_timer = new QTimer();
+ m_timer->connect(m_timer, SIGNAL(timeout()), listView(), SLOT(triggerUpdate()));
+ }
+ m_timer->start(30 * 1000); // every 30 seconds
+ }
+
+ // have to put this in a timer, or it doesn't update properly
+ QTimer::singleShot(500, listView(), SLOT(triggerUpdate()));
+}
+
+void DetailedEntryItem::paintCell(QPainter* p_, const QColorGroup& cg_,
+ int column_, int width_, int align_) {
+ if(m_state == Normal) {
+ EntryItem::paintCell(p_, cg_, column_, width_, align_);
+ return;
+ }
+
+ int t = m_time->elapsed()/(60 * 1000);
+ if(t > ENTRY_MAX_MINUTES_MESSAGE) {
+ setState(Normal);
+ t = 0;
+ }
+
+ QFont f = p_->font();
+ f.setBold(true);
+ if(m_state == New) {
+ f.setItalic(true);
+ }
+ p_->setFont(f);
+
+ // taken from ListViewItem, but without line drawn to right of cell
+ QColorGroup cg = cg_;
+ const QPixmap* pm = listView()->viewport()->backgroundPixmap();
+ if(pm && !pm->isNull()) {
+ cg.setBrush(QColorGroup::Base, QBrush(backgroundColor(column_), *pm));
+ QPoint o = p_->brushOrigin();
+ p_->setBrushOrigin(o.x()-listView()->contentsX(), o.y()-listView()->contentsY());
+ } else {
+ cg.setColor(listView()->viewport()->backgroundMode() == Qt::FixedColor ?
+ QColorGroup::Background : QColorGroup::Base,
+ backgroundColor(column_));
+ }
+ // don't call KListViewItem::paintCell() since that also does alternate painting, etc...
+ QListViewItem::paintCell(p_, cg, column_, width_, align_);
+}
+
+QColor DetailedEntryItem::backgroundColor(int column_) {
+ GUI::ListView* lv = listView();
+ if(!lv || m_state == Normal || isSelected()) {
+ return EntryItem::backgroundColor(column_);
+ }
+ int t = m_time->elapsed()/(60 * 1000);
+ if(t > ENTRY_MAX_MINUTES_MESSAGE) {
+ return EntryItem::backgroundColor(column_);
+ }
+ return blendColors(lv->colorGroup().highlight(),
+ lv->colorGroup().base(),
+ 80 + 20*t/ENTRY_MAX_MINUTES_MESSAGE /* percent */);
+ // no more than 20% of highlight color
+}
+
+void DetailedEntryItem::paintFocus(QPainter*, const QColorGroup&, const QRect&) {
+// don't paint anything
+}
diff --git a/src/detailedentryitem.h b/src/detailedentryitem.h
new file mode 100644
index 0000000..50f0671
--- /dev/null
+++ b/src/detailedentryitem.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ copyright : (C) 2005-2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_DETAILEDENTRYITEM_H
+#define TELLICO_DETAILEDENTRYITEM_H
+
+class QTime;
+class QTimer;
+
+#include "entryitem.h"
+
+namespace Tellico {
+
+class DetailedListView;
+
+/**
+ * @author Robby Stephenson
+ */
+class DetailedEntryItem : public EntryItem {
+public:
+ enum State { Normal, New, Modified };
+
+ DetailedEntryItem(DetailedListView* parent, Data::EntryPtr entry);
+ ~DetailedEntryItem();
+
+ void setState(State state);
+
+ virtual QColor backgroundColor(int column);
+ virtual void paintCell(QPainter* p, const QColorGroup& cg,
+ int column, int width, int align);
+
+private:
+ /**
+ * Paints a focus indicator on the rectangle (current item). Disable for current items.
+ */
+ void paintFocus(QPainter*, const QColorGroup&, const QRect&);
+
+ State m_state;
+ QTime* m_time;
+ QTimer* m_timer;
+};
+
+}
+
+#endif
diff --git a/src/detailedlistview.cpp b/src/detailedlistview.cpp
new file mode 100644
index 0000000..5c4e2d2
--- /dev/null
+++ b/src/detailedlistview.cpp
@@ -0,0 +1,894 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "detailedlistview.h"
+#include "detailedentryitem.h"
+#include "collection.h"
+#include "imagefactory.h"
+#include "controller.h"
+#include "field.h"
+#include "entry.h"
+#include "gui/ratingwidget.h"
+#include "tellico_debug.h"
+#include "tellico_kernel.h"
+#include "core/tellico_config.h"
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kapplication.h>
+#include <kaction.h>
+#include <kiconloader.h>
+#include <kpopupmenu.h>
+
+#include <qptrlist.h>
+#include <qstringlist.h>
+#include <qvaluelist.h>
+#include <qheader.h>
+
+namespace {
+ static const int MIN_COL_WIDTH = 50;
+}
+
+using Tellico::DetailedListView;
+
+DetailedListView::DetailedListView(QWidget* parent_, const char* name_/*=0*/)
+ : GUI::ListView(parent_, name_), m_filter(0),
+ m_prevSortColumn(-1), m_prev2SortColumn(-1), m_firstSection(-1),
+ m_pixWidth(50), m_pixHeight(50) {
+// myDebug() << "DetailedListView()" << endl;
+ setAllColumnsShowFocus(true);
+ setShowSortIndicator(true);
+ setShadeSortColumn(true);
+
+// connect(this, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()));
+ connect(this, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)),
+ SLOT(contextMenuRequested(QListViewItem*, const QPoint&, int)));
+ connect(header(), SIGNAL(indexChange(int, int, int)),
+ SLOT(slotUpdatePixmap()));
+
+ // header menu
+ header()->setClickEnabled(true);
+ header()->installEventFilter(this);
+ connect(header(), SIGNAL(sizeChange(int, int, int)),
+ this, SLOT(slotCacheColumnWidth(int, int, int)));
+
+ m_headerMenu = new KPopupMenu(this);
+ m_headerMenu->setCheckable(true);
+ m_headerMenu->insertTitle(i18n("View Columns"));
+ connect(m_headerMenu, SIGNAL(activated(int)),
+ this, SLOT(slotHeaderMenuActivated(int)));
+
+ m_checkPix = UserIcon(QString::fromLatin1("checkmark"));
+}
+
+DetailedListView::~DetailedListView() {
+}
+
+void DetailedListView::addCollection(Data::CollPtr coll_) {
+ if(!coll_) {
+ return;
+ }
+
+ m_imageColumns.clear();
+// myDebug() << "DetailedListView::addCollection()" << endl;
+
+ KConfigGroup config(kapp->config(), QString::fromLatin1("Options - %1").arg(coll_->typeName()));
+
+ QString configN;
+ if(coll_->type() == Data::Collection::Base) {
+ KURL url = Kernel::self()->URL();
+ for(uint i = 0; i < Config::maxCustomURLSettings(); ++i) {
+ KURL u = config.readEntry(QString::fromLatin1("URL_%1").arg(i));
+ if(u == url) {
+ configN = QString::fromLatin1("_%1").arg(i);
+ break;
+ }
+ }
+ }
+
+ QStringList colNames = config.readListEntry("ColumnNames" + configN);
+ if(colNames.isEmpty()) {
+ colNames = QString::fromLatin1("title");
+ }
+
+ // this block compensates for the chance that the user added a field and it wasn't
+ // written to the widths. Also compensates for 0.5.x to 0.6.x column layout changes
+ QValueList<int> colWidths = config.readIntListEntry("ColumnWidths" + configN);
+ if(colWidths.empty()) {
+ colWidths.insert(colWidths.begin(), colNames.count(), -1); // automatic width
+ }
+
+ QValueList<int> colOrder = config.readIntListEntry("ColumnOrder" + configN);
+
+ // need to remove values for fields which don't exist in the current collection
+ QStringList newCols;
+ QValueList<int> newWidths, removeCols;
+ for(uint i = 0; i < colNames.count(); ++i) {
+ if(!colNames[i].isEmpty() && coll_->hasField(colNames[i])) {
+ newCols += colNames[i];
+ newWidths += colWidths[i];
+ } else {
+ removeCols += i;
+ }
+ }
+ colNames = newCols;
+ colWidths = newWidths;
+
+ qHeapSort(removeCols);
+ // now need to shift values in the order if any columns were removed
+ // only need to shift by number of "holes"
+ QValueList<int> newOrder;
+ for(QValueList<int>::ConstIterator it = colOrder.begin(); it != colOrder.end(); ++it) {
+ if(removeCols.findIndex(*it) == -1) {
+ int i = *it;
+ for(uint j = 0; j < removeCols.count() && removeCols[j] < i; ++j) {
+ --i;
+ }
+ newOrder += i;
+ }
+ }
+ colOrder = newOrder;
+
+ bool none = true;
+ Data::FieldVec fields = coll_->fields();
+ for(Data::FieldVec::Iterator fIt = fields.begin(); fIt != fields.end(); ++fIt) {
+ if(colNames.findIndex(fIt->name()) > -1 && colWidths.count() > 0) {
+ addField(fIt, colWidths.front());
+ if(none && colWidths.front() != 0) {
+ none = false;
+ }
+ colWidths.pop_front();
+ } else {
+ addField(fIt, 0);
+ }
+ }
+ if(none && columns() > 0 && !colNames.isEmpty()) {
+ showColumn(coll_->fieldNames().findIndex(colNames[0]));
+ }
+
+ QValueList<int>::ConstIterator it = colOrder.begin();
+ for(int i = 0; it != colOrder.end(); ++it) {
+ header()->moveSection(i++, *it);
+ }
+ slotUpdatePixmap();
+
+ int sortCol = config.readNumEntry("SortColumn" + configN, 0);
+ bool sortAsc = config.readBoolEntry("SortAscending" + configN, true);
+ setSorting(sortCol, sortAsc);
+ int prevSortCol = config.readNumEntry("PrevSortColumn" + configN, -1);
+ int prev2SortCol = config.readNumEntry("Prev2SortColumn" + configN, -1);
+ setPrevSortedColumn(prevSortCol, prev2SortCol);
+
+ triggerUpdate();
+ kapp->processEvents();
+ setUpdatesEnabled(false);
+
+ m_loadingCollection = true;
+ Data::EntryVec entries = coll_->entries();
+ for(Data::EntryVecIt entry = entries.begin(); entry != entries.end(); ++entry) {
+ addEntryInternal(entry);
+ }
+ m_loadingCollection = false;
+
+ setUpdatesEnabled(true);
+ triggerUpdate();
+}
+
+void DetailedListView::slotReset() {
+// myDebug() << "DetailedListView::slotReset()" << endl;
+ //clear() does not remove columns
+ clear();
+// while(columns() > 0) {
+// removeColumn(0);
+// }
+ m_filter = 0;
+}
+
+void DetailedListView::addEntries(Data::EntryVec entries_) {
+ if(entries_.isEmpty()) {
+ return;
+ }
+
+// myDebug() << "DetailedListView::addEntry() - " << entry_->title() << endl;
+
+ DetailedEntryItem* item = 0;
+ for(Data::EntryVecIt entry = entries_.begin(); entry != entries_.end(); ++entry) {
+ item = addEntryInternal(entry);
+ item->setState(DetailedEntryItem::New);
+ item->setVisible(!m_filter || m_filter->matches(entry.data()));
+ }
+
+ if(isUpdatesEnabled() && item && item->isVisible()) {
+ sort();
+ ensureItemVisible(item);
+ setCurrentItem(item);
+ if(!selectedItems().isEmpty()) {
+ blockSignals(true);
+ clearSelection();
+ setSelected(item, true);
+ blockSignals(false);
+ }
+ } else {
+ triggerUpdate();
+ }
+}
+
+Tellico::DetailedEntryItem* DetailedListView::addEntryInternal(Data::EntryPtr entry_) {
+ if(m_entryPix.isNull()) {
+ m_entryPix = UserIcon(entry_->collection()->typeName());
+ if(m_entryPix.isNull()) {
+ kdWarning() << "DetailedListView::addEntryInternal() - can't find entry pix" << endl;
+ }
+ }
+
+ DetailedEntryItem* item = new DetailedEntryItem(this, entry_);
+ populateItem(item);
+ return item;
+}
+
+void DetailedListView::modifyEntries(Data::EntryVec entries_) {
+ if(entries_.isEmpty()) {
+ return;
+ }
+
+ DetailedEntryItem* item = 0;
+ for(Data::EntryVecIt entry = entries_.begin(); entry != entries_.end(); ++entry) {
+ item = locateItem(entry.data());
+ if(!item) {
+ kdWarning() << "DetailedListView::modifyEntries() - no item found for " << entry->title() << endl;
+ continue;
+ }
+
+ populateItem(item);
+ item->setState(DetailedEntryItem::Modified);
+ item->setVisible(!m_filter || m_filter->matches(entry.data()));
+ }
+
+ if(isUpdatesEnabled() && item && item->isVisible()) {
+ sort();
+ }
+
+ if(item && !item->isSelected() && !selectedItems().isEmpty()) {
+ blockSignals(true);
+ clearSelection();
+ setSelected(item, true);
+ blockSignals(false);
+ }
+}
+
+void DetailedListView::removeEntries(Data::EntryVec entries_) {
+ if(entries_.isEmpty()) {
+ return;
+ }
+
+// myDebug() << "DetailedListView::removeEntries() - " << entry_->title() << endl;
+
+ for(Data::EntryVecIt entry = entries_.begin(); entry != entries_.end(); ++entry) {
+ delete locateItem(entry);
+ }
+ // update is required
+ triggerUpdate();
+}
+
+void DetailedListView::removeCollection(Data::CollPtr coll_) {
+ if(!coll_) {
+ kdWarning() << "DetailedListView::removeCollection() - null coll pointer!" << endl;
+ return;
+ }
+
+// myDebug() << "DetailedListView::removeCollection() - " << coll_->title() << endl;
+
+ clear();
+ while(columns() > 0) {
+ removeColumn(0);
+ }
+
+ m_headerMenu->clear();
+ m_headerMenu->insertTitle(i18n("View Columns"));
+
+ m_columnWidths.clear();
+ clearComparisons();
+ m_entryPix = QPixmap();
+
+ // clear the filter, too
+ m_filter = 0;
+}
+
+void DetailedListView::populateColumn(int col_) {
+ if(childCount() == 0) {
+ return;
+ }
+// myDebug() << "DetailedListView::populateColumn() - " << columnText(col_) << endl;
+ DetailedEntryItem* item = static_cast<DetailedEntryItem*>(firstChild());
+ Data::FieldPtr field = item->entry()->collection()->fieldByTitle(columnText(col_));
+ for( ; item; item = static_cast<DetailedEntryItem*>(item->nextSibling())) {
+ setPixmapAndText(item, col_, field);
+ }
+ m_isDirty[col_] = false;
+}
+
+void DetailedListView::populateItem(DetailedEntryItem* item_) {
+ Data::EntryPtr entry = item_->entry();
+ if(!entry) {
+ return;
+ }
+
+ for(int colNum = 0; colNum < columns(); ++colNum) {
+ if(columnWidth(colNum) > 0) {
+ Data::FieldPtr field = entry->collection()->fieldByTitle(columnText(colNum));
+ if(!field) {
+ kdWarning() << "DetailedListView::populateItem() - no field found for " << columnText(colNum) << endl;
+ continue;
+ }
+ setPixmapAndText(item_, colNum, field);
+ } else {
+ m_isDirty[colNum] = true;
+ }
+ }
+}
+
+void DetailedListView::contextMenuRequested(QListViewItem* item_, const QPoint& point_, int) {
+ if(!item_) {
+ return;
+ }
+ KPopupMenu menu(this);
+ Controller::self()->plugEntryActions(&menu);
+ menu.exec(point_);
+}
+
+// don't shadow QListView::setSelected
+void DetailedListView::setEntrySelected(Data::EntryPtr entry_) {
+// myDebug() << "DetailedListView::setEntrySelected()" << endl;
+ // if entry_ is null pointer, just return
+ if(!entry_) {
+ return;
+ }
+
+ DetailedEntryItem* item = locateItem(entry_);
+
+ blockSignals(true);
+ clearSelection();
+ setSelected(item, true);
+ setCurrentItem(item);
+ blockSignals(false);
+ ensureItemVisible(item);
+}
+
+Tellico::DetailedEntryItem* DetailedListView::locateItem(Data::EntryPtr entry_) {
+ for(QListViewItemIterator it(this); it.current(); ++it) {
+ DetailedEntryItem* item = static_cast<DetailedEntryItem*>(it.current());
+ if(item->entry() == entry_) {
+ return item;
+ }
+ }
+
+ return 0;
+}
+
+bool DetailedListView::eventFilter(QObject* obj_, QEvent* ev_) {
+ if(ev_->type() == QEvent::MouseButtonPress
+ && static_cast<QMouseEvent*>(ev_)->button() == Qt::RightButton
+ && obj_ == header()) {
+ m_headerMenu->popup(static_cast<QMouseEvent*>(ev_)->globalPos());
+ return true;
+ }
+ return GUI::ListView::eventFilter(obj_, ev_);
+}
+
+void DetailedListView::slotHeaderMenuActivated(int id_) {
+// myDebug() << "DetailedListView::slotHeaderMenuActivated() - " << m_headerMenu->text(id_) << endl;
+ bool checked = m_headerMenu->isItemChecked(id_);
+ checked = !checked; // toggle
+ m_headerMenu->setItemChecked(id_, checked);
+
+ int col = m_headerMenu->indexOf(id_) - 1; // subtract 1 because there's a title item
+
+ if(checked) { // add a column
+ showColumn(col);
+ } else {
+ hideColumn(col);
+ }
+ slotUpdatePixmap();
+}
+
+void DetailedListView::slotRefresh() {
+ if(childCount() == 0) {
+ return;
+ }
+
+ // the algorithm here is to iterate over each column, then over every list item
+ Data::CollPtr coll = static_cast<DetailedEntryItem*>(firstChild())->entry()->collection();
+ Data::FieldPtr field;
+ DetailedEntryItem* item;
+
+ for(int colNum = 0; colNum < columns(); ++colNum) {
+ field = coll->fieldByTitle(columnText(colNum));
+
+ // iterate over all items
+
+ for(QListViewItemIterator it(this); it.current(); ++it) {
+ item = static_cast<DetailedEntryItem*>(it.current());
+
+ setPixmapAndText(item, colNum, field);
+
+ // if we're doing this for the first time, go ahead and pass through filter
+ if(colNum == 0) {
+ if(m_filter && !m_filter->matches(item->entry())) {
+ item->setVisible(false);
+ } else {
+ item->setVisible(true);
+ }
+ }
+ }
+ }
+}
+
+void DetailedListView::slotRefreshImages() {
+ for(QValueVector<int>::const_iterator it = m_imageColumns.begin(); it != m_imageColumns.end(); ++it) {
+ if(columnWidth(*it) > 0) {
+ populateColumn(*it);
+ }
+ }
+}
+
+void DetailedListView::setPixmapAndText(DetailedEntryItem* item_, int col_, Data::FieldPtr field_) {
+ if(!item_ || !field_) {
+ return;
+ }
+
+ // if the bool is not empty, show the checkmark pixmap
+ if(field_->type() == Data::Field::Bool) {
+ const QString value = item_->entry()->field(field_);
+ item_->setPixmap(col_, value.isEmpty() ? QPixmap() : m_checkPix);
+ item_->setText(col_, QString::null);
+ } else if(field_->type() == Data::Field::Image) {
+ // if we're currently loading a collection
+ // don't load the image just yet, it'll get refreshed later
+ if(m_loadingCollection || columnWidth(col_) == 0) {
+ item_->setPixmap(col_, QPixmap());
+ item_->setText(col_, QString::null);
+ } else {
+ item_->setPixmap(col_, ImageFactory::pixmap(item_->entry()->field(field_), m_pixWidth, m_pixHeight));
+ item_->setText(col_, QString::null);
+ }
+ } else if(field_->type() == Data::Field::Rating) {
+ item_->setPixmap(col_, GUI::RatingWidget::pixmap(item_->entry()->field(field_)));
+ item_->setText(col_, QString::null);
+ } else { // for everything else, there's no pixmap, unless it's the first column
+ item_->setPixmap(col_, col_ == m_firstSection ? m_entryPix : QPixmap());
+ item_->setText(col_, item_->entry()->formattedField(field_));
+ }
+ item_->widthChanged(col_);
+}
+
+void DetailedListView::showColumn(int col_) {
+// myDebug() << "DetailedListView::showColumn() - " << columnText(col_) << endl;
+ int w = m_columnWidths[col_]; // this should be safe - all were initialized to 0
+ if(w == 0) {
+ setColumnWidthMode(col_, QListView::Maximum);
+ for(QListViewItemIterator it(this); it.current(); ++it) {
+ w = QMAX(it.current()->width(fontMetrics(), this, col_), w);
+ }
+ w = QMAX(w, MIN_COL_WIDTH);
+ } else {
+ setColumnWidthMode(col_, QListView::Manual);
+ }
+
+ setColumnWidth(col_, w);
+ if(m_isDirty[col_]) {
+ populateColumn(col_);
+ }
+ header()->setResizeEnabled(true, col_);
+ triggerUpdate();
+}
+
+void DetailedListView::hideColumn(int col_) {
+// myDebug() << "DetailedListView::hideColumn() - " << columnText(col_) << endl;
+ setColumnWidthMode(col_, QListView::Manual);
+ setColumnWidth(col_, 0);
+ header()->setResizeEnabled(false, col_);
+
+ // special case for images, I don't want all the items to be tall, so remove pixmaps
+ if(childCount() > 0) {
+ Data::EntryPtr entry = static_cast<DetailedEntryItem*>(firstChild())->entry();
+ if(entry) {
+ Data::FieldPtr field = entry->collection()->fieldByTitle(columnText(col_));
+ if(field && field->type() == Data::Field::Image) {
+ m_isDirty[col_] = true;
+ for(QListViewItemIterator it(this); it.current(); ++it) {
+ it.current()->setPixmap(col_, QPixmap());
+ }
+ }
+ }
+ }
+
+ triggerUpdate();
+}
+
+void DetailedListView::slotCacheColumnWidth(int section_, int oldSize_, int newSize_) {
+ // if the old size was 0, update the menu
+ if(oldSize_ == 0 && newSize_ > 0) {
+ m_headerMenu->setItemChecked(m_headerMenu->idAt(section_+1), true); // add 1 for title item
+ }
+
+ if(newSize_ > 0) {
+ m_columnWidths[section_] = newSize_;
+ }
+ setColumnWidthMode(section_, QListView::Manual);
+}
+
+void DetailedListView::setFilter(FilterPtr filter_) {
+ if(m_filter.data() != filter_) { // might just be updating
+ m_filter = filter_;
+ }
+// clearSelection();
+
+ int count = 0;
+ // iterate over all items
+ DetailedEntryItem* item;
+ for(QListViewItemIterator it(this); it.current(); ++it) {
+ item = static_cast<DetailedEntryItem*>(it.current());
+ if(m_filter && !m_filter->matches(item->entry())) {
+ item->setVisible(false);
+ setSelected(item, false);
+ } else {
+ item->setVisible(true);
+ ++count;
+ }
+ }
+ m_visibleItems = count;
+}
+
+void DetailedListView::addField(Data::CollPtr, Data::FieldPtr field) {
+ addField(field, 0); /* field is hidden by default */
+}
+
+void DetailedListView::addField(Data::FieldPtr field_, int width_) {
+// myDebug() << "DetailedListView::addField() - " << field_->title() << endl;
+ int col = addColumn(field_->title());
+
+ // Bools, images, and numbers should be centered
+ if(field_->type() == Data::Field::Bool
+ || field_->type() == Data::Field::Number
+ || field_->type() == Data::Field::Image) {
+ setColumnAlignment(col, Qt::AlignHCenter | Qt::AlignVCenter);
+ if(field_->type() == Data::Field::Image) {
+ m_imageColumns.push_back(col);
+ }
+ } else {
+ setColumnAlignment(col, Qt::AlignLeft | Qt::AlignVCenter);
+ }
+
+ // width might be -1, which means set the width to maximum
+ // but m_columnWidths is the cached width, so just set it to 0
+ m_columnWidths.push_back(QMAX(width_, 0));
+
+ m_isDirty.push_back(true);
+
+ int id = m_headerMenu->insertItem(field_->title());
+ if(width_ == 0) {
+ m_headerMenu->setItemChecked(id, false);
+ hideColumn(col);
+ } else {
+ m_headerMenu->setItemChecked(id, true);
+ showColumn(col);
+ }
+ setComparison(col, ListViewComparison::create(field_));
+ resetComparisons();
+}
+
+void DetailedListView::modifyField(Tellico::Data::CollPtr, Data::FieldPtr oldField_, Data::FieldPtr newField_) {
+ int sec; // I need it for after the loop
+ for(sec = 0; sec < columns(); ++sec) {
+ if(header()->label(sec) == oldField_->title()) {
+ break;
+ }
+ }
+
+ // I thought this would have to be mapped to index, but not the case
+ setColumnText(sec, newField_->title());
+ if(newField_->type() == Data::Field::Bool
+ || newField_->type() == Data::Field::Number
+ || newField_->type() == Data::Field::Image) {
+ setColumnAlignment(sec, Qt::AlignHCenter | Qt::AlignVCenter);
+ if(oldField_->type() == Data::Field::Image) {
+ QValueVector<int>::iterator it = qFind(m_imageColumns.begin(), m_imageColumns.end(), sec);
+ if(it != m_imageColumns.end()) {
+ m_imageColumns.erase(it);
+ }
+ }
+ if(newField_->type() == Data::Field::Image) {
+ m_imageColumns.push_back(sec);
+ }
+ } else {
+ setColumnAlignment(sec, Qt::AlignLeft | Qt::AlignVCenter);
+ }
+ m_headerMenu->changeItem(m_headerMenu->idAt(sec+1), newField_->title()); // add 1 since menu has title
+ setComparison(sec, ListViewComparison::create(newField_));
+ resetComparisons();
+}
+
+void DetailedListView::removeField(Tellico::Data::CollPtr, Data::FieldPtr field_) {
+// myDebug() << "DetailedListView::removeField() - " << field_->name() << endl;
+
+ int sec; // I need it for after the loop
+ for(sec = 0; sec < columns(); ++sec) {
+ if(header()->label(sec) == field_->title()) {
+// myDebug() << "Removing section " << sec << endl;
+ break;
+ }
+ }
+
+ if(sec == columns()) {
+ kdWarning() << "DetailedListView::removeField() - no column named " << field_->title() << endl;
+ return;
+ }
+
+ m_headerMenu->removeItem(m_headerMenu->idAt(sec+1)); // add 1 since menu has title
+
+ m_columnWidths.erase(&m_columnWidths[sec]);
+ m_isDirty.erase(&m_isDirty[sec]);
+
+ // I thought this would have to be mapped to index, but not the case
+ removeComparison(sec); // must be before removeColumn();
+ removeColumn(sec);
+
+ // sometimes resizeEnabled gets messed up
+ for(int i = sec; i < columns(); ++i) {
+ header()->setResizeEnabled(columnWidth(i) > 0, header()->mapToSection(i));
+ }
+ resetComparisons();
+ slotUpdatePixmap();
+ triggerUpdate();
+}
+
+void DetailedListView::reorderFields(const Data::FieldVec& fields_) {
+// myDebug() << "DetailedListView::reorderFields()" << endl;
+ // find the first out of place field
+ int sec = 0;
+ Data::FieldVec::ConstIterator it = fields_.begin();
+ for(sec = 0; it != fields_.end() && sec < columns(); ++sec, ++it) {
+ if(header()->label(sec) != it->title()) {
+ break;
+ }
+ }
+
+ QStringList visible = visibleColumns();
+ for( ; it != fields_.end() && sec < columns(); ++sec, ++it) {
+ header()->setLabel(sec, it->title());
+ bool isVisible = (visible.findIndex(it->title()) > -1);
+ m_headerMenu->changeItem(m_headerMenu->idAt(sec+1), it->title());
+ m_headerMenu->setItemChecked(m_headerMenu->idAt(sec+1), isVisible);
+ m_columnWidths[sec] = 0;
+ if(it->type() == Data::Field::Bool
+ || it->type() == Data::Field::Number
+ || it->type() == Data::Field::Image) {
+ setColumnAlignment(sec, Qt::AlignHCenter | Qt::AlignVCenter);
+ } else {
+ setColumnAlignment(sec, Qt::AlignLeft | Qt::AlignVCenter);
+ }
+
+ if(isVisible) {
+ showColumn(sec);
+ } else {
+ hideColumn(sec);
+ }
+ }
+
+ slotRefresh();
+ slotUpdatePixmap();
+ triggerUpdate();
+}
+
+int DetailedListView::prevSortedColumn() const {
+ return m_prevSortColumn;
+}
+
+int DetailedListView::prev2SortedColumn() const {
+ return m_prev2SortColumn;
+}
+
+void DetailedListView::setPrevSortedColumn(int prev1_, int prev2_) {
+ m_prevSortColumn = prev1_;
+ m_prev2SortColumn = prev2_;
+}
+
+void DetailedListView::setSorting(int column_, bool ascending_/*=true*/) {
+// DEBUG_BLOCK;
+ if(column_ != columnSorted()) {
+ m_prev2SortColumn = m_prevSortColumn;
+ m_prevSortColumn = columnSorted();
+ }
+ GUI::ListView::setSorting(column_, ascending_);
+}
+
+void DetailedListView::updateFirstSection() {
+ for(int numCol = 0; numCol < columns(); ++numCol) {
+ if(columnWidth(header()->mapToSection(numCol)) > 0) {
+ m_firstSection = header()->mapToSection(numCol);
+ break;
+ }
+ }
+}
+
+void DetailedListView::slotUpdatePixmap() {
+ int oldSection = m_firstSection;
+ updateFirstSection();
+ if(childCount() == 0 || oldSection == m_firstSection) {
+ return;
+ }
+
+ Data::EntryPtr entry = static_cast<DetailedEntryItem*>(firstChild())->entry();
+ if(!entry) {
+ return;
+ }
+
+ Data::FieldPtr field1 = entry->collection()->fieldByTitle(columnText(oldSection));
+ Data::FieldPtr field2 = entry->collection()->fieldByTitle(columnText(m_firstSection));
+ if(!field1 || !field2) {
+ kdWarning() << "DetailedListView::slotUpdatePixmap() - no field found." << endl;
+ return;
+ }
+
+ for(QListViewItemIterator it(this); it.current(); ++it) {
+ setPixmapAndText(static_cast<DetailedEntryItem*>(it.current()), oldSection, field1);
+ setPixmapAndText(static_cast<DetailedEntryItem*>(it.current()), m_firstSection, field2);
+ }
+}
+
+void DetailedListView::saveConfig(Tellico::Data::CollPtr coll_, int configIndex_) {
+ KConfigGroup config(kapp->config(), QString::fromLatin1("Options - %1").arg(coll_->typeName()));
+
+ // all of this is to have custom settings on a per file basis
+ QString configN;
+ if(coll_->type() == Data::Collection::Base) {
+ QValueList<ConfigInfo> info;
+ for(uint i = 0; i < Config::maxCustomURLSettings(); ++i) {
+ KURL u = config.readEntry(QString::fromLatin1("URL_%1").arg(i));
+ if(!u.isEmpty() && static_cast<int>(i) != configIndex_) {
+ configN = QString::fromLatin1("_%1").arg(i);
+ ConfigInfo ci;
+ ci.cols = config.readListEntry("ColumnNames" + configN);
+ ci.widths = config.readIntListEntry("ColumnWidths" + configN);
+ ci.order = config.readIntListEntry("ColumnOrder" + configN);
+ ci.colSorted = config.readNumEntry("SortColumn" + configN);
+ ci.ascSort = config.readBoolEntry("SortAscending" + configN);
+ ci.prevSort = config.readNumEntry("PrevSortColumn" + configN);
+ ci.prev2Sort = config.readNumEntry("Prev2SortColumn" + configN);
+ info.append(ci);
+ }
+ }
+ // subtract one since we're writing the current settings, too
+ uint limit = QMIN(info.count(), Config::maxCustomURLSettings()-1);
+ for(uint i = 0; i < limit; ++i) {
+ // starts at one since the current config will be written below
+ configN = QString::fromLatin1("_%1").arg(i+1);
+ config.writeEntry("ColumnNames" + configN, info[i].cols);
+ config.writeEntry("ColumnWidths" + configN, info[i].widths);
+ config.writeEntry("ColumnOrder" + configN, info[i].order);
+ config.writeEntry("SortColumn" + configN, info[i].colSorted);
+ config.writeEntry("SortAscending" + configN, info[i].ascSort);
+ config.writeEntry("PrevSortColumn" + configN, info[i].prevSort);
+ config.writeEntry("Prev2SortColumn" + configN, info[i].prev2Sort);
+ }
+ configN = QString::fromLatin1("_0");
+ }
+
+ QValueList<int> widths, order;
+ for(int i = 0; i < columns(); ++i) {
+ if(columnWidthMode(i) == QListView::Manual) {
+ widths += columnWidth(i);
+ } else {
+ widths += -1; // Maximum width mode
+ }
+ order += header()->mapToIndex(i);
+ }
+
+ config.writeEntry("ColumnWidths" + configN, widths);
+ config.writeEntry("ColumnOrder" + configN, order);
+ config.writeEntry("SortColumn" + configN, columnSorted());
+ config.writeEntry("SortAscending" + configN, ascendingSort());
+ config.writeEntry("PrevSortColumn" + configN, prevSortedColumn());
+ config.writeEntry("Prev2SortColumn" + configN, prev2SortedColumn());
+
+ QStringList colNames;
+ for(int col = 0; col < columns(); ++col) {
+ colNames += coll_->fieldNameByTitle(columnText(col));
+ }
+ config.writeEntry("ColumnNames" + configN, colNames);
+}
+
+QString DetailedListView::sortColumnTitle1() const {
+ return columnSorted() == -1 ? QString::null : header()->label(columnSorted());
+}
+
+QString DetailedListView::sortColumnTitle2() const {
+ return prevSortedColumn() == -1 ? QString::null : header()->label(prevSortedColumn());
+}
+
+QString DetailedListView::sortColumnTitle3() const {
+ return prev2SortedColumn() == -1 ? QString::null : header()->label(prev2SortedColumn());
+}
+
+QStringList DetailedListView::visibleColumns() const {
+ QStringList titles;
+ for(int i = 0; i < columns(); ++i) {
+ if(columnWidth(header()->mapToSection(i)) > 0) {
+ titles << columnText(header()->mapToSection(i));
+ }
+ }
+ return titles;
+}
+
+// can't be const
+Tellico::Data::EntryVec DetailedListView::visibleEntries() {
+ // We could just return the full collection entry list if the filter is 0
+ // but printing depends on the sorted order
+ Data::EntryVec entries;
+ for(QListViewItemIterator it(this); it.current(); ++it) {
+ if(it.current()->isVisible()) {
+ entries.append(static_cast<DetailedEntryItem*>(it.current())->entry());
+ }
+ }
+ return entries;
+}
+
+void DetailedListView::selectAllVisible() {
+ blockSignals(true);
+ for(QListViewItemIterator it(this); it.current(); ++it) {
+ if(it.current()->isVisible()) {
+ setSelected(it.current(), true);
+ }
+ }
+ blockSignals(false);
+ // FIXME: not right with MultiSelectionListView
+ slotSelectionChanged();
+}
+
+void DetailedListView::resetEntryStatus() {
+ for(QListViewItemIterator it(this); it.current(); ++it) {
+ static_cast<DetailedEntryItem*>(it.current())->setState(DetailedEntryItem::Normal);
+ }
+ triggerUpdate();
+}
+
+int DetailedListView::compare(int col_, const GUI::ListViewItem* item1_, GUI::ListViewItem* item2_, bool asc_) {
+ DetailedEntryItem* item2 = static_cast<DetailedEntryItem*>(item2_);
+ int res = 0;
+ return (res = compareColumn(col_, item1_, item2, asc_)) != 0 ? res :
+ (res = compareColumn(m_prevSortColumn, item1_, item2, asc_)) != 0 ? res :
+ (res = compareColumn(m_prev2SortColumn, item1_, item2, asc_)) != 0 ? res : 0;
+}
+
+int DetailedListView::compareColumn(int col, const GUI::ListViewItem* item1, GUI::ListViewItem* item2, bool asc) {
+ return GUI::ListView::compare(col, item1, item2, asc);
+}
+
+void DetailedListView::resetComparisons() {
+ // this is only allowed when the view is not empty, so we can grab a collection ptr
+ if(childCount() == 0) {
+ return;
+ }
+ Data::CollPtr coll = static_cast<DetailedEntryItem*>(firstChild())->entry()->collection();
+ if(!coll) {
+ return;
+ }
+ for(int i = 0; i < columns(); ++i) {
+ Data::FieldPtr f = coll->fieldByTitle(header()->label(i));
+ if(f) {
+ setComparison(i, ListViewComparison::create(f));
+ }
+ }
+}
+
+#include "detailedlistview.moc"
diff --git a/src/detailedlistview.h b/src/detailedlistview.h
new file mode 100644
index 0000000..c6c7299
--- /dev/null
+++ b/src/detailedlistview.h
@@ -0,0 +1,214 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef DETAILEDLISTVIEW_H
+#define DETAILEDLISTVIEW_H
+
+#include "gui/listview.h"
+#include "observer.h"
+#include "filter.h"
+
+#include <qstringlist.h>
+#include <qpixmap.h>
+#include <qvaluevector.h>
+
+class KPopupMenu;
+
+namespace Tellico {
+ class DetailedEntryItem;
+
+/**
+ * The DetailedListView class shows detailed information about entries in the
+ * collection.
+ *
+ * @author Robby Stephenson
+ */
+class DetailedListView : public GUI::ListView, public Observer {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor initializes the popup menu, but no columns are inserted.
+ *
+ * @param parent A pointer to the parent widget
+ * @param name The widget name
+ */
+ DetailedListView(QWidget* parent, const char* name=0);
+ ~DetailedListView();
+
+ /**
+ * Event filter used to popup the menu
+ */
+ bool eventFilter(QObject* obj, QEvent* ev);
+ /**
+ * Selects the item which refers to a certain entry.
+ *
+ * @param entry A pointer to the entry
+ */
+ void setEntrySelected(Data::EntryPtr entry);
+ void setFilter(FilterPtr filter);
+ FilterPtr filter() { return m_filter; }
+
+ int prevSortedColumn() const;
+ int prev2SortedColumn() const;
+ virtual void setSorting(int column, bool ascending = true);
+ void setPrevSortedColumn(int prev1, int prev2);
+ QString sortColumnTitle1() const;
+ QString sortColumnTitle2() const;
+ QString sortColumnTitle3() const;
+ QStringList visibleColumns() const;
+ Data::EntryVec visibleEntries();
+
+ /**
+ * @param coll A pointer to the collection
+ */
+ void addCollection(Data::CollPtr coll);
+ /**
+ * Removes all items which refers to a entry within a collection.
+ *
+ * @param coll A pointer to the collection
+ */
+ void removeCollection(Data::CollPtr coll);
+
+ /**
+ * Adds a new list item showing the details for a entry.
+ *
+ * @param entry A pointer to the entry
+ */
+ virtual void addEntries(Data::EntryVec entries);
+ /**
+ * Modifies any item which refers to a entry, resetting the column contents.
+ *
+ * @param entry A pointer to the entry
+ */
+ virtual void modifyEntries(Data::EntryVec entries);
+ /**
+ * Removes any item which refers to a certain entry.
+ *
+ * @param entry A pointer to the entry
+ */
+ virtual void removeEntries(Data::EntryVec entries);
+
+ virtual void addField(Data::CollPtr, Data::FieldPtr field);
+ void addField(Data::FieldPtr field, int width);
+ virtual void modifyField(Data::CollPtr, Data::FieldPtr oldField, Data::FieldPtr newField);
+ virtual void removeField(Data::CollPtr, Data::FieldPtr field);
+
+ void reorderFields(const Data::FieldVec& fields);
+ /**
+ * saveConfig is only needed for custom collections */
+ void saveConfig(Data::CollPtr coll, int saveConfig);
+ /**
+ * Select all visible items.
+ */
+ void selectAllVisible();
+ int visibleItems() const { return m_filter ? m_visibleItems : childCount(); }
+ /**
+ * Set max size of pixmaps.
+ *
+ * @param width Width
+ * @param height Height
+ */
+ void setPixmapSize(int width, int height) { m_pixWidth = width; m_pixHeight = height; }
+ void resetEntryStatus();
+
+ virtual int compare(int col, const GUI::ListViewItem* item1, GUI::ListViewItem* item2, bool asc);
+
+public slots:
+ /**
+ * Resets the list view, clearing and deleting all items.
+ */
+ void slotReset();
+ /**
+ * Refreshes the view, repopulating all items.
+ */
+ void slotRefresh();
+ /**
+ * Refreshes all images only.
+ */
+ void slotRefreshImages();
+
+private:
+ DetailedEntryItem* addEntryInternal(Data::EntryPtr entry);
+ int compareColumn(int col, const GUI::ListViewItem* item1, GUI::ListViewItem* item2, bool asc);
+
+ /**
+ * A helper method to populate an item. The column text is initialized by pulling
+ * the contents from the entry pointer of the item, so it should properly be set
+ * before this method is called.
+ *
+ * @param item A pointer to the item
+ */
+ void populateItem(DetailedEntryItem* item);
+ void populateColumn(int col);
+ void setPixmapAndText(DetailedEntryItem* item, int col, Data::FieldPtr field);
+
+ /**
+ * A helper method to locate any item which refers to a certain entry. If none
+ * is found, a NULL pointer is returned.
+ *
+ * @param entry A pointer to the entry
+ * @return A pointer to the item
+ */
+ DetailedEntryItem* locateItem(Data::EntryPtr entry);
+ void showColumn(int col);
+ void hideColumn(int col);
+ void updateFirstSection();
+ void resetComparisons();
+
+private slots:
+ /**
+ * Handles the appearance of the popup menu.
+ *
+ * @param item A pointer to the list item underneath the mouse
+ * @param point The location point
+ * @param col The column number, not currently used
+ */
+ void contextMenuRequested(QListViewItem* item, const QPoint& point, int col);
+ void slotHeaderMenuActivated(int id);
+ void slotCacheColumnWidth(int section, int oldSize, int newSize);
+ /**
+ * Slot to update the position of the pixmap
+ */
+ void slotUpdatePixmap();
+
+private:
+ struct ConfigInfo {
+ QStringList cols;
+ QValueList<int> widths;
+ QValueList<int> order;
+ int colSorted;
+ bool ascSort : 1;
+ int prevSort;
+ int prev2Sort;
+ };
+
+ KPopupMenu* m_headerMenu;
+ QValueVector<int> m_columnWidths;
+ QValueVector<bool> m_isDirty;
+ QValueVector<int> m_imageColumns;
+ bool m_loadingCollection;
+ QPixmap m_entryPix;
+ QPixmap m_checkPix;
+
+ FilterPtr m_filter;
+ int m_prevSortColumn;
+ int m_prev2SortColumn;
+ int m_firstSection;
+ int m_visibleItems;
+ int m_pixWidth;
+ int m_pixHeight;
+};
+
+} // end namespace;
+#endif
diff --git a/src/document.cpp b/src/document.cpp
new file mode 100644
index 0000000..6163af8
--- /dev/null
+++ b/src/document.cpp
@@ -0,0 +1,679 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "document.h"
+#include "mainwindow.h" // needed for calling fileSave()
+#include "collectionfactory.h"
+#include "translators/tellicoimporter.h"
+#include "translators/tellicozipexporter.h"
+#include "translators/tellicoxmlexporter.h"
+#include "collection.h"
+#include "filehandler.h"
+#include "controller.h"
+#include "borrower.h"
+#include "tellico_kernel.h"
+#include "latin1literal.h"
+#include "tellico_debug.h"
+#include "imagefactory.h"
+#include "image.h"
+#include "stringset.h"
+#include "progressmanager.h"
+#include "core/tellico_config.h"
+
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kapplication.h>
+
+#include <qregexp.h>
+#include <qtimer.h>
+
+// use a vector so we can use a sort functor
+#include <vector>
+#include <algorithm>
+
+using Tellico::Data::Document;
+Document* Document::s_self = 0;
+
+Document::Document() : QObject(), m_coll(0), m_isModified(false),
+ m_loadAllImages(false), m_validFile(false), m_importer(0), m_cancelImageWriting(false),
+ m_fileFormat(Import::TellicoImporter::Unknown) {
+ m_allImagesOnDisk = Config::imageLocation() != Config::ImagesInFile;
+ newDocument(Collection::Book);
+}
+
+Document::~Document() {
+ delete m_importer;
+ m_importer = 0;
+}
+
+Tellico::Data::CollPtr Document::collection() const {
+ return m_coll;
+}
+
+void Document::setURL(const KURL& url_) {
+ m_url = url_;
+ if(m_url.fileName() != i18n("Untitled")) {
+ ImageFactory::setLocalDirectory(m_url);
+ }
+}
+
+void Document::slotSetModified(bool m_/*=true*/) {
+ m_isModified = m_;
+ emit signalModified(m_isModified);
+}
+
+void Document::slotDocumentRestored() {
+ slotSetModified(false);
+}
+
+bool Document::newDocument(int type_) {
+// kdDebug() << "Document::newDocument()" << endl;
+ delete m_importer;
+ m_importer = 0;
+ deleteContents();
+
+ m_coll = CollectionFactory::collection(static_cast<Collection::Type>(type_), true);
+ m_coll->setTrackGroups(true);
+
+ Kernel::self()->resetHistory();
+ Controller::self()->slotCollectionAdded(m_coll);
+
+ slotSetModified(false);
+ KURL url;
+ url.setFileName(i18n("Untitled"));
+ setURL(url);
+ m_validFile = false;
+ m_fileFormat = Import::TellicoImporter::Unknown;
+
+ return true;
+}
+
+bool Document::openDocument(const KURL& url_) {
+ myLog() << "Document::openDocument() - " << url_.prettyURL() << endl;
+
+ m_loadAllImages = false;
+ // delayed image loading only works for local files
+ if(!url_.isLocalFile()) {
+ m_loadAllImages = true;
+ }
+
+ delete m_importer;
+ m_importer = new Import::TellicoImporter(url_, m_loadAllImages);
+
+ CollPtr coll = m_importer->collection();
+ // delayed image loading only works for zip files
+ // format is only known AFTER collection() is called
+
+ m_fileFormat = m_importer->format();
+ m_allImagesOnDisk = !m_importer->hasImages();
+ if(!m_importer->hasImages() || m_fileFormat != Import::TellicoImporter::Zip) {
+ m_loadAllImages = true;
+ }
+
+ if(!coll) {
+// myDebug() << "Document::openDocument() - returning false" << endl;
+ Kernel::self()->sorry(m_importer->statusMessage());
+ m_validFile = false;
+ return false;
+ }
+ deleteContents();
+ m_coll = coll;
+ m_coll->setTrackGroups(true);
+ setURL(url_);
+ m_validFile = true;
+
+ Kernel::self()->resetHistory();
+ Controller::self()->slotCollectionAdded(m_coll);
+
+ // m_importer might have been deleted?
+ slotSetModified(m_importer && m_importer->modifiedOriginal());
+// if(pruneImages()) {
+// slotSetModified(true);
+// }
+ if(m_importer->hasImages()) {
+ m_cancelImageWriting = false;
+ QTimer::singleShot(500, this, SLOT(slotLoadAllImages()));
+ } else {
+ emit signalCollectionImagesLoaded(m_coll);
+ }
+ return true;
+}
+
+bool Document::saveModified() {
+ bool completed = true;
+
+ if(m_isModified) {
+ MainWindow* app = static_cast<MainWindow*>(Kernel::self()->widget());
+ QString str = i18n("The current file has been modified.\n"
+ "Do you want to save it?");
+ int want_save = KMessageBox::warningYesNoCancel(Kernel::self()->widget(), str, i18n("Unsaved Changes"),
+ KStdGuiItem::save(), KStdGuiItem::discard());
+ switch(want_save) {
+ case KMessageBox::Yes:
+ completed = app->fileSave();
+ break;
+
+ case KMessageBox::No:
+ slotSetModified(false);
+ completed = true;
+ break;
+
+ case KMessageBox::Cancel:
+ default:
+ completed = false;
+ break;
+ }
+ }
+
+ return completed;
+}
+
+bool Document::saveDocument(const KURL& url_) {
+ if(!FileHandler::queryExists(url_)) {
+ return false;
+ }
+// DEBUG_BLOCK;
+
+ // in case we're still loading images, give that a chance to cancel
+ m_cancelImageWriting = true;
+ kapp->processEvents();
+
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, i18n("Saving file..."), false);
+ ProgressItem::Done done(this);
+
+ // will always save as zip file, no matter if has images or not
+ int imageLocation = Config::imageLocation();
+ bool includeImages = imageLocation == Config::ImagesInFile;
+ int totalSteps;
+ // write all images to disk cache if needed
+ // have to do this before executing exporter in case
+ // the user changed the imageInFile setting from Yes to No, in which
+ // case saving will over write the old file that has the images in it!
+ if(includeImages) {
+ totalSteps = 10;
+ item.setTotalSteps(10);
+ // since TellicoZipExporter uses 100 steps, then it will get 100/110 of the total progress
+ } else {
+ totalSteps = 100;
+ item.setTotalSteps(100);
+ m_cancelImageWriting = false;
+ writeAllImages(imageLocation == Config::ImagesInAppDir ? ImageFactory::DataDir : ImageFactory::LocalDir, url_);
+ }
+ Export::Exporter* exporter;
+ if(m_fileFormat == Import::TellicoImporter::XML) {
+ exporter = new Export::TellicoXMLExporter();
+ static_cast<Export::TellicoXMLExporter*>(exporter)->setIncludeImages(includeImages);
+ } else {
+ exporter = new Export::TellicoZipExporter();
+ static_cast<Export::TellicoZipExporter*>(exporter)->setIncludeImages(includeImages);
+ }
+ item.setProgress(int(0.8*totalSteps));
+ exporter->setEntries(m_coll->entries());
+ exporter->setURL(url_);
+ // since we already asked about overwriting the file, force the save
+ long opt = exporter->options() | Export::ExportForce | Export::ExportProgress;
+ // only write the image sizes if they're known already
+ opt &= ~Export::ExportImageSize;
+ exporter->setOptions(opt);
+ bool success = exporter->exec();
+ item.setProgress(int(0.9*totalSteps));
+
+ if(success) {
+ Kernel::self()->resetHistory();
+ setURL(url_);
+ // if successful, doc is no longer modified
+ slotSetModified(false);
+ } else {
+ myDebug() << "Document::saveDocument() - not successful saving to " << url_.prettyURL() << endl;
+ }
+ delete exporter;
+ return success;
+}
+
+bool Document::closeDocument() {
+ delete m_importer;
+ m_importer = 0;
+ deleteContents();
+ return true;
+}
+
+void Document::deleteContents() {
+ if(m_coll) {
+ Controller::self()->slotCollectionDeleted(m_coll);
+ }
+ // don't delete the m_importer here, bad things will happen
+
+ // since the collection holds a pointer to each entry and each entry
+ // hold a pointer to the collection, and they're both sharedptrs,
+ // neither will ever get deleted, unless the entries are removed from the collection
+ if(m_coll) {
+ m_coll->clear();
+ }
+ m_coll = 0; // old collection gets deleted as a KSharedPtr
+ m_cancelImageWriting = true;
+}
+
+void Document::appendCollection(CollPtr coll_) {
+ if(!coll_) {
+ return;
+ }
+
+ m_coll->blockSignals(true);
+ Data::FieldVec fields = coll_->fields();
+ for(FieldVec::Iterator field = fields.begin(); field != fields.end(); ++field) {
+ m_coll->mergeField(field);
+ }
+
+ EntryVec entries = coll_->entries();
+ for(EntryVec::Iterator entry = entries.begin(); entry != entries.end(); ++entry) {
+ Data::EntryPtr newEntry = new Data::Entry(*entry);
+ newEntry->setCollection(m_coll);
+ }
+ m_coll->addEntries(entries);
+ // TODO: merge filters and loans
+ m_coll->blockSignals(false);
+}
+
+Tellico::Data::MergePair Document::mergeCollection(CollPtr coll_) {
+ MergePair pair;
+ if(!coll_) {
+ return pair;
+ }
+
+ m_coll->blockSignals(true);
+ Data::FieldVec fields = coll_->fields();
+ for(FieldVec::Iterator field = fields.begin(); field != fields.end(); ++field) {
+ m_coll->mergeField(field);
+ }
+
+ EntryVec currEntries = m_coll->entries();
+ EntryVec newEntries = coll_->entries();
+ for(EntryVec::Iterator newIt = newEntries.begin(); newIt != newEntries.end(); ++newIt) {
+ int bestMatch = 0;
+ Data::EntryPtr matchEntry;
+ for(EntryVec::Iterator currIt = currEntries.begin(); currIt != currEntries.end(); ++currIt) {
+ int match = m_coll->sameEntry(&*currIt, &*newIt);
+ if(match >= Collection::ENTRY_PERFECT_MATCH) {
+ matchEntry = currIt;
+ break;
+ } else if(match >= Collection::ENTRY_GOOD_MATCH && match > bestMatch) {
+ bestMatch = match;
+ matchEntry = currIt;
+ // don't break, keep looking for better one
+ }
+ }
+ if(matchEntry) {
+ m_coll->mergeEntry(matchEntry, &*newIt, false /*overwrite*/);
+ } else {
+ Data::EntryPtr e = new Data::Entry(*newIt);
+ e->setCollection(m_coll);
+ // keep track of which entries got added
+ pair.first.append(e);
+ }
+ }
+ m_coll->addEntries(pair.first);
+ // TODO: merge filters and loans
+ m_coll->blockSignals(false);
+ return pair;
+}
+
+void Document::replaceCollection(CollPtr coll_) {
+ if(!coll_) {
+ return;
+ }
+
+// kdDebug() << "Document::replaceCollection()" << endl;
+
+ KURL url;
+ url.setFileName(i18n("Untitled"));
+ setURL(url);
+ m_validFile = false;
+
+ // the collection gets cleared by the CollectionCommand that called this function
+ // no need to do it here
+
+ m_coll = coll_;
+ m_coll->setTrackGroups(true);
+ m_cancelImageWriting = true;
+ // CollectionCommand takes care of calling Controller signals
+}
+
+void Document::unAppendCollection(CollPtr coll_, FieldVec origFields_) {
+ if(!coll_) {
+ return;
+ }
+
+ m_coll->blockSignals(true);
+
+ StringSet origFieldNames;
+ for(FieldVec::Iterator field = origFields_.begin(); field != origFields_.end(); ++field) {
+ m_coll->modifyField(field);
+ origFieldNames.add(field->name());
+ }
+
+ EntryVec entries = coll_->entries();
+ for(EntryVec::Iterator entry = entries.begin(); entry != entries.end(); ++entry) {
+ // probably don't need to do this, but on the safe side...
+ entry->setCollection(coll_);
+ }
+ m_coll->removeEntries(entries);
+
+ // since Collection::removeField() iterates over all entries to reset the value of the field
+ // don't removeField() until after removeEntry() is done
+ FieldVec currFields = m_coll->fields();
+ for(FieldVec::Iterator field = currFields.begin(); field != currFields.end(); ++field) {
+ if(!origFieldNames.has(field->name())) {
+ m_coll->removeField(field);
+ }
+ }
+ m_coll->blockSignals(false);
+}
+
+void Document::unMergeCollection(CollPtr coll_, FieldVec origFields_, MergePair entryPair_) {
+ if(!coll_) {
+ return;
+ }
+
+ m_coll->blockSignals(true);
+
+ QStringList origFieldNames;
+ for(FieldVec::Iterator field = origFields_.begin(); field != origFields_.end(); ++field) {
+ m_coll->modifyField(field);
+ origFieldNames << field->name();
+ }
+
+ // first item in pair are the entries added by the operation, remove them
+ EntryVec entries = entryPair_.first;
+ m_coll->removeEntries(entries);
+
+ // second item in pair are the entries which got modified by the original merge command
+ const QString track = QString::fromLatin1("track");
+ PairVector trackChanges = entryPair_.second;
+ // need to go through them in reverse since one entry may have been modified multiple times
+ // first item in the pair is the entry pointer
+ // second item is the old value of the track field
+ for(int i = trackChanges.count()-1; i >= 0; --i) {
+ trackChanges[i].first->setField(track, trackChanges[i].second);
+ }
+
+ // since Collection::removeField() iterates over all entries to reset the value of the field
+ // don't removeField() until after removeEntry() is done
+ FieldVec currFields = m_coll->fields();
+ for(FieldVec::Iterator field = currFields.begin(); field != currFields.end(); ++field) {
+ if(origFieldNames.findIndex(field->name()) == -1) {
+ m_coll->removeField(field);
+ }
+ }
+ m_coll->blockSignals(false);
+}
+
+bool Document::isEmpty() const {
+ //an empty doc may contain a collection, but no entries
+ return (!m_coll || m_coll->entries().isEmpty());
+}
+
+bool Document::loadImage(const QString& id_) {
+// myLog() << "Document::loadImage() - id = " << id_ << endl;
+ if(!m_coll) {
+ return false;
+ }
+
+ bool b = !m_loadAllImages && m_validFile && m_importer && m_importer->loadImage(id_);
+ if(b) {
+ m_allImagesOnDisk = false;
+ }
+ return b;
+}
+
+bool Document::loadAllImagesNow() const {
+// myLog() << "Document::loadAllImagesNow()" << endl;
+ if(!m_coll || !m_validFile) {
+ return false;
+ }
+ if(m_loadAllImages) {
+ myDebug() << "Document::loadAllImagesNow() - all valid images should already be loaded!" << endl;
+ return false;
+ }
+ return Import::TellicoImporter::loadAllImages(m_url);
+}
+
+Tellico::Data::EntryVec Document::filteredEntries(Filter::Ptr filter_) const {
+ Data::EntryVec matches;
+ Data::EntryVec entries = m_coll->entries();
+ for(EntryVec::Iterator it = entries.begin(); it != entries.end(); ++it) {
+ if(filter_->matches(it.data())) {
+ matches.append(it);
+ }
+ }
+ return matches;
+}
+
+void Document::checkOutEntry(Data::EntryPtr entry_) {
+ if(!entry_) {
+ return;
+ }
+
+ const QString loaned = QString::fromLatin1("loaned");
+ if(!m_coll->hasField(loaned)) {
+ FieldPtr f = new Field(loaned, i18n("Loaned"), Field::Bool);
+ f->setFlags(Field::AllowGrouped);
+ f->setCategory(i18n("Personal"));
+ m_coll->addField(f);
+ }
+ entry_->setField(loaned, QString::fromLatin1("true"));
+ EntryVec vec;
+ vec.append(entry_);
+ m_coll->updateDicts(vec);
+}
+
+void Document::checkInEntry(Data::EntryPtr entry_) {
+ if(!entry_) {
+ return;
+ }
+
+ const QString loaned = QString::fromLatin1("loaned");
+ if(!m_coll->hasField(loaned)) {
+ return;
+ }
+ entry_->setField(loaned, QString::null);
+ m_coll->updateDicts(EntryVec(entry_));
+}
+
+void Document::renameCollection(const QString& newTitle_) {
+ m_coll->setTitle(newTitle_);
+}
+
+// this only gets called when a zip file with images is opened
+// by loading every image, it gets pulled out of the zip file and
+// copied to disk. then the zip file can be closed and not retained in memory
+void Document::slotLoadAllImages() {
+ QString id;
+ StringSet images;
+ Data::EntryVec entries = m_coll->entries();
+ Data::FieldVec imageFields = m_coll->imageFields();
+ for(Data::EntryVec::Iterator entry = entries.begin(); entry != entries.end(); ++entry) {
+ for(Data::FieldVec::Iterator field = imageFields.begin(); field != imageFields.end() && !m_cancelImageWriting; ++field) {
+ id = entry->field(field);
+ if(id.isEmpty() || images.has(id)) {
+ continue;
+ }
+ // this is the early loading, so just by calling imageById()
+ // the image gets sucked from the zip file and written to disk
+ //by ImageFactory::imageById()
+ if(ImageFactory::imageById(id).isNull()) {
+ myDebug() << "Document::slotLoadAllImages() - entry title: " << entry->title() << endl;
+ }
+ images.add(id);
+ }
+ if(m_cancelImageWriting) {
+ break;
+ }
+ // stay responsive, do this in the background
+ kapp->processEvents();
+ }
+
+ if(m_cancelImageWriting) {
+ myLog() << "Document::slotLoadAllImages() - cancel image writing" << endl;
+ } else {
+ emit signalCollectionImagesLoaded(m_coll);
+ }
+
+ m_cancelImageWriting = false;
+}
+
+void Document::writeAllImages(int cacheDir_, const KURL& localDir_) {
+ // images get 80 steps in saveDocument()
+ const uint stepSize = 1 + QMAX(1, m_coll->entryCount()/80); // add 1 since it could round off
+ uint j = 1;
+
+ QString oldLocalDir = ImageFactory::localDir();
+ ImageFactory::setLocalDirectory(localDir_);
+
+ ImageFactory::CacheDir cacheDir = static_cast<ImageFactory::CacheDir>(cacheDir_);
+
+ QString id;
+ StringSet images;
+ EntryVec entries = m_coll->entries();
+ FieldVec imageFields = m_coll->imageFields();
+ for(EntryVec::Iterator entry = entries.begin(); entry != entries.end(); ++entry) {
+ for(FieldVec::Iterator field = imageFields.begin(); field != imageFields.end() && !m_cancelImageWriting; ++field) {
+ id = entry->field(field);
+ if(id.isEmpty() || images.has(id)) {
+ continue;
+ }
+ images.add(id);
+ if(ImageFactory::imageInfo(id).linkOnly) {
+ continue;
+ }
+ if(!ImageFactory::writeCachedImage(id, cacheDir)) {
+ myDebug() << "Document::writeAllImages() - did not write image for entry title: " << entry->title() << endl;
+ }
+ }
+ if(j%stepSize == 0) {
+ ProgressManager::self()->setProgress(this, j/stepSize);
+ kapp->processEvents();
+ }
+ ++j;
+ if(m_cancelImageWriting) {
+ break;
+ }
+ }
+
+ if(m_cancelImageWriting) {
+ myDebug() << "Document::writeAllImages() - cancel image writing" << endl;
+ }
+
+ m_cancelImageWriting = false;
+ ImageFactory::setLocalDirectory(oldLocalDir);
+}
+
+bool Document::pruneImages() {
+ bool found = false;
+ QString id;
+ StringSet images;
+ Data::EntryVec entries = m_coll->entries();
+ Data::FieldVec imageFields = m_coll->imageFields();
+ for(Data::EntryVec::Iterator entry = entries.begin(); entry != entries.end(); ++entry) {
+ for(Data::FieldVec::Iterator field = imageFields.begin(); field != imageFields.end(); ++field) {
+ id = entry->field(field);
+ if(id.isEmpty() || images.has(id)) {
+ continue;
+ }
+ const Data::Image& img = ImageFactory::imageById(id);
+ if(img.isNull()) {
+ entry->setField(field, QString::null);
+ found = true;
+ myDebug() << "Document::pruneImages() - removing null image for " << entry->title() << ": " << id << endl;
+ } else {
+ images.add(id);
+ }
+ }
+ }
+ return found;
+}
+
+int Document::imageCount() const {
+ if(!m_coll) {
+ return 0;
+ }
+ StringSet images;
+ FieldVec fields = m_coll->imageFields();
+ EntryVec entries = m_coll->entries();
+ for(FieldVecIt f = fields.begin(); f != fields.end(); ++f) {
+ for(EntryVecIt e = entries.begin(); e != entries.end(); ++e) {
+ images.add(e->field(f->name()));
+ }
+ }
+ return images.count();
+}
+
+Tellico::Data::EntryVec Document::sortEntries(EntryVec entries_) const {
+ std::vector<EntryPtr> vec;
+ for(EntryVecIt e = entries_.begin(); e != entries_.end(); ++e) {
+ vec.push_back(e);
+ }
+
+ QStringList titles = Controller::self()->sortTitles();
+ // have to go in reverse for sorting
+ for(int i = titles.count()-1; i >= 0; --i) {
+ if(titles[i].isEmpty()) {
+ continue;
+ }
+ QString field = m_coll->fieldNameByTitle(titles[i]);
+ std::sort(vec.begin(), vec.end(), EntryCmp(field));
+ }
+
+ Data::EntryVec sorted;
+ for(std::vector<EntryPtr>::iterator it = vec.begin(); it != vec.end(); ++it) {
+ sorted.append(*it);
+ }
+ return sorted;
+}
+
+void Document::removeImagesNotInCollection(EntryVec entries_, EntryVec entriesToKeep_) {
+ // first get list of all images in collection
+ StringSet images;
+ FieldVec fields = m_coll->imageFields();
+ EntryVec allEntries = m_coll->entries();
+ for(FieldVecIt f = fields.begin(); f != fields.end(); ++f) {
+ for(EntryVecIt e = allEntries.begin(); e != allEntries.end(); ++e) {
+ images.add(e->field(f->name()));
+ }
+ for(EntryVecIt e = entriesToKeep_.begin(); e != entriesToKeep_.end(); ++e) {
+ images.add(e->field(f->name()));
+ }
+ }
+
+ // now for all images not in the cache, we can clear them
+ StringSet imagesToCheck = ImageFactory::imagesNotInCache();
+
+ // if entries_ is not empty, that means we want to limit the images removed
+ // to those that are referenced in those entries
+ StringSet imagesToRemove;
+ for(FieldVecIt f = fields.begin(); f != fields.end(); ++f) {
+ for(EntryVecIt e = entries_.begin(); e != entries_.end(); ++e) {
+ QString id = e->field(f->name());
+ if(!id.isEmpty() && imagesToCheck.has(id) && !images.has(id)) {
+ imagesToRemove.add(id);
+ }
+ }
+ }
+
+ const QStringList realImagesToRemove = imagesToRemove.toList();
+ for(QStringList::ConstIterator it = realImagesToRemove.begin(); it != realImagesToRemove.end(); ++it) {
+ ImageFactory::removeImage(*it, false); // doesn't delete, just remove link
+ }
+}
+
+#include "document.moc"
diff --git a/src/document.h b/src/document.h
new file mode 100644
index 0000000..82d74f7
--- /dev/null
+++ b/src/document.h
@@ -0,0 +1,237 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_DOCUMENT_H
+#define TELLICO_DOCUMENT_H
+
+#include <config.h>
+
+#include "datavectors.h"
+#include "filter.h"
+
+#include <kurl.h>
+
+#include <qobject.h>
+#include <qguardedptr.h>
+
+namespace Tellico {
+ namespace Import {
+ class TellicoImporter;
+ }
+ namespace Data {
+
+/**
+ * The Document contains everything needed to deal with the contents, thus separated from
+ * the viewer, the Tellico object. It can take of opening and saving documents, and contains
+ * a list of the collections in the document.
+ *
+ * @author Robby Stephenson
+ */
+class Document : public QObject {
+Q_OBJECT
+
+public:
+ static Document* self() { if(!s_self) s_self = new Document(); return s_self; }
+
+ /**
+ * Sets the URL associated with the document.
+ *
+ * @param url The URL
+ */
+ void setURL(const KURL& url);
+ /**
+ * Checks the modified flag, which indicates if the document has changed since the
+ * last save.
+ *
+ * @return A boolean indicating the modified status
+ */
+ bool isModified() const { return m_isModified; }
+ /**
+ * Sets whether all images are loaded from file or not
+ */
+ void setLoadAllImages(bool loadAll) { m_loadAllImages = loadAll; }
+ /**
+ * Returns the current url associated with the document
+ *
+ * @return The url
+ */
+ const KURL& URL() const { return m_url; }
+ /**
+ * Initializes a new document. The signalNewDoc() signal is emitted. The return
+ * value is currently always true, but should indicate whether or not a new document
+ * was correctly initialized.
+ *
+ * @param type The type of collection to add
+ * @return A boolean indicating success
+ */
+ bool newDocument(int type);
+ /**
+ * Open a document given a specified location. If, for whatever reason, the file
+ * cannot be opened, a proper message box is shown, indicating the problem. The
+ * signalNewDoc() signal is made once the file contents have been confirmed.
+ *
+ * @param url The location to open
+ * @return A boolean indicating success
+ */
+ bool openDocument(const KURL& url);
+ /**
+ * Checks to see if the document has been modified before deleting the contents.
+ * If it has, then a message box asks the user if the document should be saved,
+ * and then acts on the result.
+ *
+ * @return A boolean indicating success
+ */
+ bool saveModified();
+ /**
+ * Saves the document contents to a file.
+ *
+ * @param url The location to save the file
+ * @return A boolean indicating success
+ */
+ bool saveDocument(const KURL& url);
+ /**
+ * Closes the document, deleting the contents. The return value is presently always true.
+ *
+ * @return A boolean indicating success
+ */
+ bool closeDocument();
+ /**
+ * Deletes the contents of the document. A signalCollectionDeleted() will be sent for every
+ * collection in the document.
+ */
+ void deleteContents();
+ /**
+ * Returns a pointer to the document collection
+ *
+ * @return The collection
+ */
+ CollPtr collection() const;
+ /**
+ * Returns true if there are no entries. A doc with an empty collection is still empty.
+ */
+ bool isEmpty() const;
+ /**
+ * Appends the contents of another collection to the current one. The collections must be the
+ * same type. Fields which are in the current collection are left alone. Fields
+ * in the appended collection not in the current one are added. Entrys in the appended collection
+ * are added to the current one.
+ *
+ * @param coll A pointer to the appended collection.
+ */
+ void appendCollection(CollPtr coll);
+ /**
+ * Merges another collection into this one. The collections must be the same type. Fields in the
+ * current collection are left alone. Fields not in the current are added. The merging is slow
+ * since each entry in @p coll must be compared to ever entry in the current collection.
+ *
+ * @param coll A pointer to the collection to be merged.
+ * @return A QPair of the merged entries, see note in datavectors.h
+ */
+ MergePair mergeCollection(CollPtr coll);
+ /**
+ * Replace the current collection with a new one. Effectively, this is equivalent to opening
+ * a new file containing this collection.
+ *
+ * @param coll A Pointer to the new collection, the document takes ownership.
+ */
+ void replaceCollection(CollPtr coll);
+ void unAppendCollection(CollPtr coll, FieldVec origFields);
+ void unMergeCollection(CollPtr coll, FieldVec origFields_, MergePair entryPair);
+ /**
+ * Attempts to load an image from the document file
+ */
+ bool loadImage(const QString& id);
+ bool loadAllImagesNow() const;
+ bool allImagesOnDisk() const { return m_allImagesOnDisk; }
+ int imageCount() const;
+ EntryVec filteredEntries(Filter::Ptr filter) const;
+ /**
+ * Sort entries according to current detailed view
+ */
+ EntryVec sortEntries(EntryVec entries) const;
+
+ void renameCollection(const QString& newTitle);
+
+ void checkInEntry(EntryPtr entry);
+ void checkOutEntry(EntryPtr entry);
+
+ /**
+ * The second entry vector contains entries with images which should not be removed
+ * in addition to those already in the collection
+ */
+ void removeImagesNotInCollection(EntryVec entries, EntryVec entriesToKeep);
+ void cancelImageWriting() { m_cancelImageWriting = true; }
+
+public slots:
+ /**
+ * Sets the modified flag. If it is true, the signalModified signal is made.
+ *
+ * @param m A boolean indicating the current modified status
+ */
+ void slotSetModified(bool m=true);
+ void slotDocumentRestored();
+
+signals:
+ /**
+ * Signals that the document has been modified.
+ */
+ void signalModified(bool modified);
+ /**
+ * Signals that a status message should be shown.
+ *
+ * @param str The message
+ */
+ void signalStatusMsg(const QString& str);
+ /**
+ * Signals that all images in the loaded file have been loaded
+ * into memory or onto the disk
+ */
+ void signalCollectionImagesLoaded(Tellico::Data::CollPtr coll);
+
+private slots:
+ /**
+ * Does an initial loading of all images, used for writing
+ * images to temp dir initially
+ */
+ void slotLoadAllImages();
+
+private:
+ static Document* s_self;
+
+ /**
+ * Writes all images in the current collection to the cache directory
+ * if cacheDir = LocalDir, then url will be used and must not be empty
+ */
+ void writeAllImages(int cacheDir, const KURL& url=KURL());
+ bool pruneImages();
+
+ // make all constructors private
+ Document();
+ Document(const Document& doc);
+ Document& operator=(const Document&);
+ ~Document();
+
+ CollPtr m_coll;
+ bool m_isModified : 1;
+ bool m_loadAllImages : 1;
+ KURL m_url;
+ bool m_validFile : 1;
+ QGuardedPtr<Import::TellicoImporter> m_importer;
+ bool m_cancelImageWriting : 1;
+ int m_fileFormat;
+ bool m_allImagesOnDisk : 1;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/entry.cpp b/src/entry.cpp
new file mode 100644
index 0000000..a558ba2
--- /dev/null
+++ b/src/entry.cpp
@@ -0,0 +1,466 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "entry.h"
+#include "collection.h"
+#include "field.h"
+#include "translators/bibtexhandler.h" // needed for BibtexHandler::cleanText()
+#include "document.h"
+#include "tellico_debug.h"
+#include "tellico_utils.h"
+#include "tellico_debug.h"
+#include "latin1literal.h"
+#include "../isbnvalidator.h"
+#include "../lccnvalidator.h"
+
+#include <klocale.h>
+
+#include <qregexp.h>
+
+using Tellico::Data::Entry;
+using Tellico::Data::EntryGroup;
+
+EntryGroup::EntryGroup(const QString& group, const QString& field)
+ : QObject(), EntryVec(), m_group(Tellico::shareString(group)), m_field(Tellico::shareString(field)) {
+}
+
+EntryGroup::~EntryGroup() {
+ // need a copy since we remove ourselves
+ EntryVec vec = *this;
+ for(Data::EntryVecIt entry = vec.begin(); entry != vec.end(); ++entry) {
+ entry->removeFromGroup(this);
+ }
+}
+
+bool Entry::operator==(const Entry& e1) {
+// special case for file catalog, just check the url
+ if(m_coll && m_coll->type() == Collection::File &&
+ e1.m_coll && e1.m_coll->type() == Collection::File) {
+ // don't forget case where both could have empty urls
+ // but different values for other fields
+ QString u = field(QString::fromLatin1("url"));
+ if(!u.isEmpty()) {
+ // versions before 1.2.7 could have saved the url without the protocol
+ bool b = KURL::fromPathOrURL(u) == KURL::fromPathOrURL(e1.field(QString::fromLatin1("url")));
+ if(b) {
+ return true;
+ } else {
+ Data::FieldPtr f = m_coll->fieldByName(QString::fromLatin1("url"));
+ if(f && f->property(QString::fromLatin1("relative")) == Latin1Literal("true")) {
+ return KURL(Document::self()->URL(), u) == KURL::fromPathOrURL(e1.field(QString::fromLatin1("url")));
+ }
+ }
+ }
+ }
+ if(e1.m_fields.count() != m_fields.count()) {
+ return false;
+ }
+ for(StringMap::ConstIterator it = e1.m_fields.begin(); it != e1.m_fields.end(); ++it) {
+ if(!m_fields.contains(it.key()) || m_fields[it.key()] != it.data()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+Entry::Entry(CollPtr coll_) : KShared(), m_coll(coll_), m_id(-1) {
+#ifndef NDEBUG
+ if(!coll_) {
+ kdWarning() << "Entry() - null collection pointer!" << endl;
+ }
+#endif
+}
+
+Entry::Entry(CollPtr coll_, int id_) : KShared(), m_coll(coll_), m_id(id_) {
+#ifndef NDEBUG
+ if(!coll_) {
+ kdWarning() << "Entry() - null collection pointer!" << endl;
+ }
+#endif
+}
+
+Entry::Entry(const Entry& entry_) :
+ KShared(entry_),
+ m_coll(entry_.m_coll),
+ m_id(-1),
+ m_fields(entry_.m_fields),
+ m_formattedFields(entry_.m_formattedFields) {
+}
+
+Entry& Entry::operator=(const Entry& other_) {
+ if(this == &other_) return *this;
+
+// myDebug() << "Entry::operator=()" << endl;
+ static_cast<KShared&>(*this) = static_cast<const KShared&>(other_);
+ m_coll = other_.m_coll;
+ m_id = other_.m_id;
+ m_fields = other_.m_fields;
+ m_formattedFields = other_.m_formattedFields;
+ return *this;
+}
+
+Entry::~Entry() {
+}
+
+Tellico::Data::CollPtr Entry::collection() const {
+ return m_coll;
+}
+
+void Entry::setCollection(CollPtr coll_) {
+ if(coll_ == m_coll) {
+ myDebug() << "Entry::setCollection() - already belongs to collection!" << endl;
+ return;
+ }
+ // special case adding a book to a bibtex collection
+ // it would be better to do this in a real OOO way, but this should work
+ const bool addEntryType = m_coll->type() == Collection::Book &&
+ coll_->type() == Collection::Bibtex &&
+ !m_coll->hasField(QString::fromLatin1("entry-type"));
+ m_coll = coll_;
+ m_id = -1;
+ // set this after changing the m_coll pointer since setField() checks field validity
+ if(addEntryType) {
+ setField(QString::fromLatin1("entry-type"), QString::fromLatin1("book"));
+ }
+}
+
+QString Entry::title() const {
+ return formattedField(QString::fromLatin1("title"));
+}
+
+QString Entry::field(Data::FieldPtr field_, bool formatted_/*=false*/) const {
+ return field(field_->name(), formatted_);
+}
+
+QString Entry::field(const QString& fieldName_, bool formatted_/*=false*/) const {
+ if(formatted_) {
+ return formattedField(fieldName_);
+ }
+
+ FieldPtr f = m_coll->fieldByName(fieldName_);
+ if(!f) {
+ return QString::null;
+ }
+ if(f->type() == Field::Dependent) {
+ return dependentValue(this, f->description(), false);
+ }
+
+ if(!m_fields.isEmpty() && m_fields.contains(fieldName_)) {
+ return m_fields[fieldName_];
+ }
+ return QString::null;
+}
+
+QString Entry::formattedField(Data::FieldPtr field_) const {
+ return formattedField(field_->name());
+}
+
+QString Entry::formattedField(const QString& fieldName_) const {
+ FieldPtr f = m_coll->fieldByName(fieldName_);
+ if(!f) {
+ return QString::null;
+ }
+
+ Field::FormatFlag flag = f->formatFlag();
+ if(f->type() == Field::Dependent) {
+ if(flag == Field::FormatNone) {
+ return dependentValue(this, f->description(), false);
+ } else {
+ // format sub fields and whole string
+ return Field::format(dependentValue(this, f->description(), true), flag);
+ }
+ }
+
+ // if auto format is not set or FormatNone, then just return the value
+ if(flag == Field::FormatNone) {
+ return field(fieldName_);
+ }
+
+ if(m_formattedFields.isEmpty() || !m_formattedFields.contains(fieldName_)) {
+ QString value = field(fieldName_);
+ if(!value.isEmpty()) {
+ // special for Bibtex collections
+ if(m_coll->type() == Collection::Bibtex) {
+ BibtexHandler::cleanText(value);
+ }
+ value = Field::format(value, flag);
+ m_formattedFields.insert(fieldName_, value);
+ }
+ return value;
+ }
+ // otherwise, just look it up
+ return m_formattedFields[fieldName_];
+}
+
+QStringList Entry::fields(Data::FieldPtr field_, bool formatted_) const {
+ return fields(field_->name(), formatted_);
+}
+
+QStringList Entry::fields(const QString& field_, bool formatted_) const {
+ QString s = formatted_ ? formattedField(field_) : field(field_);
+ if(s.isEmpty()) {
+ return QStringList();
+ }
+ return Field::split(s, true);
+}
+
+bool Entry::setField(Data::FieldPtr field_, const QString& value_) {
+ return setField(field_->name(), value_);
+}
+
+bool Entry::setField(const QString& name_, const QString& value_) {
+ if(name_.isEmpty()) {
+ kdWarning() << "Entry::setField() - empty field name for value: " << value_ << endl;
+ return false;
+ }
+ // an empty value means remove the field
+ if(value_.isEmpty()) {
+ if(!m_fields.isEmpty() && m_fields.contains(name_)) {
+ m_fields.remove(name_);
+ }
+ invalidateFormattedFieldValue(name_);
+ return true;
+ }
+
+#ifndef NDEBUG
+ if(m_coll && (m_coll->fields().count() == 0 || !m_coll->hasField(name_))) {
+ myDebug() << "Entry::setField() - unknown collection entry field - "
+ << name_ << endl;
+ return false;
+ }
+#endif
+
+ if(m_coll && !m_coll->isAllowed(name_, value_)) {
+ myDebug() << "Entry::setField() - for " << name_
+ << ", value is not allowed - " << value_ << endl;
+ return false;
+ }
+
+ Data::FieldPtr f = m_coll->fieldByName(name_);
+ if(!f) {
+ return false;
+ }
+
+ // the string store is probable only useful for fields with auto-completion or choice/number/bool
+ if(!(f->flags() & Field::AllowMultiple) &&
+ ((f->type() == Field::Choice || f->type() == Field::Bool || f->type() == Field::Number) ||
+ (f->type() == Field::Line && (f->flags() & Field::AllowCompletion)))) {
+ m_fields.insert(Tellico::shareString(name_), Tellico::shareString(value_));
+ } else {
+ m_fields.insert(Tellico::shareString(name_), value_);
+ }
+ invalidateFormattedFieldValue(name_);
+ return true;
+}
+
+bool Entry::addToGroup(EntryGroup* group_) {
+ if(!group_ || m_groups.contains(group_)) {
+ return false;
+ }
+
+ m_groups.push_back(group_);
+ group_->append(this);
+// m_coll->groupModified(group_);
+ return true;
+}
+
+bool Entry::removeFromGroup(EntryGroup* group_) {
+ // if the removal isn't successful, just return
+ bool success = m_groups.remove(group_);
+ success = success && group_->remove(this);
+// myDebug() << "Entry::removeFromGroup() - removing from group - "
+// << group_->fieldName() << "::" << group_->groupName() << endl;
+ if(success) {
+// m_coll->groupModified(group_);
+ } else {
+ myDebug() << "Entry::removeFromGroup() failed! " << endl;
+ }
+ return success;
+}
+
+void Entry::clearGroups() {
+ m_groups.clear();
+}
+
+// this function gets called before m_groups is updated. In fact, it is used to
+// update that list. This is the function that actually parses the field values
+// and returns the list of the group names.
+QStringList Entry::groupNamesByFieldName(const QString& fieldName_) const {
+// myDebug() << "Entry::groupsByfieldName() - " << fieldName_ << endl;
+ FieldPtr f = m_coll->fieldByName(fieldName_);
+
+ // easy if not allowing multiple values
+ if(!(f->flags() & Field::AllowMultiple)) {
+ QString value = formattedField(fieldName_);
+ if(value.isEmpty()) {
+ return i18n(Collection::s_emptyGroupTitle);
+ } else {
+ return value;
+ }
+ }
+
+ QStringList groups = fields(fieldName_, true);
+ if(groups.isEmpty()) {
+ return i18n(Collection::s_emptyGroupTitle);
+ } else if(f->type() == Field::Table) {
+ // quick hack for tables, how often will a user have "::" in their value?
+ // only use first column for group
+ QStringList::Iterator it = groups.begin();
+ while(it != groups.end()) {
+ (*it) = (*it).section(QString::fromLatin1("::"), 0, 0);
+ if((*it).isEmpty()) {
+ it = groups.remove(it); // points to next in list
+ } else {
+ ++it;
+ }
+ }
+ }
+ return groups;
+}
+
+bool Entry::isOwned() {
+ return (m_coll && m_id > -1 && m_coll->entryCount() > 0 && m_coll->entries().contains(this));
+}
+
+// a null string means invalidate all
+void Entry::invalidateFormattedFieldValue(const QString& name_) {
+ if(name_.isNull()) {
+ m_formattedFields.clear();
+ } else if(!m_formattedFields.isEmpty() && m_formattedFields.contains(name_)) {
+ m_formattedFields.remove(name_);
+ }
+}
+
+// format is something like "%{year} %{author}"
+QString Entry::dependentValue(ConstEntryPtr entry_, const QString& format_, bool formatted_) {
+ if(!entry_) {
+ return format_;
+ }
+
+ QString result, fieldName;
+ FieldPtr field;
+
+ int endPos;
+ int curPos = 0;
+ int pctPos = format_.find('%', curPos);
+ while(pctPos != -1 && pctPos+1 < static_cast<int>(format_.length())) {
+ if(format_[pctPos+1] == '{') {
+ endPos = format_.find('}', pctPos+2);
+ if(endPos > -1) {
+ result += format_.mid(curPos, pctPos-curPos);
+ fieldName = format_.mid(pctPos+2, endPos-pctPos-2);
+ field = entry_->collection()->fieldByName(fieldName);
+ if(!field) {
+ // allow the user to also use field titles
+ field = entry_->collection()->fieldByTitle(fieldName);
+ }
+ if(field) {
+ // don't format, just capitalize
+ result += entry_->field(field, formatted_);
+ } else if(fieldName == Latin1Literal("id")) {
+ result += QString::number(entry_->id());
+ } else {
+ result += format_.mid(pctPos, endPos-pctPos+1);
+ }
+ curPos = endPos+1;
+ } else {
+ break;
+ }
+ } else {
+ result += format_.mid(curPos, pctPos-curPos+1);
+ curPos = pctPos+1;
+ }
+ pctPos = format_.find('%', curPos);
+ }
+ result += format_.mid(curPos, format_.length()-curPos);
+// myDebug() << "Entry::dependentValue() - " << format_ << " = " << result << endl;
+ // sometimes field value might empty, resulting in multiple consecutive white spaces
+ // so let's simplify that...
+ return result.simplifyWhiteSpace();
+}
+
+int Entry::compareValues(EntryPtr e1, EntryPtr e2, const QString& f, ConstCollPtr c) {
+ return compareValues(e1, e2, c->fieldByName(f));
+}
+
+int Entry::compareValues(EntryPtr e1, EntryPtr e2, FieldPtr f) {
+ if(!e1 || !e2 || !f) {
+ return 0;
+ }
+ QString s1 = e1->field(f).lower();
+ QString s2 = e2->field(f).lower();
+ if(s1.isEmpty() || s2.isEmpty()) {
+ return 0;
+ }
+ // complicated string matching, here are the cases I want to match
+ // "bend it like beckham" == "bend it like beckham (widescreen edition)"
+ // "the return of the king" == "return of the king"
+ if(s1 == s2) {
+ return 5;
+ }
+ // special case for isbn
+ if(f->name() == Latin1Literal("isbn") && ISBNValidator::isbn10(s1) == ISBNValidator::isbn10(s2)) {
+ return 5;
+ }
+ if(f->name() == Latin1Literal("lccn") && LCCNValidator::formalize(s1) == LCCNValidator::formalize(s2)) {
+ return 5;
+ }
+ if(f->formatFlag() == Field::FormatName) {
+ s1 = e1->field(f, true).lower();
+ s2 = e2->field(f, true).lower();
+ if(s1 == s2) {
+ return 5;
+ }
+ }
+ // try removing punctuation
+ QRegExp notAlphaNum(QString::fromLatin1("[^\\s\\w]"));
+ QString s1a = s1; s1a.remove(notAlphaNum);
+ QString s2a = s2; s2a.remove(notAlphaNum);
+ if(!s1a.isEmpty() && s1a == s2a) {
+// myDebug() << "match without punctuation" << endl;
+ return 5;
+ }
+ Field::stripArticles(s1);
+ Field::stripArticles(s2);
+ if(!s1.isEmpty() && s1 == s2) {
+// myDebug() << "match without articles" << endl;
+ return 3;
+ }
+ // try removing everything between parentheses
+ QRegExp rx(QString::fromLatin1("\\s*\\(.*\\)\\s*"));
+ s1.remove(rx);
+ s2.remove(rx);
+ if(!s1.isEmpty() && s1 == s2) {
+// myDebug() << "match without parentheses" << endl;
+ return 2;
+ }
+ if(f->flags() & Field::AllowMultiple) {
+ QStringList sl1 = e1->fields(f, false);
+ QStringList sl2 = e2->fields(f, false);
+ int matches = 0;
+ for(QStringList::ConstIterator it = sl1.begin(); it != sl1.end(); ++it) {
+ matches += sl2.contains(*it);
+ }
+ if(matches == 0 && f->formatFlag() == Field::FormatName) {
+ sl1 = e1->fields(f, true);
+ sl2 = e2->fields(f, true);
+ for(QStringList::ConstIterator it = sl1.begin(); it != sl1.end(); ++it) {
+ matches += sl2.contains(*it);
+ }
+ }
+ return matches;
+ }
+ return 0;
+}
+
+#include "entry.moc"
diff --git a/src/entry.h b/src/entry.h
new file mode 100644
index 0000000..bff3d7d
--- /dev/null
+++ b/src/entry.h
@@ -0,0 +1,256 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_ENTRY_H
+#define TELLICO_ENTRY_H
+
+#include "datavectors.h"
+
+#include <qstringlist.h>
+#include <qstring.h>
+#include <qobject.h>
+
+#include <functional>
+
+namespace Tellico {
+ namespace Data {
+ class Collection;
+
+/**
+ * The EntryGroup is simply a vector of entries which knows the name of its group,
+ * and the name of the field to which that group belongs.
+ *
+ * An example for a book collection would be a group of books, all written by
+ * David Weber. The @ref groupName() would be "Weber, David" and the
+ * @ref fieldName() would be "author".
+ *
+ * It's a QObject because EntryGroupItem holds a QGuardedPtr
+ *
+ * @author Robby Stephenson
+ */
+class EntryGroup : public QObject, public EntryVec {
+Q_OBJECT
+
+public:
+ EntryGroup(const QString& group, const QString& field);
+ ~EntryGroup();
+
+ const QString& groupName() const { return m_group; }
+ const QString& fieldName() const { return m_field; }
+
+private:
+ QString m_group;
+ QString m_field;
+};
+
+/**
+ * The Entry class represents a book, a CD, or whatever is the basic entity
+ * in the collection.
+ *
+ * Each Entry object has a set of field values, such as title, artist, or format,
+ * and must belong to a collection. A unique id number identifies each entry.
+ *
+ * @see Field
+ *
+ * @author Robby Stephenson
+ */
+class Entry : public KShared {
+
+public:
+ /**
+ * The constructor, which automatically sets the id to the current number
+ * of entries in the collection.
+ *
+ * @param coll A pointer to the parent collection object
+ */
+ Entry(CollPtr coll);
+ Entry(CollPtr coll, int id);
+ /**
+ * The copy constructor, needed since the id must be different.
+ */
+ Entry(const Entry& entry);
+ /**
+ * The assignment operator is overloaded, since the id must be different.
+ */
+ Entry& operator=(const Entry& other);
+ /**
+ * two entries are equal if all their field values are equal, except for
+ * file catalogs which match on the url only
+ */
+ bool operator==(const Entry& other);
+
+ ~Entry();
+
+ /**
+ * Every entry has a title.
+ *
+ * @return The entry title
+ */
+ QString title() const;
+ /**
+ * Returns the value of the field with a given key name. If the key doesn't
+ * exist, the method returns @ref QString::null.
+ *
+ * @param fieldName The field name
+ * @param formatted Whether to format the field or not.
+ * @return The value of the field
+ */
+ QString field(const QString& fieldName, bool formatted=false) const;
+ QString field(Data::FieldPtr field, bool formatted=false) const;
+ /**
+ * Returns the formatted value of the field with a given key name. If the
+ * key doesn't exist, the method returns @ref QString::null. The value is cached,
+ * so the first time the value is requested, @ref Field::format is called.
+ * The second time, that lookup isn't necessary.
+ *
+ * @param fieldName The field name
+ * @return The formatted value of the field
+ */
+ QString formattedField(const QString& fieldName) const;
+ QString formattedField(Data::FieldPtr field) const;
+ /**
+ * Splits a field value. This is faster than calling Data::Field::split() since
+ * a regexp is not used, only a string.
+ *
+ * @param field The field name
+ * @param format Whether to format the values or not
+ * @return The list of field values
+ */
+ QStringList fields(const QString& fieldName, bool formatted) const;
+ QStringList fields(Data::FieldPtr field, bool formatted) const;
+ /**
+ * Sets the value of an field for the entry. The method first verifies that
+ * the value is allowed for that particular key.
+ *
+ * @param fieldName The name of the field
+ * @param value The value of the field
+ * @return A boolean indicating whether or not the field was successfully set
+ */
+ bool setField(const QString& fieldName, const QString& value);
+ bool setField(Data::FieldPtr field, const QString& value);
+ /**
+ * Returns a pointer to the parent collection of the entry.
+ *
+ * @return The collection pointer
+ */
+ CollPtr collection() const;
+ /**
+ * Changes the collection owner of the entry
+ */
+ void setCollection(CollPtr coll);
+ /**
+ * Returns the id of the entry
+ *
+ * @return The id
+ */
+ long id() const { return m_id; }
+ void setId(long id) { m_id = id; }
+ /**
+ * Adds the entry to a group. The group list within the entry is updated
+ * and the entry is added to the group.
+ *
+ * @param group The group
+ * @return a bool indicating if it was successfully added. If the entry was already
+ * in the group, the return value is false
+ */
+ bool addToGroup(EntryGroup* group);
+ /**
+ * Removes the entry from a group. The group list within the entry is updated
+ * and the entry is removed from the group.
+ *
+ * @param group The group
+ * @return a bool indicating if the group was successfully removed
+ */
+ bool removeFromGroup(EntryGroup* group);
+ void clearGroups();
+ /**
+ * Returns a list of the groups to which the entry belongs
+ *
+ * @return The list of groups
+ */
+ const PtrVector<EntryGroup>& groups() const { return m_groups; }
+ /**
+ * Returns a list containing the names of the groups for
+ * a certain field to which the entry belongs
+ *
+ * @param fieldName The name of the field
+ * @return The list of names
+ */
+ QStringList groupNamesByFieldName(const QString& fieldName) const;
+ /**
+ * Returns a list of all the field values contained in the entry.
+ *
+ * @return The list of field values
+ */
+ QStringList fieldValues() const { return m_fields.values(); }
+ /**
+ * Returns a list of all the formatted field values contained in the entry.
+ *
+ * @return The list of field values
+ */
+ QStringList formattedFieldValues() const { return m_formattedFields.values(); }
+ /**
+ * Returns a boolean indicating if the entry's parent collection recognizes
+ * it existence, that is, the parent collection has this entry in its list.
+ *
+ * @return Whether the entry is owned or not
+ */
+ bool isOwned();
+ /**
+ * Removes the formatted value of the field from the map. This should be used when
+ * the field's format flag has changed.
+ *
+ * @param name The name of the field that changed. QString::null means invalidate all fields.
+ */
+ void invalidateFormattedFieldValue(const QString& name=QString::null);
+
+ static int compareValues(EntryPtr entry1, EntryPtr entry2, FieldPtr field);
+ static int compareValues(EntryPtr entry1, EntryPtr entry2, const QString& field, ConstCollPtr coll);
+
+ /**
+ * Construct the derived valued for an field. The format string should be
+ * of the form "%{name1} %{name2}" where the names are replaced by the value
+ * of that field for the entry. Whether or not formatting is done on the
+ * strings themselves should be taken into account.
+ *
+ * @param formatString The format string
+ * @param formatted Whether the inserted values should be formatted.
+ * @return The constructed field value
+ */
+ static QString dependentValue(ConstEntryPtr e, const QString& formatString, bool formatted);
+
+private:
+ CollPtr m_coll;
+ long m_id;
+ StringMap m_fields;
+ mutable StringMap m_formattedFields;
+ PtrVector<EntryGroup> m_groups;
+};
+
+class EntryCmp : public std::binary_function<EntryPtr, EntryPtr, bool> {
+
+public:
+ EntryCmp(const QString& field) : m_field(field) {}
+
+ bool operator()(EntryPtr e1, EntryPtr e2) const {
+ return e1->field(m_field) < e2->field(m_field);
+ }
+
+private:
+ QString m_field;
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/entryeditdialog.cpp b/src/entryeditdialog.cpp
new file mode 100644
index 0000000..db99d7f
--- /dev/null
+++ b/src/entryeditdialog.cpp
@@ -0,0 +1,757 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "entryeditdialog.h"
+#include "gui/tabcontrol.h"
+#include "collection.h"
+#include "controller.h"
+#include "field.h"
+#include "entry.h"
+#include "tellico_utils.h"
+#include "tellico_kernel.h"
+#include "tellico_debug.h"
+#include "latin1literal.h"
+
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kaccelmanager.h>
+#include <kiconloader.h>
+#include <kdeversion.h>
+#include <kpushbutton.h>
+#include <kaccel.h>
+
+#include <qlayout.h>
+#include <qstringlist.h>
+#include <qpushbutton.h>
+#include <qvaluevector.h>
+#include <qvbox.h>
+#include <qobjectlist.h>
+#include <qtabbar.h>
+#include <qstyle.h>
+#include <qapplication.h>
+
+namespace {
+ // must be an even number
+ static const int NCOLS = 2; // number of columns of GUI::FieldWidgets
+}
+
+using Tellico::EntryEditDialog;
+
+EntryEditDialog::EntryEditDialog(QWidget* parent_, const char* name_)
+ : KDialogBase(parent_, name_, false, i18n("Edit Entry"), Help|User1|User2|User3|Apply|Close, User1, false,
+ KGuiItem(i18n("&New Entry"))),
+ m_currColl(0),
+ m_tabs(new GUI::TabControl(this)),
+ m_modified(false),
+ m_isOrphan(false),
+ m_isWorking(false),
+ m_needReset(false) {
+ setMainWidget(m_tabs);
+
+ m_prevBtn = User3;
+ m_nextBtn = User2;
+ m_newBtn = User1;
+ m_saveBtn = Apply;
+ KGuiItem save = KStdGuiItem::save();
+ save.setText(i18n("Sa&ve Entry"));
+ setButtonGuiItem(m_saveBtn, save);
+ enableButton(m_saveBtn, false);
+
+ connect(this, SIGNAL(applyClicked()), SLOT(slotHandleSave()));
+ connect(this, SIGNAL(user1Clicked()), SLOT(slotHandleNew()));
+ connect(this, SIGNAL(user2Clicked()), SLOT(slotGoNextEntry()));
+ connect(this, SIGNAL(user3Clicked()), SLOT(slotGoPrevEntry()));
+
+ KGuiItem prev;
+ prev.setIconName(QString::fromLatin1(QApplication::reverseLayout() ? "forward" : "back"));
+ prev.setToolTip(i18n("Go to the previous entry in the collection"));
+ prev.setWhatsThis(prev.toolTip());
+
+ KGuiItem next;
+ next.setIconName(QString::fromLatin1(QApplication::reverseLayout() ? "back" : "forward"));
+ next.setToolTip(i18n("Go to the next entry in the collection"));
+ next.setWhatsThis(next.toolTip());
+
+ setButtonGuiItem(m_nextBtn, next);
+ setButtonGuiItem(m_prevBtn, prev);
+
+ KAccel* accel = new KAccel(this);
+ accel->insert(QString::fromLatin1("Go Prev"), QString(), prev.toolTip(), Qt::Key_PageUp,
+ Controller::self(), SLOT(slotGoPrevEntry()));
+ accel->insert(QString::fromLatin1("Go Next"), QString(), next.toolTip(), Qt::Key_PageDown,
+ Controller::self(), SLOT(slotGoNextEntry()));
+
+ setHelp(QString::fromLatin1("entry-editor"));
+
+ resize(configDialogSize(QString::fromLatin1("Edit Dialog Options")));
+}
+
+void EntryEditDialog::slotClose() {
+ // check to see if an entry should be saved before hiding
+ // block signals so the entry view and selection isn't cleared
+ if(queryModified()) {
+ hide();
+// blockSignals(true);
+// slotHandleNew();
+// blockSignals(false);
+ }
+}
+
+void EntryEditDialog::slotReset() {
+// myDebug() << "EntryEditDialog::slotReset()" << endl;
+ if(m_isWorking) {
+ return;
+ }
+
+ enableButton(m_saveBtn, false);
+ setButtonText(m_saveBtn, i18n("Sa&ve Entry"));
+ m_currColl = 0;
+ m_currEntries.clear();
+
+ m_modified = false;
+
+ m_tabs->clear(); // GUI::FieldWidgets get deleted here
+ m_widgetDict.clear();
+}
+
+void EntryEditDialog::setLayout(Data::CollPtr coll_) {
+ if(!coll_ || m_isWorking) {
+ return;
+ }
+// myDebug() << "EntryEditDialog::setLayout()" << endl;
+
+ actionButton(m_newBtn)->setIconSet(UserIconSet(coll_->typeName()));
+
+ setUpdatesEnabled(false);
+ if(m_tabs->count() > 0) {
+// myDebug() << "EntryEditDialog::setLayout() - resetting contents." << endl;
+ slotReset();
+ }
+ m_isWorking = true;
+
+ m_currColl = coll_;
+
+ int maxHeight = 0;
+ QPtrList<QWidget> gridList;
+ bool noChoices = true;
+
+ bool focusedFirst = false;
+ QStringList catList = m_currColl->fieldCategories();
+ for(QStringList::ConstIterator catIt = catList.begin(); catIt != catList.end(); ++catIt) {
+ Data::FieldVec fields = m_currColl->fieldsByCategory(*catIt);
+ if(fields.isEmpty()) { // sanity check
+ continue;
+ }
+
+ // if this layout model is changed, be sure to check slotUpdateField()
+ QWidget* page = new QWidget(m_tabs);
+ // (parent, margin, spacing)
+ QVBoxLayout* boxLayout = new QVBoxLayout(page, 0, 0);
+
+ QWidget* grid = new QWidget(page);
+ gridList.append(grid);
+ // (parent, nrows, ncols, margin, spacing)
+ // spacing gets a bit weird, if there are absolutely no Choice fields,
+ // then spacing should be 5, which is set later
+ QGridLayout* layout = new QGridLayout(grid, 0, NCOLS, 8, 2);
+ // keramik styles make big widget, cut down the spacing a bit
+ if(QCString(style().name()).lower().find("keramik", 0, false) > -1) {
+ layout->setSpacing(0);
+ }
+
+ boxLayout->addWidget(grid, 0);
+ // those with multiple, get a stretch
+ if(fields.count() > 1 || !fields[0]->isSingleCategory()) {
+ boxLayout->addStretch(1);
+ }
+
+ // keep track of which should expand
+ QValueVector<bool> expands(NCOLS, false);
+ QValueVector<int> maxWidth(NCOLS, 0);
+
+ Data::FieldVec::Iterator it = fields.begin(); // needed later
+ for(int count = 0; it != fields.end(); ++it) {
+ Data::FieldPtr field = it;
+ // ReadOnly and Dependent fields don't get widgets
+ if(field->type() == Data::Field::ReadOnly || field->type() == Data::Field::Dependent) {
+ continue;
+ }
+ if(field->type() == Data::Field::Choice) {
+ noChoices = false;
+ }
+
+ GUI::FieldWidget* widget = GUI::FieldWidget::create(field, grid);
+ if(!widget) {
+ continue;
+ }
+ connect(widget, SIGNAL(modified()), SLOT(slotSetModified()));
+ if(!focusedFirst && widget->isFocusEnabled()) {
+ widget->setFocus();
+ focusedFirst = true;
+ }
+
+ int r = count/NCOLS;
+ int c = count%NCOLS;
+ layout->addWidget(widget, r, c);
+ layout->setRowStretch(r, 1);
+
+ m_widgetDict.insert(QString::number(m_currColl->id()) + field->name(), widget);
+
+ maxWidth[count%NCOLS] = QMAX(maxWidth[count%NCOLS], widget->labelWidth());
+ if(widget->expands()) {
+ expands[count%NCOLS] = true;
+ }
+ widget->updateGeometry();
+ if(!field->isSingleCategory()) {
+ maxHeight = QMAX(maxHeight, widget->minimumSizeHint().height());
+ }
+ ++count;
+ }
+
+ // now, the labels in a column should all be the same width
+ it = fields.begin();
+ for(int count = 0; it != fields.end(); ++it) {
+ GUI::FieldWidget* widget = m_widgetDict.find(QString::number(m_currColl->id()) + it->name());
+ if(widget) {
+ widget->setLabelWidth(maxWidth[count%NCOLS]);
+ ++count;
+ }
+ }
+
+ // update stretch factors for columns with a line edit
+ for(int col = 0; col < NCOLS; ++col) {
+ if(expands[col]) {
+ layout->setColStretch(col, 1);
+ }
+ }
+
+ m_tabs->addTab(page, *catIt);
+ }
+
+ // Now, go through and set all the field widgets to the same height
+ for(QPtrListIterator<QWidget> it(gridList); it.current(); ++it) {
+ QGridLayout* l = static_cast<QGridLayout*>(it.current()->layout());
+ if(noChoices) {
+ l->setSpacing(5);
+ }
+ for(int row = 0; row < l->numRows() && it.current()->children()->count() > 1; ++row) {
+ l->addRowSpacing(row, maxHeight);
+ }
+ // I don't want anything to be hidden, Keramik has a bug if I don't do this
+ it.current()->setMinimumHeight(it.current()->sizeHint().height());
+ // the parent of the grid is the page that got added to the tabs
+ it.current()->parentWidget()->layout()->invalidate();
+ it.current()->parentWidget()->setMinimumHeight(it.current()->parentWidget()->sizeHint().height());
+ }
+
+ setUpdatesEnabled(true);
+// this doesn't seem to work
+// setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
+// so do this instead
+ layout()->invalidate(); // needed so the sizeHint() gets recalculated
+ m_tabs->setMinimumHeight(m_tabs->minimumSizeHint().height());
+ m_tabs->setMinimumWidth(m_tabs->sizeHint().width());
+
+ // update keyboard accels
+ // only want to manage tabBar()
+ KAcceleratorManager::manage(m_tabs->tabBar());
+
+ m_tabs->setCurrentPage(0);
+
+ m_isWorking = false;
+ slotHandleNew();
+ m_modified = false; // because the year is inserted
+}
+
+void EntryEditDialog::slotHandleNew() {
+ if(!m_currColl || !queryModified()) {
+ return;
+ }
+
+ m_tabs->setCurrentPage(0);
+ m_tabs->setFocusToFirstChild();
+ clear();
+ m_isWorking = true; // clear() will get called again
+ Controller::self()->slotClearSelection();
+ m_isWorking = false;
+
+ enableButton(m_prevBtn, false);
+ enableButton(m_nextBtn, false);
+
+ Data::EntryPtr entry = new Data::Entry(m_currColl);
+ m_currEntries.append(entry);
+ m_isOrphan = true;
+}
+
+void EntryEditDialog::slotHandleSave() {
+ if(!m_currColl || m_isWorking) {
+ return;
+ }
+
+ m_isWorking = true;
+
+ if(m_currEntries.isEmpty()) {
+ myDebug() << "EntryEditDialog::slotHandleSave() - creating new entry" << endl;
+ m_currEntries.append(new Data::Entry(m_currColl));
+ m_isOrphan = true;
+ }
+
+ // add a message box if multiple items are selected
+ if(m_currEntries.count() > 1) {
+ QStringList names;
+ for(Data::EntryVec::ConstIterator entry = m_currEntries.constBegin(); entry != m_currEntries.constEnd(); ++entry) {
+ names += entry->title();
+ }
+ QString str(i18n("Do you really want to modify these entries?"));
+ QString dontAsk = QString::fromLatin1("SaveMultipleBooks"); // don't change 'books', invisible anyway
+ int ret = KMessageBox::questionYesNoList(this, str, names, i18n("Modify Multiple Entries"),
+ KStdGuiItem::yes(), KStdGuiItem::no(), dontAsk);
+ if(ret != KMessageBox::Yes) {
+ m_isWorking = false;
+ return;
+ }
+ }
+
+ GUI::CursorSaver cs;
+
+ Data::EntryVec oldEntries;
+ Data::FieldVec fields = m_currColl->fields();
+ Data::FieldVec fieldsRequiringValues;
+ // boolean to keep track if any field gets changed
+ bool modified = false;
+ for(Data::EntryVecIt entry = m_currEntries.begin(); entry != m_currEntries.end(); ++entry) {
+ // if the entry is owned, then we're modifying an existing entry, keep a copy of the old one
+ if(entry->isOwned()) {
+ oldEntries.append(new Data::Entry(*entry));
+ }
+ for(Data::FieldVec::Iterator fIt = fields.begin(); fIt != fields.end(); ++fIt) {
+ QString key = QString::number(m_currColl->id()) + fIt->name();
+ GUI::FieldWidget* widget = m_widgetDict.find(key);
+ if(widget && widget->isEnabled()) {
+ QString temp = widget->text();
+ // ok to set field empty string, just not all of them
+ if(modified == false && entry->field(fIt) != temp) {
+ modified = true;
+ }
+ entry->setField(fIt, temp);
+ if(temp.isEmpty()) {
+ QString prop = fIt->property(QString::fromLatin1("required")).lower();
+ if(prop == Latin1Literal("1") || prop == Latin1Literal("true")) {
+ fieldsRequiringValues.append(fIt.data());
+ }
+ }
+ }
+ }
+ }
+
+ if(!fieldsRequiringValues.isEmpty()) {
+ GUI::CursorSaver cs2(Qt::arrowCursor);
+ QString str = i18n("A value is required for the following fields. Do you want to continue?");
+ QStringList titles;
+ for(Data::FieldVecIt it = fieldsRequiringValues.begin(); it != fieldsRequiringValues.end(); ++it) {
+ titles << it->title();
+ }
+ QString dontAsk = QString::fromLatin1("SaveWithoutRequired");
+ int ret = KMessageBox::questionYesNoList(this, str, titles, i18n("Modify Entries"),
+ KStdGuiItem::yes(), KStdGuiItem::no(), dontAsk);
+ if(ret != KMessageBox::Yes) {
+ m_isWorking = false;
+ return;
+ }
+ }
+
+ // if something was not empty, signal a save
+ if(modified) {
+ m_isOrphan = false;
+ if(oldEntries.isEmpty()) {
+ Kernel::self()->addEntries(m_currEntries, false);
+ } else {
+ Kernel::self()->modifyEntries(oldEntries, m_currEntries);
+ }
+ if(!m_currEntries.isEmpty() && !m_currEntries[0]->title().isEmpty()) {
+ setCaption(i18n("Edit Entry") + QString::fromLatin1(" - ") + m_currEntries[0]->title());
+ }
+ }
+
+ m_modified = false;
+ m_isWorking = false;
+ enableButton(m_saveBtn, false);
+// slotHandleNew();
+}
+
+void EntryEditDialog::clear() {
+ if(m_isWorking) {
+ return;
+ }
+// myDebug() << "EntryEditDialog::clear()" << endl;
+
+ m_isWorking = true;
+ // clear the widgets
+ for(QDictIterator<GUI::FieldWidget> it(m_widgetDict); it.current(); ++it) {
+ it.current()->setEnabled(true);
+ it.current()->clear();
+ it.current()->insertDefault();
+ }
+
+ setCaption(i18n("Edit Entry"));
+
+ if(m_isOrphan) {
+ if(m_currEntries.count() > 1) {
+ kdWarning() << "EntryEditDialog::clear() - is an orphan, but more than one" << endl;
+ }
+ m_isOrphan = false;
+ }
+ m_currEntries.clear();
+
+ setButtonText(m_saveBtn, i18n("Sa&ve Entry"));
+ enableButton(m_saveBtn, false);
+
+ m_modified = false;
+ m_isWorking = false;
+}
+
+void EntryEditDialog::setContents(Data::EntryVec entries_) {
+ // this slot might get called if we try to save multiple items, so just return
+ if(m_isWorking) {
+ return;
+ }
+
+ if(entries_.isEmpty()) {
+// myDebug() << "EntryEditDialog::setContents() - empty list" << endl;
+ if(queryModified()) {
+ blockSignals(true);
+ slotHandleNew();
+ blockSignals(false);
+ }
+ return;
+ }
+
+// myDebug() << "EntryEditDialog::setContents() - " << entries_.count() << " entries" << endl;
+
+ // if some entries get selected in one view, then in another, don't reset
+ if(!m_needReset && entries_ == m_currEntries) {
+ return;
+ }
+ m_needReset = false;
+
+ // first set contents to first item
+ setContents(entries_.front());
+ // something weird...if list count can actually be 1 before the setContents call
+ // and 0 after it. Why is that? It's const!
+ if(entries_.count() < 2) {
+ return;
+ }
+
+ // multiple entries, so don't set caption
+ setCaption(i18n("Edit Entries"));
+
+ m_currEntries = entries_;
+ m_isWorking = true;
+ blockSignals(true);
+
+ Data::EntryVec::ConstIterator entry;
+ Data::FieldVec fields = m_currColl->fields();
+ for(Data::FieldVec::Iterator fIt = fields.begin(); fIt != fields.end(); ++fIt) {
+ QString key = QString::number(m_currColl->id()) + fIt->name();
+ GUI::FieldWidget* widget = m_widgetDict.find(key);
+ if(!widget) { // probably read-only
+ continue;
+ }
+ widget->editMultiple(true);
+
+ QString value = entries_[0]->field(fIt);
+ entry = entries_.constBegin();
+ for(++entry; entry != entries_.constEnd(); ++entry) { // skip checking the first one
+ if(entry->field(fIt) != value) {
+ widget->setEnabled(false);
+ break;
+ }
+ }
+ } // end field loop
+
+ blockSignals(false);
+ m_isWorking = false;
+
+ // can't go to next entry if multiple are selected
+ enableButton(m_prevBtn, false);
+ enableButton(m_nextBtn, false);
+ setButtonText(m_saveBtn, i18n("Sa&ve Entries"));
+}
+
+void EntryEditDialog::setContents(Data::EntryPtr entry_) {
+ bool ok = queryModified();
+ if(!ok || m_isWorking) {
+ return;
+ }
+
+ if(!entry_) {
+ myDebug() << "EntryEditDialog::setContents() - null entry pointer" << endl;
+ slotHandleNew();
+ return;
+ }
+
+// myDebug() << "EntryEditDialog::setContents() - " << entry_->title() << endl;
+ blockSignals(true);
+ clear();
+ blockSignals(false);
+
+ m_isWorking = true;
+ m_currEntries.append(entry_);
+
+ if(!entry_->title().isEmpty()) {
+ setCaption(i18n("Edit Entry") + QString::fromLatin1(" - ") + entry_->title());
+ }
+
+ if(m_currColl != entry_->collection()) {
+ myDebug() << "EntryEditDialog::setContents() - collections don't match" << endl;
+ m_currColl = entry_->collection();
+ }
+
+// m_tabs->showTab(0);
+
+ slotSetModified(false);
+
+ Data::FieldVec fields = m_currColl->fields();
+ for(Data::FieldVec::Iterator field = fields.begin(); field != fields.end(); ++field) {
+ QString key = QString::number(m_currColl->id()) + field->name();
+ GUI::FieldWidget* widget = m_widgetDict.find(key);
+ if(!widget) { // is probably read-only
+ continue;
+ }
+
+ widget->setText(entry_->field(field));
+ widget->setEnabled(true);
+ widget->editMultiple(false);
+ } // end field loop
+
+ enableButton(m_prevBtn, true);
+ enableButton(m_nextBtn, true);
+ if(entry_->isOwned()) {
+ setButtonText(m_saveBtn, i18n("Sa&ve Entry"));
+ enableButton(m_saveBtn, m_modified);
+ } else {
+ slotSetModified(true);
+ }
+ m_isWorking = false;
+}
+
+void EntryEditDialog::removeField(Data::CollPtr, Data::FieldPtr field_) {
+ if(!field_) {
+ return;
+ }
+
+// myDebug() << "EntryEditDialog::removeField - name = " << field_->name() << endl;
+ QString key = QString::number(m_currColl->id()) + field_->name();
+ GUI::FieldWidget* widget = m_widgetDict.find(key);
+ if(widget) {
+ m_widgetDict.remove(key);
+ // if this is the last field in the category, need to remove the tab page
+ // this function is called after the field has been removed from the collection,
+ // so the category should be gone from the category list
+ if(m_currColl->fieldCategories().findIndex(field_->category()) == -1) {
+// myDebug() << "last field in the category" << endl;
+ // fragile, widget's parent is the grid, whose parent is the tab page
+ QWidget* w = widget->parentWidget()->parentWidget();
+ m_tabs->removePage(w);
+ delete w; // automatically deletes child widget
+ } else {
+ // much of this replicates code in setLayout()
+ QGridLayout* layout = static_cast<QGridLayout*>(widget->parentWidget()->layout());
+ delete widget; // automatically removes from layout
+
+ QValueVector<bool> expands(NCOLS, false);
+ QValueVector<int> maxWidth(NCOLS, 0);
+
+ Data::FieldVec vec = m_currColl->fieldsByCategory(field_->category());
+ Data::FieldVec::Iterator it = vec.begin();
+ for(int count = 0; it != vec.end(); ++it) {
+ GUI::FieldWidget* widget = m_widgetDict.find(QString::number(m_currColl->id()) + it->name());
+ if(widget) {
+ layout->remove(widget);
+ layout->addWidget(widget, count/NCOLS, count%NCOLS);
+
+ maxWidth[count%NCOLS] = QMAX(maxWidth[count%NCOLS], widget->labelWidth());
+ if(widget->expands()) {
+ expands[count%NCOLS] = true;
+ }
+ widget->updateGeometry();
+ ++count;
+ }
+ }
+
+ // now, the labels in a column should all be the same width
+ it = vec.begin();
+ for(int count = 0; it != vec.end(); ++it) {
+ GUI::FieldWidget* widget = m_widgetDict.find(QString::number(m_currColl->id()) + it->name());
+ if(widget) {
+ widget->setLabelWidth(maxWidth[count%NCOLS]);
+ ++count;
+ }
+ }
+
+ // update stretch factors for columns with a line edit
+ for(int col = 0; col < NCOLS; ++col) {
+ if(expands[col]) {
+ layout->setColStretch(col, 1);
+ }
+ }
+ }
+ }
+}
+
+void EntryEditDialog::updateCompletions(Data::EntryPtr entry_) {
+#ifndef NDEBUG
+ if(m_currColl != entry_->collection()) {
+ myDebug() << "EntryEditDialog::updateCompletions - inconsistent collection pointers!" << endl;
+// m_currColl = entry_->collection();
+ }
+#endif
+
+ Data::FieldVec fields = m_currColl->fields();
+ for(Data::FieldVec::Iterator it = fields.begin(); it != fields.end(); ++it) {
+ if(it->type() != Data::Field::Line
+ || !(it->flags() & Data::Field::AllowCompletion)) {
+ continue;
+ }
+
+ QString key = QString::number(m_currColl->id()) + it->name();
+ GUI::FieldWidget* widget = m_widgetDict.find(key);
+ if(!widget) {
+ continue;
+ }
+ if(it->flags() & Data::Field::AllowMultiple) {
+ QStringList items = entry_->fields(it, false);
+ for(QStringList::ConstIterator it = items.begin(); it != items.end(); ++it) {
+ widget->addCompletionObjectItem(*it);
+ }
+ } else {
+ widget->addCompletionObjectItem(entry_->field(it->name()));
+ }
+ }
+}
+
+void EntryEditDialog::slotSetModified(bool mod_/*=true*/) {
+ m_modified = mod_;
+ enableButton(m_saveBtn, mod_);
+}
+
+bool EntryEditDialog::queryModified() {
+// myDebug() << "EntryEditDialog::queryModified() - modified is " << (m_modified?"true":"false") << endl;
+ bool ok = true;
+ // assume that if the dialog is hidden, we shouldn't ask the user to modify changes
+ if(!isShown()) {
+ m_modified = false;
+ }
+ if(m_modified) {
+ QString str(i18n("The current entry has been modified.\n"
+ "Do you want to enter the changes?"));
+ KGuiItem item = KStdGuiItem::save();
+ item.setText(i18n("Save Entry"));
+ int want_save = KMessageBox::warningYesNoCancel(this, str, i18n("Unsaved Changes"),
+ item, KStdGuiItem::discard());
+ switch(want_save) {
+ case KMessageBox::Yes:
+ slotHandleSave();
+ ok = true;
+ break;
+
+ case KMessageBox::No:
+ m_modified = false;
+ ok = true;
+ break;
+
+ case KMessageBox::Cancel:
+ ok = false;
+ break;
+ }
+ }
+ return ok;
+}
+
+// modified fields will always have the same name
+void EntryEditDialog::modifyField(Data::CollPtr coll_, Data::FieldPtr oldField_, Data::FieldPtr newField_) {
+// myDebug() << "EntryEditDialog::slotUpdateField() - " << newField_->name() << endl;
+
+ if(coll_ != m_currColl) {
+ myDebug() << "EntryEditDialog::slotUpdateField() - wrong collection pointer!" << endl;
+ m_currColl = coll_;
+ }
+
+ // if the field type changed, go ahead and redo the whole layout
+ // also if the category changed for a non-single field, since a new tab must be created
+ if(oldField_->type() != newField_->type()
+ || (oldField_->category() != newField_->category() && !newField_->isSingleCategory())) {
+ bool modified = m_modified;
+ setLayout(coll_);
+ setContents(m_currEntries);
+ m_modified = modified;
+ return;
+ }
+
+ QString key = QString::number(coll_->id()) + oldField_->name();
+ GUI::FieldWidget* widget = m_widgetDict[key];
+ if(widget) {
+ widget->updateField(oldField_, newField_);
+ // need to update label widths
+ if(newField_->title() != oldField_->title()) {
+ int maxWidth = 0;
+ QObjectList* childList = widget->parentWidget()->queryList("Tellico::GUI::FieldWidget", 0, false, false);
+ QObjectListIt it(*childList);
+ for(it.toFirst(); it.current(); ++it) {
+ maxWidth = QMAX(maxWidth, static_cast<GUI::FieldWidget*>(it.current())->labelWidth());
+ }
+ for(it.toFirst(); it.current(); ++it) {
+ static_cast<GUI::FieldWidget*>(it.current())->setLabelWidth(maxWidth);
+ }
+ delete childList;
+ }
+ // this is very fragile!
+ // field widgets's parent is the grid, whose parent is the tab page
+ // this is for singleCategory fields
+ if(newField_->category() != oldField_->category()) {
+ m_tabs->setTabLabel(widget->parentWidget()->parentWidget(), newField_->category());
+ }
+ }
+}
+
+void EntryEditDialog::addEntries(Data::EntryVec entries_) {
+ for(Data::EntryVecIt entry = entries_.begin(); entry != entries_.end(); ++entry) {
+ updateCompletions(entry);
+ }
+}
+
+void EntryEditDialog::modifyEntries(Data::EntryVec entries_) {
+ bool updateContents = false;
+ for(Data::EntryVecIt entry = entries_.begin(); entry != entries_.end(); ++entry) {
+ updateCompletions(entry);
+ if(!updateContents && m_currEntries.contains(entry)) {
+ updateContents = true;
+ }
+ }
+ if(updateContents) {
+ m_needReset = true;
+ setContents(m_currEntries);
+ }
+}
+
+void EntryEditDialog::slotGoPrevEntry() {
+ queryModified();
+ Controller::self()->slotGoPrevEntry();
+}
+
+void EntryEditDialog::slotGoNextEntry() {
+ queryModified();
+ Controller::self()->slotGoNextEntry();
+}
+
+#include "entryeditdialog.moc"
diff --git a/src/entryeditdialog.h b/src/entryeditdialog.h
new file mode 100644
index 0000000..2d71b63
--- /dev/null
+++ b/src/entryeditdialog.h
@@ -0,0 +1,149 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef ENTRYEDITDIALOG_H
+#define ENTRYEDITDIALOG_H
+
+class KPushButton;
+
+#include "observer.h"
+#include "gui/fieldwidget.h"
+
+#include <kdialogbase.h>
+
+#include <qdict.h>
+
+namespace Tellico {
+ namespace GUI {
+ class TabControl;
+ }
+
+/**
+ * @author Robby Stephenson
+ */
+class EntryEditDialog : public KDialogBase, public Observer {
+Q_OBJECT
+
+// needed for completion object support
+friend class GUI::FieldWidget;
+
+public:
+ EntryEditDialog(QWidget* parent, const char* name);
+
+ /**
+ * Checks to see if any data needs to be saved. Returns @p true if it's ok to continue with
+ * saving or closing the widget.
+ *
+ * @return Returns @p true if either the data has not been modified or the user to save or discard the new data.
+ */
+ bool queryModified();
+ /**
+ * Deletes and resets the layout of the tabs.
+ *
+ * @param coll A pointer to the collection whose fields should be used for setting up the layout
+ */
+ void setLayout(Data::CollPtr coll);
+ /**
+ * Sets the contents of the input controls to match the contents of a list of entries.
+ *
+ * @param list A list of the entries. The data in the first one will be inserted in the controls, and
+ * the widgets will be enabled or not, depending on whether the rest of the entries match the first one.
+ */
+ void setContents(Data::EntryVec entries);
+ /**
+ * Clears all of the input controls in the widget. The pointer to the
+ * current entry is nullified, but not the pointer to the current collection.
+ */
+ void clear();
+
+ virtual void addEntries(Data::EntryVec entries);
+ virtual void modifyEntries(Data::EntryVec entries);
+
+ virtual void addField(Data::CollPtr coll, Data::FieldPtr) { setLayout(coll); }
+ /**
+ * Updates a widget when its field has been modified. The category may have changed, completions may have
+ * been added or removed, or what-have-you.
+ *
+ * @param coll A pointer to the parent collection
+ * @param oldField A pointer to the old field, which should have the same name as the new one
+ * @param newField A pointer to the new field
+ */
+ virtual void modifyField(Data::CollPtr coll, Data::FieldPtr oldField, Data::FieldPtr newField);
+ /**
+ * Removes a field from the editor.
+ *
+ * @param field The field to be removed
+ */
+ virtual void removeField(Data::CollPtr, Data::FieldPtr field);
+
+public slots:
+ /**
+ * Called when the Close button is clicked. It just hides the dialog.
+ */
+ virtual void slotClose();
+ /**
+ * Resets the widget, deleting all of its contents
+ */
+ void slotReset();
+ /**
+ * Handles clicking the New button. The old entry pointer is destroyed and a
+ * new one is created, but not added to any collection.
+ */
+ void slotHandleNew();
+ /**
+ * Handles clicking the Save button. All the values in the entry widgets are
+ * copied into the entry object. @ref signalSaveEntry is made. The widget is cleared,
+ * and the first tab is shown.
+ */
+ void slotHandleSave();
+ /**
+ * This slot is called whenever anything is modified. It's public so I can call it
+ * from a @ref FieldEditWidget.
+ */
+ void slotSetModified(bool modified=true);
+
+private slots:
+ void slotGoPrevEntry();
+ void slotGoNextEntry();
+
+private:
+ /**
+ * Sets the contents of the input controls to match the contents of a entry.
+ *
+ * @param entry A pointer to the entry
+ * @param highlight An optional string to highlight
+ */
+ void setContents(Data::EntryPtr entry);
+ /**
+ * Updates the completion objects in the edit boxes to include values
+ * contained in a certain entry.
+ *
+ * @param entry A pointer to the entry
+ */
+ void updateCompletions(Data::EntryPtr entry);
+
+ Data::CollPtr m_currColl;
+ Data::EntryVec m_currEntries;
+ GUI::TabControl* m_tabs;
+ QDict<GUI::FieldWidget> m_widgetDict;
+
+ ButtonCode m_saveBtn, m_newBtn, m_nextBtn, m_prevBtn;
+
+ bool m_modified;
+ bool m_isOrphan;
+ bool m_isWorking;
+ bool m_needReset;
+};
+
+} // end namespace
+#endif
diff --git a/src/entrygroupitem.cpp b/src/entrygroupitem.cpp
new file mode 100644
index 0000000..f2de60d
--- /dev/null
+++ b/src/entrygroupitem.cpp
@@ -0,0 +1,140 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "entrygroupitem.h"
+#include "entry.h"
+#include "collection.h"
+#include "gui/ratingwidget.h"
+#include "tellico_debug.h"
+#include "latin1literal.h"
+#include "core/tellico_config.h"
+
+#include <kiconloader.h>
+#include <klocale.h>
+
+#include <qpixmap.h>
+#include <qpainter.h>
+
+using Tellico::EntryGroupItem;
+
+EntryGroupItem::EntryGroupItem(GUI::ListView* parent_, Data::EntryGroup* group_, int fieldType_)
+ : GUI::CountedItem(parent_), m_group(group_), m_fieldType(fieldType_) {
+ setText(0, group_->groupName());
+ m_emptyGroup = group_->groupName() == i18n(Data::Collection::s_emptyGroupTitle);
+}
+
+QPixmap EntryGroupItem::ratingPixmap() {
+ if(!m_group) {
+ return QPixmap();
+ }
+ QPixmap stars = GUI::RatingWidget::pixmap(m_group->groupName());
+ if(m_pix.isNull() && stars.isNull()) {
+ m_emptyGroup = true;
+ return QPixmap();
+ }
+
+ QPixmap newPix(m_pix.width() + 4 + stars.width(), QMAX(m_pix.height(), stars.height()));
+ newPix.fill(isSelected() ? listView()->colorGroup().highlight() : backgroundColor(0));
+ QPainter p(&newPix);
+ if(!m_pix.isNull()) {
+ p.drawPixmap(0, 0, m_pix);
+ }
+ if(!stars.isNull()) {
+ p.drawPixmap(m_pix.width() + 4, 0, stars);
+ }
+ p.end();
+ return newPix;
+}
+
+void EntryGroupItem::setPixmap(int col, const QPixmap& pix) {
+ m_pix = pix;
+ GUI::CountedItem::setPixmap(col, m_pix);
+}
+
+void EntryGroupItem::paintCell(QPainter* p_, const QColorGroup& cg_,
+ int column_, int width_, int align_) {
+ if(column_> 0 || m_fieldType != Data::Field::Rating || m_emptyGroup) {
+ return GUI::CountedItem::paintCell(p_, cg_, column_, width_, align_);
+ }
+
+ QString oldText = text(column_);
+ // "\t\t" is the flag to not paint the item
+ // CountedItem already uses "\t"
+ if(oldText == Latin1Literal("\t\t")) {
+ return;
+ }
+
+ setText(column_, QString::fromLatin1("\t\t"));
+ GUI::CountedItem::setPixmap(column_, ratingPixmap());
+ GUI::CountedItem::paintCell(p_, cg_, column_, width_, align_);
+// GUI::CountedItem::setPixmap(column_, m_pix);
+ setText(column_, oldText);
+}
+
+// prepend a tab character to always sort the empty group name first
+// also check for surname prefixes
+QString EntryGroupItem::key(int col_, bool) const {
+ if(col_ > 0) {
+ return text(col_);
+ }
+
+ if((m_fieldType == Data::Field::Rating || text(col_).isEmpty())
+ && pixmap(col_) && !pixmap(col_)->isNull()) {
+ // a little weird, sort for width, too, in case of rating widget
+ // but sort reverse by width
+ return QChar('\t') + QString::number(1000-pixmap(col_)->width());
+ } else if(text(col_) == i18n(Data::Collection::s_emptyGroupTitle)) {
+ return QChar('\t');
+ }
+
+ if(m_text.isEmpty() || m_text != text(col_)) {
+ m_text = text(col_);
+ if(Config::autoFormat()) {
+ const QStringList prefixes = Config::surnamePrefixList();
+ // build a regexp to match surname prefixes
+ // complicated by fact that prefix could have an apostrophe
+ QString tokens;
+ for(QStringList::ConstIterator it = prefixes.begin();
+ it != prefixes.end();
+ ++it) {
+ tokens += (*it);
+ if(!(*it).endsWith(QChar('\''))) {
+ tokens += QString::fromLatin1("\\s");
+ }
+ // if it's not the last item, add a pipe
+ if((*it) != prefixes.last()) {
+ tokens += QChar('|');
+ }
+ }
+ QRegExp rx(QString::fromLatin1("^(") + tokens + QChar(')'), false);
+ // expensive
+ if(rx.search(m_text) > -1) {
+ m_key = m_text.mid(rx.matchedLength());
+ } else {
+ m_key = m_text;
+ }
+ } else {
+ m_key = m_text;
+ }
+ }
+
+ return m_key;
+}
+
+int EntryGroupItem::count() const {
+ return m_group ? m_group->count() : GUI::CountedItem::count();
+}
+
+Tellico::Data::EntryVec EntryGroupItem::entries() const {
+ return m_group ? *m_group : Data::EntryVec();
+}
diff --git a/src/entrygroupitem.h b/src/entrygroupitem.h
new file mode 100644
index 0000000..827ce8d
--- /dev/null
+++ b/src/entrygroupitem.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef ENTRYGROUPITEM_H
+#define ENTRYGROUPITEM_H
+
+#include "gui/counteditem.h"
+
+#include <qpixmap.h>
+#include <qguardedptr.h>
+
+namespace Tellico {
+ namespace Data {
+ class EntryGroup;
+ }
+
+/**
+ * @author Robby Stephenson
+ */
+class EntryGroupItem : public GUI::CountedItem {
+public:
+ EntryGroupItem(GUI::ListView* parent, Data::EntryGroup* group, int fieldType);
+
+ virtual bool isEntryGroupItem() const { return true; }
+ Data::EntryGroup* group() const { return m_group; }
+ void setGroup(Data::EntryGroup* group) { m_group = group; }
+
+ QPixmap ratingPixmap();
+
+ virtual void setPixmap(int col, const QPixmap& pix);
+ virtual void paintCell(QPainter* p, const QColorGroup& cg,
+ int column, int width, int align);
+ /**
+ * Returns the key for sorting the listitems. The text used for an empty
+ * value should be sorted first, so the returned key is "\t". Since the text may
+ * have the number of entries or something added to the name, only check if the
+ * text begins with the empty name. Maybe there should be something better.
+ *
+ * @param col The column number
+ * @return The key
+ */
+ virtual QString key(int col, bool) const;
+
+ virtual int count() const;
+ virtual Data::EntryVec entries() const;
+
+private:
+ QGuardedPtr<Data::EntryGroup> m_group;
+ int m_fieldType;
+ QPixmap m_pix;
+ bool m_emptyGroup : 1;
+
+// since I do an expensive RegExp match for the surname prefixes, I want to
+// cache the text and the resulting key
+ mutable QString m_text;
+ mutable QString m_key;
+};
+
+}
+
+#endif
diff --git a/src/entryiconfactory.cpp b/src/entryiconfactory.cpp
new file mode 100644
index 0000000..0f4696d
--- /dev/null
+++ b/src/entryiconfactory.cpp
@@ -0,0 +1,43 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "entryiconfactory.h"
+#include "tellico_kernel.h"
+
+#include <kiconloader.h>
+#include <kimageeffect.h>
+
+#include <qimage.h>
+
+using Tellico::EntryIconFactory;
+
+EntryIconFactory::EntryIconFactory(int size_) : QIconFactory(), m_size(size_) {
+ setAutoDelete(true);
+}
+
+QPixmap* EntryIconFactory::createPixmap(const QIconSet&, QIconSet::Size, QIconSet::Mode, QIconSet::State) {
+ QPixmap entryPix = UserIcon(Kernel::self()->collectionTypeName());
+ // if we're 22x22 or smaller, just use entry icon
+ if(m_size < 23) {
+ QImage entryImg = entryPix.convertToImage();
+ entryPix.convertFromImage(entryImg.smoothScale(m_size, m_size, QImage::ScaleMin), 0);
+ return new QPixmap(entryPix);
+ }
+
+ QPixmap newPix = BarIcon(QString::fromLatin1("mime_empty"), m_size);
+ QImage newImg = newPix.convertToImage();
+// QImage blend; Not exactly sure what the coordinates mean, but this seems to work ok.
+ KImageEffect::blendOnLower(m_size/4, m_size/4, entryPix.convertToImage(), newImg);
+ newPix.convertFromImage(newImg, 0);
+ return new QPixmap(newPix);
+}
diff --git a/src/entryiconfactory.h b/src/entryiconfactory.h
new file mode 100644
index 0000000..d5461a3
--- /dev/null
+++ b/src/entryiconfactory.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_ENTRYICONFACTORY_H
+#define TELLICO_ENTRYICONFACTORY_H
+
+#include <qiconset.h>
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class EntryIconFactory : public QIconFactory {
+public:
+ EntryIconFactory(int size);
+
+ virtual QPixmap* createPixmap(const QIconSet&, QIconSet::Size, QIconSet::Mode, QIconSet::State);
+
+private:
+ int m_size;
+};
+
+}
+
+#endif
diff --git a/src/entryiconview.cpp b/src/entryiconview.cpp
new file mode 100644
index 0000000..2acd870
--- /dev/null
+++ b/src/entryiconview.cpp
@@ -0,0 +1,444 @@
+/***************************************************************************
+ copyright : (C) 2002-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "entryiconview.h"
+#include "collection.h"
+#include "collectionfactory.h"
+#include "imagefactory.h"
+#include "controller.h"
+#include "entry.h"
+#include "field.h"
+#include "tellico_utils.h"
+#include "tellico_debug.h"
+#include "listviewcomparison.h"
+
+#include <kpopupmenu.h>
+#include <kstringhandler.h>
+#include <kiconloader.h>
+#include <kwordwrap.h>
+#include <kimageeffect.h>
+#include <klocale.h>
+
+#include <qpainter.h>
+
+namespace {
+ static const int MIN_ENTRY_ICON_SIZE = 32;
+ static const int MAX_ENTRY_ICON_SIZE = 128;
+ static const int ENTRY_ICON_SIZE_PAD = 6;
+ static const int ENTRY_ICON_SHADOW_RIGHT = 1;
+ static const int ENTRY_ICON_SHADOW_BOTTOM = 1;
+}
+
+using Tellico::EntryIconView;
+using Tellico::EntryIconViewItem;
+
+EntryIconView::EntryIconView(QWidget* parent_, const char* name_/*=0*/)
+ : KIconView(parent_, name_), m_coll(0), m_maxAllowedIconWidth(MAX_ENTRY_ICON_SIZE),
+ m_maxIconWidth(MIN_ENTRY_ICON_SIZE), m_maxIconHeight(MIN_ENTRY_ICON_SIZE),
+ m_comparison(0) {
+ setAutoArrange(true);
+ setSorting(true);
+ setItemsMovable(false);
+ setSelectionMode(QIconView::Extended);
+ setResizeMode(QIconView::Adjust);
+ setMode(KIconView::Select);
+ setSpacing(4);
+// setWordWrapIconText(false);
+
+ m_defaultPixmaps.setAutoDelete(true);
+
+ connect(this, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()));
+ connect(this, SIGNAL(doubleClicked(QIconViewItem*)), SLOT(slotDoubleClicked(QIconViewItem*)));
+ connect(this, SIGNAL(contextMenuRequested(QIconViewItem*, const QPoint&)),
+ SLOT(slotShowContextMenu(QIconViewItem*, const QPoint&)));
+}
+
+EntryIconView::~EntryIconView() {
+ delete m_comparison;
+ m_comparison = 0;
+}
+
+EntryIconViewItem* EntryIconView::firstItem() const {
+ return static_cast<EntryIconViewItem*>(KIconView::firstItem());
+}
+
+void EntryIconView::findImageField() {
+ m_imageField.truncate(0);
+ if(!m_coll) {
+ return;
+ }
+ const Data::FieldVec& fields = m_coll->imageFields();
+ if(!fields.isEmpty()) {
+ m_imageField = fields[0]->name();
+ }
+// myDebug() << "EntryIconView::findImageField() - image field = " << m_imageField << endl;
+}
+
+const QString& EntryIconView::imageField() {
+ return m_imageField;
+}
+
+const QString& EntryIconView::sortField() {
+ return m_comparison ? m_comparison->fieldName() : QString::null;
+}
+
+const QPixmap& EntryIconView::defaultPixmap() {
+ QPixmap* pix = m_defaultPixmaps[m_coll->type()];
+ if(pix) {
+ return *pix;
+ }
+ KIconLoader* loader = KGlobal::instance()->iconLoader();
+ QPixmap tmp = loader->loadIcon(QString::fromLatin1("nocover_") + CollectionFactory::typeName(m_coll->type()),
+ KIcon::User, 0, KIcon::DefaultState, 0, true /*canReturnNull */);
+ if(tmp.isNull()) {
+ myLog() << "EntryIconView::defaultPixmap() - null nocover image, loading tellico.png" << endl;
+ tmp = UserIcon(QString::fromLatin1("tellico"));
+ }
+ if(QMAX(tmp.width(), tmp.height()) > static_cast<int>(MIN_ENTRY_ICON_SIZE)) {
+ tmp.convertFromImage(tmp.convertToImage().smoothScale(m_maxIconWidth, m_maxIconHeight, QImage::ScaleMin));
+ }
+ pix = new QPixmap(tmp);
+ m_defaultPixmaps.insert(m_coll->type(), pix);
+ return *pix;
+}
+
+void EntryIconView::setMaxAllowedIconWidth(int width_) {
+ m_maxAllowedIconWidth = QMAX(MIN_ENTRY_ICON_SIZE, QMIN(MAX_ENTRY_ICON_SIZE, width_));
+ setMaxItemWidth(m_maxAllowedIconWidth + 2*ENTRY_ICON_SIZE_PAD);
+ m_defaultPixmaps.clear();
+ refresh();
+}
+
+void EntryIconView::fillView() {
+ setSorting(false);
+ setGridX(m_maxAllowedIconWidth + 2*ENTRY_ICON_SIZE_PAD); // set default spacing initially
+
+ GUI::CursorSaver cs(Qt::waitCursor);
+
+ bool allDefaultImages = true;
+ m_maxIconWidth = QMAX(MIN_ENTRY_ICON_SIZE, m_maxIconWidth);
+ m_maxIconHeight = QMAX(MIN_ENTRY_ICON_SIZE, m_maxIconHeight);
+ EntryIconViewItem* item;
+ for(Data::EntryVecIt it = m_entries.begin(); it != m_entries.end(); ++it) {
+ item = new EntryIconViewItem(this, it);
+ m_maxIconWidth = QMAX(m_maxIconWidth, item->width());
+ m_maxIconHeight = QMAX(m_maxIconHeight, item->pixmapRect().height());
+ if(item->usesImage()) {
+ allDefaultImages = false;
+ }
+ }
+ if(allDefaultImages) {
+ m_maxIconWidth = m_maxAllowedIconWidth;
+ m_maxIconHeight = m_maxAllowedIconWidth;
+ }
+ // if both width and height are min, then that means there are no images
+ m_defaultPixmaps.clear();
+ // now reset size of all default pixmaps
+ for(item = firstItem(); item; item = item->nextItem()) {
+ if(!item->usesImage()) {
+ item->updatePixmap();
+ }
+ }
+ setGridX(m_maxIconWidth + 2*ENTRY_ICON_SIZE_PAD); // the pad is so the text can be wider than the icon
+ setGridY(m_maxIconHeight + fontMetrics().height());
+ sort();
+ setSorting(true);
+}
+
+void EntryIconView::refresh() {
+ if(!m_coll) {
+ return;
+ }
+ showEntries(m_entries);
+}
+
+void EntryIconView::clear() {
+ KIconView::clear();
+ m_coll = 0;
+ m_entries.clear();
+ m_imageField.truncate(0);
+}
+
+void EntryIconView::showEntries(const Data::EntryVec& entries_) {
+ setUpdatesEnabled(false);
+ KIconView::clear(); // don't call EntryIconView::clear() since that clears the entries_ ref
+ if(entries_.isEmpty()) {
+ return;
+ }
+ m_coll = entries_[0]->collection();
+ m_entries = entries_;
+ findImageField();
+ fillView();
+ setUpdatesEnabled(true);
+}
+
+void EntryIconView::addEntries(Data::EntryVec entries_) {
+ if(entries_.isEmpty()) {
+ return;
+ }
+ if(!m_coll) {
+ m_coll = entries_[0]->collection();
+ }
+ // since the view probably doesn't show all the current entries
+ // only add the new ones if the count is the total
+ if(m_entries.count() + entries_.count() < m_coll->entryCount()) {
+ return;
+ }
+ int w = MIN_ENTRY_ICON_SIZE;
+ int h = MIN_ENTRY_ICON_SIZE;
+ for(Data::EntryVecIt entry = entries_.begin(); entry != entries_.end(); ++entry) {
+ m_entries.append(entry);
+ EntryIconViewItem* item = new EntryIconViewItem(this, entry);
+ w = QMAX(w, item->width());
+ h = QMAX(h, item->pixmapRect().height());
+ }
+ if(w > m_maxIconWidth || h > m_maxIconHeight) {
+ refresh();
+ }
+}
+
+void EntryIconView::modifyEntries(Data::EntryVec entries_) {
+ for(Data::EntryVecIt entry = entries_.begin(); entry != entries_.end(); ++entry) {
+ EntryIconViewItem* item = 0;
+ for(EntryIconViewItem* it = firstItem(); it; it = it->nextItem()) {
+ if(it->entry() == entry) {
+ item = it;
+ break;
+ }
+ }
+ if(!item) {
+ continue;
+ }
+ item->update();
+ }
+}
+
+void EntryIconView::removeEntries(Data::EntryVec entries_) {
+ for(Data::EntryVecIt entry = entries_.begin(); entry != entries_.end(); ++entry) {
+ m_entries.remove(entry);
+ }
+ bool found = false;
+ EntryIconViewItem* item = firstItem();
+ while(item) {
+ if(entries_.contains(item->entry())) {
+ EntryIconViewItem* prev = item;
+ item = item->nextItem();
+ delete prev;
+ found = true;
+ } else {
+ item = item->nextItem();
+ }
+ }
+ if(found) {
+ arrangeItemsInGrid();
+ }
+}
+
+void EntryIconView::slotSelectionChanged() {
+ Data::EntryVec entries;
+ const QPtrList<EntryIconViewItem>& items = selectedItems();
+ for(QPtrListIterator<EntryIconViewItem> it(items); it.current(); ++it) {
+ entries.append(it.current()->entry());
+ }
+ Controller::self()->slotUpdateSelection(this, entries);
+}
+
+void EntryIconView::slotDoubleClicked(QIconViewItem* item_) {
+ EntryIconViewItem* i = static_cast<EntryIconViewItem*>(item_);
+ if(i) {
+ Controller::self()->editEntry(i->entry());
+ }
+}
+
+void EntryIconView::updateSelected(EntryIconViewItem* item_, bool s_) const {
+ if(s_) {
+ m_selectedItems.append(item_);
+ } else {
+ m_selectedItems.removeRef(item_);
+ }
+}
+
+void EntryIconView::slotShowContextMenu(QIconViewItem* item_, const QPoint& point_) {
+ KPopupMenu menu(this);
+
+ // only insert entry items if one is selected
+ if(item_) {
+ Controller::self()->plugEntryActions(&menu);
+ menu.insertSeparator();
+ }
+
+ KPopupMenu sortMenu(&menu);
+ const QStringList titles = m_coll->fieldTitles();
+ for(QStringList::ConstIterator it = titles.begin(); it != titles.end(); ++it) {
+ sortMenu.insertItem(*it);
+ }
+ connect(&sortMenu, SIGNAL(activated(int)), SLOT(slotSortMenuActivated(int)));
+
+ menu.insertItem(i18n("&Sort By"), &sortMenu);
+ menu.exec(point_);
+}
+
+void EntryIconView::slotSortMenuActivated(int id_) {
+ const KPopupMenu* menu = ::qt_cast<KPopupMenu*>(sender());
+ if(menu) {
+ QString title = menu->text(id_);
+ Data::FieldPtr f = m_coll->fieldByTitle(title);
+ if(f) {
+ delete m_comparison;
+ m_comparison = ListViewComparison::create(f);
+ sort();
+ }
+ }
+}
+
+int EntryIconView::compare(const EntryIconViewItem* item1, EntryIconViewItem* item2) {
+ if(m_comparison) {
+ return m_comparison->compare(item1, item2);
+ }
+ return 0;
+}
+
+/* *********************************************************** */
+
+EntryIconViewItem::EntryIconViewItem(EntryIconView* parent_, Data::EntryPtr entry_)
+ : KIconViewItem(parent_, entry_->title()), m_entry(entry_), m_usesImage(false) {
+ setDragEnabled(false);
+ const QString& imageField = parent_->imageField();
+ if(!imageField.isEmpty()) {
+ QPixmap p = ImageFactory::pixmap(m_entry->field(imageField),
+ parent_->maxAllowedIconWidth(),
+ parent_->maxAllowedIconWidth());
+ if(!p.isNull()) {
+ setPixmap(p);
+ m_usesImage = true;
+ }
+ }
+}
+
+EntryIconViewItem::~EntryIconViewItem() {
+ // be sure to remove from selected list when it's deleted
+ EntryIconView* view = iconView();
+ if(view) {
+ view->updateSelected(this, false);
+ }
+}
+
+void EntryIconViewItem::setSelected(bool s_) {
+ setSelected(s_, false);
+}
+
+void EntryIconViewItem::setSelected(bool s_, bool cb_) {
+ EntryIconView* view = iconView();
+ if(!view) {
+ return;
+ }
+ if(s_ != isSelected()) {
+ view->updateSelected(this, s_);
+ KIconViewItem::setSelected(s_, cb_);
+ }
+}
+
+void EntryIconViewItem::updatePixmap() {
+ EntryIconView* view = iconView();
+ const QString& imageField = view->imageField();
+ m_usesImage = false;
+ if(imageField.isEmpty()) {
+ setPixmap(view->defaultPixmap());
+ } else {
+ QPixmap p = ImageFactory::pixmap(m_entry->field(imageField),
+ view->maxAllowedIconWidth(),
+ view->maxAllowedIconWidth());
+ if(p.isNull()) {
+ setPixmap(view->defaultPixmap());
+ } else {
+ setPixmap(p);
+ m_usesImage = true;
+ calcRect();
+ }
+ }
+}
+
+void EntryIconViewItem::update() {
+ setText(m_entry->title());
+ updatePixmap();
+ iconView()->arrangeItemsInGrid();
+}
+
+void EntryIconViewItem::calcRect(const QString& text_) {
+ KIconViewItem::calcRect(text_);
+ QRect r = pixmapRect();
+ r.rRight() += ENTRY_ICON_SHADOW_RIGHT;
+ r.rBottom() += ENTRY_ICON_SHADOW_BOTTOM;
+ setPixmapRect(r);
+}
+
+void EntryIconViewItem::paintItem(QPainter* p_, const QColorGroup &cg_) {
+ p_->save();
+ paintPixmap(p_, cg_);
+ paintText(p_, cg_);
+ p_->restore();
+}
+
+void EntryIconViewItem::paintFocus(QPainter*, const QColorGroup&) {
+ // don't draw anything
+}
+
+void EntryIconViewItem::paintPixmap(QPainter* p_, const QColorGroup& cg_) {
+ // only draw the shadow if there's an image
+ // oh, and don't draw it if it's a file catalog, it doesn't look right
+ if(m_usesImage && !isSelected() && m_entry->collection()->type() != Data::Collection::File) {
+ // pixmapRect() already includes shadow size, so shift the rect by that amount
+ QRect r = pixmapRect(false);
+ r.setLeft(r.left() + ENTRY_ICON_SHADOW_RIGHT);
+ r.setTop(r.top() + ENTRY_ICON_SHADOW_BOTTOM);
+ QColor c = Tellico::blendColors(iconView()->backgroundColor(), Qt::black, 10);
+ p_->fillRect(r, c);
+ }
+ KIconViewItem::paintPixmap(p_, cg_);
+}
+
+void EntryIconViewItem::paintText(QPainter* p_, const QColorGroup &cg_) {
+ QRect tr = textRect(false);
+ int textX = tr.x() + 2;
+ int textY = tr.y();
+
+ if(isSelected()) {
+ p_->setBrush(QBrush(cg_.highlight()));
+ p_->setPen(QPen(cg_.highlight()));
+ p_->drawRoundRect(tr, 1000/tr.width(), 1000/tr.height());
+ p_->setPen(QPen(cg_.highlightedText()));
+ } else {
+ if(iconView()->itemTextBackground() != NoBrush) {
+ p_->fillRect(tr, iconView()->itemTextBackground());
+ }
+ p_->setPen(cg_.text());
+ }
+
+ int align = iconView()->itemTextPos() == QIconView::Bottom ? AlignHCenter : AlignAuto;
+ wordWrap()->drawText(p_, textX, textY, align | KWordWrap::Truncate);
+}
+
+QString EntryIconViewItem::key() const {
+ const QString& sortField = iconView()->sortField();
+ if(sortField.isEmpty()) {
+ return KIconViewItem::key();
+ }
+ return m_entry->field(sortField);
+}
+
+int EntryIconViewItem::compare(QIconViewItem* item_) const {
+ int res = iconView()->compare(this, static_cast<EntryIconViewItem*>(item_));
+ return res == 0 ? KIconViewItem::compare(item_) : res;
+}
+
+#include "entryiconview.moc"
diff --git a/src/entryiconview.h b/src/entryiconview.h
new file mode 100644
index 0000000..335818c
--- /dev/null
+++ b/src/entryiconview.h
@@ -0,0 +1,133 @@
+/***************************************************************************
+ copyright : (C) 2002-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICOENTRYICONVIEW_H
+#define TELLICOENTRYICONVIEW_H
+
+#include "observer.h"
+#include "entry.h"
+
+#include <kiconview.h>
+
+#include <qintdict.h>
+
+namespace Tellico {
+ class EntryIconViewItem;
+ namespace Data {
+ class Collection;
+ }
+ class ListViewComparison;
+
+/**
+ * @author Robby Stephenson
+ */
+class EntryIconView : public KIconView, public Observer {
+Q_OBJECT
+
+friend class EntryIconViewItem;
+
+public:
+ EntryIconView(QWidget* parent, const char* name = 0);
+ ~EntryIconView();
+
+ EntryIconViewItem* firstItem() const;
+
+ virtual void clear();
+ void refresh();
+ void showEntries(const Data::EntryVec& entries);
+ /**
+ * Adds a new list item showing the details for a entry.
+ *
+ * @param entry A pointer to the entry
+ */
+ virtual void addEntries(Data::EntryVec entries);
+ virtual void modifyEntries(Data::EntryVec entries);
+ virtual void removeEntries(Data::EntryVec entries);
+
+ const QString& imageField();
+ const QString& sortField();
+ void setMaxAllowedIconWidth(int width);
+ int maxAllowedIconWidth() const { return m_maxAllowedIconWidth; }
+
+ const QPixmap& defaultPixmap();
+ /**
+ * Returns a list of the currently selected items;
+ *
+ * @return The list of selected items
+ */
+ const QPtrList<EntryIconViewItem>& selectedItems() const { return m_selectedItems; }
+
+ int compare(const EntryIconViewItem* item1, EntryIconViewItem* item2);
+
+private slots:
+ void slotSelectionChanged();
+ void slotDoubleClicked(QIconViewItem* item);
+ void slotShowContextMenu(QIconViewItem* item, const QPoint& point);
+ void slotSortMenuActivated(int id);
+
+private:
+ /**
+ * Updates the pointer list.
+ *
+ * @param item The item being selected or deselected
+ * @param s Selected or not
+ */
+ void updateSelected(EntryIconViewItem* item, bool s) const;
+ mutable QPtrList<EntryIconViewItem> m_selectedItems;
+
+ void findImageField();
+ void fillView();
+
+ Data::CollPtr m_coll;
+ Data::EntryVec m_entries;
+ QString m_imageField;
+ QIntDict<QPixmap> m_defaultPixmaps;
+ int m_maxAllowedIconWidth;
+ int m_maxIconWidth;
+ int m_maxIconHeight;
+ ListViewComparison* m_comparison;
+};
+
+class EntryIconViewItem : public KIconViewItem {
+public:
+ EntryIconViewItem(EntryIconView* parent, Data::EntryPtr entry);
+ ~EntryIconViewItem();
+
+ EntryIconView* iconView() const { return static_cast<EntryIconView*>(KIconViewItem::iconView()); }
+ EntryIconViewItem* nextItem() const { return static_cast<EntryIconViewItem*>(KIconViewItem::nextItem()); }
+
+ Data::EntryPtr entry() const { return m_entry; }
+ virtual void setSelected(bool s, bool cb);
+ virtual void setSelected(bool s);
+ virtual QString key() const;
+ virtual int compare(QIconViewItem* item_) const;
+
+ bool usesImage() const { return m_usesImage; }
+ void updatePixmap();
+
+ void update();
+
+protected:
+ virtual void calcRect(const QString& text = QString::null);
+ virtual void paintItem(QPainter* p, const QColorGroup& cg);
+ virtual void paintFocus(QPainter* p, const QColorGroup& cg);
+ void paintPixmap(QPainter* p, const QColorGroup& cg);
+ void paintText(QPainter* p, const QColorGroup& cg);
+
+private:
+ Data::EntryPtr m_entry;
+ bool m_usesImage : 1;
+};
+
+} // end namespace
+#endif
diff --git a/src/entryitem.cpp b/src/entryitem.cpp
new file mode 100644
index 0000000..0079d44
--- /dev/null
+++ b/src/entryitem.cpp
@@ -0,0 +1,55 @@
+/***************************************************************************
+ copyright : (C) 2003-2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "entryitem.h"
+#include "entry.h"
+#include "gui/counteditem.h"
+#include "collection.h"
+#include "controller.h"
+
+#include <kiconloader.h>
+
+using Tellico::EntryItem;
+
+EntryItem::EntryItem(GUI::ListView* parent, Data::EntryPtr entry)
+ : GUI::ListViewItem(parent), m_entry(entry), m_isDetailedList(true) {
+}
+
+EntryItem::EntryItem(GUI::CountedItem* parent_, Data::EntryPtr entry_)
+ : GUI::ListViewItem(parent_), m_entry(entry_), m_isDetailedList(false) {
+ setText(0, m_entry->title());
+ setPixmap(0, UserIcon(entry_->collection()->typeName()));
+}
+
+Tellico::Data::EntryPtr const EntryItem::entry() const {
+ return m_entry;
+}
+
+QString EntryItem::key(int col_, bool) const {
+ // first column is always title unless it's a detailed list
+ // detailed list takes care of things on its own
+ bool checkArticles = (!m_isDetailedList && col_ == 0);
+ // there's some sort of painting bug if the key is identical for multiple entries
+ // probably a null string in the group view. TODO
+ // don't add the entry id if it's a detailed view cause that messes up secondary sorting
+ QString key = (checkArticles ? Data::Field::sortKeyTitle(text(col_)) : text(col_));
+ return (m_isDetailedList ? key : key + QString::number(m_entry->id()));
+}
+
+void EntryItem::doubleClicked() {
+ Controller::self()->editEntry(m_entry);
+}
+
+Tellico::Data::EntryVec EntryItem::entries() const {
+ return Data::EntryVec(entry());
+}
diff --git a/src/entryitem.h b/src/entryitem.h
new file mode 100644
index 0000000..4e529c8
--- /dev/null
+++ b/src/entryitem.h
@@ -0,0 +1,83 @@
+/***************************************************************************
+ copyright : (C) 2001-2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_ENTRYITEM_H
+#define TELLICO_ENTRYITEM_H
+
+#include "gui/listview.h"
+#include "datavectors.h"
+
+namespace Tellico {
+ namespace GUI {
+ class CountedItem;
+ }
+
+/**
+ * The EntryItem is a subclass of ListViewItem containing a pointer to an Entry.
+ *
+ * The entry pointer allows easy access to listview items which refer to a certain entry.
+ *
+ * @see Entry
+ *
+ * @author Robby Stephenson
+ */
+class EntryItem : public GUI::ListViewItem {
+public:
+ /**
+ * This constructor is for items which are direct children of a ListView object,
+ * which is just the @ref DetailedListView.
+ *
+ * @param parent A pointer to the parent
+ * @param entry A pointer to the entry to which the item refers
+ */
+ EntryItem(GUI::ListView* parent, Data::EntryPtr entry);
+ /**
+ * This constructor is for items which have other KListViewItems as parents. It
+ * initializes the text in the first column, as well.
+ *
+ * @param parent A pointer to the parent
+ * @param text The text in the first column
+ * @param entry A pointer to the entry to which the item refers
+ */
+ EntryItem(GUI::CountedItem* parent, Data::EntryPtr entry);
+
+ virtual bool isEntryItem() const { return true; }
+
+ /**
+ * Returns the key for the list item. The key is just the text, unless there is none,
+ * in which case a tab character is returned if there is a non-null pixmap.
+ *
+ * @param col Column to compare
+ * @return The key string
+ */
+ virtual QString key(int col, bool) const;
+ /**
+ * Returns a const pointer to the entry to which the item refers
+ *
+ * @return The entry pointer
+ */
+ Data::EntryPtr const entry() const;
+
+ virtual void doubleClicked();
+ virtual Data::EntryVec entries() const;
+
+private:
+ Data::EntryPtr m_entry;
+ // if the parent is a DetailedListView
+ // this way, I don't have to call listView()->isA("Tellico::DetailedListView") every time
+ // when I want to do funky comparisons
+ bool m_isDetailedList : 1;
+};
+
+} // end namespace
+#endif
diff --git a/src/entrymerger.cpp b/src/entrymerger.cpp
new file mode 100644
index 0000000..4767026
--- /dev/null
+++ b/src/entrymerger.cpp
@@ -0,0 +1,107 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "entrymerger.h"
+#include "entry.h"
+#include "collection.h"
+#include "tellico_kernel.h"
+#include "controller.h"
+#include "progressmanager.h"
+#include "statusbar.h"
+#include "tellico_debug.h"
+
+#include <klocale.h>
+
+#include <qtimer.h>
+
+using Tellico::EntryMerger;
+
+EntryMerger::EntryMerger(Data::EntryVec entries_, QObject* parent_)
+ : QObject(parent_), m_entriesToCheck(entries_), m_origCount(entries_.count()), m_cancelled(false) {
+
+ m_entriesLeft = m_entriesToCheck;
+ Kernel::self()->beginCommandGroup(i18n("Merge Entries"));
+
+ QString label = i18n("Merging entries...");
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, label, true /*canCancel*/);
+ item.setTotalSteps(m_origCount);
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+
+ // done if no entries to merge
+ if(m_origCount < 2) {
+ QTimer::singleShot(500, this, SLOT(slotCleanup()));
+ } else {
+ slotStartNext(); // starts fetching
+ }
+}
+
+void EntryMerger::slotStartNext() {
+ QString statusMsg = i18n("Total merged/scanned entries: %1/%2")
+ .arg(m_entriesToRemove.count())
+ .arg(m_origCount - m_entriesToCheck.count());
+ StatusBar::self()->setStatus(statusMsg);
+ ProgressManager::self()->setProgress(this, m_origCount - m_entriesToCheck.count());
+
+ Data::EntryPtr baseEntry = m_entriesToCheck.front();
+ Data::EntryVec::Iterator it = m_entriesToCheck.begin();
+ ++it; // skip checking against first
+ for( ; it != m_entriesToCheck.end(); ++it) {
+ bool match = cleanMerge(baseEntry, &*it);
+ if(!match) {
+ int score = baseEntry->collection()->sameEntry(baseEntry, &*it);
+ match = score >= Data::Collection::ENTRY_PERFECT_MATCH;
+ }
+ if(match) {
+ bool merge_ok = baseEntry->collection()->mergeEntry(baseEntry, &*it, false /*overwrite*/, true /*askUser*/);
+ if(merge_ok) {
+ m_entriesToRemove.append(it);
+ m_entriesLeft.remove(it);
+ }
+ }
+ }
+ m_entriesToCheck.remove(baseEntry);
+
+ if(m_cancelled || m_entriesToCheck.count() < 2) {
+ QTimer::singleShot(0, this, SLOT(slotCleanup()));
+ } else {
+ QTimer::singleShot(0, this, SLOT(slotStartNext()));
+ }
+}
+
+void EntryMerger::slotCancel() {
+ m_cancelled = true;
+}
+
+void EntryMerger::slotCleanup() {
+ Kernel::self()->removeEntries(m_entriesToRemove);
+ Controller::self()->slotUpdateSelection(0, m_entriesLeft);
+ StatusBar::self()->clearStatus();
+ ProgressManager::self()->setDone(this);
+ Kernel::self()->endCommandGroup();
+ deleteLater();
+}
+
+bool EntryMerger::cleanMerge(Data::EntryPtr e1, Data::EntryPtr e2) const {
+ // figure out if there's a clean merge possible
+ Data::FieldVec fields = e1->collection()->fields();
+ for(Data::FieldVecIt it = fields.begin(); it != fields.end(); ++it) {
+ QString val1 = e1->field(it);
+ QString val2 = e2->field(it);
+ if(val1 != val2 && !val1.isEmpty() && !val2.isEmpty()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+#include "entrymerger.moc"
diff --git a/src/entrymerger.h b/src/entrymerger.h
new file mode 100644
index 0000000..46e23ca
--- /dev/null
+++ b/src/entrymerger.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_ENTRYMERGER_H
+#define TELLICO_ENTRYMERGER_H
+
+#include "datavectors.h"
+
+#include <qobject.h>
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class EntryMerger : public QObject {
+Q_OBJECT
+public:
+ EntryMerger(Data::EntryVec entries, QObject* parent);
+
+public slots:
+ void slotCancel();
+
+private slots:
+ void slotStartNext();
+ void slotCleanup();
+
+private:
+ // if a clean merge is possible
+ bool cleanMerge(Data::EntryPtr entry1, Data::EntryPtr entry2) const;
+ bool askUser(Data::EntryPtr entry1, Data::EntryPtr entry2);
+
+ Data::EntryVec m_entriesToCheck;
+ Data::EntryVec m_entriesToRemove;
+ Data::EntryVec m_entriesLeft;
+ int m_origCount;
+ bool m_cancelled;
+};
+
+} // end namespace
+
+#endif
diff --git a/src/entryupdater.cpp b/src/entryupdater.cpp
new file mode 100644
index 0000000..5c3ba2d
--- /dev/null
+++ b/src/entryupdater.cpp
@@ -0,0 +1,273 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "entryupdater.h"
+#include "entry.h"
+#include "collection.h"
+#include "tellico_kernel.h"
+#include "tellico_debug.h"
+#include "progressmanager.h"
+#include "statusbar.h"
+#include "gui/richtextlabel.h"
+#include "document.h"
+
+#include <kdialogbase.h>
+#include <klocale.h>
+#include <klistview.h>
+#include <kiconloader.h>
+
+#include <qvbox.h>
+#include <qtimer.h>
+
+namespace {
+ static const int CHECK_COLLECTION_IMAGES_STEP_SIZE = 10;
+}
+
+using Tellico::EntryUpdater;
+
+// for each entry, we loop over all available fetchers
+// then we loop over all entries
+EntryUpdater::EntryUpdater(Data::CollPtr coll_, Data::EntryVec entries_, QObject* parent_)
+ : QObject(parent_), m_coll(coll_), m_entriesToUpdate(entries_), m_cancelled(false) {
+ // for now, we're assuming all entries are same collection type
+ m_fetchers = Fetch::Manager::self()->createUpdateFetchers(m_coll->type());
+ for(Fetch::FetcherVec::Iterator it = m_fetchers.begin(); it != m_fetchers.end(); ++it) {
+ connect(it.data(), SIGNAL(signalResultFound(Tellico::Fetch::SearchResult*)),
+ SLOT(slotResult(Tellico::Fetch::SearchResult*)));
+ connect(it.data(), SIGNAL(signalDone(Tellico::Fetch::Fetcher::Ptr)),
+ SLOT(slotDone()));
+ }
+ init();
+}
+
+EntryUpdater::EntryUpdater(const QString& source_, Data::CollPtr coll_, Data::EntryVec entries_, QObject* parent_)
+ : QObject(parent_)
+ , m_coll(coll_)
+ , m_entriesToUpdate(entries_)
+ , m_cancelled(false) {
+ // for now, we're assuming all entries are same collection type
+ Fetch::Fetcher::Ptr f = Fetch::Manager::self()->createUpdateFetcher(m_coll->type(), source_);
+ if(f) {
+ m_fetchers.append(f);
+ connect(f, SIGNAL(signalResultFound(Tellico::Fetch::SearchResult*)),
+ SLOT(slotResult(Tellico::Fetch::SearchResult*)));
+ connect(f, SIGNAL(signalDone(Tellico::Fetch::Fetcher::Ptr)),
+ SLOT(slotDone()));
+ }
+ init();
+}
+
+EntryUpdater::~EntryUpdater() {
+ for(ResultList::Iterator res = m_results.begin(); res != m_results.end(); ++res) {
+ delete (*res).first;
+ }
+}
+
+void EntryUpdater::init() {
+ m_fetchIndex = 0;
+ m_origEntryCount = m_entriesToUpdate.count();
+ QString label;
+ if(m_entriesToUpdate.count() == 1) {
+ label = i18n("Updating %1...").arg(m_entriesToUpdate.front()->title());
+ } else {
+ label = i18n("Updating entries...");
+ }
+ Kernel::self()->beginCommandGroup(i18n("Update Entries"));
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, label, true /*canCancel*/);
+ item.setTotalSteps(m_fetchers.count() * m_origEntryCount);
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+
+ // done if no fetchers available
+ if(m_fetchers.isEmpty()) {
+ QTimer::singleShot(500, this, SLOT(slotCleanup()));
+ } else {
+ slotStartNext(); // starts fetching
+ }
+}
+
+void EntryUpdater::slotStartNext() {
+ StatusBar::self()->setStatus(i18n("Updating <b>%1</b>...").arg(m_entriesToUpdate.front()->title()));
+ ProgressManager::self()->setProgress(this, m_fetchers.count() * (m_origEntryCount - m_entriesToUpdate.count()) + m_fetchIndex);
+
+ Fetch::Fetcher::Ptr f = m_fetchers[m_fetchIndex];
+// myDebug() << "EntryUpdater::slotDone() - starting " << f->source() << endl;
+ f->updateEntry(m_entriesToUpdate.front());
+}
+
+void EntryUpdater::slotDone() {
+ if(m_cancelled) {
+ myLog() << "EntryUpdater::slotDone() - cancelled" << endl;
+ QTimer::singleShot(500, this, SLOT(slotCleanup()));
+ return;
+ }
+
+ if(!m_results.isEmpty()) {
+ handleResults();
+ }
+
+ m_results.clear();
+ ++m_fetchIndex;
+// myDebug() << "EntryUpdater::slotDone() " << m_fetchIndex << endl;
+ if(m_fetchIndex == static_cast<int>(m_fetchers.count())) {
+ m_fetchIndex = 0;
+ // we've gone through the loop for the first entry in the vector
+ // pop it and move on
+ m_entriesToUpdate.remove(m_entriesToUpdate.begin());
+ // if there are no more entries, and this is the last fetcher, time to delete
+ if(m_entriesToUpdate.isEmpty()) {
+ QTimer::singleShot(500, this, SLOT(slotCleanup()));
+ return;
+ }
+ }
+ kapp->processEvents();
+ // so the entry updater can clean up a bit
+ QTimer::singleShot(500, this, SLOT(slotStartNext()));
+}
+
+void EntryUpdater::slotResult(Fetch::SearchResult* result_) {
+ if(!result_ || m_cancelled) {
+ return;
+ }
+
+// myDebug() << "EntryUpdater::slotResult() - " << result_->title << " [" << result_->fetcher->source() << "]" << endl;
+ m_results.append(UpdateResult(result_, m_fetchers[m_fetchIndex]->updateOverwrite()));
+ Data::EntryPtr e = result_->fetchEntry();
+ if(e) {
+ m_fetchedEntries.append(e);
+ int match = m_coll->sameEntry(m_entriesToUpdate.front(), e);
+ if(match > Data::Collection::ENTRY_PERFECT_MATCH) {
+ result_->fetcher->stop();
+ }
+ }
+ kapp->processEvents();
+}
+
+void EntryUpdater::slotCancel() {
+// myDebug() << "EntryUpdater::slotCancel()" << endl;
+ m_cancelled = true;
+ Fetch::Fetcher::Ptr f = m_fetchers[m_fetchIndex];
+ if(f) {
+ f->stop(); // ends up calling slotDone();
+ } else {
+ slotDone();
+ }
+}
+
+void EntryUpdater::handleResults() {
+ Data::EntryPtr entry = m_entriesToUpdate.front();
+ int best = 0;
+ ResultList matches;
+ for(ResultList::Iterator res = m_results.begin(); res != m_results.end(); ++res) {
+ Data::EntryPtr e = (*res).first->fetchEntry();
+ if(!e) {
+ continue;
+ }
+ m_fetchedEntries.append(e);
+ int match = m_coll->sameEntry(entry, e);
+ if(match) {
+// myDebug() << e->title() << " matches by " << match << endl;
+ }
+ if(match > best) {
+ best = match;
+ matches.clear();
+ matches.append(*res);
+ } else if(match == best && best > 0) {
+ matches.append(*res);
+ }
+ }
+ if(best < Data::Collection::ENTRY_GOOD_MATCH) {
+ if(best > 0) {
+ myDebug() << "no good match (score > 10), best match = " << best << " (" << matches.count() << " matches)" << endl;
+ }
+ return;
+ }
+// myDebug() << "best match = " << best << " (" << matches.count() << " matches)" << endl;
+ UpdateResult match(0, true);
+ if(matches.count() == 1) {
+ match = matches.front();
+ } else if(matches.count() > 1) {
+ match = askUser(matches);
+ }
+ // askUser() could come back with nil
+ if(match.first) {
+ mergeCurrent(match.first->fetchEntry(), match.second);
+ }
+}
+
+Tellico::EntryUpdater::UpdateResult EntryUpdater::askUser(ResultList results) {
+ KDialogBase dlg(Kernel::self()->widget(), "entry updater dialog",
+ true, i18n("Select Match"), KDialogBase::Ok|KDialogBase::Cancel);
+ QVBox* box = new QVBox(&dlg);
+ box->setSpacing(10);
+
+ QHBox* hbox = new QHBox(box);
+ hbox->setSpacing(10);
+ QLabel* icon = new QLabel(hbox);
+ icon->setPixmap(KGlobal::iconLoader()->loadIcon(QString::fromLatin1("network"), KIcon::Panel, 64));
+ QString s = i18n("<qt><b>%1</b> returned multiple results which could match <b>%2</b>, "
+ "the entry currently in the collection. Please select the correct match.</qt>")
+ .arg(m_fetchers[m_fetchIndex]->source())
+ .arg(m_entriesToUpdate.front()->field(QString::fromLatin1("title")));
+ GUI::RichTextLabel* l = new GUI::RichTextLabel(s, hbox);
+ hbox->setStretchFactor(l, 100);
+
+ KListView* view = new KListView(box);
+ view->setShowSortIndicator(true);
+ view->setAllColumnsShowFocus(true);
+ view->setResizeMode(QListView::AllColumns);
+ view->setMinimumWidth(640);
+ view->addColumn(i18n("Title"));
+ view->addColumn(i18n("Description"));
+ QMap<KListViewItem*, UpdateResult> map;
+ for(ResultList::Iterator res = results.begin(); res != results.end(); ++res) {
+ map.insert(new KListViewItem(view, (*res).first->fetchEntry()->title(), (*res).first->desc), *res);
+ }
+
+ dlg.setMainWidget(box);
+ if(dlg.exec() != QDialog::Accepted) {
+ return UpdateResult(0, false);
+ }
+ KListViewItem* item = static_cast<KListViewItem*>(view->selectedItem());
+ if(!item) {
+ return UpdateResult(0, false);
+ }
+ return map[item];
+}
+
+void EntryUpdater::mergeCurrent(Data::EntryPtr entry_, bool overWrite_) {
+ Data::EntryPtr currEntry = m_entriesToUpdate.front();
+ if(entry_) {
+ m_matchedEntries.append(entry_);
+ Kernel::self()->updateEntry(currEntry, entry_, overWrite_);
+ if(m_entriesToUpdate.count() % CHECK_COLLECTION_IMAGES_STEP_SIZE == 1) {
+ // I don't want to remove any images in the entries that are getting
+ // updated since they'll reference them later and the command isn't
+ // executed until the command history group is finished
+ // so remove pointers to matched entries
+ Data::EntryVec nonUpdatedEntries = m_fetchedEntries;
+ for(Data::EntryVecIt match = m_matchedEntries.begin(); match != m_matchedEntries.end(); ++match) {
+ nonUpdatedEntries.remove(match);
+ }
+ Data::Document::self()->removeImagesNotInCollection(nonUpdatedEntries, m_matchedEntries);
+ }
+ }
+}
+
+void EntryUpdater::slotCleanup() {
+ StatusBar::self()->clearStatus();
+ ProgressManager::self()->setDone(this);
+ Kernel::self()->endCommandGroup();
+ deleteLater();
+}
+
+#include "entryupdater.moc"
diff --git a/src/entryupdater.h b/src/entryupdater.h
new file mode 100644
index 0000000..ddf4aa4
--- /dev/null
+++ b/src/entryupdater.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_ENTRYUPDATER_H
+#define TELLICO_ENTRYUPDATER_H
+
+#include "datavectors.h"
+#include "fetch/fetchmanager.h"
+
+#include <qpair.h>
+#include <qvaluelist.h>
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class EntryUpdater : public QObject {
+Q_OBJECT
+public:
+ EntryUpdater(Data::CollPtr coll, Data::EntryVec entries, QObject* parent);
+ EntryUpdater(const QString& fetcher, Data::CollPtr coll, Data::EntryVec entries, QObject* parent);
+ ~EntryUpdater();
+
+public slots:
+ void slotResult(Tellico::Fetch::SearchResult* result);
+ void slotCancel();
+
+private slots:
+ void slotStartNext();
+ void slotDone();
+ void slotCleanup();
+
+private:
+ typedef QPair<Fetch::SearchResult*, bool> UpdateResult;
+ typedef QValueList<UpdateResult> ResultList;
+
+ void init();
+ void handleResults();
+ UpdateResult askUser(ResultList results);
+ void mergeCurrent(Data::EntryPtr entry, bool overwrite);
+
+ Data::CollPtr m_coll;
+ Data::EntryVec m_entriesToUpdate;
+ Data::EntryVec m_fetchedEntries;
+ Data::EntryVec m_matchedEntries;
+ Fetch::FetcherVec m_fetchers;
+ int m_fetchIndex;
+ int m_origEntryCount;
+ ResultList m_results;
+ bool m_cancelled : 1;
+};
+
+} // end namespace
+
+#endif
diff --git a/src/entryview.cpp b/src/entryview.cpp
new file mode 100644
index 0000000..c4b0d38
--- /dev/null
+++ b/src/entryview.cpp
@@ -0,0 +1,364 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "entryview.h"
+#include "entry.h"
+#include "field.h"
+#include "filehandler.h"
+#include "translators/xslthandler.h"
+#include "translators/tellicoxmlexporter.h"
+#include "collection.h"
+#include "imagefactory.h"
+#include "tellico_kernel.h"
+#include "tellico_utils.h"
+#include "core/tellico_config.h"
+#include "newstuff/manager.h"
+#include "document.h"
+#include "latin1literal.h"
+#include "../core/drophandler.h"
+
+#include <kstandarddirs.h>
+#include <krun.h>
+#include <kmessagebox.h>
+#include <khtmlview.h>
+#include <dom/dom_element.h>
+#include <kapplication.h>
+#include <ktempfile.h>
+#include <klocale.h>
+
+#include <qfile.h>
+
+using Tellico::EntryView;
+
+EntryView::EntryView(QWidget* parent_, const char* name_) : KHTMLPart(parent_, name_),
+ m_entry(0), m_handler(0), m_run(0), m_tempFile(0), m_useGradientImages(true), m_checkCommonFile(true) {
+ setJScriptEnabled(false);
+ setJavaEnabled(false);
+ setMetaRefreshEnabled(false);
+ setPluginsEnabled(false);
+ clear(); // needed for initial layout
+
+ view()->setAcceptDrops(true);
+ DropHandler* drophandler = new DropHandler(this);
+ view()->installEventFilter(drophandler);
+
+ connect(browserExtension(), SIGNAL(openURLRequest(const KURL&, const KParts::URLArgs&)),
+ SLOT(slotOpenURL(const KURL&)));
+ connect(kapp, SIGNAL(kdisplayPaletteChanged()), SLOT(slotResetColors()));
+}
+
+EntryView::~EntryView() {
+ if(m_run) {
+ m_run->abort();
+ }
+ delete m_handler;
+ m_handler = 0;
+ delete m_tempFile;
+ m_tempFile = 0;
+}
+
+void EntryView::clear() {
+ m_entry = 0;
+
+ // just clear the view
+ begin();
+ if(!m_textToShow.isEmpty()) {
+ write(m_textToShow);
+ }
+ end();
+ view()->layout(); // I need this because some of the margins and widths may get messed up
+}
+
+void EntryView::showEntry(Data::EntryPtr entry_) {
+ if(!entry_) {
+ clear();
+ return;
+ }
+
+ m_textToShow = QString();
+#if 0
+ kdWarning() << "EntryView::showEntry() - turn me off!" << endl;
+ m_entry = 0;
+ setXSLTFile(m_xsltFile);
+#endif
+ if(!m_handler || !m_handler->isValid()) {
+ setXSLTFile(m_xsltFile);
+ }
+
+ m_entry = entry_;
+
+ // by setting the xslt file as the URL, any images referenced in the xslt "theme" can be found
+ // by simply using a relative path in the xslt file
+ KURL u;
+ u.setPath(m_xsltFile);
+ begin(u);
+
+ Export::TellicoXMLExporter exporter(entry_->collection());
+ exporter.setEntries(entry_);
+ long opt = exporter.options();
+ // verify images for the view
+ opt |= Export::ExportVerifyImages;
+ // on second thought, don't auto-format everything, just clean it
+// if(Data::Field::autoFormat()) {
+// opt = Export::ExportFormatted;
+// }
+ if(entry_->collection()->type() == Data::Collection::Bibtex) {
+ opt |= Export::ExportClean;
+ }
+ exporter.setOptions(opt);
+ QDomDocument dom = exporter.exportXML();
+
+// myDebug() << dom.toString() << endl;
+#if 0
+ kdWarning() << "EntryView::showEntry() - turn me off!" << endl;
+ QFile f1(QString::fromLatin1("/tmp/test.xml"));
+ if(f1.open(IO_WriteOnly)) {
+ QTextStream t(&f1);
+ t << dom.toString();
+ }
+ f1.close();
+#endif
+
+ QString html = m_handler->applyStylesheet(dom.toString());
+ // write out image files
+ Data::FieldVec fields = entry_->collection()->imageFields();
+ for(Data::FieldVec::Iterator field = fields.begin(); field != fields.end(); ++field) {
+ QString id = entry_->field(field);
+ if(id.isEmpty()) {
+ continue;
+ }
+ if(Data::Document::self()->allImagesOnDisk()) {
+ ImageFactory::writeCachedImage(id, ImageFactory::DataDir);
+ } else {
+ ImageFactory::writeCachedImage(id, ImageFactory::TempDir);
+ }
+ }
+
+#if 0
+ kdWarning() << "EntryView::showEntry() - turn me off!" << endl;
+ QFile f2(QString::fromLatin1("/tmp/test.html"));
+ if(f2.open(IO_WriteOnly)) {
+ QTextStream t(&f2);
+ t << html;
+ }
+ f2.close();
+#endif
+
+// myDebug() << html << endl;
+ write(html);
+ end();
+ // not need anymore?
+ view()->layout(); // I need this because some of the margins and widths may get messed up
+}
+
+void EntryView::showText(const QString& text_) {
+ m_textToShow = text_;
+ begin();
+ write(text_);
+ end();
+}
+
+void EntryView::setXSLTFile(const QString& file_) {
+ QString oldFile = m_xsltFile;
+ // if starts with slash, then absolute path
+ if(file_.at(0) == '/') {
+ m_xsltFile = file_;
+ } else {
+ const QString templateDir = QString::fromLatin1("entry-templates/");
+ m_xsltFile = locate("appdata", templateDir + file_);
+ if(m_xsltFile.isEmpty()) {
+ if(!file_.isEmpty()) {
+ kdWarning() << "EntryView::setXSLTFile() - can't locate " << file_ << endl;
+ }
+ m_xsltFile = locate("appdata", templateDir + QString::fromLatin1("Fancy.xsl"));
+ if(m_xsltFile.isEmpty()) {
+ QString str = QString::fromLatin1("<qt>");
+ str += i18n("Tellico is unable to locate the default entry stylesheet.");
+ str += QChar(' ');
+ str += i18n("Please check your installation.");
+ str += QString::fromLatin1("</qt>");
+ KMessageBox::error(view(), str);
+ clear();
+ return;
+ }
+ }
+ }
+
+ const int type = m_entry ? m_entry->collection()->type() : Kernel::self()->collectionType();
+
+ // we need to know if the colors changed from last time, in case
+ // we need to do that ugly hack to reload the cache
+ bool reloadImages = m_useGradientImages;
+ // if m_useGradientImages is false, then we don't even need to check
+ // if there's no handler, there there's _no way_ to check
+ if(m_handler && reloadImages) {
+ // the only two colors that matter for the gradients are the base color
+ // and highlight base color
+ const QCString& oldBase = m_handler->param("bgcolor");
+ const QCString& oldHigh = m_handler->param("color2");
+ // remember the string params have apostrophes on either side, so we can start search at pos == 1
+ reloadImages = oldBase.find(Config::templateBaseColor(type).name().latin1(), 1) == -1
+ || oldHigh.find(Config::templateHighlightedBaseColor(type).name().latin1(), 1) == -1;
+ }
+
+ if(!m_handler || m_xsltFile != oldFile) {
+ delete m_handler;
+ // must read the file name to get proper context
+ m_handler = new XSLTHandler(QFile::encodeName(m_xsltFile));
+ if(m_checkCommonFile && !m_handler->isValid()) {
+ NewStuff::Manager::checkCommonFile();
+ m_checkCommonFile = false;
+ delete m_handler;
+ m_handler = new XSLTHandler(QFile::encodeName(m_xsltFile));
+ }
+ if(!m_handler->isValid()) {
+ kdWarning() << "EntryView::setXSLTFile() - invalid xslt handler" << endl;
+ clear();
+ delete m_handler;
+ m_handler = 0;
+ return;
+ }
+ }
+
+ m_handler->addStringParam("font", Config::templateFont(type).family().latin1());
+ m_handler->addStringParam("fontsize", QCString().setNum(Config::templateFont(type).pointSize()));
+ m_handler->addStringParam("bgcolor", Config::templateBaseColor(type).name().latin1());
+ m_handler->addStringParam("fgcolor", Config::templateTextColor(type).name().latin1());
+ m_handler->addStringParam("color1", Config::templateHighlightedTextColor(type).name().latin1());
+ m_handler->addStringParam("color2", Config::templateHighlightedBaseColor(type).name().latin1());
+
+ if(Data::Document::self()->allImagesOnDisk()) {
+ m_handler->addStringParam("imgdir", QFile::encodeName(ImageFactory::dataDir()));
+ } else {
+ m_handler->addStringParam("imgdir", QFile::encodeName(ImageFactory::tempDir()));
+ }
+
+ // look for a file that gets installed to know the installation directory
+ QString appdir = KGlobal::dirs()->findResourceDir("appdata", QString::fromLatin1("pics/tellico.png"));
+ m_handler->addStringParam("datadir", QFile::encodeName(appdir));
+
+ // if we don't have to reload the images, then just show the entry and we're done
+ if(!reloadImages) {
+ showEntry(m_entry);
+ return;
+ }
+
+ // now, have to recreate images and refresh khtml cache
+ resetColors();
+}
+
+void EntryView::slotRefresh() {
+ setXSLTFile(m_xsltFile);
+ showEntry(m_entry);
+ view()->repaint();
+}
+
+// do some contortions in case the url is relative
+// need to interpret it relative to document URL instead of xslt file
+// the current node under the mouse vould be the text node inside
+// the anchor node, so iterate up the parents
+void EntryView::slotOpenURL(const KURL& url_) {
+ if(url_.protocol() == Latin1Literal("tc")) {
+ // handle this internally
+ emit signalAction(url_);
+ return;
+ }
+
+ KURL u = url_;
+ for(DOM::Node node = nodeUnderMouse(); !node.isNull(); node = node.parentNode()) {
+ if(node.nodeType() == DOM::Node::ELEMENT_NODE && static_cast<DOM::Element>(node).tagName() == "a") {
+ QString href = static_cast<DOM::Element>(node).getAttribute("href").string();
+ if(!href.isEmpty() && KURL::isRelativeURL(href)) {
+ // interpet url relative to document url
+ u = KURL(Kernel::self()->URL(), href);
+ }
+ break;
+ }
+ }
+ // open the url, m_run gets auto-deleted
+ m_run = new KRun(u);
+}
+
+void EntryView::slotReloadEntry() {
+ // this slot should only be connected in setXSLTFile()
+ // must disconnect the signal first, otherwise, get an infinite loop
+ disconnect(SIGNAL(completed()));
+ closeURL(); // this is needed to stop everything, for some reason
+ view()->setUpdatesEnabled(true);
+
+ if(m_entry) {
+ showEntry(m_entry);
+ } else {
+ // setXSLTFile() writes some html to clear the image cache
+ // but we don't want to see that, so just clear everything
+ clear();
+ }
+ delete m_tempFile;
+ m_tempFile = 0;
+}
+
+void EntryView::setXSLTOptions(const StyleOptions& opt_) {
+ m_handler->addStringParam("font", opt_.fontFamily.latin1());
+ m_handler->addStringParam("fontsize", QCString().setNum(opt_.fontSize));
+ m_handler->addStringParam("bgcolor", opt_.baseColor.name().latin1());
+ m_handler->addStringParam("fgcolor", opt_.textColor.name().latin1());
+ m_handler->addStringParam("color1", opt_.highlightedTextColor.name().latin1());
+ m_handler->addStringParam("color2", opt_.highlightedBaseColor.name().latin1());
+ m_handler->addStringParam("imgdir", QFile::encodeName(opt_.imgDir));
+}
+
+
+void EntryView::slotResetColors() {
+ // this will delete and reread the default colors, assuming they changed
+ // better to do this elsewhere, but do it here for now
+ Config::deleteAndReset();
+ delete m_handler; m_handler = 0;
+ setXSLTFile(m_xsltFile);
+}
+
+void EntryView::resetColors() {
+ ImageFactory::createStyleImages(); // recreate gradients
+
+ QString dir = m_handler ? m_handler->param("imgdir") : QString();
+ if(dir.isEmpty()) {
+ dir = Data::Document::self()->allImagesOnDisk() ? ImageFactory::dataDir() : ImageFactory::tempDir();
+ } else {
+ // it's a string param, so it has quotes on both sides
+ dir = dir.mid(1);
+ dir.truncate(dir.length()-1);
+ }
+
+ // this is a rather bad hack to get around the fact that the image cache is not reloaded when
+ // the gradient files are changed on disk. Setting the URLArgs for write() calls doesn't seem to
+ // work. So force a reload with a temp file, then catch the completed signal and repaint
+ QString s = QString::fromLatin1("<html><body><img src=\"%1\"><img src=\"%2\"></body></html>")
+ .arg(dir + QString::fromLatin1("gradient_bg.png"))
+ .arg(dir + QString::fromLatin1("gradient_header.png"));
+
+ delete m_tempFile;
+ m_tempFile = new KTempFile;
+ m_tempFile->setAutoDelete(true);
+ *m_tempFile->textStream() << s;
+ m_tempFile->file()->close(); // have to close it
+
+ KParts::URLArgs args = browserExtension()->urlArgs();
+ args.reload = true; // tell the cache to reload images
+ browserExtension()->setURLArgs(args);
+
+ // don't flicker
+ view()->setUpdatesEnabled(false);
+ openURL(m_tempFile->name());
+ connect(this, SIGNAL(completed()), SLOT(slotReloadEntry()));
+}
+
+#include "entryview.moc"
diff --git a/src/entryview.h b/src/entryview.h
new file mode 100644
index 0000000..ddca518
--- /dev/null
+++ b/src/entryview.h
@@ -0,0 +1,106 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef ENTRYVIEW_H
+#define ENTRYVIEW_H
+
+class KRun;
+class KTempFile;
+
+#include "datavectors.h"
+
+#include <khtml_part.h>
+
+#include <qguardedptr.h>
+
+namespace Tellico {
+ class XSLTHandler;
+ class ImageFactory;
+ class StyleOptions;
+
+/**
+ * @author Robby Stephenson
+ */
+class EntryView : public KHTMLPart {
+Q_OBJECT
+
+public:
+ /**
+ * The EntryView shows a HTML representation of the data in the entry.
+ *
+ * @param parent QWidget parent
+ * @param name QObject name
+ */
+ EntryView(QWidget* parent, const char* name=0);
+ /**
+ */
+ virtual ~EntryView();
+
+ /**
+ * Uses the xslt handler to convert an entry to html, and then writes that html to the view
+ *
+ * @param entry The entry to show
+ */
+ void showEntry(Data::EntryPtr entry);
+ void showText(const QString& text);
+
+ /**
+ * Clear the widget and set Entry pointer to NULL
+ */
+ void clear();
+ /**
+ * Sets the XSLT file. If the file name does not start with a back-slash, then the
+ * standard directories are searched.
+ *
+ * @param file The XSLT file name
+ */
+ void setXSLTFile(const QString& file);
+ void setXSLTOptions(const StyleOptions& options);
+ void setUseGradientImages(bool b) { m_useGradientImages = b; }
+
+signals:
+ void signalAction(const KURL& url);
+
+public slots:
+ /**
+ * Helper function to refresh view.
+ */
+ void slotRefresh();
+
+private slots:
+ /**
+ * Open a URL.
+ *
+ * @param url The URL to open
+ */
+ void slotOpenURL(const KURL& url);
+ void slotReloadEntry();
+ void slotResetColors();
+
+private:
+ void resetColors();
+
+ Data::EntryPtr m_entry;
+ XSLTHandler* m_handler;
+ QString m_xsltFile;
+ QString m_textToShow;
+
+ // to run any clicked processes
+ QGuardedPtr<KRun> m_run;
+ KTempFile* m_tempFile;
+ bool m_useGradientImages : 1;
+ bool m_checkCommonFile : 1;
+};
+
+} //end namespace
+#endif
diff --git a/src/exportdialog.cpp b/src/exportdialog.cpp
new file mode 100644
index 0000000..7ef61a0
--- /dev/null
+++ b/src/exportdialog.cpp
@@ -0,0 +1,262 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "exportdialog.h"
+#include "collection.h"
+#include "filehandler.h"
+#include "controller.h"
+#include "document.h"
+
+#include "translators/exporter.h"
+#include "translators/tellicoxmlexporter.h"
+#include "translators/tellicozipexporter.h"
+#include "translators/htmlexporter.h"
+#include "translators/csvexporter.h"
+#include "translators/bibtexexporter.h"
+#include "translators/bibtexmlexporter.h"
+#include "translators/xsltexporter.h"
+#include "translators/pilotdbexporter.h"
+#include "translators/alexandriaexporter.h"
+#include "translators/onixexporter.h"
+#include "translators/gcfilmsexporter.h"
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <kconfig.h>
+
+#include <qlayout.h>
+#include <qcheckbox.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qwhatsthis.h>
+#include <qtextcodec.h>
+
+using Tellico::ExportDialog;
+
+ExportDialog::ExportDialog(Export::Format format_, Data::CollPtr coll_, QWidget* parent_, const char* name_)
+ : KDialogBase(parent_, name_, true /*modal*/, i18n("Export Options"), Ok|Cancel),
+ m_format(format_), m_coll(coll_), m_exporter(exporter(format_)) {
+ QWidget* widget = new QWidget(this);
+ QVBoxLayout* topLayout = new QVBoxLayout(widget, 0, spacingHint());
+
+ QGroupBox* group1 = new QGroupBox(1, Qt::Horizontal, i18n("Formatting"), widget);
+ topLayout->addWidget(group1, 0);
+ m_formatFields = new QCheckBox(i18n("Format all fields"), group1);
+ m_formatFields->setChecked(false);
+ QWhatsThis::add(m_formatFields, i18n("If checked, the values of the fields will be "
+ "automatically formatted according to their format type."));
+ m_exportSelected = new QCheckBox(i18n("Export selected entries only"), group1);
+ m_exportSelected->setChecked(false);
+ QWhatsThis::add(m_exportSelected, i18n("If checked, only the currently selected entries will "
+ "be exported."));
+
+ QButtonGroup* bg = new QButtonGroup(1, Qt::Horizontal, i18n("Encoding"), widget);
+ topLayout->addWidget(bg, 0);
+ m_encodeUTF8 = new QRadioButton(i18n("Encode in Unicode (UTF-8)"), bg);
+ m_encodeUTF8->setChecked(true);
+ QWhatsThis::add(m_encodeUTF8, i18n("Encode the exported file in Unicode (UTF-8)."));
+ QString localStr = i18n("Encode in user locale (%1)").arg(
+ QString::fromLatin1(QTextCodec::codecForLocale()->name()));
+ m_encodeLocale = new QRadioButton(localStr, bg);
+ QWhatsThis::add(m_encodeLocale, i18n("Encode the exported file in the local encoding."));
+
+ QWidget* w = m_exporter->widget(widget, "exporter_widget");
+ if(w) {
+ topLayout->addWidget(w, 0);
+ }
+
+ topLayout->addStretch();
+
+ setMainWidget(widget);
+ readOptions();
+ // bibtex, CSV, and text are forced to locale
+ if(format_ == Export::Bibtex || format_ == Export::CSV || format_ == Export::Text) {
+ m_encodeUTF8->setEnabled(false);
+ m_encodeLocale->setChecked(true);
+// m_encodeLocale->setEnabled(false);
+ } else if(format_ == Export::Alexandria || format_ == Export::PilotDB) {
+ bg->setEnabled(false);
+ }
+ connect(this, SIGNAL(okClicked()), SLOT(slotSaveOptions()));
+}
+
+ExportDialog::~ExportDialog() {
+ delete m_exporter;
+ m_exporter = 0;
+}
+
+QString ExportDialog::fileFilter() {
+ return m_exporter ? m_exporter->fileFilter() : QString::null;
+}
+
+void ExportDialog::readOptions() {
+ KConfigGroup config(KGlobal::config(), "ExportOptions");
+ bool format = config.readBoolEntry("FormatFields", false);
+ m_formatFields->setChecked(format);
+ bool selected = config.readBoolEntry("ExportSelectedOnly", false);
+ m_exportSelected->setChecked(selected);
+ bool encode = config.readBoolEntry("EncodeUTF8", true);
+ if(encode) {
+ m_encodeUTF8->setChecked(true);
+ } else {
+ m_encodeLocale->setChecked(true);
+ }
+}
+
+void ExportDialog::slotSaveOptions() {
+ KConfig* config = KGlobal::config();
+ // each exporter sets its own group
+ m_exporter->saveOptions(config);
+
+ KConfigGroup configGroup(config, "ExportOptions");
+ configGroup.writeEntry("FormatFields", m_formatFields->isChecked());
+ configGroup.writeEntry("ExportSelectedOnly", m_exportSelected->isChecked());
+ configGroup.writeEntry("EncodeUTF8", m_encodeUTF8->isChecked());
+}
+
+// static
+Tellico::Export::Exporter* ExportDialog::exporter(Export::Format format_) {
+ Export::Exporter* exporter = 0;
+
+ switch(format_) {
+ case Export::TellicoXML:
+ exporter = new Export::TellicoXMLExporter();
+ break;
+
+ case Export::TellicoZip:
+ exporter = new Export::TellicoZipExporter();
+ break;
+
+ case Export::HTML:
+ {
+ Export::HTMLExporter* htmlExp = new Export::HTMLExporter();
+ htmlExp->setGroupBy(Controller::self()->expandedGroupBy());
+ htmlExp->setSortTitles(Controller::self()->sortTitles());
+ htmlExp->setColumns(Controller::self()->visibleColumns());
+ exporter = htmlExp;
+ }
+ break;
+
+ case Export::CSV:
+ exporter = new Export::CSVExporter();
+ break;
+
+ case Export::Bibtex:
+ exporter = new Export::BibtexExporter();
+ break;
+
+ case Export::Bibtexml:
+ exporter = new Export::BibtexmlExporter();
+ break;
+
+ case Export::XSLT:
+ exporter = new Export::XSLTExporter();
+ break;
+
+ case Export::PilotDB:
+ {
+ Export::PilotDBExporter* pdbExp = new Export::PilotDBExporter();
+ pdbExp->setColumns(Controller::self()->visibleColumns());
+ exporter = pdbExp;
+ }
+ break;
+
+ case Export::Alexandria:
+ exporter = new Export::AlexandriaExporter();
+ break;
+
+ case Export::ONIX:
+ exporter = new Export::ONIXExporter();
+ break;
+
+ case Export::GCfilms:
+ exporter = new Export::GCfilmsExporter();
+ break;
+
+ default:
+ kdDebug() << "ExportDialog::exporter() - not implemented!" << endl;
+ break;
+ }
+ if(exporter) {
+ exporter->readOptions(KGlobal::config());
+ }
+ return exporter;
+}
+
+bool ExportDialog::exportURL(const KURL& url_/*=KURL()*/) const {
+ if(!m_exporter) {
+ return false;
+ }
+
+ if(!url_.isEmpty() && !FileHandler::queryExists(url_)) {
+ return false;
+ }
+
+ // exporter might need to know final URL, say for writing images or something
+ m_exporter->setURL(url_);
+ if(m_exportSelected->isChecked()) {
+ m_exporter->setEntries(Controller::self()->selectedEntries());
+ } else {
+ m_exporter->setEntries(m_coll->entries());
+ }
+ long opt = Export::ExportImages | Export::ExportComplete | Export::ExportProgress; // for now, always export images
+ if(m_formatFields->isChecked()) {
+ opt |= Export::ExportFormatted;
+ }
+ if(m_encodeUTF8->isChecked()) {
+ opt |= Export::ExportUTF8;
+ }
+ // since we already asked about overwriting the file, force the save
+ opt |= Export::ExportForce;
+
+ m_exporter->setOptions(opt);
+
+ return m_exporter->exec();
+}
+
+// static
+// alexandria is exported to known directory
+// all others are files
+Tellico::Export::Target ExportDialog::exportTarget(Export::Format format_) {
+ switch(format_) {
+ case Export::Alexandria:
+ return Export::None;
+ default:
+ return Export::File;
+ }
+}
+
+// static
+bool ExportDialog::exportCollection(Export::Format format_, const KURL& url_) {
+ Export::Exporter* exp = exporter(format_);
+
+ exp->setURL(url_);
+ exp->setEntries(Data::Document::self()->collection()->entries());
+
+ KConfigGroup config(KGlobal::config(), "ExportOptions");
+ long options = 0;
+ if(config.readBoolEntry("FormatFields", false)) {
+ options |= Export::ExportFormatted;
+ }
+ if(config.readBoolEntry("EncodeUTF8", true)) {
+ options |= Export::ExportUTF8;
+ }
+ exp->setOptions(options | Export::ExportForce);
+
+ bool success = exp->exec();
+ delete exp;
+ return success;
+}
+
+#include "exportdialog.moc"
diff --git a/src/exportdialog.h b/src/exportdialog.h
new file mode 100644
index 0000000..2e68ca3
--- /dev/null
+++ b/src/exportdialog.h
@@ -0,0 +1,65 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef EXPORTDIALOG_H
+#define EXPORTDIALOG_H
+
+class QCheckBox;
+class QRadioButton;
+
+#include "translators/translators.h"
+#include "datavectors.h"
+
+#include <kdialogbase.h>
+#include <kurl.h>
+
+namespace Tellico {
+ namespace Export {
+ class Exporter;
+ }
+
+/**
+ * @author Robby Stephenson
+ */
+class ExportDialog : public KDialogBase {
+Q_OBJECT
+
+public:
+ ExportDialog(Export::Format format, Data::CollPtr coll, QWidget* parent, const char* name);
+ ~ExportDialog();
+
+ QString fileFilter();
+ bool exportURL(const KURL& url=KURL()) const;
+
+ static Export::Target exportTarget(Export::Format format);
+ static bool exportCollection(Export::Format format, const KURL& url);
+
+private slots:
+ void slotSaveOptions();
+
+private:
+ static Export::Exporter* exporter(Export::Format format);
+
+ void readOptions();
+
+ Export::Format m_format;
+ Data::CollPtr m_coll;
+ Export::Exporter* m_exporter;
+ QCheckBox* m_formatFields;
+ QCheckBox* m_exportSelected;
+ QRadioButton* m_encodeUTF8;
+ QRadioButton* m_encodeLocale;
+};
+
+} // end namespace
+#endif
diff --git a/src/fetch/Makefile.am b/src/fetch/Makefile.am
new file mode 100644
index 0000000..fbf2ea1
--- /dev/null
+++ b/src/fetch/Makefile.am
@@ -0,0 +1,46 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+noinst_LIBRARIES = libfetch.a
+
+AM_CPPFLAGS = $(all_includes) $(LIBXML_CFLAGS) $(LIBXSLT_CFLAGS) $(YAZ_CFLAGS)
+
+libfetch_a_METASOURCES = AUTO
+
+libfetch_a_SOURCES = amazonfetcher.cpp animenfofetcher.cpp arxivfetcher.cpp \
+ bibsonomyfetcher.cpp citebasefetcher.cpp configwidget.cpp crossreffetcher.cpp \
+ discogsfetcher.cpp entrezfetcher.cpp execexternalfetcher.cpp fetcher.cpp fetchmanager.cpp \
+ gcstarpluginfetcher.cpp googlescholarfetcher.cpp ibsfetcher.cpp imdbfetcher.cpp \
+ isbndbfetcher.cpp messagehandler.cpp srufetcher.cpp yahoofetcher.cpp z3950connection.cpp \
+ z3950fetcher.cpp
+
+####### kdevelop will overwrite this part!!! (end)############
+
+SUBDIRS = scripts
+
+CLEANFILES = *~
+
+KDE_OPTIONS = noautodist
+
+EXTRA_DIST = \
+fetcher.h fetcher.cpp fetchmanager.h fetchmanager.cpp \
+amazonfetcher.h amazonfetcher.cpp z3950fetcher.h z3950fetcher.cpp \
+imdbfetcher.h imdbfetcher.cpp fetch.h configwidget.h configwidget.cpp \
+entrezfetcher.h entrezfetcher.cpp \
+execexternalfetcher.h execexternalfetcher.cpp \
+messagehandler.h messagehandler.cpp \
+z3950connection.h z3950connection.cpp \
+yahoofetcher.h yahoofetcher.cpp \
+animenfofetcher.h animenfofetcher.cpp \
+ibsfetcher.h ibsfetcher.cpp \
+srufetcher.h srufetcher.cpp \
+isbndbfetcher.h isbndbfetcher.cpp \
+gcstarpluginfetcher.h gcstarpluginfetcher.cpp \
+crossreffetcher.h crossreffetcher.cpp \
+arxivfetcher.h arxivfetcher.cpp \
+citebasefetcher.h citebasefetcher.cpp \
+bibsonomyfetcher.h bibsonomyfetcher.cpp \
+googlescholarfetcher.h googlescholarfetcher.cpp \
+discogsfetcher.h discogsfetcher.cpp \
+z3950-servers.cfg
+
+appdir = $(kde_datadir)/tellico
+app_DATA = z3950-servers.cfg
diff --git a/src/fetch/amazonfetcher.cpp b/src/fetch/amazonfetcher.cpp
new file mode 100644
index 0000000..36c009f
--- /dev/null
+++ b/src/fetch/amazonfetcher.cpp
@@ -0,0 +1,937 @@
+/***************************************************************************
+ copyright : (C) 2004-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "amazonfetcher.h"
+#include "messagehandler.h"
+#include "../translators/xslthandler.h"
+#include "../translators/tellicoimporter.h"
+#include "../imagefactory.h"
+#include "../tellico_kernel.h"
+#include "../latin1literal.h"
+#include "../collection.h"
+#include "../document.h"
+#include "../entry.h"
+#include "../field.h"
+#include "../tellico_utils.h"
+#include "../tellico_debug.h"
+#include "../isbnvalidator.h"
+#include "../gui/combobox.h"
+
+#include <klocale.h>
+#include <kio/job.h>
+#include <kstandarddirs.h>
+#include <kconfig.h>
+#include <klineedit.h>
+#include <kseparator.h>
+#include <kcombobox.h>
+#include <kaccelmanager.h>
+
+#include <qdom.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qwhatsthis.h>
+#include <qcheckbox.h>
+#include <qfile.h>
+#include <qtextcodec.h>
+
+namespace {
+ static const int AMAZON_RETURNS_PER_REQUEST = 10;
+ static const int AMAZON_MAX_RETURNS_TOTAL = 20;
+ static const char* AMAZON_ACCESS_KEY = "0834VQ4S71KYPVSYQD02";
+ static const char* AMAZON_ASSOC_TOKEN = "tellico-20";
+ // need to have these in the translation file
+ static const char* linkText = I18N_NOOP("Amazon Link");
+}
+
+using Tellico::Fetch::AmazonFetcher;
+
+// static
+const AmazonFetcher::SiteData& AmazonFetcher::siteData(int site_) {
+ static SiteData dataVector[6] = {
+ {
+ i18n("Amazon (US)"),
+ "http://webservices.amazon.com/onca/xml"
+ }, {
+ i18n("Amazon (UK)"),
+ "http://webservices.amazon.co.uk/onca/xml"
+ }, {
+ i18n("Amazon (Germany)"),
+ "http://webservices.amazon.de/onca/xml"
+ }, {
+ i18n("Amazon (Japan)"),
+ "http://webservices.amazon.co.jp/onca/xml"
+ }, {
+ i18n("Amazon (France)"),
+ "http://webservices.amazon.fr/onca/xml"
+ }, {
+ i18n("Amazon (Canada)"),
+ "http://webservices.amazon.ca/onca/xml"
+ }
+ };
+
+ return dataVector[site_];
+}
+
+AmazonFetcher::AmazonFetcher(Site site_, QObject* parent_, const char* name_)
+ : Fetcher(parent_, name_), m_xsltHandler(0), m_site(site_), m_imageSize(MediumImage),
+ m_access(QString::fromLatin1(AMAZON_ACCESS_KEY)),
+ m_assoc(QString::fromLatin1(AMAZON_ASSOC_TOKEN)), m_addLinkField(true), m_limit(AMAZON_MAX_RETURNS_TOTAL),
+ m_countOffset(0), m_page(1), m_total(-1), m_numResults(0), m_job(0), m_started(false) {
+ m_name = siteData(site_).title;
+}
+
+AmazonFetcher::~AmazonFetcher() {
+ delete m_xsltHandler;
+ m_xsltHandler = 0;
+}
+
+QString AmazonFetcher::defaultName() {
+ return i18n("Amazon.com Web Services");
+}
+
+QString AmazonFetcher::source() const {
+ return m_name.isEmpty() ? defaultName() : m_name;
+}
+
+bool AmazonFetcher::canFetch(int type) const {
+ return type == Data::Collection::Book
+ || type == Data::Collection::ComicBook
+ || type == Data::Collection::Bibtex
+ || type == Data::Collection::Album
+ || type == Data::Collection::Video
+ || type == Data::Collection::Game;
+}
+
+void AmazonFetcher::readConfigHook(const KConfigGroup& config_) {
+ QString s = config_.readEntry("AccessKey");
+ if(!s.isEmpty()) {
+ m_access = s;
+ }
+ s = config_.readEntry("AssocToken");
+ if(!s.isEmpty()) {
+ m_assoc = s;
+ }
+ int imageSize = config_.readNumEntry("Image Size", -1);
+ if(imageSize > -1) {
+ m_imageSize = static_cast<ImageSize>(imageSize);
+ }
+ m_fields = config_.readListEntry("Custom Fields", QString::fromLatin1("keyword"));
+}
+
+void AmazonFetcher::search(FetchKey key_, const QString& value_) {
+ m_key = key_;
+ m_value = value_.stripWhiteSpace();
+ m_started = true;
+ m_page = 1;
+ m_total = -1;
+ m_countOffset = 0;
+ m_numResults = 0;
+ doSearch();
+}
+
+void AmazonFetcher::continueSearch() {
+ m_started = true;
+ m_limit += AMAZON_MAX_RETURNS_TOTAL;
+ doSearch();
+}
+
+void AmazonFetcher::doSearch() {
+ m_data.truncate(0);
+
+// myDebug() << "AmazonFetcher::doSearch() - value = " << m_value << endl;
+// myDebug() << "AmazonFetcher::doSearch() - getting page " << m_page << endl;
+
+ const SiteData& data = siteData(m_site);
+ KURL u = data.url;
+ u.addQueryItem(QString::fromLatin1("Service"), QString::fromLatin1("AWSECommerceService"));
+ u.addQueryItem(QString::fromLatin1("AssociateTag"), m_assoc);
+ u.addQueryItem(QString::fromLatin1("AWSAccessKeyId"), m_access);
+ u.addQueryItem(QString::fromLatin1("Operation"), QString::fromLatin1("ItemSearch"));
+ u.addQueryItem(QString::fromLatin1("ResponseGroup"), QString::fromLatin1("Large"));
+ u.addQueryItem(QString::fromLatin1("ItemPage"), QString::number(m_page));
+ u.addQueryItem(QString::fromLatin1("Version"), QString::fromLatin1("2007-10-29"));
+
+ const int type = Kernel::self()->collectionType();
+ switch(type) {
+ case Data::Collection::Book:
+ case Data::Collection::ComicBook:
+ case Data::Collection::Bibtex:
+ u.addQueryItem(QString::fromLatin1("SearchIndex"), QString::fromLatin1("Books"));
+ u.addQueryItem(QString::fromLatin1("SortIndex"), QString::fromLatin1("relevancerank"));
+ break;
+
+ case Data::Collection::Album:
+ u.addQueryItem(QString::fromLatin1("SearchIndex"), QString::fromLatin1("Music"));
+ break;
+
+ case Data::Collection::Video:
+ u.addQueryItem(QString::fromLatin1("SearchIndex"), QString::fromLatin1("Video"));
+ u.addQueryItem(QString::fromLatin1("SortIndex"), QString::fromLatin1("relevancerank"));
+ break;
+
+ case Data::Collection::Game:
+ u.addQueryItem(QString::fromLatin1("SearchIndex"), QString::fromLatin1("VideoGames"));
+ break;
+
+ case Data::Collection::Coin:
+ case Data::Collection::Stamp:
+ case Data::Collection::Wine:
+ case Data::Collection::Base:
+ case Data::Collection::Card:
+ default:
+ message(i18n("%1 does not allow searching for this collection type.").arg(source()), MessageHandler::Warning);
+ stop();
+ return;
+ }
+
+ // I have not been able to find any documentation about what character set to use
+ // when URL encoding the search term in the Amazon REST interface. But I do know
+ // that utf8 DOES NOT WORK. So I'm arbitrarily using iso-8859-1, except for JP.
+ // Why different for JP? Well, I've not received any bug reports from that direction yet
+
+// QString value = KURL::decode_string(value_, 106);
+// QString value = QString::fromLocal8Bit(value_.utf8());
+ QString value = m_value;
+ // a mibenum of 106 is utf-8, 4 is iso-8859-1, 0 means use user's locale,
+ int mib = m_site == AmazonFetcher::JP ? 106 : 4;
+
+ switch(m_key) {
+ case Title:
+ u.addQueryItem(QString::fromLatin1("Title"), value, mib);
+ break;
+
+ case Person:
+ if(type == Data::Collection::Video) {
+ u.addQueryItem(QString::fromLatin1("Actor"), value, mib);
+ u.addQueryItem(QString::fromLatin1("Director"), value, mib);
+ } else if(type == Data::Collection::Album) {
+ u.addQueryItem(QString::fromLatin1("Artist"), value, mib);
+ } else if(type == Data::Collection::Game) {
+ u.addQueryItem(QString::fromLatin1("Manufacturer"), value, mib);
+ } else { // books and bibtex
+ QString s = QString::fromLatin1("author:%1 or publisher:%2").arg(value, value);
+// u.addQueryItem(QString::fromLatin1("Author"), value, mib);
+// u.addQueryItem(QString::fromLatin1("Publisher"), value, mib);
+ u.addQueryItem(QString::fromLatin1("Power"), s, mib);
+ }
+ break;
+
+ case ISBN:
+ {
+ u.removeQueryItem(QString::fromLatin1("Operation"));
+ u.addQueryItem(QString::fromLatin1("Operation"), QString::fromLatin1("ItemLookup"));
+
+ QString s = m_value; // not encValue!!!
+ s.remove('-');
+ // ISBN only get digits or 'X', and multiple values are connected with "; "
+ QStringList isbns = QStringList::split(QString::fromLatin1("; "), s);
+ // Amazon isbn13 search is still very flaky, so if possible, we're going to convert
+ // all of them to isbn10. If we run into a 979 isbn13, then we're forced to do an
+ // isbn13 search
+ bool isbn13 = false;
+ for(QStringList::Iterator it = isbns.begin(); it != isbns.end(); ) {
+ if(m_value.startsWith(QString::fromLatin1("979"))) {
+ if(m_site == JP) { // never works for JP
+ kdWarning() << "AmazonFetcher:doSearch() - ISBN-13 searching not implemented for Japan" << endl;
+ isbns.remove(it); // automatically skips to next
+ continue;
+ }
+ isbn13 = true;
+ break;
+ }
+ ++it;
+ }
+ // if we want isbn10, then convert all
+ if(!isbn13) {
+ for(QStringList::Iterator it = isbns.begin(); it != isbns.end(); ++it) {
+ if((*it).length() > 12) {
+ (*it) = ISBNValidator::isbn10(*it);
+ (*it).remove('-');
+ }
+ }
+ // the default search is by ASIN, which prohibits SearchIndex
+ u.removeQueryItem(QString::fromLatin1("SearchIndex"));
+ }
+ // limit to first 10
+ while(isbns.size() > 10) {
+ isbns.pop_back();
+ }
+ u.addQueryItem(QString::fromLatin1("ItemId"), isbns.join(QString::fromLatin1(",")));
+ if(isbn13) {
+ u.addQueryItem(QString::fromLatin1("IdType"), QString::fromLatin1("EAN"));
+ }
+ }
+ break;
+
+ case UPC:
+ {
+ u.removeQueryItem(QString::fromLatin1("Operation"));
+ u.addQueryItem(QString::fromLatin1("Operation"), QString::fromLatin1("ItemLookup"));
+ // US allows UPC, all others are EAN
+ if(m_site == US) {
+ u.addQueryItem(QString::fromLatin1("IdType"), QString::fromLatin1("UPC"));
+ } else {
+ u.addQueryItem(QString::fromLatin1("IdType"), QString::fromLatin1("EAN"));
+ }
+ QString s = m_value; // not encValue!!!
+ s.remove('-');
+ // limit to first 10
+ s.replace(QString::fromLatin1("; "), QString::fromLatin1(","));
+ s = s.section(',', 0, 9);
+ u.addQueryItem(QString::fromLatin1("ItemId"), s);
+ }
+ break;
+
+ case Keyword:
+ u.addQueryItem(QString::fromLatin1("Keywords"), m_value, mib);
+ break;
+
+ case Raw:
+ {
+ QString key = value.section('=', 0, 0).stripWhiteSpace();
+ QString str = value.section('=', 1).stripWhiteSpace();
+ u.addQueryItem(key, str, mib);
+ }
+ break;
+
+ default:
+ kdWarning() << "AmazonFetcher::search() - key not recognized: " << m_key << endl;
+ stop();
+ return;
+ }
+// myDebug() << "AmazonFetcher::search() - url: " << u.url() << endl;
+
+ m_job = KIO::get(u, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+}
+
+void AmazonFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+// myDebug() << "AmazonFetcher::stop()" << endl;
+ if(m_job) {
+ m_job->kill();
+ m_job = 0;
+ }
+ m_data.truncate(0);
+ m_started = false;
+ emit signalDone(this);
+}
+
+void AmazonFetcher::slotData(KIO::Job*, const QByteArray& data_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(data_.data(), data_.size());
+}
+
+void AmazonFetcher::slotComplete(KIO::Job* job_) {
+// myDebug() << "AmazonFetcher::slotComplete()" << endl;
+
+ // since the fetch is done, don't worry about holding the job pointer
+ m_job = 0;
+
+ if(job_->error()) {
+ job_->showErrorDialog(Kernel::self()->widget());
+ stop();
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "AmazonFetcher::slotComplete() - no data" << endl;
+ stop();
+ return;
+ }
+
+#if 0
+ kdWarning() << "Remove debug from amazonfetcher.cpp" << endl;
+ QFile f(QString::fromLatin1("/tmp/test%1.xml").arg(m_page));
+ if(f.open(IO_WriteOnly)) {
+ QTextStream t(&f);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << QCString(m_data, m_data.size()+1);
+ }
+ f.close();
+#endif
+
+ QStringList errors;
+ if(m_total == -1) {
+ QDomDocument dom;
+ if(!dom.setContent(m_data, false)) {
+ kdWarning() << "AmazonFetcher::slotComplete() - server did not return valid XML." << endl;
+ stop();
+ return;
+ }
+ // find TotalResults element
+ // it's in the first level under the root element
+ //ItemSearchResponse/Items/TotalResults
+ QDomNode n = dom.documentElement().namedItem(QString::fromLatin1("Items"))
+ .namedItem(QString::fromLatin1("TotalResults"));
+ QDomElement e = n.toElement();
+ if(!e.isNull()) {
+ m_total = e.text().toInt();
+ }
+ n = dom.documentElement().namedItem(QString::fromLatin1("Items"))
+ .namedItem(QString::fromLatin1("Request"))
+ .namedItem(QString::fromLatin1("Errors"));
+ e = n.toElement();
+ if(!e.isNull()) {
+ QDomNodeList nodes = e.elementsByTagName(QString::fromLatin1("Error"));
+ for(uint i = 0; i < nodes.count(); ++i) {
+ e = nodes.item(i).toElement().namedItem(QString::fromLatin1("Code")).toElement();
+ if(!e.isNull() && e.text() == Latin1Literal("AWS.ECommerceService.NoExactMatches")) {
+ // no exact match, not a real error, so skip
+ continue;
+ }
+ // for some reason, Amazon will return an error simply when a valid ISBN is not found
+ // I really want to ignore that, so check the IsValid element in the Request element
+ QDomNode isValidNode = n.parentNode().namedItem(QString::fromLatin1("IsValid"));
+ if(m_key == ISBN && isValidNode.toElement().text().lower() == Latin1Literal("true")) {
+ continue;
+ }
+ e = nodes.item(i).toElement().namedItem(QString::fromLatin1("Message")).toElement();
+ if(!e.isNull()) {
+ errors << e.text();
+ }
+ }
+ }
+ }
+
+ if(!m_xsltHandler) {
+ initXSLTHandler();
+ if(!m_xsltHandler) { // probably an error somewhere in the stylesheet loading
+ stop();
+ return;
+ }
+ }
+
+// QRegExp stripHTML(QString::fromLatin1("<.*>"), true);
+// stripHTML.setMinimal(true);
+
+ // assume amazon is always utf-8
+ QString str = m_xsltHandler->applyStylesheet(QString::fromUtf8(m_data, m_data.size()));
+ Import::TellicoImporter imp(str);
+ Data::CollPtr coll = imp.collection();
+ if(!coll) {
+ myDebug() << "AmazonFetcher::slotComplete() - no collection pointer" << endl;
+ stop();
+ return;
+ }
+
+ if(!m_addLinkField) {
+ // remove amazon field if it's not to be added
+ coll->removeField(QString::fromLatin1("amazon"));
+ }
+
+ Data::EntryVec entries = coll->entries();
+ if(entries.isEmpty() && !errors.isEmpty()) {
+ for(QStringList::ConstIterator it = errors.constBegin(); it != errors.constEnd(); ++it) {
+ myDebug() << "AmazonFetcher::" << *it << endl;
+ }
+ message(errors[0], MessageHandler::Error);
+ stop();
+ return;
+ }
+
+ int count = 0;
+ for(Data::EntryVec::Iterator entry = entries.begin();
+ m_numResults < m_limit && entry != entries.end();
+ ++entry, ++count) {
+ if(count < m_countOffset) {
+ continue;
+ }
+ if(!m_started) {
+ // might get aborted
+ break;
+ }
+
+ // special case book author
+ // amazon is really bad about not putting spaces after periods
+ if(coll->type() == Data::Collection::Book) {
+ QRegExp rx(QString::fromLatin1("\\.([^\\s])"));
+ QStringList values = entry->fields(QString::fromLatin1("author"), false);
+ for(QStringList::Iterator it = values.begin(); it != values.end(); ++it) {
+ (*it).replace(rx, QString::fromLatin1(". \\1"));
+ }
+ entry->setField(QString::fromLatin1("author"), values.join(QString::fromLatin1("; ")));
+ }
+
+ // UK puts the year in the title for some reason
+ if(m_site == UK && coll->type() == Data::Collection::Video) {
+ QRegExp rx(QString::fromLatin1("\\[(\\d{4})\\]"));
+ QString t = entry->title();
+ if(t.find(rx) > -1) {
+ QString y = rx.cap(1);
+ t.remove(rx).simplifyWhiteSpace();
+ entry->setField(QString::fromLatin1("title"), t);
+ if(entry->field(QString::fromLatin1("year")).isEmpty()) {
+ entry->setField(QString::fromLatin1("year"), y);
+ }
+ }
+ }
+
+ QString desc;
+ switch(coll->type()) {
+ case Data::Collection::Book:
+ case Data::Collection::ComicBook:
+ case Data::Collection::Bibtex:
+ desc = entry->field(QString::fromLatin1("author"))
+ + QChar('/') + entry->field(QString::fromLatin1("publisher"));
+ if(!entry->field(QString::fromLatin1("cr_year")).isEmpty()) {
+ desc += QChar('/') + entry->field(QString::fromLatin1("cr_year"));
+ } else if(!entry->field(QString::fromLatin1("pub_year")).isEmpty()){
+ desc += QChar('/') + entry->field(QString::fromLatin1("pub_year"));
+ }
+ break;
+
+ case Data::Collection::Video:
+ desc = entry->field(QString::fromLatin1("studio"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("director"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("year"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("medium"));
+ break;
+
+ case Data::Collection::Album:
+ desc = entry->field(QString::fromLatin1("artist"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("label"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("year"));
+ break;
+
+ case Data::Collection::Game:
+ desc = entry->field(QString::fromLatin1("platform"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("year"));
+ break;
+
+ default:
+ break;
+ }
+
+ // strip HTML from comments, or plot in movies
+ // tentatively don't do this, looks like ECS 4 cleaned everything up
+/*
+ if(coll->type() == Data::Collection::Video) {
+ QString plot = entry->field(QString::fromLatin1("plot"));
+ plot.remove(stripHTML);
+ entry->setField(QString::fromLatin1("plot"), plot);
+ } else if(coll->type() == Data::Collection::Game) {
+ QString desc = entry->field(QString::fromLatin1("description"));
+ desc.remove(stripHTML);
+ entry->setField(QString::fromLatin1("description"), desc);
+ } else {
+ QString comments = entry->field(QString::fromLatin1("comments"));
+ comments.remove(stripHTML);
+ entry->setField(QString::fromLatin1("comments"), comments);
+ }
+*/
+// myDebug() << "AmazonFetcher::slotComplete() - " << entry->title() << endl;
+ SearchResult* r = new SearchResult(this, entry->title(), desc, entry->field(QString::fromLatin1("isbn")));
+ m_entries.insert(r->uid, Data::EntryPtr(entry));
+ emit signalResultFound(r);
+ ++m_numResults;
+ }
+
+ // we might have gotten aborted
+ if(!m_started) {
+ return;
+ }
+
+ // are there any additional results to get?
+ m_hasMoreResults = m_page * AMAZON_RETURNS_PER_REQUEST < m_total;
+
+ const int currentTotal = QMIN(m_total, m_limit);
+ if(m_page * AMAZON_RETURNS_PER_REQUEST < currentTotal) {
+ int foundCount = (m_page-1) * AMAZON_RETURNS_PER_REQUEST + coll->entryCount();
+ message(i18n("Results from %1: %2/%3").arg(source()).arg(foundCount).arg(m_total), MessageHandler::Status);
+ ++m_page;
+ m_countOffset = 0;
+ doSearch();
+ } else if(m_value.contains(';') > 9) {
+ search(m_key, m_value.section(';', 10));
+ } else {
+ m_countOffset = m_entries.count() % AMAZON_RETURNS_PER_REQUEST;
+ if(m_countOffset == 0) {
+ ++m_page; // need to go to next page
+ }
+ stop();
+ }
+}
+
+Tellico::Data::EntryPtr AmazonFetcher::fetchEntry(uint uid_) {
+ Data::EntryPtr entry = m_entries[uid_];
+ if(!entry) {
+ kdWarning() << "AmazonFetcher::fetchEntry() - no entry in dict" << endl;
+ return 0;
+ }
+
+ QStringList defaultFields = customFields().keys();
+ for(QStringList::Iterator it = defaultFields.begin(); it != defaultFields.end(); ++it) {
+ if(!m_fields.contains(*it)) {
+ entry->setField(*it, QString::null);
+ }
+ }
+
+ // do what we can to remove useless keywords
+ const int type = Kernel::self()->collectionType();
+ switch(type) {
+ case Data::Collection::Book:
+ case Data::Collection::ComicBook:
+ case Data::Collection::Bibtex:
+ {
+ const QString keywords = QString::fromLatin1("keyword");
+ QStringList oldWords = entry->fields(keywords, false);
+ StringSet words;
+ for(QStringList::Iterator it = oldWords.begin(); it != oldWords.end(); ++it) {
+ // the amazon2tellico stylesheet separates keywords with '/'
+ QStringList nodes = QStringList::split('/', *it);
+ for(QStringList::Iterator it2 = nodes.begin(); it2 != nodes.end(); ++it2) {
+ if(*it2 == Latin1Literal("General") ||
+ *it2 == Latin1Literal("Subjects") ||
+ *it2 == Latin1Literal("Par prix") || // french stuff
+ *it2 == Latin1Literal("Divers") || // french stuff
+ (*it2).startsWith(QChar('(')) ||
+ (*it2).startsWith(QString::fromLatin1("Authors"))) {
+ continue;
+ }
+ words.add(*it2);
+ }
+ }
+ entry->setField(keywords, words.toList().join(QString::fromLatin1("; ")));
+ }
+ entry->setField(QString::fromLatin1("comments"), Tellico::decodeHTML(entry->field(QString::fromLatin1("comments"))));
+ break;
+
+ case Data::Collection::Video:
+ {
+ const QString genres = QString::fromLatin1("genre");
+ QStringList oldWords = entry->fields(genres, false);
+ StringSet words;
+ // only care about genres that have "Genres" in the amazon response
+ // and take the first word after that
+ for(QStringList::Iterator it = oldWords.begin(); it != oldWords.end(); ++it) {
+ if((*it).find(QString::fromLatin1("Genres")) == -1) {
+ continue;
+ }
+
+ // the amazon2tellico stylesheet separates words with '/'
+ QStringList nodes = QStringList::split('/', *it);
+ for(QStringList::Iterator it2 = nodes.begin(); it2 != nodes.end(); ++it2) {
+ if(*it2 != Latin1Literal("Genres")) {
+ continue;
+ }
+ ++it2;
+ if(it2 != nodes.end() && *it2 != Latin1Literal("General")) {
+ words.add(*it2);
+ }
+ break; // we're done
+ }
+ }
+ entry->setField(genres, words.toList().join(QString::fromLatin1("; ")));
+ // language tracks get duplicated, too
+ QStringList langs = entry->fields(QString::fromLatin1("language"), false);
+ words.clear();
+ for(QStringList::ConstIterator it = langs.begin(); it != langs.end(); ++it) {
+ words.add(*it);
+ }
+ entry->setField(QString::fromLatin1("language"), words.toList().join(QString::fromLatin1("; ")));
+ }
+ entry->setField(QString::fromLatin1("plot"), Tellico::decodeHTML(entry->field(QString::fromLatin1("plot"))));
+ break;
+
+ case Data::Collection::Album:
+ {
+ const QString genres = QString::fromLatin1("genre");
+ QStringList oldWords = entry->fields(genres, false);
+ StringSet words;
+ // only care about genres that have "Styles" in the amazon response
+ // and take the first word after that
+ for(QStringList::Iterator it = oldWords.begin(); it != oldWords.end(); ++it) {
+ if((*it).find(QString::fromLatin1("Styles")) == -1) {
+ continue;
+ }
+
+ // the amazon2tellico stylesheet separates words with '/'
+ QStringList nodes = QStringList::split('/', *it);
+ bool isStyle = false;
+ for(QStringList::Iterator it2 = nodes.begin(); it2 != nodes.end(); ++it2) {
+ if(!isStyle) {
+ if(*it2 == Latin1Literal("Styles")) {
+ isStyle = true;
+ }
+ continue;
+ }
+ if(*it2 != Latin1Literal("General")) {
+ words.add(*it2);
+ }
+ }
+ }
+ entry->setField(genres, words.toList().join(QString::fromLatin1("; ")));
+ }
+ entry->setField(QString::fromLatin1("comments"), Tellico::decodeHTML(entry->field(QString::fromLatin1("comments"))));
+ break;
+
+ case Data::Collection::Game:
+ entry->setField(QString::fromLatin1("description"), Tellico::decodeHTML(entry->field(QString::fromLatin1("description"))));
+ break;
+ }
+
+ // clean up the title
+ parseTitle(entry, type);
+
+ // also sometimes table fields have rows but no values
+ Data::FieldVec fields = entry->collection()->fields();
+ QRegExp blank(QString::fromLatin1("[\\s:;]+")); // only white space, column separators and row separators
+ for(Data::FieldVec::Iterator fIt = fields.begin(); fIt != fields.end(); ++fIt) {
+ if(fIt->type() != Data::Field::Table) {
+ continue;
+ }
+ if(blank.exactMatch(entry->field(fIt))) {
+ entry->setField(fIt, QString::null);
+ }
+ }
+
+ KURL imageURL;
+ switch(m_imageSize) {
+ case SmallImage:
+ imageURL = entry->field(QString::fromLatin1("small-image"));
+ break;
+ case MediumImage:
+ imageURL = entry->field(QString::fromLatin1("medium-image"));
+ break;
+ case LargeImage:
+ imageURL = entry->field(QString::fromLatin1("large-image"));
+ break;
+ case NoImage:
+ default:
+ break;
+ }
+// myDebug() << "AmazonFetcher::fetchEntry() - grabbing " << imageURL.prettyURL() << endl;
+ if(!imageURL.isEmpty()) {
+ QString id = ImageFactory::addImage(imageURL, true);
+ // FIXME: need to add cover image field to bibtex collection
+ if(id.isEmpty()) {
+ message(i18n("The cover image could not be loaded."), MessageHandler::Warning);
+ } else { // amazon serves up 1x1 gifs occasionally, but that's caught in the image constructor
+ // all relevant collection types have cover fields
+ entry->setField(QString::fromLatin1("cover"), id);
+ }
+ }
+
+ // don't want to show image urls in the fetch dialog
+ entry->setField(QString::fromLatin1("small-image"), QString::null);
+ entry->setField(QString::fromLatin1("medium-image"), QString::null);
+ entry->setField(QString::fromLatin1("large-image"), QString::null);
+ return entry;
+}
+
+void AmazonFetcher::initXSLTHandler() {
+ QString xsltfile = locate("appdata", QString::fromLatin1("amazon2tellico.xsl"));
+ if(xsltfile.isEmpty()) {
+ kdWarning() << "AmazonFetcher::initXSLTHandler() - can not locate amazon2tellico.xsl." << endl;
+ return;
+ }
+
+ KURL u;
+ u.setPath(xsltfile);
+
+ delete m_xsltHandler;
+ m_xsltHandler = new XSLTHandler(u);
+ if(!m_xsltHandler->isValid()) {
+ kdWarning() << "AmazonFetcher::initXSLTHandler() - error in amazon2tellico.xsl." << endl;
+ delete m_xsltHandler;
+ m_xsltHandler = 0;
+ return;
+ }
+}
+
+void AmazonFetcher::updateEntry(Data::EntryPtr entry_) {
+// myDebug() << "AmazonFetcher::updateEntry()" << endl;
+
+ int type = entry_->collection()->type();
+ if(type == Data::Collection::Book || type == Data::Collection::ComicBook || type == Data::Collection::Bibtex) {
+ QString isbn = entry_->field(QString::fromLatin1("isbn"));
+ if(!isbn.isEmpty()) {
+ m_limit = 5; // no need for more
+ search(Fetch::ISBN, isbn);
+ return;
+ }
+ } else if(type == Data::Collection::Album) {
+ QString a = entry_->field(QString::fromLatin1("artist"));
+ if(!a.isEmpty()) {
+ search(Fetch::Person, a);
+ return;
+ }
+ }
+
+ // optimistically try searching for title and rely on Collection::sameEntry() to figure things out
+ QString t = entry_->field(QString::fromLatin1("title"));
+ if(!t.isEmpty()) {
+ search(Fetch::Title, t);
+ return;
+ }
+
+ myDebug() << "AmazonFetcher::updateEntry() - insufficient info to search" << endl;
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+void AmazonFetcher::parseTitle(Data::EntryPtr entry, int collType) {
+ Q_UNUSED(collType);
+ // assume that everything in brackets or parentheses is extra
+ QRegExp rx(QString::fromLatin1("[\\(\\[](.*)[\\)\\]]"));
+ rx.setMinimal(true);
+ QString title = entry->field(QString::fromLatin1("title"));
+ int pos = rx.search(title);
+ while(pos > -1) {
+ if(parseTitleToken(entry, rx.cap(1))) {
+ title.remove(pos, rx.matchedLength());
+ --pos; // search again there
+ }
+ pos = rx.search(title, pos+1);
+ }
+ entry->setField(QString::fromLatin1("title"), title.stripWhiteSpace());
+}
+
+bool AmazonFetcher::parseTitleToken(Data::EntryPtr entry, const QString& token) {
+ // if res = true, then the token gets removed from the title
+ bool res = false;
+ if(token.find(QString::fromLatin1("widescreen"), 0, false /* case-insensitive*/) > -1 ||
+ token.find(i18n("Widescreen"), 0, false) > -1) {
+ entry->setField(QString::fromLatin1("widescreen"), QString::fromLatin1("true"));
+ // res = true; leave it in the title
+ } else if(token.find(QString::fromLatin1("full screen"), 0, false) > -1) {
+ // skip, but go ahead and remove from title
+ res = true;
+ }
+ if(token.find(QString::fromLatin1("blu-ray"), 0, false) > -1) {
+ entry->setField(QString::fromLatin1("medium"), i18n("Blu-ray"));
+ res = true;
+ } else if(token.find(QString::fromLatin1("hd dvd"), 0, false) > -1) {
+ entry->setField(QString::fromLatin1("medium"), i18n("HD DVD"));
+ res = true;
+ }
+ if(token.find(QString::fromLatin1("director's cut"), 0, false) > -1 ||
+ token.find(i18n("Director's Cut"), 0, false) > -1) {
+ entry->setField(QString::fromLatin1("directors-cut"), QString::fromLatin1("true"));
+ // res = true; leave it in the title
+ }
+ return res;
+}
+
+Tellico::Fetch::ConfigWidget* AmazonFetcher::configWidget(QWidget* parent_) const {
+ return new AmazonFetcher::ConfigWidget(parent_, this);
+}
+
+AmazonFetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const AmazonFetcher* fetcher_/*=0*/)
+ : Fetch::ConfigWidget(parent_) {
+ QGridLayout* l = new QGridLayout(optionsWidget(), 4, 2);
+ l->setSpacing(4);
+ l->setColStretch(1, 10);
+
+ int row = -1;
+ QLabel* label = new QLabel(i18n("Co&untry: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_siteCombo = new GUI::ComboBox(optionsWidget());
+ m_siteCombo->insertItem(i18n("United States"), US);
+ m_siteCombo->insertItem(i18n("United Kingdom"), UK);
+ m_siteCombo->insertItem(i18n("Germany"), DE);
+ m_siteCombo->insertItem(i18n("Japan"), JP);
+ m_siteCombo->insertItem(i18n("France"), FR);
+ m_siteCombo->insertItem(i18n("Canada"), CA);
+ connect(m_siteCombo, SIGNAL(activated(int)), SLOT(slotSetModified()));
+ connect(m_siteCombo, SIGNAL(activated(int)), SLOT(slotSiteChanged()));
+ l->addWidget(m_siteCombo, row, 1);
+ QString w = i18n("Amazon.com provides data from several different localized sites. Choose the one "
+ "you wish to use for this data source.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_siteCombo, w);
+ label->setBuddy(m_siteCombo);
+
+ label = new QLabel(i18n("&Image size: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_imageCombo = new GUI::ComboBox(optionsWidget());
+ m_imageCombo->insertItem(i18n("Small Image"), SmallImage);
+ m_imageCombo->insertItem(i18n("Medium Image"), MediumImage);
+ m_imageCombo->insertItem(i18n("Large Image"), LargeImage);
+ m_imageCombo->insertItem(i18n("No Image"), NoImage);
+ connect(m_imageCombo, SIGNAL(activated(int)), SLOT(slotSetModified()));
+ l->addWidget(m_imageCombo, row, 1);
+ w = i18n("The cover image may be downloaded as well. However, too many large images in the "
+ "collection may degrade performance.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_imageCombo, w);
+ label->setBuddy(m_imageCombo);
+
+ label = new QLabel(i18n("&Associate's ID: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_assocEdit = new KLineEdit(optionsWidget());
+ connect(m_assocEdit, SIGNAL(textChanged(const QString&)), SLOT(slotSetModified()));
+ l->addWidget(m_assocEdit, row, 1);
+ w = i18n("The associate's id identifies the person accessing the Amazon.com Web Services, and is included "
+ "in any links to the Amazon.com site.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_assocEdit, w);
+ label->setBuddy(m_assocEdit);
+
+ l->setRowStretch(++row, 10);
+
+ if(fetcher_) {
+ m_siteCombo->setCurrentData(fetcher_->m_site);
+ m_assocEdit->setText(fetcher_->m_assoc);
+ m_imageCombo->setCurrentData(fetcher_->m_imageSize);
+ } else { // defaults
+ m_assocEdit->setText(QString::fromLatin1(AMAZON_ASSOC_TOKEN));
+ m_imageCombo->setCurrentData(MediumImage);
+ }
+
+ addFieldsWidget(AmazonFetcher::customFields(), fetcher_ ? fetcher_->m_fields : QStringList());
+
+ KAcceleratorManager::manage(optionsWidget());
+}
+
+void AmazonFetcher::ConfigWidget::saveConfig(KConfigGroup& config_) {
+ int n = m_siteCombo->currentData().toInt();
+ config_.writeEntry("Site", n);
+ QString s = m_assocEdit->text().stripWhiteSpace();
+ if(!s.isEmpty()) {
+ config_.writeEntry("AssocToken", s);
+ }
+ n = m_imageCombo->currentData().toInt();
+ config_.writeEntry("Image Size", n);
+
+ saveFieldsConfig(config_);
+ slotSetModified(false);
+}
+
+QString AmazonFetcher::ConfigWidget::preferredName() const {
+ return AmazonFetcher::siteData(m_siteCombo->currentData().toInt()).title;
+}
+
+void AmazonFetcher::ConfigWidget::slotSiteChanged() {
+ emit signalName(preferredName());
+}
+
+//static
+Tellico::StringMap AmazonFetcher::customFields() {
+ StringMap map;
+ map[QString::fromLatin1("keyword")] = i18n("Keywords");
+ return map;
+}
+
+#include "amazonfetcher.moc"
diff --git a/src/fetch/amazonfetcher.h b/src/fetch/amazonfetcher.h
new file mode 100644
index 0000000..05df8d7
--- /dev/null
+++ b/src/fetch/amazonfetcher.h
@@ -0,0 +1,158 @@
+/***************************************************************************
+ copyright : (C) 2004-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef AMAZONFETCHER_H
+#define AMAZONFETCHER_H
+
+#include "fetcher.h"
+#include "configwidget.h"
+#include "../datavectors.h"
+
+#include <kurl.h>
+
+#include <qcstring.h> // for QByteArray
+#include <qguardedptr.h>
+
+class KLineEdit;
+
+class QCheckBox;
+class QLabel;
+
+namespace KIO {
+ class Job;
+}
+
+namespace Tellico {
+
+ class XSLTHandler;
+ namespace GUI {
+ class ComboBox;
+ }
+
+ namespace Fetch {
+
+/**
+ * A fetcher for Amazon.com.
+ *
+ * @author Robby Stephenson
+ */
+class AmazonFetcher : public Fetcher {
+Q_OBJECT
+
+public:
+ enum Site {
+ Unknown = -1,
+ US = 0,
+ UK = 1,
+ DE = 2,
+ JP = 3,
+ FR = 4,
+ CA = 5
+ };
+
+ enum ImageSize {
+ SmallImage=0,
+ MediumImage=1,
+ LargeImage=2,
+ NoImage=3
+ };
+
+ AmazonFetcher(Site site, QObject* parent, const char* name = 0);
+ virtual ~AmazonFetcher();
+
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual void search(FetchKey key, const QString& value);
+ virtual void continueSearch();
+ // amazon can search title, person, isbn, or keyword. No Raw for now.
+ virtual bool canSearch(FetchKey k) const { return k == Title || k == Person || k == ISBN || k == UPC || k == Keyword; }
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return Amazon; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+
+ virtual void updateEntry(Data::EntryPtr entry);
+
+ struct SiteData {
+ QString title;
+ KURL url;
+ };
+ static const SiteData& siteData(int site);
+
+ /**
+ * Returns a widget for modifying the fetcher's config.
+ */
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const ;
+
+ static StringMap customFields();
+
+ class ConfigWidget;
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+private slots:
+ void slotData(KIO::Job* job, const QByteArray& data);
+ void slotComplete(KIO::Job* job);
+
+private:
+ void initXSLTHandler();
+ void doSearch();
+ void parseTitle(Data::EntryPtr entry, int collType);
+ bool parseTitleToken(Data::EntryPtr entry, const QString& token);
+
+ XSLTHandler* m_xsltHandler;
+ Site m_site;
+ ImageSize m_imageSize;
+
+ QString m_access;
+ QString m_assoc;
+ bool m_addLinkField;
+ int m_limit;
+ int m_countOffset;
+
+ QByteArray m_data;
+ int m_page;
+ int m_total;
+ int m_numResults;
+ QMap<int, Data::EntryPtr> m_entries; // they get modified after collection is created, so can't be const
+ QGuardedPtr<KIO::Job> m_job;
+
+ FetchKey m_key;
+ QString m_value;
+ bool m_started;
+ QStringList m_fields;
+};
+
+class AmazonFetcher::ConfigWidget : public Fetch::ConfigWidget {
+Q_OBJECT
+
+public:
+ ConfigWidget(QWidget* parent_, const AmazonFetcher* fetcher = 0);
+
+ virtual void saveConfig(KConfigGroup& config);
+ virtual QString preferredName() const;
+
+private slots:
+ void slotSiteChanged();
+
+private:
+ KLineEdit* m_assocEdit;
+ GUI::ComboBox* m_siteCombo;
+ GUI::ComboBox* m_imageCombo;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/fetch/animenfofetcher.cpp b/src/fetch/animenfofetcher.cpp
new file mode 100644
index 0000000..728c583
--- /dev/null
+++ b/src/fetch/animenfofetcher.cpp
@@ -0,0 +1,378 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "animenfofetcher.h"
+#include "messagehandler.h"
+#include "../tellico_kernel.h"
+#include "../tellico_utils.h"
+#include "../collections/videocollection.h"
+#include "../entry.h"
+#include "../filehandler.h"
+#include "../latin1literal.h"
+#include "../imagefactory.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kio/job.h>
+
+#include <qregexp.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qfile.h>
+
+//#define ANIMENFO_TEST
+
+namespace {
+ static const char* ANIMENFO_BASE_URL = "http://www.animenfo.com/search.php";
+}
+
+using Tellico::Fetch::AnimeNfoFetcher;
+
+AnimeNfoFetcher::AnimeNfoFetcher(QObject* parent_, const char* name_ /*=0*/)
+ : Fetcher(parent_, name_), m_started(false) {
+}
+
+QString AnimeNfoFetcher::defaultName() {
+ return QString::fromLatin1("AnimeNfo.com");
+}
+
+QString AnimeNfoFetcher::source() const {
+ return m_name.isEmpty() ? defaultName() : m_name;
+}
+
+bool AnimeNfoFetcher::canFetch(int type) const {
+ return type == Data::Collection::Video;
+}
+
+void AnimeNfoFetcher::readConfigHook(const KConfigGroup& config_) {
+ Q_UNUSED(config_);
+}
+
+void AnimeNfoFetcher::search(FetchKey key_, const QString& value_) {
+ m_started = true;
+ m_matches.clear();
+
+#ifdef ANIMENFO_TEST
+ KURL u = KURL::fromPathOrURL(QString::fromLatin1("/home/robby/animenfo.html"));
+#else
+ KURL u(QString::fromLatin1(ANIMENFO_BASE_URL));
+ u.addQueryItem(QString::fromLatin1("action"), QString::fromLatin1("Go"));
+ u.addQueryItem(QString::fromLatin1("option"), QString::fromLatin1("keywords"));
+ u.addQueryItem(QString::fromLatin1("queryin"), QString::fromLatin1("anime_titles"));
+
+ if(!canFetch(Kernel::self()->collectionType())) {
+ message(i18n("%1 does not allow searching for this collection type.").arg(source()), MessageHandler::Warning);
+ stop();
+ return;
+ }
+
+ switch(key_) {
+ case Keyword:
+ u.addQueryItem(QString::fromLatin1("query"), value_);
+ break;
+
+ default:
+ kdWarning() << "AnimeNfoFetcher::search() - key not recognized: " << key_ << endl;
+ stop();
+ return;
+ }
+#endif
+// myDebug() << "AnimeNfoFetcher::search() - url: " << u.url() << endl;
+
+ m_job = KIO::get(u, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+}
+
+void AnimeNfoFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+
+ if(m_job) {
+ m_job->kill();
+ m_job = 0;
+ }
+ m_data.truncate(0);
+ m_started = false;
+ emit signalDone(this);
+}
+
+void AnimeNfoFetcher::slotData(KIO::Job*, const QByteArray& data_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(data_.data(), data_.size());
+}
+
+void AnimeNfoFetcher::slotComplete(KIO::Job* job_) {
+// myDebug() << "AnimeNfoFetcher::slotComplete()" << endl;
+ // since the fetch is done, don't worry about holding the job pointer
+ m_job = 0;
+
+ if(job_->error()) {
+ job_->showErrorDialog(Kernel::self()->widget());
+ stop();
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "AnimeNfoFetcher::slotComplete() - no data" << endl;
+ stop();
+ return;
+ }
+
+ QString s = Tellico::decodeHTML(QString(m_data));
+
+ QRegExp infoRx(QString::fromLatin1("<td\\s+[^>]*class\\s*=\\s*[\"']anime_info[\"'][^>]*>(.*)</td>"), false);
+ infoRx.setMinimal(true);
+ QRegExp anchorRx(QString::fromLatin1("<a\\s+[^>]*href\\s*=\\s*[\"'](.*)[\"'][^>]*>(.*)</a>"), false);
+ anchorRx.setMinimal(true);
+ QRegExp yearRx(QString::fromLatin1("\\d{4}"), false);
+
+ // search page comes in groups of threes
+ int n = 0;
+ QString u, t, y;
+
+ for(int pos = infoRx.search(s); m_started && pos > -1; pos = infoRx.search(s, pos+1)) {
+ if(n == 0 && !u.isEmpty()) {
+ SearchResult* r = new SearchResult(this, t, y, QString());
+ emit signalResultFound(r);
+
+#ifdef ANIMENFO_TEST
+ KURL url = KURL::fromPathOrURL(QString::fromLatin1("/home/robby/animetitle.html"));
+#else
+ KURL url(QString::fromLatin1(ANIMENFO_BASE_URL), u);
+ url.setQuery(QString::null);
+#endif
+ m_matches.insert(r->uid, url);
+
+ u.truncate(0);
+ t.truncate(0);
+ y.truncate(0);
+ }
+ switch(n) {
+ case 0: // title and url
+ {
+ int pos2 = anchorRx.search(infoRx.cap(1));
+ if(pos2 > -1) {
+ u = anchorRx.cap(1);
+ t = anchorRx.cap(2);
+ }
+ }
+ break;
+ case 1: // don't case
+ break;
+ case 2:
+ if(yearRx.exactMatch(infoRx.cap(1))) {
+ y = infoRx.cap(1);
+ }
+ break;
+ }
+
+ n = (n+1)%3;
+ }
+
+ // grab last response
+#ifndef ANIMENFO_TEST
+ if(!u.isEmpty()) {
+ SearchResult* r = new SearchResult(this, t, y, QString());
+ emit signalResultFound(r);
+ KURL url(QString::fromLatin1(ANIMENFO_BASE_URL), u);
+ url.setQuery(QString::null);
+ m_matches.insert(r->uid, url);
+ }
+#endif
+ stop();
+}
+
+Tellico::Data::EntryPtr AnimeNfoFetcher::fetchEntry(uint uid_) {
+ // if we already grabbed this one, then just pull it out of the dict
+ Data::EntryPtr entry = m_entries[uid_];
+ if(entry) {
+ return entry;
+ }
+
+ KURL url = m_matches[uid_];
+ if(url.isEmpty()) {
+ kdWarning() << "AnimeNfoFetcher::fetchEntry() - no url in map" << endl;
+ return 0;
+ }
+
+ QString results = Tellico::decodeHTML(FileHandler::readTextFile(url, true));
+ if(results.isEmpty()) {
+ myDebug() << "AnimeNfoFetcher::fetchEntry() - no text results" << endl;
+ return 0;
+ }
+
+#if 0
+ kdWarning() << "Remove debug from animenfofetcher.cpp" << endl;
+ QFile f(QString::fromLatin1("/tmp/test.html"));
+ if(f.open(IO_WriteOnly)) {
+ QTextStream t(&f);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << results;
+ }
+ f.close();
+#endif
+
+ entry = parseEntry(results);
+ if(!entry) {
+ myDebug() << "AnimeNfoFetcher::fetchEntry() - error in processing entry" << endl;
+ return 0;
+ }
+ m_entries.insert(uid_, entry); // keep for later
+ return entry;
+}
+
+Tellico::Data::EntryPtr AnimeNfoFetcher::parseEntry(const QString& str_) {
+ // myDebug() << "AnimeNfoFetcher::parseEntry()" << endl;
+ // class might be anime_info_top
+ QRegExp infoRx(QString::fromLatin1("<td\\s+[^>]*class\\s*=\\s*[\"']anime_info[^>]*>(.*)</td>"), false);
+ infoRx.setMinimal(true);
+ QRegExp tagRx(QString::fromLatin1("<.*>"));
+ tagRx.setMinimal(true);
+ QRegExp anchorRx(QString::fromLatin1("<a\\s+[^>]*href\\s*=\\s*[\"'](.*)[\"'][^>]*>(.*)</a>"), false);
+ anchorRx.setMinimal(true);
+ QRegExp jsRx(QString::fromLatin1("<script.*</script>"), false);
+ jsRx.setMinimal(true);
+
+ QString s = str_;
+ s.remove(jsRx);
+
+ Data::CollPtr coll = new Data::VideoCollection(true);
+
+ // add new fields
+ Data::FieldPtr f = new Data::Field(QString::fromLatin1("origtitle"), i18n("Original Title"));
+ coll->addField(f);
+
+ f = new Data::Field(QString::fromLatin1("alttitle"), i18n("Alternative Titles"), Data::Field::Table);
+ f->setFormatFlag(Data::Field::FormatTitle);
+ coll->addField(f);
+
+ f = new Data::Field(QString::fromLatin1("distributor"), i18n("Distributor"));
+ f->setCategory(i18n("Other People"));
+ f->setFlags(Data::Field::AllowCompletion | Data::Field::AllowMultiple | Data::Field::AllowGrouped);
+ f->setFormatFlag(Data::Field::FormatPlain);
+ coll->addField(f);
+
+ f = new Data::Field(QString::fromLatin1("episodes"), i18n("Episodes"), Data::Field::Number);
+ f->setCategory(i18n("Features"));
+ coll->addField(f);
+
+ // map captions in HTML to field names
+ QMap<QString, QString> fieldMap;
+ fieldMap.insert(QString::fromLatin1("Title"), QString::fromLatin1("title"));
+ fieldMap.insert(QString::fromLatin1("Japanese Title"), QString::fromLatin1("origtitle"));
+ fieldMap.insert(QString::fromLatin1("Total Episodes"), QString::fromLatin1("episodes"));
+ fieldMap.insert(QString::fromLatin1("Genres"), QString::fromLatin1("genre"));
+ fieldMap.insert(QString::fromLatin1("Year Published"), QString::fromLatin1("year"));
+ fieldMap.insert(QString::fromLatin1("Studio"), QString::fromLatin1("studio"));
+ fieldMap.insert(QString::fromLatin1("US Distribution"), QString::fromLatin1("distributor"));
+
+ Data::EntryPtr entry = new Data::Entry(coll);
+
+ int n = 0;
+ QString key, value;
+ int oldpos = -1;
+ for(int pos = infoRx.search(s); pos > -1; pos = infoRx.search(s, pos+1)) {
+ if(n == 0 && !key.isEmpty()) {
+ if(fieldMap.contains(key)) {
+ value = value.simplifyWhiteSpace();
+ if(value.length() > 2) { // might be "-"
+ if(key == Latin1Literal("Genres")) {
+ entry->setField(fieldMap[key], QStringList::split(QRegExp(QString::fromLatin1("\\s*,\\s*")),
+ value).join(QString::fromLatin1("; ")));
+ } else {
+ entry->setField(fieldMap[key], value);
+ }
+ }
+ }
+ key.truncate(0);
+ value.truncate(0);
+ }
+ switch(n) {
+ case 0:
+ key = infoRx.cap(1).remove(tagRx);
+ break;
+ case 1:
+ value = infoRx.cap(1).remove(tagRx);
+ break;
+ }
+ n = (n+1)%2;
+ oldpos = pos;
+ }
+
+ // image
+ QRegExp imgRx(QString::fromLatin1("<img\\s+[^>]*src\\s*=\\s*[\"']([^>]*)[\"']\\s+[^>]*alt\\s*=\\s*[\"']%1[\"']")
+ .arg(entry->field(QString::fromLatin1("title"))), false);
+ imgRx.setMinimal(true);
+ int pos = imgRx.search(s);
+ if(pos > -1) {
+ KURL imgURL(QString::fromLatin1(ANIMENFO_BASE_URL), imgRx.cap(1));
+ QString id = ImageFactory::addImage(imgURL, true);
+ if(!id.isEmpty()) {
+ entry->setField(QString::fromLatin1("cover"), id);
+ }
+ }
+
+ // now look for alternative titles and plot
+ const QString a = QString::fromLatin1("Alternative titles");
+ pos = s.find(a, oldpos+1, false);
+ if(pos > -1) {
+ pos += a.length();
+ }
+ int pos2 = -1;
+ if(pos > -1) {
+ pos2 = s.find(QString::fromLatin1("Description"), pos+1, true);
+ if(pos2 > -1) {
+ value = s.mid(pos, pos2-pos).remove(tagRx).simplifyWhiteSpace();
+ entry->setField(QString::fromLatin1("alttitle"), value);
+ }
+ }
+ QRegExp descRx(QString::fromLatin1("class\\s*=\\s*[\"']description[\"'][^>]*>(.*)<"), false);
+ descRx.setMinimal(true);
+ pos = descRx.search(s, QMAX(pos, pos2));
+ if(pos > -1) {
+ entry->setField(QString::fromLatin1("plot"), descRx.cap(1).simplifyWhiteSpace());
+ }
+
+ return entry;
+}
+
+void AnimeNfoFetcher::updateEntry(Data::EntryPtr entry_) {
+ QString t = entry_->field(QString::fromLatin1("title"));
+ if(!t.isEmpty()) {
+ search(Fetch::Keyword, t);
+ return;
+ }
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+Tellico::Fetch::ConfigWidget* AnimeNfoFetcher::configWidget(QWidget* parent_) const {
+ return new AnimeNfoFetcher::ConfigWidget(parent_);
+}
+
+AnimeNfoFetcher::ConfigWidget::ConfigWidget(QWidget* parent_)
+ : Fetch::ConfigWidget(parent_) {
+ QVBoxLayout* l = new QVBoxLayout(optionsWidget());
+ l->addWidget(new QLabel(i18n("This source has no options."), optionsWidget()));
+ l->addStretch();
+}
+
+QString AnimeNfoFetcher::ConfigWidget::preferredName() const {
+ return AnimeNfoFetcher::defaultName();
+}
+
+#include "animenfofetcher.moc"
diff --git a/src/fetch/animenfofetcher.h b/src/fetch/animenfofetcher.h
new file mode 100644
index 0000000..7e4028e
--- /dev/null
+++ b/src/fetch/animenfofetcher.h
@@ -0,0 +1,86 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FETCH_ANIMENFOFETCHER_H
+#define TELLICO_FETCH_ANIMENFOFETCHER_H
+
+#include "fetcher.h"
+#include "configwidget.h"
+
+#include <qcstring.h> // for QByteArray
+#include <qguardedptr.h>
+
+namespace KIO {
+ class Job;
+}
+
+namespace Tellico {
+ namespace Fetch {
+
+/**
+ * A fetcher for animenfo.com
+ *
+ * @author Robby Stephenson
+ */
+class AnimeNfoFetcher : public Fetcher {
+Q_OBJECT
+
+public:
+ AnimeNfoFetcher(QObject* parent, const char* name = 0);
+ virtual ~AnimeNfoFetcher() {}
+
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual void search(FetchKey key, const QString& value);
+ // only keyword search
+ virtual bool canSearch(FetchKey k) const { return k == Keyword; }
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return AnimeNfo; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+
+ virtual void updateEntry(Data::EntryPtr entry);
+
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const;
+
+ class ConfigWidget : public Fetch::ConfigWidget {
+ public:
+ ConfigWidget(QWidget* parent_);
+ virtual void saveConfig(KConfigGroup&) {}
+ virtual QString preferredName() const;
+ };
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+private slots:
+ void slotData(KIO::Job* job, const QByteArray& data);
+ void slotComplete(KIO::Job* job);
+
+private:
+ Data::EntryPtr parseEntry(const QString& str);
+
+ QByteArray m_data;
+ int m_total;
+ QMap<int, Data::EntryPtr> m_entries;
+ QMap<int, KURL> m_matches;
+ QGuardedPtr<KIO::Job> m_job;
+
+ bool m_started;
+// QStringList m_fields;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/fetch/arxivfetcher.cpp b/src/fetch/arxivfetcher.cpp
new file mode 100644
index 0000000..442ef30
--- /dev/null
+++ b/src/fetch/arxivfetcher.cpp
@@ -0,0 +1,366 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "arxivfetcher.h"
+#include "messagehandler.h"
+#include "../translators/xslthandler.h"
+#include "../translators/tellicoimporter.h"
+#include "../tellico_kernel.h"
+#include "../tellico_utils.h"
+#include "../collection.h"
+#include "../entry.h"
+#include "../core/netaccess.h"
+#include "../imagefactory.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kconfig.h>
+
+#include <qdom.h>
+#include <qlabel.h>
+#include <qlayout.h>
+
+//#define ARXIV_TEST
+
+namespace {
+ static const int ARXIV_RETURNS_PER_REQUEST = 20;
+ static const char* ARXIV_BASE_URL = "http://export.arxiv.org/api/query";
+}
+
+using Tellico::Fetch::ArxivFetcher;
+
+ArxivFetcher::ArxivFetcher(QObject* parent_)
+ : Fetcher(parent_), m_xsltHandler(0), m_start(0), m_job(0), m_started(false) {
+}
+
+ArxivFetcher::~ArxivFetcher() {
+ delete m_xsltHandler;
+ m_xsltHandler = 0;
+}
+
+QString ArxivFetcher::defaultName() {
+ return i18n("arXiv.org");
+}
+
+QString ArxivFetcher::source() const {
+ return m_name.isEmpty() ? defaultName() : m_name;
+}
+
+bool ArxivFetcher::canFetch(int type) const {
+ return type == Data::Collection::Bibtex;
+}
+
+void ArxivFetcher::readConfigHook(const KConfigGroup&) {
+}
+
+void ArxivFetcher::search(FetchKey key_, const QString& value_) {
+ m_key = key_;
+ m_value = value_.stripWhiteSpace();
+ m_started = true;
+ m_start = 0;
+ m_total = -1;
+ doSearch();
+}
+
+void ArxivFetcher::continueSearch() {
+ m_started = true;
+ doSearch();
+}
+
+void ArxivFetcher::doSearch() {
+ if(!canFetch(Kernel::self()->collectionType())) {
+ message(i18n("%1 does not allow searching for this collection type.").arg(source()), MessageHandler::Warning);
+ stop();
+ return;
+ }
+
+ m_data.truncate(0);
+
+// myDebug() << "ArxivFetcher::search() - value = " << value_ << endl;
+
+ KURL u = searchURL(m_key, m_value);
+ if(u.isEmpty()) {
+ stop();
+ return;
+ }
+
+ m_job = KIO::get(u, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+}
+
+void ArxivFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+// myDebug() << "ArxivFetcher::stop()" << endl;
+ if(m_job) {
+ m_job->kill();
+ m_job = 0;
+ }
+ m_data.truncate(0);
+ m_started = false;
+ emit signalDone(this);
+}
+
+void ArxivFetcher::slotData(KIO::Job*, const QByteArray& data_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(data_.data(), data_.size());
+}
+
+void ArxivFetcher::slotComplete(KIO::Job* job_) {
+// myDebug() << "ArxivFetcher::slotComplete()" << endl;
+ // since the fetch is done, don't worry about holding the job pointer
+ m_job = 0;
+
+ if(job_->error()) {
+ job_->showErrorDialog(Kernel::self()->widget());
+ stop();
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "ArxivFetcher::slotComplete() - no data" << endl;
+ stop();
+ return;
+ }
+
+#if 0
+ kdWarning() << "Remove debug from arxivfetcher.cpp" << endl;
+ QFile f(QString::fromLatin1("/tmp/test.xml"));
+ if(f.open(IO_WriteOnly)) {
+ QTextStream t(&f);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << QCString(m_data, m_data.size()+1);
+ }
+ f.close();
+#endif
+
+ if(!m_xsltHandler) {
+ initXSLTHandler();
+ if(!m_xsltHandler) { // probably an error somewhere in the stylesheet loading
+ stop();
+ return;
+ }
+ }
+
+ if(m_total == -1) {
+ QDomDocument dom;
+ if(!dom.setContent(m_data, true /*namespace*/)) {
+ kdWarning() << "ArxivFetcher::slotComplete() - server did not return valid XML." << endl;
+ return;
+ }
+ // total is top level element, with attribute totalResultsAvailable
+ QDomNodeList list = dom.elementsByTagNameNS(QString::fromLatin1("http://a9.com/-/spec/opensearch/1.1/"),
+ QString::fromLatin1("totalResults"));
+ if(list.count() > 0) {
+ m_total = list.item(0).toElement().text().toInt();
+ }
+ }
+
+ // assume result is always utf-8
+ QString str = m_xsltHandler->applyStylesheet(QString::fromUtf8(m_data, m_data.size()));
+ Import::TellicoImporter imp(str);
+ Data::CollPtr coll = imp.collection();
+
+ if(!coll) {
+ myDebug() << "ArxivFetcher::slotComplete() - no valid result" << endl;
+ stop();
+ return;
+ }
+
+ Data::EntryVec entries = coll->entries();
+ for(Data::EntryVec::Iterator entry = entries.begin(); entry != entries.end(); ++entry) {
+ if(!m_started) {
+ // might get aborted
+ break;
+ }
+ QString desc = entry->field(QString::fromLatin1("author"))
+ + QChar('/') + entry->field(QString::fromLatin1("publisher"));
+ if(!entry->field(QString::fromLatin1("year")).isEmpty()) {
+ desc += QChar('/') + entry->field(QString::fromLatin1("year"));
+ }
+
+ SearchResult* r = new SearchResult(this, entry->title(), desc, entry->field(QString::fromLatin1("isbn")));
+ m_entries.insert(r->uid, Data::EntryPtr(entry));
+ emit signalResultFound(r);
+ }
+
+ m_start = m_entries.count();
+ m_hasMoreResults = m_start < m_total;
+ stop(); // required
+}
+
+Tellico::Data::EntryPtr ArxivFetcher::fetchEntry(uint uid_) {
+ Data::EntryPtr entry = m_entries[uid_];
+ // if URL but no cover image, fetch it
+ if(!entry->field(QString::fromLatin1("url")).isEmpty()) {
+ Data::CollPtr coll = entry->collection();
+ Data::FieldPtr field = coll->fieldByName(QString::fromLatin1("cover"));
+ if(!field && !coll->imageFields().isEmpty()) {
+ field = coll->imageFields().front();
+ } else if(!field) {
+ field = new Data::Field(QString::fromLatin1("cover"), i18n("Front Cover"), Data::Field::Image);
+ coll->addField(field);
+ }
+ if(entry->field(field).isEmpty()) {
+ QPixmap pix = NetAccess::filePreview(entry->field(QString::fromLatin1("url")));
+ if(!pix.isNull()) {
+ QString id = ImageFactory::addImage(pix, QString::fromLatin1("PNG"));
+ if(!id.isEmpty()) {
+ entry->setField(field, id);
+ }
+ }
+ }
+ }
+ return entry;
+}
+
+void ArxivFetcher::initXSLTHandler() {
+ QString xsltfile = locate("appdata", QString::fromLatin1("arxiv2tellico.xsl"));
+ if(xsltfile.isEmpty()) {
+ kdWarning() << "ArxivFetcher::initXSLTHandler() - can not locate arxiv2tellico.xsl." << endl;
+ return;
+ }
+
+ KURL u;
+ u.setPath(xsltfile);
+
+ delete m_xsltHandler;
+ m_xsltHandler = new XSLTHandler(u);
+ if(!m_xsltHandler->isValid()) {
+ kdWarning() << "ArxivFetcher::initXSLTHandler() - error in arxiv2tellico.xsl." << endl;
+ delete m_xsltHandler;
+ m_xsltHandler = 0;
+ return;
+ }
+}
+
+KURL ArxivFetcher::searchURL(FetchKey key_, const QString& value_) const {
+ KURL u(QString::fromLatin1(ARXIV_BASE_URL));
+ u.addQueryItem(QString::fromLatin1("start"), QString::number(m_start));
+ u.addQueryItem(QString::fromLatin1("max_results"), QString::number(ARXIV_RETURNS_PER_REQUEST));
+
+ // quotes should be used if spaces are present, just use all the time
+ QString quotedValue = '"' + value_ + '"';
+ switch(key_) {
+ case Title:
+ u.addQueryItem(QString::fromLatin1("search_query"), QString::fromLatin1("ti:%1").arg(quotedValue));
+ break;
+
+ case Person:
+ u.addQueryItem(QString::fromLatin1("search_query"), QString::fromLatin1("au:%1").arg(quotedValue));
+ break;
+
+ case Keyword:
+ // keyword gets to use all the words without being quoted
+ u.addQueryItem(QString::fromLatin1("search_query"), QString::fromLatin1("all:%1").arg(value_));
+ break;
+
+ case ArxivID:
+ {
+ // remove prefix and/or version number
+ QString value = value_;
+ value.remove(QRegExp(QString::fromLatin1("^arxiv:"), false));
+ value.remove(QRegExp(QString::fromLatin1("v\\d+$")));
+ u.addQueryItem(QString::fromLatin1("search_query"), QString::fromLatin1("id:%1").arg(value));
+ }
+ break;
+
+ default:
+ kdWarning() << "ArxivFetcher::search() - key not recognized: " << m_key << endl;
+ return KURL();
+ }
+
+#ifdef ARXIV_TEST
+ u = KURL::fromPathOrURL(QString::fromLatin1("/home/robby/arxiv.xml"));
+#endif
+ myDebug() << "ArxivFetcher::search() - url: " << u.url() << endl;
+ return u;
+}
+
+void ArxivFetcher::updateEntry(Data::EntryPtr entry_) {
+ QString id = entry_->field(QString::fromLatin1("arxiv"));
+ if(!id.isEmpty()) {
+ search(Fetch::ArxivID, id);
+ return;
+ }
+
+ // optimistically try searching for title and rely on Collection::sameEntry() to figure things out
+ QString t = entry_->field(QString::fromLatin1("title"));
+ if(!t.isEmpty()) {
+ search(Fetch::Title, t);
+ return;
+ }
+
+ myDebug() << "ArxivFetcher::updateEntry() - insufficient info to search" << endl;
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+void ArxivFetcher::updateEntrySynchronous(Data::EntryPtr entry) {
+ if(!entry) {
+ return;
+ }
+ QString arxiv = entry->field(QString::fromLatin1("arxiv"));
+ if(arxiv.isEmpty()) {
+ return;
+ }
+
+ KURL u = searchURL(ArxivID, arxiv);
+ QString xml = FileHandler::readTextFile(u, true, true);
+ if(xml.isEmpty()) {
+ return;
+ }
+
+ if(!m_xsltHandler) {
+ initXSLTHandler();
+ if(!m_xsltHandler) { // probably an error somewhere in the stylesheet loading
+ return;
+ }
+ }
+
+ // assume result is always utf-8
+ QString str = m_xsltHandler->applyStylesheet(xml);
+ Import::TellicoImporter imp(str);
+ Data::CollPtr coll = imp.collection();
+ if(coll && coll->entryCount() > 0) {
+ myLog() << "ArxivFetcher::updateEntrySynchronous() - found Arxiv result, merging" << endl;
+ Data::Collection::mergeEntry(entry, coll->entries().front(), false /*overwrite*/);
+ // the arxiv id might have a version#
+ entry->setField(QString::fromLatin1("arxiv"),
+ coll->entries().front()->field(QString::fromLatin1("arxiv")));
+ }
+}
+
+Tellico::Fetch::ConfigWidget* ArxivFetcher::configWidget(QWidget* parent_) const {
+ return new ArxivFetcher::ConfigWidget(parent_, this);
+}
+
+ArxivFetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const ArxivFetcher*)
+ : Fetch::ConfigWidget(parent_) {
+ QVBoxLayout* l = new QVBoxLayout(optionsWidget());
+ l->addWidget(new QLabel(i18n("This source has no options."), optionsWidget()));
+ l->addStretch();
+}
+
+void ArxivFetcher::ConfigWidget::saveConfig(KConfigGroup&) {
+}
+
+QString ArxivFetcher::ConfigWidget::preferredName() const {
+ return ArxivFetcher::defaultName();
+}
+
+#include "arxivfetcher.moc"
diff --git a/src/fetch/arxivfetcher.h b/src/fetch/arxivfetcher.h
new file mode 100644
index 0000000..bce5f9d
--- /dev/null
+++ b/src/fetch/arxivfetcher.h
@@ -0,0 +1,93 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FETCH_ARXIVFETCHER_H
+#define TELLICO_FETCH_ARXIVFETCHER_H
+
+#include "fetcher.h"
+#include "configwidget.h"
+#include "../datavectors.h"
+
+#include <kio/job.h>
+
+#include <qcstring.h> // for QByteArray
+#include <qguardedptr.h>
+
+namespace Tellico {
+
+ class XSLTHandler;
+
+ namespace Fetch {
+
+/**
+ * @author Robby Stephenson
+ */
+class ArxivFetcher : public Fetcher {
+Q_OBJECT
+
+public:
+ ArxivFetcher(QObject* parent);
+ ~ArxivFetcher();
+
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual void search(FetchKey key, const QString& value);
+ virtual void continueSearch();
+
+ virtual bool canSearch(FetchKey k) const { return k == Title || k == Person || k == Keyword || k == ArxivID; }
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return Arxiv; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+
+ virtual void updateEntry(Data::EntryPtr entry);
+ virtual void updateEntrySynchronous(Data::EntryPtr entry);
+
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const;
+
+ class ConfigWidget : public Fetch::ConfigWidget {
+ public:
+ ConfigWidget(QWidget* parent_, const ArxivFetcher* fetcher = 0);
+ virtual void saveConfig(KConfigGroup& config);
+ virtual QString preferredName() const;
+ };
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+private slots:
+ void slotData(KIO::Job* job, const QByteArray& data);
+ void slotComplete(KIO::Job* job);
+
+private:
+ void initXSLTHandler();
+ KURL searchURL(FetchKey key, const QString& value) const;
+ void doSearch();
+
+ XSLTHandler* m_xsltHandler;
+ int m_start;
+ int m_total;
+
+ QByteArray m_data;
+ QMap<int, Data::EntryPtr> m_entries;
+ QGuardedPtr<KIO::Job> m_job;
+
+ FetchKey m_key;
+ QString m_value;
+ bool m_started;
+};
+
+ }
+}
+#endif
diff --git a/src/fetch/bibsonomyfetcher.cpp b/src/fetch/bibsonomyfetcher.cpp
new file mode 100644
index 0000000..faa48a4
--- /dev/null
+++ b/src/fetch/bibsonomyfetcher.cpp
@@ -0,0 +1,209 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "bibsonomyfetcher.h"
+#include "messagehandler.h"
+#include "../translators/bibteximporter.h"
+#include "../tellico_kernel.h"
+#include "../tellico_utils.h"
+#include "../collection.h"
+#include "../entry.h"
+#include "../core/netaccess.h"
+#include "../filehandler.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+
+namespace {
+ // always bibtex
+ static const char* BIBSONOMY_BASE_URL = "http://bibsonomy.org";
+ static const int BIBSONOMY_MAX_RESULTS = 20;
+}
+
+using Tellico::Fetch::BibsonomyFetcher;
+
+BibsonomyFetcher::BibsonomyFetcher(QObject* parent_)
+ : Fetcher(parent_), m_job(0), m_started(false) {
+}
+
+BibsonomyFetcher::~BibsonomyFetcher() {
+}
+
+QString BibsonomyFetcher::defaultName() {
+ return QString::fromLatin1("Bibsonomy");
+}
+
+QString BibsonomyFetcher::source() const {
+ return m_name.isEmpty() ? defaultName() : m_name;
+}
+
+bool BibsonomyFetcher::canFetch(int type) const {
+ return type == Data::Collection::Bibtex;
+}
+
+void BibsonomyFetcher::readConfigHook(const KConfigGroup&) {
+}
+
+void BibsonomyFetcher::search(FetchKey key_, const QString& value_) {
+ m_key = key_;
+ m_value = value_.stripWhiteSpace();
+ m_started = true;
+
+ if(!canFetch(Kernel::self()->collectionType())) {
+ message(i18n("%1 does not allow searching for this collection type.").arg(source()), MessageHandler::Warning);
+ stop();
+ return;
+ }
+
+ m_data.truncate(0);
+
+// myDebug() << "BibsonomyFetcher::search() - value = " << value_ << endl;
+
+ KURL u = searchURL(m_key, m_value);
+ if(u.isEmpty()) {
+ stop();
+ return;
+ }
+
+ m_job = KIO::get(u, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+}
+
+void BibsonomyFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+// myDebug() << "BibsonomyFetcher::stop()" << endl;
+ if(m_job) {
+ m_job->kill();
+ m_job = 0;
+ }
+ m_data.truncate(0);
+ m_started = false;
+ emit signalDone(this);
+}
+
+void BibsonomyFetcher::slotData(KIO::Job*, const QByteArray& data_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(data_.data(), data_.size());
+}
+
+void BibsonomyFetcher::slotComplete(KIO::Job* job_) {
+// myDebug() << "BibsonomyFetcher::slotComplete()" << endl;
+ // since the fetch is done, don't worry about holding the job pointer
+ m_job = 0;
+
+ if(job_->error()) {
+ job_->showErrorDialog(Kernel::self()->widget());
+ stop();
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "BibsonomyFetcher::slotComplete() - no data" << endl;
+ stop();
+ return;
+ }
+
+ Import::BibtexImporter imp(QString::fromUtf8(m_data, m_data.size()));
+ Data::CollPtr coll = imp.collection();
+
+ if(!coll) {
+ myDebug() << "BibsonomyFetcher::slotComplete() - no valid result" << endl;
+ stop();
+ return;
+ }
+
+ Data::EntryVec entries = coll->entries();
+ for(Data::EntryVec::Iterator entry = entries.begin(); entry != entries.end(); ++entry) {
+ if(!m_started) {
+ // might get aborted
+ break;
+ }
+ QString desc = entry->field(QString::fromLatin1("author"))
+ + QChar('/') + entry->field(QString::fromLatin1("publisher"));
+ if(!entry->field(QString::fromLatin1("year")).isEmpty()) {
+ desc += QChar('/') + entry->field(QString::fromLatin1("year"));
+ }
+
+ SearchResult* r = new SearchResult(this, entry->title(), desc, entry->field(QString::fromLatin1("isbn")));
+ m_entries.insert(r->uid, Data::EntryPtr(entry));
+ emit signalResultFound(r);
+ }
+
+ stop(); // required
+}
+
+Tellico::Data::EntryPtr BibsonomyFetcher::fetchEntry(uint uid_) {
+ return m_entries[uid_];
+}
+
+KURL BibsonomyFetcher::searchURL(FetchKey key_, const QString& value_) const {
+ KURL u(QString::fromLatin1(BIBSONOMY_BASE_URL));
+ u.setPath(QString::fromLatin1("/bib/"));
+
+ switch(key_) {
+ case Person:
+ u.addPath(QString::fromLatin1("author/%1").arg(value_));
+ break;
+
+ case Keyword:
+ u.addPath(QString::fromLatin1("search/%1").arg(value_));
+ break;
+
+ default:
+ kdWarning() << "BibsonomyFetcher::search() - key not recognized: " << m_key << endl;
+ return KURL();
+ }
+
+ u.addQueryItem(QString::fromLatin1("items"), QString::number(BIBSONOMY_MAX_RESULTS));
+ myDebug() << "BibsonomyFetcher::search() - url: " << u.url() << endl;
+ return u;
+}
+
+void BibsonomyFetcher::updateEntry(Data::EntryPtr entry_) {
+ QString title = entry_->field(QString::fromLatin1("title"));
+ if(!title.isEmpty()) {
+ search(Fetch::Keyword, title);
+ return;
+ }
+
+ myDebug() << "BibsonomyFetcher::updateEntry() - insufficient info to search" << endl;
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+Tellico::Fetch::ConfigWidget* BibsonomyFetcher::configWidget(QWidget* parent_) const {
+ return new BibsonomyFetcher::ConfigWidget(parent_, this);
+}
+
+BibsonomyFetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const BibsonomyFetcher*)
+ : Fetch::ConfigWidget(parent_) {
+ QVBoxLayout* l = new QVBoxLayout(optionsWidget());
+ l->addWidget(new QLabel(i18n("This source has no options."), optionsWidget()));
+ l->addStretch();
+}
+
+void BibsonomyFetcher::ConfigWidget::saveConfig(KConfigGroup&) {
+}
+
+QString BibsonomyFetcher::ConfigWidget::preferredName() const {
+ return BibsonomyFetcher::defaultName();
+}
+
+#include "bibsonomyfetcher.moc"
diff --git a/src/fetch/bibsonomyfetcher.h b/src/fetch/bibsonomyfetcher.h
new file mode 100644
index 0000000..fc59928
--- /dev/null
+++ b/src/fetch/bibsonomyfetcher.h
@@ -0,0 +1,82 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FETCH_BIBSONOMYFETCHER_H
+#define TELLICO_FETCH_BIBSONOMYFETCHER_H
+
+#include "fetcher.h"
+#include "configwidget.h"
+#include "../datavectors.h"
+
+#include <kio/job.h>
+
+#include <qcstring.h> // for QByteArray
+#include <qguardedptr.h>
+
+namespace Tellico {
+ namespace Fetch {
+
+/**
+ * @author Robby Stephenson
+ */
+class BibsonomyFetcher : public Fetcher {
+Q_OBJECT
+
+public:
+ BibsonomyFetcher(QObject* parent);
+ ~BibsonomyFetcher();
+
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual void search(FetchKey key, const QString& value);
+
+ virtual bool canSearch(FetchKey k) const { return k == Person || k == Keyword; }
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return Bibsonomy; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+
+ virtual void updateEntry(Data::EntryPtr entry);
+
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const;
+
+ class ConfigWidget : public Fetch::ConfigWidget {
+ public:
+ ConfigWidget(QWidget* parent_, const BibsonomyFetcher* fetcher = 0);
+ virtual void saveConfig(KConfigGroup& config);
+ virtual QString preferredName() const;
+ };
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+private slots:
+ void slotData(KIO::Job* job, const QByteArray& data);
+ void slotComplete(KIO::Job* job);
+
+private:
+ KURL searchURL(FetchKey key, const QString& value) const;
+
+ QByteArray m_data;
+ QMap<int, Data::EntryPtr> m_entries;
+ QGuardedPtr<KIO::Job> m_job;
+
+ FetchKey m_key;
+ QString m_value;
+ bool m_started;
+};
+
+ }
+}
+#endif
diff --git a/src/fetch/citebasefetcher.cpp b/src/fetch/citebasefetcher.cpp
new file mode 100644
index 0000000..798d690
--- /dev/null
+++ b/src/fetch/citebasefetcher.cpp
@@ -0,0 +1,248 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "citebasefetcher.h"
+#include "messagehandler.h"
+#include "../translators/bibteximporter.h"
+#include "../tellico_kernel.h"
+#include "../tellico_utils.h"
+#include "../collection.h"
+#include "../entry.h"
+#include "../core/netaccess.h"
+#include "../filehandler.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+
+// #define CITEBASE_TEST
+
+namespace {
+ // always bibtex
+ static const char* CITEBASE_BASE_URL = "http://www.citebase.org/openurl/?url_ver=Z39.88-2004&svc_id=bibtex";
+}
+
+using Tellico::Fetch::CitebaseFetcher;
+
+CitebaseFetcher::CitebaseFetcher(QObject* parent_)
+ : Fetcher(parent_), m_job(0), m_started(false) {
+}
+
+CitebaseFetcher::~CitebaseFetcher() {
+}
+
+QString CitebaseFetcher::defaultName() {
+ return QString::fromLatin1("Citebase");
+}
+
+QString CitebaseFetcher::source() const {
+ return m_name.isEmpty() ? defaultName() : m_name;
+}
+
+bool CitebaseFetcher::canFetch(int type) const {
+ return type == Data::Collection::Bibtex;
+}
+
+void CitebaseFetcher::readConfigHook(const KConfigGroup&) {
+}
+
+void CitebaseFetcher::search(FetchKey key_, const QString& value_) {
+ m_key = key_;
+ m_value = value_.stripWhiteSpace();
+ m_started = true;
+
+ if(!canFetch(Kernel::self()->collectionType())) {
+ message(i18n("%1 does not allow searching for this collection type.").arg(source()), MessageHandler::Warning);
+ stop();
+ return;
+ }
+
+ m_data.truncate(0);
+
+// myDebug() << "CitebaseFetcher::search() - value = " << value_ << endl;
+
+ KURL u = searchURL(m_key, m_value);
+ if(u.isEmpty()) {
+ stop();
+ return;
+ }
+
+ m_job = KIO::get(u, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+}
+
+void CitebaseFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+// myDebug() << "CitebaseFetcher::stop()" << endl;
+ if(m_job) {
+ m_job->kill();
+ m_job = 0;
+ }
+ m_data.truncate(0);
+ m_started = false;
+ emit signalDone(this);
+}
+
+void CitebaseFetcher::slotData(KIO::Job*, const QByteArray& data_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(data_.data(), data_.size());
+}
+
+void CitebaseFetcher::slotComplete(KIO::Job* job_) {
+// myDebug() << "CitebaseFetcher::slotComplete()" << endl;
+ // since the fetch is done, don't worry about holding the job pointer
+ m_job = 0;
+
+ if(job_->error()) {
+ job_->showErrorDialog(Kernel::self()->widget());
+ stop();
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "CitebaseFetcher::slotComplete() - no data" << endl;
+ stop();
+ return;
+ }
+
+#if 0
+ kdWarning() << "Remove debug from citebasefetcher.cpp" << endl;
+ QFile f(QString::fromLatin1("/tmp/test.bib"));
+ if(f.open(IO_WriteOnly)) {
+ QTextStream t(&f);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << QCString(m_data, m_data.size()+1);
+ }
+ f.close();
+#endif
+
+ Import::BibtexImporter imp(QString::fromUtf8(m_data, m_data.size()));
+ Data::CollPtr coll = imp.collection();
+
+ if(!coll) {
+ myDebug() << "CitebaseFetcher::slotComplete() - no valid result" << endl;
+ stop();
+ return;
+ }
+
+ Data::EntryVec entries = coll->entries();
+ for(Data::EntryVec::Iterator entry = entries.begin(); entry != entries.end(); ++entry) {
+ if(!m_started) {
+ // might get aborted
+ break;
+ }
+ QString desc = entry->field(QString::fromLatin1("author"))
+ + QChar('/') + entry->field(QString::fromLatin1("publisher"));
+ if(!entry->field(QString::fromLatin1("year")).isEmpty()) {
+ desc += QChar('/') + entry->field(QString::fromLatin1("year"));
+ }
+
+ SearchResult* r = new SearchResult(this, entry->title(), desc, entry->field(QString::fromLatin1("isbn")));
+ m_entries.insert(r->uid, Data::EntryPtr(entry));
+ emit signalResultFound(r);
+ }
+
+ stop(); // required
+}
+
+Tellico::Data::EntryPtr CitebaseFetcher::fetchEntry(uint uid_) {
+ return m_entries[uid_];
+}
+
+KURL CitebaseFetcher::searchURL(FetchKey key_, const QString& value_) const {
+ KURL u(QString::fromLatin1(CITEBASE_BASE_URL));
+
+ switch(key_) {
+ case ArxivID:
+ {
+ // remove prefix and/or version number
+ QString value = value_;
+ value.remove(QRegExp(QString::fromLatin1("^arxiv:"), false));
+ value.remove(QRegExp(QString::fromLatin1("v\\d+$")));
+ u.addQueryItem(QString::fromLatin1("rft_id"), QString::fromLatin1("oai:arXiv.org:%1").arg(value));
+ }
+ break;
+
+ default:
+ kdWarning() << "CitebaseFetcher::search() - key not recognized: " << m_key << endl;
+ return KURL();
+ }
+
+#ifdef CITEBASE_TEST
+ u = KURL::fromPathOrURL(QString::fromLatin1("/home/robby/citebase.bib"));
+#endif
+ myDebug() << "CitebaseFetcher::search() - url: " << u.url() << endl;
+ return u;
+}
+
+void CitebaseFetcher::updateEntry(Data::EntryPtr entry_) {
+ QString arxiv = entry_->field(QString::fromLatin1("arxiv"));
+ if(!arxiv.isEmpty()) {
+ search(Fetch::ArxivID, arxiv);
+ return;
+ }
+
+ myDebug() << "CitebaseFetcher::updateEntry() - insufficient info to search" << endl;
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+void CitebaseFetcher::updateEntrySynchronous(Data::EntryPtr entry) {
+ if(!entry) {
+ return;
+ }
+ QString arxiv = entry->field(QString::fromLatin1("arxiv"));
+ if(arxiv.isEmpty()) {
+ return;
+ }
+
+ KURL u = searchURL(ArxivID, arxiv);
+ QString bibtex = FileHandler::readTextFile(u, true);
+ if(bibtex.isEmpty()) {
+ return;
+ }
+
+ // assume result is always utf-8
+ Import::BibtexImporter imp(bibtex);
+ Data::CollPtr coll = imp.collection();
+ if(coll && coll->entryCount() > 0) {
+ myLog() << "CitebaseFetcher::updateEntrySynchronous() - found arxiv result, merging" << endl;
+ Data::Collection::mergeEntry(entry, coll->entries().front(), false /*overwrite*/);
+ }
+}
+
+Tellico::Fetch::ConfigWidget* CitebaseFetcher::configWidget(QWidget* parent_) const {
+ return new CitebaseFetcher::ConfigWidget(parent_, this);
+}
+
+CitebaseFetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const CitebaseFetcher*)
+ : Fetch::ConfigWidget(parent_) {
+ QVBoxLayout* l = new QVBoxLayout(optionsWidget());
+ l->addWidget(new QLabel(i18n("This source has no options."), optionsWidget()));
+ l->addStretch();
+}
+
+void CitebaseFetcher::ConfigWidget::saveConfig(KConfigGroup&) {
+}
+
+QString CitebaseFetcher::ConfigWidget::preferredName() const {
+ return CitebaseFetcher::defaultName();
+}
+
+#include "citebasefetcher.moc"
diff --git a/src/fetch/citebasefetcher.h b/src/fetch/citebasefetcher.h
new file mode 100644
index 0000000..a292107
--- /dev/null
+++ b/src/fetch/citebasefetcher.h
@@ -0,0 +1,83 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FETCH_CITEBASEFETCHER_H
+#define TELLICO_FETCH_CITEBASEFETCHER_H
+
+#include "fetcher.h"
+#include "configwidget.h"
+#include "../datavectors.h"
+
+#include <kio/job.h>
+
+#include <qcstring.h> // for QByteArray
+#include <qguardedptr.h>
+
+namespace Tellico {
+ namespace Fetch {
+
+/**
+ * @author Robby Stephenson
+ */
+class CitebaseFetcher : public Fetcher {
+Q_OBJECT
+
+public:
+ CitebaseFetcher(QObject* parent);
+ ~CitebaseFetcher();
+
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual void search(FetchKey key, const QString& value);
+
+ virtual bool canSearch(FetchKey k) const { return k == ArxivID; }
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return Citebase; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+
+ virtual void updateEntry(Data::EntryPtr entry);
+ virtual void updateEntrySynchronous(Data::EntryPtr entry);
+
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const;
+
+ class ConfigWidget : public Fetch::ConfigWidget {
+ public:
+ ConfigWidget(QWidget* parent_, const CitebaseFetcher* fetcher = 0);
+ virtual void saveConfig(KConfigGroup& config);
+ virtual QString preferredName() const;
+ };
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+private slots:
+ void slotData(KIO::Job* job, const QByteArray& data);
+ void slotComplete(KIO::Job* job);
+
+private:
+ KURL searchURL(FetchKey key, const QString& value) const;
+
+ QByteArray m_data;
+ QMap<int, Data::EntryPtr> m_entries;
+ QGuardedPtr<KIO::Job> m_job;
+
+ FetchKey m_key;
+ QString m_value;
+ bool m_started;
+};
+
+ }
+}
+#endif
diff --git a/src/fetch/configwidget.cpp b/src/fetch/configwidget.cpp
new file mode 100644
index 0000000..c7b3b59
--- /dev/null
+++ b/src/fetch/configwidget.cpp
@@ -0,0 +1,66 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "configwidget.h"
+
+#include <kconfig.h>
+#include <klocale.h>
+#include <kaccelmanager.h>
+
+#include <qvgroupbox.h>
+#include <qlayout.h>
+
+using Tellico::Fetch::ConfigWidget;
+
+ConfigWidget::ConfigWidget(QWidget* parent_) : QWidget(parent_), m_modified(false), m_accepted(false) {
+ QHBoxLayout* boxLayout = new QHBoxLayout(this);
+ boxLayout->setSpacing(10);
+
+ QGroupBox* vbox = new QVGroupBox(i18n("Source Options"), this);
+ boxLayout->addWidget(vbox, 10 /*stretch*/);
+
+ m_optionsWidget = new QWidget(vbox);
+}
+
+void ConfigWidget::addFieldsWidget(const StringMap& customFields_, const QStringList& fieldsToAdd_) {
+ if(customFields_.isEmpty()) {
+ return;
+ }
+
+ QVGroupBox* box = new QVGroupBox(i18n("Available Fields"), this);
+ static_cast<QBoxLayout*>(layout())->addWidget(box);
+ for(StringMap::ConstIterator it = customFields_.begin(); it != customFields_.end(); ++it) {
+ QCheckBox* cb = new QCheckBox(it.data(), box);
+ m_fields.insert(it.key(), cb);
+ if(fieldsToAdd_.contains(it.key())) {
+ cb->setChecked(true);
+ }
+ connect(cb, SIGNAL(clicked()), SLOT(slotSetModified()));
+ }
+
+ KAcceleratorManager::manage(this);
+
+ return;
+}
+
+void ConfigWidget::saveFieldsConfig(KConfigGroup& config_) const {
+ QStringList fields;
+ for(QDictIterator<QCheckBox> it(m_fields); it.current(); ++it) {
+ if(it.current()->isChecked()) {
+ fields << it.currentKey();
+ }
+ }
+ config_.writeEntry(QString::fromLatin1("Custom Fields"), fields);
+}
+
+#include "configwidget.moc"
diff --git a/src/fetch/configwidget.h b/src/fetch/configwidget.h
new file mode 100644
index 0000000..9f18f83
--- /dev/null
+++ b/src/fetch/configwidget.h
@@ -0,0 +1,78 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef FETCHCONFIGWIDGET_H
+#define FETCHCONFIGWIDGET_H
+
+#include "../datavectors.h"
+
+#include <qwidget.h>
+#include <qdict.h>
+#include <qcheckbox.h>
+
+class KConfigGroup;
+class QStringList;
+
+namespace Tellico {
+ namespace Fetch {
+
+/**
+ * @author Robby Stephenson
+ */
+class ConfigWidget : public QWidget {
+Q_OBJECT
+
+public:
+ ConfigWidget(QWidget* parent);
+ virtual ~ConfigWidget() {}
+
+ void setAccepted(bool accepted_) { m_accepted = accepted_; }
+ bool shouldSave() const { return m_modified && m_accepted; }
+ /**
+ * Saves any configuration options. The config group must be
+ * set before calling this function.
+ *
+ * @param config_ The KConfig pointer
+ */
+ virtual void saveConfig(KConfigGroup& config) = 0;
+ /**
+ * Called when a fetcher data source is removed. Useful for any cleanup work necessary.
+ * The ExecExternalFetcher might need to remove the script, for example.
+ * Because of the way the ConfigDialog is setup, easier to have that in the ConfigWidget
+ * class than in the Fetcher class itself
+ */
+ virtual void removed() {}
+ virtual QString preferredName() const = 0;
+
+signals:
+ void signalName(const QString& name);
+
+public slots:
+ void slotSetModified(bool modified_ = true) { m_modified = modified_; }
+
+protected:
+ QWidget* optionsWidget() { return m_optionsWidget; }
+ void addFieldsWidget(const StringMap& customFields, const QStringList& fieldsToAdd);
+ void saveFieldsConfig(KConfigGroup& config) const;
+
+private:
+ bool m_modified;
+ bool m_accepted;
+ QWidget* m_optionsWidget;
+ QDict<QCheckBox> m_fields;
+};
+
+ }
+}
+
+#endif
diff --git a/src/fetch/crossreffetcher.cpp b/src/fetch/crossreffetcher.cpp
new file mode 100644
index 0000000..8c5d303
--- /dev/null
+++ b/src/fetch/crossreffetcher.cpp
@@ -0,0 +1,392 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "crossreffetcher.h"
+#include "messagehandler.h"
+#include "../translators/xslthandler.h"
+#include "../translators/tellicoimporter.h"
+#include "../tellico_kernel.h"
+#include "../tellico_utils.h"
+#include "../collection.h"
+#include "../entry.h"
+#include "../core/netaccess.h"
+#include "../imagefactory.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kconfig.h>
+#include <klineedit.h>
+#include <kactivelabel.h>
+
+#include <qlabel.h>
+#include <qwhatsthis.h>
+#include <qlayout.h>
+#include <qfile.h>
+
+// #define CROSSREF_TEST
+
+#define CROSSREF_USE_UNIXREF
+
+namespace {
+ static const char* CROSSREF_BASE_URL = "http://www.crossref.org/openurl/?url_ver=Z39.88-2004&noredirect=true";
+}
+
+using Tellico::Fetch::CrossRefFetcher;
+
+CrossRefFetcher::CrossRefFetcher(QObject* parent_)
+ : Fetcher(parent_), m_xsltHandler(0), m_job(0), m_started(false) {
+}
+
+CrossRefFetcher::~CrossRefFetcher() {
+ delete m_xsltHandler;
+ m_xsltHandler = 0;
+}
+
+QString CrossRefFetcher::defaultName() {
+ return QString::fromLatin1("CrossRef");
+}
+
+QString CrossRefFetcher::source() const {
+ return m_name.isEmpty() ? defaultName() : m_name;
+}
+
+bool CrossRefFetcher::canFetch(int type) const {
+ return type == Data::Collection::Bibtex;
+}
+
+void CrossRefFetcher::readConfigHook(const KConfigGroup& config_) {
+ QString s = config_.readEntry("User");
+ if(!s.isEmpty()) {
+ m_user = s;
+ }
+ s = config_.readEntry("Password");
+ if(!s.isEmpty()) {
+ m_password = s;
+ }
+}
+
+void CrossRefFetcher::search(FetchKey key_, const QString& value_) {
+ m_key = key_;
+ m_value = value_.stripWhiteSpace();
+ m_started = true;
+
+ if(m_user.isEmpty() || m_password.isEmpty()) {
+ message(i18n("%1 requires a username and password.").arg(source()), MessageHandler::Warning);
+ stop();
+ return;
+ }
+
+ if(!canFetch(Kernel::self()->collectionType())) {
+ message(i18n("%1 does not allow searching for this collection type.").arg(source()), MessageHandler::Warning);
+ stop();
+ return;
+ }
+
+ m_data.truncate(0);
+
+// myDebug() << "CrossRefFetcher::search() - value = " << value_ << endl;
+
+ KURL u = searchURL(m_key, m_value);
+ if(u.isEmpty()) {
+ stop();
+ return;
+ }
+
+ m_job = KIO::get(u, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+}
+
+void CrossRefFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+// myDebug() << "CrossRefFetcher::stop()" << endl;
+ if(m_job) {
+ m_job->kill();
+ m_job = 0;
+ }
+ m_data.truncate(0);
+ m_started = false;
+ emit signalDone(this);
+}
+
+void CrossRefFetcher::slotData(KIO::Job*, const QByteArray& data_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(data_.data(), data_.size());
+}
+
+void CrossRefFetcher::slotComplete(KIO::Job* job_) {
+// myDebug() << "CrossRefFetcher::slotComplete()" << endl;
+ // since the fetch is done, don't worry about holding the job pointer
+ m_job = 0;
+
+ if(job_->error()) {
+ job_->showErrorDialog(Kernel::self()->widget());
+ stop();
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "CrossRefFetcher::slotComplete() - no data" << endl;
+ stop();
+ return;
+ }
+
+#if 0
+ kdWarning() << "Remove debug from crossreffetcher.cpp" << endl;
+ QFile f(QString::fromLatin1("/tmp/test.xml"));
+ if(f.open(IO_WriteOnly)) {
+ QTextStream t(&f);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << QCString(m_data, m_data.size()+1);
+ }
+ f.close();
+#endif
+
+ if(!m_xsltHandler) {
+ initXSLTHandler();
+ if(!m_xsltHandler) { // probably an error somewhere in the stylesheet loading
+ stop();
+ return;
+ }
+ }
+
+ // assume result is always utf-8
+ QString str = m_xsltHandler->applyStylesheet(QString::fromUtf8(m_data, m_data.size()));
+ Import::TellicoImporter imp(str);
+ Data::CollPtr coll = imp.collection();
+
+ if(!coll) {
+ myDebug() << "CrossRefFetcher::slotComplete() - no valid result" << endl;
+ stop();
+ return;
+ }
+
+ Data::EntryVec entries = coll->entries();
+ for(Data::EntryVec::Iterator entry = entries.begin(); entry != entries.end(); ++entry) {
+ if(!m_started) {
+ // might get aborted
+ break;
+ }
+ QString desc = entry->field(QString::fromLatin1("author"))
+ + QChar('/') + entry->field(QString::fromLatin1("publisher"));
+ if(!entry->field(QString::fromLatin1("year")).isEmpty()) {
+ desc += QChar('/') + entry->field(QString::fromLatin1("year"));
+ }
+
+ SearchResult* r = new SearchResult(this, entry->title(), desc, entry->field(QString::fromLatin1("isbn")));
+ m_entries.insert(r->uid, Data::EntryPtr(entry));
+ emit signalResultFound(r);
+ }
+
+ stop(); // required
+}
+
+Tellico::Data::EntryPtr CrossRefFetcher::fetchEntry(uint uid_) {
+ Data::EntryPtr entry = m_entries[uid_];
+ // if URL but no cover image, fetch it
+ if(!entry->field(QString::fromLatin1("url")).isEmpty()) {
+ Data::CollPtr coll = entry->collection();
+ Data::FieldPtr field = coll->fieldByName(QString::fromLatin1("cover"));
+ if(!field && !coll->imageFields().isEmpty()) {
+ field = coll->imageFields().front();
+ } else if(!field) {
+ field = new Data::Field(QString::fromLatin1("cover"), i18n("Front Cover"), Data::Field::Image);
+ coll->addField(field);
+ }
+ if(entry->field(field).isEmpty()) {
+ QPixmap pix = NetAccess::filePreview(entry->field(QString::fromLatin1("url")));
+ if(!pix.isNull()) {
+ QString id = ImageFactory::addImage(pix, QString::fromLatin1("PNG"));
+ if(!id.isEmpty()) {
+ entry->setField(field, id);
+ }
+ }
+ }
+ }
+ return entry;
+}
+
+void CrossRefFetcher::initXSLTHandler() {
+#ifdef CROSSREF_USE_UNIXREF
+ QString xsltfile = locate("appdata", QString::fromLatin1("unixref2tellico.xsl"));
+#else
+ QString xsltfile = locate("appdata", QString::fromLatin1("crossref2tellico.xsl"));
+#endif
+ if(xsltfile.isEmpty()) {
+ kdWarning() << "CrossRefFetcher::initXSLTHandler() - can not locate xslt file." << endl;
+ return;
+ }
+
+ KURL u;
+ u.setPath(xsltfile);
+
+ delete m_xsltHandler;
+ m_xsltHandler = new XSLTHandler(u);
+ if(!m_xsltHandler->isValid()) {
+ kdWarning() << "CrossRefFetcher::initXSLTHandler() - error in crossref2tellico.xsl." << endl;
+ delete m_xsltHandler;
+ m_xsltHandler = 0;
+ return;
+ }
+}
+
+KURL CrossRefFetcher::searchURL(FetchKey key_, const QString& value_) const {
+ KURL u(QString::fromLatin1(CROSSREF_BASE_URL));
+#ifdef CROSSREF_USE_UNIXREF
+ u.addQueryItem(QString::fromLatin1("format"), QString::fromLatin1("unixref"));
+#endif
+ u.addQueryItem(QString::fromLatin1("req_dat"), QString::fromLatin1("ourl_%1:%2").arg(m_user, m_password));
+
+ switch(key_) {
+ case DOI:
+ u.addQueryItem(QString::fromLatin1("rft_id"), QString::fromLatin1("info:doi/%1").arg(value_));
+ break;
+
+ default:
+ kdWarning() << "CrossRefFetcher::search() - key not recognized: " << m_key << endl;
+ return KURL();
+ }
+
+#ifdef CROSSREF_TEST
+ u = KURL::fromPathOrURL(QString::fromLatin1("/home/robby/crossref.xml"));
+#endif
+ myDebug() << "CrossRefFetcher::search() - url: " << u.url() << endl;
+ return u;
+}
+
+void CrossRefFetcher::updateEntry(Data::EntryPtr entry_) {
+ QString doi = entry_->field(QString::fromLatin1("doi"));
+ if(!doi.isEmpty()) {
+ search(Fetch::DOI, doi);
+ return;
+ }
+
+#if 0
+ // optimistically try searching for title and rely on Collection::sameEntry() to figure things out
+ QString t = entry_->field(QString::fromLatin1("title"));
+ if(!t.isEmpty()) {
+ m_limit = 10; // raise limit so more possibility of match
+ search(Fetch::Title, t);
+ return;
+ }
+#endif
+
+ myDebug() << "CrossRefFetcher::updateEntry() - insufficient info to search" << endl;
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+void CrossRefFetcher::updateEntrySynchronous(Data::EntryPtr entry) {
+ if(!entry) {
+ return;
+ }
+ if(m_user.isEmpty() || m_password.isEmpty()) {
+ myDebug() << "CrossRefFetcher::updateEntrySynchronous() - username and password is required" << endl;
+ return;
+ }
+ QString doi = entry->field(QString::fromLatin1("doi"));
+ if(doi.isEmpty()) {
+ return;
+ }
+
+ KURL u = searchURL(DOI, doi);
+ QString xml = FileHandler::readTextFile(u, true, true);
+ if(xml.isEmpty()) {
+ return;
+ }
+
+ if(!m_xsltHandler) {
+ initXSLTHandler();
+ if(!m_xsltHandler) { // probably an error somewhere in the stylesheet loading
+ return;
+ }
+ }
+
+ // assume result is always utf-8
+ QString str = m_xsltHandler->applyStylesheet(xml);
+ Import::TellicoImporter imp(str);
+ Data::CollPtr coll = imp.collection();
+ if(coll && coll->entryCount() > 0) {
+ myLog() << "CrossRefFetcher::updateEntrySynchronous() - found DOI result, merging" << endl;
+ Data::Collection::mergeEntry(entry, coll->entries().front(), false /*overwrite*/);
+ }
+}
+
+Tellico::Fetch::ConfigWidget* CrossRefFetcher::configWidget(QWidget* parent_) const {
+ return new CrossRefFetcher::ConfigWidget(parent_, this);
+}
+
+CrossRefFetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const CrossRefFetcher* fetcher_)
+ : Fetch::ConfigWidget(parent_) {
+ QGridLayout* l = new QGridLayout(optionsWidget(), 4, 2);
+ l->setSpacing(4);
+ l->setColStretch(1, 10);
+
+ int row = 0;
+
+ KActiveLabel* al = new KActiveLabel(i18n("CrossRef requires an account for access. "
+ "Please read the terms and conditions and "
+ "<a href='http://www.crossref.org/requestaccount/'>"
+ "request an account</a>. Enter your OpenURL "
+ "account information below."),
+ optionsWidget());
+ ++row;
+ l->addMultiCellWidget(al, row, row, 0, 1);
+ // richtext gets weird with size
+ al->setMinimumWidth(al->sizeHint().width());
+
+ QLabel* label = new QLabel(i18n("&Username: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_userEdit = new KLineEdit(optionsWidget());
+ connect(m_userEdit, SIGNAL(textChanged(const QString&)), SLOT(slotSetModified()));
+ l->addWidget(m_userEdit, row, 1);
+ QString w = i18n("A username and password is required to access the CrossRef service. The password is "
+ "stored as plain text in the Tellico configuration file.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_userEdit, w);
+ label->setBuddy(m_userEdit);
+
+ label = new QLabel(i18n("&Password: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_passEdit = new KLineEdit(optionsWidget());
+ connect(m_passEdit, SIGNAL(textChanged(const QString&)), SLOT(slotSetModified()));
+ l->addWidget(m_passEdit, row, 1);
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_passEdit, w);
+ label->setBuddy(m_passEdit);
+
+ if(fetcher_) {
+ m_userEdit->setText(fetcher_->m_user);
+ m_passEdit->setText(fetcher_->m_password);
+ }
+}
+
+void CrossRefFetcher::ConfigWidget::saveConfig(KConfigGroup& config_) {
+ QString s = m_userEdit->text();
+ config_.writeEntry("User", s);
+
+ s = m_passEdit->text();
+ config_.writeEntry("Password", s);
+
+ slotSetModified(false);
+}
+
+QString CrossRefFetcher::ConfigWidget::preferredName() const {
+ return CrossRefFetcher::defaultName();
+}
+
+#include "crossreffetcher.moc"
diff --git a/src/fetch/crossreffetcher.h b/src/fetch/crossreffetcher.h
new file mode 100644
index 0000000..392d46a
--- /dev/null
+++ b/src/fetch/crossreffetcher.h
@@ -0,0 +1,97 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FETCH_CROSSREFFETCHER_H
+#define TELLICO_FETCH_CROSSREFFETCHER_H
+
+#include "fetcher.h"
+#include "configwidget.h"
+#include "../datavectors.h"
+
+#include <kio/job.h>
+
+#include <qcstring.h> // for QByteArray
+#include <qguardedptr.h>
+
+class KLineEdit;
+
+namespace Tellico {
+
+ class XSLTHandler;
+
+ namespace Fetch {
+
+/**
+ * @author Robby Stephenson
+ */
+class CrossRefFetcher : public Fetcher {
+Q_OBJECT
+
+public:
+ CrossRefFetcher(QObject* parent);
+ ~CrossRefFetcher();
+
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual void search(FetchKey key, const QString& value);
+
+ virtual bool canSearch(FetchKey k) const { return k == DOI; }
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return CrossRef; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+
+ virtual void updateEntry(Data::EntryPtr entry);
+ virtual void updateEntrySynchronous(Data::EntryPtr entry);
+
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const;
+
+ class ConfigWidget : public Fetch::ConfigWidget {
+ public:
+ ConfigWidget(QWidget* parent_, const CrossRefFetcher* fetcher = 0);
+ virtual void saveConfig(KConfigGroup& config);
+ virtual QString preferredName() const;
+ private:
+ KLineEdit* m_userEdit;
+ KLineEdit* m_passEdit;
+ };
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+private slots:
+ void slotData(KIO::Job* job, const QByteArray& data);
+ void slotComplete(KIO::Job* job);
+
+private:
+ void initXSLTHandler();
+ KURL searchURL(FetchKey key, const QString& value) const;
+
+ XSLTHandler* m_xsltHandler;
+
+ QString m_user;
+ QString m_password;
+
+ QByteArray m_data;
+ QMap<int, Data::EntryPtr> m_entries;
+ QGuardedPtr<KIO::Job> m_job;
+
+ FetchKey m_key;
+ QString m_value;
+ bool m_started;
+};
+
+ }
+}
+#endif
diff --git a/src/fetch/discogsfetcher.cpp b/src/fetch/discogsfetcher.cpp
new file mode 100644
index 0000000..31a8bab
--- /dev/null
+++ b/src/fetch/discogsfetcher.cpp
@@ -0,0 +1,413 @@
+/***************************************************************************
+ copyright : (C) 2008 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "discogsfetcher.h"
+#include "messagehandler.h"
+#include "../translators/xslthandler.h"
+#include "../translators/tellicoimporter.h"
+#include "../imagefactory.h"
+#include "../tellico_kernel.h"
+#include "../tellico_utils.h"
+#include "../collection.h"
+#include "../entry.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kconfig.h>
+#include <kio/job.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qfile.h>
+#include <qwhatsthis.h>
+
+//#define DISCOGS_TEST
+
+namespace {
+ static const int DISCOGS_MAX_RETURNS_TOTAL = 20;
+ static const char* DISCOGS_API_URL = "http://www.discogs.com";
+ static const char* DISCOGS_API_KEY = "de6cb96534";
+}
+
+using Tellico::Fetch::DiscogsFetcher;
+
+DiscogsFetcher::DiscogsFetcher(QObject* parent_, const char* name_)
+ : Fetcher(parent_, name_), m_xsltHandler(0),
+ m_limit(DISCOGS_MAX_RETURNS_TOTAL), m_job(0), m_started(false),
+ m_apiKey(QString::fromLatin1(DISCOGS_API_KEY)) {
+}
+
+DiscogsFetcher::~DiscogsFetcher() {
+ delete m_xsltHandler;
+ m_xsltHandler = 0;
+}
+
+QString DiscogsFetcher::defaultName() {
+ return i18n("Discogs Audio Search");
+}
+
+QString DiscogsFetcher::source() const {
+ return m_name.isEmpty() ? defaultName() : m_name;
+}
+
+bool DiscogsFetcher::canFetch(int type) const {
+ return type == Data::Collection::Album;
+}
+
+void DiscogsFetcher::readConfigHook(const KConfigGroup& config_) {
+ QString k = config_.readEntry("API Key");
+ if(!k.isEmpty()) {
+ m_apiKey = k;
+ }
+ m_fetchImages = config_.readBoolEntry("Fetch Images", true);
+ m_fields = config_.readListEntry("Custom Fields");
+}
+
+void DiscogsFetcher::search(FetchKey key_, const QString& value_) {
+ m_key = key_;
+ m_value = value_;
+ m_started = true;
+ m_start = 1;
+ m_total = -1;
+ doSearch();
+}
+
+void DiscogsFetcher::continueSearch() {
+ m_started = true;
+ doSearch();
+}
+
+void DiscogsFetcher::doSearch() {
+ KURL u(QString::fromLatin1(DISCOGS_API_URL));
+ u.addQueryItem(QString::fromLatin1("f"), QString::fromLatin1("xml"));
+ u.addQueryItem(QString::fromLatin1("api_key"), m_apiKey);
+
+ if(!canFetch(Kernel::self()->collectionType())) {
+ message(i18n("%1 does not allow searching for this collection type.").arg(source()), MessageHandler::Warning);
+ stop();
+ return;
+ }
+
+ switch(m_key) {
+ case Title:
+ u.setPath(QString::fromLatin1("/search"));
+ u.addQueryItem(QString::fromLatin1("q"), m_value);
+ u.addQueryItem(QString::fromLatin1("type"), QString::fromLatin1("release"));
+ break;
+
+ case Person:
+ u.setPath(QString::fromLatin1("/artist/%1").arg(m_value));
+ break;
+
+ case Keyword:
+ u.setPath(QString::fromLatin1("/search"));
+ u.addQueryItem(QString::fromLatin1("q"), m_value);
+ u.addQueryItem(QString::fromLatin1("type"), QString::fromLatin1("all"));
+ break;
+
+ default:
+ kdWarning() << "DiscogsFetcher::search() - key not recognized: " << m_key << endl;
+ stop();
+ return;
+ }
+
+#ifdef DISCOGS_TEST
+ u = KURL(QString::fromLatin1("/home/robby/discogs-results.xml"));
+#endif
+// myDebug() << "DiscogsFetcher::search() - url: " << u.url() << endl;
+
+ m_job = KIO::get(u, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+}
+
+void DiscogsFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+ if(m_job) {
+ m_job->kill();
+ m_job = 0;
+ }
+ m_data.truncate(0);
+ m_started = false;
+ emit signalDone(this);
+}
+
+void DiscogsFetcher::slotData(KIO::Job*, const QByteArray& data_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(data_.data(), data_.size());
+}
+
+void DiscogsFetcher::slotComplete(KIO::Job* job_) {
+// myDebug() << "DiscogsFetcher::slotComplete()" << endl;
+ if(job_->error()) {
+ job_->showErrorDialog(Kernel::self()->widget());
+ stop();
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "DiscogsFetcher::slotComplete() - no data" << endl;
+ stop();
+ return;
+ }
+
+#if 0
+ kdWarning() << "Remove debug from discogsfetcher.cpp" << endl;
+ QFile f(QString::fromLatin1("/tmp/test.xml"));
+ if(f.open(IO_WriteOnly)) {
+ QTextStream t(&f);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << QCString(m_data, m_data.size()+1);
+ }
+ f.close();
+#endif
+
+ if(!m_xsltHandler) {
+ initXSLTHandler();
+ if(!m_xsltHandler) { // probably an error somewhere in the stylesheet loading
+ stop();
+ return;
+ }
+ }
+
+ if(m_total == -1) {
+ QDomDocument dom;
+ if(!dom.setContent(m_data, false)) {
+ kdWarning() << "DiscogsFetcher::slotComplete() - server did not return valid XML." << endl;
+ return;
+ }
+ // total is /resp/searchresults/@numResults
+ QDomNode n = dom.documentElement().namedItem(QString::fromLatin1("resp"))
+ .namedItem(QString::fromLatin1("searchresults"));
+ QDomElement e = n.toElement();
+ if(!e.isNull()) {
+ m_total = e.attribute(QString::fromLatin1("numResults")).toInt();
+ myDebug() << "total = " << m_total;
+ }
+ }
+
+ // assume discogs is always utf-8
+ QString str = m_xsltHandler->applyStylesheet(QString::fromUtf8(m_data, m_data.size()));
+ Import::TellicoImporter imp(str);
+ Data::CollPtr coll = imp.collection();
+ if(!coll) {
+ myDebug() << "DiscogsFetcher::slotComplete() - no collection pointer" << endl;
+ stop();
+ return;
+ }
+
+ int count = 0;
+ Data::EntryVec entries = coll->entries();
+ for(Data::EntryVec::Iterator entry = entries.begin(); count < m_limit && entry != entries.end(); ++entry, ++count) {
+ if(!m_started) {
+ // might get aborted
+ break;
+ }
+ QString desc = entry->field(QString::fromLatin1("artist"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("label"));
+
+ SearchResult* r = new SearchResult(this, entry->title(), desc, QString());
+ m_entries.insert(r->uid, Data::EntryPtr(entry));
+ emit signalResultFound(r);
+ }
+ m_start = m_entries.count() + 1;
+ // not sure how tospecify start in the REST url
+ // m_hasMoreResults = m_start <= m_total;
+
+ stop(); // required
+}
+
+Tellico::Data::EntryPtr DiscogsFetcher::fetchEntry(uint uid_) {
+ Data::EntryPtr entry = m_entries[uid_];
+ if(!entry) {
+ kdWarning() << "DiscogsFetcher::fetchEntry() - no entry in dict" << endl;
+ return 0;
+ }
+ // one way we tell if this entry has been fully initialized is to
+ // check for a cover image
+ if(!entry->field(QString::fromLatin1("cover")).isEmpty()) {
+ myLog() << "DiscogsFetcher::fetchEntry() - already downloaded " << entry->title() << endl;
+ return entry;
+ }
+
+ QString release = entry->field(QString::fromLatin1("discogs-id"));
+ if(release.isEmpty()) {
+ myDebug() << "DiscogsFetcher::fetchEntry() - no discogs release found" << endl;
+ return entry;
+ }
+
+#ifdef DISCOGS_TEST
+ KURL u(QString::fromLatin1("/home/robby/discogs-release.xml"));
+#else
+ KURL u(QString::fromLatin1(DISCOGS_API_URL));
+ u.setPath(QString::fromLatin1("/release/%1").arg(release));
+ u.addQueryItem(QString::fromLatin1("f"), QString::fromLatin1("xml"));
+ u.addQueryItem(QString::fromLatin1("api_key"), m_apiKey);
+#endif
+// myDebug() << "DiscogsFetcher::fetchEntry() - url: " << u << endl;
+
+ // quiet, utf8, allowCompressed
+ QString output = FileHandler::readTextFile(u, true, true, true);
+#if 0
+ kdWarning() << "Remove output debug from discogsfetcher.cpp" << endl;
+ QFile f(QString::fromLatin1("/tmp/test.xml"));
+ if(f.open(IO_WriteOnly)) {
+ QTextStream t(&f);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << output;
+ }
+ f.close();
+#endif
+
+ Import::TellicoImporter imp(m_xsltHandler->applyStylesheet(output));
+ Data::CollPtr coll = imp.collection();
+// getTracks(entry);
+ if(!coll) {
+ kdWarning() << "DiscogsFetcher::fetchEntry() - no collection pointer" << endl;
+ return entry;
+ }
+
+ if(coll->entryCount() > 1) {
+ myDebug() << "DiscogsFetcher::fetchEntry() - weird, more than one entry found" << endl;
+ }
+
+ const StringMap customFields = this->customFields();
+ for(StringMap::ConstIterator it = customFields.begin(); it != customFields.end(); ++it) {
+ if(!m_fields.contains(it.key())) {
+ coll->removeField(it.key());
+ }
+ }
+
+ // don't want to include id
+ coll->removeField(QString::fromLatin1("discogs-id"));
+
+ entry = coll->entries().front();
+ m_entries.replace(uid_, entry);
+ return entry;
+}
+
+void DiscogsFetcher::initXSLTHandler() {
+ QString xsltfile = locate("appdata", QString::fromLatin1("discogs2tellico.xsl"));
+ if(xsltfile.isEmpty()) {
+ kdWarning() << "DiscogsFetcher::initXSLTHandler() - can not locate discogs2tellico.xsl." << endl;
+ return;
+ }
+
+ KURL u;
+ u.setPath(xsltfile);
+
+ delete m_xsltHandler;
+ m_xsltHandler = new XSLTHandler(u);
+ if(!m_xsltHandler->isValid()) {
+ kdWarning() << "DiscogsFetcher::initXSLTHandler() - error in discogs2tellico.xsl." << endl;
+ delete m_xsltHandler;
+ m_xsltHandler = 0;
+ return;
+ }
+}
+
+void DiscogsFetcher::updateEntry(Data::EntryPtr entry_) {
+// myDebug() << "DiscogsFetcher::updateEntry()" << endl;
+
+ QString value;
+ QString title = entry_->field(QString::fromLatin1("title"));
+ if(!title.isEmpty()) {
+ search(Title, value);
+ return;
+ }
+
+ QString artist = entry_->field(QString::fromLatin1("artist"));
+ if(!artist.isEmpty()) {
+ search(Person, artist);
+ return;
+ }
+
+ myDebug() << "DiscogsFetcher::updateEntry() - insufficient info to search" << endl;
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+Tellico::Fetch::ConfigWidget* DiscogsFetcher::configWidget(QWidget* parent_) const {
+ return new DiscogsFetcher::ConfigWidget(parent_, this);
+}
+
+DiscogsFetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const DiscogsFetcher* fetcher_)
+ : Fetch::ConfigWidget(parent_) {
+ QGridLayout* l = new QGridLayout(optionsWidget(), 2, 2);
+ l->setSpacing(4);
+ l->setColStretch(1, 10);
+
+ int row = -1;
+ QLabel* label = new QLabel(i18n("API &key: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+
+ m_apiKeyEdit = new KLineEdit(optionsWidget());
+ connect(m_apiKeyEdit, SIGNAL(textChanged(const QString&)), SLOT(slotSetModified()));
+ l->addWidget(m_apiKeyEdit, row, 1);
+ QString w = i18n("With your discogs.com account you receive an API key for the usage of their XML-based interface "
+ "(See http://www.discogs.com/help/api).");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_apiKeyEdit, w);
+ label->setBuddy(m_apiKeyEdit);
+
+ m_fetchImageCheck = new QCheckBox(i18n("Download cover &image"), optionsWidget());
+ connect(m_fetchImageCheck, SIGNAL(clicked()), SLOT(slotSetModified()));
+ ++row;
+ l->addMultiCellWidget(m_fetchImageCheck, row, row, 0, 1);
+ w = i18n("The cover image may be downloaded as well. However, too many large images in the "
+ "collection may degrade performance.");
+ QWhatsThis::add(m_fetchImageCheck, w);
+
+ l->setRowStretch(++row, 10);
+
+ // now add additional fields widget
+ addFieldsWidget(DiscogsFetcher::customFields(), fetcher_ ? fetcher_->m_fields : QStringList());
+
+ if(fetcher_) {
+ m_apiKeyEdit->setText(fetcher_->m_apiKey);
+ m_fetchImageCheck->setChecked(fetcher_->m_fetchImages);
+ } else {
+ m_apiKeyEdit->setText(QString::fromLatin1(DISCOGS_API_KEY));
+ m_fetchImageCheck->setChecked(true);
+ }
+}
+
+void DiscogsFetcher::ConfigWidget::saveConfig(KConfigGroup& config_) {
+ QString apiKey = m_apiKeyEdit->text().stripWhiteSpace();
+ if(!apiKey.isEmpty()) {
+ config_.writeEntry("API Key", apiKey);
+ }
+ config_.writeEntry("Fetch Images", m_fetchImageCheck->isChecked());
+
+ saveFieldsConfig(config_);
+ slotSetModified(false);
+}
+
+QString DiscogsFetcher::ConfigWidget::preferredName() const {
+ return DiscogsFetcher::defaultName();
+}
+
+Tellico::StringMap DiscogsFetcher::customFields() {
+ StringMap map;
+ map[QString::fromLatin1("producer")] = i18n("Producer");
+ map[QString::fromLatin1("nationality")] = i18n("Nationality");
+ map[QString::fromLatin1("discogs")] = i18n("Discogs Link");
+ return map;
+}
+
+#include "discogsfetcher.moc"
diff --git a/src/fetch/discogsfetcher.h b/src/fetch/discogsfetcher.h
new file mode 100644
index 0000000..ac8c1b8
--- /dev/null
+++ b/src/fetch/discogsfetcher.h
@@ -0,0 +1,117 @@
+/***************************************************************************
+ copyright : (C) 2008 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef DISCOGSFETCHER_H
+#define DISCOGSFETCHER_H
+
+namespace Tellico {
+ class XSLTHandler;
+}
+
+#include "fetcher.h"
+#include "configwidget.h"
+#include "../datavectors.h"
+#include <klineedit.h>
+
+#include <qdom.h>
+#include <qcstring.h> // for QByteArray
+#include <qguardedptr.h>
+
+namespace KIO {
+ class Job;
+}
+
+namespace Tellico {
+ namespace Fetch {
+
+/**
+ * A fetcher for discogs.com
+ *
+ * @author Robby Stephenson
+ */
+class DiscogsFetcher : public Fetcher {
+Q_OBJECT
+
+public:
+ /**
+ */
+ DiscogsFetcher(QObject* parent, const char* name = 0);
+ /**
+ */
+ virtual ~DiscogsFetcher();
+
+ /**
+ */
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual void search(FetchKey key, const QString& value);
+ virtual void continueSearch();
+ // amazon can search title or person
+ virtual bool canSearch(FetchKey k) const { return k == Title || k == Person || k == Keyword; }
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return Discogs; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+
+ virtual void updateEntry(Data::EntryPtr entry);
+
+ /**
+ * Returns a widget for modifying the fetcher's config.
+ */
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const;
+
+ static StringMap customFields();
+
+ class ConfigWidget : public Fetch::ConfigWidget {
+ public:
+ ConfigWidget(QWidget* parent_, const DiscogsFetcher* fetcher = 0);
+ virtual void saveConfig(KConfigGroup&);
+ virtual QString preferredName() const;
+ private:
+ KLineEdit *m_apiKeyEdit;
+ QCheckBox* m_fetchImageCheck;
+ };
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+private slots:
+ void slotData(KIO::Job* job, const QByteArray& data);
+ void slotComplete(KIO::Job* job);
+
+private:
+ void initXSLTHandler();
+ void doSearch();
+
+ XSLTHandler* m_xsltHandler;
+ int m_limit;
+ int m_start;
+ int m_total;
+
+ QByteArray m_data;
+ QMap<int, Data::EntryPtr> m_entries;
+ QGuardedPtr<KIO::Job> m_job;
+
+ FetchKey m_key;
+ QString m_value;
+ bool m_started;
+
+ bool m_fetchImages;
+ QString m_apiKey;
+ QStringList m_fields;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/fetch/entrezfetcher.cpp b/src/fetch/entrezfetcher.cpp
new file mode 100644
index 0000000..14b9e20
--- /dev/null
+++ b/src/fetch/entrezfetcher.cpp
@@ -0,0 +1,498 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "entrezfetcher.h"
+#include "../tellico_kernel.h"
+#include "../latin1literal.h"
+#include "../collection.h"
+#include "../entry.h"
+#include "../filehandler.h"
+#include "../translators/xslthandler.h"
+#include "../translators/tellicoimporter.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kstandarddirs.h>
+#include <kio/job.h>
+
+#include <qdom.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qfile.h>
+
+//#define ENTREZ_TEST
+
+namespace {
+ static const int ENTREZ_MAX_RETURNS_TOTAL = 25;
+ static const char* ENTREZ_BASE_URL = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/";
+ static const char* ENTREZ_SEARCH_CGI = "esearch.fcgi";
+ static const char* ENTREZ_SUMMARY_CGI = "esummary.fcgi";
+ static const char* ENTREZ_FETCH_CGI = "efetch.fcgi";
+ static const char* ENTREZ_LINK_CGI = "elink.fcgi";
+ static const char* ENTREZ_DEFAULT_DATABASE = "pubmed";
+}
+
+using Tellico::Fetch::EntrezFetcher;
+
+EntrezFetcher::EntrezFetcher(QObject* parent_, const char* name_) : Fetcher(parent_, name_), m_xsltHandler(0),
+ m_step(Begin), m_started(false) {
+}
+
+EntrezFetcher::~EntrezFetcher() {
+}
+
+QString EntrezFetcher::defaultName() {
+ return i18n("Entrez Database");
+}
+
+QString EntrezFetcher::source() const {
+ return m_name.isEmpty() ? defaultName() : m_name;
+}
+
+bool EntrezFetcher::canFetch(int type) const {
+ return type == Data::Collection::Bibtex;
+}
+
+void EntrezFetcher::readConfigHook(const KConfigGroup& config_) {
+ QString s = config_.readEntry("Database", QString::fromLatin1(ENTREZ_DEFAULT_DATABASE)); // default to pubmed
+ if(!s.isEmpty()) {
+ m_dbname = s;
+ }
+ m_fields = config_.readListEntry("Custom Fields");
+}
+
+void EntrezFetcher::search(FetchKey key_, const QString& value_) {
+ m_started = true;
+ m_start = 1;
+ m_total = -1;
+
+// only search if current collection is a bibliography
+ if(!canFetch(Kernel::self()->collectionType())) {
+ myDebug() << "EntrezFetcher::search() - collection type mismatch, stopping" << endl;
+ stop();
+ return;
+ }
+ if(m_dbname.isEmpty()) {
+ m_dbname = QString::fromLatin1(ENTREZ_DEFAULT_DATABASE);
+ }
+
+#ifdef ENTREZ_TEST
+ KURL u = KURL::fromPathOrURL(QString::fromLatin1("/home/robby/esearch.xml"));
+#else
+ KURL u(QString::fromLatin1(ENTREZ_BASE_URL));
+ u.addPath(QString::fromLatin1(ENTREZ_SEARCH_CGI));
+ u.addQueryItem(QString::fromLatin1("tool"), QString::fromLatin1("Tellico"));
+ u.addQueryItem(QString::fromLatin1("retmode"), QString::fromLatin1("xml"));
+ u.addQueryItem(QString::fromLatin1("usehistory"), QString::fromLatin1("y"));
+ u.addQueryItem(QString::fromLatin1("retmax"), QString::fromLatin1("1")); // we're just getting the count
+ u.addQueryItem(QString::fromLatin1("db"), m_dbname);
+ u.addQueryItem(QString::fromLatin1("term"), value_);
+ switch(key_) {
+ case Title:
+ u.addQueryItem(QString::fromLatin1("field"), QString::fromLatin1("titl"));
+ break;
+
+ case Person:
+ u.addQueryItem(QString::fromLatin1("field"), QString::fromLatin1("auth"));
+ break;
+
+ case Keyword:
+ // for Tellico Keyword searches basically mean search for any field matching
+// u.addQueryItem(QString::fromLatin1("field"), QString::fromLatin1("word"));
+ break;
+
+ case PubmedID:
+ u.addQueryItem(QString::fromLatin1("field"), QString::fromLatin1("pmid"));
+ break;
+
+ case DOI:
+ case Raw:
+ u.setQuery(u.query() + '&' + value_);
+ break;
+
+ default:
+ kdWarning() << "EntrezFetcher::search() - FetchKey not supported" << endl;
+ stop();
+ return;
+ }
+#endif
+
+ m_step = Search;
+// myLog() << "EntrezFetcher::doSearch() - url: " << u.url() << endl;
+ m_job = KIO::get(u, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+}
+
+void EntrezFetcher::continueSearch() {
+ m_started = true;
+ doSummary();
+}
+
+void EntrezFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+ if(m_job) {
+ m_job->kill();
+ m_job = 0;
+ }
+ m_data.truncate(0);
+ m_started = false;
+ m_step = Begin;
+ emit signalDone(this);
+}
+
+void EntrezFetcher::slotData(KIO::Job*, const QByteArray& data_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(data_.data(), data_.size());
+}
+
+void EntrezFetcher::slotComplete(KIO::Job* job_) {
+ // since the fetch is done, don't worry about holding the job pointer
+ m_job = 0;
+
+ if(job_->error()) {
+ job_->showErrorDialog(Kernel::self()->widget());
+ stop();
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "EntrezFetcher::slotComplete() - no data" << endl;
+ stop();
+ return;
+ }
+
+#if 0
+ kdWarning() << "Remove debug from entrezfetcher.cpp: " << __LINE__ << endl;
+ QFile f(QString::fromLatin1("/tmp/test.xml"));
+ if(f.open(IO_WriteOnly)) {
+ QTextStream t(&f);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << QCString(m_data, m_data.size()+1);
+ }
+ f.close();
+#endif
+
+ switch(m_step) {
+ case Search:
+ searchResults();
+ break;
+ case Summary:
+ summaryResults();
+ break;
+ case Begin:
+ case Fetch:
+ default:
+ myLog() << "EntrezFetcher::slotComplete() - wrong step = " << m_step << endl;
+ stop();
+ break;
+ }
+}
+
+void EntrezFetcher::searchResults() {
+ QDomDocument dom;
+ if(!dom.setContent(m_data, false)) {
+ kdWarning() << "EntrezFetcher::searchResults() - server did not return valid XML." << endl;
+ stop();
+ return;
+ }
+ // find Count, QueryKey, and WebEnv elements
+ int count = 0;
+ for(QDomNode n = dom.documentElement().firstChild(); !n.isNull(); n = n.nextSibling()) {
+ QDomElement e = n.toElement();
+ if(e.isNull()) {
+ continue;
+ }
+ if(e.tagName() == Latin1Literal("Count")) {
+ m_total = e.text().toInt();
+ ++count;
+ } else if(e.tagName() == Latin1Literal("QueryKey")) {
+ m_queryKey = e.text();
+ ++count;
+ } else if(e.tagName() == Latin1Literal("WebEnv")) {
+ m_webEnv = e.text();
+ ++count;
+ }
+ if(count >= 3) {
+ break; // found them all
+ }
+ }
+
+ m_data.truncate(0);
+ doSummary();
+}
+
+void EntrezFetcher::doSummary() {
+#ifdef ENTREZ_TEST
+ KURL u = KURL::fromPathOrURL(QString::fromLatin1("/home/robby/esummary.xml"));
+#else
+ KURL u(QString::fromLatin1(ENTREZ_BASE_URL));
+ u.addPath(QString::fromLatin1(ENTREZ_SUMMARY_CGI));
+ u.addQueryItem(QString::fromLatin1("tool"), QString::fromLatin1("Tellico"));
+ u.addQueryItem(QString::fromLatin1("retmode"), QString::fromLatin1("xml"));
+ u.addQueryItem(QString::fromLatin1("retstart"), QString::number(m_start));
+ u.addQueryItem(QString::fromLatin1("retmax"), QString::number(QMIN(m_total-m_start-1, ENTREZ_MAX_RETURNS_TOTAL)));
+ u.addQueryItem(QString::fromLatin1("usehistory"), QString::fromLatin1("y"));
+ u.addQueryItem(QString::fromLatin1("db"), m_dbname);
+ u.addQueryItem(QString::fromLatin1("query_key"), m_queryKey);
+ u.addQueryItem(QString::fromLatin1("WebEnv"), m_webEnv);
+#endif
+
+ m_step = Summary;
+// myLog() << "EntrezFetcher::searchResults() - url: " << u.url() << endl;
+ m_job = KIO::get(u, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+}
+
+void EntrezFetcher::summaryResults() {
+ QDomDocument dom;
+ if(!dom.setContent(m_data, false)) {
+ kdWarning() << "EntrezFetcher::summaryResults() - server did not return valid XML." << endl;
+ stop();
+ return;
+ }
+ // top child is eSummaryResult
+ // all children are DocSum
+ for(QDomNode n = dom.documentElement().firstChild(); !n.isNull(); n = n.nextSibling()) {
+ QDomElement e = n.toElement();
+ if(e.isNull() || e.tagName() != Latin1Literal("DocSum")) {
+ continue;
+ }
+ QDomNodeList nodes = e.elementsByTagName(QString::fromLatin1("Id"));
+ if(nodes.count() == 0) {
+ myDebug() << "EntrezFetcher::summaryResults() - no Id elements" << endl;
+ continue;
+ }
+ int id = nodes.item(0).toElement().text().toInt();
+ QString title, pubdate, authors;
+ nodes = e.elementsByTagName(QString::fromLatin1("Item"));
+ for(uint j = 0; j < nodes.count(); ++j) {
+ if(nodes.item(j).toElement().attribute(QString::fromLatin1("Name")) == Latin1Literal("Title")) {
+ title = nodes.item(j).toElement().text();
+ } else if(nodes.item(j).toElement().attribute(QString::fromLatin1("Name")) == Latin1Literal("PubDate")) {
+ pubdate = nodes.item(j).toElement().text();
+ } else if(nodes.item(j).toElement().attribute(QString::fromLatin1("Name")) == Latin1Literal("AuthorList")) {
+ QStringList list;
+ for(QDomNode aNode = nodes.item(j).firstChild(); !aNode.isNull(); aNode = aNode.nextSibling()) {
+ // lazy, assume all children Items are authors
+ if(aNode.nodeName() == Latin1Literal("Item")) {
+ list << aNode.toElement().text();
+ }
+ }
+ authors = list.join(QString::fromLatin1("; "));
+ }
+ if(!title.isEmpty() && !pubdate.isEmpty() && !authors.isEmpty()) {
+ break; // done now
+ }
+ }
+ SearchResult* r = new SearchResult(this, title, pubdate + '/' + authors, QString());
+ m_matches.insert(r->uid, id);
+ emit signalResultFound(r);
+ }
+ m_start = m_matches.count() + 1;
+ m_hasMoreResults = m_start <= m_total;
+ stop(); // done searching
+}
+
+Tellico::Data::EntryPtr EntrezFetcher::fetchEntry(uint uid_) {
+ // if we already grabbed this one, then just pull it out of the dict
+ Data::EntryPtr entry = m_entries[uid_];
+ if(entry) {
+ return entry;
+ }
+
+ if(!m_matches.contains(uid_)) {
+ return 0;
+ }
+
+ if(!m_xsltHandler) {
+ initXSLTHandler();
+ if(!m_xsltHandler) { // probably an error somewhere in the stylesheet loading
+ stop();
+ return 0;
+ }
+ }
+
+ int id = m_matches[uid_];
+#ifdef ENTREZ_TEST
+ KURL u = KURL::fromPathOrURL(QString::fromLatin1("/home/robby/pubmed.xml"));
+#else
+ KURL u(QString::fromLatin1(ENTREZ_BASE_URL));
+ u.addPath(QString::fromLatin1(ENTREZ_FETCH_CGI));
+ u.addQueryItem(QString::fromLatin1("tool"), QString::fromLatin1("Tellico"));
+ u.addQueryItem(QString::fromLatin1("retmode"), QString::fromLatin1("xml"));
+ u.addQueryItem(QString::fromLatin1("rettype"), QString::fromLatin1("abstract"));
+ u.addQueryItem(QString::fromLatin1("db"), m_dbname);
+ u.addQueryItem(QString::fromLatin1("id"), QString::number(id));
+#endif
+ // now it's sychronous, and we know that it's utf8
+ QString xmlOutput = FileHandler::readTextFile(u, false /*quiet*/, true /*utf8*/);
+ if(xmlOutput.isEmpty()) {
+ kdWarning() << "EntrezFetcher::fetchEntry() - unable to download " << u << endl;
+ return 0;
+ }
+#if 0
+ kdWarning() << "EntrezFetcher::fetchEntry() - turn me off!" << endl;
+ QFile f1(QString::fromLatin1("/tmp/test-entry.xml"));
+ if(f1.open(IO_WriteOnly)) {
+ QTextStream t(&f1);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << xmlOutput;
+ }
+ f1.close();
+#endif
+ QString str = m_xsltHandler->applyStylesheet(xmlOutput);
+ Import::TellicoImporter imp(str);
+ Data::CollPtr coll = imp.collection();
+ if(!coll) {
+ kdWarning() << "EntrezFetcher::fetchEntry() - invalid collection" << endl;
+ return 0;
+ }
+ if(coll->entryCount() == 0) {
+ myDebug() << "EntrezFetcher::fetchEntry() - no entries in collection" << endl;
+ return 0;
+ } else if(coll->entryCount() > 1) {
+ myDebug() << "EntrezFetcher::fetchEntry() - collection has multiple entries, taking first one" << endl;
+ }
+
+ Data::EntryPtr e = coll->entries().front();
+
+ // try to get a link, but only if necessary
+ if(m_fields.contains(QString::fromLatin1("url"))) {
+ KURL link(QString::fromLatin1(ENTREZ_BASE_URL));
+ link.addPath(QString::fromLatin1(ENTREZ_LINK_CGI));
+ link.addQueryItem(QString::fromLatin1("tool"), QString::fromLatin1("Tellico"));
+ link.addQueryItem(QString::fromLatin1("cmd"), QString::fromLatin1("llinks"));
+ link.addQueryItem(QString::fromLatin1("db"), m_dbname);
+ link.addQueryItem(QString::fromLatin1("dbfrom"), m_dbname);
+ link.addQueryItem(QString::fromLatin1("id"), QString::number(id));
+
+ QDomDocument linkDom = FileHandler::readXMLFile(link, false /* namespace */, true /* quiet */);
+ // need eLinkResult/LinkSet/IdUrlList/IdUrlSet/ObjUrl/Url
+ QDomNode linkNode = linkDom.namedItem(QString::fromLatin1("eLinkResult"))
+ .namedItem(QString::fromLatin1("LinkSet"))
+ .namedItem(QString::fromLatin1("IdUrlList"))
+ .namedItem(QString::fromLatin1("IdUrlSet"))
+ .namedItem(QString::fromLatin1("ObjUrl"))
+ .namedItem(QString::fromLatin1("Url"));
+ if(!linkNode.isNull()) {
+ QString u = linkNode.toElement().text();
+// myDebug() << u << endl;
+ if(!u.isEmpty()) {
+ if(!coll->hasField(QString::fromLatin1("url"))) {
+ Data::FieldPtr field = new Data::Field(QString::fromLatin1("url"), i18n("URL"), Data::Field::URL);
+ field->setCategory(i18n("Miscellaneous"));
+ coll->addField(field);
+ }
+ e->setField(QString::fromLatin1("url"), u);
+ }
+ }
+ }
+
+ const StringMap customFields = EntrezFetcher::customFields();
+ for(StringMap::ConstIterator it = customFields.begin(); it != customFields.end(); ++it) {
+ if(!m_fields.contains(it.key())) {
+ coll->removeField(it.key());
+ }
+ }
+
+ m_entries.insert(uid_, e);
+ return e;
+}
+
+void EntrezFetcher::initXSLTHandler() {
+ QString xsltfile = locate("appdata", QString::fromLatin1("pubmed2tellico.xsl"));
+ if(xsltfile.isEmpty()) {
+ kdWarning() << "EntrezFetcher::initXSLTHandler() - can not locate pubmed2tellico.xsl." << endl;
+ return;
+ }
+
+ KURL u;
+ u.setPath(xsltfile);
+
+ if(!m_xsltHandler) {
+ m_xsltHandler = new XSLTHandler(u);
+ }
+ if(!m_xsltHandler->isValid()) {
+ kdWarning() << "EntrezFetcher::initXSLTHandler() - error in pubmed2tellico.xsl." << endl;
+ delete m_xsltHandler;
+ m_xsltHandler = 0;
+ return;
+ }
+}
+
+void EntrezFetcher::updateEntry(Data::EntryPtr entry_) {
+// myDebug() << "EntrezFetcher::updateEntry()" << endl;
+ QString s = entry_->field(QString::fromLatin1("pmid"));
+ if(!s.isEmpty()) {
+ search(PubmedID, s);
+ return;
+ }
+
+ s = entry_->field(QString::fromLatin1("doi"));
+ if(!s.isEmpty()) {
+ search(DOI, s);
+ return;
+ }
+
+ s = entry_->field(QString::fromLatin1("title"));
+ if(!s.isEmpty()) {
+ search(Title, s);
+ return;
+ }
+
+ myDebug() << "EntrezFetcher::updateEntry() - insufficient info to search" << endl;
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+Tellico::Fetch::ConfigWidget* EntrezFetcher::configWidget(QWidget* parent_) const {
+ return new EntrezFetcher::ConfigWidget(parent_, this);
+}
+
+EntrezFetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const EntrezFetcher* fetcher_/*=0*/)
+ : Fetch::ConfigWidget(parent_) {
+ QVBoxLayout* l = new QVBoxLayout(optionsWidget());
+ l->addWidget(new QLabel(i18n("This source has no options."), optionsWidget()));
+ l->addStretch();
+
+ // now add additional fields widget
+ addFieldsWidget(EntrezFetcher::customFields(), fetcher_ ? fetcher_->m_fields : QStringList());
+}
+
+void EntrezFetcher::ConfigWidget::saveConfig(KConfigGroup& config_) {
+ saveFieldsConfig(config_);
+ slotSetModified(false);
+}
+
+QString EntrezFetcher::ConfigWidget::preferredName() const {
+ return EntrezFetcher::defaultName();
+}
+
+//static
+Tellico::StringMap EntrezFetcher::customFields() {
+ StringMap map;
+ map[QString::fromLatin1("institution")] = i18n("Institution");
+ map[QString::fromLatin1("abstract")] = i18n("Abstract");
+ map[QString::fromLatin1("url")] = i18n("URL");
+ return map;
+}
+
+#include "entrezfetcher.moc"
diff --git a/src/fetch/entrezfetcher.h b/src/fetch/entrezfetcher.h
new file mode 100644
index 0000000..c8aac49
--- /dev/null
+++ b/src/fetch/entrezfetcher.h
@@ -0,0 +1,113 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_ENTREZFETCHER_H
+#define TELLICO_ENTREZFETCHER_H
+
+namespace Tellico {
+ class XSLTHandler;
+}
+
+#include "fetcher.h"
+#include "configwidget.h"
+#include "../datavectors.h"
+
+#include <qcstring.h> // for QByteArray
+#include <qguardedptr.h>
+
+namespace KIO {
+ class Job;
+}
+
+namespace Tellico {
+ namespace Fetch {
+
+/**
+ * @author Robby Stephenson
+ */
+class EntrezFetcher : public Fetcher {
+Q_OBJECT
+
+public:
+ EntrezFetcher(QObject* parent, const char* name=0);
+ /**
+ */
+ virtual ~EntrezFetcher();
+
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ // pubmed can search title, person, and keyword
+ virtual bool canSearch(FetchKey k) const { return k == Title || k == Person || k == Keyword || k == Raw || k == PubmedID || k == DOI; }
+ virtual void search(FetchKey key, const QString& value);
+ virtual void continueSearch();
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return Entrez; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+ virtual void updateEntry(Data::EntryPtr entry);
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const;
+
+ static StringMap customFields();
+
+ class ConfigWidget : public Fetch::ConfigWidget {
+ public:
+ ConfigWidget(QWidget* parent_, const EntrezFetcher* fetcher=0);
+ virtual void saveConfig(KConfigGroup& config);
+ virtual QString preferredName() const;
+ };
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+private slots:
+ void slotData(KIO::Job* job, const QByteArray& data);
+ void slotComplete(KIO::Job* job);
+
+private:
+ void initXSLTHandler();
+ void doSummary();
+
+ void searchResults();
+ void summaryResults();
+
+ enum Step {
+ Begin,
+ Search,
+ Summary,
+ Fetch
+ };
+
+ XSLTHandler* m_xsltHandler;
+ QString m_dbname;
+
+ int m_start;
+ int m_total;
+
+ QByteArray m_data;
+ QMap<int, Data::EntryPtr> m_entries; // map from search result id to entry
+ QMap<int, int> m_matches; // search result id to pubmed id
+ QGuardedPtr<KIO::Job> m_job;
+
+ QString m_queryKey;
+ QString m_webEnv;
+ Step m_step;
+
+ bool m_started;
+ QStringList m_fields;
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/fetch/execexternalfetcher.cpp b/src/fetch/execexternalfetcher.cpp
new file mode 100644
index 0000000..07b99d8
--- /dev/null
+++ b/src/fetch/execexternalfetcher.cpp
@@ -0,0 +1,561 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "execexternalfetcher.h"
+#include "messagehandler.h"
+#include "fetchmanager.h"
+#include "../collection.h"
+#include "../entry.h"
+#include "../importdialog.h"
+#include "../translators/tellicoimporter.h"
+#include "../tellico_debug.h"
+#include "../gui/combobox.h"
+#include "../gui/lineedit.h"
+#include "../gui/collectiontypecombo.h"
+#include "../tellico_utils.h"
+#include "../newstuff/manager.h"
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kprocess.h>
+#include <kurlrequester.h>
+#include <kaccelmanager.h>
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qwhatsthis.h>
+#include <qregexp.h>
+#include <qvgroupbox.h>
+#include <qfile.h> // needed for QFile::remove
+
+using Tellico::Fetch::ExecExternalFetcher;
+
+QStringList ExecExternalFetcher::parseArguments(const QString& str_) {
+ // matching escaped quotes is too hard... :(
+// QRegExp quotes(QString::fromLatin1("[^\\\\](['\"])(.*[^\\\\])\\1"));
+ QRegExp quotes(QString::fromLatin1("(['\"])(.*)\\1"));
+ quotes.setMinimal(true);
+ QRegExp spaces(QString::fromLatin1("\\s+"));
+ spaces.setMinimal(true);
+
+ QStringList args;
+ int pos = 0;
+ for(int nextPos = quotes.search(str_); nextPos > -1; pos = nextPos+1, nextPos = quotes.search(str_, pos)) {
+ // a non-quotes arguments runs from pos to nextPos
+ args += QStringList::split(spaces, str_.mid(pos, nextPos-pos));
+ // move nextpos marker to end of match
+ pos = quotes.pos(2); // skip quotation mark
+ nextPos += quotes.matchedLength();
+ args += str_.mid(pos, nextPos-pos-1);
+ }
+ // catch the end stuff
+ args += QStringList::split(spaces, str_.mid(pos));
+
+#if 0
+ for(QStringList::ConstIterator it = args.begin(); it != args.end(); ++it) {
+ myDebug() << *it << endl;
+ }
+#endif
+
+ return args;
+}
+
+ExecExternalFetcher::ExecExternalFetcher(QObject* parent_, const char* name_/*=0*/) : Fetcher(parent_, name_),
+ m_started(false), m_collType(-1), m_formatType(-1), m_canUpdate(false), m_process(0), m_deleteOnRemove(false) {
+}
+
+ExecExternalFetcher::~ExecExternalFetcher() {
+ stop();
+}
+
+QString ExecExternalFetcher::defaultName() {
+ return i18n("External Application");
+}
+
+QString ExecExternalFetcher::source() const {
+ return m_name;
+}
+
+bool ExecExternalFetcher::canFetch(int type_) const {
+ return m_collType == -1 ? false : m_collType == type_;
+}
+
+void ExecExternalFetcher::readConfigHook(const KConfigGroup& config_) {
+ QString s = config_.readPathEntry("ExecPath");
+ if(!s.isEmpty()) {
+ m_path = s;
+ }
+ QValueList<int> il;
+ if(config_.hasKey("ArgumentKeys")) {
+ il = config_.readIntListEntry("ArgumentKeys");
+ } else {
+ il.append(Keyword);
+ }
+ QStringList sl = config_.readListEntry("Arguments");
+ if(il.count() != sl.count()) {
+ kdWarning() << "ExecExternalFetcher::readConfig() - unequal number of arguments and keys" << endl;
+ }
+ int n = QMIN(il.count(), sl.count());
+ for(int i = 0; i < n; ++i) {
+ m_args[static_cast<FetchKey>(il[i])] = sl[i];
+ }
+ if(config_.hasKey("UpdateArgs")) {
+ m_canUpdate = true;
+ m_updateArgs = config_.readEntry("UpdateArgs");
+ } else {
+ m_canUpdate = false;
+ }
+ m_collType = config_.readNumEntry("CollectionType", -1);
+ m_formatType = config_.readNumEntry("FormatType", -1);
+ m_deleteOnRemove = config_.readBoolEntry("DeleteOnRemove", false);
+ m_newStuffName = config_.readEntry("NewStuffName");
+}
+
+void ExecExternalFetcher::search(FetchKey key_, const QString& value_) {
+ m_started = true;
+
+ if(!m_args.contains(key_)) {
+ stop();
+ return;
+ }
+
+ // should KProcess::quote() be used?
+ // %1 gets replaced by the search value, but since the arguments are going to be split
+ // the search value needs to be enclosed in quotation marks
+ // but first check to make sure the user didn't do that already
+ // AND the "%1" wasn't used in the settings
+ QString value = value_;
+ if(key_ == ISBN) {
+ value.remove('-'); // remove hyphens from isbn values
+ // shouldn't hurt and might keep from confusing stupid search sources
+ }
+ QRegExp rx1(QString::fromLatin1("['\"].*\\1"));
+ if(!rx1.exactMatch(value)) {
+ value.prepend('"').append('"');
+ }
+ QString args = m_args[key_];
+ QRegExp rx2(QString::fromLatin1("['\"]%1\\1"));
+ args.replace(rx2, QString::fromLatin1("%1"));
+ startSearch(parseArguments(args.arg(value))); // replace %1 with search value
+}
+
+void ExecExternalFetcher::startSearch(const QStringList& args_) {
+ if(m_path.isEmpty()) {
+ stop();
+ return;
+ }
+
+#if 0
+ myDebug() << m_path << endl;
+ for(QStringList::ConstIterator it = args_.begin(); it != args_.end(); ++it) {
+ myDebug() << " " << *it << endl;
+ }
+#endif
+
+ m_process = new KProcess();
+ connect(m_process, SIGNAL(receivedStdout(KProcess*, char*, int)), SLOT(slotData(KProcess*, char*, int)));
+ connect(m_process, SIGNAL(receivedStderr(KProcess*, char*, int)), SLOT(slotError(KProcess*, char*, int)));
+ connect(m_process, SIGNAL(processExited(KProcess*)), SLOT(slotProcessExited(KProcess*)));
+ *m_process << m_path << args_;
+ if(!m_process->start(KProcess::NotifyOnExit, KProcess::AllOutput)) {
+ myDebug() << "ExecExternalFetcher::startSearch() - process failed to start" << endl;
+ stop();
+ }
+}
+
+void ExecExternalFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+ if(m_process) {
+ m_process->kill();
+ delete m_process;
+ m_process = 0;
+ }
+ m_data.truncate(0);
+ m_started = false;
+ m_errors.clear();
+ emit signalDone(this);
+}
+
+void ExecExternalFetcher::slotData(KProcess*, char* buffer_, int len_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(buffer_, len_);
+}
+
+void ExecExternalFetcher::slotError(KProcess*, char* buffer_, int len_) {
+ GUI::CursorSaver cs(Qt::arrowCursor);
+ QString msg = QString::fromLocal8Bit(buffer_, len_);
+ msg.prepend(source() + QString::fromLatin1(": "));
+ if(msg.endsWith(QChar('\n'))) {
+ msg.truncate(msg.length()-1);
+ }
+ myDebug() << "ExecExternalFetcher::slotError() - " << msg << endl;
+ m_errors << msg;
+}
+
+void ExecExternalFetcher::slotProcessExited(KProcess*) {
+// myDebug() << "ExecExternalFetcher::slotProcessExited()" << endl;
+ if(!m_process->normalExit() || m_process->exitStatus()) {
+ myDebug() << "ExecExternalFetcher::slotProcessExited() - "<< source() << ": process did not exit successfully" << endl;
+ if(!m_errors.isEmpty()) {
+ message(m_errors.join(QChar('\n')), MessageHandler::Error);
+ }
+ stop();
+ return;
+ }
+ if(!m_errors.isEmpty()) {
+ message(m_errors.join(QChar('\n')), MessageHandler::Warning);
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "ExecExternalFetcher::slotProcessExited() - "<< source() << ": no data" << endl;
+ stop();
+ return;
+ }
+
+ Import::Format format = static_cast<Import::Format>(m_formatType > -1 ? m_formatType : Import::TellicoXML);
+ Import::Importer* imp = ImportDialog::importer(format, KURL::List());
+ if(!imp) {
+ stop();
+ return;
+ }
+
+ imp->setText(QString::fromUtf8(m_data, m_data.size()));
+ Data::CollPtr coll = imp->collection();
+ if(!coll) {
+ if(!imp->statusMessage().isEmpty()) {
+ message(imp->statusMessage(), MessageHandler::Status);
+ }
+ myDebug() << "ExecExternalFetcher::slotProcessExited() - "<< source() << ": no collection pointer" << endl;
+ delete imp;
+ stop();
+ return;
+ }
+
+ delete imp;
+ if(coll->entryCount() == 0) {
+// myDebug() << "ExecExternalFetcher::slotProcessExited() - no results" << endl;
+ stop();
+ return;
+ }
+
+ Data::EntryVec entries = coll->entries();
+ for(Data::EntryVec::Iterator entry = entries.begin(); entry != entries.end(); ++entry) {
+ QString desc;
+ switch(coll->type()) {
+ case Data::Collection::Book:
+ case Data::Collection::Bibtex:
+ desc = entry->field(QString::fromLatin1("author"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("publisher"));
+ if(!entry->field(QString::fromLatin1("cr_year")).isEmpty()) {
+ desc += QChar('/') + entry->field(QString::fromLatin1("cr_year"));
+ } else if(!entry->field(QString::fromLatin1("pub_year")).isEmpty()){
+ desc += QChar('/') + entry->field(QString::fromLatin1("pub_year"));
+ }
+ break;
+
+ case Data::Collection::Video:
+ desc = entry->field(QString::fromLatin1("studio"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("director"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("year"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("medium"));
+ break;
+
+ case Data::Collection::Album:
+ desc = entry->field(QString::fromLatin1("artist"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("label"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("year"));
+ break;
+
+ case Data::Collection::Game:
+ desc = entry->field(QString::fromLatin1("platform"));
+ break;
+
+ case Data::Collection::ComicBook:
+ desc = entry->field(QString::fromLatin1("publisher"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("pub_year"));
+ break;
+
+ case Data::Collection::BoardGame:
+ desc = entry->field(QString::fromLatin1("designer"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("publisher"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("year"));
+ break;
+
+ default:
+ break;
+ }
+ SearchResult* r = new SearchResult(this, entry->title(), desc, entry->field(QString::fromLatin1("isbn")));
+ m_entries.insert(r->uid, entry);
+ emit signalResultFound(r);
+ }
+ stop(); // be sure to call this
+}
+
+Tellico::Data::EntryPtr ExecExternalFetcher::fetchEntry(uint uid_) {
+ return m_entries[uid_];
+}
+
+void ExecExternalFetcher::updateEntry(Data::EntryPtr entry_) {
+ if(!m_canUpdate) {
+ emit signalDone(this); // must do this
+ }
+
+ m_started = true;
+
+ Data::ConstEntryPtr e(entry_.data());
+ QStringList args = parseArguments(m_updateArgs);
+ for(QStringList::Iterator it = args.begin(); it != args.end(); ++it) {
+ *it = Data::Entry::dependentValue(e, *it, false);
+ }
+ startSearch(args);
+}
+
+Tellico::Fetch::ConfigWidget* ExecExternalFetcher::configWidget(QWidget* parent_) const {
+ return new ExecExternalFetcher::ConfigWidget(parent_, this);
+}
+
+ExecExternalFetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const ExecExternalFetcher* fetcher_/*=0*/)
+ : Fetch::ConfigWidget(parent_), m_deleteOnRemove(false) {
+ QGridLayout* l = new QGridLayout(optionsWidget(), 5, 2);
+ l->setSpacing(4);
+ l->setColStretch(1, 10);
+
+ int row = -1;
+
+ QLabel* label = new QLabel(i18n("Collection &type:"), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_collCombo = new GUI::CollectionTypeCombo(optionsWidget());
+ connect(m_collCombo, SIGNAL(activated(int)), SLOT(slotSetModified()));
+ l->addWidget(m_collCombo, row, 1);
+ QString w = i18n("Set the collection type of the data returned from the external application.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_collCombo, w);
+ label->setBuddy(m_collCombo);
+
+ label = new QLabel(i18n("&Result type: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_formatCombo = new GUI::ComboBox(optionsWidget());
+ Import::FormatMap formatMap = ImportDialog::formatMap();
+ for(Import::FormatMap::Iterator it = formatMap.begin(); it != formatMap.end(); ++it) {
+ if(ImportDialog::formatImportsText(it.key())) {
+ m_formatCombo->insertItem(it.data(), it.key());
+ }
+ }
+ connect(m_formatCombo, SIGNAL(activated(int)), SLOT(slotSetModified()));
+ l->addWidget(m_formatCombo, row, 1);
+ w = i18n("Set the result type of the data returned from the external application.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_formatCombo, w);
+ label->setBuddy(m_formatCombo);
+
+ label = new QLabel(i18n("Application &path: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_pathEdit = new KURLRequester(optionsWidget());
+ connect(m_pathEdit, SIGNAL(textChanged(const QString&)), SLOT(slotSetModified()));
+ l->addWidget(m_pathEdit, row, 1);
+ w = i18n("Set the path of the application to run that should output a valid Tellico data file.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_pathEdit, w);
+ label->setBuddy(m_pathEdit);
+
+ w = i18n("Select the search keys supported by the data source.");
+ QString w2 = i18n("Add any arguments that may be needed. <b>%1</b> will be replaced by the search term.");
+ QVGroupBox* box = new QVGroupBox(i18n("Arguments"), optionsWidget());
+ ++row;
+ l->addMultiCellWidget(box, row, row, 0, 1);
+ QWidget* grid = new QWidget(box);
+ QGridLayout* gridLayout = new QGridLayout(grid);
+ gridLayout->setSpacing(2);
+ row = -1;
+ const Fetch::KeyMap keyMap = Fetch::Manager::self()->keyMap();
+ for(Fetch::KeyMap::ConstIterator it = keyMap.begin(); it != keyMap.end(); ++it) {
+ FetchKey key = it.key();
+ if(key == Raw) {
+ continue;
+ }
+ QCheckBox* cb = new QCheckBox(it.data(), grid);
+ gridLayout->addWidget(cb, ++row, 0);
+ m_cbDict.insert(key, cb);
+ GUI::LineEdit* le = new GUI::LineEdit(grid);
+ le->setHint(QString::fromLatin1("%1")); // for example
+ le->completionObject()->addItem(QString::fromLatin1("%1"));
+ gridLayout->addWidget(le, row, 1);
+ m_leDict.insert(key, le);
+ if(fetcher_ && fetcher_->m_args.contains(key)) {
+ cb->setChecked(true);
+ le->setEnabled(true);
+ le->setText(fetcher_->m_args[key]);
+ } else {
+ cb->setChecked(false);
+ le->setEnabled(false);
+ }
+ connect(cb, SIGNAL(toggled(bool)), le, SLOT(setEnabled(bool)));
+ QWhatsThis::add(cb, w);
+ QWhatsThis::add(le, w2);
+ }
+ m_cbUpdate = new QCheckBox(i18n("Update"), grid);
+ gridLayout->addWidget(m_cbUpdate, ++row, 0);
+ m_leUpdate = new GUI::LineEdit(grid);
+ m_leUpdate->setHint(QString::fromLatin1("%{title}")); // for example
+ m_leUpdate->completionObject()->addItem(QString::fromLatin1("%{title}"));
+ m_leUpdate->completionObject()->addItem(QString::fromLatin1("%{isbn}"));
+ gridLayout->addWidget(m_leUpdate, row, 1);
+ /* TRANSLATORS: Do not translate %{author}. */
+ w2 = i18n("<p>Enter the arguments which should be used to search for available updates to an entry.</p><p>"
+ "The format is the same as for <i>Dependent</i> fields, where field values "
+ "are contained inside braces, such as <i>%{author}</i>. See the documentation for details.</p>");
+ QWhatsThis::add(m_cbUpdate, w);
+ QWhatsThis::add(m_leUpdate, w2);
+ if(fetcher_ && fetcher_->m_canUpdate) {
+ m_cbUpdate->setChecked(true);
+ m_leUpdate->setEnabled(true);
+ m_leUpdate->setText(fetcher_->m_updateArgs);
+ } else {
+ m_cbUpdate->setChecked(false);
+ m_leUpdate->setEnabled(false);
+ }
+ connect(m_cbUpdate, SIGNAL(toggled(bool)), m_leUpdate, SLOT(setEnabled(bool)));
+
+ l->setRowStretch(++row, 1);
+
+ if(fetcher_) {
+ m_pathEdit->setURL(fetcher_->m_path);
+ m_newStuffName = fetcher_->m_newStuffName;
+ }
+ if(fetcher_ && fetcher_->m_collType > -1) {
+ m_collCombo->setCurrentType(fetcher_->m_collType);
+ } else {
+ m_collCombo->setCurrentType(Data::Collection::Book);
+ }
+ if(fetcher_ && fetcher_->m_formatType > -1) {
+ m_formatCombo->setCurrentItem(formatMap[static_cast<Import::Format>(fetcher_->m_formatType)]);
+ } else {
+ m_formatCombo->setCurrentItem(formatMap[Import::TellicoXML]);
+ }
+ m_deleteOnRemove = fetcher_ && fetcher_->m_deleteOnRemove;
+ KAcceleratorManager::manage(optionsWidget());
+}
+
+ExecExternalFetcher::ConfigWidget::~ConfigWidget() {
+}
+
+void ExecExternalFetcher::ConfigWidget::readConfig(KConfig* config_) {
+ m_pathEdit->setURL(config_->readPathEntry("ExecPath"));
+ QValueList<int> argKeys = config_->readIntListEntry("ArgumentKeys");
+ QStringList argValues = config_->readListEntry("Arguments");
+ if(argKeys.count() != argValues.count()) {
+ kdWarning() << "ExecExternalFetcher::ConfigWidget::readConfig() - unequal number of arguments and keys" << endl;
+ }
+ int n = QMIN(argKeys.count(), argValues.count());
+ QMap<FetchKey, QString> args;
+ for(int i = 0; i < n; ++i) {
+ args[static_cast<FetchKey>(argKeys[i])] = argValues[i];
+ }
+ for(QValueList<int>::Iterator it = argKeys.begin(); it != argKeys.end(); ++it) {
+ if(*it == Raw) {
+ continue;
+ }
+ FetchKey key = static_cast<FetchKey>(*it);
+ QCheckBox* cb = m_cbDict[key];
+ KLineEdit* le = m_leDict[key];
+ if(cb && le) {
+ if(args.contains(key)) {
+ cb->setChecked(true);
+ le->setEnabled(true);
+ le->setText(args[key]);
+ } else {
+ cb->setChecked(false);
+ le->setEnabled(false);
+ le->clear();
+ }
+ }
+ }
+
+ if(config_->hasKey("UpdateArgs")) {
+ m_cbUpdate->setChecked(true);
+ m_leUpdate->setEnabled(true);
+ m_leUpdate->setText(config_->readEntry("UpdateArgs"));
+ } else {
+ m_cbUpdate->setChecked(false);
+ m_leUpdate->setEnabled(false);
+ m_leUpdate->clear();
+ }
+
+ int collType = config_->readNumEntry("CollectionType");
+ m_collCombo->setCurrentType(collType);
+
+ Import::FormatMap formatMap = ImportDialog::formatMap();
+ int formatType = config_->readNumEntry("FormatType");
+ m_formatCombo->setCurrentItem(formatMap[static_cast<Import::Format>(formatType)]);
+ m_deleteOnRemove = config_->readBoolEntry("DeleteOnRemove", false);
+ m_name = config_->readEntry("Name");
+ m_newStuffName = config_->readEntry("NewStuffName");
+}
+
+void ExecExternalFetcher::ConfigWidget::saveConfig(KConfigGroup& config_) {
+ QString s = m_pathEdit->url();
+ if(!s.isEmpty()) {
+ config_.writePathEntry("ExecPath", s);
+ }
+ QValueList<int> keys;
+ QStringList args;
+ for(QIntDictIterator<QCheckBox> it(m_cbDict); it.current(); ++it) {
+ if(it.current()->isChecked()) {
+ keys << it.currentKey();
+ args << m_leDict[it.currentKey()]->text();
+ }
+ }
+ config_.writeEntry("ArgumentKeys", keys);
+ config_.writeEntry("Arguments", args);
+
+ if(m_cbUpdate->isChecked()) {
+ config_.writeEntry("UpdateArgs", m_leUpdate->text());
+ } else {
+ config_.deleteEntry("UpdateArgs");
+ }
+
+ config_.writeEntry("CollectionType", m_collCombo->currentType());
+ config_.writeEntry("FormatType", m_formatCombo->currentData().toInt());
+ config_.writeEntry("DeleteOnRemove", m_deleteOnRemove);
+ if(!m_newStuffName.isEmpty()) {
+ config_.writeEntry("NewStuffName", m_newStuffName);
+ }
+ slotSetModified(false);
+}
+
+void ExecExternalFetcher::ConfigWidget::removed() {
+ if(!m_deleteOnRemove) {
+ return;
+ }
+ if(!m_newStuffName.isEmpty()) {
+ NewStuff::Manager man(this);
+ man.removeScript(m_newStuffName);
+ }
+}
+
+QString ExecExternalFetcher::ConfigWidget::preferredName() const {
+ return m_name.isEmpty() ? ExecExternalFetcher::defaultName() : m_name;
+}
+
+#include "execexternalfetcher.moc"
diff --git a/src/fetch/execexternalfetcher.h b/src/fetch/execexternalfetcher.h
new file mode 100644
index 0000000..bdc2a40
--- /dev/null
+++ b/src/fetch/execexternalfetcher.h
@@ -0,0 +1,118 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_EXECEXTERNALFETCHER_H
+#define TELLICO_EXECEXTERNALFETCHER_H
+
+#include "fetcher.h"
+#include "configwidget.h"
+#include "../datavectors.h"
+
+#include <qintdict.h>
+
+class KProcess;
+class KURLRequester;
+class KLineEdit;
+class KComboBox;
+
+class QCheckBox;
+
+namespace Tellico {
+ namespace GUI {
+ class ComboBox;
+ class LineEdit;
+ class CollectionTypeCombo;
+ }
+ namespace Fetch {
+
+/**
+ * @author Robby Stephenson
+ */
+class ExecExternalFetcher : public Fetcher {
+Q_OBJECT
+
+public:
+ ExecExternalFetcher(QObject* parent, const char* name=0);
+ /**
+ */
+ virtual ~ExecExternalFetcher();
+
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual bool canSearch(FetchKey k) const { return m_args.contains(k); }
+ virtual bool canUpdate() const { return m_canUpdate; }
+ virtual void search(FetchKey key, const QString& value);
+ virtual void updateEntry(Data::EntryPtr entry);
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return ExecExternal; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const;
+
+ const QString& execPath() const { return m_path; }
+
+ class ConfigWidget : public Fetch::ConfigWidget {
+ public:
+ ConfigWidget(QWidget* parent = 0, const ExecExternalFetcher* fetcher = 0);
+ ~ConfigWidget();
+
+ void readConfig(KConfig* config);
+ virtual void saveConfig(KConfigGroup& config);
+ virtual void removed();
+ virtual QString preferredName() const;
+
+ private:
+ bool m_deleteOnRemove : 1;
+ QString m_name, m_newStuffName;
+ KURLRequester* m_pathEdit;
+ GUI::CollectionTypeCombo* m_collCombo;
+ GUI::ComboBox* m_formatCombo;
+ QIntDict<QCheckBox> m_cbDict;
+ QIntDict<GUI::LineEdit> m_leDict;
+ QCheckBox* m_cbUpdate;
+ GUI::LineEdit* m_leUpdate;
+ };
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+private slots:
+ void slotData(KProcess* proc, char* buffer, int len);
+ void slotError(KProcess* proc, char* buffer, int len);
+ void slotProcessExited(KProcess* proc);
+
+private:
+ static QStringList parseArguments(const QString& str);
+
+ void startSearch(const QStringList& args);
+
+ bool m_started;
+ int m_collType;
+ int m_formatType;
+ QString m_path;
+ QMap<FetchKey, QString> m_args;
+ bool m_canUpdate : 1;
+ QString m_updateArgs;
+ KProcess* m_process;
+ QByteArray m_data;
+ QMap<int, Data::EntryPtr> m_entries; // map from search result id to entry
+ QStringList m_errors;
+ bool m_deleteOnRemove : 1;
+ QString m_newStuffName;
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/fetch/fetch.h b/src/fetch/fetch.h
new file mode 100644
index 0000000..0cdb726
--- /dev/null
+++ b/src/fetch/fetch.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FETCH_H
+#define TELLICO_FETCH_H
+
+namespace Tellico {
+ namespace Fetch {
+
+/**
+ * FetchFirst must be first, and the rest must follow consecutively in value.
+ * FetchLast must be last!
+ */
+enum FetchKey {
+ FetchFirst = 0,
+ Title,
+ Person,
+ ISBN,
+ UPC,
+ Keyword,
+ DOI,
+ ArxivID,
+ PubmedID,
+ LCCN,
+ Raw,
+ FetchLast
+};
+
+// real ones must start at 0!
+enum Type {
+ Unknown = -1,
+ Amazon = 0,
+ IMDB,
+ Z3950,
+ SRU,
+ Entrez,
+ ExecExternal,
+ Yahoo,
+ AnimeNfo,
+ IBS,
+ ISBNdb,
+ GCstarPlugin,
+ CrossRef,
+ Citebase,
+ Arxiv,
+ Bibsonomy,
+ GoogleScholar,
+ Discogs
+};
+
+ }
+}
+
+#endif
diff --git a/src/fetch/fetcher.cpp b/src/fetch/fetcher.cpp
new file mode 100644
index 0000000..3bc7749
--- /dev/null
+++ b/src/fetch/fetcher.cpp
@@ -0,0 +1,61 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "fetcher.h"
+#include "messagehandler.h"
+#include "../entry.h"
+
+#include <kglobal.h>
+#include <kconfig.h>
+
+using Tellico::Fetch::Fetcher;
+using Tellico::Fetch::SearchResult;
+
+Fetcher::~Fetcher() {
+ KConfigGroup config(KGlobal::config(), m_configGroup);
+ saveConfigHook(config);
+}
+
+void Fetcher::readConfig(const KConfigGroup& config_, const QString& groupName_) {
+ m_configGroup = groupName_;
+
+ QString s = config_.readEntry("Name");
+ if(!s.isEmpty()) {
+ m_name = s;
+ }
+ m_updateOverwrite = config_.readBoolEntry("UpdateOverwrite", false);
+ // be sure to read config for subclass
+ readConfigHook(config_);
+}
+
+void Fetcher::message(const QString& message_, int type_) const {
+ if(m_messager) {
+ m_messager->send(message_, static_cast<MessageHandler::Type>(type_));
+ }
+}
+
+void Fetcher::infoList(const QString& message_, const QStringList& list_) const {
+ if(m_messager) {
+ m_messager->infoList(message_, list_);
+ }
+}
+
+void Fetcher::updateEntry(Data::EntryPtr) {
+ emit signalDone(this);
+}
+
+Tellico::Data::EntryPtr SearchResult::fetchEntry() {
+ return fetcher->fetchEntry(uid);
+}
+
+#include "fetcher.moc"
diff --git a/src/fetch/fetcher.h b/src/fetch/fetcher.h
new file mode 100644
index 0000000..0d2496e
--- /dev/null
+++ b/src/fetch/fetcher.h
@@ -0,0 +1,151 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef FETCHER_H
+#define FETCHER_H
+
+#include "fetch.h"
+#include "../datavectors.h"
+
+#include <kapplication.h> // for KApplication::random()
+
+#include <qobject.h>
+#include <qstring.h>
+
+class KConfigGroup;
+
+namespace Tellico {
+ namespace Fetch {
+ class ConfigWidget;
+ class MessageHandler;
+ class SearchResult;
+
+/**
+ * The top-level abstract class for fetching data.
+ *
+ * @author Robby Stephenson
+ */
+class Fetcher : public QObject, public KShared {
+Q_OBJECT
+
+public:
+ typedef KSharedPtr<Fetcher> Ptr;
+ typedef KSharedPtr<const Fetcher> CPtr;
+
+ /**
+ */
+ Fetcher(QObject* parent, const char* name = 0) : QObject(parent, name), KShared(),
+ m_updateOverwrite(false), m_hasMoreResults(false),
+ m_messager(0) {}
+ /**
+ */
+ virtual ~Fetcher();
+
+ /**
+ * Returns true if the fetcher might return entries from a certain collection type.
+ */
+ virtual bool canFetch(int type) const = 0;
+ /**
+ * Returns true if the fetcher can search using a certain key.
+ */
+ virtual bool canSearch(FetchKey key) const = 0;
+ virtual bool canUpdate() const { return true; }
+
+ /**
+ * Returns the type of the data source.
+ */
+ virtual Type type() const = 0;
+ /**
+ * Returns the name of the data source, as defined by the user.
+ */
+ virtual QString source() const = 0;
+ /**
+ * Returns whether the fetcher will overwite existing info when updating
+ */
+ bool updateOverwrite() const { return m_updateOverwrite; }
+ /**
+ * Starts a search, using a key and value.
+ */
+ virtual void search(FetchKey key, const QString& value) = 0;
+ virtual void continueSearch() {}
+ virtual void updateEntry(Data::EntryPtr);
+ // mopst fetchers won't support this. it's particular useful for text fetchers
+ virtual void updateEntrySynchronous(Data::EntryPtr) {}
+ /**
+ * Returns true if the fetcher is currently searching.
+ */
+ virtual bool isSearching() const = 0;
+ /**
+ * Returns true if the fetcher can continue and fetch more results
+ * The fetcher is responsible for remembering state.
+ */
+ virtual bool hasMoreResults() const { return m_hasMoreResults; }
+ /**
+ * Stops the fetcher.
+ */
+ virtual void stop() = 0;
+ /**
+ * Fetches an entry, given the uid of the search result.
+ */
+ virtual Data::EntryPtr fetchEntry(uint uid) = 0;
+
+ void setMessageHandler(MessageHandler* handler) { m_messager = handler; }
+ MessageHandler* messageHandler() const { return m_messager; }
+ /**
+ */
+ void message(const QString& message, int type) const;
+ void infoList(const QString& message, const QStringList& list) const;
+
+ /**
+ * Reads the config for the widget, given a config group.
+ */
+ void readConfig(const KConfigGroup& config, const QString& groupName);
+ /**
+ * Returns a widget for modifying the fetcher's config.
+ */
+ virtual ConfigWidget* configWidget(QWidget* parent) const = 0;
+
+signals:
+// void signalStatus(const QString& status);
+ void signalResultFound(Tellico::Fetch::SearchResult* result);
+ void signalDone(Tellico::Fetch::Fetcher::Ptr);
+
+protected:
+ QString m_name;
+ bool m_updateOverwrite : 1;
+ bool m_hasMoreResults : 1;
+
+private:
+ virtual void readConfigHook(const KConfigGroup&) = 0;
+ virtual void saveConfigHook(KConfigGroup&) {}
+
+ MessageHandler* m_messager;
+ QString m_configGroup;
+};
+
+class SearchResult {
+public:
+ SearchResult(Fetcher::Ptr f, const QString& t, const QString& d, const QString& i)
+ : uid(KApplication::random()), fetcher(f), title(t), desc(d), isbn(i) {}
+ Data::EntryPtr fetchEntry();
+ uint uid;
+ Fetcher::Ptr fetcher;
+ QString title;
+ QString desc;
+ QString isbn;
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/fetch/fetchmanager.cpp b/src/fetch/fetchmanager.cpp
new file mode 100644
index 0000000..84f4f39
--- /dev/null
+++ b/src/fetch/fetchmanager.cpp
@@ -0,0 +1,707 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include <config.h>
+
+#include "fetchmanager.h"
+#include "configwidget.h"
+#include "messagehandler.h"
+#include "../tellico_kernel.h"
+#include "../entry.h"
+#include "../collection.h"
+#include "../tellico_utils.h"
+#include "../tellico_debug.h"
+
+#ifdef AMAZON_SUPPORT
+#include "amazonfetcher.h"
+#endif
+#ifdef IMDB_SUPPORT
+#include "imdbfetcher.h"
+#endif
+#ifdef HAVE_YAZ
+#include "z3950fetcher.h"
+#endif
+#include "srufetcher.h"
+#include "entrezfetcher.h"
+#include "execexternalfetcher.h"
+#include "yahoofetcher.h"
+#include "animenfofetcher.h"
+#include "ibsfetcher.h"
+#include "isbndbfetcher.h"
+#include "gcstarpluginfetcher.h"
+#include "crossreffetcher.h"
+#include "arxivfetcher.h"
+#include "citebasefetcher.h"
+#include "bibsonomyfetcher.h"
+#include "googlescholarfetcher.h"
+#include "discogsfetcher.h"
+
+#include <kglobal.h>
+#include <kconfig.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kmimetype.h>
+#include <kstandarddirs.h>
+#include <dcopref.h>
+#include <ktempfile.h>
+#include <kio/netaccess.h>
+
+#include <qfileinfo.h>
+#include <qdir.h>
+
+#define LOAD_ICON(name, group, size) \
+ KGlobal::iconLoader()->loadIcon(name, static_cast<KIcon::Group>(group), size_)
+
+using Tellico::Fetch::Manager;
+Manager* Manager::s_self = 0;
+
+Manager::Manager() : QObject(), m_currentFetcherIndex(-1), m_messager(new ManagerMessage()),
+ m_count(0), m_loadDefaults(false) {
+ loadFetchers();
+
+// m_keyMap.insert(FetchFirst, QString::null);
+ m_keyMap.insert(Title, i18n("Title"));
+ m_keyMap.insert(Person, i18n("Person"));
+ m_keyMap.insert(ISBN, i18n("ISBN"));
+ m_keyMap.insert(UPC, i18n("UPC/EAN"));
+ m_keyMap.insert(Keyword, i18n("Keyword"));
+ m_keyMap.insert(DOI, i18n("DOI"));
+ m_keyMap.insert(ArxivID, i18n("arXiv ID"));
+ m_keyMap.insert(PubmedID, i18n("Pubmed ID"));
+ // to keep from having a new i18n string, just remove octothorpe
+ m_keyMap.insert(LCCN, i18n("LCCN#").remove('#'));
+ m_keyMap.insert(Raw, i18n("Raw Query"));
+// m_keyMap.insert(FetchLast, QString::null);
+}
+
+Manager::~Manager() {
+ delete m_messager;
+}
+
+void Manager::loadFetchers() {
+// myDebug() << "Manager::loadFetchers()" << endl;
+ m_fetchers.clear();
+ m_configMap.clear();
+
+ KConfig* config = KGlobal::config();
+ if(config->hasGroup(QString::fromLatin1("Data Sources"))) {
+ KConfigGroup configGroup(config, QString::fromLatin1("Data Sources"));
+ int nSources = configGroup.readNumEntry("Sources Count", 0);
+ for(int i = 0; i < nSources; ++i) {
+ QString group = QString::fromLatin1("Data Source %1").arg(i);
+ Fetcher::Ptr f = createFetcher(config, group);
+ if(f) {
+ m_configMap.insert(f, group);
+ m_fetchers.append(f);
+ f->setMessageHandler(m_messager);
+ }
+ }
+ m_loadDefaults = false;
+ } else { // add default sources
+ m_fetchers = defaultFetchers();
+ m_loadDefaults = true;
+ }
+}
+
+Tellico::Fetch::FetcherVec Manager::fetchers(int type_) {
+ FetcherVec vec;
+ for(FetcherVec::Iterator it = m_fetchers.begin(); it != m_fetchers.end(); ++it) {
+ if(it->canFetch(type_)) {
+ vec.append(it.data());
+ }
+ }
+ return vec;
+}
+
+Tellico::Fetch::KeyMap Manager::keyMap(const QString& source_) const {
+ // an empty string means return all
+ if(source_.isEmpty()) {
+ return m_keyMap;
+ }
+
+ // assume there's only one fetcher match
+ KSharedPtr<const Fetcher> f = 0;
+ for(FetcherVec::ConstIterator it = m_fetchers.constBegin(); it != m_fetchers.constEnd(); ++it) {
+ if(source_ == it->source()) {
+ f = it.data();
+ break;
+ }
+ }
+ if(!f) {
+ kdWarning() << "Manager::keyMap() - no fetcher found!" << endl;
+ return KeyMap();
+ }
+
+ KeyMap map;
+ for(KeyMap::ConstIterator it = m_keyMap.begin(); it != m_keyMap.end(); ++it) {
+ if(f->canSearch(it.key())) {
+ map.insert(it.key(), it.data());
+ }
+ }
+ return map;
+}
+
+void Manager::startSearch(const QString& source_, FetchKey key_, const QString& value_) {
+ if(value_.isEmpty()) {
+ emit signalDone();
+ return;
+ }
+
+ // assume there's only one fetcher match
+ int i = 0;
+ m_currentFetcherIndex = -1;
+ for(FetcherVec::Iterator it = m_fetchers.begin(); it != m_fetchers.end(); ++it, ++i) {
+ if(source_ == it->source()) {
+ ++m_count; // Fetcher::search() might emit done(), so increment before calling search()
+ connect(it.data(), SIGNAL(signalResultFound(Tellico::Fetch::SearchResult*)),
+ SIGNAL(signalResultFound(Tellico::Fetch::SearchResult*)));
+ connect(it.data(), SIGNAL(signalDone(Tellico::Fetch::Fetcher::Ptr)),
+ SLOT(slotFetcherDone(Tellico::Fetch::Fetcher::Ptr)));
+ it->search(key_, value_);
+ m_currentFetcherIndex = i;
+ break;
+ }
+ }
+}
+
+void Manager::continueSearch() {
+ if(m_currentFetcherIndex < 0 || m_currentFetcherIndex >= static_cast<int>(m_fetchers.count())) {
+ myDebug() << "Manager::continueSearch() - can't continue!" << endl;
+ emit signalDone();
+ return;
+ }
+ Fetcher::Ptr f = m_fetchers[m_currentFetcherIndex];
+ if(f && f->hasMoreResults()) {
+ ++m_count;
+ connect(f, SIGNAL(signalResultFound(Tellico::Fetch::SearchResult*)),
+ SIGNAL(signalResultFound(Tellico::Fetch::SearchResult*)));
+ connect(f, SIGNAL(signalDone(Tellico::Fetch::Fetcher::Ptr)),
+ SLOT(slotFetcherDone(Tellico::Fetch::Fetcher::Ptr)));
+ f->continueSearch();
+ } else {
+ emit signalDone();
+ }
+}
+
+bool Manager::hasMoreResults() const {
+ if(m_currentFetcherIndex < 0 || m_currentFetcherIndex >= static_cast<int>(m_fetchers.count())) {
+ return false;
+ }
+ Fetcher::Ptr f = m_fetchers[m_currentFetcherIndex];
+ return f && f->hasMoreResults();
+}
+
+void Manager::stop() {
+// myDebug() << "Manager::stop()" << endl;
+ for(FetcherVec::Iterator it = m_fetchers.begin(); it != m_fetchers.end(); ++it) {
+ if(it->isSearching()) {
+ it->stop();
+ }
+ }
+#ifndef NDEBUG
+ if(m_count != 0) {
+ myDebug() << "Manager::stop() - count should be 0!" << endl;
+ }
+#endif
+ m_count = 0;
+}
+
+void Manager::slotFetcherDone(Fetcher::Ptr fetcher_) {
+// myDebug() << "Manager::slotFetcherDone() - " << (fetcher_ ? fetcher_->source() : QString::null)
+// << " :" << m_count << endl;
+ fetcher_->disconnect(); // disconnect all signals
+ --m_count;
+ if(m_count <= 0) {
+ emit signalDone();
+ }
+}
+
+bool Manager::canFetch() const {
+ for(FetcherVec::ConstIterator it = m_fetchers.constBegin(); it != m_fetchers.constEnd(); ++it) {
+ if(it->canFetch(Kernel::self()->collectionType())) {
+ return true;
+ }
+ }
+ return false;
+}
+
+Tellico::Fetch::Fetcher::Ptr Manager::createFetcher(KConfig* config_, const QString& group_) {
+ if(!config_->hasGroup(group_)) {
+ myDebug() << "Manager::createFetcher() - no config group for " << group_ << endl;
+ return 0;
+ }
+
+ KConfigGroup config(config_, group_);
+
+ int fetchType = config.readNumEntry("Type", Fetch::Unknown);
+ if(fetchType == Fetch::Unknown) {
+ myDebug() << "Manager::createFetcher() - unknown type " << fetchType << ", skipping" << endl;
+ return 0;
+ }
+
+ Fetcher::Ptr f = 0;
+ switch(fetchType) {
+ case Amazon:
+#ifdef AMAZON_SUPPORT
+ {
+ int site = config.readNumEntry("Site", AmazonFetcher::Unknown);
+ if(site == AmazonFetcher::Unknown) {
+ myDebug() << "Manager::createFetcher() - unknown amazon site " << site << ", skipping" << endl;
+ } else {
+ f = new AmazonFetcher(static_cast<AmazonFetcher::Site>(site), this);
+ }
+ }
+#endif
+ break;
+
+ case IMDB:
+#ifdef IMDB_SUPPORT
+ f = new IMDBFetcher(this);
+#endif
+ break;
+
+ case Z3950:
+#ifdef HAVE_YAZ
+ f = new Z3950Fetcher(this);
+#endif
+ break;
+
+ case SRU:
+ f = new SRUFetcher(this);
+ break;
+
+ case Entrez:
+ f = new EntrezFetcher(this);
+ break;
+
+ case ExecExternal:
+ f = new ExecExternalFetcher(this);
+ break;
+
+ case Yahoo:
+ f = new YahooFetcher(this);
+ break;
+
+ case AnimeNfo:
+ f = new AnimeNfoFetcher(this);
+ break;
+
+ case IBS:
+ f = new IBSFetcher(this);
+ break;
+
+ case ISBNdb:
+ f = new ISBNdbFetcher(this);
+ break;
+
+ case GCstarPlugin:
+ f = new GCstarPluginFetcher(this);
+ break;
+
+ case CrossRef:
+ f = new CrossRefFetcher(this);
+ break;
+
+ case Arxiv:
+ f = new ArxivFetcher(this);
+ break;
+
+ case Citebase:
+ f = new CitebaseFetcher(this);
+ break;
+
+ case Bibsonomy:
+ f = new BibsonomyFetcher(this);
+ break;
+
+ case GoogleScholar:
+ f = new GoogleScholarFetcher(this);
+ break;
+
+ case Discogs:
+ f = new DiscogsFetcher(this);
+ break;
+
+ case Unknown:
+ default:
+ break;
+ }
+ if(f) {
+ f->readConfig(config, group_);
+ }
+ return f;
+}
+
+// static
+Tellico::Fetch::FetcherVec Manager::defaultFetchers() {
+ FetcherVec vec;
+#ifdef AMAZON_SUPPORT
+ vec.append(new AmazonFetcher(AmazonFetcher::US, this));
+#endif
+#ifdef IMDB_SUPPORT
+ vec.append(new IMDBFetcher(this));
+#endif
+ vec.append(SRUFetcher::libraryOfCongress(this));
+ vec.append(new ISBNdbFetcher(this));
+ vec.append(new YahooFetcher(this));
+ vec.append(new AnimeNfoFetcher(this));
+ vec.append(new ArxivFetcher(this));
+ vec.append(new GoogleScholarFetcher(this));
+ vec.append(new DiscogsFetcher(this));
+// only add IBS if user includes italian
+ if(KGlobal::locale()->languagesTwoAlpha().contains(QString::fromLatin1("it"))) {
+ vec.append(new IBSFetcher(this));
+ }
+ return vec;
+}
+
+Tellico::Fetch::FetcherVec Manager::createUpdateFetchers(int collType_) {
+ if(m_loadDefaults) {
+ return defaultFetchers();
+ }
+
+ FetcherVec vec;
+ KConfigGroup config(KGlobal::config(), "Data Sources");
+ int nSources = config.readNumEntry("Sources Count", 0);
+ for(int i = 0; i < nSources; ++i) {
+ QString group = QString::fromLatin1("Data Source %1").arg(i);
+ // needs the KConfig*
+ Fetcher::Ptr f = createFetcher(KGlobal::config(), group);
+ if(f && f->canFetch(collType_) && f->canUpdate()) {
+ vec.append(f);
+ }
+ }
+ return vec;
+}
+
+Tellico::Fetch::FetcherVec Manager::createUpdateFetchers(int collType_, FetchKey key_) {
+ FetcherVec fetchers;
+ // creates new fetchers
+ FetcherVec allFetchers = createUpdateFetchers(collType_);
+ for(Fetch::FetcherVec::Iterator it = allFetchers.begin(); it != allFetchers.end(); ++it) {
+ if(it->canSearch(key_)) {
+ fetchers.append(it);
+ }
+ }
+ return fetchers;
+}
+
+Tellico::Fetch::Fetcher::Ptr Manager::createUpdateFetcher(int collType_, const QString& source_) {
+ Fetcher::Ptr fetcher = 0;
+ // creates new fetchers
+ FetcherVec fetchers = createUpdateFetchers(collType_);
+ for(Fetch::FetcherVec::Iterator it = fetchers.begin(); it != fetchers.end(); ++it) {
+ if(it->source() == source_) {
+ fetcher = it;
+ break;
+ }
+ }
+ return fetcher;
+}
+
+void Manager::updateStatus(const QString& message_) {
+ emit signalStatus(message_);
+}
+
+Tellico::Fetch::TypePairList Manager::typeList() {
+ Fetch::TypePairList list;
+#ifdef AMAZON_SUPPORT
+ list.append(TypePair(AmazonFetcher::defaultName(), Amazon));
+#endif
+#ifdef IMDB_SUPPORT
+ list.append(TypePair(IMDBFetcher::defaultName(), IMDB));
+#endif
+#ifdef HAVE_YAZ
+ list.append(TypePair(Z3950Fetcher::defaultName(), Z3950));
+#endif
+ list.append(TypePair(SRUFetcher::defaultName(), SRU));
+ list.append(TypePair(EntrezFetcher::defaultName(), Entrez));
+ list.append(TypePair(ExecExternalFetcher::defaultName(), ExecExternal));
+ list.append(TypePair(YahooFetcher::defaultName(), Yahoo));
+ list.append(TypePair(AnimeNfoFetcher::defaultName(), AnimeNfo));
+ list.append(TypePair(IBSFetcher::defaultName(), IBS));
+ list.append(TypePair(ISBNdbFetcher::defaultName(), ISBNdb));
+ list.append(TypePair(GCstarPluginFetcher::defaultName(), GCstarPlugin));
+ list.append(TypePair(CrossRefFetcher::defaultName(), CrossRef));
+ list.append(TypePair(ArxivFetcher::defaultName(), Arxiv));
+ list.append(TypePair(CitebaseFetcher::defaultName(), Citebase));
+ list.append(TypePair(BibsonomyFetcher::defaultName(), Bibsonomy));
+ list.append(TypePair(GoogleScholarFetcher::defaultName(),GoogleScholar));
+ list.append(TypePair(DiscogsFetcher::defaultName(), Discogs));
+
+ // now find all the scripts distributed with tellico
+ QStringList files = KGlobal::dirs()->findAllResources("appdata", QString::fromLatin1("data-sources/*.spec"),
+ false, true);
+ for(QStringList::Iterator it = files.begin(); it != files.end(); ++it) {
+ KConfig spec(*it, false, false);
+ QString name = spec.readEntry("Name");
+ if(name.isEmpty()) {
+ myDebug() << "Fetch::Manager::typeList() - no Name for " << *it << endl;
+ continue;
+ }
+
+ if(!bundledScriptHasExecPath(*it, &spec)) { // no available exec
+ continue;
+ }
+
+ list.append(TypePair(name, ExecExternal));
+ m_scriptMap.insert(name, *it);
+ }
+ list.sort();
+ return list;
+}
+
+
+// called when creating a new fetcher
+Tellico::Fetch::ConfigWidget* Manager::configWidget(QWidget* parent_, Type type_, const QString& name_) {
+ ConfigWidget* w = 0;
+ switch(type_) {
+#ifdef AMAZON_SUPPORT
+ case Amazon:
+ w = new AmazonFetcher::ConfigWidget(parent_);
+ break;
+#endif
+#ifdef IMDB_SUPPORT
+ case IMDB:
+ w = new IMDBFetcher::ConfigWidget(parent_);
+ break;
+#endif
+#ifdef HAVE_YAZ
+ case Z3950:
+ w = new Z3950Fetcher::ConfigWidget(parent_);
+ break;
+#endif
+ case SRU:
+ w = new SRUConfigWidget(parent_);
+ break;
+ case Entrez:
+ w = new EntrezFetcher::ConfigWidget(parent_);
+ break;
+ case ExecExternal:
+ w = new ExecExternalFetcher::ConfigWidget(parent_);
+ if(!name_.isEmpty() && m_scriptMap.contains(name_)) {
+ // bundledScriptHasExecPath() actually needs to write the exec path
+ // back to the config so the configWidget can read it. But if the spec file
+ // is not readablle, that doesn't work. So work around it with a copy to a temp file
+ KTempFile tmpFile;
+ tmpFile.setAutoDelete(true);
+ KURL from, to;
+ from.setPath(m_scriptMap[name_]);
+ to.setPath(tmpFile.name());
+ // have to overwrite since KTempFile already created it
+ if(!KIO::NetAccess::file_copy(from, to, -1, true /*overwrite*/)) {
+ myDebug() << KIO::NetAccess::lastErrorString() << endl;
+ }
+ KConfig spec(to.path(), false, false);
+ // pass actual location of spec file
+ if(name_ == spec.readEntry("Name") && bundledScriptHasExecPath(m_scriptMap[name_], &spec)) {
+ static_cast<ExecExternalFetcher::ConfigWidget*>(w)->readConfig(&spec);
+ } else {
+ kdWarning() << "Fetch::Manager::configWidget() - Can't read config file for " << to.path() << endl;
+ }
+ }
+ break;
+ case Yahoo:
+ w = new YahooFetcher::ConfigWidget(parent_);
+ break;
+ case AnimeNfo:
+ w = new AnimeNfoFetcher::ConfigWidget(parent_);
+ break;
+ case IBS:
+ w = new IBSFetcher::ConfigWidget(parent_);
+ break;
+ case ISBNdb:
+ w = new ISBNdbFetcher::ConfigWidget(parent_);
+ break;
+ case GCstarPlugin:
+ w = new GCstarPluginFetcher::ConfigWidget(parent_);
+ break;
+ case CrossRef:
+ w = new CrossRefFetcher::ConfigWidget(parent_);
+ break;
+ case Arxiv:
+ w = new ArxivFetcher::ConfigWidget(parent_);
+ break;
+ case Citebase:
+ w = new CitebaseFetcher::ConfigWidget(parent_);
+ break;
+ case Bibsonomy:
+ w = new BibsonomyFetcher::ConfigWidget(parent_);
+ break;
+ case GoogleScholar:
+ w = new GoogleScholarFetcher::ConfigWidget(parent_);
+ break;
+ case Discogs:
+ w = new DiscogsFetcher::ConfigWidget(parent_);
+ break;
+ case Unknown:
+ kdWarning() << "Fetch::Manager::configWidget() - no widget defined for type = " << type_ << endl;
+ }
+ return w;
+}
+
+// static
+QString Manager::typeName(Fetch::Type type_) {
+ switch(type_) {
+#ifdef AMAZON_SUPPORT
+ case Amazon: return AmazonFetcher::defaultName();
+#endif
+#ifdef IMDB_SUPPORT
+ case IMDB: return IMDBFetcher::defaultName();
+#endif
+#ifdef HAVE_YAZ
+ case Z3950: return Z3950Fetcher::defaultName();
+#endif
+ case SRU: return SRUFetcher::defaultName();
+ case Entrez: return EntrezFetcher::defaultName();
+ case ExecExternal: return ExecExternalFetcher::defaultName();
+ case Yahoo: return YahooFetcher::defaultName();
+ case AnimeNfo: return AnimeNfoFetcher::defaultName();
+ case IBS: return IBSFetcher::defaultName();
+ case ISBNdb: return ISBNdbFetcher::defaultName();
+ case GCstarPlugin: return GCstarPluginFetcher::defaultName();
+ case CrossRef: return CrossRefFetcher::defaultName();
+ case Arxiv: return ArxivFetcher::defaultName();
+ case Citebase: return CitebaseFetcher::defaultName();
+ case Bibsonomy: return BibsonomyFetcher::defaultName();
+ case GoogleScholar: return GoogleScholarFetcher::defaultName();
+ case Discogs: return DiscogsFetcher::defaultName();
+ case Unknown: break;
+ }
+ myWarning() << "Manager::typeName() - none found for " << type_ << endl;
+ return QString::null;
+}
+
+QPixmap Manager::fetcherIcon(Fetch::Fetcher::CPtr fetcher_, int group_, int size_) {
+#ifdef HAVE_YAZ
+ if(fetcher_->type() == Fetch::Z3950) {
+ const Fetch::Z3950Fetcher* f = static_cast<const Fetch::Z3950Fetcher*>(fetcher_.data());
+ KURL u;
+ u.setProtocol(QString::fromLatin1("http"));
+ u.setHost(f->host());
+ QString icon = favIcon(u);
+ if(u.isValid() && !icon.isEmpty()) {
+ return LOAD_ICON(icon, group_, size_);
+ }
+ } else
+#endif
+ if(fetcher_->type() == Fetch::ExecExternal) {
+ const Fetch::ExecExternalFetcher* f = static_cast<const Fetch::ExecExternalFetcher*>(fetcher_.data());
+ const QString p = f->execPath();
+ KURL u;
+ if(p.find(QString::fromLatin1("allocine")) > -1) {
+ u = QString::fromLatin1("http://www.allocine.fr");
+ } else if(p.find(QString::fromLatin1("ministerio_de_cultura")) > -1) {
+ u = QString::fromLatin1("http://www.mcu.es");
+ } else if(p.find(QString::fromLatin1("dark_horse_comics")) > -1) {
+ u = QString::fromLatin1("http://www.darkhorse.com");
+ } else if(p.find(QString::fromLatin1("boardgamegeek")) > -1) {
+ u = QString::fromLatin1("http://www.boardgamegeek.com");
+ } else if(f->source().find(QString::fromLatin1("amarok"), 0, false /*case-sensitive*/) > -1) {
+ return LOAD_ICON(QString::fromLatin1("amarok"), group_, size_);
+ }
+ if(!u.isEmpty() && u.isValid()) {
+ QString icon = favIcon(u);
+ if(!icon.isEmpty()) {
+ return LOAD_ICON(icon, group_, size_);
+ }
+ }
+ }
+ return fetcherIcon(fetcher_->type(), group_);
+}
+
+QPixmap Manager::fetcherIcon(Fetch::Type type_, int group_, int size_) {
+ QString name;
+ switch(type_) {
+ case Amazon:
+ name = favIcon("http://amazon.com"); break;
+ case IMDB:
+ name = favIcon("http://imdb.com"); break;
+ case Z3950:
+ name = QString::fromLatin1("network"); break; // rather arbitrary
+ case SRU:
+ name = QString::fromLatin1("network_local"); break; // just to be different than z3950
+ case Entrez:
+ name = favIcon("http://www.ncbi.nlm.nih.gov"); break;
+ case ExecExternal:
+ name = QString::fromLatin1("exec"); break;
+ case Yahoo:
+ name = favIcon("http://yahoo.com"); break;
+ case AnimeNfo:
+ name = favIcon("http://animenfo.com"); break;
+ case IBS:
+ name = favIcon("http://internetbookshop.it"); break;
+ case ISBNdb:
+ name = favIcon("http://isbndb.com"); break;
+ case GCstarPlugin:
+ name = QString::fromLatin1("gcstar"); break;
+ case CrossRef:
+ name = favIcon("http://crossref.org"); break;
+ case Arxiv:
+ name = favIcon("http://arxiv.org"); break;
+ case Citebase:
+ name = favIcon("http://citebase.org"); break;
+ case Bibsonomy:
+ name = favIcon("http://bibsonomy.org"); break;
+ case GoogleScholar:
+ name = favIcon("http://scholar.google.com"); break;
+ case Discogs:
+ name = favIcon("http://www.discogs.com"); break;
+ case Unknown:
+ kdWarning() << "Fetch::Manager::fetcherIcon() - no pixmap defined for type = " << type_ << endl;
+ }
+
+ return name.isEmpty() ? QPixmap() : LOAD_ICON(name, group_, size_);
+}
+
+QString Manager::favIcon(const KURL& url_) {
+ DCOPRef kded("kded", "favicons");
+ DCOPReply reply = kded.call("iconForURL(KURL)", url_);
+ QString iconName = reply.isValid() ? reply : QString();
+ if(!iconName.isEmpty()) {
+ return iconName;
+ } else {
+ // go ahead and try to download it for later
+ kded.call("downloadHostIcon(KURL)", url_);
+ }
+ return KMimeType::iconForURL(url_);
+}
+
+bool Manager::bundledScriptHasExecPath(const QString& specFile_, KConfig* config_) {
+ // make sure ExecPath is set and executable
+ // for the bundled scripts, either the exec name is not set, in which case it is the
+ // name of the spec file, minus the .spec, or the exec is set, and is local to the dir
+ // if not, look for it
+ QString exec = config_->readPathEntry("ExecPath");
+ QFileInfo specInfo(specFile_), execInfo(exec);
+ if(exec.isEmpty() || !execInfo.exists()) {
+ exec = specInfo.dirPath(true) + QDir::separator() + specInfo.baseName(true); // remove ".spec"
+ } else if(execInfo.isRelative()) {
+ exec = specInfo.dirPath(true) + exec;
+ } else if(!execInfo.isExecutable()) {
+ kdWarning() << "Fetch::Manager::execPathForBundledScript() - not executable: " << specFile_ << endl;
+ return false;
+ }
+ execInfo.setFile(exec);
+ if(!execInfo.exists() || !execInfo.isExecutable()) {
+ kdWarning() << "Fetch::Manager::execPathForBundledScript() - no exec file for " << specFile_ << endl;
+ kdWarning() << "exec = " << exec << endl;
+ return false; // we're not ok
+ }
+
+ config_->writePathEntry("ExecPath", exec);
+ config_->sync(); // might be readonly, but that's ok
+ return true;
+}
+
+#include "fetchmanager.moc"
diff --git a/src/fetch/fetchmanager.h b/src/fetch/fetchmanager.h
new file mode 100644
index 0000000..7036d71
--- /dev/null
+++ b/src/fetch/fetchmanager.h
@@ -0,0 +1,108 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef FETCHMANAGER_H
+#define FETCHMANAGER_H
+
+namespace Tellico {
+ namespace Fetch {
+ class SearchResult;
+ class ConfigWidget;
+ class ManagerMessage;
+ }
+}
+
+#include "fetcher.h"
+#include "../ptrvector.h"
+
+#include <ksortablevaluelist.h>
+
+#include <qobject.h>
+#include <qmap.h>
+
+namespace Tellico {
+ namespace Fetch {
+
+typedef KSortableItem<Type, QString> TypePair; // fetcher info, type and name of type
+typedef KSortableValueList<Type, QString> TypePairList;
+typedef QMap<FetchKey, QString> KeyMap; // map key type to name of key
+typedef Vector<Fetcher> FetcherVec;
+
+/**
+ * A manager for handling all the different classes of Fetcher.
+ *
+ * @author Robby Stephenson
+ */
+class Manager : public QObject {
+Q_OBJECT
+
+public:
+ static Manager* self() { if(!s_self) s_self = new Manager(); return s_self; }
+
+ ~Manager();
+
+ KeyMap keyMap(const QString& source = QString::null) const;
+ void startSearch(const QString& source, FetchKey key, const QString& value);
+ void continueSearch();
+ void stop();
+ bool canFetch() const;
+ bool hasMoreResults() const;
+ void loadFetchers();
+ const FetcherVec& fetchers() const { return m_fetchers; }
+ FetcherVec fetchers(int type);
+ TypePairList typeList();
+ ConfigWidget* configWidget(QWidget* parent, Type type, const QString& name);
+
+ // create fetcher for updating an entry
+ FetcherVec createUpdateFetchers(int collType);
+ FetcherVec createUpdateFetchers(int collType, FetchKey key);
+ Fetcher::Ptr createUpdateFetcher(int collType, const QString& source);
+
+ static QString typeName(Type type);
+ static QPixmap fetcherIcon(Fetch::Type type, int iconGroup=3 /*Small*/, int size=0 /* default */);
+ static QPixmap fetcherIcon(Fetch::Fetcher::CPtr ptr, int iconGroup=3 /*Small*/, int size=0 /* default*/);
+
+signals:
+ void signalStatus(const QString& status);
+ void signalResultFound(Tellico::Fetch::SearchResult* result);
+ void signalDone();
+
+private slots:
+ void slotFetcherDone(Tellico::Fetch::Fetcher::Ptr);
+
+private:
+ friend class ManagerMessage;
+ static Manager* s_self;
+
+ Manager();
+ Fetcher::Ptr createFetcher(KConfig* config, const QString& configGroup);
+ FetcherVec defaultFetchers();
+ void updateStatus(const QString& message);
+
+ static QString favIcon(const KURL& url);
+ static bool bundledScriptHasExecPath(const QString& specFile, KConfig* config);
+
+ FetcherVec m_fetchers;
+ int m_currentFetcherIndex;
+ KeyMap m_keyMap;
+ typedef QMap<Fetcher::Ptr, QString> ConfigMap;
+ ConfigMap m_configMap;
+ StringMap m_scriptMap;
+ ManagerMessage* m_messager;
+ uint m_count;
+ bool m_loadDefaults : 1;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/fetch/gcstarpluginfetcher.cpp b/src/fetch/gcstarpluginfetcher.cpp
new file mode 100644
index 0000000..4bffed7
--- /dev/null
+++ b/src/fetch/gcstarpluginfetcher.cpp
@@ -0,0 +1,486 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "gcstarpluginfetcher.h"
+#include "messagehandler.h"
+#include "fetchmanager.h"
+#include "../collection.h"
+#include "../entry.h"
+#include "../translators/tellicoimporter.h"
+#include "../gui/combobox.h"
+#include "../gui/collectiontypecombo.h"
+#include "../filehandler.h"
+#include "../tellico_kernel.h"
+#include "../tellico_debug.h"
+#include "../latin1literal.h"
+#include "../tellico_utils.h"
+
+#include <kconfig.h>
+#include <kprocess.h>
+#include <kprocio.h>
+#include <kstandarddirs.h>
+#include <kaccelmanager.h>
+
+#include <qdir.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qwhatsthis.h>
+
+using Tellico::Fetch::GCstarPluginFetcher;
+
+GCstarPluginFetcher::PluginMap GCstarPluginFetcher::pluginMap;
+GCstarPluginFetcher::PluginParse GCstarPluginFetcher::pluginParse = NotYet;
+
+//static
+GCstarPluginFetcher::PluginList GCstarPluginFetcher::plugins(int collType_) {
+ if(!pluginMap.contains(collType_)) {
+ GUI::CursorSaver cs;
+ QString gcstar = KStandardDirs::findExe(QString::fromLatin1("gcstar"));
+
+ if(pluginParse == NotYet) {
+ KProcIO proc;
+ proc << gcstar << QString::fromLatin1("--version");
+ // wait 5 seconds at most, just a sanity thing, never want to block completely
+ if(proc.start(KProcess::Block) && proc.wait(5)) {
+ QString output;
+ proc.readln(output);
+ if(!output.isEmpty()) {
+ // always going to be x.y[.z] ?
+ QRegExp versionRx(QString::fromLatin1("(\\d+)\\.(\\d+)(?:\\.(\\d+))?"));
+ if(versionRx.search(output) > -1) {
+ int x = versionRx.cap(1).toInt();
+ int y = versionRx.cap(2).toInt();
+ int z = versionRx.cap(3).toInt(); // ok to be empty
+ myDebug() << QString::fromLatin1("GCstarPluginFetcher() - found %1.%2.%3").arg(x).arg(y).arg(z) << endl;
+ // --list-plugins argument was added for 1.3 release
+ pluginParse = (x >= 1 && y >=3) ? New : Old;
+ }
+ }
+ }
+ // if still zero, then we should use old in future
+ if(pluginParse == NotYet) {
+ pluginParse = Old;
+ }
+ }
+
+ if(pluginParse == New) {
+ readPluginsNew(collType_, gcstar);
+ } else {
+ readPluginsOld(collType_, gcstar);
+ }
+ }
+
+ return pluginMap.contains(collType_) ? pluginMap[collType_] : GCstarPluginFetcher::PluginList();
+}
+
+void GCstarPluginFetcher::readPluginsNew(int collType_, const QString& gcstar_) {
+ PluginList plugins;
+
+ QString gcstarCollection = gcstarType(collType_);
+ if(gcstarCollection.isEmpty()) {
+ pluginMap.insert(collType_, plugins);
+ return;
+ }
+
+ KProcIO proc;
+ proc << gcstar_
+ << QString::fromLatin1("-x")
+ << QString::fromLatin1("--list-plugins")
+ << QString::fromLatin1("--collection") << gcstarCollection;
+
+ if(!proc.start(KProcess::Block)) {
+ myWarning() << "GCstarPluginFetcher::readPluginsNew() - can't start" << endl;
+ return;
+ }
+
+ bool hasName = false;
+ PluginInfo info;
+ QString line;
+ for(int length = 0; length > -1; length = proc.readln(line)) {
+ if(line.isEmpty()) {
+ if(hasName) {
+ plugins << info;
+ }
+ hasName = false;
+ info.clear();
+ } else {
+ // authors have \t at beginning
+ line = line.stripWhiteSpace();
+ if(!hasName) {
+ info.insert(QString::fromLatin1("name"), line);
+ hasName = true;
+ } else {
+ info.insert(QString::fromLatin1("author"), line);
+ }
+// myDebug() << line << endl;
+ }
+ }
+
+ pluginMap.insert(collType_, plugins);
+}
+
+void GCstarPluginFetcher::readPluginsOld(int collType_, const QString& gcstar_) {
+ QDir dir(gcstar_, QString::fromLatin1("GC*.pm"));
+ dir.cd(QString::fromLatin1("../../lib/gcstar/GCPlugins/"));
+
+ QRegExp rx(QString::fromLatin1("get(Name|Author|Lang)\\s*\\{\\s*return\\s+['\"](.+)['\"]"));
+ rx.setMinimal(true);
+
+ PluginList plugins;
+
+ QString dirName = gcstarType(collType_);
+ if(dirName.isEmpty()) {
+ pluginMap.insert(collType_, plugins);
+ return;
+ }
+
+ QStringList files = dir.entryList();
+ for(QStringList::ConstIterator file = files.begin(); file != files.end(); ++file) {
+ KURL u;
+ u.setPath(dir.filePath(*file));
+ PluginInfo info;
+ QString text = FileHandler::readTextFile(u);
+ for(int pos = rx.search(text);
+ pos > -1;
+ pos = rx.search(text, pos+rx.matchedLength())) {
+ info.insert(rx.cap(1).lower(), rx.cap(2));
+ }
+ // only add if it has a name
+ if(info.contains(QString::fromLatin1("name"))) {
+ plugins << info;
+ }
+ }
+ // inserting empty map is ok
+ pluginMap.insert(collType_, plugins);
+}
+
+QString GCstarPluginFetcher::gcstarType(int collType_) {
+ switch(collType_) {
+ case Data::Collection::Book: return QString::fromLatin1("GCbooks");
+ case Data::Collection::Video: return QString::fromLatin1("GCfilms");
+ case Data::Collection::Game: return QString::fromLatin1("GCgames");
+ case Data::Collection::Album: return QString::fromLatin1("GCmusics");
+ case Data::Collection::Coin: return QString::fromLatin1("GCcoins");
+ case Data::Collection::Wine: return QString::fromLatin1("GCwines");
+ case Data::Collection::BoardGame: return QString::fromLatin1("GCboardgames");
+ default: break;
+ }
+ return QString();
+}
+
+GCstarPluginFetcher::GCstarPluginFetcher(QObject* parent_, const char* name_/*=0*/) : Fetcher(parent_, name_),
+ m_started(false), m_collType(-1), m_process(0) {
+}
+
+GCstarPluginFetcher::~GCstarPluginFetcher() {
+ stop();
+}
+
+QString GCstarPluginFetcher::defaultName() {
+ return i18n("GCstar Plugin");
+}
+
+QString GCstarPluginFetcher::source() const {
+ return m_name;
+}
+
+bool GCstarPluginFetcher::canFetch(int type_) const {
+ return m_collType == -1 ? false : m_collType == type_;
+}
+
+void GCstarPluginFetcher::readConfigHook(const KConfigGroup& config_) {
+ m_collType = config_.readNumEntry("CollectionType", -1);
+ m_plugin = config_.readEntry("Plugin");
+}
+
+void GCstarPluginFetcher::search(FetchKey key_, const QString& value_) {
+ m_started = true;
+ m_data.truncate(0);
+
+ if(key_ != Fetch::Title) {
+ myDebug() << "GCstarPluginFetcher::search() - only Title searches are supported" << endl;
+ stop();
+ return;
+ }
+
+ QString gcstar = KStandardDirs::findExe(QString::fromLatin1("gcstar"));
+ if(gcstar.isEmpty()) {
+ myWarning() << "GCstarPluginFetcher::search() - gcstar not found!" << endl;
+ stop();
+ return;
+ }
+
+ QString gcstarCollection = gcstarType(m_collType);
+
+ if(m_plugin.isEmpty()) {
+ myWarning() << "GCstarPluginFetcher::search() - no plugin name! " << endl;
+ stop();
+ return;
+ }
+
+ m_process = new KProcess();
+ connect(m_process, SIGNAL(receivedStdout(KProcess*, char*, int)), SLOT(slotData(KProcess*, char*, int)));
+ connect(m_process, SIGNAL(receivedStderr(KProcess*, char*, int)), SLOT(slotError(KProcess*, char*, int)));
+ connect(m_process, SIGNAL(processExited(KProcess*)), SLOT(slotProcessExited(KProcess*)));
+ QStringList args;
+ args << gcstar << QString::fromLatin1("-x")
+ << QString::fromLatin1("--collection") << gcstarCollection
+ << QString::fromLatin1("--export") << QString::fromLatin1("Tellico")
+ << QString::fromLatin1("--website") << m_plugin
+ << QString::fromLatin1("--download") << KProcess::quote(value_);
+ myLog() << "GCstarPluginFetcher::search() - " << args.join(QChar(' ')) << endl;
+ *m_process << args;
+ if(!m_process->start(KProcess::NotifyOnExit, KProcess::AllOutput)) {
+ myDebug() << "GCstarPluginFetcher::startSearch() - process failed to start" << endl;
+ stop();
+ }
+}
+
+void GCstarPluginFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+ if(m_process) {
+ m_process->kill();
+ delete m_process;
+ m_process = 0;
+ }
+ m_data.truncate(0);
+ m_started = false;
+ m_errors.clear();
+ emit signalDone(this);
+}
+
+void GCstarPluginFetcher::slotData(KProcess*, char* buffer_, int len_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(buffer_, len_);
+}
+
+void GCstarPluginFetcher::slotError(KProcess*, char* buffer_, int len_) {
+ QString msg = QString::fromLocal8Bit(buffer_, len_);
+ msg.prepend(source() + QString::fromLatin1(": "));
+ myDebug() << "GCstarPluginFetcher::slotError() - " << msg << endl;
+ m_errors << msg;
+}
+
+void GCstarPluginFetcher::slotProcessExited(KProcess*) {
+// myDebug() << "GCstarPluginFetcher::slotProcessExited()" << endl;
+ if(!m_process->normalExit() || m_process->exitStatus()) {
+ myDebug() << "GCstarPluginFetcher::slotProcessExited() - "<< source() << ": process did not exit successfully" << endl;
+ if(!m_errors.isEmpty()) {
+ message(m_errors.join(QChar('\n')), MessageHandler::Error);
+ }
+ stop();
+ return;
+ }
+ if(!m_errors.isEmpty()) {
+ message(m_errors.join(QChar('\n')), MessageHandler::Warning);
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "GCstarPluginFetcher::slotProcessExited() - "<< source() << ": no data" << endl;
+ stop();
+ return;
+ }
+
+ Import::TellicoImporter imp(QString::fromUtf8(m_data, m_data.size()));
+
+ Data::CollPtr coll = imp.collection();
+ if(!coll) {
+ if(!imp.statusMessage().isEmpty()) {
+ message(imp.statusMessage(), MessageHandler::Status);
+ }
+ myDebug() << "GCstarPluginFetcher::slotProcessExited() - "<< source() << ": no collection pointer" << endl;
+ stop();
+ return;
+ }
+
+ Data::EntryVec entries = coll->entries();
+ for(Data::EntryVec::Iterator entry = entries.begin(); entry != entries.end(); ++entry) {
+ QString desc;
+ switch(coll->type()) {
+ case Data::Collection::Book:
+ case Data::Collection::Bibtex:
+ desc = entry->field(QString::fromLatin1("author"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("publisher"));
+ if(!entry->field(QString::fromLatin1("cr_year")).isEmpty()) {
+ desc += QChar('/') + entry->field(QString::fromLatin1("cr_year"));
+ } else if(!entry->field(QString::fromLatin1("pub_year")).isEmpty()){
+ desc += QChar('/') + entry->field(QString::fromLatin1("pub_year"));
+ }
+ break;
+
+ case Data::Collection::Video:
+ desc = entry->field(QString::fromLatin1("studio"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("director"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("year"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("medium"));
+ break;
+
+ case Data::Collection::Album:
+ desc = entry->field(QString::fromLatin1("artist"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("label"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("year"));
+ break;
+
+ case Data::Collection::Game:
+ desc = entry->field(QString::fromLatin1("platform"));
+ break;
+
+ case Data::Collection::ComicBook:
+ desc = entry->field(QString::fromLatin1("publisher"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("pub_year"));
+ break;
+
+ case Data::Collection::BoardGame:
+ desc = entry->field(QString::fromLatin1("designer"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("publisher"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("year"));
+ break;
+
+ default:
+ break;
+ }
+ SearchResult* r = new SearchResult(this, entry->title(), desc, entry->field(QString::fromLatin1("isbn")));
+ m_entries.insert(r->uid, entry);
+ emit signalResultFound(r);
+ }
+ stop(); // be sure to call this
+}
+
+Tellico::Data::EntryPtr GCstarPluginFetcher::fetchEntry(uint uid_) {
+ return m_entries[uid_];
+}
+
+void GCstarPluginFetcher::updateEntry(Data::EntryPtr entry_) {
+ // ry searching for title and rely on Collection::sameEntry() to figure things out
+ QString t = entry_->field(QString::fromLatin1("title"));
+ if(!t.isEmpty()) {
+ search(Fetch::Title, t);
+ return;
+ }
+
+ myDebug() << "GCstarPluginFetcher::updateEntry() - insufficient info to search" << endl;
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+Tellico::Fetch::ConfigWidget* GCstarPluginFetcher::configWidget(QWidget* parent_) const {
+ return new GCstarPluginFetcher::ConfigWidget(parent_, this);
+}
+
+GCstarPluginFetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const GCstarPluginFetcher* fetcher_/*=0*/)
+ : Fetch::ConfigWidget(parent_), m_needPluginList(true) {
+ QGridLayout* l = new QGridLayout(optionsWidget(), 3, 4);
+ l->setSpacing(4);
+ l->setColStretch(1, 10);
+
+ int row = -1;
+
+ QLabel* label = new QLabel(i18n("Collection &type:"), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_collCombo = new GUI::CollectionTypeCombo(optionsWidget());
+ connect(m_collCombo, SIGNAL(activated(int)), SLOT(slotSetModified()));
+ connect(m_collCombo, SIGNAL(activated(int)), SLOT(slotTypeChanged()));
+ l->addMultiCellWidget(m_collCombo, row, row, 1, 3);
+ QString w = i18n("Set the collection type of the data returned from the plugin.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_collCombo, w);
+ label->setBuddy(m_collCombo);
+
+ label = new QLabel(i18n("&Plugin: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_pluginCombo = new GUI::ComboBox(optionsWidget());
+ connect(m_pluginCombo, SIGNAL(activated(int)), SLOT(slotSetModified()));
+ connect(m_pluginCombo, SIGNAL(activated(int)), SLOT(slotPluginChanged()));
+ l->addMultiCellWidget(m_pluginCombo, row, row, 1, 3);
+ w = i18n("Select the GCstar plugin used for the data source.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_pluginCombo, w);
+ label->setBuddy(m_pluginCombo);
+
+ label = new QLabel(i18n("Author: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_authorLabel = new QLabel(optionsWidget());
+ l->addWidget(m_authorLabel, row, 1);
+
+// label = new QLabel(i18n("Language: "), optionsWidget());
+// l->addWidget(label, row, 2);
+// m_langLabel = new QLabel(optionsWidget());
+// l->addWidget(m_langLabel, row, 3);
+
+ if(fetcher_ && fetcher_->m_collType > -1) {
+ m_collCombo->setCurrentType(fetcher_->m_collType);
+ } else {
+ m_collCombo->setCurrentType(Kernel::self()->collectionType());
+ }
+
+ if(fetcher_) {
+ m_originalPluginName = fetcher_->m_plugin;
+ }
+
+ KAcceleratorManager::manage(optionsWidget());
+}
+
+GCstarPluginFetcher::ConfigWidget::~ConfigWidget() {
+}
+
+void GCstarPluginFetcher::ConfigWidget::saveConfig(KConfigGroup& config_) {
+ config_.writeEntry("CollectionType", m_collCombo->currentType());
+ config_.writeEntry("Plugin", m_pluginCombo->currentText());
+}
+
+QString GCstarPluginFetcher::ConfigWidget::preferredName() const {
+ return QString::fromLatin1("GCstar - ") + m_pluginCombo->currentText();
+}
+
+void GCstarPluginFetcher::ConfigWidget::slotTypeChanged() {
+ int collType = m_collCombo->currentType();
+ m_pluginCombo->clear();
+ QStringList pluginNames;
+ GCstarPluginFetcher::PluginList list = GCstarPluginFetcher::plugins(collType);
+ for(GCstarPluginFetcher::PluginList::ConstIterator it = list.begin(); it != list.end(); ++it) {
+ pluginNames << (*it)[QString::fromLatin1("name")].toString();
+ m_pluginCombo->insertItem(pluginNames.last(), *it);
+ }
+ slotPluginChanged();
+ emit signalName(preferredName());
+}
+
+void GCstarPluginFetcher::ConfigWidget::slotPluginChanged() {
+ PluginInfo info = m_pluginCombo->currentData().toMap();
+ m_authorLabel->setText(info[QString::fromLatin1("author")].toString());
+// m_langLabel->setText(info[QString::fromLatin1("lang")].toString());
+ emit signalName(preferredName());
+}
+
+void GCstarPluginFetcher::ConfigWidget::showEvent(QShowEvent*) {
+ if(m_needPluginList) {
+ m_needPluginList = false;
+ slotTypeChanged(); // update plugin combo box
+ if(!m_originalPluginName.isEmpty()) {
+ m_pluginCombo->setCurrentText(m_originalPluginName);
+ slotPluginChanged();
+ }
+ }
+}
+
+#include "gcstarpluginfetcher.moc"
diff --git a/src/fetch/gcstarpluginfetcher.h b/src/fetch/gcstarpluginfetcher.h
new file mode 100644
index 0000000..1994b58
--- /dev/null
+++ b/src/fetch/gcstarpluginfetcher.h
@@ -0,0 +1,121 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_GCSTARPLUGINFETCHER_H
+#define TELLICO_GCSTARPLUGINFETCHER_H
+
+#include "fetcher.h"
+#include "configwidget.h"
+#include "../datavectors.h"
+
+#include <qintdict.h>
+
+class QLabel;
+class KProcess;
+
+namespace Tellico {
+ namespace GUI {
+ class ComboBox;
+ class CollectionTypeCombo;
+ }
+ namespace Fetch {
+
+/**
+ * @author Robby Stephenson
+ */
+class GCstarPluginFetcher : public Fetcher {
+Q_OBJECT
+
+public:
+
+ GCstarPluginFetcher(QObject* parent, const char* name=0);
+ /**
+ */
+ virtual ~GCstarPluginFetcher();
+
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual bool canSearch(FetchKey k) const { return k == Title; }
+
+ virtual void search(FetchKey key, const QString& value);
+ virtual void updateEntry(Data::EntryPtr entry);
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return GCstarPlugin; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const;
+
+ class ConfigWidget;
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+private slots:
+ void slotData(KProcess* proc, char* buffer, int len);
+ void slotError(KProcess* proc, char* buffer, int len);
+ void slotProcessExited(KProcess* proc);
+
+private:
+ // map Author, Name, Lang, etc...
+ typedef QMap<QString, QVariant> PluginInfo;
+ typedef QValueList<PluginInfo> PluginList;
+ // map collection type to all available plugins
+ typedef QMap<int, PluginList> PluginMap;
+ static PluginMap pluginMap;
+ static PluginList plugins(int collType);
+ // we need to keep track if we've searched for plugins yet and by what method
+ enum PluginParse {NotYet, Old, New};
+ static PluginParse pluginParse;
+ static void readPluginsNew(int collType, const QString& exe);
+ static void readPluginsOld(int collType, const QString& exe);
+ static QString gcstarType(int collType);
+
+ bool m_started;
+ int m_collType;
+ QString m_plugin;
+ KProcess* m_process;
+ QByteArray m_data;
+ QMap<int, Data::EntryPtr> m_entries; // map from search result id to entry
+ QStringList m_errors;
+};
+
+class GCstarPluginFetcher::ConfigWidget : public Fetch::ConfigWidget {
+Q_OBJECT
+
+public:
+ ConfigWidget(QWidget* parent, const GCstarPluginFetcher* fetcher = 0);
+ ~ConfigWidget();
+
+ virtual void saveConfig(KConfigGroup& config);
+ virtual QString preferredName() const;
+
+private slots:
+ void slotTypeChanged();
+ void slotPluginChanged();
+
+private:
+ void showEvent(QShowEvent* event);
+
+ bool m_needPluginList;
+ QString m_originalPluginName;
+ GUI::CollectionTypeCombo* m_collCombo;
+ GUI::ComboBox* m_pluginCombo;
+ QLabel* m_authorLabel;
+ QLabel* m_langLabel;
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/fetch/googlescholarfetcher.cpp b/src/fetch/googlescholarfetcher.cpp
new file mode 100644
index 0000000..21979c4
--- /dev/null
+++ b/src/fetch/googlescholarfetcher.cpp
@@ -0,0 +1,233 @@
+/***************************************************************************
+ copyright : (C) 2008 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "googlescholarfetcher.h"
+#include "messagehandler.h"
+#include "../filehandler.h"
+#include "../translators/bibteximporter.h"
+#include "../collection.h"
+#include "../entry.h"
+#include "../tellico_kernel.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kio/job.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+
+namespace {
+ static const int GOOGLE_MAX_RETURNS_TOTAL = 20;
+ static const char* SCHOLAR_BASE_URL = "http://scholar.google.com/scholar";
+}
+
+using Tellico::Fetch::GoogleScholarFetcher;
+
+GoogleScholarFetcher::GoogleScholarFetcher(QObject* parent_, const char* name_)
+ : Fetcher(parent_, name_),
+ m_limit(GOOGLE_MAX_RETURNS_TOTAL), m_start(0), m_job(0), m_started(false),
+ m_cookieIsSet(false) {
+ m_bibtexRx = QRegExp(QString::fromLatin1("<a\\s.*href\\s*=\\s*\"([^>]*scholar\\.bib[^>]*)\""));
+ m_bibtexRx.setMinimal(true);
+}
+
+GoogleScholarFetcher::~GoogleScholarFetcher() {
+}
+
+QString GoogleScholarFetcher::defaultName() {
+ // no i18n
+ return QString::fromLatin1("Google Scholar");
+}
+
+QString GoogleScholarFetcher::source() const {
+ return m_name.isEmpty() ? defaultName() : m_name;
+}
+
+bool GoogleScholarFetcher::canFetch(int type) const {
+ return type == Data::Collection::Bibtex;
+}
+
+void GoogleScholarFetcher::readConfigHook(const KConfigGroup& config_) {
+ Q_UNUSED(config_);
+}
+
+void GoogleScholarFetcher::search(FetchKey key_, const QString& value_) {
+ if(!m_cookieIsSet) {
+ // have to set preferences to have bibtex output
+ FileHandler::readTextFile(QString::fromLatin1("http://scholar.google.com/scholar_setprefs?num=100&scis=yes&scisf=4&submit=Save+Preferences"), true);
+ m_cookieIsSet = true;
+ }
+ m_key = key_;
+ m_value = value_;
+ m_started = true;
+ m_start = 0;
+ m_total = -1;
+ doSearch();
+}
+
+void GoogleScholarFetcher::continueSearch() {
+ m_started = true;
+ doSearch();
+}
+
+void GoogleScholarFetcher::doSearch() {
+// myDebug() << "GoogleScholarFetcher::search() - value = " << value_ << endl;
+
+ if(!canFetch(Kernel::self()->collectionType())) {
+ message(i18n("%1 does not allow searching for this collection type.").arg(source()), MessageHandler::Warning);
+ stop();
+ return;
+ }
+
+ KURL u(QString::fromLatin1(SCHOLAR_BASE_URL));
+ u.addQueryItem(QString::fromLatin1("start"), QString::number(m_start));
+
+ switch(m_key) {
+ case Title:
+ u.addQueryItem(QString::fromLatin1("q"), QString::fromLatin1("allintitle:%1").arg(m_value));
+ break;
+
+ case Keyword:
+ u.addQueryItem(QString::fromLatin1("q"), m_value);
+ break;
+
+ case Person:
+ u.addQueryItem(QString::fromLatin1("q"), QString::fromLatin1("author:%1").arg(m_value));
+ break;
+
+ default:
+ kdWarning() << "GoogleScholarFetcher::search() - key not recognized: " << m_key << endl;
+ stop();
+ return;
+ }
+// myDebug() << "GoogleScholarFetcher::search() - url: " << u.url() << endl;
+
+ m_job = KIO::get(u, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+}
+
+void GoogleScholarFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+ if(m_job) {
+ m_job->kill();
+ m_job = 0;
+ }
+ m_data.truncate(0);
+ m_started = false;
+ emit signalDone(this);
+}
+
+void GoogleScholarFetcher::slotData(KIO::Job*, const QByteArray& data_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(data_.data(), data_.size());
+}
+
+void GoogleScholarFetcher::slotComplete(KIO::Job* job_) {
+// myDebug() << "GoogleScholarFetcher::slotComplete()" << endl;
+ // since the fetch is done, don't worry about holding the job pointer
+ m_job = 0;
+
+ if(job_->error()) {
+ job_->showErrorDialog(Kernel::self()->widget());
+ stop();
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "GoogleScholarFetcher::slotComplete() - no data" << endl;
+ stop();
+ return;
+ }
+
+ QString text = QString::fromUtf8(m_data, m_data.size());
+ QString bibtex;
+ int count = 0;
+ for(int pos = text.find(m_bibtexRx); count < m_limit && pos > -1; pos = text.find(m_bibtexRx, pos+m_bibtexRx.matchedLength()), ++count) {
+ KURL bibtexUrl(QString::fromLatin1(SCHOLAR_BASE_URL), m_bibtexRx.cap(1));
+// myDebug() << bibtexUrl << endl;
+ bibtex += FileHandler::readTextFile(bibtexUrl, true);
+ }
+
+ Import::BibtexImporter imp(bibtex);
+ Data::CollPtr coll = imp.collection();
+ if(!coll) {
+ myDebug() << "GoogleScholarFetcher::slotComplete() - no collection pointer" << endl;
+ stop();
+ return;
+ }
+
+ count = 0;
+ Data::EntryVec entries = coll->entries();
+ for(Data::EntryVec::Iterator entry = entries.begin(); count < m_limit && entry != entries.end(); ++entry, ++count) {
+ if(!m_started) {
+ // might get aborted
+ break;
+ }
+ QString desc = entry->field(QString::fromLatin1("author"))
+ + QChar('/') + entry->field(QString::fromLatin1("publisher"));
+ if(!entry->field(QString::fromLatin1("year")).isEmpty()) {
+ desc += QChar('/') + entry->field(QString::fromLatin1("year"));
+ }
+
+ SearchResult* r = new SearchResult(this, entry->title(), desc, entry->field(QString::fromLatin1("isbn")));
+ m_entries.insert(r->uid, Data::EntryPtr(entry));
+ emit signalResultFound(r);
+ }
+ m_start = m_entries.count();
+// m_hasMoreResults = m_start <= m_total;
+ m_hasMoreResults = false; // for now, no continued searches
+
+ stop(); // required
+}
+
+Tellico::Data::EntryPtr GoogleScholarFetcher::fetchEntry(uint uid_) {
+ return m_entries[uid_];
+}
+
+void GoogleScholarFetcher::updateEntry(Data::EntryPtr entry_) {
+// myDebug() << "GoogleScholarFetcher::updateEntry()" << endl;
+ // limit to top 5 results
+ m_limit = 5;
+
+ QString title = entry_->field(QString::fromLatin1("title"));
+ if(!title.isEmpty()) {
+ search(Title, title);
+ return;
+ }
+
+ myDebug() << "GoogleScholarFetcher::updateEntry() - insufficient info to search" << endl;
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+Tellico::Fetch::ConfigWidget* GoogleScholarFetcher::configWidget(QWidget* parent_) const {
+ return new GoogleScholarFetcher::ConfigWidget(parent_, this);
+}
+
+GoogleScholarFetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const GoogleScholarFetcher*/*=0*/)
+ : Fetch::ConfigWidget(parent_) {
+ QVBoxLayout* l = new QVBoxLayout(optionsWidget());
+ l->addWidget(new QLabel(i18n("This source has no options."), optionsWidget()));
+ l->addStretch();
+}
+
+QString GoogleScholarFetcher::ConfigWidget::preferredName() const {
+ return GoogleScholarFetcher::defaultName();
+}
+
+#include "googlescholarfetcher.moc"
diff --git a/src/fetch/googlescholarfetcher.h b/src/fetch/googlescholarfetcher.h
new file mode 100644
index 0000000..4e15475
--- /dev/null
+++ b/src/fetch/googlescholarfetcher.h
@@ -0,0 +1,103 @@
+/***************************************************************************
+ copyright : (C) 2008 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef GOOGLESCHOLARFETCHER_H
+#define GOOGLESCHOLARFETCHER_H
+
+#include "fetcher.h"
+#include "configwidget.h"
+#include "../datavectors.h"
+
+#include <qguardedptr.h>
+#include <qregexp.h>
+
+namespace KIO {
+ class Job;
+}
+
+namespace Tellico {
+ namespace Fetch {
+
+/**
+ * A fetcher for Google Scholar
+ *
+ * @author Robby Stephenson
+ */
+class GoogleScholarFetcher : public Fetcher {
+Q_OBJECT
+
+public:
+ /**
+ */
+ GoogleScholarFetcher(QObject* parent, const char* name = 0);
+ /**
+ */
+ virtual ~GoogleScholarFetcher();
+
+ /**
+ */
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual void search(FetchKey key, const QString& value);
+ virtual void continueSearch();
+ // amazon can search title or person
+ virtual bool canSearch(FetchKey k) const { return k == Title || k == Person || k == Keyword; }
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return GoogleScholar; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+
+ virtual void updateEntry(Data::EntryPtr entry);
+
+ /**
+ * Returns a widget for modifying the fetcher's config.
+ */
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const;
+
+ class ConfigWidget : public Fetch::ConfigWidget {
+ public:
+ ConfigWidget(QWidget* parent_, const GoogleScholarFetcher* fetcher = 0);
+ virtual void saveConfig(KConfigGroup&) {}
+ virtual QString preferredName() const;
+ };
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+private slots:
+ void slotData(KIO::Job* job, const QByteArray& data);
+ void slotComplete(KIO::Job* job);
+
+private:
+ void doSearch();
+
+ int m_limit;
+ int m_start;
+ int m_total;
+
+ QByteArray m_data;
+ QMap<int, Data::EntryPtr> m_entries;
+ QGuardedPtr<KIO::Job> m_job;
+
+ FetchKey m_key;
+ QString m_value;
+ bool m_started;
+
+ QRegExp m_bibtexRx;
+ bool m_cookieIsSet;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/fetch/ibsfetcher.cpp b/src/fetch/ibsfetcher.cpp
new file mode 100644
index 0000000..b11258b
--- /dev/null
+++ b/src/fetch/ibsfetcher.cpp
@@ -0,0 +1,415 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "ibsfetcher.h"
+#include "messagehandler.h"
+#include "../tellico_kernel.h"
+#include "../tellico_utils.h"
+#include "../collections/bookcollection.h"
+#include "../entry.h"
+#include "../filehandler.h"
+#include "../latin1literal.h"
+#include "../imagefactory.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kio/job.h>
+
+#include <qregexp.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qfile.h>
+
+//#define IBS_TEST
+
+namespace {
+ static const char* IBS_BASE_URL = "http://www.internetbookshop.it/ser/serpge.asp";
+}
+
+using Tellico::Fetch::IBSFetcher;
+
+IBSFetcher::IBSFetcher(QObject* parent_, const char* name_ /*=0*/)
+ : Fetcher(parent_, name_), m_started(false) {
+}
+
+QString IBSFetcher::defaultName() {
+ return i18n("Internet Bookshop (ibs.it)");
+}
+
+QString IBSFetcher::source() const {
+ return m_name.isEmpty() ? defaultName() : m_name;
+}
+
+bool IBSFetcher::canFetch(int type) const {
+ return type == Data::Collection::Book || type == Data::Collection::Bibtex;
+}
+
+void IBSFetcher::readConfigHook(const KConfigGroup& config_) {
+ Q_UNUSED(config_);
+}
+
+void IBSFetcher::search(FetchKey key_, const QString& value_) {
+ m_started = true;
+ m_matches.clear();
+
+#ifdef IBS_TEST
+ KURL u = KURL::fromPathOrURL(QString::fromLatin1("/home/robby/ibs.html"));
+#else
+ KURL u(QString::fromLatin1(IBS_BASE_URL));
+
+ if(!canFetch(Kernel::self()->collectionType())) {
+ message(i18n("%1 does not allow searching for this collection type.").arg(source()), MessageHandler::Warning);
+ stop();
+ return;
+ }
+
+ switch(key_) {
+ case Title:
+ u.addQueryItem(QString::fromLatin1("Type"), QString::fromLatin1("keyword"));
+ u.addQueryItem(QString::fromLatin1("T"), value_);
+ break;
+
+ case Person:
+ u.addQueryItem(QString::fromLatin1("Type"), QString::fromLatin1("keyword"));
+ u.addQueryItem(QString::fromLatin1("A"), value_);
+ break;
+
+ case ISBN:
+ {
+ QString s = value_;
+ s.remove('-');
+ // limit to first isbn
+ s = s.section(';', 0, 0);
+ u.setFileName(QString::fromLatin1("serdsp.asp"));
+ u.addQueryItem(QString::fromLatin1("isbn"), s);
+ }
+ break;
+
+ case Keyword:
+ u.addQueryItem(QString::fromLatin1("Type"), QString::fromLatin1("keyword"));
+ u.addQueryItem(QString::fromLatin1("S"), value_);
+ break;
+
+ default:
+ kdWarning() << "IBSFetcher::search() - key not recognized: " << key_ << endl;
+ stop();
+ return;
+ }
+#endif
+// myDebug() << "IBSFetcher::search() - url: " << u.url() << endl;
+
+ m_job = KIO::get(u, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ if(key_ == ISBN) {
+ connect(m_job, SIGNAL(result(KIO::Job*)), SLOT(slotCompleteISBN(KIO::Job*)));
+ } else {
+ connect(m_job, SIGNAL(result(KIO::Job*)), SLOT(slotComplete(KIO::Job*)));
+ }
+}
+
+void IBSFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+
+ if(m_job) {
+ m_job->kill();
+ m_job = 0;
+ }
+ m_data.truncate(0);
+ m_started = false;
+ emit signalDone(this);
+}
+
+void IBSFetcher::slotData(KIO::Job*, const QByteArray& data_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(data_.data(), data_.size());
+}
+
+void IBSFetcher::slotComplete(KIO::Job* job_) {
+ // since the fetch is done, don't worry about holding the job pointer
+ m_job = 0;
+
+ if(job_->error()) {
+ job_->showErrorDialog(Kernel::self()->widget());
+ stop();
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "IBSFetcher::slotComplete() - no data" << endl;
+ stop();
+ return;
+ }
+
+ QString s = Tellico::decodeHTML(QString(m_data));
+ // really specific regexp
+ QString pat = QString::fromLatin1("http://www.internetbookshop.it/code/");
+ QRegExp anchorRx(QString::fromLatin1("<a\\s+[^>]*href\\s*=\\s*[\"'](") +
+ QRegExp::escape(pat) +
+ QString::fromLatin1("[^\"]*)\"[^>]*><b>([^<]+)<"), false);
+ anchorRx.setMinimal(true);
+ QRegExp tagRx(QString::fromLatin1("<.*>"));
+ tagRx.setMinimal(true);
+
+ QString u, t, d;
+ int pos2;
+ for(int pos = anchorRx.search(s); m_started && pos > -1; pos = anchorRx.search(s, pos+anchorRx.matchedLength())) {
+ if(!u.isEmpty()) {
+ SearchResult* r = new SearchResult(this, t, d, QString());
+ emit signalResultFound(r);
+
+#ifdef IBS_TEST
+ KURL url = KURL::fromPathOrURL(QString::fromLatin1("/home/robby/ibs2.html"));
+#else
+ // the url probable contains &amp; so be careful
+ KURL url = u.replace(QString::fromLatin1("&amp;"), QChar('&'));
+#endif
+ m_matches.insert(r->uid, url);
+
+ u.truncate(0);
+ t.truncate(0);
+ d.truncate(0);
+ }
+ u = anchorRx.cap(1);
+ t = anchorRx.cap(2);
+ pos2 = s.find(QString::fromLatin1("<br>"), pos, false);
+ if(pos2 > -1) {
+ int pos3 = s.find(QString::fromLatin1("<br>"), pos2+1, false);
+ if(pos3 > -1) {
+ d = s.mid(pos2, pos3-pos2).remove(tagRx).simplifyWhiteSpace();
+ }
+ }
+ }
+#ifndef IBS_TEST
+ if(!u.isEmpty()) {
+ SearchResult* r = new SearchResult(this, t, d, QString());
+ emit signalResultFound(r);
+ m_matches.insert(r->uid, u.replace(QString::fromLatin1("&amp;"), QChar('&')));
+ }
+#endif
+
+ stop();
+}
+
+void IBSFetcher::slotCompleteISBN(KIO::Job* job_) {
+ // since the fetch is done, don't worry about holding the job pointer
+ m_job = 0;
+
+ if(job_->error()) {
+ job_->showErrorDialog(Kernel::self()->widget());
+ stop();
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "IBSFetcher::slotCompleteISBN() - no data" << endl;
+ stop();
+ return;
+ }
+
+ QString str = Tellico::decodeHTML(QString(m_data));
+ if(str.find(QString::fromLatin1("Libro non presente"), 0, false /* cas-sensitive */) > -1) {
+ stop();
+ return;
+ }
+ Data::EntryPtr entry = parseEntry(str);
+ if(entry) {
+ QString desc = entry->field(QString::fromLatin1("author"))
+ + '/' + entry->field(QString::fromLatin1("publisher"));
+ SearchResult* r = new SearchResult(this, entry->title(), desc, entry->field(QString::fromLatin1("isbn")));
+ emit signalResultFound(r);
+ m_matches.insert(r->uid, static_cast<KIO::TransferJob*>(job_)->url().url());
+ }
+
+ stop();
+}
+
+Tellico::Data::EntryPtr IBSFetcher::fetchEntry(uint uid_) {
+ // if we already grabbed this one, then just pull it out of the dict
+ Data::EntryPtr entry = m_entries[uid_];
+ if(entry) {
+ return entry;
+ }
+
+ KURL url = m_matches[uid_];
+ if(url.isEmpty()) {
+ kdWarning() << "IBSFetcher::fetchEntry() - no url in map" << endl;
+ return 0;
+ }
+
+ QString results = Tellico::decodeHTML(FileHandler::readTextFile(url, true));
+ if(results.isEmpty()) {
+ myDebug() << "IBSFetcher::fetchEntry() - no text results" << endl;
+ return 0;
+ }
+
+// myDebug() << url.url() << endl;
+#if 0
+ kdWarning() << "Remove debug from ibsfetcher.cpp" << endl;
+ QFile f(QString::fromLatin1("/tmp/test.html"));
+ if(f.open(IO_WriteOnly)) {
+ QTextStream t(&f);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << results;
+ }
+ f.close();
+#endif
+
+ entry = parseEntry(results);
+ if(!entry) {
+ myDebug() << "IBSFetcher::fetchEntry() - error in processing entry" << endl;
+ return 0;
+ }
+ m_entries.insert(uid_, entry); // keep for later
+ return entry;
+}
+
+Tellico::Data::EntryPtr IBSFetcher::parseEntry(const QString& str_) {
+ // myDebug() << "IBSFetcher::parseEntry()" << endl;
+ // class might be anime_info_top
+ QString pat = QString::fromLatin1("%1(?:<[^>]+>)+([^<>\\s][^<>]+)");
+
+ QRegExp isbnRx(QString::fromLatin1("isbn=([\\dxX]{13})"), false);
+ QString isbn;
+ int pos = isbnRx.search(str_);
+ if(pos > -1) {
+ isbn = isbnRx.cap(1);
+ }
+
+ Data::CollPtr coll = new Data::BookCollection(true);
+
+ // map captions in HTML to field names
+ QMap<QString, QString> fieldMap;
+ fieldMap.insert(QString::fromLatin1("Titolo"), QString::fromLatin1("title"));
+ fieldMap.insert(QString::fromLatin1("Autore"), QString::fromLatin1("author"));
+ fieldMap.insert(QString::fromLatin1("Anno"), QString::fromLatin1("pub_year"));
+ fieldMap.insert(QString::fromLatin1("Categoria"), QString::fromLatin1("genre"));
+ fieldMap.insert(QString::fromLatin1("Rilegatura"), QString::fromLatin1("binding"));
+ fieldMap.insert(QString::fromLatin1("Editore"), QString::fromLatin1("publisher"));
+ fieldMap.insert(QString::fromLatin1("Dati"), QString::fromLatin1("edition"));
+
+ QRegExp pagesRx(QString::fromLatin1("(\\d+) p\\.(\\s*,\\s*)?"));
+ Data::EntryPtr entry = new Data::Entry(coll);
+
+ for(QMap<QString, QString>::Iterator it = fieldMap.begin(); it != fieldMap.end(); ++it) {
+ QRegExp infoRx(pat.arg(it.key()));
+ pos = infoRx.search(str_);
+ if(pos > -1) {
+ if(it.data() == Latin1Literal("edition")) {
+ int pos2 = pagesRx.search(infoRx.cap(1));
+ if(pos2 > -1) {
+ entry->setField(QString::fromLatin1("pages"), pagesRx.cap(1));
+ entry->setField(it.data(), infoRx.cap(1).remove(pagesRx));
+ } else {
+ entry->setField(it.data(), infoRx.cap(1));
+ }
+ } else {
+ entry->setField(it.data(), infoRx.cap(1));
+ }
+ }
+ }
+
+ // image
+ if(!isbn.isEmpty()) {
+ entry->setField(QString::fromLatin1("isbn"), isbn);
+#if 1
+ QString imgURL = QString::fromLatin1("http://giotto.ibs.it/cop/copt13.asp?f=%1").arg(isbn);
+ myLog() << "IBSFetcher() - cover = " << imgURL << endl;
+ QString id = ImageFactory::addImage(imgURL, true, QString::fromLatin1("http://internetbookshop.it"));
+ if(!id.isEmpty()) {
+ entry->setField(QString::fromLatin1("cover"), id);
+ }
+#else
+ QRegExp imgRx(QString::fromLatin1("<img\\s+[^>]*\\s*src\\s*=\\s*\"(http://[^/]*\\.ibs\\.it/[^\"]+e=%1)").arg(isbn));
+ imgRx.setMinimal(true);
+ pos = imgRx.search(str_);
+ if(pos > -1) {
+ myLog() << "IBSFetcher() - cover = " << imgRx.cap(1) << endl;
+ QString id = ImageFactory::addImage(imgRx.cap(1), true, QString::fromLatin1("http://internetbookshop.it"));
+ if(!id.isEmpty()) {
+ entry->setField(QString::fromLatin1("cover"), id);
+ }
+ }
+#endif
+ }
+
+ // now look for description
+ QRegExp descRx(QString::fromLatin1("Descrizione(?:<[^>]+>)+([^<>\\s].+)</span>"), false);
+ descRx.setMinimal(true);
+ pos = descRx.search(str_);
+ if(pos == -1) {
+ descRx.setPattern(QString::fromLatin1("In sintesi(?:<[^>]+>)+([^<>\\s].+)</span>"));
+ pos = descRx.search(str_);
+ }
+ if(pos > -1) {
+ Data::FieldPtr f = new Data::Field(QString::fromLatin1("plot"), i18n("Plot Summary"), Data::Field::Para);
+ coll->addField(f);
+ entry->setField(f, descRx.cap(1).simplifyWhiteSpace());
+ }
+
+ // IBS switches the surname and family name of the author
+ QStringList names = entry->fields(QString::fromLatin1("author"), false);
+ if(!names.isEmpty() && !names[0].isEmpty()) {
+ for(QStringList::Iterator it = names.begin(); it != names.end(); ++it) {
+ if((*it).find(',') > -1) {
+ continue; // skip if it has a comma
+ }
+ QStringList words = QStringList::split(' ', *it);
+ if(words.isEmpty()) {
+ continue;
+ }
+ // put first word in back
+ words.append(words[0]);
+ words.pop_front();
+ *it = words.join(QChar(' '));
+ }
+ entry->setField(QString::fromLatin1("author"), names.join(QString::fromLatin1("; ")));
+ }
+ return entry;
+}
+
+void IBSFetcher::updateEntry(Data::EntryPtr entry_) {
+ QString isbn = entry_->field(QString::fromLatin1("isbn"));
+ if(!isbn.isEmpty()) {
+ search(Fetch::ISBN, isbn);
+ return;
+ }
+ QString t = entry_->field(QString::fromLatin1("title"));
+ if(!t.isEmpty()) {
+ search(Fetch::Title, t);
+ return;
+ }
+
+ myDebug() << "IBSFetcher::updateEntry() - insufficient info to search" << endl;
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+Tellico::Fetch::ConfigWidget* IBSFetcher::configWidget(QWidget* parent_) const {
+ return new IBSFetcher::ConfigWidget(parent_);
+}
+
+IBSFetcher::ConfigWidget::ConfigWidget(QWidget* parent_)
+ : Fetch::ConfigWidget(parent_) {
+ QVBoxLayout* l = new QVBoxLayout(optionsWidget());
+ l->addWidget(new QLabel(i18n("This source has no options."), optionsWidget()));
+ l->addStretch();
+}
+
+QString IBSFetcher::ConfigWidget::preferredName() const {
+ return IBSFetcher::defaultName();
+}
+
+#include "ibsfetcher.moc"
diff --git a/src/fetch/ibsfetcher.h b/src/fetch/ibsfetcher.h
new file mode 100644
index 0000000..39326b2
--- /dev/null
+++ b/src/fetch/ibsfetcher.h
@@ -0,0 +1,87 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FETCH_IBSFETCHER_H
+#define TELLICO_FETCH_IBSFETCHER_H
+
+#include "fetcher.h"
+#include "configwidget.h"
+
+#include <qcstring.h> // for QByteArray
+#include <qguardedptr.h>
+
+namespace KIO {
+ class Job;
+}
+
+namespace Tellico {
+ namespace Fetch {
+
+/**
+ * A fetcher for animenfo.com
+ *
+ * @author Robby Stephenson
+ */
+class IBSFetcher : public Fetcher {
+Q_OBJECT
+
+public:
+ IBSFetcher(QObject* parent, const char* name = 0);
+ virtual ~IBSFetcher() {}
+
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual void search(FetchKey key, const QString& value);
+ // can search title, person, isbn, or keyword. No UPC or Raw for now.
+ virtual bool canSearch(FetchKey k) const { return k == Title || k == Person || k == ISBN || k == Keyword; }
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return IBS; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+
+ virtual void updateEntry(Data::EntryPtr entry);
+
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const;
+
+ class ConfigWidget : public Fetch::ConfigWidget {
+ public:
+ ConfigWidget(QWidget* parent_);
+ virtual void saveConfig(KConfigGroup&) {}
+ virtual QString preferredName() const;
+ };
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+private slots:
+ void slotData(KIO::Job* job, const QByteArray& data);
+ void slotComplete(KIO::Job* job);
+ void slotCompleteISBN(KIO::Job* job);
+
+private:
+ Data::EntryPtr parseEntry(const QString& str);
+
+ QByteArray m_data;
+ int m_total;
+ QMap<int, Data::EntryPtr> m_entries;
+ QMap<int, KURL> m_matches;
+ QGuardedPtr<KIO::Job> m_job;
+
+ bool m_started;
+// QStringList m_fields;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/fetch/imdbfetcher.cpp b/src/fetch/imdbfetcher.cpp
new file mode 100644
index 0000000..1066177
--- /dev/null
+++ b/src/fetch/imdbfetcher.cpp
@@ -0,0 +1,1208 @@
+/***************************************************************************
+ copyright : (C) 2004-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "imdbfetcher.h"
+#include "../tellico_kernel.h"
+#include "../collections/videocollection.h"
+#include "../entry.h"
+#include "../field.h"
+#include "../filehandler.h"
+#include "../latin1literal.h"
+#include "../imagefactory.h"
+#include "../tellico_utils.h"
+#include "../gui/listboxtext.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+#include <kdialogbase.h>
+#include <kconfig.h>
+#include <klineedit.h>
+#include <knuminput.h>
+
+#include <qregexp.h>
+#include <qfile.h>
+#include <qmap.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qlistbox.h>
+#include <qwhatsthis.h>
+#include <qlayout.h>
+#include <qcheckbox.h>
+#include <qvgroupbox.h>
+
+//#define IMDB_TEST
+
+namespace {
+ static const char* IMDB_SERVER = "akas.imdb.com";
+ static const uint IMDB_MAX_RESULTS = 20;
+ static const QString sep = QString::fromLatin1("; ");
+}
+
+using Tellico::Fetch::IMDBFetcher;
+
+QRegExp* IMDBFetcher::s_tagRx = 0;
+QRegExp* IMDBFetcher::s_anchorRx = 0;
+QRegExp* IMDBFetcher::s_anchorTitleRx = 0;
+QRegExp* IMDBFetcher::s_anchorNameRx = 0;
+QRegExp* IMDBFetcher::s_titleRx = 0;
+
+// static
+void IMDBFetcher::initRegExps() {
+ s_tagRx = new QRegExp(QString::fromLatin1("<.*>"));
+ s_tagRx->setMinimal(true);
+
+ s_anchorRx = new QRegExp(QString::fromLatin1("<a\\s+[^>]*href\\s*=\\s*\"([^\"]*)\"[^<]*>([^<]*)</a>"), false);
+ s_anchorRx->setMinimal(true);
+
+ s_anchorTitleRx = new QRegExp(QString::fromLatin1("<a\\s+[^>]*href\\s*=\\s*\"([^\"]*/title/[^\"]*)\"[^<]*>([^<]*)</a>"), false);
+ s_anchorTitleRx->setMinimal(true);
+
+ s_anchorNameRx = new QRegExp(QString::fromLatin1("<a\\s+[^>]*href\\s*=\\s*\"([^\"]*/name/[^\"]*)\"[^<]*>([^<]*)</a>"), false);
+ s_anchorNameRx->setMinimal(true);
+
+ s_titleRx = new QRegExp(QString::fromLatin1("<title>(.*)</title>"), false);
+ s_titleRx->setMinimal(true);
+}
+
+IMDBFetcher::IMDBFetcher(QObject* parent_, const char* name_) : Fetcher(parent_, name_),
+ m_job(0), m_started(false), m_fetchImages(true), m_host(QString::fromLatin1(IMDB_SERVER)),
+ m_limit(IMDB_MAX_RESULTS), m_countOffset(0) {
+ if(!s_tagRx) {
+ initRegExps();
+ }
+}
+
+IMDBFetcher::~IMDBFetcher() {
+}
+
+QString IMDBFetcher::defaultName() {
+ return i18n("Internet Movie Database");
+}
+
+QString IMDBFetcher::source() const {
+ return m_name.isEmpty() ? defaultName() : m_name;
+}
+
+bool IMDBFetcher::canFetch(int type) const {
+ return type == Data::Collection::Video;
+}
+
+void IMDBFetcher::readConfigHook(const KConfigGroup& config_) {
+ QString h = config_.readEntry("Host");
+ if(!h.isEmpty()) {
+ m_host = h;
+ }
+ m_numCast = config_.readNumEntry("Max Cast", 10);
+ m_fetchImages = config_.readBoolEntry("Fetch Images", true);
+ m_fields = config_.readListEntry("Custom Fields");
+}
+
+// multiple values not supported
+void IMDBFetcher::search(FetchKey key_, const QString& value_) {
+ m_key = key_;
+ m_value = value_;
+ m_started = true;
+ m_redirected = false;
+ m_data.truncate(0);
+ m_matches.clear();
+ m_popularTitles.truncate(0);
+ m_exactTitles.truncate(0);
+ m_partialTitles.truncate(0);
+ m_currentTitleBlock = Unknown;
+ m_countOffset = 0;
+
+// only search if current collection is a video collection
+ if(Kernel::self()->collectionType() != Data::Collection::Video) {
+ myDebug() << "IMDBFetcher::search() - collection type mismatch, stopping" << endl;
+ stop();
+ return;
+ }
+
+#ifdef IMDB_TEST
+ if(m_key == Title) {
+ m_url = KURL::fromPathOrURL(QString::fromLatin1("/home/robby/imdb-title.html"));
+ m_redirected = false;
+ } else {
+ m_url = KURL::fromPathOrURL(QString::fromLatin1("/home/robby/imdb-name.html"));
+ m_redirected = true;
+ }
+#else
+ m_url = KURL();
+ m_url.setProtocol(QString::fromLatin1("http"));
+ m_url.setHost(m_host.isEmpty() ? QString::fromLatin1(IMDB_SERVER) : m_host);
+ m_url.setPath(QString::fromLatin1("/find"));
+
+ switch(key_) {
+ case Title:
+ m_url.addQueryItem(QString::fromLatin1("s"), QString::fromLatin1("tt"));
+ break;
+
+ case Person:
+ m_url.addQueryItem(QString::fromLatin1("s"), QString::fromLatin1("nm"));
+ break;
+
+ default:
+ kdWarning() << "IMDBFetcher::search() - FetchKey not supported" << endl;
+ stop();
+ return;
+ }
+
+ // as far as I can tell, the url encoding should always be iso-8859-1
+ // not utf-8
+ m_url.addQueryItem(QString::fromLatin1("q"), value_, 4 /* iso-8859-1 */);
+
+// myDebug() << "IMDBFetcher::search() url = " << m_url << endl;
+#endif
+
+ m_job = KIO::get(m_url, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+ connect(m_job, SIGNAL(redirection(KIO::Job *, const KURL&)),
+ SLOT(slotRedirection(KIO::Job*, const KURL&)));
+}
+
+void IMDBFetcher::continueSearch() {
+ m_started = true;
+ m_limit += IMDB_MAX_RESULTS;
+
+ if(m_currentTitleBlock == Popular) {
+ parseTitleBlock(m_popularTitles);
+ // if the offset is 0, then we need to be looking at the next block
+ m_currentTitleBlock = m_countOffset == 0 ? Exact : Popular;
+ }
+
+ // current title block might have changed
+ if(m_currentTitleBlock == Exact) {
+ parseTitleBlock(m_exactTitles);
+ m_currentTitleBlock = m_countOffset == 0 ? Partial : Exact;
+ }
+
+ if(m_currentTitleBlock == Partial) {
+ parseTitleBlock(m_partialTitles);
+ m_currentTitleBlock = m_countOffset == 0 ? Unknown : Partial;
+ }
+
+ if(m_currentTitleBlock == SinglePerson) {
+ parseSingleNameResult();
+ }
+
+ stop();
+}
+
+void IMDBFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+// myLog() << "IMDBFetcher::stop()" << endl;
+ if(m_job) {
+ m_job->kill();
+ m_job = 0;
+ }
+
+ m_started = false;
+ m_redirected = false;
+
+ emit signalDone(this);
+}
+
+void IMDBFetcher::slotData(KIO::Job*, const QByteArray& data_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(data_.data(), data_.size());
+}
+
+void IMDBFetcher::slotRedirection(KIO::Job*, const KURL& toURL_) {
+ m_url = toURL_;
+ m_redirected = true;
+}
+
+void IMDBFetcher::slotComplete(KIO::Job* job_) {
+ // since the fetch is done, don't worry about holding the job pointer
+ m_job = 0;
+
+ if(job_->error()) {
+ job_->showErrorDialog(Kernel::self()->widget());
+ stop();
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ stop();
+ return;
+ }
+
+ // a single result was found if we got redirected
+ if(m_key == Title) {
+ if(m_redirected) {
+ parseSingleTitleResult();
+ } else {
+ parseMultipleTitleResults();
+ }
+ } else {
+ if(m_redirected) {
+ parseSingleNameResult();
+ } else {
+ parseMultipleNameResults();
+ }
+ }
+}
+
+void IMDBFetcher::parseSingleTitleResult() {
+// myDebug() << "IMDBFetcher::parseSingleTitleResult()" << endl;
+ s_titleRx->search(Tellico::decodeHTML(QString(m_data)));
+ // split title at parenthesis
+ const QString cap1 = s_titleRx->cap(1);
+ int pPos = cap1.find('(');
+ // FIXME: maybe remove parentheses here?
+ SearchResult* r = new SearchResult(this,
+ pPos == -1 ? cap1 : cap1.left(pPos),
+ pPos == -1 ? QString::null : cap1.mid(pPos),
+ QString());
+ m_matches.insert(r->uid, m_url);
+ emit signalResultFound(r);
+
+ m_hasMoreResults = false;
+ stop();
+}
+
+void IMDBFetcher::parseMultipleTitleResults() {
+// myDebug() << "IMDBFetcher::parseMultipleTitleResults()" << endl;
+ QString output = Tellico::decodeHTML(QString(m_data));
+
+ // IMDb can return three title lists, popular, exact, and partial
+ // the popular titles are in the first table, after the "Popular Results" text
+ int pos_popular = output.find(QString::fromLatin1("Popular Titles"), 0, false);
+ int pos_exact = output.find(QString::fromLatin1("Exact Matches"), QMAX(pos_popular, 0), false);
+ int pos_partial = output.find(QString::fromLatin1("Partial Matches"), QMAX(pos_exact, 0), false);
+ int end_popular = pos_exact; // keep track of where to end
+ if(end_popular == -1) {
+ end_popular = pos_partial == -1 ? output.length() : pos_partial;
+ }
+ int end_exact = pos_partial; // keep track of where to end
+ if(end_exact == -1) {
+ end_exact = output.length();
+ }
+
+ // if found popular matches
+ if(pos_popular > -1) {
+ m_popularTitles = output.mid(pos_popular, end_popular-pos_popular);
+ }
+ // if found exact matches
+ if(pos_exact > -1) {
+ m_exactTitles = output.mid(pos_exact, end_exact-pos_exact);
+ }
+ if(pos_partial > -1) {
+ m_partialTitles = output.mid(pos_partial);
+ }
+
+ parseTitleBlock(m_popularTitles);
+ // if the offset is 0, then we need to be looking at the next block
+ m_currentTitleBlock = m_countOffset == 0 ? Exact : Popular;
+
+ if(m_matches.size() < m_limit) {
+ parseTitleBlock(m_exactTitles);
+ m_currentTitleBlock = m_countOffset == 0 ? Partial : Exact;
+ }
+
+ if(m_matches.size() < m_limit) {
+ parseTitleBlock(m_partialTitles);
+ m_currentTitleBlock = m_countOffset == 0 ? Unknown : Partial;
+ }
+
+#ifndef NDEBUG
+ if(m_matches.size() == 0) {
+ myDebug() << "IMDBFetcher::parseMultipleTitleResults() - no matches found." << endl;
+ }
+#endif
+
+ stop();
+}
+
+void IMDBFetcher::parseTitleBlock(const QString& str_) {
+ if(str_.isEmpty()) {
+ m_countOffset = 0;
+ return;
+ }
+// myDebug() << "IMDBFetcher::parseTitleBlock() - " << m_currentTitleBlock << endl;
+
+ QRegExp akaRx(QString::fromLatin1("aka (.*)(</li>|<br)"), false);
+ akaRx.setMinimal(true);
+
+ m_hasMoreResults = false;
+
+ int count = 0;
+ int start = s_anchorTitleRx->search(str_);
+ while(m_started && start > -1) {
+ // split title at parenthesis
+ const QString cap1 = s_anchorTitleRx->cap(1); // the anchor url
+ const QString cap2 = s_anchorTitleRx->cap(2).stripWhiteSpace(); // the anchor text
+ start += s_anchorTitleRx->matchedLength();
+ int pPos = cap2.find('('); // if it has parentheses, use that for description
+ QString desc;
+ if(pPos > -1) {
+ int pPos2 = cap2.find(')', pPos+1);
+ if(pPos2 > -1) {
+ desc = cap2.mid(pPos+1, pPos2-pPos-1);
+ }
+ } else {
+ // parenthesis might be outside anchor tag
+ int end = s_anchorTitleRx->search(str_, start);
+ if(end == -1) {
+ end = str_.length();
+ }
+ QString text = str_.mid(start, end-start);
+ pPos = text.find('(');
+ if(pPos > -1) {
+ int pNewLine = text.find(QString::fromLatin1("<br"));
+ if(pNewLine == -1 || pPos < pNewLine) {
+ int pPos2 = text.find(')', pPos);
+ desc = text.mid(pPos+1, pPos2-pPos-1);
+ }
+ pPos = -1;
+ }
+ }
+ // multiple matches might have 'aka' info
+ int end = s_anchorTitleRx->search(str_, start+1);
+ if(end == -1) {
+ end = str_.length();
+ }
+ int akaPos = akaRx.search(str_, start+1);
+ if(akaPos > -1 && akaPos < end) {
+ // limit to 50 chars
+ desc += QChar(' ') + akaRx.cap(1).stripWhiteSpace().remove(*s_tagRx);
+ if(desc.length() > 50) {
+ desc = desc.left(50) + QString::fromLatin1("...");
+ }
+ }
+
+ start = s_anchorTitleRx->search(str_, start);
+
+ if(count < m_countOffset) {
+ ++count;
+ continue;
+ }
+
+ // if we got this far, then there is a valid result
+ if(m_matches.size() >= m_limit) {
+ m_hasMoreResults = true;
+ break;
+ }
+
+ SearchResult* r = new SearchResult(this, pPos == -1 ? cap2 : cap2.left(pPos), desc, QString());
+ KURL u(m_url, cap1);
+ u.setQuery(QString::null);
+ m_matches.insert(r->uid, u);
+ emit signalResultFound(r);
+ ++count;
+ }
+ if(!m_hasMoreResults && m_currentTitleBlock != Partial) {
+ m_hasMoreResults = true;
+ }
+ m_countOffset = m_matches.size() < m_limit ? 0 : count;
+}
+
+void IMDBFetcher::parseSingleNameResult() {
+// myDebug() << "IMDBFetcher::parseSingleNameResult()" << endl;
+
+ m_currentTitleBlock = SinglePerson;
+
+ QString output = Tellico::decodeHTML(QString(m_data));
+
+ int pos = s_anchorTitleRx->search(output);
+ if(pos == -1) {
+ stop();
+ return;
+ }
+
+ QRegExp tvRegExp(QString::fromLatin1("TV\\sEpisode"), false);
+
+ int len = 0;
+ int count = 0;
+ QString desc;
+ for( ; m_started && pos > -1; pos = s_anchorTitleRx->search(output, pos+len)) {
+ desc.truncate(0);
+ bool isEpisode = false;
+ len = s_anchorTitleRx->cap(0).length();
+ // split title at parenthesis
+ const QString cap2 = s_anchorTitleRx->cap(2).stripWhiteSpace();
+ int pPos = cap2.find('(');
+ if(pPos > -1) {
+ desc = cap2.mid(pPos);
+ } else {
+ // look until the next <a
+ int aPos = output.find(QString::fromLatin1("<a"), pos+len, false);
+ if(aPos == -1) {
+ aPos = output.length();
+ }
+ QString tmp = output.mid(pos+len, aPos-pos-len);
+ if(tmp.find(tvRegExp) > -1) {
+ isEpisode = true;
+ }
+ pPos = tmp.find('(');
+ if(pPos > -1) {
+ int pNewLine = tmp.find(QString::fromLatin1("<br"));
+ if(pNewLine == -1 || pPos < pNewLine) {
+ int pEnd = tmp.find(')', pPos+1);
+ desc = tmp.mid(pPos+1, pEnd-pPos-1).remove(*s_tagRx);
+ }
+ // but need to indicate it wasn't found initially
+ pPos = -1;
+ }
+ }
+
+ ;
+
+ if(count < m_countOffset) {
+ ++count;
+ continue;
+ }
+
+ ++count;
+ if(isEpisode) {
+ continue;
+ }
+
+ // if we got this far, then there is a valid result
+ if(m_matches.size() >= m_limit) {
+ m_hasMoreResults = true;
+ break;
+ }
+
+ // FIXME: maybe remove parentheses here?
+ SearchResult* r = new SearchResult(this, pPos == -1 ? cap2 : cap2.left(pPos), desc, QString());
+ KURL u(m_url, s_anchorTitleRx->cap(1)); // relative URL constructor
+ u.setQuery(QString::null);
+ m_matches.insert(r->uid, u);
+// myDebug() << u.prettyURL() << endl;
+// myDebug() << cap2 << endl;
+ emit signalResultFound(r);
+ }
+ if(pos == -1) {
+ m_hasMoreResults = false;
+ }
+ m_countOffset = count - 1;
+
+ stop();
+}
+
+void IMDBFetcher::parseMultipleNameResults() {
+// myDebug() << "IMDBFetcher::parseMultipleNameResults()" << endl;
+
+ // the exact results are in the first table after the "exact results" text
+ QString output = Tellico::decodeHTML(QString(m_data));
+ int pos = output.find(QString::fromLatin1("Popular Results"), 0, false);
+ if(pos == -1) {
+ pos = output.find(QString::fromLatin1("Exact Matches"), 0, false);
+ }
+
+ // find beginning of partial matches
+ int end = output.find(QString::fromLatin1("Other Results"), QMAX(pos, 0), false);
+ if(end == -1) {
+ end = output.find(QString::fromLatin1("Partial Matches"), QMAX(pos, 0), false);
+ if(end == -1) {
+ end = output.find(QString::fromLatin1("Approx Matches"), QMAX(pos, 0), false);
+ if(end == -1) {
+ end = output.length();
+ }
+ }
+ }
+
+ QMap<QString, KURL> map;
+ QMap<QString, int> nameMap;
+
+ QString s;
+ // if found exact matches
+ if(pos > -1) {
+ pos = s_anchorNameRx->search(output, pos+13);
+ while(pos > -1 && pos < end && m_matches.size() < m_limit) {
+ KURL u(m_url, s_anchorNameRx->cap(1));
+ s = s_anchorNameRx->cap(2).stripWhiteSpace() + ' ';
+ // if more than one exact, add parentheses
+ if(nameMap.contains(s) && nameMap[s] > 0) {
+ // fix the first one that didn't have a number
+ if(nameMap[s] == 1) {
+ KURL u2 = map[s];
+ map.remove(s);
+ map.insert(s + "(1) ", u2);
+ }
+ nameMap.insert(s, nameMap[s] + 1);
+ // check for duplicate names
+ s += QString::fromLatin1("(%1) ").arg(nameMap[s]);
+ } else {
+ nameMap.insert(s, 1);
+ }
+ map.insert(s, u);
+ pos = s_anchorNameRx->search(output, pos+s_anchorNameRx->cap(0).length());
+ }
+ }
+
+ // go ahead and search for partial matches
+ pos = s_anchorNameRx->search(output, end);
+ while(pos > -1 && m_matches.size() < m_limit) {
+ KURL u(m_url, s_anchorNameRx->cap(1)); // relative URL
+ s = s_anchorNameRx->cap(2).stripWhiteSpace();
+ if(nameMap.contains(s) && nameMap[s] > 0) {
+ // fix the first one that didn't have a number
+ if(nameMap[s] == 1) {
+ KURL u2 = map[s];
+ map.remove(s);
+ map.insert(s + " (1)", u2);
+ }
+ nameMap.insert(s, nameMap[s] + 1);
+ // check for duplicate names
+ s += QString::fromLatin1(" (%1)").arg(nameMap[s]);
+ } else {
+ nameMap.insert(s, 1);
+ }
+ map.insert(s, u);
+ pos = s_anchorNameRx->search(output, pos+s_anchorNameRx->cap(0).length());
+ }
+
+ if(map.count() == 0) {
+ stop();
+ return;
+ }
+
+ KDialogBase* dlg = new KDialogBase(Kernel::self()->widget(), "imdb dialog",
+ true, i18n("Select IMDB Result"), KDialogBase::Ok|KDialogBase::Cancel);
+ QVBox* box = new QVBox(dlg);
+ box->setSpacing(10);
+ (void) new QLabel(i18n("<qt>Your search returned multiple matches. Please select one below.</qt>"), box);
+
+ QListBox* listBox = new QListBox(box);
+ listBox->setMinimumWidth(400);
+ listBox->setColumnMode(QListBox::FitToWidth);
+ const QStringList values = map.keys();
+ for(QStringList::ConstIterator it = values.begin(); it != values.end(); ++it) {
+ if((*it).endsWith(QChar(' '))) {
+ GUI::ListBoxText* box = new GUI::ListBoxText(listBox, *it, 0);
+ box->setColored(true);
+ } else {
+ (void) new GUI::ListBoxText(listBox, *it);
+ }
+ }
+ listBox->setSelected(0, true);
+ QWhatsThis::add(listBox, i18n("<qt>Select a search result.</qt>"));
+
+ dlg->setMainWidget(box);
+ if(dlg->exec() != QDialog::Accepted || listBox->currentText().isEmpty()) {
+ dlg->delayedDestruct();
+ stop();
+ return;
+ }
+
+ m_url = map[listBox->currentText()];
+ dlg->delayedDestruct();
+
+ // redirected is true since that's how I tell if an exact match has been found
+ m_redirected = true;
+ m_data.truncate(0);
+ m_job = KIO::get(m_url, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+ connect(m_job, SIGNAL(redirection(KIO::Job *, const KURL&)),
+ SLOT(slotRedirection(KIO::Job*, const KURL&)));
+
+ // do not stop() here
+}
+
+Tellico::Data::EntryPtr IMDBFetcher::fetchEntry(uint uid_) {
+ // if we already grabbed this one, then just pull it out of the dict
+ Data::EntryPtr entry = m_entries[uid_];
+ if(entry) {
+ return entry;
+ }
+
+ KURL url = m_matches[uid_];
+ if(url.isEmpty()) {
+ myDebug() << "IMDBFetcher::fetchEntry() - no url found" << endl;
+ return 0;
+ }
+
+ KURL origURL = m_url; // keep to switch back
+ QString results;
+ // if the url matches the current one, no need to redownload it
+ if(url == m_url) {
+// myDebug() << "IMDBFetcher::fetchEntry() - matches previous URL, no downloading needed." << endl;
+ results = Tellico::decodeHTML(QString(m_data));
+ } else {
+ // now it's sychronous
+#ifdef IMDB_TEST
+ KURL u = KURL::fromPathOrURL(QString::fromLatin1("/home/robby/imdb-title-result.html"));
+ results = Tellico::decodeHTML(FileHandler::readTextFile(u));
+#else
+ // be quiet about failure
+ results = Tellico::decodeHTML(FileHandler::readTextFile(url, true));
+ m_url = url; // needed for processing
+#endif
+ }
+ if(results.isEmpty()) {
+ myDebug() << "IMDBFetcher::fetchEntry() - no text results" << endl;
+ m_url = origURL;
+ return 0;
+ }
+
+ entry = parseEntry(results);
+ m_url = origURL;
+ if(!entry) {
+ myDebug() << "IMDBFetcher::fetchEntry() - error in processing entry" << endl;
+ return 0;
+ }
+ m_entries.insert(uid_, entry); // keep for later
+ return entry;
+}
+
+Tellico::Data::EntryPtr IMDBFetcher::parseEntry(const QString& str_) {
+ Data::CollPtr coll = new Data::VideoCollection(true);
+ Data::EntryPtr entry = new Data::Entry(coll);
+
+ doTitle(str_, entry);
+ doRunningTime(str_, entry);
+ doAspectRatio(str_, entry);
+ doAlsoKnownAs(str_, entry);
+ doPlot(str_, entry, m_url);
+ doLists(str_, entry);
+ doPerson(str_, entry, QString::fromLatin1("Director"), QString::fromLatin1("director"));
+ doPerson(str_, entry, QString::fromLatin1("Writer"), QString::fromLatin1("writer"));
+ doRating(str_, entry);
+ doCast(str_, entry, m_url);
+ if(m_fetchImages) {
+ // needs base URL
+ doCover(str_, entry, m_url);
+ }
+
+ const QString imdb = QString::fromLatin1("imdb");
+ if(!coll->hasField(imdb) && m_fields.findIndex(imdb) > -1) {
+ Data::FieldPtr field = new Data::Field(imdb, i18n("IMDB Link"), Data::Field::URL);
+ field->setCategory(i18n("General"));
+ coll->addField(field);
+ }
+ if(coll->hasField(imdb) && coll->fieldByName(imdb)->type() == Data::Field::URL) {
+ m_url.setQuery(QString::null);
+ entry->setField(imdb, m_url.url());
+ }
+ return entry;
+}
+
+void IMDBFetcher::doTitle(const QString& str_, Data::EntryPtr entry_) {
+ if(s_titleRx->search(str_) > -1) {
+ const QString cap1 = s_titleRx->cap(1);
+ // titles always have parentheses
+ int pPos = cap1.find('(');
+ QString title = cap1.left(pPos).stripWhiteSpace();
+ // remove first and last quotes is there
+ if(title.startsWith(QChar('"')) && title.endsWith(QChar('"'))) {
+ title = title.mid(1, title.length()-2);
+ }
+ entry_->setField(QString::fromLatin1("title"), title);
+ // remove parenthesis
+ uint pPos2 = pPos+1;
+ while(pPos2 < cap1.length() && cap1[pPos2].isDigit()) {
+ ++pPos2;
+ }
+ QString year = cap1.mid(pPos+1, pPos2-pPos-1);
+ if(!year.isEmpty()) {
+ entry_->setField(QString::fromLatin1("year"), year);
+ }
+ }
+}
+
+void IMDBFetcher::doRunningTime(const QString& str_, Data::EntryPtr entry_) {
+ // running time
+ QRegExp runtimeRx(QString::fromLatin1("runtime:.*(\\d+)\\s+min"), false);
+ runtimeRx.setMinimal(true);
+
+ if(runtimeRx.search(str_) > -1) {
+// myDebug() << "running-time = " << runtimeRx.cap(1) << endl;
+ entry_->setField(QString::fromLatin1("running-time"), runtimeRx.cap(1));
+ }
+}
+
+void IMDBFetcher::doAspectRatio(const QString& str_, Data::EntryPtr entry_) {
+ QRegExp rx(QString::fromLatin1("aspect ratio:.*([\\d\\.]+\\s*:\\s*[\\d\\.]+)"), false);
+ rx.setMinimal(true);
+
+ if(rx.search(str_) > -1) {
+// myDebug() << "aspect ratio = " << rx.cap(1) << endl;
+ entry_->setField(QString::fromLatin1("aspect-ratio"), rx.cap(1).stripWhiteSpace());
+ }
+}
+
+void IMDBFetcher::doAlsoKnownAs(const QString& str_, Data::EntryPtr entry_) {
+ if(m_fields.findIndex(QString::fromLatin1("alttitle")) == -1) {
+ return;
+ }
+
+ // match until next b tag
+// QRegExp akaRx(QString::fromLatin1("also known as(.*)<b(?:\\s.*)?>"));
+ QRegExp akaRx(QString::fromLatin1("also known as(.*)<(b[>\\s/]|div)"), false);
+ akaRx.setMinimal(true);
+
+ if(akaRx.search(str_) > -1 && !akaRx.cap(1).isEmpty()) {
+ Data::FieldPtr f = entry_->collection()->fieldByName(QString::fromLatin1("alttitle"));
+ if(!f) {
+ f = new Data::Field(QString::fromLatin1("alttitle"), i18n("Alternative Titles"), Data::Field::Table);
+ f->setFormatFlag(Data::Field::FormatTitle);
+ entry_->collection()->addField(f);
+ }
+
+ // split by <br>, remembering it could become valid xhtml!
+ QRegExp brRx(QString::fromLatin1("<br[\\s/]*>"), false);
+ brRx.setMinimal(true);
+ QStringList list = QStringList::split(brRx, akaRx.cap(1));
+ // lang could be included with [fr]
+// const QRegExp parRx(QString::fromLatin1("\\(.+\\)"));
+ const QRegExp brackRx(QString::fromLatin1("\\[\\w+\\]"));
+ QStringList values;
+ for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
+ QString s = *it;
+ // sometimes, the word "more" gets linked to the releaseinfo page, check that
+ if(s.find(QString::fromLatin1("releaseinfo")) > -1) {
+ continue;
+ }
+ s.remove(*s_tagRx);
+ s.remove(brackRx);
+ s = s.stripWhiteSpace();
+ // the first value ends up being or starting with the colon after "Also know as"
+ // I'm too lazy to figure out a better regexp
+ if(s.startsWith(QChar(':'))) {
+ s = s.mid(1);
+ }
+ if(!s.isEmpty()) {
+ values += s;
+ }
+ }
+ if(!values.isEmpty()) {
+ entry_->setField(QString::fromLatin1("alttitle"), values.join(sep));
+ }
+ }
+}
+
+void IMDBFetcher::doPlot(const QString& str_, Data::EntryPtr entry_, const KURL& baseURL_) {
+ // plot summaries provided by users are on a separate page
+ // should those be preferred?
+
+ bool useUserSummary = false;
+
+ QString thisPlot;
+ // match until next opening tag
+ QRegExp plotRx(QString::fromLatin1("plot (?:outline|summary):(.*)<[^/].*</"), false);
+ plotRx.setMinimal(true);
+ QRegExp plotURLRx(QString::fromLatin1("<a\\s+.*href\\s*=\\s*\".*/title/.*/plotsummary\""), false);
+ plotURLRx.setMinimal(true);
+ if(plotRx.search(str_) > -1) {
+ thisPlot = plotRx.cap(1);
+ thisPlot.remove(*s_tagRx); // remove HTML tags
+ entry_->setField(QString::fromLatin1("plot"), thisPlot);
+ // if thisPlot ends with (more) or contains
+ // a url that ends with plotsummary, then we'll grab it, otherwise not
+ if(plotRx.cap(0).endsWith(QString::fromLatin1("(more)</")) || plotURLRx.search(plotRx.cap(0)) > -1) {
+ useUserSummary = true;
+ }
+ }
+
+ if(useUserSummary) {
+ QRegExp idRx(QString::fromLatin1("title/(tt\\d+)"));
+ idRx.search(baseURL_.path());
+ KURL plotURL = baseURL_;
+ plotURL.setPath(QString::fromLatin1("/title/") + idRx.cap(1) + QString::fromLatin1("/plotsummary"));
+ // be quiet about failure
+ QString plotPage = FileHandler::readTextFile(plotURL, true);
+
+ if(!plotPage.isEmpty()) {
+ QRegExp plotRx(QString::fromLatin1("<p\\s+class\\s*=\\s*\"plotpar\">(.*)</p"));
+ plotRx.setMinimal(true);
+ if(plotRx.search(plotPage) > -1) {
+ QString userPlot = plotRx.cap(1);
+ userPlot.remove(*s_tagRx); // remove HTML tags
+ entry_->setField(QString::fromLatin1("plot"), Tellico::decodeHTML(userPlot));
+ }
+ }
+ }
+}
+
+void IMDBFetcher::doPerson(const QString& str_, Data::EntryPtr entry_,
+ const QString& imdbHeader_, const QString& fieldName_) {
+ QRegExp br2Rx(QString::fromLatin1("<br[\\s/]*>\\s*<br[\\s/]*>"), false);
+ br2Rx.setMinimal(true);
+ QRegExp divRx(QString::fromLatin1("<[/]*div"), false);
+ divRx.setMinimal(true);
+ QString name = QString::fromLatin1("/name/");
+
+ StringSet people;
+ for(int pos = str_.find(imdbHeader_); pos > 0; pos = str_.find(imdbHeader_, pos)) {
+ // loop until repeated <br> tags or </div> tag
+ const int endPos1 = str_.find(br2Rx, pos);
+ const int endPos2 = str_.find(divRx, pos);
+ const int endPos = QMIN(endPos1, endPos2); // ok to be -1
+ pos = s_anchorRx->search(str_, pos+1);
+ while(pos > -1 && pos < endPos) {
+ if(s_anchorRx->cap(1).find(name) > -1) {
+ people.add(s_anchorRx->cap(2).stripWhiteSpace());
+ }
+ pos = s_anchorRx->search(str_, pos+1);
+ }
+ }
+ if(!people.isEmpty()) {
+ entry_->setField(fieldName_, people.toList().join(sep));
+ }
+}
+
+void IMDBFetcher::doCast(const QString& str_, Data::EntryPtr entry_, const KURL& baseURL_) {
+ // the extended cast list is on a separate page
+ // that's usually a lot of people
+ // but since it can be in billing order, the main actors might not
+ // be in the short list
+ QRegExp idRx(QString::fromLatin1("title/(tt\\d+)"));
+ idRx.search(baseURL_.path());
+#ifdef IMDB_TEST
+ KURL castURL = KURL::fromPathOrURL(QString::fromLatin1("/home/robby/imdb-title-fullcredits.html"));
+#else
+ KURL castURL = baseURL_;
+ castURL.setPath(QString::fromLatin1("/title/") + idRx.cap(1) + QString::fromLatin1("/fullcredits"));
+#endif
+ // be quiet about failure and be sure to translate entities
+ QString castPage = Tellico::decodeHTML(FileHandler::readTextFile(castURL, true));
+
+ int pos = -1;
+ // the text to search, depends on which page is being read
+ QString castText = castPage;
+ if(castText.isEmpty()) {
+ // fall back to short list
+ castText = str_;
+ pos = castText.find(QString::fromLatin1("cast overview"), 0, false);
+ if(pos == -1) {
+ pos = castText.find(QString::fromLatin1("credited cast"), 0, false);
+ }
+ } else {
+ // first look for anchor
+ QRegExp castAnchorRx(QString::fromLatin1("<a\\s+name\\s*=\\s*\"cast\""), false);
+ pos = castText.find(castAnchorRx);
+ if(pos < 0) {
+ QRegExp tableClassRx(QString::fromLatin1("<table\\s+class\\s*=\\s*\"cast\""), false);
+ pos = castText.find(tableClassRx);
+ if(pos < 0) {
+ // fragile, the word "cast" appears in the title, but need to find
+ // the one right above the actual cast table
+ // for TV shows, there's a link on the sidebar for "episodes case"
+ // so need to not match that one
+ pos = castText.find(QString::fromLatin1("cast</"), 0, false);
+ if(pos > 9) {
+ // back up 9 places
+ if(castText.mid(pos-9, 9).startsWith(QString::fromLatin1("episodes"))) {
+ // find next cast list
+ pos = castText.find(QString::fromLatin1("cast</"), pos+6, false);
+ }
+ }
+ }
+ }
+ }
+ if(pos == -1) { // no cast list found
+ myDebug() << "IMDBFetcher::doCast() - no cast list found" << endl;
+ return;
+ }
+
+ const QString name = QString::fromLatin1("/name/");
+ QRegExp tdRx(QString::fromLatin1("<td[^>]*>(.*)</td>"), false);
+ tdRx.setMinimal(true);
+
+ QStringList cast;
+ // loop until closing table tag
+ const int endPos = castText.find(QString::fromLatin1("</table"), pos, false);
+ pos = s_anchorRx->search(castText, pos+1);
+ while(pos > -1 && pos < endPos && static_cast<int>(cast.count()) < m_numCast) {
+ if(s_anchorRx->cap(1).find(name) > -1) {
+ // now search for <td> item with character name
+ // there's a column with ellipses then the character
+ const int pos2 = tdRx.search(castText, pos);
+ if(pos2 > -1 && tdRx.search(castText, pos2+1) > -1) {
+ cast += s_anchorRx->cap(2).stripWhiteSpace()
+ + QString::fromLatin1("::") + tdRx.cap(1).simplifyWhiteSpace().remove(*s_tagRx);
+ } else {
+ cast += s_anchorRx->cap(2).stripWhiteSpace();
+ }
+ }
+ pos = s_anchorRx->search(castText, pos+1);
+ }
+
+ if(!cast.isEmpty()) {
+ entry_->setField(QString::fromLatin1("cast"), cast.join(sep));
+ }
+}
+
+void IMDBFetcher::doRating(const QString& str_, Data::EntryPtr entry_) {
+ if(m_fields.findIndex(QString::fromLatin1("imdb-rating")) == -1) {
+ return;
+ }
+
+ // don't add a colon, since there's a <br> at the end
+ // some of the imdb images use /10.gif in their path, so check for space or bracket
+ QRegExp rx(QString::fromLatin1("[>\\s](\\d+.?\\d*)/10[<//s]"), false);
+ rx.setMinimal(true);
+
+ if(rx.search(str_) > -1 && !rx.cap(1).isEmpty()) {
+ Data::FieldPtr f = entry_->collection()->fieldByName(QString::fromLatin1("imdb-rating"));
+ if(!f) {
+ f = new Data::Field(QString::fromLatin1("imdb-rating"), i18n("IMDB Rating"), Data::Field::Rating);
+ f->setCategory(i18n("General"));
+ f->setProperty(QString::fromLatin1("maximum"), QString::fromLatin1("10"));
+ entry_->collection()->addField(f);
+ }
+
+ bool ok;
+ float value = rx.cap(1).toFloat(&ok);
+ if(ok) {
+ entry_->setField(QString::fromLatin1("imdb-rating"), QString::number(value));
+ }
+ }
+}
+
+void IMDBFetcher::doCover(const QString& str_, Data::EntryPtr entry_, const KURL& baseURL_) {
+ // cover is the img with the "cover" alt text
+ QRegExp imgRx(QString::fromLatin1("<img\\s+[^>]*src\\s*=\\s*\"([^\"]*)\"[^>]*>"), false);
+ imgRx.setMinimal(true);
+
+ QRegExp posterRx(QString::fromLatin1("<a\\s+[^>]*name\\s*=\\s*\"poster\"[^>]*>(.*)</a>"), false);
+ posterRx.setMinimal(true);
+
+ const QString cover = QString::fromLatin1("cover");
+
+ int pos = posterRx.search(str_);
+ while(pos > -1) {
+ if(imgRx.search(posterRx.cap(1)) > -1) {
+ KURL u(baseURL_, imgRx.cap(1));
+ QString id = ImageFactory::addImage(u, true);
+ if(!id.isEmpty()) {
+ entry_->setField(cover, id);
+ }
+ return;
+ }
+ pos = posterRx.search(str_, pos+1);
+ }
+
+ // didn't find the cover, IMDb also used to put "cover" inside the url
+ pos = imgRx.search(str_);
+ while(pos > -1) {
+ if(imgRx.cap(0).find(cover, 0, false) > -1) {
+ KURL u(baseURL_, imgRx.cap(1));
+ QString id = ImageFactory::addImage(u, true);
+ if(!id.isEmpty()) {
+ entry_->setField(cover, id);
+ }
+ return;
+ }
+ pos = imgRx.search(str_, pos+1);
+ }
+}
+
+// end up reparsing whole string, but it's not really that slow
+// loook at every anchor tag in the string
+void IMDBFetcher::doLists(const QString& str_, Data::EntryPtr entry_) {
+ const QString genre = QString::fromLatin1("/Genres/");
+ const QString country = QString::fromLatin1("/Countries/");
+ const QString lang = QString::fromLatin1("/Languages/");
+ const QString colorInfo = QString::fromLatin1("color-info");
+ const QString cert = QString::fromLatin1("certificates=");
+ const QString soundMix = QString::fromLatin1("sound-mix=");
+ const QString year = QString::fromLatin1("/Years/");
+ const QString company = QString::fromLatin1("/company/");
+
+ // IIMdb also has links with the word "sections" in them, remove that
+ // for genres and nationalities
+
+ QStringList genres, countries, langs, certs, tracks, studios;
+ for(int pos = s_anchorRx->search(str_); pos > -1; pos = s_anchorRx->search(str_, pos+1)) {
+ const QString cap1 = s_anchorRx->cap(1);
+ if(cap1.find(genre) > -1) {
+ if(s_anchorRx->cap(2).find(QString::fromLatin1(" section"), 0, false) == -1) {
+ genres += s_anchorRx->cap(2).stripWhiteSpace();
+ }
+ } else if(cap1.find(country) > -1) {
+ if(s_anchorRx->cap(2).find(QString::fromLatin1(" section"), 0, false) == -1) {
+ countries += s_anchorRx->cap(2).stripWhiteSpace();
+ }
+ } else if(cap1.find(lang) > -1) {
+ langs += s_anchorRx->cap(2).stripWhiteSpace();
+ } else if(cap1.find(colorInfo) > -1) {
+ // change "black and white" to "black & white"
+ entry_->setField(QString::fromLatin1("color"),
+ s_anchorRx->cap(2).replace(QString::fromLatin1("and"), QChar('&')).stripWhiteSpace());
+ } else if(cap1.find(cert) > -1) {
+ certs += s_anchorRx->cap(2).stripWhiteSpace();
+ } else if(cap1.find(soundMix) > -1) {
+ tracks += s_anchorRx->cap(2).stripWhiteSpace();
+ } else if(cap1.find(company) > -1) {
+ studios += s_anchorRx->cap(2).stripWhiteSpace();
+ // if year field wasn't set before, do it now
+ } else if(entry_->field(QString::fromLatin1("year")).isEmpty() && cap1.find(year) > -1) {
+ entry_->setField(QString::fromLatin1("year"), s_anchorRx->cap(2).stripWhiteSpace());
+ }
+ }
+
+ entry_->setField(QString::fromLatin1("genre"), genres.join(sep));
+ entry_->setField(QString::fromLatin1("nationality"), countries.join(sep));
+ entry_->setField(QString::fromLatin1("language"), langs.join(sep));
+ entry_->setField(QString::fromLatin1("audio-track"), tracks.join(sep));
+ entry_->setField(QString::fromLatin1("studio"), studios.join(sep));
+ if(!certs.isEmpty()) {
+ // first try to set default certification
+ const QStringList& certsAllowed = entry_->collection()->fieldByName(QString::fromLatin1("certification"))->allowed();
+ for(QStringList::ConstIterator it = certs.begin(); it != certs.end(); ++it) {
+ QString country = (*it).section(':', 0, 0);
+ QString cert = (*it).section(':', 1, 1);
+ if(cert == Latin1Literal("Unrated")) {
+ cert = QChar('U');
+ }
+ cert += QString::fromLatin1(" (") + country + ')';
+ if(certsAllowed.findIndex(cert) > -1) {
+ entry_->setField(QString::fromLatin1("certification"), cert);
+ break;
+ }
+ }
+
+ // now add new field for all certifications
+ const QString allc = QString::fromLatin1("allcertification");
+ if(m_fields.findIndex(allc) > -1) {
+ Data::FieldPtr f = entry_->collection()->fieldByName(allc);
+ if(!f) {
+ f = new Data::Field(allc, i18n("Certifications"), Data::Field::Table);
+ f->setFlags(Data::Field::AllowGrouped);
+ entry_->collection()->addField(f);
+ }
+ entry_->setField(QString::fromLatin1("allcertification"), certs.join(sep));
+ }
+ }
+}
+
+void IMDBFetcher::updateEntry(Data::EntryPtr entry_) {
+// myLog() << "IMDBFetcher::updateEntry() - " << entry_->title() << endl;
+ // only take first 5
+ m_limit = 5;
+ QString t = entry_->field(QString::fromLatin1("title"));
+ KURL link = entry_->field(QString::fromLatin1("imdb"));
+ if(!link.isEmpty() && link.isValid()) {
+ // check if we want a different host
+ if(link.host() != m_host) {
+// myLog() << "IMDBFetcher::updateEntry() - switching hosts to " << m_host << endl;
+ link.setHost(m_host);
+ }
+ m_key = Fetch::Title;
+ m_value = t;
+ m_started = true;
+ m_data.truncate(0);
+ m_matches.clear();
+ m_url = link;
+ m_redirected = true; // m_redirected is used as a flag later to tell if we get a single result
+ m_job = KIO::get(m_url, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+ connect(m_job, SIGNAL(redirection(KIO::Job *, const KURL&)),
+ SLOT(slotRedirection(KIO::Job*, const KURL&)));
+ return;
+ }
+ // optimistically try searching for title and rely on Collection::sameEntry() to figure things out
+ if(!t.isEmpty()) {
+ search(Fetch::Title, t);
+ return;
+ }
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+Tellico::Fetch::ConfigWidget* IMDBFetcher::configWidget(QWidget* parent_) const {
+ return new IMDBFetcher::ConfigWidget(parent_, this);
+}
+
+IMDBFetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const IMDBFetcher* fetcher_/*=0*/)
+ : Fetch::ConfigWidget(parent_) {
+ QGridLayout* l = new QGridLayout(optionsWidget(), 4, 2);
+ l->setSpacing(4);
+ l->setColStretch(1, 10);
+
+ int row = -1;
+ QLabel* label = new QLabel(i18n("Hos&t: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_hostEdit = new KLineEdit(optionsWidget());
+ connect(m_hostEdit, SIGNAL(textChanged(const QString&)), SLOT(slotSetModified()));
+ l->addWidget(m_hostEdit, row, 1);
+ QString w = i18n("The Internet Movie Database uses several different servers. Choose the one "
+ "you wish to use.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_hostEdit, w);
+ label->setBuddy(m_hostEdit);
+
+ label = new QLabel(i18n("&Maximum cast: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_numCast = new KIntSpinBox(0, 99, 1, 10, 10, optionsWidget());
+ connect(m_numCast, SIGNAL(valueChanged(const QString&)), SLOT(slotSetModified()));
+ l->addWidget(m_numCast, row, 1);
+ w = i18n("The list of cast members may include many people. Set the maximum number returned from the search.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_numCast, w);
+ label->setBuddy(m_numCast);
+
+ m_fetchImageCheck = new QCheckBox(i18n("Download cover &image"), optionsWidget());
+ connect(m_fetchImageCheck, SIGNAL(clicked()), SLOT(slotSetModified()));
+ ++row;
+ l->addMultiCellWidget(m_fetchImageCheck, row, row, 0, 1);
+ w = i18n("The cover image may be downloaded as well. However, too many large images in the "
+ "collection may degrade performance.");
+ QWhatsThis::add(m_fetchImageCheck, w);
+
+ l->setRowStretch(++row, 10);
+
+ // now add additional fields widget
+ addFieldsWidget(IMDBFetcher::customFields(), fetcher_ ? fetcher_->m_fields : QStringList());
+
+ if(fetcher_) {
+ m_hostEdit->setText(fetcher_->m_host);
+ m_numCast->setValue(fetcher_->m_numCast);
+ m_fetchImageCheck->setChecked(fetcher_->m_fetchImages);
+ } else { //defaults
+ m_hostEdit->setText(QString::fromLatin1(IMDB_SERVER));
+ m_numCast->setValue(10);
+ m_fetchImageCheck->setChecked(true);
+ }
+}
+
+void IMDBFetcher::ConfigWidget::saveConfig(KConfigGroup& config_) {
+ QString host = m_hostEdit->text().stripWhiteSpace();
+ if(!host.isEmpty()) {
+ config_.writeEntry("Host", host);
+ }
+ config_.writeEntry("Max Cast", m_numCast->value());
+ config_.writeEntry("Fetch Images", m_fetchImageCheck->isChecked());
+
+ saveFieldsConfig(config_);
+ slotSetModified(false);
+}
+
+QString IMDBFetcher::ConfigWidget::preferredName() const {
+ return IMDBFetcher::defaultName();
+}
+
+//static
+Tellico::StringMap IMDBFetcher::customFields() {
+ StringMap map;
+ map[QString::fromLatin1("imdb")] = i18n("IMDB Link");
+ map[QString::fromLatin1("imdb-rating")] = i18n("IMDB Rating");
+ map[QString::fromLatin1("alttitle")] = i18n("Alternative Titles");
+ map[QString::fromLatin1("allcertification")] = i18n("Certifications");
+ return map;
+}
+
+#include "imdbfetcher.moc"
diff --git a/src/fetch/imdbfetcher.h b/src/fetch/imdbfetcher.h
new file mode 100644
index 0000000..3dc19f2
--- /dev/null
+++ b/src/fetch/imdbfetcher.h
@@ -0,0 +1,141 @@
+/***************************************************************************
+ copyright : (C) 2004-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef IMDBFETCHER_H
+#define IMDBFETCHER_H
+
+#include "fetcher.h"
+#include "configwidget.h"
+#include "../datavectors.h"
+
+#include <kurl.h>
+#include <kio/job.h>
+
+#include <qcstring.h> // for QByteArray
+#include <qmap.h>
+#include <qguardedptr.h>
+
+class KLineEdit;
+class KIntSpinBox;
+class QCheckBox;
+class QRegExpr;
+
+namespace Tellico {
+ namespace Fetch {
+
+/**
+ * @author Robby Stephenson
+ */
+class IMDBFetcher : public Fetcher {
+Q_OBJECT
+
+public:
+ IMDBFetcher(QObject* parent, const char* name=0);
+ /**
+ */
+ virtual ~IMDBFetcher();
+
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual void search(FetchKey key, const QString& value);
+ virtual void continueSearch();
+ // imdb can search title, person
+ virtual bool canSearch(FetchKey k) const { return k == Title || k == Person; }
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return IMDB; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+
+ virtual void updateEntry(Data::EntryPtr entry);
+
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const;
+
+ static StringMap customFields();
+
+ class ConfigWidget : public Fetch::ConfigWidget {
+ public:
+ ConfigWidget(QWidget* parent_, const IMDBFetcher* fetcher = 0);
+ virtual void saveConfig(KConfigGroup& config);
+ virtual QString preferredName() const;
+
+ private:
+ KLineEdit* m_hostEdit;
+ QCheckBox* m_fetchImageCheck;
+ KIntSpinBox* m_numCast;
+ };
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+private slots:
+ void slotData(KIO::Job* job, const QByteArray& data);
+ void slotComplete(KIO::Job* job);
+ void slotRedirection(KIO::Job* job, const KURL& toURL);
+
+private:
+ static void initRegExps();
+ static QRegExp* s_tagRx;
+ static QRegExp* s_anchorRx;
+ static QRegExp* s_anchorTitleRx;
+ static QRegExp* s_anchorNameRx;
+ static QRegExp* s_titleRx;
+
+ void doTitle(const QString& s, Data::EntryPtr e);
+ void doRunningTime(const QString& s, Data::EntryPtr e);
+ void doAspectRatio(const QString& s, Data::EntryPtr e);
+ void doAlsoKnownAs(const QString& s, Data::EntryPtr e);
+ void doPlot(const QString& s, Data::EntryPtr e, const KURL& baseURL_);
+ void doPerson(const QString& s, Data::EntryPtr e,
+ const QString& imdbHeader, const QString& fieldName);
+ void doCast(const QString& s, Data::EntryPtr e, const KURL& baseURL_);
+ void doLists(const QString& s, Data::EntryPtr e);
+ void doRating(const QString& s, Data::EntryPtr e);
+ void doCover(const QString& s, Data::EntryPtr e, const KURL& baseURL);
+
+ void parseSingleTitleResult();
+ void parseSingleNameResult();
+ void parseMultipleTitleResults();
+ void parseTitleBlock(const QString& str);
+ void parseMultipleNameResults();
+ Data::EntryPtr parseEntry(const QString& str);
+
+ QByteArray m_data;
+ QMap<int, Data::EntryPtr> m_entries;
+ QMap<int, KURL> m_matches;
+ QGuardedPtr<KIO::Job> m_job;
+
+ FetchKey m_key;
+ QString m_value;
+ bool m_started;
+ bool m_fetchImages;
+
+ QString m_host;
+ int m_numCast;
+ KURL m_url;
+ bool m_redirected;
+ uint m_limit;
+ QStringList m_fields;
+
+ QString m_popularTitles;
+ QString m_exactTitles;
+ QString m_partialTitles;
+ enum TitleBlock { Unknown = 0, Popular = 1, Exact = 2, Partial = 3, SinglePerson = 4};
+ TitleBlock m_currentTitleBlock;
+ int m_countOffset;
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/fetch/isbndbfetcher.cpp b/src/fetch/isbndbfetcher.cpp
new file mode 100644
index 0000000..5ffc379
--- /dev/null
+++ b/src/fetch/isbndbfetcher.cpp
@@ -0,0 +1,350 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "isbndbfetcher.h"
+#include "messagehandler.h"
+#include "../translators/xslthandler.h"
+#include "../translators/tellicoimporter.h"
+#include "../tellico_kernel.h"
+#include "../tellico_utils.h"
+#include "../collection.h"
+#include "../entry.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kconfig.h>
+
+#include <qdom.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qfile.h>
+
+namespace {
+ static const int ISBNDB_RETURNS_PER_REQUEST = 10;
+ static const int ISBNDB_MAX_RETURNS_TOTAL = 25;
+ static const char* ISBNDB_BASE_URL = "http://isbndb.com/api/books.xml";
+ static const char* ISBNDB_APP_ID = "3B9S3BQS";
+}
+
+using Tellico::Fetch::ISBNdbFetcher;
+
+ISBNdbFetcher::ISBNdbFetcher(QObject* parent_, const char* name_)
+ : Fetcher(parent_, name_), m_xsltHandler(0),
+ m_limit(ISBNDB_MAX_RETURNS_TOTAL), m_page(1), m_total(-1), m_countOffset(0),
+ m_job(0), m_started(false) {
+}
+
+ISBNdbFetcher::~ISBNdbFetcher() {
+ delete m_xsltHandler;
+ m_xsltHandler = 0;
+}
+
+QString ISBNdbFetcher::defaultName() {
+ return i18n("ISBNdb.com");
+}
+
+QString ISBNdbFetcher::source() const {
+ return m_name.isEmpty() ? defaultName() : m_name;
+}
+
+bool ISBNdbFetcher::canFetch(int type) const {
+ return type == Data::Collection::Book || type == Data::Collection::ComicBook || type == Data::Collection::Bibtex;
+}
+
+void ISBNdbFetcher::readConfigHook(const KConfigGroup& config_) {
+ Q_UNUSED(config_);
+}
+
+void ISBNdbFetcher::search(FetchKey key_, const QString& value_) {
+ m_key = key_;
+ m_value = value_.stripWhiteSpace();
+ m_started = true;
+ m_page = 1;
+ m_total = -1;
+ m_numResults = 0;
+ m_countOffset = 0;
+
+ if(!canFetch(Kernel::self()->collectionType())) {
+ message(i18n("%1 does not allow searching for this collection type.").arg(source()), MessageHandler::Warning);
+ stop();
+ return;
+ }
+ doSearch();
+}
+
+void ISBNdbFetcher::continueSearch() {
+ m_started = true;
+ m_limit += ISBNDB_MAX_RETURNS_TOTAL;
+ doSearch();
+}
+
+void ISBNdbFetcher::doSearch() {
+ m_data.truncate(0);
+
+// myDebug() << "ISBNdbFetcher::search() - value = " << value_ << endl;
+
+ KURL u(QString::fromLatin1(ISBNDB_BASE_URL));
+ u.addQueryItem(QString::fromLatin1("access_key"), QString::fromLatin1(ISBNDB_APP_ID));
+ u.addQueryItem(QString::fromLatin1("results"), QString::fromLatin1("details,authors,subjects,texts"));
+ u.addQueryItem(QString::fromLatin1("page_number"), QString::number(m_page));
+
+ switch(m_key) {
+ case Title:
+ u.addQueryItem(QString::fromLatin1("index1"), QString::fromLatin1("title"));
+ u.addQueryItem(QString::fromLatin1("value1"), m_value);
+ break;
+
+ case Person:
+ // yes, this also queries titles, too, it's a limitation of the isbndb api service
+ u.addQueryItem(QString::fromLatin1("index1"), QString::fromLatin1("combined"));
+ u.addQueryItem(QString::fromLatin1("value1"), m_value);
+ break;
+
+ case Keyword:
+ u.addQueryItem(QString::fromLatin1("index1"), QString::fromLatin1("full"));
+ u.addQueryItem(QString::fromLatin1("value1"), m_value);
+ break;
+
+ case ISBN:
+ u.addQueryItem(QString::fromLatin1("index1"), QString::fromLatin1("isbn"));
+ {
+ // only grab first value
+ QString v = m_value.section(QChar(';'), 0);
+ v.remove('-');
+ u.addQueryItem(QString::fromLatin1("value1"), v);
+ }
+ break;
+
+ default:
+ kdWarning() << "ISBNdbFetcher::search() - key not recognized: " << m_key << endl;
+ stop();
+ return;
+ }
+// myDebug() << "ISBNdbFetcher::search() - url: " << u.url() << endl;
+
+ m_job = KIO::get(u, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+}
+
+void ISBNdbFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+// myDebug() << "ISBNdbFetcher::stop()" << endl;
+ if(m_job) {
+ m_job->kill();
+ m_job = 0;
+ }
+ m_data.truncate(0);
+ m_started = false;
+ emit signalDone(this);
+}
+
+void ISBNdbFetcher::slotData(KIO::Job*, const QByteArray& data_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(data_.data(), data_.size());
+}
+
+void ISBNdbFetcher::slotComplete(KIO::Job* job_) {
+// myDebug() << "ISBNdbFetcher::slotComplete()" << endl;
+ // since the fetch is done, don't worry about holding the job pointer
+ m_job = 0;
+
+ if(job_->error()) {
+ job_->showErrorDialog(Kernel::self()->widget());
+ stop();
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "ISBNdbFetcher::slotComplete() - no data" << endl;
+ stop();
+ return;
+ }
+
+#if 0
+ kdWarning() << "Remove debug from isbndbfetcher.cpp" << endl;
+ QFile f(QString::fromLatin1("/tmp/test.xml"));
+ if(f.open(IO_WriteOnly)) {
+ QTextStream t(&f);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << QCString(m_data, m_data.size()+1);
+ }
+ f.close();
+#endif
+
+ QDomDocument dom;
+ if(!dom.setContent(m_data, false)) {
+ kdWarning() << "ISBNdbFetcher::slotComplete() - server did not return valid XML." << endl;
+ return;
+ }
+
+ if(m_total == -1) {
+ QDomNode n = dom.documentElement().namedItem(QString::fromLatin1("BookList"));
+ QDomElement e = n.toElement();
+ if(!e.isNull()) {
+ m_total = e.attribute(QString::fromLatin1("total_results"), QString::number(-1)).toInt();
+ }
+ }
+
+ if(!m_xsltHandler) {
+ initXSLTHandler();
+ if(!m_xsltHandler) { // probably an error somewhere in the stylesheet loading
+ stop();
+ return;
+ }
+ }
+
+ // assume result is always utf-8
+ QString str = m_xsltHandler->applyStylesheet(QString::fromUtf8(m_data, m_data.size()));
+ Import::TellicoImporter imp(str);
+ Data::CollPtr coll = imp.collection();
+
+ int count = 0;
+ Data::EntryVec entries = coll->entries();
+ for(Data::EntryVec::Iterator entry = entries.begin(); m_numResults < m_limit && entry != entries.end(); ++entry, ++count) {
+ if(count < m_countOffset) {
+ continue;
+ }
+ if(!m_started) {
+ // might get aborted
+ break;
+ }
+ QString desc = entry->field(QString::fromLatin1("author"))
+ + QChar('/') + entry->field(QString::fromLatin1("publisher"));
+ if(!entry->field(QString::fromLatin1("cr_year")).isEmpty()) {
+ desc += QChar('/') + entry->field(QString::fromLatin1("cr_year"));
+ } else if(!entry->field(QString::fromLatin1("pub_year")).isEmpty()){
+ desc += QChar('/') + entry->field(QString::fromLatin1("pub_year"));
+ }
+
+ SearchResult* r = new SearchResult(this, entry->title(), desc, entry->field(QString::fromLatin1("isbn")));
+ m_entries.insert(r->uid, Data::EntryPtr(entry));
+ emit signalResultFound(r);
+ ++m_numResults;
+ }
+
+ // are there any additional results to get?
+ m_hasMoreResults = m_page * ISBNDB_RETURNS_PER_REQUEST < m_total;
+
+ const int currentTotal = QMIN(m_total, m_limit);
+ if(m_page * ISBNDB_RETURNS_PER_REQUEST < currentTotal) {
+ int foundCount = (m_page-1) * ISBNDB_RETURNS_PER_REQUEST + coll->entryCount();
+ message(i18n("Results from %1: %2/%3").arg(source()).arg(foundCount).arg(m_total), MessageHandler::Status);
+ ++m_page;
+ m_countOffset = 0;
+ doSearch();
+ } else {
+ m_countOffset = m_entries.count() % ISBNDB_RETURNS_PER_REQUEST;
+ if(m_countOffset == 0) {
+ ++m_page; // need to go to next page
+ }
+ stop(); // required
+ }
+}
+
+Tellico::Data::EntryPtr ISBNdbFetcher::fetchEntry(uint uid_) {
+ Data::EntryPtr entry = m_entries[uid_];
+ if(!entry) {
+ kdWarning() << "ISBNdbFetcher::fetchEntry() - no entry in dict" << endl;
+ return 0;
+ }
+
+ // if the publisher id is set, then we need to grab the real publisher name
+ const QString id = entry->field(QString::fromLatin1("pub_id"));
+ if(!id.isEmpty()) {
+ KURL u(QString::fromLatin1(ISBNDB_BASE_URL));
+ u.setFileName(QString::fromLatin1("publishers.xml"));
+ u.addQueryItem(QString::fromLatin1("access_key"), QString::fromLatin1(ISBNDB_APP_ID));
+ u.addQueryItem(QString::fromLatin1("index1"), QString::fromLatin1("publisher_id"));
+ u.addQueryItem(QString::fromLatin1("value1"), id);
+
+ QDomDocument dom = FileHandler::readXMLFile(u, true);
+ if(!dom.isNull()) {
+ QString pub = dom.documentElement().namedItem(QString::fromLatin1("PublisherList"))
+ .namedItem(QString::fromLatin1("PublisherData"))
+ .namedItem(QString::fromLatin1("Name"))
+ .toElement().text();
+ if(!pub.isEmpty()) {
+ entry->setField(QString::fromLatin1("publisher"), pub);
+ }
+ }
+ entry->setField(QString::fromLatin1("pub_id"), QString());
+ }
+
+ return entry;
+}
+
+void ISBNdbFetcher::initXSLTHandler() {
+ QString xsltfile = locate("appdata", QString::fromLatin1("isbndb2tellico.xsl"));
+ if(xsltfile.isEmpty()) {
+ kdWarning() << "ISBNdbFetcher::initXSLTHandler() - can not locate isbndb2tellico.xsl." << endl;
+ return;
+ }
+
+ KURL u;
+ u.setPath(xsltfile);
+
+ delete m_xsltHandler;
+ m_xsltHandler = new XSLTHandler(u);
+ if(!m_xsltHandler->isValid()) {
+ kdWarning() << "ISBNdbFetcher::initXSLTHandler() - error in isbndb2tellico.xsl." << endl;
+ delete m_xsltHandler;
+ m_xsltHandler = 0;
+ return;
+ }
+}
+
+void ISBNdbFetcher::updateEntry(Data::EntryPtr entry_) {
+// myDebug() << "ISBNdbFetcher::updateEntry()" << endl;
+ // limit to top 5 results
+ m_limit = 5;
+
+ QString isbn = entry_->field(QString::fromLatin1("isbn"));
+ if(!isbn.isEmpty()) {
+ search(Fetch::ISBN, isbn);
+ return;
+ }
+
+ // optimistically try searching for title and rely on Collection::sameEntry() to figure things out
+ QString t = entry_->field(QString::fromLatin1("title"));
+ if(!t.isEmpty()) {
+ m_limit = 10; // raise limit so more possibility of match
+ search(Fetch::Title, t);
+ return;
+ }
+
+ myDebug() << "ISBNdbFetcher::updateEntry() - insufficient info to search" << endl;
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+Tellico::Fetch::ConfigWidget* ISBNdbFetcher::configWidget(QWidget* parent_) const {
+ return new ISBNdbFetcher::ConfigWidget(parent_, this);
+}
+
+ISBNdbFetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const ISBNdbFetcher*/*=0*/)
+ : Fetch::ConfigWidget(parent_) {
+ QVBoxLayout* l = new QVBoxLayout(optionsWidget());
+ l->addWidget(new QLabel(i18n("This source has no options."), optionsWidget()));
+ l->addStretch();
+}
+
+QString ISBNdbFetcher::ConfigWidget::preferredName() const {
+ return ISBNdbFetcher::defaultName();
+}
+
+#include "isbndbfetcher.moc"
diff --git a/src/fetch/isbndbfetcher.h b/src/fetch/isbndbfetcher.h
new file mode 100644
index 0000000..e49246a
--- /dev/null
+++ b/src/fetch/isbndbfetcher.h
@@ -0,0 +1,94 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FETCH_ISBNDBFETCHER_H
+#define TELLICO_FETCH_ISBNDBFETCHER_H
+
+namespace Tellico {
+ class XSLTHandler;
+}
+
+#include "fetcher.h"
+#include "configwidget.h"
+#include "../datavectors.h"
+
+#include <kio/job.h>
+
+#include <qcstring.h> // for QByteArray
+#include <qguardedptr.h>
+
+namespace Tellico {
+ namespace Fetch {
+
+/**
+ * @author Robby Stephenson
+ */
+class ISBNdbFetcher : public Fetcher {
+Q_OBJECT
+
+public:
+ ISBNdbFetcher(QObject* parent = 0, const char* name = 0);
+ ~ISBNdbFetcher();
+
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual void search(FetchKey key, const QString& value);
+ virtual void continueSearch();
+ virtual bool canSearch(FetchKey k) const { return k == Title || k == Person || k == Keyword || k == ISBN; }
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return ISBNdb; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+
+ virtual void updateEntry(Data::EntryPtr entry);
+
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const;
+
+ class ConfigWidget : public Fetch::ConfigWidget {
+ public:
+ ConfigWidget(QWidget* parent_, const ISBNdbFetcher* fetcher = 0);
+ virtual void saveConfig(KConfigGroup&) {}
+ virtual QString preferredName() const;
+ };
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+private slots:
+ void slotData(KIO::Job* job, const QByteArray& data);
+ void slotComplete(KIO::Job* job);
+
+private:
+ void initXSLTHandler();
+ void doSearch();
+
+ XSLTHandler* m_xsltHandler;
+ int m_limit;
+ int m_page;
+ int m_total;
+ int m_numResults;
+ int m_countOffset;
+
+ QByteArray m_data;
+ QMap<int, Data::EntryPtr> m_entries;
+ QGuardedPtr<KIO::Job> m_job;
+
+ FetchKey m_key;
+ QString m_value;
+ bool m_started;
+};
+
+ }
+}
+#endif
diff --git a/src/fetch/messagehandler.cpp b/src/fetch/messagehandler.cpp
new file mode 100644
index 0000000..f3c36a1
--- /dev/null
+++ b/src/fetch/messagehandler.cpp
@@ -0,0 +1,35 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "messagehandler.h"
+#include "fetchmanager.h"
+#include "../tellico_kernel.h"
+
+#include <kmessagebox.h>
+
+using Tellico::Fetch::ManagerMessage;
+
+// all messages go to manager
+void ManagerMessage::send(const QString& message_, Type type_) {
+ Fetch::Manager::self()->updateStatus(message_);
+ // plus errors get a message box
+ if(type_ == Error) {
+ KMessageBox::sorry(Kernel::self()->widget(), message_);
+ } else if(type_ == Warning) {
+ KMessageBox::information(Kernel::self()->widget(), message_);
+ }
+}
+
+void ManagerMessage::infoList(const QString& message_, const QStringList& list_) {
+ KMessageBox::informationList(Kernel::self()->widget(), message_, list_);
+}
diff --git a/src/fetch/messagehandler.h b/src/fetch/messagehandler.h
new file mode 100644
index 0000000..0ec9269
--- /dev/null
+++ b/src/fetch/messagehandler.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FETCH_MESSAGEHANDLER_H
+#define TELLICO_FETCH_MESSAGEHANDLER_H
+
+class QString;
+class QStringList;
+
+namespace Tellico {
+ namespace Fetch {
+
+/**
+ * @author Robby Stephenson
+ */
+class MessageHandler {
+public:
+ enum Type { Status, Warning, Error, ListError };
+
+ MessageHandler() {}
+ virtual ~MessageHandler() {}
+
+ virtual void send(const QString& message, Type type) = 0;
+ virtual void infoList(const QString& message, const QStringList& list) = 0;
+};
+
+class ManagerMessage : public MessageHandler {
+public:
+ ManagerMessage() : MessageHandler() {}
+ virtual ~ManagerMessage() {}
+
+ virtual void send(const QString& message, Type type);
+ virtual void infoList(const QString& message, const QStringList& list);
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/fetch/scripts/Makefile.am b/src/fetch/scripts/Makefile.am
new file mode 100644
index 0000000..050c460
--- /dev/null
+++ b/src/fetch/scripts/Makefile.am
@@ -0,0 +1,30 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+EXTRA_DIST = \
+fr.allocine.py fr.allocine.py.spec \
+ministerio_de_cultura.py ministerio_de_cultura.py.spec \
+dark_horse_comics.py dark_horse_comics.py.spec \
+boardgamegeek.rb boardgamegeek.rb.spec
+
+####### kdevelop will overwrite this part!!! (end)############
+
+scriptdir = $(kde_datadir)/tellico/data-sources
+script_SCRIPTS = \
+fr.allocine.py \
+ministerio_de_cultura.py \
+dark_horse_comics.py \
+boardgamegeek.rb
+
+script_DATA = \
+fr.allocine.py.spec \
+ministerio_de_cultura.py.spec \
+dark_horse_comics.py.spec \
+boardgamegeek.rb.spec
+
+KDE_OPTIONS = noautodist
+
+CLEANFILES = *~
+
+# probably a better way to do this
+uninstall-hook:
+ -if [ -d $(scriptdir) ]; then rmdir $(scriptdir); fi
diff --git a/src/fetch/scripts/boardgamegeek.rb b/src/fetch/scripts/boardgamegeek.rb
new file mode 100644
index 0000000..b3cf4f3
--- /dev/null
+++ b/src/fetch/scripts/boardgamegeek.rb
@@ -0,0 +1,235 @@
+#!/usr/bin/env ruby
+#
+# ***************************************************************************
+# copyright : (C) 2006 by Steve Beattie
+# : (C) 2008 by Sven Werlen
+# email : sbeattie@suse.de
+# : sven@boisdechet.org
+# ***************************************************************************
+#
+# ***************************************************************************
+# * *
+# * This program is free software; you can redistribute it and/or modify *
+# * it under the terms of version 2 of the GNU General Public License as *
+# * published by the Free Software Foundation; *
+# * *
+# ***************************************************************************
+
+# $Id: boardgamegeek.rb 313 2006-10-02 22:17:11Z steve $
+
+# This program is expected to be invoked from tellico
+# (http://periapsis.org/tellico) as an external data source. It provides
+# searches for boardgames from the boardgamegeek.com website, via
+# boardgamegeek's xmlapi interface
+# (http://www.boardgamegeek.com/xmlapi/)
+#
+# It only allows searches via name; the boardgamegeek xmlapi is not yet
+# rich enough to support queries by designer, publisher, category, or
+# mechanism. I'd like to add support for querying by boardgamegeek id,
+# but that needs additional support in tellico.
+#
+# Sven Werlen: 03 Feb 2008: script has been extended to retrieve cover
+# images (/thumbnail from xmlapi). Images are retrieved from the website
+# and base64 is generated on-the-fly.
+#
+require 'rexml/document'
+require 'net/http'
+require 'cgi'
+require "base64"
+include REXML
+
+$my_version = '$Rev: 313 $'
+
+class Game
+ attr_writer :year
+ attr_writer :description
+ attr_writer :cover
+ attr_writer :image
+
+ def initialize(name, id)
+ @name = name
+ @id = id
+ @publishers = []
+ @designers = []
+ @players = []
+ end
+
+ def add_publisher(publisher)
+ @publishers << publisher
+ end
+
+ def add_designer(designer)
+ @designers << designer
+ end
+
+ def add_players(players)
+ @players << players
+ end
+
+ def to_s()
+ "@name (#@id #@publishers #@year)"
+ end
+
+ def toXML()
+ element = Element.new 'entry'
+ element.add_element Element.new('title').add_text(@name)
+ element.add_element Element.new('description').add_text(@description) if @description
+ element.add_element Element.new('year').add_text(@year) if @year
+ element.add_element Element.new('boardgamegeek-link').add_text("http://www.boardgamegeek/game/#{@id}") if @id
+ element.add_element Element.new('bggid').add_text(@id) if @id
+ element.add_element Element.new('cover').add_text(@cover) if @cover
+
+ if @publishers.length > 0
+ pub_elements = Element.new('publishers')
+ @publishers.each {|p| pub_elements.add_element Element.new('publisher').add_text(p)}
+ element.add_element pub_elements
+ end
+ if @designers.length > 0
+ des_elements = Element.new('designers')
+ @designers.each {|d| des_elements.add_element Element.new('designer').add_text(d)}
+ element.add_element des_elements
+ end
+ if @players.length > 0
+ players_elements = Element.new('num-players')
+ @players.each {|n| players_elements.add_element Element.new('num-player').add_text(n.to_s)}
+ element.add_element players_elements
+ end
+ return element
+ end
+
+ def image()
+ image = Element.new 'image'
+ image.add_attribute('format', 'JPEG')
+ image.add_attribute('id', @id + ".jpg")
+ image.add_text(@image)
+ return image
+ end
+end
+
+def getGameList(query)
+ #puts("Query is #{query}")
+
+ search_result = nil
+ Net::HTTP.start('www.boardgamegeek.com', 80) do
+ |http| search_result = (http.get("/xmlapi/search?search=#{CGI.escape(query)}",
+ {"User-Agent" => "BoardGameGeek plugin for Tellico #{$my_version}"}).body)
+ http.finish
+ end
+ doc = REXML::Document.new(search_result)
+
+ games = XPath.match(doc, "//game")
+ #games.each {|g| puts g.elements['name'].text+g.attributes['gameid']}
+ ids = []
+ games.each {|g| ids << g.attributes['gameid']}
+ return ids
+end
+
+def getGameDetails(ids)
+ #ids.each {|id| puts id}
+
+ query = "/xmlapi/game/#{ids.join(',')}"
+ #puts query
+ search_result = nil
+ Net::HTTP.start('www.boardgamegeek.com', 80) do |http|
+ search_result = http.get(query, {"User-Agent" => "BoardGameGeek plugin for Tellico #{$my_version}"})
+ http.finish
+ end
+ games = []
+ case search_result
+ when Net::HTTPOK then
+ doc = REXML::Document.new(search_result.body)
+
+ games_xml = XPath.match(doc, "//game")
+ games_xml.each do |g|
+ if( g.elements['name'] != nil )
+ game = Game.new(g.elements['name'].text, g.attributes['gameid'])
+ game.year = g.elements['yearpublished'].text
+ game.description = g.elements['description'].text
+ g.elements.each('publisher'){|p| game.add_publisher p.elements['name'].text}
+ g.elements.each('designer'){|d| game.add_designer d.elements['name'].text}
+ minp = Integer(g.elements['minplayers'].text)
+ maxp = Integer(g.elements['maxplayers'].text)
+ minp.upto(maxp) {|n| game.add_players(n)}
+
+ # retrieve cover
+ coverurl = g.elements['thumbnail'] != nil ? g.elements['thumbnail'].text : nil
+ if( coverurl =~ /files.boardgamegeek.com(.*)$/ )
+ # puts "downloading... " + $1
+ cover = nil
+ Net::HTTP.start('files.boardgamegeek.com', 80) do |http|
+ cover = (http.get($1, {"User-Agent" => "BoardGameGeek plugin for Tellico #{$my_version}"}))
+ end
+ case cover
+ when Net::HTTPOK then
+ game.cover = g.attributes['gameid'] + ".jpg";
+ game.image = Base64.encode64(cover.body);
+ end
+ else
+ # puts "invalid cover: " + coverurl
+ end
+ games << game
+ end
+ end
+ end
+ return games
+end
+
+def listToXML(gameList)
+ doc = REXML::Document.new
+ doc << REXML::DocType.new('tellico PUBLIC', '"-//Robby Stephenson/DTD Tellico V10.0//EN" "http://periapsis.org/tellico/dtd/v10/tellico.dtd"')
+ doc << XMLDecl.new
+ tellico = Element.new 'tellico'
+ tellico.add_attribute('xmlns', 'http://periapsis.org/tellico/')
+ tellico.add_attribute('syntaxVersion', '10')
+ collection = Element.new 'collection'
+ collection.add_attribute('title', 'My Collection')
+ collection.add_attribute('type', '13')
+
+ fields = Element.new 'fields'
+ field = Element.new 'field'
+ field.add_attribute('name', '_default')
+ fields.add_element(field)
+ field = Element.new 'field'
+ field.add_attribute('name', 'bggid')
+ field.add_attribute('title', 'BoardGameGeek ID')
+ field.add_attribute('category', 'General')
+ field.add_attribute('flags', '0')
+ field.add_attribute('format', '4')
+ field.add_attribute('type', '6')
+ field.add_attribute('i18n', 'true')
+ fields.add_element(field)
+ collection.add_element(fields)
+
+ images = Element.new 'images'
+
+ id = 0
+ gameList.each do
+ |g| element = g.toXML()
+ element.add_attribute('id', id)
+ id = id + 1
+ collection.add_element(element)
+ images.add_element(g.image());
+ end
+ collection.add_element(images);
+ tellico.add_element(collection)
+ doc.add_element(tellico)
+ doc.write($stdout, 0)
+ puts ""
+end
+
+if __FILE__ == $0
+
+ def showUsage
+ warn "usage: #{__FILE__} game_query"
+ exit 1
+ end
+
+ showUsage unless ARGV.length == 1
+
+ idList = getGameList(ARGV.shift)
+ if idList
+ gameList = getGameDetails(idList)
+ end
+
+ listToXML(gameList)
+end
diff --git a/src/fetch/scripts/boardgamegeek.rb.spec b/src/fetch/scripts/boardgamegeek.rb.spec
new file mode 100644
index 0000000..6e0aab0
--- /dev/null
+++ b/src/fetch/scripts/boardgamegeek.rb.spec
@@ -0,0 +1,7 @@
+Name=BoardGameGeek
+Type=data-source
+ArgumentKeys=1
+Arguments=%1
+CollectionType=13
+FormatType=0
+UpdateArgs=%{title}
diff --git a/src/fetch/scripts/dark_horse_comics.py b/src/fetch/scripts/dark_horse_comics.py
new file mode 100644
index 0000000..4f3b651
--- /dev/null
+++ b/src/fetch/scripts/dark_horse_comics.py
@@ -0,0 +1,399 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-1 -*-
+
+# ***************************************************************************
+# copyright : (C) 2006 by Mathias Monnerville
+# email : tellico_dev@yahoo.fr
+# ***************************************************************************
+#
+# ***************************************************************************
+# * *
+# * This program is free software; you can redistribute it and/or modify *
+# * it under the terms of version 2 of the GNU General Public License as *
+# * published by the Free Software Foundation; *
+# * *
+# ***************************************************************************
+
+# $Id: comics_darkhorsecomics.py 123 2006-03-24 08:47:48Z mathias $
+
+"""
+This script has to be used with tellico (http://periapsis.org/tellico) as an external data source program.
+It allows searching through the Dark Horse Comics web database.
+
+Related info and cover are fetched automatically. It takes only one argument (comic title).
+
+Tellico data source setup:
+- source name: Dark Horse Comics (US) (or whatever you want :)
+- Collection type: comics collection
+- Result type: tellico
+- Path: /path/to/script/comics_darkhorsecomics.py
+- Arguments:
+Title (checked) = %1
+Update (checked) = %{title}
+"""
+
+import sys, os, re, md5, random, string
+import urllib, urllib2, time, base64
+import xml.dom.minidom
+
+XML_HEADER = """<?xml version="1.0" encoding="UTF-8"?>"""
+DOCTYPE = """<!DOCTYPE tellico PUBLIC "-//Robby Stephenson/DTD Tellico V9.0//EN" "http://periapsis.org/tellico/dtd/v9/tellico.dtd">"""
+NULLSTRING = ''
+
+VERSION = "0.2"
+
+
+def genMD5():
+ """
+ Generates and returns a random md5 string. Its main purpose is to allow random
+ image file name generation.
+ """
+ obj = md5.new()
+ float = random.random()
+ obj.update(str(float))
+ return obj.hexdigest()
+
+class BasicTellicoDOM:
+ """
+ This class manages tellico's XML data model (DOM)
+ """
+ def __init__(self):
+ self.__doc = xml.dom.minidom.Document()
+ self.__root = self.__doc.createElement('tellico')
+ self.__root.setAttribute('xmlns', 'http://periapsis.org/tellico/')
+ self.__root.setAttribute('syntaxVersion', '9')
+
+ self.__collection = self.__doc.createElement('collection')
+ self.__collection.setAttribute('title', 'My Comics')
+ self.__collection.setAttribute('type', '6')
+
+ self.__images = self.__doc.createElement('images')
+
+ self.__root.appendChild(self.__collection)
+ self.__doc.appendChild(self.__root)
+
+ # Current movie id. See entry's id attribute in self.addEntry()
+ self.__currentId = 0
+
+
+ def addEntry(self, movieData):
+ """
+ Add a comic entry.
+ Returns an entry node instance
+ """
+ d = movieData
+ entryNode = self.__doc.createElement('entry')
+ entryNode.setAttribute('id', str(self.__currentId))
+
+ titleNode = self.__doc.createElement('title')
+ titleNode.appendChild(self.__doc.createTextNode(unicode(d['title'], 'latin-1').encode('utf-8')))
+
+ yearNode = self.__doc.createElement('pub_year')
+ yearNode.appendChild(self.__doc.createTextNode(d['pub_year']))
+
+ countryNode = self.__doc.createElement('country')
+ countryNode.appendChild(self.__doc.createTextNode(d['country']))
+ pubNode = self.__doc.createElement('publisher')
+ pubNode.appendChild(self.__doc.createTextNode(d['publisher']))
+ langNode = self.__doc.createElement('language')
+ langNode.appendChild(self.__doc.createTextNode(d['language']))
+
+ writersNode = self.__doc.createElement('writers')
+ for g in d['writer']:
+ writerNode = self.__doc.createElement('writer')
+ writerNode.appendChild(self.__doc.createTextNode(unicode(g, 'latin-1').encode('utf-8')))
+ writersNode.appendChild(writerNode)
+
+ genresNode = self.__doc.createElement('genres')
+ for g in d['genre']:
+ genreNode = self.__doc.createElement('genre')
+ genreNode.appendChild(self.__doc.createTextNode(unicode(g, 'latin-1').encode('utf-8')))
+ genresNode.appendChild(genreNode)
+
+ commentsNode = self.__doc.createElement('comments')
+ #for g in d['comments']:
+ # commentsNode.appendChild(self.__doc.createTextNode(unicode("%s\n\n" % g, 'latin-1').encode('utf-8')))
+ commentsData = string.join(d['comments'], '\n\n')
+ commentsNode.appendChild(self.__doc.createTextNode(unicode(commentsData, 'latin-1').encode('utf-8')))
+
+ artistsNode = self.__doc.createElement('artists')
+ for k, v in d['artist'].iteritems():
+ artistNode = self.__doc.createElement('artist')
+ artistNode.appendChild(self.__doc.createTextNode(unicode(v, 'latin-1').encode('utf-8')))
+ artistsNode.appendChild(artistNode)
+
+ pagesNode = self.__doc.createElement('pages')
+ pagesNode.appendChild(self.__doc.createTextNode(d['pages']))
+
+ issueNode = self.__doc.createElement('issue')
+ issueNode.appendChild(self.__doc.createTextNode(d['issue']))
+
+ if d['image']:
+ imageNode = self.__doc.createElement('image')
+ imageNode.setAttribute('format', 'JPEG')
+ imageNode.setAttribute('id', d['image'][0])
+ imageNode.appendChild(self.__doc.createTextNode(unicode(d['image'][1], 'latin-1').encode('utf-8')))
+
+ coverNode = self.__doc.createElement('cover')
+ coverNode.appendChild(self.__doc.createTextNode(d['image'][0]))
+
+ for name in ( 'writersNode', 'genresNode', 'artistsNode', 'pagesNode', 'yearNode',
+ 'titleNode', 'issueNode', 'commentsNode', 'pubNode', 'langNode',
+ 'countryNode' ):
+ entryNode.appendChild(eval(name))
+
+ if d['image']:
+ entryNode.appendChild(coverNode)
+ self.__images.appendChild(imageNode)
+
+ self.__collection.appendChild(entryNode)
+
+ self.__currentId += 1
+ return entryNode
+
+ def printEntry(self, nEntry):
+ """
+ Prints entry's XML content to stdout
+ """
+ try:
+ print nEntry.toxml()
+ except:
+ print sys.stderr, "Error while outputing XML content from entry to Tellico"
+
+ def printXMLTree(self):
+ """
+ Outputs XML content to stdout
+ """
+ self.__collection.appendChild(self.__images)
+ print XML_HEADER; print DOCTYPE
+ print self.__root.toxml()
+
+
+class DarkHorseParser:
+ def __init__(self):
+ self.__baseURL = 'http://www.darkhorse.com'
+ self.__basePath = '/profile/profile.php?sku='
+ self.__searchURL = '/search/search.php?frompage=userinput&sstring=%s&x=0&y=0'
+ self.__coverPath = 'http://images.darkhorse.com/covers/'
+ self.__movieURL = self.__baseURL + self.__basePath
+
+ # Define some regexps
+ self.__regExps = { 'title' : '<font size="\+2"><b>(?P<title>.*?)</b></font>',
+ 'pub_date' : '<b>Pub.* Date:</b> *<a.*>(?P<pub_date>.*)</a>',
+ 'desc' : '<p>(?P<desc>.*?)<br>',
+ 'writer' : '<b>Writer: *</b> *<a.*?>(?P<writer>.*)</a>',
+ 'cover_artist' : '<b>Cover Artist: *</b> *<a.*>(?P<cover_artist>.*)</a>',
+ 'penciller' : '<b>Penciller: *</b> *<a.*>(?P<penciller>.*)</a>',
+ 'inker' : '<b>Inker: *</b> *<a.*>(?P<inker>.*)</a>',
+ 'letterer' : '<b>Letterer: *</b> *<a.*>(?P<letterer>.*)</a>',
+ 'colorist' : '<b>Colorist: *</b> *<a.*>(?P<colorist>.*)</a>',
+ 'genre' : '<b>Genre: *</b> *<a.*?>(?P<genre>.*?)</a><br>',
+ 'format' : '<b>Format: *</b> *(?P<format>.*?)<br>',
+ }
+
+ # Compile patterns objects
+ self.__regExpsPO = {}
+ for k, pattern in self.__regExps.iteritems():
+ self.__regExpsPO[k] = re.compile(pattern)
+
+ self.__domTree = BasicTellicoDOM()
+
+ def run(self, title):
+ """
+ Runs the allocine.fr parser: fetch movie related links, then fills and prints the DOM tree
+ to stdout (in tellico format) so that tellico can use it.
+ """
+ self.__getMovie(title)
+ # Print results to stdout
+ self.__domTree.printXMLTree()
+
+ def __getHTMLContent(self, url):
+ """
+ Fetch HTML data from url
+ """
+ u = urllib2.urlopen(url)
+ self.__data = u.read()
+ u.close()
+
+ def __fetchMovieLinks(self):
+ """
+ Retrieve all links related to the search. self.__data contains HTML content fetched by self.__getHTMLContent()
+ that need to be parsed.
+ """
+ matchList = re.findall("""<a *href="%s(?P<page>.*?)">(?P<title>.*?)</a>""" % self.__basePath.replace('?', '\?'), self.__data)
+ if not matchList: return None
+
+ return matchList
+
+ def __fetchCover(self, path, delete = True):
+ """
+ Fetch cover to /tmp. Returns base64 encoding of data.
+ The image is deleted if delete is True
+ """
+ md5 = genMD5()
+ imObj = urllib2.urlopen(path.strip())
+ img = imObj.read()
+ imObj.close()
+ imgPath = "/tmp/%s.jpeg" % md5
+ try:
+ f = open(imgPath, 'w')
+ f.write(img)
+ f.close()
+ except:
+ print sys.stderr, "Error: could not write image into /tmp"
+
+ b64data = (md5 + '.jpeg', base64.encodestring(img))
+
+ # Delete temporary image
+ if delete:
+ try:
+ os.remove(imgPath)
+ except:
+ print sys.stderr, "Error: could not delete temporary image /tmp/%s.jpeg" % md5
+
+ return b64data
+
+ def __fetchMovieInfo(self, url):
+ """
+ Looks for movie information
+ """
+ self.__getHTMLContent(url)
+
+ # First grab picture data
+ imgMatch = re.search("""<img src="%s(?P<imgpath>.*?)".*>""" % self.__coverPath, self.__data)
+ if imgMatch:
+ imgPath = self.__coverPath + imgMatch.group('imgpath')
+ # Fetch cover and gets its base64 encoded data
+ b64img = self.__fetchCover(imgPath)
+ else:
+ b64img = None
+
+ # Now isolate data between <div class="bodytext">...</div> elements
+ # re.S sets DOTALL; it makes the "." special character match any character at all, including a newline
+ m = re.search("""<div class="bodytext">(?P<part>.*)</div>""", self.__data, re.S)
+ self.__data = m.group('part')
+
+ matches = {}
+ data = {}
+ data['comments'] = []
+ data['artist'] = {}
+
+ # Default values
+ data['publisher'] = 'Dark Horse Comics'
+ data['language'] = 'English'
+ data['country'] = 'USA'
+
+ data['image'] = b64img
+ data['pub_year'] = NULLSTRING
+
+ for name, po in self.__regExpsPO.iteritems():
+ data[name] = NULLSTRING
+ if name == 'desc':
+ matches[name] = re.findall(self.__regExps[name], self.__data, re.S | re.I)
+ else:
+ matches[name] = po.search(self.__data)
+
+ if matches[name]:
+ if name == 'title':
+ title = matches[name].group('title').strip()
+ data[name] = title
+ # Look for issue information
+ m = re.search("#(?P<issue>[0-9]+)", title)
+ if m:
+ data['issue'] = m.group('issue')
+ else:
+ data['issue'] = ''
+
+ elif name == 'pub_date':
+ pub_date = matches[name].group('pub_date').strip()
+ data['pub_year'] = pub_date[-4:]
+ # Add this to comments field
+ data['comments'].insert(0, "Pub. Date: %s" % pub_date)
+
+ elif name == 'desc':
+ # Find biggest size
+ max = 0
+ for i in range(len(matches[name])):
+ if len(matches[name][i]) > len(matches[name][max]):
+ max = i
+ data['comments'].append(matches[name][max].strip())
+
+ elif name == 'writer':
+ # We may find several writers
+ data[name] = []
+ writersList = re.sub('</?a.*?>', '', matches[name].group('writer')).split(',')
+ for d in writersList:
+ data[name].append(d.strip())
+
+ elif name == 'cover_artist':
+ data['artist']['Cover Artist'] = matches[name].group('cover_artist').strip()
+
+ elif name == 'penciller':
+ data['artist']['Penciller'] = matches[name].group('penciller').strip()
+
+ elif name == 'inker':
+ data['artist']['Inker'] = matches[name].group('inker').strip()
+
+ elif name == 'colorist':
+ data['artist']['Colorist'] = matches[name].group('colorist').strip()
+
+ elif name == 'letterer':
+ data['artist']['Letterer'] = matches[name].group('letterer').strip()
+
+ elif name == 'genre':
+ # We may find several genres
+ data[name] = []
+ genresList = re.sub('</?a.*?>', '', matches[name].group('genre')).split(',')
+ for d in genresList:
+ data[name].append(d.strip())
+
+ elif name == 'format':
+ format = matches[name].group('format').strip()
+ data['comments'].insert(1, format)
+ m = re.search("(?P<pages>[0-9]+)", format)
+ if m:
+ data['pages'] = m.group('pages')
+ else:
+ data['pages'] = ''
+
+ return data
+
+
+ def __getMovie(self, title):
+ if not len(title): return
+
+ self.__title = title
+ self.__getHTMLContent("%s%s" % (self.__baseURL, self.__searchURL % urllib.quote(self.__title)))
+
+ # Get all links
+ links = self.__fetchMovieLinks()
+
+ # Now retrieve infos
+ if links:
+ for entry in links:
+ data = self.__fetchMovieInfo( url = self.__movieURL + entry[0] )
+ # Add DC link (custom field)
+ data['darkhorse'] = "%s%s" % (self.__movieURL, entry[0])
+ node = self.__domTree.addEntry(data)
+ # Print entries on-the-fly
+ #self.__domTree.printEntry(node)
+ else:
+ return None
+
+def halt():
+ print "HALT."
+ sys.exit(0)
+
+def showUsage():
+ print "Usage: %s comic" % sys.argv[0]
+ sys.exit(1)
+
+def main():
+ if len(sys.argv) < 2:
+ showUsage()
+
+ parser = DarkHorseParser()
+ parser.run(sys.argv[1])
+
+if __name__ == '__main__':
+ main()
diff --git a/src/fetch/scripts/dark_horse_comics.py.spec b/src/fetch/scripts/dark_horse_comics.py.spec
new file mode 100644
index 0000000..9481dc8
--- /dev/null
+++ b/src/fetch/scripts/dark_horse_comics.py.spec
@@ -0,0 +1,7 @@
+Name=Dark Horse Comics
+Type=data-source
+ArgumentKeys=1
+Arguments=%1
+CollectionType=6
+FormatType=0
+UpdateArgs=%{title}
diff --git a/src/fetch/scripts/fr.allocine.py b/src/fetch/scripts/fr.allocine.py
new file mode 100755
index 0000000..97a2247
--- /dev/null
+++ b/src/fetch/scripts/fr.allocine.py
@@ -0,0 +1,335 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-1 -*-
+
+# ***************************************************************************
+# copyright : (C) 2006 by Mathias Monnerville
+# email : tellico@monnerville.com
+# ***************************************************************************
+#
+# ***************************************************************************
+# * *
+# * This program is free software; you can redistribute it and/or modify *
+# * it under the terms of version 2 of the GNU General Public License as *
+# * published by the Free Software Foundation; *
+# * *
+# ***************************************************************************
+
+# Version 0.4: 2007-08-27
+# * Fixed parsing errors: some fields in allocine's HTML pages have changed recently. Multiple actors and genres
+# could not be retrieved. Fixed bad http request error due to some changes in HTML code.
+#
+# Version 0.3:
+# * Fixed parsing: some fields in allocine's HTML pages have changed. Movie's image could not be fetched anymore. Fixed.
+#
+# Version 0.2:
+# * Fixed parsing: allocine's HTML pages have changed. Movie's image could not be fetched anymore.
+#
+# Version 0.1:
+# * Initial release.
+
+import sys, os, re, md5, random
+import urllib, urllib2, time, base64
+import xml.dom.minidom
+
+XML_HEADER = """<?xml version="1.0" encoding="UTF-8"?>"""
+DOCTYPE = """<!DOCTYPE tellico PUBLIC "-//Robby Stephenson/DTD Tellico V9.0//EN" "http://periapsis.org/tellico/dtd/v9/tellico.dtd">"""
+
+VERSION = "0.4"
+
+def genMD5():
+ obj = md5.new()
+ float = random.random()
+ obj.update(str(float))
+ return obj.hexdigest()
+
+class BasicTellicoDOM:
+ def __init__(self):
+ self.__doc = xml.dom.minidom.Document()
+ self.__root = self.__doc.createElement('tellico')
+ self.__root.setAttribute('xmlns', 'http://periapsis.org/tellico/')
+ self.__root.setAttribute('syntaxVersion', '9')
+
+ self.__collection = self.__doc.createElement('collection')
+ self.__collection.setAttribute('title', 'My Movies')
+ self.__collection.setAttribute('type', '3')
+
+ self.__fields = self.__doc.createElement('fields')
+ # Add all default (standard) fields
+ self.__dfltField = self.__doc.createElement('field')
+ self.__dfltField.setAttribute('name', '_default')
+
+ # Add a custom 'Collection' field
+ self.__customField = self.__doc.createElement('field')
+ self.__customField.setAttribute('name', 'titre-original')
+ self.__customField.setAttribute('title', 'Original Title')
+ self.__customField.setAttribute('flags', '8')
+ self.__customField.setAttribute('category', 'General')
+ self.__customField.setAttribute('format', '1')
+ self.__customField.setAttribute('type', '1')
+ self.__customField.setAttribute('i18n', 'yes')
+
+ self.__fields.appendChild(self.__dfltField)
+ self.__fields.appendChild(self.__customField)
+ self.__collection.appendChild(self.__fields)
+
+ self.__images = self.__doc.createElement('images')
+
+ self.__root.appendChild(self.__collection)
+ self.__doc.appendChild(self.__root)
+
+ # Current movie id
+ self.__currentId = 0
+
+
+ def addEntry(self, movieData):
+ """
+ Add a movie entry
+ """
+ d = movieData
+ entryNode = self.__doc.createElement('entry')
+ entryNode.setAttribute('id', str(self.__currentId))
+
+ titleNode = self.__doc.createElement('title')
+ titleNode.appendChild(self.__doc.createTextNode(unicode(d['title'], 'latin-1').encode('utf-8')))
+
+ otitleNode = self.__doc.createElement('titre-original')
+ otitleNode.appendChild(self.__doc.createTextNode(unicode(d['otitle'], 'latin-1').encode('utf-8')))
+
+ yearNode = self.__doc.createElement('year')
+ yearNode.appendChild(self.__doc.createTextNode(unicode(d['year'], 'latin-1').encode('utf-8')))
+
+ genresNode = self.__doc.createElement('genres')
+ for g in d['genres']:
+ genreNode = self.__doc.createElement('genre')
+ genreNode.appendChild(self.__doc.createTextNode(unicode(g, 'latin-1').encode('utf-8')))
+ genresNode.appendChild(genreNode)
+
+ natsNode = self.__doc.createElement('nationalitys')
+ natNode = self.__doc.createElement('nat')
+ natNode.appendChild(self.__doc.createTextNode(unicode(d['nat'], 'latin-1').encode('utf-8')))
+ natsNode.appendChild(natNode)
+
+ castsNode = self.__doc.createElement('casts')
+ for g in d['actors']:
+ castNode = self.__doc.createElement('cast')
+ col1Node = self.__doc.createElement('column')
+ col2Node = self.__doc.createElement('column')
+ col1Node.appendChild(self.__doc.createTextNode(unicode(g, 'latin-1').encode('utf-8')))
+ castNode.appendChild(col1Node)
+ castNode.appendChild(col2Node)
+ castsNode.appendChild(castNode)
+
+ dirsNode = self.__doc.createElement('directors')
+ for g in d['dirs']:
+ dirNode = self.__doc.createElement('director')
+ dirNode.appendChild(self.__doc.createTextNode(unicode(g, 'latin-1').encode('utf-8')))
+ dirsNode.appendChild(dirNode)
+
+ timeNode = self.__doc.createElement('running-time')
+ timeNode.appendChild(self.__doc.createTextNode(unicode(d['time'], 'latin-1').encode('utf-8')))
+
+ allocineNode = self.__doc.createElement(unicode('allocin-link', 'latin-1').encode('utf-8'))
+ allocineNode.appendChild(self.__doc.createTextNode(unicode(d['allocine'], 'latin-1').encode('utf-8')))
+
+ plotNode = self.__doc.createElement('plot')
+ plotNode.appendChild(self.__doc.createTextNode(unicode(d['plot'], 'latin-1').encode('utf-8')))
+
+ if d['image']:
+ imageNode = self.__doc.createElement('image')
+ imageNode.setAttribute('format', 'JPEG')
+ imageNode.setAttribute('id', d['image'][0])
+ imageNode.setAttribute('width', '120')
+ imageNode.setAttribute('height', '160')
+ imageNode.appendChild(self.__doc.createTextNode(unicode(d['image'][1], 'latin-1').encode('utf-8')))
+
+ coverNode = self.__doc.createElement('cover')
+ coverNode.appendChild(self.__doc.createTextNode(d['image'][0]))
+
+ for name in ( 'titleNode', 'otitleNode', 'yearNode', 'genresNode', 'natsNode',
+ 'castsNode', 'dirsNode', 'timeNode', 'allocineNode', 'plotNode' ):
+ entryNode.appendChild(eval(name))
+
+ if d['image']:
+ entryNode.appendChild(coverNode)
+ self.__images.appendChild(imageNode)
+
+ self.__collection.appendChild(entryNode)
+
+ self.__currentId += 1
+
+ def printXML(self):
+ """
+ Outputs XML content to stdout
+ """
+ self.__collection.appendChild(self.__images)
+ print XML_HEADER; print DOCTYPE
+ print self.__root.toxml()
+
+
+class AlloCineParser:
+ def __init__(self):
+ self.__baseURL = 'http://www.allocine.fr'
+ self.__basePath = '/film/fichefilm_gen_cfilm'
+ self.__searchURL= 'http://www.allocine.fr/recherche/?motcle=%s&f=3&rub=1'
+ self.__movieURL = self.__baseURL + self.__basePath
+
+ # Define some regexps
+ self.__regExps = { 'title' : '<title>(?P<title>.+?)</title>',
+ 'dirs' : 'Ralis par <a.*?>(?P<step1>.+?)</a>.*?</h4>',
+ 'actors' : '<h4>Avec *<a.*?>(?P<step1>.+)</a> &nbsp;',
+ 'nat' : '<h4>Film *(?P<nat>.+?)[,\.]',
+ 'genres' : '<h4>Genre *: *<a.*?>(?P<step1>.+?)</a></h4>',
+ 'time' : '<h4>Dure *: *(?P<hours>[0-9])?h *(?P<mins>[0-9]{1,2})min',
+ 'year' : 'Anne de production *: *(?P<year>[0-9]{4})',
+ # Original movie title
+ 'otitle' : 'Titre original *: *<i>(?P<otitle>.+?)</i>',
+ 'plot' : """(?s)<td valign="top" style="padding:10 0 0 0"><div align="justify"><h4> *(?P<plot>.+?) *</h4>""",
+ 'image' : """<td valign="top" width="120".*?<img src="(?P<image>.+?)" border"""}
+
+
+ self.__domTree = BasicTellicoDOM()
+
+ def run(self, title):
+ """
+ Runs the allocine.fr parser: fetch movie related links, then fills and prints the DOM tree
+ to stdout (in tellico format) so that tellico can use it.
+ """
+ self.__getMovie(title)
+ # Print results to stdout
+ self.__domTree.printXML()
+
+ def __getHTMLContent(self, url):
+ """
+ Fetch HTML data from url
+ """
+
+ u = urllib2.urlopen(url)
+ self.__data = u.read()
+ u.close()
+
+ def __fetchMovieLinks(self):
+ """
+ Retrieve all links related to movie
+ """
+ matchList = re.findall("""<h4><a *href="%s=(?P<page>.*?\.html?)" *class="link1">(?P<title>.*?)</a>""" % self.__basePath, self.__data)
+ if not matchList: return None
+
+ return matchList
+
+ def __fetchMovieInfo(self, url):
+ """
+ Looks for movie information
+ """
+ self.__getHTMLContent(url)
+
+ matches = data = {}
+
+ for name, regexp in self.__regExps.iteritems():
+ if name == 'image':
+ matches[name] = re.findall(self.__regExps[name], self.__data, re.S | re.I)
+ else:
+ matches[name] = re.search(regexp, self.__data)
+
+ if matches[name]:
+ if name == 'title':
+ data[name] = matches[name].group('title').strip()
+ elif name == 'dirs':
+ dirsList = re.sub('</?a.*?>', '', matches[name].group('step1')).split(',')
+ data[name] = []
+ for d in dirsList:
+ data[name].append(d.strip())
+
+ elif name == 'actors':
+ actorsList = re.sub('</?a.*?>', '', matches[name].group('step1')).split(',')
+ data[name] = []
+ for d in actorsList:
+ data[name].append(d.strip())
+
+ elif name == 'nat':
+ data[name] = matches[name].group('nat').strip()
+
+ elif name == 'genres':
+ genresList = re.sub('</?a.*?>', '', matches[name].group('step1')).split(',')
+ data[name] = []
+ for d in genresList:
+ data[name].append(d.strip())
+
+ elif name == 'time':
+ h, m = matches[name].group('hours'), matches[name].group('mins')
+ totmin = int(h)*60+int(m)
+ data[name] = str(totmin)
+
+ elif name == 'year':
+ data[name] = matches[name].group('year').strip()
+
+ elif name == 'otitle':
+ data[name] = matches[name].group('otitle').strip()
+
+ elif name == 'plot':
+ data[name] = matches[name].group('plot').strip()
+
+ # Image path
+ elif name == 'image':
+ # Save image to a temporary folder
+ md5 = genMD5()
+ imObj = urllib2.urlopen(matches[name][0].strip())
+ img = imObj.read()
+ imObj.close()
+ imgPath = "/tmp/%s.jpeg" % md5
+ try:
+ f = open(imgPath, 'w')
+ f.write(img)
+ f.close()
+ except:
+ # Could be great if we can pass exit code and some message
+ # to tellico in case of failure...
+ pass
+
+ data[name] = (md5 + '.jpeg', base64.encodestring(img))
+ # Delete temporary image
+ try:
+ os.remove(imgPath)
+ except:
+ # Could be great if we can pass exit code and some msg
+ # to tellico in case of failure...
+ pass
+ else:
+ matches[name] = ''
+
+ return data
+
+
+ def __getMovie(self, title):
+ if not len(title): return
+
+ self.__title = title
+ self.__getHTMLContent(self.__searchURL % urllib.quote(self.__title))
+
+ # Get all links
+ links = self.__fetchMovieLinks()
+
+ # Now retrieve infos
+ if links:
+ for entry in links:
+ data = self.__fetchMovieInfo( url = "%s=%s" % (self.__movieURL, entry[0]) )
+ # Add allocine link (custom field)
+ data['allocine'] = "%s=%s" % (self.__movieURL, entry[0])
+ self.__domTree.addEntry(data)
+ else:
+ return None
+
+
+
+def showUsage():
+ print "Usage: %s movietitle" % sys.argv[0]
+ sys.exit(1)
+
+def main():
+ if len(sys.argv) < 2:
+ showUsage()
+
+ parser = AlloCineParser()
+ parser.run(sys.argv[1])
+
+if __name__ == '__main__':
+ main()
diff --git a/src/fetch/scripts/fr.allocine.py.spec b/src/fetch/scripts/fr.allocine.py.spec
new file mode 100644
index 0000000..773b951
--- /dev/null
+++ b/src/fetch/scripts/fr.allocine.py.spec
@@ -0,0 +1,7 @@
+Name=Allocine.fr
+Type=data-source
+ArgumentKeys=1
+Arguments=%1
+CollectionType=3
+FormatType=0
+UpdateArgs=%{title}
diff --git a/src/fetch/scripts/ministerio_de_cultura.py b/src/fetch/scripts/ministerio_de_cultura.py
new file mode 100644
index 0000000..8a768f9
--- /dev/null
+++ b/src/fetch/scripts/ministerio_de_cultura.py
@@ -0,0 +1,595 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-1 -*-
+
+# ***************************************************************************
+# copyright : (C) 2006-2008 by Mathias Monnerville
+# email : tellico@monnerville.com
+# ***************************************************************************
+#
+# ***************************************************************************
+# * *
+# * This program is free software; you can redistribute it and/or modify *
+# * it under the terms of version 2 of the GNU General Public License as *
+# * published by the Free Software Foundation; *
+# * *
+# ***************************************************************************
+
+# $Id: books_ministerio_de_cultura.py 428 2007-03-07 13:17:17Z mathias $
+
+"""
+This script has to be used with tellico (http://periapsis.org/tellico) as an external data source program.
+It allows searching for books in Spanish Ministry of Culture's database (at http://www.mcu.es/bases/spa/isbn/ISBN.html).
+
+Multiple ISBN/UPC searching is supported through the -m option:
+ ./books_ministerio_de_cultura.py -m filename
+where filename holds one ISBN or UPC per line.
+
+Tellico data source setup:
+- Source type: External Application
+- Source name: Ministerio de Cultura (ES) (or whatever you want :)
+- Collection type: Book Collection
+- Result type: Tellico
+- Path: /path/to/script/books_ministerio_de_cultura.py
+- Arguments:
+Title (checked) = -t %1
+Person (checked) = -a %1
+ISBN (checked) = -i %1
+UPC (checked) = -i %1
+Update (checked) = %{title}
+
+** Please note that this script is also part of the Tellico's distribution.
+** You will always find the latest version in the SVN trunk of Tellico
+
+SVN Version:
+ * Removes translators for Authors List
+ * Adds translators to translator field
+ * Change from "Collection" to "Series"
+ * Process "Series Number"
+ * Adds in comments "ed.lit." authors
+ * If there isn't connection to Spanish Ministry of Culture
+ shows a nice error message (timeout: 5 seconds)
+ * Removed "translated from/to" from Comments field as already
+ exists in "Publishing" field
+ * Removed "Collection" field as I moved to Series/Series Number
+
+Version 0.3.2:
+ * Now find 'notas' field related information
+ * search URL modified to fetch information of exhausted books too
+
+Version 0.3.1:
+Bug Fixes:
+ * The 'tr.' string does not appear among authors anymore
+ * Fixed an AttributeError exception related to a regexp matching the number of pages
+
+Version 0.3:
+Bug Fixes:
+ * URL of the search engine has changed:
+ http://www.mcu.es/bases/spa/isbn/ISBN.html is now http://www.mcu.es/comun/bases/isbn/ISBN.html
+ * All the regexps have been rewritten to match the new site's content
+
+Version 0.2:
+New features:
+ * Support for multiple ISBN/UPC searching (support from command line with -m option)
+ * Default books collection enhanced with a new custom field 'Collection'
+ * Search extended for both available and exhausted books
+ * Hyphens are stripped out in the ISBN (or UPC) search
+
+Bug Fixes:
+ * Publication year now holds only the year
+ * ISBN regexp fix
+ * Fix for publisher field (values were inverted)
+ * -i parameter works for both ISBN and UPC based search
+
+Version 0.1:
+ * Initial Release
+"""
+
+import sys, os, re, md5, random, string
+import urllib, urllib2, time, base64
+import xml.dom.minidom, types
+import socket
+
+XML_HEADER = """<?xml version="1.0" encoding="UTF-8"?>"""
+DOCTYPE = """<!DOCTYPE tellico PUBLIC "-//Robby Stephenson/DTD Tellico V9.0//EN" "http://periapsis.org/tellico/dtd/v9/tellico.dtd">"""
+NULLSTRING = ''
+
+VERSION = "0.3.2"
+
+ISBN, AUTHOR, TITLE = range(3)
+
+TRANSLATOR_STR = "tr."
+EDLIT_STR = "ed. lit."
+
+class EngineError(Exception): pass
+
+class BasicTellicoDOM:
+ """
+ This class manages tellico's XML data model (DOM)
+ """
+ def __init__(self):
+ self.__doc = xml.dom.minidom.Document()
+ self.__root = self.__doc.createElement('tellico')
+ self.__root.setAttribute('xmlns', 'http://periapsis.org/tellico/')
+ self.__root.setAttribute('syntaxVersion', '9')
+
+ self.__collection = self.__doc.createElement('collection')
+ self.__collection.setAttribute('title', 'My Books')
+ self.__collection.setAttribute('type', '2')
+
+ self.__fields = self.__doc.createElement('fields')
+ # Add all default (standard) fields
+ self.__dfltField = self.__doc.createElement('field')
+ self.__dfltField.setAttribute('name', '_default')
+
+ # Add a custom 'Collection' field (Left by reference for
+ # the future)
+ #self.__customCollectionField = self.__doc.createElement('field')
+ #self.__customCollectionField.setAttribute('name', 'book_collection')
+ #self.__customCollectionField.setAttribute('title', 'Collection')
+ #self.__customCollectionField.setAttribute('flags', '7')
+ #self.__customCollectionField.setAttribute('category', 'Classification')
+ #self.__customCollectionField.setAttribute('format', '0')
+ #self.__customCollectionField.setAttribute('type', '1')
+ #self.__customCollectionField.setAttribute('i18n', 'yes')
+
+
+ self.__fields.appendChild(self.__dfltField)
+ #self.__fields.appendChild(self.__customCollectionField)
+ self.__collection.appendChild(self.__fields)
+
+ self.__root.appendChild(self.__collection)
+ self.__doc.appendChild(self.__root)
+
+ # Current movie id. See entry's id attribute in self.addEntry()
+ self.__currentId = 0
+
+
+ def addEntry(self, movieData):
+ """
+ Add a comic entry.
+ Returns an entry node instance
+ """
+
+ d = movieData
+
+ # Convert all strings to UTF-8
+ for i in d.keys():
+ if type(d[i]) == types.ListType:
+ d[i] = [unicode(d[i][j], 'latin-1').encode('utf-8') for j in range(len(d[i]))]
+ elif type(d[i]) == types.StringType:
+ d[i] = unicode(d[i], 'latin-1').encode('utf-8')
+
+ entryNode = self.__doc.createElement('entry')
+ entryNode.setAttribute('id', str(self.__currentId))
+
+ titleNode = self.__doc.createElement('title')
+ titleNode.appendChild(self.__doc.createTextNode(d['title']))
+
+ yearNode = self.__doc.createElement('pub_year')
+ yearNode.appendChild(self.__doc.createTextNode(d['pub_year']))
+
+ pubNode = self.__doc.createElement('publisher')
+ pubNode.appendChild(self.__doc.createTextNode(d['publisher']))
+
+ langsNode = self.__doc.createElement('languages')
+ for l in d['language']:
+ langNode = self.__doc.createElement('language')
+ langNode.appendChild(self.__doc.createTextNode(l))
+ langsNode.appendChild(langNode)
+
+ keywordsNode = self.__doc.createElement('keywords')
+ keywordNode = self.__doc.createElement('keyword')
+ keywordNode.appendChild(self.__doc.createTextNode(d['keyword']))
+ keywordsNode.appendChild(keywordNode)
+
+ edNode = self.__doc.createElement('edition')
+ edNode.appendChild(self.__doc.createTextNode(d['edition']))
+
+ writersNode = self.__doc.createElement('authors')
+ for g in d['author']:
+ writerNode = self.__doc.createElement('author')
+ writerNode.appendChild(self.__doc.createTextNode(g))
+ writersNode.appendChild(writerNode)
+
+ commentsNode = self.__doc.createElement('comments')
+ commentsData = string.join(d['comments'], '<br/>')
+ commentsNode.appendChild(self.__doc.createTextNode(commentsData))
+
+ pagesNode = self.__doc.createElement('pages')
+ pagesNode.appendChild(self.__doc.createTextNode(d['pages']))
+
+ isbnNode = self.__doc.createElement('isbn')
+ isbnNode.appendChild(self.__doc.createTextNode(d['isbn']))
+
+ priceNode = self.__doc.createElement('pur_price')
+ priceNode.appendChild(self.__doc.createTextNode(d['pur_price']))
+
+ seriesNode = self.__doc.createElement('series')
+ seriesNode.appendChild(self.__doc.createTextNode(d['series']))
+
+ seriesNumNode = self.__doc.createElement('series_num')
+ seriesNumNode.appendChild(self.__doc.createTextNode(d['series_num']))
+
+ translatorNode = self.__doc.createElement('translator')
+ translatorNode.appendChild(self.__doc.createTextNode(d['translator']))
+
+ for name in ( 'title', 'year', 'pub', 'langs', 'keyword', 'ed', 'writers',
+ 'comments', 'pages', 'isbn', 'price', 'series', 'seriesNum', 'translator' ):
+ entryNode.appendChild(eval(name + 'Node'))
+
+ self.__collection.appendChild(entryNode)
+ self.__currentId += 1
+
+ return entryNode
+
+ def printEntry(self, nEntry):
+ """
+ Prints entry's XML content to stdout
+ """
+
+ try:
+ print nEntry.toxml()
+ except:
+ print sys.stderr, "Error while outputing XML content from entry to Tellico"
+
+ def printXMLTree(self):
+ """
+ Outputs XML content to stdout
+ """
+
+ print XML_HEADER; print DOCTYPE
+ print self.__root.toxml()
+
+
+class MinisterioCulturaParser:
+ def __init__(self):
+ # Search form is at http://www.mcu.es/comun/bases/isbn/ISBN.html
+ self.__baseURL = 'http://www.mcu.es'
+ self.__searchURL = '/cgi-brs/BasesHTML/isbn/BRSCGI?CMD=VERLST&BASE=ISBN&DOCS=1-15&CONF=AEISPA.cnf&OPDEF=AND&SEPARADOR=' + \
+ '&WDIS-C=DISPONIBLE+or+AGOTADO&WGEN-C=&WISB-C=%s&WAUT-C=%s&WTIT-C=%s&WMAT-C=&WEDI-C=&'
+
+ self.__suffixURL = 'WFEP-C=&%40T353-GE=&%40T353-LE=&WSER-C=&WLUG-C=&WLEN-C=&WCLA-C=&WSOP-C='
+
+ # Define some regexps
+ self.__regExps = { 'author' : '<th scope="row">Autor:.*?<td>(?P<author>.*?)</td>',
+ 'isbn' : '<span class="cabTitulo">ISBN.*?<strong>(?P<isbn>.*?)</strong>', # Matches ISBN 13
+ 'title' : '<th scope="row">T&iacute;tulo:.*?<td>(?P<title>.*?)</td>',
+ 'language' : '<th scope="row">Lengua:.*?<td>(?P<language>.*?)</td>',
+ 'edition' : '<th scope="row">Edici&oacute;n:.*?<td>.*?<span>(?P<edition>.*?)</span>',
+ 'pur_price' : '<th scope="row">Precio:.*?<td>.*?<span>(?P<pur_price>.*?)&euro;</span>',
+ 'desc' : '<th scope="row">Descripci&oacute;n:.*?<td>.*?<span>(?P<desc>.*?)</span>',
+ 'publication' : '<th scope="row">Publicaci&oacute;n:.*?<td>.*?<span>(?P<publication>.*?)</span>',
+ 'keyword' : '<th scope="row">Materias:.*?<td>.*?<span>(?P<keywords>.*?)</span>',
+ 'notas' : '<th scope="row">Notas:.*?<td>.*?<span>(?P<notas>.*?)</span>',
+ 'cdu' : '<th scope="row">CDU:.*?<td><span>(?P<cdu>.*?)</span></td>',
+ 'encuadernacion': '<th scope="row">Encuadernaci&oacute;n:.*?<td>.*?<span>(?P<encuadernacion>.*?)</span>',
+ 'series' : '<th scope="row">Colecci&oacute;n:.*?<td>.*?<span>(?P<series>.*?)</span>'
+ }
+
+ # Compile patterns objects
+ self.__regExpsPO = {}
+ for k, pattern in self.__regExps.iteritems():
+ self.__regExpsPO[k] = re.compile(pattern)
+
+ self.__domTree = BasicTellicoDOM()
+
+ def run(self, criteria, kind):
+ """
+ Runs the parser: fetch book related links, then fills and prints the DOM tree
+ to stdout (in tellico format) so that tellico can use it.
+ """
+
+ # Strip out hyphens if kind is ISBN
+ if kind == ISBN:
+ criteria = criteria.replace('-', NULLSTRING)
+ # Support for multiple search
+ isbnList = criteria.split(';')
+ for n in isbnList:
+ self.__getBook(n, kind)
+ else:
+ self.__getBook(criteria, kind)
+
+ # Print results to stdout
+ self.__domTree.printXMLTree()
+
+ def __getHTMLContent(self, url):
+ """
+ Fetch HTML data from url
+ """
+
+ try:
+ u = urllib2.urlopen(url)
+ except Exception, e:
+ u.close()
+ sys.exit("""
+Network error while getting HTML content.
+Tellico cannot connect to: http://www.mcu.es/comun/bases/isbn/ISBN.htm webpage:
+'%s'""" % e)
+
+
+ self.__data = u.read()
+ u.close()
+
+ def __fetchBookLinks(self):
+ """
+ Retrieve all links related to the search. self.__data contains HTML content fetched by self.__getHTMLContent()
+ that need to be parsed.
+ """
+
+ matchList = re.findall("""<div class="isbnResDescripcion">.*?<p>.*?<A target="_top" HREF="(?P<url>.*?)">""", self.__data, re.S)
+
+ if not matchList: return None
+ return matchList
+
+ def __fetchBookInfo(self, url):
+ """
+ Looks for book information
+ """
+
+ self.__getHTMLContent(url)
+
+ matches = {}
+ data = {}
+
+ data['comments'] = []
+ # Empty string if series not available
+ data['series_num'] = NULLSTRING
+ data['translator'] = NULLSTRING
+
+ for name, po in self.__regExpsPO.iteritems():
+ data[name] = NULLSTRING
+ matches[name] = re.search(self.__regExps[name], self.__data, re.S | re.I)
+
+
+ if matches[name]:
+ if name == 'title':
+ d = matches[name].group('title').strip()
+ d = re.sub('<.?strong>', NULLSTRING, d)
+ d = re.sub('\n', NULLSTRING, d)
+ data['title'] = d
+
+ elif name == 'isbn':
+ data['isbn'] = matches[name].group('isbn').strip()
+
+ elif name == 'edition':
+ data['edition'] = matches[name].group('edition').strip()
+
+ elif name == 'pur_price':
+ d = matches[name].group('pur_price')
+ data['pur_price'] = d.strip() + ' EUR'
+
+ elif name == 'publication':
+ d = matches[name].group('publication')
+ for p in ('</?[Aa].*?>', '&nbsp;', ':', ','):
+ d = re.sub(p, NULLSTRING, d)
+
+ d = d.split('\n')
+ # d[1] is an empty string
+ data['publisher'] = "%s (%s)" % (d[2], d[0])
+ data['pub_year'] = re.sub('\d{2}\/', NULLSTRING, d[3])
+ del data['publication']
+
+ elif name == 'desc':
+ d = matches[name].group('desc')
+ m = re.search('\d+ ', d)
+ # When not available
+ data['pages'] = NULLSTRING
+ if m:
+ data['pages'] = m.group(0).strip()
+ m = re.search('; (?P<format>.*cm)', d)
+ if m:
+ data['comments'].append('Format: ' + m.group('format').strip())
+ del data['desc']
+
+ elif name == 'encuadernacion':
+ data['comments'].append(matches[name].group('encuadernacion').strip())
+
+ elif name == 'keyword':
+ d = matches[name].group('keywords')
+ d = re.sub('</?[Aa].*?>', NULLSTRING, d)
+ data['keyword'] = d.strip()
+
+ elif name == 'cdu':
+ data['comments'].append('CDU: ' + matches[name].group('cdu').strip())
+
+ elif name == 'notas':
+ data['comments'].append(matches[name].group('notas').strip())
+
+ elif name == 'series':
+ d = matches[name].group('series').strip()
+ d = re.sub('&nbsp;', ' ', d)
+ data[name] = d
+ # data[name] can contain something like 'Byblos, 162/24'
+
+ # Maybe better to add the reg exp to get seriesNum in self.__regExps
+ p = re.compile('[0-9]+$')
+ s = re.search(p, data[name])
+
+ if s:
+ # if series ends with a number, it seems that is a
+ # number of the book inside the series. We save in seriesNum
+ data['series_num'] = s.group()
+
+ # it removes lasts digits (plus one because is space or /) from
+ # data['series']
+ l = len(data['series_num']) + 1
+ data[name] = data[name][0:-l]
+ data[name] = data[name].rstrip(",") # remove the , between series and series_num
+
+ elif name == 'author':
+ # We may find several authors
+ data[name] = []
+ authorsList = re.findall('<a.*?>(?P<author>.*?)</a>', matches[name].group('author'), re.S | re.I)
+ if not authorsList:
+ # No href links
+ authors = re.search('<li>(?P<author>.*?)</li>', matches[name].group('author'), re.S | re.I)
+ try:
+ results = authors.group('author').strip().split(',')
+ except AttributeError:
+ results = []
+ results = [r.strip() for r in results]
+ data[name] = results
+ else:
+ for d in authorsList:
+ # Sometimes, the search engine outputs some image between a elements
+ if d.strip()[:4] != '<img':
+ data[name].append(d.strip())
+
+ # Move tr authors (translators) to translators list
+ translator = self.__getSpecialRol(data[name], TRANSLATOR_STR)
+ edlit = self.__getSpecialRol(data[name], EDLIT_STR)
+ data[name] = self.__removeSpecialsFromAuthors(data[name], translator, TRANSLATOR_STR)
+ data[name] = self.__removeSpecialsFromAuthors(data[name], edlit, EDLIT_STR)
+
+ if len(translator) > 0:
+ data['translator'] = self.__formatSpecials(translator, NULLSTRING)
+
+ if len(edlit) > 0:
+ data['comments'].append(self.__formatSpecials(edlit, "Editor Literario: "))
+
+ elif name == 'language':
+ # We may find several languages
+ d = matches[name].group('language')
+ d = re.sub('\n', NULLSTRING, d)
+ d = d.split('<span>')
+ a = []
+ for lg in d:
+ if len(lg):
+ lg = re.sub('</span>', NULLSTRING, lg)
+ # Because HTML is not interpreted in the 'language' field of Tellico
+ lg = re.sub('&oacute;', 'o', lg)
+ a.append(lg.strip())
+ # Removes that word so that only the language name remains.
+ a[0] = re.sub('publicacion: ', NULLSTRING, a[0])
+ data['language'] = a
+ # Add other language related info to the 'comments' field too
+ #for lg in a[1:]:
+ #data['comments'].append(lg)
+
+ return data
+
+
+ def __getBook(self, data, kind = ISBN):
+ if not len(data):
+ raise EngineError, "No data given. Unable to proceed."
+
+ if kind == ISBN:
+ self.__getHTMLContent("%s%s%s" % (self.__baseURL, self.__searchURL % \
+ (urllib.quote(data), # ISBN
+ NULLSTRING, # AUTHOR
+ NULLSTRING), # TITLE
+ self.__suffixURL)
+ )
+ elif kind == AUTHOR:
+ self.__getHTMLContent("%s%s%s" % (self.__baseURL, self.__searchURL % \
+ (NULLSTRING, # ISBN
+ urllib.quote(data), # AUTHOR
+ NULLSTRING), # TITLE
+ self.__suffixURL)
+ )
+
+ elif kind == TITLE:
+ self.__getHTMLContent("%s%s%s" % (self.__baseURL, self.__searchURL % \
+ (NULLSTRING, # ISBN
+ NULLSTRING, # AUTHOR
+ urllib.quote(data)), # TITLE
+ self.__suffixURL)
+ )
+
+ # Get all links
+ links = self.__fetchBookLinks()
+
+ # Now retrieve infos
+ if links:
+ for entry in links:
+ data = self.__fetchBookInfo( url = self.__baseURL + entry.replace(' ', '%20') )
+ node = self.__domTree.addEntry(data)
+ else:
+ return None
+
+ def __getSpecialRol(self, authors, special):
+ """
+ Receives a list like ['Stephen King','Lorenzo Cortina','tr.',
+ 'Rosala Vzquez','tr.'] and returns a list with special names
+ """
+
+ j = 0; max = len(authors)
+ special_rol = []
+ while j < max:
+ if authors[j] == special:
+ special_rol.append(authors[j-1])
+ j += 1
+
+ return special_rol
+
+ def __removeSpecialsFromAuthors(self, authors, specials, string):
+ """
+ Receives a list with authors+translators and removes 'tr.' and
+ authors from there. Example:
+ authors: ['Stephen King','Lorenzo Cortina','tr.','Rosala Vzquez','tr.']
+ translators: ['Lorenzo Cortina','Rosala Vzquez']
+ returns: ['Stephen King']
+
+ (We could also guess string value because is the next position
+ in authors list)
+ """
+
+ newauthors = authors[:]
+
+ for t in specials:
+ newauthors.remove(t)
+ newauthors.remove(string)
+
+ return newauthors
+
+ def __formatSpecials(self, translators, prefix):
+ """
+ Receives a list with translators and returns a string
+ (authors are handled different: each author in a different node)
+ """
+
+ return prefix + string.join(translators, '; ')
+
+def halt():
+ print "HALT."
+ sys.exit(0)
+
+def showUsage():
+ print """Usage: %s options
+Where options are:
+ -t title
+ -i (ISBN|UPC)
+ -a author
+ -m filename (support for multiple ISBN/UPC search)""" % sys.argv[0]
+ sys.exit(1)
+
+def main():
+ if len(sys.argv) < 3:
+ showUsage()
+
+ socket.setdefaulttimeout(5)
+
+ # ;-separated ISBNs string
+ isbnStringList = NULLSTRING
+
+ opts = {'-t' : TITLE, '-i' : ISBN, '-a' : AUTHOR, '-m' : isbnStringList}
+ if sys.argv[1] not in opts.keys():
+ showUsage()
+
+ if sys.argv[1] == '-m':
+ try:
+ f = open(sys.argv[2], 'r')
+ data = f.readlines()
+ # remove trailing \n
+ sys.argv[2] = string.join([d[:-1] for d in data], ';')
+ sys.argv[1] = '-i'
+ f.close()
+ except IOError, e:
+ print "Error: %s" % e
+ sys.exit(1)
+
+ parser = MinisterioCulturaParser()
+ parser.run(sys.argv[2], opts[sys.argv[1]])
+
+if __name__ == '__main__':
+ main()
diff --git a/src/fetch/scripts/ministerio_de_cultura.py.spec b/src/fetch/scripts/ministerio_de_cultura.py.spec
new file mode 100644
index 0000000..ef24ac5
--- /dev/null
+++ b/src/fetch/scripts/ministerio_de_cultura.py.spec
@@ -0,0 +1,7 @@
+Name=Spanish Ministry of Culture
+Type=data-source
+ArgumentKeys=1,2,3,4
+Arguments=-t %1,-a %1,-i %1,-i %1
+CollectionType=2
+FormatType=0
+UpdateArgs=-t %{title}
diff --git a/src/fetch/srufetcher.cpp b/src/fetch/srufetcher.cpp
new file mode 100644
index 0000000..1d7289b
--- /dev/null
+++ b/src/fetch/srufetcher.cpp
@@ -0,0 +1,541 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "srufetcher.h"
+#include "messagehandler.h"
+#include "../field.h"
+#include "../collection.h"
+#include "../translators/tellico_xml.h"
+#include "../translators/xslthandler.h"
+#include "../translators/tellicoimporter.h"
+#include "../translators/dcimporter.h"
+#include "../tellico_kernel.h"
+#include "../tellico_debug.h"
+#include "../gui/lineedit.h"
+#include "../gui/combobox.h"
+#include "../latin1literal.h"
+#include "../tellico_utils.h"
+#include "../lccnvalidator.h"
+
+#include <klocale.h>
+#include <kio/job.h>
+#include <kstandarddirs.h>
+#include <kconfig.h>
+#include <kcombobox.h>
+#include <kaccelmanager.h>
+#include <knuminput.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qwhatsthis.h>
+
+//#define SRU_DEBUG
+
+namespace {
+ // 7090 was the old default port, but that wa sjust because LoC used it
+ // let's use default HTTP port of 80 now
+ static const int SRU_DEFAULT_PORT = 80;
+ static const int SRU_MAX_RECORDS = 25;
+}
+
+using Tellico::Fetch::SRUFetcher;
+using Tellico::Fetch::SRUConfigWidget;
+
+SRUFetcher::SRUFetcher(QObject* parent_, const char* name_)
+ : Fetcher(parent_, name_), m_job(0), m_MARCXMLHandler(0), m_MODSHandler(0), m_started(false) {
+}
+
+SRUFetcher::SRUFetcher(const QString& name_, const QString& host_, uint port_, const QString& path_,
+ QObject* parent_) : Fetcher(parent_),
+ m_host(host_), m_port(port_), m_path(path_),
+ m_job(0), m_MARCXMLHandler(0), m_MODSHandler(0), m_started(false) {
+ m_name = name_; // m_name is protected in super class
+}
+
+SRUFetcher::~SRUFetcher() {
+ delete m_MARCXMLHandler;
+ m_MARCXMLHandler = 0;
+ delete m_MODSHandler;
+ m_MODSHandler = 0;
+}
+
+QString SRUFetcher::defaultName() {
+ return i18n("SRU Server");
+}
+
+QString SRUFetcher::source() const {
+ return m_name.isEmpty() ? defaultName() : m_name;
+}
+
+bool SRUFetcher::canFetch(int type) const {
+ return type == Data::Collection::Book || type == Data::Collection::Bibtex;
+}
+
+void SRUFetcher::readConfigHook(const KConfigGroup& config_) {
+ m_host = config_.readEntry("Host");
+ int p = config_.readNumEntry("Port", SRU_DEFAULT_PORT);
+ if(p > 0) {
+ m_port = p;
+ }
+ m_path = config_.readEntry("Path");
+ // used to be called Database
+ if(m_path.isEmpty()) {
+ m_path = config_.readEntry("Database");
+ }
+ if(!m_path.startsWith(QChar('/'))) {
+ m_path.prepend('/');
+ }
+ m_format = config_.readEntry("Format", QString::fromLatin1("mods"));
+ m_fields = config_.readListEntry("Custom Fields");
+}
+
+void SRUFetcher::search(FetchKey key_, const QString& value_) {
+ if(m_host.isEmpty() || m_path.isEmpty()) {
+ myDebug() << "SRUFetcher::search() - settings are not set!" << endl;
+ stop();
+ return;
+ }
+
+ m_started = true;
+
+#ifdef SRU_DEBUG
+ KURL u = KURL::fromPathOrURL(QString::fromLatin1("/home/robby/sru.xml"));
+#else
+ KURL u;
+ u.setProtocol(QString::fromLatin1("http"));
+ u.setHost(m_host);
+ u.setPort(m_port);
+ u.setPath(m_path);
+
+ u.addQueryItem(QString::fromLatin1("operation"), QString::fromLatin1("searchRetrieve"));
+ u.addQueryItem(QString::fromLatin1("version"), QString::fromLatin1("1.1"));
+ u.addQueryItem(QString::fromLatin1("maximumRecords"), QString::number(SRU_MAX_RECORDS));
+ u.addQueryItem(QString::fromLatin1("recordSchema"), m_format);
+
+ const int type = Kernel::self()->collectionType();
+ QString str = QChar('"') + value_ + QChar('"');
+ switch(key_) {
+ case Title:
+ u.addQueryItem(QString::fromLatin1("query"), QString::fromLatin1("dc.title=") + str);
+ break;
+
+ case Person:
+ {
+ QString s;
+ if(type == Data::Collection::Book || type == Data::Collection::Bibtex) {
+ s = QString::fromLatin1("author=") + str + QString::fromLatin1(" or dc.author=") + str;
+ } else {
+ s = QString::fromLatin1("dc.creator=") + str + QString::fromLatin1(" or dc.editor=") + str;
+ }
+ u.addQueryItem(QString::fromLatin1("query"), s);
+ }
+ break;
+
+ case ISBN:
+ // no validation here
+ str.remove('-');
+ // limit to first isbn
+ str = str.section(';', 0, 0);
+ u.addQueryItem(QString::fromLatin1("query"), QString::fromLatin1("bath.isbn=") + str);
+ break;
+
+ case LCCN:
+ {
+ // limit to first lccn
+ str.remove('-');
+ str = str.section(';', 0, 0);
+ // also try formalized lccn
+ QString lccn = LCCNValidator::formalize(str);
+ u.addQueryItem(QString::fromLatin1("query"),
+ QString::fromLatin1("bath.lccn=") + str +
+ QString::fromLatin1(" or bath.lccn=") + lccn
+ );
+ }
+ break;
+
+ case Keyword:
+ u.addQueryItem(QString::fromLatin1("query"), str);
+ break;
+
+ case Raw:
+ {
+ QString key = value_.section('=', 0, 0).stripWhiteSpace();
+ QString str = value_.section('=', 1).stripWhiteSpace();
+ u.addQueryItem(key, str);
+ }
+ break;
+
+ default:
+ kdWarning() << "SRUFetcher::search() - key not recognized: " << key_ << endl;
+ stop();
+ break;
+ }
+#endif
+// myDebug() << u.prettyURL() << endl;
+
+ m_job = KIO::get(u, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+}
+
+void SRUFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+ if(m_job) {
+ m_job->kill();
+ m_job = 0;
+ }
+ m_data.truncate(0);
+ m_started = false;
+ emit signalDone(this);
+}
+
+void SRUFetcher::slotData(KIO::Job*, const QByteArray& data_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(data_.data(), data_.size());
+}
+
+void SRUFetcher::slotComplete(KIO::Job* job_) {
+ // since the fetch is done, don't worry about holding the job pointer
+ m_job = 0;
+
+ if(job_->error()) {
+ job_->showErrorDialog(Kernel::self()->widget());
+ stop();
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ stop();
+ return;
+ }
+
+ Data::CollPtr coll;
+ QString msg;
+
+ const QString result = QString::fromUtf8(m_data, m_data.size());
+
+ // first check for SRU errors
+ const QString& diag = XML::nsZingDiag;
+ Import::XMLImporter xmlImporter(result);
+ QDomDocument dom = xmlImporter.domDocument();
+
+ QDomNodeList diagList = dom.elementsByTagNameNS(diag, QString::fromLatin1("diagnostic"));
+ for(uint i = 0; i < diagList.count(); ++i) {
+ QDomElement elem = diagList.item(i).toElement();
+ QDomNodeList nodeList1 = elem.elementsByTagNameNS(diag, QString::fromLatin1("message"));
+ QDomNodeList nodeList2 = elem.elementsByTagNameNS(diag, QString::fromLatin1("details"));
+ for(uint j = 0; j < nodeList1.count(); ++j) {
+ QString d = nodeList1.item(j).toElement().text();
+ if(!d.isEmpty()) {
+ QString d2 = nodeList2.item(j).toElement().text();
+ if(!d2.isEmpty()) {
+ d += " (" + d2 + ')';
+ }
+ myDebug() << "SRUFetcher::slotComplete() - " << d << endl;
+ if(!msg.isEmpty()) msg += '\n';
+ msg += d;
+ }
+ }
+ }
+
+ QString modsResult;
+ if(m_format == Latin1Literal("mods")) {
+ modsResult = result;
+ } else if(m_format == Latin1Literal("marcxml") && initMARCXMLHandler()) {
+ modsResult = m_MARCXMLHandler->applyStylesheet(result);
+ }
+ if(!modsResult.isEmpty() && initMODSHandler()) {
+ Import::TellicoImporter imp(m_MODSHandler->applyStylesheet(modsResult));
+ coll = imp.collection();
+ if(!msg.isEmpty()) msg += '\n';
+ msg += imp.statusMessage();
+ } else if(m_format == Latin1Literal("dc")) {
+ Import::DCImporter imp(dom);
+ coll = imp.collection();
+ if(!msg.isEmpty()) msg += '\n';
+ msg += imp.statusMessage();
+ } else {
+ myDebug() << "SRUFetcher::slotComplete() - unrecognized format: " << m_format << endl;
+ stop();
+ return;
+ }
+
+ if(coll && !msg.isEmpty()) {
+ message(msg, coll->entryCount() == 0 ? MessageHandler::Warning : MessageHandler::Status);
+ }
+
+ if(!coll) {
+ myDebug() << "SRUFetcher::slotComplete() - no collection pointer" << endl;
+ if(!msg.isEmpty()) {
+ message(msg, MessageHandler::Error);
+ }
+ stop();
+ return;
+ }
+
+ const StringMap customFields = SRUFetcher::customFields();
+ for(StringMap::ConstIterator it = customFields.begin(); it != customFields.end(); ++it) {
+ if(!m_fields.contains(it.key())) {
+ coll->removeField(it.key());
+ }
+ }
+
+ Data::EntryVec entries = coll->entries();
+ for(Data::EntryVec::Iterator entry = entries.begin(); entry != entries.end(); ++entry) {
+ QString desc;
+ switch(coll->type()) {
+ case Data::Collection::Book:
+ desc = entry->field(QString::fromLatin1("author"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("publisher"));
+ if(!entry->field(QString::fromLatin1("cr_year")).isEmpty()) {
+ desc += QChar('/') + entry->field(QString::fromLatin1("cr_year"));
+ } else if(!entry->field(QString::fromLatin1("pub_year")).isEmpty()){
+ desc += QChar('/') + entry->field(QString::fromLatin1("pub_year"));
+ }
+ break;
+
+ case Data::Collection::Video:
+ desc = entry->field(QString::fromLatin1("studio"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("director"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("year"));
+ break;
+
+ case Data::Collection::Album:
+ desc = entry->field(QString::fromLatin1("artist"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("label"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("year"));
+ break;
+
+ default:
+ break;
+ }
+ SearchResult* r = new SearchResult(this, entry->title(), desc, entry->field(QString::fromLatin1("isbn")));
+ m_entries.insert(r->uid, entry);
+ emit signalResultFound(r);
+ }
+ stop();
+}
+
+Tellico::Data::EntryPtr SRUFetcher::fetchEntry(uint uid_) {
+ return m_entries[uid_];
+}
+
+void SRUFetcher::updateEntry(Data::EntryPtr entry_) {
+// myDebug() << "SRUFetcher::updateEntry() - " << source() << ": " << entry_->title() << endl;
+ QString isbn = entry_->field(QString::fromLatin1("isbn"));
+ if(!isbn.isEmpty()) {
+ search(Fetch::ISBN, isbn);
+ return;
+ }
+
+ QString lccn = entry_->field(QString::fromLatin1("lccn"));
+ if(!lccn.isEmpty()) {
+ search(Fetch::LCCN, lccn);
+ return;
+ }
+
+ // optimistically try searching for title and rely on Collection::sameEntry() to figure things out
+ QString t = entry_->field(QString::fromLatin1("title"));
+ if(!t.isEmpty()) {
+ search(Fetch::Title, t);
+ return;
+ }
+
+ myDebug() << "SRUFetcher::updateEntry() - insufficient info to search" << endl;
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+bool SRUFetcher::initMARCXMLHandler() {
+ if(m_MARCXMLHandler) {
+ return true;
+ }
+
+ QString xsltfile = locate("appdata", QString::fromLatin1("MARC21slim2MODS3.xsl"));
+ if(xsltfile.isEmpty()) {
+ kdWarning() << "SRUFetcher::initHandlers() - can not locate MARC21slim2MODS3.xsl." << endl;
+ return false;
+ }
+
+ KURL u;
+ u.setPath(xsltfile);
+
+ m_MARCXMLHandler = new XSLTHandler(u);
+ if(!m_MARCXMLHandler->isValid()) {
+ kdWarning() << "SRUFetcher::initHandlers() - error in MARC21slim2MODS3.xsl." << endl;
+ delete m_MARCXMLHandler;
+ m_MARCXMLHandler = 0;
+ return false;
+ }
+ return true;
+}
+
+bool SRUFetcher::initMODSHandler() {
+ if(m_MODSHandler) {
+ return true;
+ }
+
+ QString xsltfile = locate("appdata", QString::fromLatin1("mods2tellico.xsl"));
+ if(xsltfile.isEmpty()) {
+ kdWarning() << "SRUFetcher::initHandlers() - can not locate mods2tellico.xsl." << endl;
+ return false;
+ }
+
+ KURL u;
+ u.setPath(xsltfile);
+
+ m_MODSHandler = new XSLTHandler(u);
+ if(!m_MODSHandler->isValid()) {
+ kdWarning() << "SRUFetcher::initHandlers() - error in mods2tellico.xsl." << endl;
+ delete m_MODSHandler;
+ m_MODSHandler = 0;
+ return false;
+ }
+ return true;
+}
+
+Tellico::Fetch::Fetcher::Ptr SRUFetcher::libraryOfCongress(QObject* parent_) {
+ return new SRUFetcher(i18n("Library of Congress (US)"), QString::fromLatin1("z3950.loc.gov"), 7090,
+ QString::fromLatin1("voyager"), parent_);
+}
+
+// static
+Tellico::StringMap SRUFetcher::customFields() {
+ StringMap map;
+ map[QString::fromLatin1("address")] = i18n("Address");
+ map[QString::fromLatin1("abstract")] = i18n("Abstract");
+ return map;
+}
+
+Tellico::Fetch::ConfigWidget* SRUFetcher::configWidget(QWidget* parent_) const {
+ return new SRUConfigWidget(parent_, this);
+}
+
+SRUConfigWidget::SRUConfigWidget(QWidget* parent_, const SRUFetcher* fetcher_ /*=0*/)
+ : ConfigWidget(parent_) {
+ QGridLayout* l = new QGridLayout(optionsWidget(), 4, 2);
+ l->setSpacing(4);
+ l->setColStretch(1, 10);
+
+ int row = -1;
+ QLabel* label = new QLabel(i18n("Hos&t: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_hostEdit = new GUI::LineEdit(optionsWidget());
+ connect(m_hostEdit, SIGNAL(textChanged(const QString&)), SLOT(slotSetModified()));
+ connect(m_hostEdit, SIGNAL(textChanged(const QString&)), SIGNAL(signalName(const QString&)));
+ connect(m_hostEdit, SIGNAL(textChanged(const QString&)), SLOT(slotCheckHost()));
+ l->addWidget(m_hostEdit, row, 1);
+ QString w = i18n("Enter the host name of the server.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_hostEdit, w);
+ label->setBuddy(m_hostEdit);
+
+ label = new QLabel(i18n("&Port: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_portSpinBox = new KIntSpinBox(0, 999999, 1, SRU_DEFAULT_PORT, 10, optionsWidget());
+ connect(m_portSpinBox, SIGNAL(valueChanged(int)), SLOT(slotSetModified()));
+ l->addWidget(m_portSpinBox, row, 1);
+ w = i18n("Enter the port number of the server. The default is %1.").arg(SRU_DEFAULT_PORT);
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_portSpinBox, w);
+ label->setBuddy(m_portSpinBox);
+
+ label = new QLabel(i18n("Path: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_pathEdit = new GUI::LineEdit(optionsWidget());
+ connect(m_pathEdit, SIGNAL(textChanged(const QString&)), SLOT(slotSetModified()));
+ l->addWidget(m_pathEdit, row, 1);
+ w = i18n("Enter the path to the database used by the server.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_pathEdit, w);
+ label->setBuddy(m_pathEdit);
+
+ label = new QLabel(i18n("Format: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_formatCombo = new GUI::ComboBox(optionsWidget());
+ m_formatCombo->insertItem(QString::fromLatin1("MODS"), QString::fromLatin1("mods"));
+ m_formatCombo->insertItem(QString::fromLatin1("MARCXML"), QString::fromLatin1("marcxml"));
+ m_formatCombo->insertItem(QString::fromLatin1("Dublin Core"), QString::fromLatin1("dc"));
+ connect(m_formatCombo, SIGNAL(activated(int)), SLOT(slotSetModified()));
+ l->addWidget(m_formatCombo, row, 1);
+ w = i18n("Enter the result format used by the server.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_formatCombo, w);
+ label->setBuddy(m_formatCombo);
+
+ l->setRowStretch(++row, 1);
+
+ // now add additional fields widget
+ addFieldsWidget(SRUFetcher::customFields(), fetcher_ ? fetcher_->m_fields : QStringList());
+
+ if(fetcher_) {
+ m_hostEdit->setText(fetcher_->m_host);
+ m_portSpinBox->setValue(fetcher_->m_port);
+ m_pathEdit->setText(fetcher_->m_path);
+ m_formatCombo->setCurrentData(fetcher_->m_format);
+ }
+ KAcceleratorManager::manage(optionsWidget());
+}
+
+void SRUConfigWidget::saveConfig(KConfigGroup& config_) {
+ QString s = m_hostEdit->text().stripWhiteSpace();
+ if(!s.isEmpty()) {
+ config_.writeEntry("Host", s);
+ }
+ int port = m_portSpinBox->value();
+ if(port > 0) {
+ config_.writeEntry("Port", port);
+ }
+ s = m_pathEdit->text().stripWhiteSpace();
+ if(!s.isEmpty()) {
+ config_.writeEntry("Path", s);
+ }
+ s = m_formatCombo->currentData().toString();
+ if(!s.isEmpty()) {
+ config_.writeEntry("Format", s);
+ }
+ saveFieldsConfig(config_);
+ slotSetModified(false);
+}
+
+QString SRUConfigWidget::preferredName() const {
+ QString s = m_hostEdit->text();
+ return s.isEmpty() ? SRUFetcher::defaultName() : s;
+}
+
+void SRUConfigWidget::slotCheckHost() {
+ QString s = m_hostEdit->text();
+ // someone might be pasting a full URL, check that
+ if(s.find(':') > -1 || s.find('/') > -1) {
+ KURL u(s);
+ if(u.isValid()) {
+ m_hostEdit->setText(u.host());
+ if(u.port() > 0) {
+ m_portSpinBox->setValue(u.port());
+ }
+ if(!u.path().isEmpty()) {
+ m_pathEdit->setText(u.path());
+ }
+ }
+ }
+}
+
+#include "srufetcher.moc"
diff --git a/src/fetch/srufetcher.h b/src/fetch/srufetcher.h
new file mode 100644
index 0000000..fd07323
--- /dev/null
+++ b/src/fetch/srufetcher.h
@@ -0,0 +1,131 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_SRUFETCHER_H
+#define TELLICO_SRUFETCHER_H
+
+namespace Tellico {
+ class XSLTHandler;
+ namespace GUI {
+ class LineEdit;
+ class ComboBox;
+ }
+}
+
+class KIntSpinBox;
+class KComboBox;
+namespace KIO {
+ class Job;
+}
+
+#include "fetcher.h"
+#include "configwidget.h"
+#include "../datavectors.h"
+
+#include <qcstring.h> // for QByteArray
+#include <qguardedptr.h>
+
+namespace Tellico {
+ namespace Fetch {
+
+class SRUConfigWidget;
+
+/**
+ * A fetcher for SRU servers.
+ * Right now, only MODS is supported.
+ *
+ * @author Robby Stephenson
+ */
+class SRUFetcher : public Fetcher {
+Q_OBJECT
+
+friend class SRUConfigWidget;
+
+public:
+ /**
+ */
+ SRUFetcher(QObject* parent, const char* name = 0);
+ SRUFetcher(const QString& name, const QString& host, uint port, const QString& dbname,
+ QObject* parent);
+ /**
+ */
+ virtual ~SRUFetcher();
+
+ /**
+ */
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual void search(FetchKey key, const QString& value);
+ // only search title, person, isbn, or keyword. No Raw for now.
+ virtual bool canSearch(FetchKey k) const { return k == Title || k == Person || k == ISBN || k == Keyword || k == LCCN; }
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return SRU; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+
+ virtual void updateEntry(Data::EntryPtr entry);
+
+ static StringMap customFields();
+
+ virtual ConfigWidget* configWidget(QWidget* parent) const;
+
+ static QString defaultName();
+
+ static Fetcher::Ptr libraryOfCongress(QObject* parent);
+
+private slots:
+ void slotData(KIO::Job* job, const QByteArray& data);
+ void slotComplete(KIO::Job* job);
+
+private:
+ bool initMARCXMLHandler();
+ bool initMODSHandler();
+
+ QString m_host;
+ uint m_port;
+ QString m_path;
+ QString m_format;
+
+ QByteArray m_data;
+ QMap<int, Data::EntryPtr> m_entries;
+ QGuardedPtr<KIO::Job> m_job;
+ XSLTHandler* m_MARCXMLHandler;
+ XSLTHandler* m_MODSHandler;
+ bool m_started;
+ QStringList m_fields;
+};
+
+class SRUConfigWidget : public ConfigWidget {
+Q_OBJECT
+
+friend class SRUFetcher;
+
+public:
+ SRUConfigWidget(QWidget* parent_, const SRUFetcher* fetcher = 0);
+ virtual void saveConfig(KConfigGroup& config);
+ virtual QString preferredName() const;
+
+private slots:
+ void slotCheckHost();
+
+private:
+ GUI::LineEdit* m_hostEdit;
+ KIntSpinBox* m_portSpinBox;
+ GUI::LineEdit* m_pathEdit;
+ GUI::ComboBox* m_formatCombo;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/fetch/yahoofetcher.cpp b/src/fetch/yahoofetcher.cpp
new file mode 100644
index 0000000..002b63b
--- /dev/null
+++ b/src/fetch/yahoofetcher.cpp
@@ -0,0 +1,400 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "yahoofetcher.h"
+#include "messagehandler.h"
+#include "../translators/xslthandler.h"
+#include "../translators/tellicoimporter.h"
+#include "../imagefactory.h"
+#include "../tellico_kernel.h"
+#include "../tellico_utils.h"
+#include "../collection.h"
+#include "../entry.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kconfig.h>
+#include <kio/job.h>
+
+#include <qdom.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qfile.h>
+
+namespace {
+ static const int YAHOO_MAX_RETURNS_TOTAL = 20;
+ static const char* YAHOO_BASE_URL = "http://search.yahooapis.com/AudioSearchService/V1/albumSearch";
+ static const char* YAHOO_APP_ID = "tellico-robby";
+}
+
+using Tellico::Fetch::YahooFetcher;
+
+YahooFetcher::YahooFetcher(QObject* parent_, const char* name_)
+ : Fetcher(parent_, name_), m_xsltHandler(0),
+ m_limit(YAHOO_MAX_RETURNS_TOTAL), m_job(0), m_started(false) {
+}
+
+YahooFetcher::~YahooFetcher() {
+ delete m_xsltHandler;
+ m_xsltHandler = 0;
+}
+
+QString YahooFetcher::defaultName() {
+ return i18n("Yahoo! Audio Search");
+}
+
+QString YahooFetcher::source() const {
+ return m_name.isEmpty() ? defaultName() : m_name;
+}
+
+bool YahooFetcher::canFetch(int type) const {
+ return type == Data::Collection::Album;
+}
+
+void YahooFetcher::readConfigHook(const KConfigGroup& config_) {
+ Q_UNUSED(config_);
+}
+
+void YahooFetcher::search(FetchKey key_, const QString& value_) {
+ m_key = key_;
+ m_value = value_;
+ m_started = true;
+ m_start = 1;
+ m_total = -1;
+ doSearch();
+}
+
+void YahooFetcher::continueSearch() {
+ m_started = true;
+ doSearch();
+}
+
+void YahooFetcher::doSearch() {
+// myDebug() << "YahooFetcher::search() - value = " << value_ << endl;
+
+ KURL u(QString::fromLatin1(YAHOO_BASE_URL));
+ u.addQueryItem(QString::fromLatin1("appid"), QString::fromLatin1(YAHOO_APP_ID));
+ u.addQueryItem(QString::fromLatin1("type"), QString::fromLatin1("all"));
+ u.addQueryItem(QString::fromLatin1("output"), QString::fromLatin1("xml"));
+ u.addQueryItem(QString::fromLatin1("start"), QString::number(m_start));
+ u.addQueryItem(QString::fromLatin1("results"), QString::number(YAHOO_MAX_RETURNS_TOTAL));
+
+ if(!canFetch(Kernel::self()->collectionType())) {
+ message(i18n("%1 does not allow searching for this collection type.").arg(source()), MessageHandler::Warning);
+ stop();
+ return;
+ }
+
+ switch(m_key) {
+ case Title:
+ u.addQueryItem(QString::fromLatin1("album"), m_value);
+ break;
+
+ case Person:
+ u.addQueryItem(QString::fromLatin1("artist"), m_value);
+ break;
+
+ // raw is used for the entry updates
+ case Raw:
+// u.removeQueryItem(QString::fromLatin1("type"));
+// u.addQueryItem(QString::fromLatin1("type"), QString::fromLatin1("phrase"));
+ u.setQuery(u.query() + '&' + m_value);
+ break;
+
+ default:
+ kdWarning() << "YahooFetcher::search() - key not recognized: " << m_key << endl;
+ stop();
+ return;
+ }
+// myDebug() << "YahooFetcher::search() - url: " << u.url() << endl;
+
+ m_job = KIO::get(u, false, false);
+ connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(m_job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotComplete(KIO::Job*)));
+}
+
+void YahooFetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+ if(m_job) {
+ m_job->kill();
+ m_job = 0;
+ }
+ m_data.truncate(0);
+ m_started = false;
+ emit signalDone(this);
+}
+
+void YahooFetcher::slotData(KIO::Job*, const QByteArray& data_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(data_.data(), data_.size());
+}
+
+void YahooFetcher::slotComplete(KIO::Job* job_) {
+// myDebug() << "YahooFetcher::slotComplete()" << endl;
+ // since the fetch is done, don't worry about holding the job pointer
+ m_job = 0;
+
+ if(job_->error()) {
+ job_->showErrorDialog(Kernel::self()->widget());
+ stop();
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "YahooFetcher::slotComplete() - no data" << endl;
+ stop();
+ return;
+ }
+
+#if 0
+ kdWarning() << "Remove debug from yahoofetcher.cpp" << endl;
+ QFile f(QString::fromLatin1("/tmp/test.xml"));
+ if(f.open(IO_WriteOnly)) {
+ QTextStream t(&f);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << QCString(m_data, m_data.size()+1);
+ }
+ f.close();
+#endif
+
+ if(!m_xsltHandler) {
+ initXSLTHandler();
+ if(!m_xsltHandler) { // probably an error somewhere in the stylesheet loading
+ stop();
+ return;
+ }
+ }
+
+ if(m_total == -1) {
+ QDomDocument dom;
+ if(!dom.setContent(m_data, false)) {
+ kdWarning() << "YahooFetcher::slotComplete() - server did not return valid XML." << endl;
+ return;
+ }
+ // total is top level element, with attribute totalResultsAvailable
+ QDomElement e = dom.documentElement();
+ if(!e.isNull()) {
+ m_total = e.attribute(QString::fromLatin1("totalResultsAvailable")).toInt();
+ }
+ }
+
+ // assume yahoo is always utf-8
+ QString str = m_xsltHandler->applyStylesheet(QString::fromUtf8(m_data, m_data.size()));
+ Import::TellicoImporter imp(str);
+ Data::CollPtr coll = imp.collection();
+ if(!coll) {
+ myDebug() << "YahooFetcher::slotComplete() - no collection pointer" << endl;
+ stop();
+ return;
+ }
+
+ int count = 0;
+ Data::EntryVec entries = coll->entries();
+ for(Data::EntryVec::Iterator entry = entries.begin(); count < m_limit && entry != entries.end(); ++entry, ++count) {
+ if(!m_started) {
+ // might get aborted
+ break;
+ }
+ QString desc = entry->field(QString::fromLatin1("artist"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("label"))
+ + QChar('/')
+ + entry->field(QString::fromLatin1("year"));
+
+ SearchResult* r = new SearchResult(this, entry->title(), desc, entry->field(QString::fromLatin1("isbn")));
+ m_entries.insert(r->uid, Data::EntryPtr(entry));
+ emit signalResultFound(r);
+ }
+ m_start = m_entries.count() + 1;
+ m_hasMoreResults = m_start <= m_total;
+ stop(); // required
+}
+
+Tellico::Data::EntryPtr YahooFetcher::fetchEntry(uint uid_) {
+ Data::EntryPtr entry = m_entries[uid_];
+ if(!entry) {
+ kdWarning() << "YahooFetcher::fetchEntry() - no entry in dict" << endl;
+ return 0;
+ }
+
+ KURL imageURL = entry->field(QString::fromLatin1("image"));
+ if(!imageURL.isEmpty()) {
+ QString id = ImageFactory::addImage(imageURL, true);
+ if(id.isEmpty()) {
+ // rich text causes layout issues
+// emit signalStatus(i18n("<qt>The cover image for <i>%1</i> could not be loaded.</qt>").arg(
+// entry->field(QString::fromLatin1("title"))));
+ message(i18n("The cover image could not be loaded."), MessageHandler::Warning);
+ } else {
+ entry->setField(QString::fromLatin1("cover"), id);
+ }
+ }
+
+ getTracks(entry);
+
+ // don't want to show image urls in the fetch dialog
+ entry->setField(QString::fromLatin1("image"), QString::null);
+ // no need for album id now ?
+ entry->setField(QString::fromLatin1("yahoo"), QString::null);
+ return entry;
+}
+
+void YahooFetcher::initXSLTHandler() {
+ QString xsltfile = locate("appdata", QString::fromLatin1("yahoo2tellico.xsl"));
+ if(xsltfile.isEmpty()) {
+ kdWarning() << "YahooFetcher::initXSLTHandler() - can not locate yahoo2tellico.xsl." << endl;
+ return;
+ }
+
+ KURL u;
+ u.setPath(xsltfile);
+
+ delete m_xsltHandler;
+ m_xsltHandler = new XSLTHandler(u);
+ if(!m_xsltHandler->isValid()) {
+ kdWarning() << "YahooFetcher::initXSLTHandler() - error in yahoo2tellico.xsl." << endl;
+ delete m_xsltHandler;
+ m_xsltHandler = 0;
+ return;
+ }
+}
+
+void YahooFetcher::getTracks(Data::EntryPtr entry_) {
+ // get album id
+ if(!entry_ || entry_->field(QString::fromLatin1("yahoo")).isEmpty()) {
+ return;
+ }
+
+ const QString albumid = entry_->field(QString::fromLatin1("yahoo"));
+
+ KURL u(QString::fromLatin1(YAHOO_BASE_URL));
+ u.setFileName(QString::fromLatin1("songSearch"));
+ u.addQueryItem(QString::fromLatin1("appid"), QString::fromLatin1(YAHOO_APP_ID));
+ u.addQueryItem(QString::fromLatin1("type"), QString::fromLatin1("all"));
+ u.addQueryItem(QString::fromLatin1("output"), QString::fromLatin1("xml"));
+ // go ahesad and ask for all results, since there might well be more than 10 songs on the CD
+ u.addQueryItem(QString::fromLatin1("results"), QString::number(50));
+ u.addQueryItem(QString::fromLatin1("albumid"), albumid);
+
+// myDebug() << "YahooFetcher::getTracks() - url: " << u.url() << endl;
+ QDomDocument dom = FileHandler::readXMLFile(u, false /*no namespace*/, true /*quiet*/);
+ if(dom.isNull()) {
+ myDebug() << "YahooFetcher::getTracks() - null dom returned" << endl;
+ return;
+ }
+
+#if 0
+ kdWarning() << "Remove debug from yahoofetcher.cpp" << endl;
+ QFile f(QString::fromLatin1("/tmp/test.xml"));
+ if(f.open(IO_WriteOnly)) {
+ QTextStream t(&f);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << dom.toString();
+ }
+ f.close();
+#endif
+
+ const QString track = QString::fromLatin1("track");
+
+ QDomNodeList nodes = dom.documentElement().childNodes();
+ for(uint i = 0; i < nodes.count(); ++i) {
+ QDomElement e = nodes.item(i).toElement();
+ if(e.isNull()) {
+ continue;
+ }
+ QString t = e.namedItem(QString::fromLatin1("Title")).toElement().text();
+ QString n = e.namedItem(QString::fromLatin1("Track")).toElement().text();
+ bool ok;
+ int trackNum = Tellico::toUInt(n, &ok);
+ // trackNum might be 0
+ if(t.isEmpty() || !ok || trackNum < 1) {
+ continue;
+ }
+ QString a = e.namedItem(QString::fromLatin1("Artist")).toElement().text();
+ QString l = e.namedItem(QString::fromLatin1("Length")).toElement().text();
+
+ int len = Tellico::toUInt(l, &ok);
+ QString value = t + "::" + a;
+ if(ok && len > 0) {
+ value += + "::" + Tellico::minutes(len);
+ }
+ entry_->setField(track, insertValue(entry_->field(track), value, trackNum));
+ }
+}
+
+// not zero-based
+QString YahooFetcher::insertValue(const QString& str_, const QString& value_, uint pos_) {
+ QStringList list = Data::Field::split(str_, true);
+ for(uint i = list.count(); i < pos_; ++i) {
+ list += QString::null;
+ }
+ bool write = true;
+ if(!list[pos_-1].isNull()) {
+ // for some reason, some songs are repeated from yahoo, with 0 length, don't overwrite that
+ if(value_.contains(QString::fromLatin1("::")) < 2) { // means no length value
+ write = false;
+ }
+ }
+ if(!value_.isEmpty() && write) {
+ list[pos_-1] = value_;
+ }
+ return list.join(QString::fromLatin1("; "));
+}
+
+void YahooFetcher::updateEntry(Data::EntryPtr entry_) {
+// myDebug() << "YahooFetcher::updateEntry()" << endl;
+ // limit to top 5 results
+ m_limit = 5;
+
+ QString value;
+ QString title = entry_->field(QString::fromLatin1("title"));
+ if(!title.isEmpty()) {
+ value += QString::fromLatin1("album=") + title;
+ }
+ QString artist = entry_->field(QString::fromLatin1("artist"));
+ if(!artist.isEmpty()) {
+ if(!value.isEmpty()) {
+ value += '&';
+ }
+ value += QString::fromLatin1("artist=") + artist;
+ }
+ if(!value.isEmpty()) {
+ search(Fetch::Raw, value);
+ return;
+ }
+
+ myDebug() << "YahooFetcher::updateEntry() - insufficient info to search" << endl;
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+Tellico::Fetch::ConfigWidget* YahooFetcher::configWidget(QWidget* parent_) const {
+ return new YahooFetcher::ConfigWidget(parent_, this);
+}
+
+YahooFetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const YahooFetcher*/*=0*/)
+ : Fetch::ConfigWidget(parent_) {
+ QVBoxLayout* l = new QVBoxLayout(optionsWidget());
+ l->addWidget(new QLabel(i18n("This source has no options."), optionsWidget()));
+ l->addStretch();
+}
+
+QString YahooFetcher::ConfigWidget::preferredName() const {
+ return YahooFetcher::defaultName();
+}
+
+#include "yahoofetcher.moc"
diff --git a/src/fetch/yahoofetcher.h b/src/fetch/yahoofetcher.h
new file mode 100644
index 0000000..7ff5733
--- /dev/null
+++ b/src/fetch/yahoofetcher.h
@@ -0,0 +1,105 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef YAHOOFETCHER_H
+#define YAHOOFETCHER_H
+
+namespace Tellico {
+ class XSLTHandler;
+}
+
+#include "fetcher.h"
+#include "configwidget.h"
+#include "../datavectors.h"
+
+#include <qcstring.h> // for QByteArray
+#include <qguardedptr.h>
+
+namespace KIO {
+ class Job;
+}
+
+namespace Tellico {
+ namespace Fetch {
+
+/**
+ * @author Robby Stephenson
+ */
+class YahooFetcher : public Fetcher {
+Q_OBJECT
+
+public:
+ /**
+ */
+ YahooFetcher(QObject* parent, const char* name = 0);
+ /**
+ */
+ virtual ~YahooFetcher();
+
+ /**
+ */
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual void search(FetchKey key, const QString& value);
+ virtual void continueSearch();
+ virtual bool canSearch(FetchKey k) const { return k == Title || k == Person; }
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return Yahoo; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+
+ virtual void updateEntry(Data::EntryPtr entry);
+
+ /**
+ * Returns a widget for modifying the fetcher's config.
+ */
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const;
+
+ class ConfigWidget : public Fetch::ConfigWidget {
+ public:
+ ConfigWidget(QWidget* parent_, const YahooFetcher* fetcher = 0);
+ virtual void saveConfig(KConfigGroup&) {}
+ virtual QString preferredName() const;
+ };
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+private slots:
+ void slotData(KIO::Job* job, const QByteArray& data);
+ void slotComplete(KIO::Job* job);
+
+private:
+ void initXSLTHandler();
+ void doSearch();
+ void getTracks(Data::EntryPtr entry);
+ QString insertValue(const QString& str, const QString& value, uint pos);
+
+ XSLTHandler* m_xsltHandler;
+ int m_limit;
+ int m_start;
+ int m_total;
+
+ QByteArray m_data;
+ QMap<int, Data::EntryPtr> m_entries; // they get modified after collection is created, so can't be const
+ QGuardedPtr<KIO::Job> m_job;
+
+ FetchKey m_key;
+ QString m_value;
+ bool m_started;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/fetch/z3950-servers.cfg b/src/fetch/z3950-servers.cfg
new file mode 100644
index 0000000..f4f6157
--- /dev/null
+++ b/src/fetch/z3950-servers.cfg
@@ -0,0 +1,106 @@
+[loc]
+Charset=marc8
+Database=Voyager
+Host=z3950.loc.gov
+Locale=en
+Name=Library of Congress (US)
+Port=7090
+Syntax=mods
+
+[blzcat]
+Host=3950cat.bl.uk
+Port=9909
+Database=BLAC
+Name=The British Library
+Charset=marc-8
+Locale=en_GB
+
+[sudoc]
+Host=carmin.sudoc.abes.fr
+Port=210
+Database=ABES-Z39-PUBLIC
+Name=Sudoc (France)
+Charset=iso-5426
+Locale=fr
+Syntax=usmarc
+
+[bibsys]
+Host=z3950.bibsys.no
+Port=2100
+Database=BIBSYS
+Name=BIBSYS (Norway)
+Charset=iso-8859-1
+Locale=no
+Syntax=usmarc
+
+[sbn]
+Host=opac.sbn.it
+Port=3950
+Database=nopac
+Name=Italian National Library
+Charset=iso-8859-1
+Locale=it
+Syntax=unimarc
+
+[porbase]
+Host=z3950.bn.pt
+Port=210
+Database=bnd
+Name=Portuguese National Library
+Charset=iso-8859-1
+Locale=pt
+Syntax=unimarc
+
+[nlp]
+Host=alpha.bn.org.pl
+Port=210
+Database=INNOPAC
+Name=National Library of Poland
+Charset=iso6937
+Locale=pl
+Syntax=usmarc
+
+[amicus]
+Host=amicus.collectionscanada.ca
+Port=210
+Database=NL
+Name=National Library of Canada
+Charset=iso-8859-1
+Locale=ca
+Syntax=marc21
+
+[iul]
+Host=libnet.ac.il
+Port=9991
+Database=ULI02
+Name=Israel Union List
+Charset=utf-8
+Locale=il
+Syntax=marc21
+
+[naul]
+Host=catalogue.nla.gov.au
+Port=7090
+Database=Voyager
+Name=National Library of Australia
+Charset=utf-8
+Locale=au
+Syntax=marc21
+
+[libis]
+Host=z3950.libis.lt
+Port=210
+Database=knygos
+Name=National Library of Lithuania
+Charset=utf-8
+Syntax=unimarc
+Locale=lt
+
+[copac]
+Host=z3950.copac.ac.uk
+Port=210
+Database=COPAC
+Name=Copac (UK and Ireland)
+Charset=utf-8
+Locale=uk,ie,en
+Syntax=mods
diff --git a/src/fetch/z3950connection.cpp b/src/fetch/z3950connection.cpp
new file mode 100644
index 0000000..27efe51
--- /dev/null
+++ b/src/fetch/z3950connection.cpp
@@ -0,0 +1,503 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : $EMAIL
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "z3950connection.h"
+#include "z3950fetcher.h"
+#include "messagehandler.h"
+#include "../latin1literal.h"
+#include "../tellico_debug.h"
+#include "../iso5426converter.h"
+#include "../iso6937converter.h"
+
+#include <config.h>
+
+#ifdef HAVE_YAZ
+extern "C" {
+#include <yaz/zoom.h>
+#include <yaz/marcdisp.h>
+#include <yaz/yaz-version.h>
+}
+#endif
+
+#include <klocale.h>
+
+#include <qfile.h>
+
+namespace {
+ static const size_t Z3950_DEFAULT_MAX_RECORDS = 20;
+}
+
+using Tellico::Fetch::Z3950ResultFound;
+using Tellico::Fetch::Z3950Connection;
+
+Z3950ResultFound::Z3950ResultFound(const QString& s) : QCustomEvent(uid())
+ , m_result(QDeepCopy<QString>(s)) {
+ ++Z3950Connection::resultsLeft;
+}
+
+Z3950ResultFound::~Z3950ResultFound() {
+ --Z3950Connection::resultsLeft;
+}
+
+class Z3950Connection::Private {
+public:
+ Private() {}
+#ifdef HAVE_YAZ
+ ~Private() {
+ ZOOM_options_destroy(conn_opt);
+ ZOOM_connection_destroy(conn);
+ };
+
+ ZOOM_options conn_opt;
+ ZOOM_connection conn;
+#endif
+};
+
+int Z3950Connection::resultsLeft = 0;
+
+// since the character set goes into a yaz api call
+// I'm paranoid about user insertions, so just grab 64
+// characters at most
+Z3950Connection::Z3950Connection(Z3950Fetcher* fetcher,
+ const QString& host,
+ uint port,
+ const QString& dbname,
+ const QString& sourceCharSet,
+ const QString& syntax,
+ const QString& esn)
+ : QThread()
+ , d(new Private())
+ , m_connected(false)
+ , m_aborted(false)
+ , m_fetcher(fetcher)
+ , m_host(QDeepCopy<QString>(host))
+ , m_port(port)
+ , m_dbname(QDeepCopy<QString>(dbname))
+ , m_sourceCharSet(QDeepCopy<QString>(sourceCharSet.left(64)))
+ , m_syntax(QDeepCopy<QString>(syntax))
+ , m_esn(QDeepCopy<QString>(esn))
+ , m_start(0)
+ , m_limit(Z3950_DEFAULT_MAX_RECORDS)
+ , m_hasMore(false) {
+}
+
+Z3950Connection::~Z3950Connection() {
+ m_connected = false;
+ delete d;
+ d = 0;
+}
+
+void Z3950Connection::reset() {
+ m_start = 0;
+ m_limit = Z3950_DEFAULT_MAX_RECORDS;
+}
+
+void Z3950Connection::setQuery(const QString& query_) {
+ m_pqn = QDeepCopy<QString>(query_);
+}
+
+void Z3950Connection::setUserPassword(const QString& user_, const QString& pword_) {
+ m_user = QDeepCopy<QString>(user_);
+ m_password = QDeepCopy<QString>(pword_);
+}
+
+void Z3950Connection::run() {
+// myDebug() << "Z3950Connection::run() - " << m_fetcher->source() << endl;
+ m_aborted = false;
+ m_hasMore = false;
+ resultsLeft = 0;
+#ifdef HAVE_YAZ
+
+ if(!makeConnection()) {
+ done();
+ return;
+ }
+
+ ZOOM_query query = ZOOM_query_create();
+ myLog() << "Z3950Connection::run() - pqn = " << toCString(m_pqn) << endl;
+ int errcode = ZOOM_query_prefix(query, toCString(m_pqn));
+ if(errcode != 0) {
+ myDebug() << "Z3950Connection::run() - query error: " << m_pqn << endl;
+ ZOOM_query_destroy(query);
+ QString s = i18n("Query error!");
+ s += ' ' + m_pqn;
+ done(s, MessageHandler::Error);
+ return;
+ }
+
+ ZOOM_resultset resultSet = ZOOM_connection_search(d->conn, query);
+
+ // check abort status
+ if(m_aborted) {
+ done();
+ return;
+ }
+
+ // I know the LOC wants the syntax = "xml" and esn = "mods"
+ // to get MODS data, that seems a bit odd...
+ // esn only makes sense for marc and grs-1
+ // if syntax is mods, set esn to mods too
+ QCString type = "raw";
+ if(m_syntax == Latin1Literal("mods")) {
+ m_syntax = QString::fromLatin1("xml");
+ ZOOM_resultset_option_set(resultSet, "elementSetName", "mods");
+ type = "xml";
+ } else {
+ ZOOM_resultset_option_set(resultSet, "elementSetName", m_esn.latin1());
+ }
+ ZOOM_resultset_option_set(resultSet, "start", QCString().setNum(m_start));
+ ZOOM_resultset_option_set(resultSet, "count", QCString().setNum(m_limit-m_start));
+ // search in default syntax, unless syntax is already set
+ if(!m_syntax.isEmpty()) {
+ ZOOM_resultset_option_set(resultSet, "preferredRecordSyntax", m_syntax.latin1());
+ }
+
+ const char* errmsg;
+ const char* addinfo;
+ errcode = ZOOM_connection_error(d->conn, &errmsg, &addinfo);
+ if(errcode != 0) {
+ ZOOM_resultset_destroy(resultSet);
+ ZOOM_query_destroy(query);
+ m_connected = false;
+
+ QString s = i18n("Connection search error %1: %2").arg(errcode).arg(toString(errmsg));
+ if(!QCString(addinfo).isEmpty()) {
+ s += " (" + toString(addinfo) + ")";
+ }
+ myDebug() << "Z3950Connection::run() - " << s << endl;
+ done(s, MessageHandler::Error);
+ return;
+ }
+
+ const size_t numResults = ZOOM_resultset_size(resultSet);
+
+ QString newSyntax = m_syntax;
+ if(numResults > 0) {
+ myLog() << "Z3950Connection::run() - current syntax is " << m_syntax << " (" << numResults << " results)" << endl;
+ // so now we know that results exist, might have to check syntax
+ int len;
+ ZOOM_record rec = ZOOM_resultset_record(resultSet, 0);
+ // want raw unless it's mods
+ ZOOM_record_get(rec, type, &len);
+ if(len > 0 && m_syntax.isEmpty()) {
+ newSyntax = QString::fromLatin1(ZOOM_record_get(rec, "syntax", &len)).lower();
+ myLog() << "Z3950Connection::run() - syntax guess is " << newSyntax << endl;
+ if(newSyntax == Latin1Literal("mods") || newSyntax == Latin1Literal("xml")) {
+ m_syntax = QString::fromLatin1("xml");
+ ZOOM_resultset_option_set(resultSet, "elementSetName", "mods");
+ } else if(newSyntax == Latin1Literal("grs-1")) {
+ // if it's defaulting to grs-1, go ahead and change it to try to get a marc
+ // record since grs-1 is a last resort for us
+ newSyntax.truncate(0);
+ }
+ }
+ // right now, we just understand mods, unimarc, marc21/usmarc, and grs-1
+ if(newSyntax != Latin1Literal("xml") &&
+ newSyntax != Latin1Literal("usmarc") &&
+ newSyntax != Latin1Literal("marc21") &&
+ newSyntax != Latin1Literal("unimarc") &&
+ newSyntax != Latin1Literal("grs-1")) {
+ myLog() << "Z3950Connection::run() - changing z39.50 syntax to MODS" << endl;
+ newSyntax = QString::fromLatin1("xml");
+ ZOOM_resultset_option_set(resultSet, "elementSetName", "mods");
+ ZOOM_resultset_option_set(resultSet, "preferredRecordSyntax", newSyntax.latin1());
+ rec = ZOOM_resultset_record(resultSet, 0);
+ ZOOM_record_get(rec, "xml", &len);
+ if(len == 0) {
+ // change set name back
+ ZOOM_resultset_option_set(resultSet, "elementSetName", m_esn.latin1());
+ newSyntax = QString::fromLatin1("usmarc"); // try usmarc
+ myLog() << "Z3950Connection::run() - changing z39.50 syntax to USMARC" << endl;
+ ZOOM_resultset_option_set(resultSet, "preferredRecordSyntax", newSyntax.latin1());
+ rec = ZOOM_resultset_record(resultSet, 0);
+ ZOOM_record_get(rec, "raw", &len);
+ }
+ if(len == 0) {
+ newSyntax = QString::fromLatin1("marc21"); // try marc21
+ myLog() << "Z3950Connection::run() - changing z39.50 syntax to MARC21" << endl;
+ ZOOM_resultset_option_set(resultSet, "preferredRecordSyntax", newSyntax.latin1());
+ rec = ZOOM_resultset_record(resultSet, 0);
+ ZOOM_record_get(rec, "raw", &len);
+ }
+ if(len == 0) {
+ newSyntax = QString::fromLatin1("unimarc"); // try unimarc
+ myLog() << "Z3950Connection::run() - changing z39.50 syntax to UNIMARC" << endl;
+ ZOOM_resultset_option_set(resultSet, "preferredRecordSyntax", newSyntax.latin1());
+ rec = ZOOM_resultset_record(resultSet, 0);
+ ZOOM_record_get(rec, "raw", &len);
+ }
+ if(len == 0) {
+ newSyntax = QString::fromLatin1("grs-1"); // try grs-1
+ myLog() << "Z3950Connection::run() - changing z39.50 syntax to GRS-1" << endl;
+ ZOOM_resultset_option_set(resultSet, "preferredRecordSyntax", newSyntax.latin1());
+ rec = ZOOM_resultset_record(resultSet, 0);
+ ZOOM_record_get(rec, "raw", &len);
+ }
+ if(len == 0) {
+ myLog() << "Z3950Connection::run() - giving up" << endl;
+ ZOOM_resultset_destroy(resultSet);
+ ZOOM_query_destroy(query);
+ done(i18n("Record syntax error"), MessageHandler::Error);
+ return;
+ }
+ myLog() << "Z3950Connection::run() - final syntax is " << newSyntax << endl;
+ }
+ }
+
+ // go back to fooling ourselves and calling it mods
+ if(m_syntax == Latin1Literal("xml")) {
+ m_syntax = QString::fromLatin1("mods");
+ }
+ if(newSyntax == Latin1Literal("xml")) {
+ newSyntax = QString::fromLatin1("mods");
+ }
+ // save syntax change for next time
+ if(m_syntax != newSyntax) {
+ kapp->postEvent(m_fetcher, new Z3950SyntaxChange(newSyntax));
+ m_syntax = newSyntax;
+ }
+
+ if(m_sourceCharSet.isEmpty()) {
+ m_sourceCharSet = QString::fromLatin1("marc-8");
+ }
+
+ const size_t realLimit = QMIN(numResults, m_limit);
+
+ for(size_t i = m_start; i < realLimit && !m_aborted; ++i) {
+ myLog() << "Z3950Connection::run() - grabbing index " << i << endl;
+ ZOOM_record rec = ZOOM_resultset_record(resultSet, i);
+ if(!rec) {
+ myDebug() << "Z3950Connection::run() - no record returned for index " << i << endl;
+ continue;
+ }
+ int len;
+ QString data;
+ if(m_syntax == Latin1Literal("mods")) {
+ data = toString(ZOOM_record_get(rec, "xml", &len));
+ } else if(m_syntax == Latin1Literal("grs-1")) { // grs-1
+ // we're going to parse the rendered data, very ugly...
+ data = toString(ZOOM_record_get(rec, "render", &len));
+ } else {
+#if 0
+ kdWarning() << "Remove debug from z3950connection.cpp" << endl;
+ {
+ QFile f1(QString::fromLatin1("/tmp/z3950.raw"));
+ if(f1.open(IO_WriteOnly)) {
+ QDataStream t(&f1);
+ t << ZOOM_record_get(rec, "raw", &len);
+ }
+ f1.close();
+ }
+#endif
+ data = toXML(ZOOM_record_get(rec, "raw", &len), m_sourceCharSet);
+ }
+ Z3950ResultFound* ev = new Z3950ResultFound(data);
+ QApplication::postEvent(m_fetcher, ev);
+ }
+
+ ZOOM_resultset_destroy(resultSet);
+ ZOOM_query_destroy(query);
+
+ m_hasMore = m_limit < numResults;
+ if(m_hasMore) {
+ m_start = m_limit;
+ m_limit += Z3950_DEFAULT_MAX_RECORDS;
+ }
+#endif
+ done();
+}
+
+bool Z3950Connection::makeConnection() {
+ if(m_connected) {
+ return true;
+ }
+// myDebug() << "Z3950Connection::makeConnection() - " << m_fetcher->source() << endl;
+// I don't know what to do except assume database, user, and password are in locale encoding
+#ifdef HAVE_YAZ
+ d->conn_opt = ZOOM_options_create();
+ ZOOM_options_set(d->conn_opt, "implementationName", "Tellico");
+ ZOOM_options_set(d->conn_opt, "databaseName", toCString(m_dbname));
+ ZOOM_options_set(d->conn_opt, "user", toCString(m_user));
+ ZOOM_options_set(d->conn_opt, "password", toCString(m_password));
+
+ d->conn = ZOOM_connection_create(d->conn_opt);
+ ZOOM_connection_connect(d->conn, m_host.latin1(), m_port);
+
+ int errcode;
+ const char* errmsg; // unused: carries same info as 'errcode'
+ const char* addinfo;
+ errcode = ZOOM_connection_error(d->conn, &errmsg, &addinfo);
+ if(errcode != 0) {
+ ZOOM_options_destroy(d->conn_opt);
+ ZOOM_connection_destroy(d->conn);
+ m_connected = false;
+
+ QString s = i18n("Connection error %1: %2").arg(errcode).arg(toString(errmsg));
+ if(!QCString(addinfo).isEmpty()) {
+ s += " (" + toString(addinfo) + ")";
+ }
+ myDebug() << "Z3950Connection::makeConnection() - " << s << endl;
+ done(s, MessageHandler::Error);
+ return false;
+ }
+#endif
+ m_connected = true;
+ return true;
+}
+
+void Z3950Connection::done() {
+ checkPendingEvents();
+ kapp->postEvent(m_fetcher, new Z3950ConnectionDone(m_hasMore));
+}
+
+void Z3950Connection::done(const QString& msg_, int type_) {
+ checkPendingEvents();
+ if(m_aborted) {
+ kapp->postEvent(m_fetcher, new Z3950ConnectionDone(m_hasMore));
+ } else {
+ kapp->postEvent(m_fetcher, new Z3950ConnectionDone(m_hasMore, msg_, type_));
+ }
+}
+
+void Z3950Connection::checkPendingEvents() {
+ // if there's still some pending result events, go ahead and just wait 1 second
+ if(resultsLeft > 0) {
+ sleep(1);
+ }
+}
+
+inline
+QCString Z3950Connection::toCString(const QString& text_) {
+ return iconvRun(text_.utf8(), QString::fromLatin1("utf-8"), m_sourceCharSet);
+}
+
+inline
+QString Z3950Connection::toString(const QCString& text_) {
+ return QString::fromUtf8(iconvRun(text_, m_sourceCharSet, QString::fromLatin1("utf-8")));
+}
+
+// static
+QCString Z3950Connection::iconvRun(const QCString& text_, const QString& fromCharSet_, const QString& toCharSet_) {
+#ifdef HAVE_YAZ
+ if(text_.isEmpty()) {
+ return text_;
+ }
+
+ if(fromCharSet_ == toCharSet_) {
+ return text_;
+ }
+
+ yaz_iconv_t cd = yaz_iconv_open(toCharSet_.latin1(), fromCharSet_.latin1());
+ if(!cd) {
+ // maybe it's iso 5426, which we sorta support
+ QString charSetLower = fromCharSet_.lower();
+ charSetLower.remove('-').remove(' ');
+ if(charSetLower == Latin1Literal("iso5426")) {
+ return iconvRun(Iso5426Converter::toUtf8(text_).utf8(), QString::fromLatin1("utf-8"), toCharSet_);
+ } else if(charSetLower == Latin1Literal("iso6937")) {
+ return iconvRun(Iso6937Converter::toUtf8(text_).utf8(), QString::fromLatin1("utf-8"), toCharSet_);
+ }
+ kdWarning() << "Z3950Connection::iconvRun() - conversion from " << fromCharSet_
+ << " to " << toCharSet_ << " is unsupported" << endl;
+ return text_;
+ }
+
+ const char* input = text_;
+ size_t inlen = text_.length();
+
+ size_t outlen = 2 * inlen; // this is enough, right?
+ QMemArray<char> result0(outlen);
+ char* result = result0.data();
+
+ int r = yaz_iconv(cd, const_cast<char**>(&input), &inlen, &result, &outlen);
+ if(r <= 0) {
+ myDebug() << "Z3950Connection::iconvRun() - can't decode buffer" << endl;
+ return text_;
+ }
+ // bug in yaz, need to flush buffer to catch last character
+ yaz_iconv(cd, 0, 0, &result, &outlen);
+
+ // length is pointer difference
+ size_t len = result - result0;
+
+ QCString output = QCString(result0, len+1);
+// myDebug() << "-------------------------------------------" << endl;
+// myDebug() << output << endl;
+// myDebug() << "-------------------------------------------" << endl;
+ yaz_iconv_close(cd);
+ return output;
+#endif
+ return text_;
+}
+
+QString Z3950Connection::toXML(const QCString& marc_, const QString& charSet_) {
+#ifdef HAVE_YAZ
+ if(marc_.isEmpty()) {
+ myDebug() << "Z3950Connection::toXML() - empty string" << endl;
+ return QString::null;
+ }
+
+ yaz_iconv_t cd = yaz_iconv_open("utf-8", charSet_.latin1());
+ if(!cd) {
+ // maybe it's iso 5426, which we sorta support
+ QString charSetLower = charSet_.lower();
+ charSetLower.remove('-').remove(' ');
+ if(charSetLower == Latin1Literal("iso5426")) {
+ return toXML(Iso5426Converter::toUtf8(marc_).utf8(), QString::fromLatin1("utf-8"));
+ } else if(charSetLower == Latin1Literal("iso6937")) {
+ return toXML(Iso6937Converter::toUtf8(marc_).utf8(), QString::fromLatin1("utf-8"));
+ }
+ kdWarning() << "Z3950Connection::toXML() - conversion from " << charSet_ << " is unsupported" << endl;
+ return QString::null;
+ }
+
+ yaz_marc_t mt = yaz_marc_create();
+ yaz_marc_iconv(mt, cd);
+ yaz_marc_xml(mt, YAZ_MARC_MARCXML);
+
+ // first 5 bytes are length
+ bool ok;
+#if YAZ_VERSIONL < 0x030000
+ int len = marc_.left(5).toInt(&ok);
+#else
+ size_t len = marc_.left(5).toInt(&ok);
+#endif
+ if(ok && (len < 25 || len > 100000)) {
+ myDebug() << "Z3950Connection::toXML() - bad length: " << (ok ? len : -1) << endl;
+ return QString::null;
+ }
+
+#if YAZ_VERSIONL < 0x030000
+ char* result;
+#else
+ const char* result;
+#endif
+ int r = yaz_marc_decode_buf(mt, marc_, -1, &result, &len);
+ if(r <= 0) {
+ myDebug() << "Z3950Connection::toXML() - can't decode buffer" << endl;
+ return QString::null;
+ }
+
+ QString output = QString::fromLatin1("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ output += QString::fromUtf8(QCString(result, len+1), len+1);
+// myDebug() << QCString(result) << endl;
+// myDebug() << "-------------------------------------------" << endl;
+// myDebug() << output << endl;
+ yaz_iconv_close(cd);
+ yaz_marc_destroy(mt);
+
+ return output;
+#else // no yaz
+ return QString::null;
+#endif
+}
diff --git a/src/fetch/z3950connection.h b/src/fetch/z3950connection.h
new file mode 100644
index 0000000..0929cb7
--- /dev/null
+++ b/src/fetch/z3950connection.h
@@ -0,0 +1,126 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FETCH_Z3950CONNECTION_H
+#define TELLICO_FETCH_Z3950CONNECTION_H
+
+#include <qthread.h>
+#include <qevent.h>
+#include <qdeepcopy.h>
+
+#include <ksharedptr.h>
+
+namespace Tellico {
+ namespace Fetch {
+ class Z3950Fetcher;
+
+class Z3950ResultFound : public QCustomEvent {
+public:
+ Z3950ResultFound(const QString& s);
+ ~Z3950ResultFound();
+ const QString& result() const { return m_result; }
+
+ static int uid() { return User + 11111; }
+
+private:
+ QString m_result;
+};
+
+class Z3950ConnectionDone : public QCustomEvent {
+public:
+ Z3950ConnectionDone(bool more) : QCustomEvent(uid()), m_type(-1), m_hasMore(more) {}
+ Z3950ConnectionDone(bool more, const QString& s, int t) : QCustomEvent(uid()), m_msg(QDeepCopy<QString>(s)), m_type(t), m_hasMore(more) {}
+
+ const QString& message() const { return m_msg; }
+ int messageType() const { return m_type; }
+ bool hasMoreResults() const { return m_hasMore; }
+
+ static int uid() { return User + 22222; }
+
+private:
+ QString m_msg;
+ int m_type;
+ bool m_hasMore;
+};
+
+class Z3950SyntaxChange : public QCustomEvent {
+public:
+ Z3950SyntaxChange(const QString& s) : QCustomEvent(uid()), m_syntax(QDeepCopy<QString>(s)) {}
+ const QString& syntax() const { return m_syntax; }
+
+ static int uid() { return User + 33333; }
+
+private:
+ QString m_syntax;
+};
+
+/**
+ * @author Robby Stephenson
+ */
+class Z3950Connection : public QThread {
+public:
+ Z3950Connection(Z3950Fetcher* fetcher,
+ const QString& host,
+ uint port,
+ const QString& dbname,
+ const QString& sourceCharSet,
+ const QString& syntax,
+ const QString& esn);
+ ~Z3950Connection();
+
+ void reset();
+ void setQuery(const QString& query);
+ void setUserPassword(const QString& user, const QString& pword);
+ void run();
+
+ void abort() { m_aborted = true; }
+
+private:
+ static QCString iconvRun(const QCString& text, const QString& fromCharSet, const QString& toCharSet);
+ static QString toXML(const QCString& marc, const QString& fromCharSet);
+
+ bool makeConnection();
+ void done();
+ void done(const QString& message, int type);
+ QCString toCString(const QString& text);
+ QString toString(const QCString& text);
+ void checkPendingEvents();
+
+ class Private;
+ Private* d;
+
+ bool m_connected;
+ bool m_aborted;
+
+ KSharedPtr<Z3950Fetcher> m_fetcher;
+ QString m_host;
+ uint m_port;
+ QString m_dbname;
+ QString m_user;
+ QString m_password;
+ QString m_sourceCharSet;
+ QString m_syntax;
+ QString m_pqn;
+ QString m_esn;
+ size_t m_start;
+ size_t m_limit;
+ bool m_hasMore;
+
+ friend class Z3950ResultFound;
+ static int resultsLeft;
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/fetch/z3950fetcher.cpp b/src/fetch/z3950fetcher.cpp
new file mode 100644
index 0000000..5e045cf
--- /dev/null
+++ b/src/fetch/z3950fetcher.cpp
@@ -0,0 +1,782 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ * In addition, as a special exception, the author gives permission to *
+ * link the code of this program with the OpenSSL library released by *
+ * the OpenSSL Project (or with modified versions of OpenSSL that use *
+ * the same license as OpenSSL), and distribute linked combinations *
+ * including the two. You must obey the GNU General Public License in *
+ * all respects for all of the code used other than OpenSSL. If you *
+ * modify this file, you may extend this exception to your version of *
+ * the file, but you are not obligated to do so. If you do not wish to *
+ * do so, delete this exception statement from your version. *
+ * *
+ ***************************************************************************/
+
+#include <config.h>
+
+#include "z3950fetcher.h"
+#include "z3950connection.h"
+#include "messagehandler.h"
+#include "../collection.h"
+#include "../latin1literal.h"
+#include "../translators/xslthandler.h"
+#include "../translators/tellicoimporter.h"
+#include "../translators/grs1importer.h"
+#include "../tellico_debug.h"
+#include "../gui/lineedit.h"
+#include "../gui/combobox.h"
+#include "../isbnvalidator.h"
+#include "../lccnvalidator.h"
+
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kapplication.h>
+#include <knuminput.h>
+#include <kconfig.h>
+#include <kcombobox.h>
+#include <kaccelmanager.h>
+#include <kseparator.h>
+
+#include <qfile.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qwhatsthis.h>
+#include <qdom.h>
+
+namespace {
+ static const int Z3950_DEFAULT_PORT = 210;
+ static const QString Z3950_DEFAULT_ESN = QString::fromLatin1("F");
+}
+
+using Tellico::Fetch::Z3950Fetcher;
+
+Z3950Fetcher::Z3950Fetcher(QObject* parent_, const char* name_)
+ : Fetcher(parent_, name_), m_conn(0), m_port(Z3950_DEFAULT_PORT), m_esn(Z3950_DEFAULT_ESN),
+ m_started(false), m_done(true), m_MARC21XMLHandler(0),
+ m_UNIMARCXMLHandler(0), m_MODSHandler(0) {
+}
+
+Z3950Fetcher::~Z3950Fetcher() {
+ delete m_MARC21XMLHandler;
+ m_MARC21XMLHandler = 0;
+ delete m_UNIMARCXMLHandler;
+ m_UNIMARCXMLHandler = 0;
+ delete m_MODSHandler;
+ m_MODSHandler = 0;
+ delete m_conn;
+ m_conn = 0;
+}
+
+QString Z3950Fetcher::defaultName() {
+ return i18n("z39.50 Server");
+}
+
+QString Z3950Fetcher::source() const {
+ return m_name.isEmpty() ? defaultName() : m_name;
+}
+
+bool Z3950Fetcher::canFetch(int type) const {
+ return type == Data::Collection::Book || type == Data::Collection::Bibtex;
+}
+
+void Z3950Fetcher::readConfigHook(const KConfigGroup& config_) {
+ QString preset = config_.readEntry("Preset");
+ if(preset.isEmpty()) {
+ m_host = config_.readEntry("Host");
+ int p = config_.readNumEntry("Port", Z3950_DEFAULT_PORT);
+ if(p > 0) {
+ m_port = p;
+ }
+ m_dbname = config_.readEntry("Database");
+ m_sourceCharSet = config_.readEntry("Charset");
+ m_syntax = config_.readEntry("Syntax");
+ m_user = config_.readEntry("User");
+ m_password = config_.readEntry("Password");
+ } else {
+ m_preset = preset;
+ QString serverFile = locate("appdata", QString::fromLatin1("z3950-servers.cfg"));
+ if(!serverFile.isEmpty()) {
+ KConfig cfg(serverFile, true /* read-only */, false /* read KDE */);
+ const QStringList servers = cfg.groupList();
+ for(QStringList::ConstIterator server = servers.begin(); server != servers.end(); ++server) {
+ cfg.setGroup(*server);
+
+ const QString id = *server;
+ if(id == preset) {
+ const QString name = cfg.readEntry("Name");
+ m_host = cfg.readEntry("Host");
+ m_port = cfg.readNumEntry("Port", Z3950_DEFAULT_PORT);
+ m_dbname = cfg.readEntry("Database");
+ m_sourceCharSet = cfg.readEntry("Charset");
+ m_syntax = cfg.readEntry("Syntax");
+ m_user = cfg.readEntry("User");
+ m_password = cfg.readEntry("Password");
+ }
+ }
+ }
+ }
+
+ m_fields = config_.readListEntry("Custom Fields");
+}
+
+void Z3950Fetcher::saveConfigHook(KConfigGroup& config_) {
+ config_.writeEntry("Syntax", m_syntax);
+ config_.sync();
+}
+
+void Z3950Fetcher::search(FetchKey key_, const QString& value_) {
+#ifdef HAVE_YAZ
+ m_started = true;
+ m_done = false;
+ if(m_host.isEmpty() || m_dbname.isEmpty()) {
+ myDebug() << "Z3950Fetcher::search() - settings are not set!" << endl;
+ stop();
+ return;
+ }
+ m_key = key_;
+ m_value = value_;
+ m_started = true;
+
+ QString svalue = m_value;
+ QRegExp rx1(QString::fromLatin1("['\"].*\\1"));
+ if(!rx1.exactMatch(svalue)) {
+ svalue.prepend('"').append('"');
+ }
+
+ switch(key_) {
+ case Title:
+ m_pqn = QString::fromLatin1("@attr 1=4 ") + svalue;
+ break;
+ case Person:
+// m_pqn = QString::fromLatin1("@or ");
+// m_pqn += QString::fromLatin1("@attr 1=1 \"") + m_value + '"';
+ m_pqn = QString::fromLatin1(" @attr 1=1003 ") + svalue;
+ break;
+ case ISBN:
+ {
+ m_pqn.truncate(0);
+ QString s = m_value;
+ s.remove('-');
+ QStringList isbnList = QStringList::split(QString::fromLatin1("; "), s);
+ // also going to search for isbn10 values
+ for(QStringList::Iterator it = isbnList.begin(); it != isbnList.end(); ++it) {
+ if((*it).startsWith(QString::fromLatin1("978"))) {
+ QString isbn10 = ISBNValidator::isbn10(*it);
+ isbn10.remove('-');
+ isbnList.insert(it, isbn10);
+ }
+ }
+ const int count = isbnList.count();
+ if(count > 1) {
+ m_pqn = QString::fromLatin1("@or ");
+ }
+ for(int i = 0; i < count; ++i) {
+ m_pqn += QString::fromLatin1(" @attr 1=7 ") + isbnList[i];
+ if(i < count-2) {
+ m_pqn += QString::fromLatin1(" @or");
+ }
+ }
+ }
+ break;
+ case LCCN:
+ {
+ m_pqn.truncate(0);
+ QString s = m_value;
+ s.remove('-');
+ QStringList lccnList = QStringList::split(QString::fromLatin1("; "), s);
+ while(!lccnList.isEmpty()) {
+ m_pqn += QString::fromLatin1(" @or @attr 1=9 ") + lccnList.front();
+ if(lccnList.count() > 1) {
+ m_pqn += QString::fromLatin1(" @or");
+ }
+ m_pqn += QString::fromLatin1(" @attr 1=9 ") + LCCNValidator::formalize(lccnList.front());
+ lccnList.pop_front();
+ }
+ }
+ break;
+ case Keyword:
+ m_pqn = QString::fromLatin1("@attr 1=1016 ") + svalue;
+ break;
+ case Raw:
+ m_pqn = m_value;
+ break;
+ default:
+ kdWarning() << "Z3950Fetcher::search() - key not recognized: " << key_ << endl;
+ stop();
+ return;
+ }
+// m_pqn = QString::fromLatin1("@attr 1=7 0253333490");
+ myLog() << "Z3950Fetcher::search() - PQN query = " << m_pqn << endl;
+
+ if(m_conn) {
+ m_conn->reset(); // reset counts
+ }
+
+ process();
+#else // HAVE_YAZ
+ Q_UNUSED(key_);
+ Q_UNUSED(value_);
+ stop();
+ return;
+#endif
+}
+
+void Z3950Fetcher::continueSearch() {
+#ifdef HAVE_YAZ
+ m_started = true;
+ process();
+#endif
+}
+
+void Z3950Fetcher::stop() {
+ if(!m_started) {
+ return;
+ }
+// myDebug() << "Z3950Fetcher::stop()" << endl;
+ m_started = false;
+ if(m_conn) {
+ // give it a second to cleanup
+ m_conn->abort();
+ m_conn->wait(1000);
+ }
+ emit signalDone(this);
+}
+
+bool Z3950Fetcher::initMARC21Handler() {
+ if(m_MARC21XMLHandler) {
+ return true;
+ }
+
+ QString xsltfile = locate("appdata", QString::fromLatin1("MARC21slim2MODS3.xsl"));
+ if(xsltfile.isEmpty()) {
+ kdWarning() << "Z3950Fetcher::initHandlers() - can not locate MARC21slim2MODS3.xsl." << endl;
+ return false;
+ }
+
+ KURL u;
+ u.setPath(xsltfile);
+
+ m_MARC21XMLHandler = new XSLTHandler(u);
+ if(!m_MARC21XMLHandler->isValid()) {
+ kdWarning() << "Z3950Fetcher::initHandlers() - error in MARC21slim2MODS3.xsl." << endl;
+ delete m_MARC21XMLHandler;
+ m_MARC21XMLHandler = 0;
+ return false;
+ }
+ return true;
+}
+
+bool Z3950Fetcher::initUNIMARCHandler() {
+ if(m_UNIMARCXMLHandler) {
+ return true;
+ }
+
+ QString xsltfile = locate("appdata", QString::fromLatin1("UNIMARC2MODS3.xsl"));
+ if(xsltfile.isEmpty()) {
+ kdWarning() << "Z3950Fetcher::initHandlers() - can not locate UNIMARC2MODS3.xsl." << endl;
+ return false;
+ }
+
+ KURL u;
+ u.setPath(xsltfile);
+
+ m_UNIMARCXMLHandler = new XSLTHandler(u);
+ if(!m_UNIMARCXMLHandler->isValid()) {
+ kdWarning() << "Z3950Fetcher::initHandlers() - error in UNIMARC2MODS3.xsl." << endl;
+ delete m_UNIMARCXMLHandler;
+ m_UNIMARCXMLHandler = 0;
+ return false;
+ }
+ return true;
+}
+
+bool Z3950Fetcher::initMODSHandler() {
+ if(m_MODSHandler) {
+ return true;
+ }
+
+ QString xsltfile = locate("appdata", QString::fromLatin1("mods2tellico.xsl"));
+ if(xsltfile.isEmpty()) {
+ kdWarning() << "Z3950Fetcher::initHandlers() - can not locate mods2tellico.xsl." << endl;
+ return false;
+ }
+
+ KURL u;
+ u.setPath(xsltfile);
+
+ m_MODSHandler = new XSLTHandler(u);
+ if(!m_MODSHandler->isValid()) {
+ kdWarning() << "Z3950Fetcher::initHandlers() - error in mods2tellico.xsl." << endl;
+ delete m_MODSHandler;
+ m_MODSHandler = 0;
+ // no use in keeping the MARC handlers now
+ delete m_MARC21XMLHandler;
+ m_MARC21XMLHandler = 0;
+ delete m_UNIMARCXMLHandler;
+ m_UNIMARCXMLHandler = 0;
+ return false;
+ }
+ return true;
+}
+
+void Z3950Fetcher::process() {
+ if(m_conn) {
+ m_conn->wait();
+ } else {
+ m_conn = new Z3950Connection(this, m_host, m_port, m_dbname, m_sourceCharSet, m_syntax, m_esn);
+ if(!m_user.isEmpty()) {
+ m_conn->setUserPassword(m_user, m_password);
+ }
+ }
+
+ m_conn->setQuery(m_pqn);
+ m_conn->start();
+}
+
+void Z3950Fetcher::handleResult(const QString& result_) {
+ if(result_.isEmpty()) {
+ myDebug() << "Z3950Fetcher::handleResult() - empty record found, maybe the character encoding or record format is wrong?" << endl;
+ return;
+ }
+
+#if 0
+ kdWarning() << "Remove debug from z3950fetcher.cpp" << endl;
+ {
+ QFile f1(QString::fromLatin1("/tmp/marc.xml"));
+ if(f1.open(IO_WriteOnly)) {
+// if(f1.open(IO_WriteOnly | IO_Append)) {
+ QTextStream t(&f1);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << result_;
+ }
+ f1.close();
+ }
+#endif
+ // assume always utf-8
+ QString str, msg;
+ Data::CollPtr coll = 0;
+ // not marc, has to be grs-1
+ if(m_syntax == Latin1Literal("grs-1")) {
+ Import::GRS1Importer imp(result_);
+ coll = imp.collection();
+ msg = imp.statusMessage();
+ } else { // now the MODS stuff
+ if(m_syntax == Latin1Literal("mods")) {
+ str = result_;
+ } else if(m_syntax == Latin1Literal("unimarc") && initUNIMARCHandler()) {
+ str = m_UNIMARCXMLHandler->applyStylesheet(result_);
+ } else if(initMARC21Handler()) { // got to be usmarc/marc21
+ str = m_MARC21XMLHandler->applyStylesheet(result_);
+ }
+ if(str.isEmpty() || !initMODSHandler()) {
+ myDebug() << "Z3950Fetcher::handleResult() - empty string or can't init" << endl;
+ stop();
+ return;
+ }
+#if 0
+ kdWarning() << "Remove debug from z3950fetcher.cpp" << endl;
+ {
+ QFile f2(QString::fromLatin1("/tmp/mods.xml"));
+// if(f2.open(IO_WriteOnly)) {
+ if(f2.open(IO_WriteOnly | IO_Append)) {
+ QTextStream t(&f2);
+ t.setEncoding(QTextStream::UnicodeUTF8);
+ t << str;
+ }
+ f2.close();
+ }
+#endif
+ Import::TellicoImporter imp(m_MODSHandler->applyStylesheet(str));
+ imp.setOptions(imp.options() & ~Import::ImportProgress); // no progress needed
+ coll = imp.collection();
+ msg = imp.statusMessage();
+ }
+
+ if(!coll) {
+ if(!msg.isEmpty()) {
+ message(msg, MessageHandler::Warning);
+ }
+ myDebug() << "Z3950Fetcher::handleResult() - no collection pointer: " << msg << endl;
+ return;
+ }
+
+ if(coll->entryCount() == 0) {
+// myDebug() << "Z3950Fetcher::handleResult() - no Tellico entry in result" << endl;
+ return;
+ }
+
+ const StringMap customFields = Z3950Fetcher::customFields();
+ for(StringMap::ConstIterator it = customFields.begin(); it != customFields.end(); ++it) {
+ if(!m_fields.contains(it.key())) {
+ coll->removeField(it.key());
+ }
+ }
+
+ Data::EntryVec entries = coll->entries();
+ for(Data::EntryVec::Iterator entry = entries.begin(); entry != entries.end(); ++entry) {
+ QString desc = entry->field(QString::fromLatin1("author")) + '/'
+ + entry->field(QString::fromLatin1("publisher"));
+ if(!entry->field(QString::fromLatin1("cr_year")).isEmpty()) {
+ desc += QChar('/') + entry->field(QString::fromLatin1("cr_year"));
+ } else if(!entry->field(QString::fromLatin1("pub_year")).isEmpty()){
+ desc += QChar('/') + entry->field(QString::fromLatin1("pub_year"));
+ }
+ SearchResult* r = new SearchResult(this, entry->title(), desc, entry->field(QString::fromLatin1("isbn")));
+ m_entries.insert(r->uid, entry);
+ emit signalResultFound(r);
+ }
+}
+
+void Z3950Fetcher::done() {
+ m_done = true;
+ stop();
+}
+
+Tellico::Data::EntryPtr Z3950Fetcher::fetchEntry(uint uid_) {
+ return m_entries[uid_];
+}
+
+void Z3950Fetcher::customEvent(QCustomEvent* event_) {
+ if(!m_conn) {
+ return;
+ }
+
+ if(event_->type() == Z3950ResultFound::uid()) {
+ if(m_done) {
+ kdWarning() << "Z3950Fetcher::customEvent() - result returned after done signal!" << endl;
+ }
+ Z3950ResultFound* e = static_cast<Z3950ResultFound*>(event_);
+ handleResult(e->result());
+ } else if(event_->type() == Z3950ConnectionDone::uid()) {
+ Z3950ConnectionDone* e = static_cast<Z3950ConnectionDone*>(event_);
+ if(e->messageType() > -1) {
+ message(e->message(), e->messageType());
+ }
+ m_hasMoreResults = e->hasMoreResults();
+ m_conn->wait();
+ done();
+ } else if(event_->type() == Z3950SyntaxChange::uid()) {
+ if(m_done) {
+ kdWarning() << "Z3950Fetcher::customEvent() - syntax changed after done signal!" << endl;
+ }
+ Z3950SyntaxChange* e = static_cast<Z3950SyntaxChange*>(event_);
+ if(m_syntax != e->syntax()) {
+ m_syntax = e->syntax();
+ // it gets saved when saveConfigHook() get's called from the Fetcher() d'tor
+ }
+ } else {
+ kdWarning() << "Z3950Fetcher::customEvent() - weird type: " << event_->type() << endl;
+ }
+}
+
+void Z3950Fetcher::updateEntry(Data::EntryPtr entry_) {
+// myDebug() << "Z3950Fetcher::updateEntry() - " << source() << ": " << entry_->title() << endl;
+ QString isbn = entry_->field(QString::fromLatin1("isbn"));
+ if(!isbn.isEmpty()) {
+ search(Fetch::ISBN, isbn);
+ return;
+ }
+
+ QString lccn = entry_->field(QString::fromLatin1("lccn"));
+ if(!lccn.isEmpty()) {
+ search(Fetch::LCCN, lccn);
+ return;
+ }
+
+ // optimistically try searching for title and rely on Collection::sameEntry() to figure things out
+ QString t = entry_->field(QString::fromLatin1("title"));
+ if(!t.isEmpty()) {
+ search(Fetch::Title, t);
+ return;
+ }
+
+ myDebug() << "Z3950Fetcher::updateEntry() - insufficient info to search" << endl;
+ emit signalDone(this); // always need to emit this if not continuing with the search
+}
+
+Tellico::Fetch::ConfigWidget* Z3950Fetcher::configWidget(QWidget* parent_) const {
+ return new Z3950Fetcher::ConfigWidget(parent_, this);
+}
+
+Z3950Fetcher::ConfigWidget::ConfigWidget(QWidget* parent_, const Z3950Fetcher* fetcher_/*=0*/)
+ : Fetch::ConfigWidget(parent_) {
+ QGridLayout* l = new QGridLayout(optionsWidget(), 7, 2);
+ l->setSpacing(4);
+ l->setColStretch(1, 10);
+
+ int row = -1;
+
+ m_usePreset = new QCheckBox(i18n("Use preset &server:"), optionsWidget());
+ l->addWidget(m_usePreset, ++row, 0);
+ connect(m_usePreset, SIGNAL(toggled(bool)), SLOT(slotTogglePreset(bool)));
+ m_serverCombo = new GUI::ComboBox(optionsWidget());
+ connect(m_serverCombo, SIGNAL(activated(int)), SLOT(slotPresetChanged()));
+ l->addWidget(m_serverCombo, row, 1);
+ ++row;
+ l->addMultiCellWidget(new KSeparator(optionsWidget()), row, row, 0, 1);
+ l->setRowSpacing(row, 10);
+
+ QLabel* label = new QLabel(i18n("Hos&t: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_hostEdit = new GUI::LineEdit(optionsWidget());
+ connect(m_hostEdit, SIGNAL(textChanged(const QString&)), SLOT(slotSetModified()));
+ connect(m_hostEdit, SIGNAL(textChanged(const QString&)), SIGNAL(signalName(const QString&)));
+ l->addWidget(m_hostEdit, row, 1);
+ QString w = i18n("Enter the host name of the server.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_hostEdit, w);
+ label->setBuddy(m_hostEdit);
+
+ label = new QLabel(i18n("&Port: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_portSpinBox = new KIntSpinBox(0, 999999, 1, Z3950_DEFAULT_PORT, 10, optionsWidget());
+ connect(m_portSpinBox, SIGNAL(valueChanged(int)), SLOT(slotSetModified()));
+ l->addWidget(m_portSpinBox, row, 1);
+ w = i18n("Enter the port number of the server. The default is %1.").arg(Z3950_DEFAULT_PORT);
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_portSpinBox, w);
+ label->setBuddy(m_portSpinBox);
+
+ label = new QLabel(i18n("&Database: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_databaseEdit = new GUI::LineEdit(optionsWidget());
+ connect(m_databaseEdit, SIGNAL(textChanged(const QString&)), SLOT(slotSetModified()));
+ l->addWidget(m_databaseEdit, row, 1);
+ w = i18n("Enter the database name used by the server.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_databaseEdit, w);
+ label->setBuddy(m_databaseEdit);
+
+ label = new QLabel(i18n("Ch&aracter set: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_charSetCombo = new KComboBox(true, optionsWidget());
+ m_charSetCombo->insertItem(QString::null);
+ m_charSetCombo->insertItem(QString::fromLatin1("marc8"));
+ m_charSetCombo->insertItem(QString::fromLatin1("iso-8859-1"));
+ m_charSetCombo->insertItem(QString::fromLatin1("utf-8"));
+ connect(m_charSetCombo, SIGNAL(textChanged(const QString&)), SLOT(slotSetModified()));
+ l->addWidget(m_charSetCombo, row, 1);
+ w = i18n("Enter the character set encoding used by the z39.50 server. The most likely choice "
+ "is MARC-8, although ISO-8859-1 is common as well.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_charSetCombo, w);
+ label->setBuddy(m_charSetCombo);
+
+ label = new QLabel(i18n("&Format: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_syntaxCombo = new GUI::ComboBox(optionsWidget());
+ m_syntaxCombo->insertItem(i18n("Auto-detect"), QString());
+ m_syntaxCombo->insertItem(QString::fromLatin1("MODS"), QString::fromLatin1("mods"));
+ m_syntaxCombo->insertItem(QString::fromLatin1("MARC21"), QString::fromLatin1("marc21"));
+ m_syntaxCombo->insertItem(QString::fromLatin1("UNIMARC"), QString::fromLatin1("unimarc"));
+ m_syntaxCombo->insertItem(QString::fromLatin1("USMARC"), QString::fromLatin1("usmarc"));
+ m_syntaxCombo->insertItem(QString::fromLatin1("GRS-1"), QString::fromLatin1("grs-1"));
+ connect(m_syntaxCombo, SIGNAL(textChanged(const QString&)), SLOT(slotSetModified()));
+ l->addWidget(m_syntaxCombo, row, 1);
+ w = i18n("Enter the data format used by the z39.50 server. Tellico will attempt to "
+ "automatically detect the best setting if <i>auto-detect</i> is selected.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_syntaxCombo, w);
+ label->setBuddy(m_syntaxCombo);
+
+ label = new QLabel(i18n("&User: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_userEdit = new GUI::LineEdit(optionsWidget());
+ m_userEdit->setHint(i18n("Optional"));
+ connect(m_userEdit, SIGNAL(textChanged(const QString&)), SLOT(slotSetModified()));
+ l->addWidget(m_userEdit, row, 1);
+ w = i18n("Enter the authentication user name used by the z39.50 database. Most servers "
+ "do not need one.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_userEdit, w);
+ label->setBuddy(m_userEdit);
+
+ label = new QLabel(i18n("Pass&word: "), optionsWidget());
+ l->addWidget(label, ++row, 0);
+ m_passwordEdit = new GUI::LineEdit(optionsWidget());
+ m_passwordEdit->setHint(i18n("Optional"));
+ m_passwordEdit->setEchoMode(QLineEdit::Password);
+ connect(m_passwordEdit, SIGNAL(textChanged(const QString&)), SLOT(slotSetModified()));
+ l->addWidget(m_passwordEdit, row, 1);
+ w = i18n("Enter the authentication password used by the z39.50 database. Most servers "
+ "do not need one. The password will be saved in plain text in the Tellico "
+ "configuration file.");
+ QWhatsThis::add(label, w);
+ QWhatsThis::add(m_passwordEdit, w);
+ label->setBuddy(m_passwordEdit);
+
+ l->setRowStretch(++row, 1);
+
+ // now add additional fields widget
+ addFieldsWidget(Z3950Fetcher::customFields(), fetcher_ ? fetcher_->m_fields : QStringList());
+
+ loadPresets(fetcher_ ? fetcher_->m_preset : QString::null);
+ if(fetcher_) {
+ m_hostEdit->setText(fetcher_->m_host);
+ m_portSpinBox->setValue(fetcher_->m_port);
+ m_databaseEdit->setText(fetcher_->m_dbname);
+ m_userEdit->setText(fetcher_->m_user);
+ m_passwordEdit->setText(fetcher_->m_password);
+ m_charSetCombo->setCurrentText(fetcher_->m_sourceCharSet);
+ // the syntax is detected automatically by the fetcher
+ // since the config group gets deleted in the config file,
+ // the value needs to be retained here
+ m_syntax = fetcher_->m_syntax;
+ m_syntaxCombo->setCurrentData(m_syntax);
+ }
+ KAcceleratorManager::manage(optionsWidget());
+
+ // start with presets turned off
+ m_usePreset->setChecked(fetcher_ && !fetcher_->m_preset.isEmpty());
+
+ slotTogglePreset(m_usePreset->isChecked());
+}
+
+Z3950Fetcher::ConfigWidget::~ConfigWidget() {
+}
+
+void Z3950Fetcher::ConfigWidget::saveConfig(KConfigGroup& config_) {
+ if(m_usePreset->isChecked()) {
+ QString presetID = m_serverCombo->currentData().toString();
+ config_.writeEntry("Preset", presetID);
+ return;
+ }
+ config_.deleteEntry("Preset");
+
+ QString s = m_hostEdit->text().stripWhiteSpace();
+ if(!s.isEmpty()) {
+ config_.writeEntry("Host", s);
+ }
+ int port = m_portSpinBox->value();
+ if(port > 0) {
+ config_.writeEntry("Port", port);
+ }
+ s = m_databaseEdit->text().stripWhiteSpace();
+ if(!s.isEmpty()) {
+ config_.writeEntry("Database", s);
+ }
+ s = m_charSetCombo->currentText();
+ if(!s.isEmpty()) {
+ config_.writeEntry("Charset", s);
+ }
+ s = m_userEdit->text();
+ if(!s.isEmpty()) {
+ config_.writeEntry("User", s);
+ }
+ s = m_passwordEdit->text();
+ if(!s.isEmpty()) {
+ config_.writeEntry("Password", s);
+ }
+ s = m_syntaxCombo->currentData().toString();
+ if(!s.isEmpty()) {
+ m_syntax = s;
+ }
+ config_.writeEntry("Syntax", m_syntax);
+
+ saveFieldsConfig(config_);
+ slotSetModified(false);
+}
+
+// static
+Tellico::StringMap Z3950Fetcher::customFields() {
+ StringMap map;
+ map[QString::fromLatin1("address")] = i18n("Address");
+ map[QString::fromLatin1("abstract")] = i18n("Abstract");
+ map[QString::fromLatin1("illustrator")] = i18n("Illustrator");
+ return map;
+}
+
+void Z3950Fetcher::ConfigWidget::slotTogglePreset(bool on) {
+ m_serverCombo->setEnabled(on);
+ if(on) {
+ emit signalName(m_serverCombo->currentText());
+ }
+ m_hostEdit->setEnabled(!on);
+ if(!on && !m_hostEdit->text().isEmpty()) {
+ emit signalName(m_hostEdit->text());
+ }
+ m_portSpinBox->setEnabled(!on);
+ m_databaseEdit->setEnabled(!on);
+ m_userEdit->setEnabled(!on);
+ m_passwordEdit->setEnabled(!on);
+ m_charSetCombo->setEnabled(!on);
+ m_syntaxCombo->setEnabled(!on);
+ if(on) {
+ emit signalName(m_serverCombo->currentText());
+ }
+}
+
+void Z3950Fetcher::ConfigWidget::slotPresetChanged() {
+ emit signalName(m_serverCombo->currentText());
+}
+
+void Z3950Fetcher::ConfigWidget::loadPresets(const QString& current_) {
+ QString lang = KGlobal::locale()->languageList().first();
+ QString lang2A;
+ {
+ QString dummy;
+ KGlobal::locale()->splitLocale(lang, lang2A, dummy, dummy);
+ }
+
+ QString serverFile = locate("appdata", QString::fromLatin1("z3950-servers.cfg"));
+ if(serverFile.isEmpty()) {
+ kdWarning() << "Z3950Fetcher::loadPresets() - no z3950 servers file found" << endl;
+ return;
+ }
+
+ int idx = -1;
+
+ KConfig cfg(serverFile, true /* read-only */, false /* read KDE */);
+ const QStringList servers = cfg.groupList();
+ // I want the list of servers sorted by name
+ QMap<QString, QString> serverNameMap;
+ for(QStringList::ConstIterator server = servers.constBegin(); server != servers.constEnd(); ++server) {
+ if((*server).isEmpty()) {
+ myDebug() << "Z3950Fetcher::ConfigWidget::loadPresets() - empty id" << endl;
+ continue;
+ }
+ cfg.setGroup(*server);
+ const QString name = cfg.readEntry("Name");
+ if(!name.isEmpty()) {
+ serverNameMap.insert(name, *server);
+ }
+ }
+ for(QMap<QString, QString>::ConstIterator it = serverNameMap.constBegin(); it != serverNameMap.constEnd(); ++it) {
+ const QString name = it.key();
+ const QString id = it.data();
+ cfg.setGroup(id);
+
+ m_serverCombo->insertItem(i18n(name.utf8()), id);
+ if(current_.isEmpty() && idx == -1) {
+ // set the initial selection to something depending on the language
+ const QStringList locales = cfg.readListEntry("Locale");
+ if(locales.findIndex(lang) > -1 || locales.findIndex(lang2A) > -1) {
+ idx = m_serverCombo->count() - 1;
+ }
+ } else if(id == current_) {
+ idx = m_serverCombo->count() - 1;
+ }
+ }
+ if(idx > -1) {
+ m_serverCombo->setCurrentItem(idx);
+ }
+}
+
+QString Z3950Fetcher::ConfigWidget::preferredName() const {
+ if(m_usePreset->isChecked()) {
+ return m_serverCombo->currentText();
+ }
+ QString s = m_hostEdit->text();
+ return s.isEmpty() ? i18n("z39.50 Server") : s;
+}
+
+#include "z3950fetcher.moc"
diff --git a/src/fetch/z3950fetcher.h b/src/fetch/z3950fetcher.h
new file mode 100644
index 0000000..ec6dca0
--- /dev/null
+++ b/src/fetch/z3950fetcher.h
@@ -0,0 +1,153 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ * In addition, as a special exception, the author gives permission to *
+ * link the code of this program with the OpenSSL library released by *
+ * the OpenSSL Project (or with modified versions of OpenSSL that use *
+ * the same license as OpenSSL), and distribute linked combinations *
+ * including the two. You must obey the GNU General Public License in *
+ * all respects for all of the code used other than OpenSSL. If you *
+ * modify this file, you may extend this exception to your version of *
+ * the file, but you are not obligated to do so. If you do not wish to *
+ * do so, delete this exception statement from your version. *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_Z3950FETCHER_H
+#define TELLICO_Z3950FETCHER_H
+
+namespace Tellico {
+ class XSLTHandler;
+ namespace GUI {
+ class LineEdit;
+ class ComboBox;
+ }
+}
+
+class KIntSpinBox;
+class KComboBox;
+
+#include "fetcher.h"
+#include "configwidget.h"
+#include "../datavectors.h"
+
+#include <qguardedptr.h>
+
+namespace Tellico {
+ namespace Fetch {
+ class Z3950Connection;
+
+/**
+ * @author Robby Stephenson
+ */
+class Z3950Fetcher : public Fetcher {
+Q_OBJECT
+
+public:
+ Z3950Fetcher(QObject* parent, const char* name = 0);
+
+ virtual ~Z3950Fetcher();
+
+ virtual QString source() const;
+ virtual bool isSearching() const { return m_started; }
+ virtual void search(FetchKey key, const QString& value);
+ virtual void continueSearch();
+ // can search title, person, isbn, or keyword. No UPC or Raw for now.
+ virtual bool canSearch(FetchKey k) const { return k == Title || k == Person || k == ISBN || k == Keyword || k == LCCN; }
+ virtual void stop();
+ virtual Data::EntryPtr fetchEntry(uint uid);
+ virtual Type type() const { return Z3950; }
+ virtual bool canFetch(int type) const;
+ virtual void readConfigHook(const KConfigGroup& config);
+ virtual void saveConfigHook(KConfigGroup& config);
+
+ virtual void updateEntry(Data::EntryPtr entry);
+ const QString& host() const { return m_host; }
+
+ static StringMap customFields();
+
+ virtual Fetch::ConfigWidget* configWidget(QWidget* parent) const;
+
+ class ConfigWidget;
+ friend class ConfigWidget;
+
+ static QString defaultName();
+
+protected:
+ virtual void customEvent(QCustomEvent* event);
+
+private:
+ bool initMARC21Handler();
+ bool initUNIMARCHandler();
+ bool initMODSHandler();
+ void process();
+ void handleResult(const QString& result);
+ void done();
+
+ Z3950Connection* m_conn;
+
+ QString m_host;
+ uint m_port;
+ QString m_dbname;
+ QString m_user;
+ QString m_password;
+ QString m_sourceCharSet;
+ QString m_syntax;
+ QString m_pqn; // prefix query notation
+ QString m_esn; // element set name
+
+ FetchKey m_key;
+ QString m_value;
+ QMap<int, Data::EntryPtr> m_entries;
+ bool m_started;
+ bool m_done;
+ QString m_preset;
+
+ XSLTHandler* m_MARC21XMLHandler;
+ XSLTHandler* m_UNIMARCXMLHandler;
+ XSLTHandler* m_MODSHandler;
+ QStringList m_fields;
+
+ friend class Z3950Connection;
+};
+
+class Z3950Fetcher::ConfigWidget : public Fetch::ConfigWidget {
+Q_OBJECT
+
+public:
+ ConfigWidget(QWidget* parent, const Z3950Fetcher* fetcher = 0);
+ virtual ~ConfigWidget();
+ virtual void saveConfig(KConfigGroup& config_);
+ virtual QString preferredName() const;
+
+private slots:
+ void slotTogglePreset(bool on);
+ void slotPresetChanged();
+
+private:
+ void loadPresets(const QString& current);
+
+ QCheckBox* m_usePreset;
+ GUI::ComboBox* m_serverCombo;
+ GUI::LineEdit* m_hostEdit;
+ KIntSpinBox* m_portSpinBox;
+ GUI::LineEdit* m_databaseEdit;
+ GUI::LineEdit* m_userEdit;
+ GUI::LineEdit* m_passwordEdit;
+ KComboBox* m_charSetCombo;
+ GUI::ComboBox* m_syntaxCombo;
+ // have to remember syntax
+ QString m_syntax;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/fetchdialog.cpp b/src/fetchdialog.cpp
new file mode 100644
index 0000000..453b1b3
--- /dev/null
+++ b/src/fetchdialog.cpp
@@ -0,0 +1,753 @@
+/***************************************************************************
+ copyright : (C) 2003-2008 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "fetchdialog.h"
+#include "fetch/fetchmanager.h"
+#include "fetch/fetcher.h"
+#include "entryview.h"
+#include "isbnvalidator.h"
+#include "upcvalidator.h"
+#include "tellico_kernel.h"
+#include "filehandler.h"
+#include "collection.h"
+#include "entry.h"
+#include "document.h"
+#include "tellico_debug.h"
+#include "gui/combobox.h"
+#include "gui/listview.h"
+#include "tellico_utils.h"
+#include "stringset.h"
+
+#include <klocale.h>
+#include <klineedit.h>
+#include <kpushbutton.h>
+#include <kstatusbar.h>
+#include <khtmlview.h>
+#include <kprogress.h>
+#include <kconfig.h>
+#include <kdialogbase.h>
+#include <kfiledialog.h>
+#include <kiconloader.h>
+#include <kaccelmanager.h>
+#include <ktextedit.h>
+
+#include <qlayout.h>
+#include <qhbox.h>
+#include <qvgroupbox.h>
+#include <qsplitter.h>
+#include <qtimer.h>
+#include <qwhatsthis.h>
+#include <qcheckbox.h>
+#include <qvbox.h>
+#include <qtimer.h>
+#include <qimage.h>
+
+#include <config.h>
+#ifdef ENABLE_WEBCAM
+#include "barcode/barcode.h"
+#endif
+
+namespace {
+ static const int FETCH_STATUS_ID = 0;
+ static const int FETCH_PROGRESS_ID = 0;
+ static const int FETCH_MIN_WIDTH = 600;
+
+ static const char* FETCH_STRING_SEARCH = I18N_NOOP("&Search");
+ static const char* FETCH_STRING_STOP = I18N_NOOP("&Stop");
+}
+
+using Tellico::FetchDialog;
+using barcodeRecognition::barcodeRecognitionThread;
+
+class FetchDialog::SearchResultItem : public Tellico::GUI::ListViewItem {
+ friend class FetchDialog;
+ // always add to end
+ SearchResultItem(GUI::ListView* lv, Fetch::SearchResult* r)
+ : GUI::ListViewItem(lv, lv->lastItem()), m_result(r) {
+ setText(1, r->title);
+ setText(2, r->desc);
+ setPixmap(3, Fetch::Manager::self()->fetcherIcon(r->fetcher.data()));
+ setText(3, r->fetcher->source());
+ }
+ Fetch::SearchResult* m_result;
+};
+
+FetchDialog::FetchDialog(QWidget* parent_, const char* name_)
+ : KDialogBase(parent_, name_, false, i18n("Internet Search"), 0),
+ m_timer(new QTimer(this)), m_started(false) {
+ m_collType = Kernel::self()->collectionType();
+
+ QWidget* mainWidget = new QWidget(this, "FetchDialog mainWidget");
+ setMainWidget(mainWidget);
+ QVBoxLayout* topLayout = new QVBoxLayout(mainWidget, 0, KDialog::spacingHint());
+
+ QVGroupBox* queryBox = new QVGroupBox(i18n("Search Query"), mainWidget, "FetchDialog queryBox");
+ topLayout->addWidget(queryBox);
+
+ QHBox* box1 = new QHBox(queryBox, "FetchDialog box1");
+ box1->setSpacing(KDialog::spacingHint());
+
+ QLabel* label = new QLabel(i18n("Start the search", "S&earch:"), box1);
+
+ m_valueLineEdit = new KLineEdit(box1);
+ label->setBuddy(m_valueLineEdit);
+ QWhatsThis::add(m_valueLineEdit, i18n("Enter a search value. An ISBN search must include the full ISBN."));
+ m_keyCombo = new GUI::ComboBox(box1);
+ Fetch::KeyMap map = Fetch::Manager::self()->keyMap();
+ for(Fetch::KeyMap::ConstIterator it = map.begin(); it != map.end(); ++it) {
+ m_keyCombo->insertItem(it.data(), it.key());
+ }
+ connect(m_keyCombo, SIGNAL(activated(int)), SLOT(slotKeyChanged(int)));
+ QWhatsThis::add(m_keyCombo, i18n("Choose the type of search"));
+
+ m_searchButton = new KPushButton(box1);
+ m_searchButton->setGuiItem(KGuiItem(i18n(FETCH_STRING_STOP),
+ SmallIconSet(QString::fromLatin1("cancel"))));
+ connect(m_searchButton, SIGNAL(clicked()), SLOT(slotSearchClicked()));
+ QWhatsThis::add(m_searchButton, i18n("Click to start or stop the search"));
+
+ // the search button's text changes from search to stop
+ // I don't want it resizing, so figure out the maximum size and set that
+ m_searchButton->polish();
+ int maxWidth = m_searchButton->sizeHint().width();
+ int maxHeight = m_searchButton->sizeHint().height();
+ m_searchButton->setGuiItem(KGuiItem(i18n(FETCH_STRING_SEARCH),
+ SmallIconSet(QString::fromLatin1("find"))));
+ maxWidth = QMAX(maxWidth, m_searchButton->sizeHint().width());
+ maxHeight = QMAX(maxHeight, m_searchButton->sizeHint().height());
+ m_searchButton->setMinimumWidth(maxWidth);
+ m_searchButton->setMinimumHeight(maxHeight);
+
+ QHBox* box2 = new QHBox(queryBox);
+ box2->setSpacing(KDialog::spacingHint());
+
+ m_multipleISBN = new QCheckBox(i18n("&Multiple ISBN/UPC search"), box2);
+ QWhatsThis::add(m_multipleISBN, i18n("Check this box to search for multiple ISBN or UPC values."));
+ connect(m_multipleISBN, SIGNAL(toggled(bool)), SLOT(slotMultipleISBN(bool)));
+
+ m_editISBN = new KPushButton(KGuiItem(i18n("Edit List..."), QString::fromLatin1("text_block")), box2);
+ m_editISBN->setEnabled(false);
+ QWhatsThis::add(m_editISBN, i18n("Click to open a text edit box for entering or editing multiple ISBN values."));
+ connect(m_editISBN, SIGNAL(clicked()), SLOT(slotEditMultipleISBN()));
+
+ // add for spacing
+ box2->setStretchFactor(new QWidget(box2), 10);
+
+ label = new QLabel(i18n("Search s&ource:"), box2);
+ m_sourceCombo = new KComboBox(box2);
+ label->setBuddy(m_sourceCombo);
+ Fetch::FetcherVec sources = Fetch::Manager::self()->fetchers(m_collType);
+ for(Fetch::FetcherVec::Iterator it = sources.begin(); it != sources.end(); ++it) {
+ m_sourceCombo->insertItem(Fetch::Manager::self()->fetcherIcon(it.data()), (*it).source());
+ }
+ connect(m_sourceCombo, SIGNAL(activated(const QString&)), SLOT(slotSourceChanged(const QString&)));
+ QWhatsThis::add(m_sourceCombo, i18n("Select the database to search"));
+
+ QSplitter* split = new QSplitter(QSplitter::Vertical, mainWidget);
+ topLayout->addWidget(split);
+
+ m_listView = new GUI::ListView(split);
+// topLayout->addWidget(m_listView);
+// topLayout->setStretchFactor(m_listView, 1);
+ m_listView->setSorting(10); // greater than number of columns, so not sorting until user clicks column header
+ m_listView->setShowSortIndicator(true);
+ m_listView->setAllColumnsShowFocus(true);
+ m_listView->setSelectionMode(QListView::Extended);
+ m_listView->addColumn(QString::null, 20); // will show a check mark when added
+ m_listView->setColumnAlignment(0, Qt::AlignHCenter); // align checkmark in middle
+// m_listView->setColumnWidthMode(0, QListView::Manual);
+ m_listView->addColumn(i18n("Title"));
+ m_listView->addColumn(i18n("Description"));
+ m_listView->addColumn(i18n("Source"));
+ m_listView->viewport()->installEventFilter(this);
+
+ connect(m_listView, SIGNAL(selectionChanged()), SLOT(slotShowEntry()));
+ // double clicking should add the entry
+ connect(m_listView, SIGNAL(doubleClicked(QListViewItem*)), SLOT(slotAddEntry()));
+ QWhatsThis::add(m_listView, i18n("As results are found, they are added to this list. Selecting one "
+ "will fetch the complete entry and show it in the view below."));
+
+ m_entryView = new EntryView(split, "entry_view");
+ // don't bother creating funky gradient images for compact view
+ m_entryView->setUseGradientImages(false);
+ // set the xslt file AFTER setting the gradient image option
+ m_entryView->setXSLTFile(QString::fromLatin1("Compact.xsl"));
+ QWhatsThis::add(m_entryView->view(), i18n("An entry may be shown here before adding it to the "
+ "current collection by selecting it in the list above"));
+
+ QHBox* box3 = new QHBox(mainWidget);
+ topLayout->addWidget(box3);
+ box3->setSpacing(KDialog::spacingHint());
+
+ m_addButton = new KPushButton(i18n("&Add Entry"), box3);
+ m_addButton->setEnabled(false);
+ m_addButton->setIconSet(UserIconSet(Kernel::self()->collectionTypeName()));
+ connect(m_addButton, SIGNAL(clicked()), SLOT(slotAddEntry()));
+ QWhatsThis::add(m_addButton, i18n("Add the selected entry to the current collection"));
+
+ m_moreButton = new KPushButton(KGuiItem(i18n("Get More Results"), SmallIconSet(QString::fromLatin1("find"))), box3);
+ m_moreButton->setEnabled(false);
+ connect(m_moreButton, SIGNAL(clicked()), SLOT(slotMoreClicked()));
+ QWhatsThis::add(m_moreButton, i18n("Fetch more results from the current data source"));
+
+ KPushButton* clearButton = new KPushButton(KStdGuiItem::clear(), box3);
+ connect(clearButton, SIGNAL(clicked()), SLOT(slotClearClicked()));
+ QWhatsThis::add(clearButton, i18n("Clear all search fields and results"));
+
+ QHBox* bottombox = new QHBox(mainWidget, "box");
+ topLayout->addWidget(bottombox);
+ bottombox->setSpacing(KDialog::spacingHint());
+
+ m_statusBar = new KStatusBar(bottombox, "statusbar");
+ m_statusBar->insertItem(QString::null, FETCH_STATUS_ID, 1, false);
+ m_statusBar->setItemAlignment(FETCH_STATUS_ID, AlignLeft | AlignVCenter);
+ m_progress = new QProgressBar(m_statusBar, "progress");
+ m_progress->setTotalSteps(0);
+ m_progress->setFixedHeight(fontMetrics().height()+2);
+ m_progress->hide();
+ m_statusBar->addWidget(m_progress, 0, true);
+
+ KPushButton* closeButton = new KPushButton(KStdGuiItem::close(), bottombox);
+ connect(closeButton, SIGNAL(clicked()), SLOT(slotClose()));
+
+ connect(m_timer, SIGNAL(timeout()), SLOT(slotMoveProgress()));
+
+ setMinimumWidth(QMAX(minimumWidth(), FETCH_MIN_WIDTH));
+ setStatus(i18n("Ready."));
+
+ resize(configDialogSize(QString::fromLatin1("Fetch Dialog Options")));
+
+ KConfigGroup config(kapp->config(), "Fetch Dialog Options");
+ QValueList<int> splitList = config.readIntListEntry("Splitter Sizes");
+ if(!splitList.empty()) {
+ split->setSizes(splitList);
+ }
+
+ connect(Fetch::Manager::self(), SIGNAL(signalResultFound(Tellico::Fetch::SearchResult*)),
+ SLOT(slotResultFound(Tellico::Fetch::SearchResult*)));
+ connect(Fetch::Manager::self(), SIGNAL(signalStatus(const QString&)),
+ SLOT(slotStatus(const QString&)));
+ connect(Fetch::Manager::self(), SIGNAL(signalDone()),
+ SLOT(slotFetchDone()));
+
+ // make sure to delete results afterwards
+ m_results.setAutoDelete(true);
+
+ KAcceleratorManager::manage(this);
+ // initialize combos
+ QTimer::singleShot(0, this, SLOT(slotInit()));
+
+#ifdef ENABLE_WEBCAM
+ // barcode recognition
+ m_barcodeRecognitionThread = new barcodeRecognitionThread();
+ if (m_barcodeRecognitionThread->isWebcamAvailable()) {
+ m_barcodePreview = new QLabel(0);
+ m_barcodePreview->move( QApplication::desktop()->width() - 350, 30 );
+ m_barcodePreview->setAutoResize( true );
+ m_barcodePreview->show();
+ } else {
+ m_barcodePreview = 0;
+ }
+ connect( m_barcodeRecognitionThread, SIGNAL(recognized(QString)), this, SLOT(slotBarcodeRecognized(QString)) );
+ connect( m_barcodeRecognitionThread, SIGNAL(gotImage(QImage&)), this, SLOT(slotBarcodeGotImage(QImage&)) );
+ m_barcodeRecognitionThread->start();
+/* //DEBUG
+ QImage img( "/home/sebastian/white.png", "PNG" );
+ m_barcodeRecognitionThread->recognizeBarcode( img );*/
+#endif
+}
+
+FetchDialog::~FetchDialog() {
+#ifdef ENABLE_WEBCAM
+ m_barcodeRecognitionThread->stop();
+ if (!m_barcodeRecognitionThread->wait( 1000 ))
+ m_barcodeRecognitionThread->terminate();
+ delete m_barcodeRecognitionThread;
+ if (m_barcodePreview)
+ delete m_barcodePreview;
+#endif
+
+ // we might have downloaded a lot of images we don't need to keep
+ Data::EntryVec entriesToCheck;
+ for(QMap<int, Data::EntryPtr>::Iterator it = m_entries.begin(); it != m_entries.end(); ++it) {
+ entriesToCheck.append(it.data());
+ }
+ // no additional entries to check images to keep though
+ Data::Document::self()->removeImagesNotInCollection(entriesToCheck, Data::EntryVec());
+
+ saveDialogSize(QString::fromLatin1("Fetch Dialog Options"));
+
+ KConfigGroup config(kapp->config(), "Fetch Dialog Options");
+ config.writeEntry("Splitter Sizes", static_cast<QSplitter*>(m_listView->parentWidget())->sizes());
+ config.writeEntry("Search Key", m_keyCombo->currentData().toInt());
+ config.writeEntry("Search Source", m_sourceCombo->currentText());
+}
+
+void FetchDialog::slotSearchClicked() {
+ m_valueLineEdit->selectAll();
+ if(m_started) {
+ setStatus(i18n("Cancelling the search..."));
+ Fetch::Manager::self()->stop();
+ slotFetchDone();
+ } else {
+ QString value = m_valueLineEdit->text().simplifyWhiteSpace();
+ if(value != m_oldSearch) {
+ m_listView->clear();
+ m_entryView->clear();
+ }
+ m_resultCount = 0;
+ m_oldSearch = value;
+ m_started = true;
+ m_searchButton->setGuiItem(KGuiItem(i18n(FETCH_STRING_STOP),
+ SmallIconSet(QString::fromLatin1("cancel"))));
+ startProgress();
+ setStatus(i18n("Searching..."));
+ kapp->processEvents();
+ Fetch::Manager::self()->startSearch(m_sourceCombo->currentText(),
+ static_cast<Fetch::FetchKey>(m_keyCombo->currentData().toInt()),
+ value);
+ }
+}
+
+void FetchDialog::slotClearClicked() {
+ slotFetchDone(false);
+ m_listView->clear();
+ m_entryView->clear();
+ Fetch::Manager::self()->stop();
+ m_multipleISBN->setChecked(false);
+ m_valueLineEdit->clear();
+ m_valueLineEdit->setFocus();
+ m_addButton->setEnabled(false);
+ m_moreButton->setEnabled(false);
+ m_isbnList.clear();
+ m_statusMessages.clear();
+ setStatus(i18n("Ready.")); // because slotFetchDone() writes text
+}
+
+void FetchDialog::slotStatus(const QString& status_) {
+ m_statusMessages.push_back(status_);
+ // if the queue was empty, start the timer
+ if(m_statusMessages.count() == 1) {
+ // wait 2 seconds
+ QTimer::singleShot(2000, this, SLOT(slotUpdateStatus()));
+ }
+}
+
+void FetchDialog::slotUpdateStatus() {
+ if(m_statusMessages.isEmpty()) {
+ return;
+ }
+ setStatus(m_statusMessages.front());
+ m_statusMessages.pop_front();
+ if(!m_statusMessages.isEmpty()) {
+ // wait 2 seconds
+ QTimer::singleShot(2000, this, SLOT(slotUpdateStatus()));
+ }
+}
+
+void FetchDialog::setStatus(const QString& text_) {
+ m_statusBar->changeItem(QChar(' ') + text_, FETCH_STATUS_ID);
+}
+
+void FetchDialog::slotFetchDone(bool checkISBN /* = true */) {
+// myDebug() << "FetchDialog::slotFetchDone()" << endl;
+ m_started = false;
+ m_searchButton->setGuiItem(KGuiItem(i18n(FETCH_STRING_SEARCH),
+ SmallIconSet(QString::fromLatin1("find"))));
+ stopProgress();
+ if(m_resultCount == 0) {
+ slotStatus(i18n("The search returned no items."));
+ } else {
+ /* TRANSLATORS: This is a plural form, you need to translate both lines (except "_n: ") */
+ slotStatus(i18n("The search returned 1 item.",
+ "The search returned %n items.",
+ m_resultCount));
+ }
+ m_moreButton->setEnabled(Fetch::Manager::self()->hasMoreResults());
+
+ // if we're not checking isbn values, then, ok to return
+ if(!checkISBN) {
+ return;
+ }
+
+ const Fetch::FetchKey key = static_cast<Fetch::FetchKey>(m_keyCombo->currentData().toInt());
+ // no way to currently check EAN/UPC values for non-book items
+ if(m_collType & (Data::Collection::Book | Data::Collection::Bibtex) &&
+ m_multipleISBN->isChecked() &&
+ (key == Fetch::ISBN || key == Fetch::UPC)) {
+ QStringList values = QStringList::split(QString::fromLatin1("; "),
+ m_oldSearch.simplifyWhiteSpace());
+ for(QStringList::Iterator it = values.begin(); it != values.end(); ++it) {
+ *it = ISBNValidator::cleanValue(*it);
+ }
+ for(QListViewItemIterator it(m_listView); it.current(); ++it) {
+ QString i = ISBNValidator::cleanValue(static_cast<SearchResultItem*>(it.current())->m_result->isbn);
+ values.remove(i);
+ if(i.length() > 10 && i.startsWith(QString::fromLatin1("978"))) {
+ values.remove(ISBNValidator::cleanValue(ISBNValidator::isbn10(i)));
+ }
+ }
+ if(!values.isEmpty()) {
+ for(QStringList::Iterator it = values.begin(); it != values.end(); ++it) {
+ ISBNValidator::staticFixup(*it);
+ }
+ // TODO dialog caption
+ KDialogBase* dlg = new KDialogBase(this, "isbn not found dialog", false, QString::null, KDialogBase::Ok);
+ QWidget* box = new QWidget(dlg);
+ QVBoxLayout* lay = new QVBoxLayout(box, KDialog::marginHint(), KDialog::spacingHint()*2);
+ QHBoxLayout* lay2 = new QHBoxLayout(lay);
+ QLabel* lab = new QLabel(box);
+ lab->setPixmap(KGlobal::iconLoader()->loadIcon(QString::fromLatin1("messagebox_info"),
+ KIcon::NoGroup,
+ KIcon::SizeMedium));
+ lay2->addWidget(lab);
+ QString s = i18n("No results were found for the following ISBN values:");
+ lay2->addWidget(new QLabel(s, box), 10);
+ KTextEdit* edit = new KTextEdit(box, "isbn list edit");
+ lay->addWidget(edit);
+ edit->setText(values.join(QChar('\n')));
+ QWhatsThis::add(edit, s);
+ connect(dlg, SIGNAL(okClicked()), dlg, SLOT(deleteLater()));
+ dlg->setMainWidget(box);
+ dlg->setMinimumWidth(QMAX(dlg->minimumWidth(), FETCH_MIN_WIDTH*2/3));
+ dlg->show();
+ }
+ }
+}
+
+void FetchDialog::slotResultFound(Tellico::Fetch::SearchResult* result_) {
+ m_results.append(result_);
+ (void) new SearchResultItem(m_listView, result_);
+ ++m_resultCount;
+ adjustColumnWidth();
+ kapp->processEvents();
+}
+
+void FetchDialog::slotAddEntry() {
+ GUI::CursorSaver cs;
+ Data::EntryVec vec;
+ for(QListViewItemIterator it(m_listView, QListViewItemIterator::Selected); it.current(); ++it) {
+ SearchResultItem* item = static_cast<SearchResultItem*>(it.current());
+
+ Fetch::SearchResult* r = item->m_result;
+ Data::EntryPtr entry = m_entries[r->uid];
+ if(!entry) {
+ setStatus(i18n("Fetching %1...").arg(r->title));
+ startProgress();
+ entry = r->fetchEntry();
+ if(!entry) {
+ continue;
+ }
+ m_entries.insert(r->uid, entry);
+ stopProgress();
+ setStatus(i18n("Ready."));
+ }
+ // add a copy, intentionally allowing multiple copies to be added
+ vec.append(new Data::Entry(*entry));
+ item->setPixmap(0, UserIcon(QString::fromLatin1("checkmark")));
+ }
+ if(!vec.isEmpty()) {
+ Kernel::self()->addEntries(vec, true);
+ }
+}
+
+void FetchDialog::slotMoreClicked() {
+ if(m_started) {
+ myDebug() << "FetchDialog::slotMoreClicked() - can't continue while running" << endl;
+ return;
+ }
+
+ m_started = true;
+ m_searchButton->setGuiItem(KGuiItem(i18n(FETCH_STRING_STOP),
+ SmallIconSet(QString::fromLatin1("cancel"))));
+ startProgress();
+ setStatus(i18n("Searching..."));
+ kapp->processEvents();
+ Fetch::Manager::self()->continueSearch();
+}
+
+void FetchDialog::slotShowEntry() {
+ // just in case
+ m_statusMessages.clear();
+
+ const GUI::ListViewItemList& items = m_listView->selectedItems();
+ if(items.isEmpty()) {
+ m_addButton->setEnabled(false);
+ return;
+ }
+
+ m_addButton->setEnabled(true);
+ if(items.count() > 1) {
+ m_entryView->clear();
+ return;
+ }
+
+ SearchResultItem* item = static_cast<SearchResultItem*>(items.getFirst());
+ Fetch::SearchResult* r = item->m_result;
+ setStatus(i18n("Fetching %1...").arg(r->title));
+ Data::EntryPtr entry = m_entries[r->uid];
+ if(!entry) {
+ GUI::CursorSaver cs;
+ startProgress();
+ entry = r->fetchEntry();
+ if(entry) { // might conceivably be null
+ m_entries.insert(r->uid, entry);
+ }
+ stopProgress();
+ }
+ setStatus(i18n("Ready."));
+
+ m_entryView->showEntry(entry);
+}
+
+void FetchDialog::startProgress() {
+ m_progress->show();
+ m_timer->start(100);
+}
+
+void FetchDialog::slotMoveProgress() {
+ m_progress->setProgress(m_progress->progress()+5);
+}
+
+void FetchDialog::stopProgress() {
+ m_timer->stop();
+ m_progress->hide();
+}
+
+void FetchDialog::slotInit() {
+ if(!Fetch::Manager::self()->canFetch()) {
+ m_searchButton->setEnabled(false);
+ Kernel::self()->sorry(i18n("No Internet sources are available for your current collection type."), this);
+ }
+
+ KConfigGroup config(kapp->config(), "Fetch Dialog Options");
+ int key = config.readNumEntry("Search Key", Fetch::FetchFirst);
+ // only change key if valid
+ if(key > Fetch::FetchFirst) {
+ m_keyCombo->setCurrentData(key);
+ }
+ slotKeyChanged(m_keyCombo->currentItem());
+
+ QString source = config.readEntry("Search Source");
+ if(!source.isEmpty()) {
+ m_sourceCombo->setCurrentItem(source);
+ }
+ slotSourceChanged(m_sourceCombo->currentText());
+
+ m_valueLineEdit->setFocus();
+ m_searchButton->setDefault(true);
+}
+
+void FetchDialog::slotKeyChanged(int idx_) {
+ int key = m_keyCombo->data(idx_).toInt();
+ if(key == Fetch::ISBN || key == Fetch::UPC || key == Fetch::LCCN) {
+ m_multipleISBN->setEnabled(true);
+ if(key == Fetch::ISBN) {
+ m_valueLineEdit->setValidator(new ISBNValidator(this));
+ } else {
+ UPCValidator* upc = new UPCValidator(this);
+ connect(upc, SIGNAL(signalISBN()), SLOT(slotUPC2ISBN()));
+ m_valueLineEdit->setValidator(upc);
+ // only want to convert to ISBN if ISBN is accepted by the fetcher
+ Fetch::KeyMap map = Fetch::Manager::self()->keyMap(m_sourceCombo->currentText());
+ upc->setCheckISBN(map.contains(Fetch::ISBN));
+ }
+ } else {
+ m_multipleISBN->setChecked(false);
+ m_multipleISBN->setEnabled(false);
+// slotMultipleISBN(false);
+ m_valueLineEdit->setValidator(0);
+ }
+}
+
+void FetchDialog::slotSourceChanged(const QString& source_) {
+ int curr = m_keyCombo->currentData().toInt();
+ m_keyCombo->clear();
+ Fetch::KeyMap map = Fetch::Manager::self()->keyMap(source_);
+ for(Fetch::KeyMap::ConstIterator it = map.begin(); it != map.end(); ++it) {
+ m_keyCombo->insertItem(it.data(), it.key());
+ }
+ m_keyCombo->setCurrentData(curr);
+ slotKeyChanged(m_keyCombo->currentItem());
+}
+
+void FetchDialog::slotMultipleISBN(bool toggle_) {
+ bool wasEnabled = m_valueLineEdit->isEnabled();
+ m_valueLineEdit->setEnabled(!toggle_);
+ if(!wasEnabled && m_valueLineEdit->isEnabled()) {
+ // if we enable it, it probably had multiple isbn values
+ // the validator doesn't like that, so only keep the first value
+ QString val = m_valueLineEdit->text().section(';', 0, 0);
+ m_valueLineEdit->setText(val);
+ }
+ m_editISBN->setEnabled(toggle_);
+}
+
+void FetchDialog::slotEditMultipleISBN() {
+ KDialogBase dlg(this, "isbn edit dialog", true, i18n("Edit ISBN/UPC Values"),
+ KDialogBase::Ok|KDialogBase::Cancel);
+ QVBox* box = new QVBox(&dlg);
+ box->setSpacing(10);
+ QString s = i18n("<qt>Enter the ISBN or UPC values, one per line.</qt>");
+ (void) new QLabel(s, box);
+ m_isbnTextEdit = new KTextEdit(box, "isbn text edit");
+ m_isbnTextEdit->setText(m_isbnList.join(QChar('\n')));
+ QWhatsThis::add(m_isbnTextEdit, s);
+ KPushButton* fromFileBtn = new KPushButton(SmallIconSet(QString::fromLatin1("fileopen")),
+ i18n("&Load From File..."), box);
+ QWhatsThis::add(fromFileBtn, i18n("<qt>Load the list from a text file.</qt>"));
+ connect(fromFileBtn, SIGNAL(clicked()), SLOT(slotLoadISBNList()));
+ dlg.setMainWidget(box);
+ dlg.setMinimumWidth(QMAX(dlg.minimumWidth(), FETCH_MIN_WIDTH*2/3));
+
+ if(dlg.exec() == QDialog::Accepted) {
+ m_isbnList = QStringList::split('\n', m_isbnTextEdit->text());
+ const QValidator* val = m_valueLineEdit->validator();
+ if(val) {
+ for(QStringList::Iterator it = m_isbnList.begin(); it != m_isbnList.end(); ++it) {
+ val->fixup(*it);
+ if((*it).isEmpty()) {
+ it = m_isbnList.remove(it);
+ // this is next item, shift backward
+ --it;
+ }
+ }
+ }
+ if(m_isbnList.count() > 100) {
+ Kernel::self()->sorry(i18n("<qt>An ISBN search can contain a maximum of 100 ISBN values. Only the "
+ "first 100 values in your list will be used.</qt>"), this);
+ }
+ while(m_isbnList.count() > 100) {
+ m_isbnList.pop_back();
+ }
+ m_valueLineEdit->setText(m_isbnList.join(QString::fromLatin1("; ")));
+ }
+ m_isbnTextEdit = 0; // gets auto-deleted
+}
+
+void FetchDialog::slotLoadISBNList() {
+ if(!m_isbnTextEdit) {
+ return;
+ }
+ KURL u = KFileDialog::getOpenURL(QString::null, QString::null, this);
+ if(u.isValid()) {
+ m_isbnTextEdit->setText(m_isbnTextEdit->text() + FileHandler::readTextFile(u));
+ m_isbnTextEdit->moveCursor(QTextEdit::MoveEnd, false);
+ m_isbnTextEdit->scrollToBottom();
+ }
+}
+
+void FetchDialog::slotUPC2ISBN() {
+ int key = m_keyCombo->currentData().toInt();
+ if(key == Fetch::UPC) {
+ m_keyCombo->setCurrentData(Fetch::ISBN);
+ slotKeyChanged(m_keyCombo->currentItem());
+ }
+}
+
+bool FetchDialog::eventFilter(QObject* obj_, QEvent* ev_) {
+ if(obj_ == m_listView->viewport() && ev_->type() == QEvent::Resize) {
+ adjustColumnWidth();
+ }
+ return false;
+}
+
+void FetchDialog::adjustColumnWidth() {
+ if(!m_listView || m_listView->childCount() == 0) {
+ return;
+ }
+
+ int sum1 = 0;
+ int sum2 = 0;
+ int w3 = 0;
+ for(QListViewItemIterator it(m_listView); it.current(); ++it) {
+ sum1 += it.current()->width(m_listView->fontMetrics(), m_listView, 1);
+ sum2 += it.current()->width(m_listView->fontMetrics(), m_listView, 2);
+ w3 = QMAX(w3, it.current()->width(m_listView->fontMetrics(), m_listView, 3));
+ }
+ // try to be smart about column width
+ // column 0 is fixed, the checkmark icon, give it 20
+ const int w0 = 20;
+ // column 3 is the source, say max is 25% of viewport
+ const int vw = m_listView->visibleWidth();
+ w3 = static_cast<int>(QMIN(1.1 * w3, 0.25 * vw));
+ // scale averages of col 1 and col 2
+ const int avg1 = sum1 / m_listView->childCount();
+ const int avg2 = sum2 / m_listView->childCount();
+ const int w2 = (vw - w0 - w3) * avg2 / (avg1 + avg2);
+ const int w1 = vw - w0 - w3 - w2;
+ m_listView->setColumnWidth(1, w1);
+ m_listView->setColumnWidth(2, w2);
+ m_listView->setColumnWidth(3, w3);
+}
+
+void FetchDialog::slotResetCollection() {
+ if(m_collType == Kernel::self()->collectionType()) {
+ return;
+ }
+ m_collType = Kernel::self()->collectionType();
+ m_sourceCombo->clear();
+ Fetch::FetcherVec sources = Fetch::Manager::self()->fetchers(m_collType);
+ for(Fetch::FetcherVec::Iterator it = sources.begin(); it != sources.end(); ++it) {
+ m_sourceCombo->insertItem(Fetch::Manager::self()->fetcherIcon(it.data()), (*it).source());
+ }
+
+ m_addButton->setIconSet(UserIconSet(Kernel::self()->collectionTypeName()));
+
+ if(Fetch::Manager::self()->canFetch()) {
+ m_searchButton->setEnabled(true);
+ } else {
+ m_searchButton->setEnabled(false);
+ Kernel::self()->sorry(i18n("No Internet sources are available for your current collection type."), this);
+ }
+}
+
+void FetchDialog::slotBarcodeRecognized( QString string )
+{
+ // attention: this slot is called in the context of another thread => do not use GUI-functions!
+ QCustomEvent *e = new QCustomEvent( QEvent::User );
+ QString *data = new QString( string );
+ e->setData( data );
+ qApp->postEvent( this, e ); // the event loop will call FetchDialog::customEvent() in the context of the GUI thread
+}
+
+void FetchDialog::slotBarcodeGotImage( QImage &img )
+{
+ // attention: this slot is called in the context of another thread => do not use GUI-functions!
+ QCustomEvent *e = new QCustomEvent( QEvent::User+1 );
+ QImage *data = new QImage( img.copy() );
+ e->setData( data );
+ qApp->postEvent( this, e ); // the event loop will call FetchDialog::customEvent() in the context of the GUI thread
+}
+
+void FetchDialog::customEvent( QCustomEvent *e )
+{
+ if (!e)
+ return;
+ if ((e->type() == QEvent::User) && e->data()) {
+ // slotBarcodeRecognized() queued call
+ QString temp = *(QString*)(e->data());
+ delete (QString*)(e->data());
+ qApp->beep();
+ m_valueLineEdit->setText( temp );
+ m_searchButton->animateClick();
+ }
+ if ((e->type() == QEvent::User+1) && e->data()) {
+ // slotBarcodegotImage() queued call
+ QImage temp = *(QImage*)(e->data());
+ delete (QImage*)(e->data());
+ m_barcodePreview->setPixmap( temp );
+ }
+}
+
+#include "fetchdialog.moc"
diff --git a/src/fetchdialog.h b/src/fetchdialog.h
new file mode 100644
index 0000000..eef4bdc
--- /dev/null
+++ b/src/fetchdialog.h
@@ -0,0 +1,133 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef FETCHDIALOG_H
+#define FETCHDIALOG_H
+
+#include "datavectors.h"
+
+#include <kdialogbase.h>
+
+#include <qguardedptr.h>
+
+namespace Tellico {
+ class EntryView;
+ namespace Fetch {
+ class Fetcher;
+ class SearchResult;
+ }
+ namespace GUI {
+ class ComboBox;
+ class ListView;
+ }
+}
+
+namespace barcodeRecognition {
+ class barcodeRecognitionThread;
+}
+
+class KComboBox;
+class KLineEdit;
+class KPushButton;
+class KStatusBar;
+class KTextEdit;
+class QProgressBar;
+class QTimer;
+class QCheckBox;
+
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class FetchDialog : public KDialogBase {
+Q_OBJECT
+
+public:
+ /**
+ * Constructor
+ */
+ FetchDialog(QWidget* parent, const char* name = 0);
+ ~FetchDialog();
+
+public slots:
+ void slotResetCollection();
+
+protected:
+ bool eventFilter(QObject* obj, QEvent* ev);
+
+private slots:
+ void slotSearchClicked();
+ void slotClearClicked();
+ void slotAddEntry();
+ void slotMoreClicked();
+ void slotShowEntry();
+ void slotMoveProgress();
+
+ void slotStatus(const QString& status);
+ void slotUpdateStatus();
+
+ void slotFetchDone(bool checkISBN = true);
+ void slotResultFound(Tellico::Fetch::SearchResult* result);
+ void slotKeyChanged(int);
+ void slotSourceChanged(const QString& source);
+ void slotMultipleISBN(bool toggle);
+ void slotEditMultipleISBN();
+ void slotInit();
+ void slotLoadISBNList();
+ void slotUPC2ISBN();
+
+ void slotBarcodeRecognized(QString);
+ void slotBarcodeGotImage(QImage&);
+private:
+ void startProgress();
+ void stopProgress();
+ void setStatus(const QString& text);
+ void adjustColumnWidth();
+
+ void customEvent( QCustomEvent *e );
+
+ class SearchResultItem;
+
+ KComboBox* m_sourceCombo;
+ GUI::ComboBox* m_keyCombo;
+ KLineEdit* m_valueLineEdit;
+ KPushButton* m_searchButton;
+ QCheckBox* m_multipleISBN;
+ KPushButton* m_editISBN;
+ GUI::ListView* m_listView;
+ EntryView* m_entryView;
+ KPushButton* m_addButton;
+ KPushButton* m_moreButton;
+ KStatusBar* m_statusBar;
+ QProgressBar* m_progress;
+ QTimer* m_timer;
+ QGuardedPtr<KTextEdit> m_isbnTextEdit;
+ QLabel *m_barcodePreview;
+
+ bool m_started;
+ int m_resultCount;
+ QString m_oldSearch;
+ QStringList m_isbnList;
+ QStringList m_statusMessages;
+ QMap<int, Data::EntryPtr> m_entries;
+ QPtrList<Fetch::SearchResult> m_results;
+ int m_collType;
+
+ barcodeRecognition::barcodeRecognitionThread *m_barcodeRecognitionThread;
+};
+
+} //end namespace
+
+#endif
diff --git a/src/fetcherconfigdialog.cpp b/src/fetcherconfigdialog.cpp
new file mode 100644
index 0000000..99d4bbe
--- /dev/null
+++ b/src/fetcherconfigdialog.cpp
@@ -0,0 +1,225 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "fetcherconfigdialog.h"
+#include "fetch/fetchmanager.h"
+#include "gui/combobox.h"
+
+#include <klocale.h>
+#include <klineedit.h>
+#include <kcombobox.h>
+#include <kiconloader.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qhgroupbox.h>
+#include <qwidgetstack.h>
+#include <qwhatsthis.h>
+#include <qhbox.h>
+#include <qvgroupbox.h>
+#include <qcheckbox.h>
+
+namespace {
+ static const int FETCHER_CONFIG_MIN_WIDTH = 600;
+}
+
+using Tellico::FetcherConfigDialog;
+
+FetcherConfigDialog::FetcherConfigDialog(QWidget* parent_)
+ : KDialogBase(parent_, "fetcher dialog", true, i18n("Data Source Properties"),
+ KDialogBase::Ok | KDialogBase::Cancel | KDialogBase::Help)
+ , m_newSource(true)
+ , m_useDefaultName(true)
+ , m_configWidget(0) {
+ init(Fetch::Unknown);
+}
+
+FetcherConfigDialog::FetcherConfigDialog(const QString& sourceName_, Fetch::Type type_, bool updateOverwrite_,
+ Fetch::ConfigWidget* configWidget_, QWidget* parent_)
+ : KDialogBase(parent_, "fetcher dialog", true, i18n("Data Source Properties"),
+ KDialogBase::Ok | KDialogBase::Cancel | KDialogBase::Help)
+ , m_newSource(false)
+ , m_useDefaultName(false)
+ , m_configWidget(configWidget_) {
+ init(type_);
+ m_nameEdit->setText(sourceName_);
+ m_cbOverwrite->setChecked(updateOverwrite_);
+}
+
+void FetcherConfigDialog::init(Fetch::Type type_) {
+ setMinimumWidth(FETCHER_CONFIG_MIN_WIDTH);
+ setHelp(QString::fromLatin1("data-sources-options"));
+
+ QWidget* widget = new QWidget(this);
+ QBoxLayout* topLayout = new QHBoxLayout(widget, KDialog::spacingHint());
+
+ QBoxLayout* vlay1 = new QVBoxLayout(topLayout, KDialog::spacingHint());
+ m_iconLabel = new QLabel(widget);
+ if(type_ == Fetch::Unknown) {
+ m_iconLabel->setPixmap(KGlobal::iconLoader()->loadIcon(QString::fromLatin1("network"), KIcon::Panel, 64));
+ } else {
+ m_iconLabel->setPixmap(Fetch::Manager::self()->fetcherIcon(type_, KIcon::Panel, 64));
+ }
+ vlay1->addWidget(m_iconLabel);
+ vlay1->addStretch(1);
+
+ QBoxLayout* vlay2 = new QVBoxLayout(topLayout, KDialog::spacingHint());
+
+ QGridLayout* gl = new QGridLayout(vlay2, 2, 2, KDialog::spacingHint());
+ int row = -1;
+
+ QLabel* label = new QLabel(i18n("&Source name: "), widget);
+ gl->addWidget(label, ++row, 0);
+ QString w = i18n("The name identifies the data source and should be unique and informative.");
+ QWhatsThis::add(label, w);
+
+ m_nameEdit = new KLineEdit(widget);
+ gl->addWidget(m_nameEdit, row, 1);
+ m_nameEdit->setFocus();
+ QWhatsThis::add(m_nameEdit, w);
+ label->setBuddy(m_nameEdit);
+ connect(m_nameEdit, SIGNAL(textChanged(const QString&)), SLOT(slotNameChanged(const QString&)));
+
+ if(m_newSource) {
+ label = new QLabel(i18n("Source &type: "), widget);
+ } else {
+ // since the label doesn't have a buddy, we don't want an accel,
+ // but also want to reuse string we already have
+ label = new QLabel(i18n("Source &type: ").remove('&'), widget);
+ }
+ gl->addWidget(label, ++row, 0);
+ w = i18n("Tellico supports several different data sources.");
+ QWhatsThis::add(label, w);
+
+ if(m_newSource) {
+ m_typeCombo = new GUI::ComboBox(widget);
+ gl->addWidget(m_typeCombo, row, 1);
+ QWhatsThis::add(m_typeCombo, w);
+ label->setBuddy(m_typeCombo);
+ } else {
+ m_typeCombo = 0;
+ QLabel* lab = new QLabel(Fetch::Manager::typeName(type_), widget);
+ gl->addWidget(lab, row, 1);
+ QWhatsThis::add(lab, w);
+ }
+ m_cbOverwrite = new QCheckBox(i18n("Updating from source should overwrite user data"), widget);
+ ++row;
+ gl->addMultiCellWidget(m_cbOverwrite, row, row, 0, 1);
+ w = i18n("If checked, updating entries will overwrite any existing information.");
+ QWhatsThis::add(m_cbOverwrite, w);
+
+ if(m_newSource) {
+ m_stack = new QWidgetStack(widget);
+ vlay2->addWidget(m_stack);
+ connect(m_typeCombo, SIGNAL(activated(int)), SLOT(slotNewSourceSelected(int)));
+
+ int z3950_idx = 0;
+ const Fetch::TypePairList typeList = Fetch::Manager::self()->typeList();
+ for(Fetch::TypePairList::ConstIterator it = typeList.begin(); it != typeList.end(); ++it) {
+ const Fetch::TypePair& type = *it;
+ m_typeCombo->insertItem(type.index(), type.value());
+ if(type.value() == Fetch::Z3950) {
+ z3950_idx = m_typeCombo->count()-1;
+ }
+ }
+ // make sure first widget gets initialized
+ // I'd like it to be the z39.50 widget
+ m_typeCombo->setCurrentItem(z3950_idx);
+ slotNewSourceSelected(z3950_idx);
+ } else {
+ m_stack = 0;
+ // just add config widget and reparent
+ m_configWidget->reparent(widget, QPoint());
+ vlay2->addWidget(m_configWidget);
+ connect(m_configWidget, SIGNAL(signalName(const QString&)), SLOT(slotPossibleNewName(const QString&)));
+ }
+
+ setMainWidget(widget);
+}
+
+QString FetcherConfigDialog::sourceName() const {
+ return m_nameEdit->text();
+}
+
+bool FetcherConfigDialog::updateOverwrite() const {
+ return m_cbOverwrite->isChecked();
+}
+
+Tellico::Fetch::ConfigWidget* FetcherConfigDialog::configWidget() const {
+ if(m_newSource) {
+ return dynamic_cast<Fetch::ConfigWidget*>(m_stack->visibleWidget());
+ }
+ kdWarning() << "FetcherConfigDialog::configWidget() called for modifying existing fetcher!" << endl;
+ return m_configWidget;
+}
+
+Tellico::Fetch::Type FetcherConfigDialog::sourceType() const {
+ if(!m_newSource || m_typeCombo->count() == 0) {
+ kdWarning() << "FetcherConfigDialog::sourceType() called for modifying existing fetcher!" << endl;
+ return Fetch::Unknown;
+ }
+ return static_cast<Fetch::Type>(m_typeCombo->currentData().toInt());
+}
+
+void FetcherConfigDialog::slotNewSourceSelected(int idx_) {
+ if(!m_newSource) {
+ return;
+ }
+
+ // always change to default name
+ m_useDefaultName = true;
+
+ Fetch::ConfigWidget* cw = m_configWidgets[idx_];
+ if(cw) {
+ m_stack->raiseWidget(cw);
+ slotPossibleNewName(cw->preferredName());
+ return;
+ }
+
+ Fetch::Type type = sourceType();
+ if(type == Fetch::Unknown) {
+ kdWarning() << "FetcherConfigDialog::slotNewSourceSelected() - unknown source type" << endl;
+ return;
+ }
+ m_iconLabel->setPixmap(Fetch::Manager::self()->fetcherIcon(type, KIcon::Panel, 64));
+ cw = Fetch::Manager::self()->configWidget(m_stack, type, m_typeCombo->currentText());
+ if(!cw) {
+ // bad bad bad!
+ kdWarning() << "FetcherConfigDialog::slotNewSourceSelected() - no config widget found for type " << type << endl;
+ m_typeCombo->setCurrentItem(0);
+ slotNewSourceSelected(0);
+ return;
+ }
+ connect(cw, SIGNAL(signalName(const QString&)), SLOT(slotPossibleNewName(const QString&)));
+ m_configWidgets.insert(idx_, cw);
+ m_stack->addWidget(cw);
+ m_stack->raiseWidget(cw);
+ slotPossibleNewName(cw->preferredName());
+}
+
+void FetcherConfigDialog::slotNameChanged(const QString&) {
+ m_useDefaultName = false;
+}
+
+void FetcherConfigDialog::slotPossibleNewName(const QString& name_) {
+ if(name_.isEmpty()) {
+ return;
+ }
+ Fetch::ConfigWidget* cw = m_stack ? static_cast<Fetch::ConfigWidget*>(m_stack->visibleWidget()) : m_configWidget;
+ if(m_useDefaultName || (cw && m_nameEdit->text() == cw->preferredName())) {
+ m_nameEdit->setText(name_);
+ m_useDefaultName = true; // it gets reset in slotNameChanged()
+ }
+}
+
+#include "fetcherconfigdialog.moc"
diff --git a/src/fetcherconfigdialog.h b/src/fetcherconfigdialog.h
new file mode 100644
index 0000000..6384102
--- /dev/null
+++ b/src/fetcherconfigdialog.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FETCHERCONFIGDIALOG_H
+#define TELLICO_FETCHERCONFIGDIALOG_H
+
+#include "fetch/fetch.h"
+#include "fetch/configwidget.h"
+
+#include <kdialogbase.h>
+
+#include <qintdict.h>
+
+class KLineEdit;
+class QCheckBox;
+class QWidgetStack;
+
+namespace Tellico {
+ namespace GUI {
+ class ComboBox;
+ }
+
+/**
+ * @author Robby Stephenson
+ */
+class FetcherConfigDialog : public KDialogBase {
+Q_OBJECT
+
+public:
+ FetcherConfigDialog(QWidget* parent);
+ FetcherConfigDialog(const QString& sourceName, Fetch::Type type, bool updateOverwrite,
+ Fetch::ConfigWidget* configWidget, QWidget* parent);
+
+ QString sourceName() const;
+ Fetch::Type sourceType() const;
+ bool updateOverwrite() const;
+ Fetch::ConfigWidget* configWidget() const;
+
+private slots:
+ void slotNewSourceSelected(int idx);
+ void slotNameChanged(const QString& name);
+ void slotPossibleNewName(const QString& name);
+
+private:
+ void init(Fetch::Type type);
+
+ bool m_newSource : 1;
+ bool m_useDefaultName : 1;
+ Fetch::ConfigWidget* m_configWidget;
+ QLabel* m_iconLabel;
+ KLineEdit* m_nameEdit;
+ GUI::ComboBox* m_typeCombo;
+ QCheckBox* m_cbOverwrite;
+ QWidgetStack* m_stack;
+ QIntDict<Fetch::ConfigWidget> m_configWidgets;
+};
+
+} // end namespace
+#endif
diff --git a/src/field.cpp b/src/field.cpp
new file mode 100644
index 0000000..206062a
--- /dev/null
+++ b/src/field.cpp
@@ -0,0 +1,594 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "field.h"
+#include "tellico_utils.h"
+#include "latin1literal.h"
+#include "tellico_debug.h"
+#include "core/tellico_config.h"
+#include "collection.h"
+
+#include <klocale.h>
+#include <kglobal.h>
+
+#include <qstringlist.h>
+#include <qregexp.h>
+#include <qdatetime.h>
+
+namespace {
+ static const QRegExp comma_split = QRegExp(QString::fromLatin1("\\s*,\\s*"));
+}
+
+using Tellico::Data::Field;
+
+//these get overwritten, but are here since they're static
+QStringList Field::s_articlesApos;
+QRegExp Field::s_delimiter = QRegExp(QString::fromLatin1("\\s*;\\s*"));
+
+// this constructor is for anything but Choice type
+Field::Field(const QString& name_, const QString& title_, Type type_/*=Line*/)
+ : KShared(), m_name(name_), m_title(title_), m_category(i18n("General")), m_desc(title_),
+ m_type(type_), m_flags(0), m_formatFlag(FormatNone) {
+
+#ifndef NDEBUG
+ if(m_type == Choice) {
+ kdWarning() << "Field() - A different constructor should be called for multiple choice attributes." << endl;
+ kdWarning() << "Constructing a Field with name = " << name_ << endl;
+ }
+#endif
+ // a paragraph's category is always its title, along with tables
+ if(isSingleCategory()) {
+ m_category = m_title;
+ }
+ if(m_type == Table || m_type == Table2) {
+ m_flags = AllowMultiple;
+ if(m_type == Table2) {
+ m_type = Table;
+ setProperty(QString::fromLatin1("columns"), QChar('2'));
+ } else {
+ setProperty(QString::fromLatin1("columns"), QChar('1'));
+ }
+ } else if(m_type == Date) { // hidden from user
+ m_formatFlag = FormatDate;
+ } else if(m_type == Rating) {
+ setProperty(QString::fromLatin1("minimum"), QChar('1'));
+ setProperty(QString::fromLatin1("maximum"), QChar('5'));
+ }
+ m_id = getID();
+}
+
+// if this constructor is called, the type is necessarily Choice
+Field::Field(const QString& name_, const QString& title_, const QStringList& allowed_)
+ : KShared(), m_name(name_), m_title(title_), m_category(i18n("General")), m_desc(title_),
+ m_type(Field::Choice), m_allowed(allowed_), m_flags(0), m_formatFlag(FormatNone) {
+ m_id = getID();
+}
+
+Field::Field(const Field& field_)
+ : KShared(field_), m_name(field_.name()), m_title(field_.title()), m_category(field_.category()),
+ m_desc(field_.description()), m_type(field_.type()),
+ m_flags(field_.flags()), m_formatFlag(field_.formatFlag()),
+ m_properties(field_.propertyList()) {
+ if(m_type == Choice) {
+ m_allowed = field_.allowed();
+ } else if(m_type == Table2) {
+ m_type = Table;
+ setProperty(QString::fromLatin1("columns"), QChar('2'));
+ }
+ m_id = getID();
+}
+
+Field& Field::operator=(const Field& field_) {
+ if(this == &field_) return *this;
+
+ static_cast<KShared&>(*this) = static_cast<const KShared&>(field_);
+ m_name = field_.name();
+ m_title = field_.title();
+ m_category = field_.category();
+ m_desc = field_.description();
+ m_type = field_.type();
+ if(m_type == Choice) {
+ m_allowed = field_.allowed();
+ } else if(m_type == Table2) {
+ m_type = Table;
+ setProperty(QString::fromLatin1("columns"), QChar('2'));
+ }
+ m_flags = field_.flags();
+ m_formatFlag = field_.formatFlag();
+ m_properties = field_.propertyList();
+ m_id = getID();
+ return *this;
+}
+
+Field::~Field() {
+}
+
+void Field::setTitle(const QString& title_) {
+ m_title = title_;
+ if(isSingleCategory()) {
+ m_category = title_;
+ }
+}
+
+void Field::setType(Field::Type type_) {
+ m_type = type_;
+ if(m_type != Field::Choice) {
+ m_allowed = QStringList();
+ }
+ if(m_type == Table || m_type == Table2) {
+ m_flags |= AllowMultiple;
+ if(m_type == Table2) {
+ m_type = Table;
+ setProperty(QString::fromLatin1("columns"), QChar('2'));
+ }
+ if(property(QString::fromLatin1("columns")).isEmpty()) {
+ setProperty(QString::fromLatin1("columns"), QChar('1'));
+ }
+ }
+ if(isSingleCategory()) {
+ m_category = m_title;
+ }
+ // hidden from user
+ if(type_ == Date) {
+ m_formatFlag = FormatDate;
+ }
+}
+
+void Field::setCategory(const QString& category_) {
+ if(!isSingleCategory()) {
+ m_category = category_;
+ }
+}
+
+void Field::setFlags(int flags_) {
+ // tables always have multiple allowed
+ if(m_type == Table || m_type == Table2) {
+ m_flags = AllowMultiple | flags_;
+ } else {
+ m_flags = flags_;
+ }
+}
+
+void Field::setFormatFlag(FormatFlag flag_) {
+ // Choice and Data fields are not allowed a format
+ if(m_type != Choice && m_type != Date) {
+ m_formatFlag = flag_;
+ }
+}
+
+const QString& Field::defaultValue() const {
+ return property(QString::fromLatin1("default"));
+}
+
+void Field::setDefaultValue(const QString& value_) {
+ if(m_type != Choice || m_allowed.findIndex(value_) > -1) {
+ setProperty(QString::fromLatin1("default"), value_);
+ }
+}
+
+bool Field::isSingleCategory() const {
+ return (m_type == Para || m_type == Table || m_type == Table2 || m_type == Image);
+}
+
+// format is something like "%{year} %{author}"
+Tellico::Data::FieldVec Field::dependsOn(CollPtr coll_) const {
+ FieldVec vec;
+ if(m_type != Dependent || !coll_) {
+ return vec;
+ }
+
+ const QStringList fieldNames = dependsOn();
+ // do NOT call recursively!
+ for(QStringList::ConstIterator it = fieldNames.begin(); it != fieldNames.end(); ++it) {
+ FieldPtr field = coll_->fieldByName(*it);
+ if(!field) {
+ // allow the user to also use field titles
+ field = coll_->fieldByTitle(*it);
+ }
+ if(field) {
+ vec.append(field);
+ }
+ }
+ return vec;
+}
+
+QStringList Field::dependsOn() const {
+ QStringList list;
+ if(m_type != Dependent) {
+ return list;
+ }
+
+ QRegExp rx(QString::fromLatin1("%\\{(.+)\\}"));
+ rx.setMinimal(true);
+ // do NOT call recursively!
+ for(int pos = m_desc.find(rx); pos > -1; pos = m_desc.find(rx, pos+3)) {
+ list << rx.cap(1);
+ }
+ return list;
+}
+
+QString Field::format(const QString& value_, FormatFlag flag_) {
+ if(value_.isEmpty()) {
+ return value_;
+ }
+
+ QString text;
+ switch(flag_) {
+ case FormatTitle:
+ text = formatTitle(value_);
+ break;
+ case FormatName:
+ text = formatName(value_);
+ break;
+ case FormatDate:
+ text = formatDate(value_);
+ break;
+ case FormatPlain:
+ text = Config::autoCapitalization() ? capitalize(value_) : value_;
+ break;
+ default:
+ text = value_;
+ break;
+ }
+ return text;
+}
+
+QString Field::formatTitle(const QString& title_) {
+ QString newTitle = title_;
+ // special case for multi-column tables, assume user never has '::' in a value
+ const QString colonColon = QString::fromLatin1("::");
+ QString tail;
+ if(newTitle.find(colonColon) > -1) {
+ tail = colonColon + newTitle.section(colonColon, 1);
+ newTitle = newTitle.section(colonColon, 0, 0);
+ }
+
+ if(Config::autoCapitalization()) {
+ newTitle = capitalize(newTitle);
+ }
+
+ if(Config::autoFormat()) {
+ const QString lower = newTitle.lower();
+ // TODO if the title has ",the" at the end, put it at the front
+ const QStringList& articles = Config::articleList();
+ for(QStringList::ConstIterator it = articles.begin(); it != articles.end(); ++it) {
+ // assume white space is already stripped
+ // the articles are already in lower-case
+ if(lower.startsWith(*it + QChar(' '))) {
+ QRegExp regexp(QChar('^') + QRegExp::escape(*it) + QString::fromLatin1("\\s*"), false);
+ // can't just use *it since it's in lower-case
+ QString article = newTitle.left((*it).length());
+ newTitle = newTitle.replace(regexp, QString::null)
+ .append(QString::fromLatin1(", "))
+ .append(article);
+ break;
+ }
+ }
+ }
+
+ // also, arbitrarily impose rule that a space must follow every comma
+ newTitle.replace(comma_split, QString::fromLatin1(", "));
+ return newTitle + tail;
+}
+
+QString Field::formatName(const QString& name_, bool multiple_/*=true*/) {
+ static const QRegExp spaceComma(QString::fromLatin1("[\\s,]"));
+ static const QString colonColon = QString::fromLatin1("::");
+ // the ending look-ahead is so that a space is not added at the end
+ static const QRegExp periodSpace(QString::fromLatin1("\\.\\s*(?=.)"));
+
+ QStringList entries;
+ if(multiple_) {
+ // split by semi-colon, optionally preceded or followed by white spacee
+ entries = QStringList::split(s_delimiter, name_, false);
+ } else {
+ entries << name_;
+ }
+
+ QRegExp lastWord;
+ lastWord.setCaseSensitive(false);
+
+ QStringList names;
+ for(QStringList::ConstIterator it = entries.begin(); it != entries.end(); ++it) {
+ QString name = *it;
+ // special case for 2-column tables, assume user never has '::' in a value
+ QString tail;
+ if(name.find(colonColon) > -1) {
+ tail = colonColon + name.section(colonColon, 1);
+ name = name.section(colonColon, 0, 0);
+ }
+ name.replace(periodSpace, QString::fromLatin1(". "));
+ if(Config::autoCapitalization()) {
+ name = capitalize(name);
+ }
+
+ // split the name by white space and commas
+ QStringList words = QStringList::split(spaceComma, name, false);
+ lastWord.setPattern(QChar('^') + QRegExp::escape(words.last()) + QChar('$'));
+
+ // if it contains a comma already and the last word is not a suffix, don't format it
+ if(!Config::autoFormat() || (name.find(',') > -1 && Config::nameSuffixList().grep(lastWord).isEmpty())) {
+ // arbitrarily impose rule that no spaces before a comma and
+ // a single space after every comma
+ name.replace(comma_split, QString::fromLatin1(", "));
+ names << name + tail;
+ continue;
+ }
+ // otherwise split it by white space, move the last word to the front
+ // but only if there is more than one word
+ if(words.count() > 1) {
+ // if the last word is a suffix, it has to be kept with last name
+ if(Config::nameSuffixList().grep(lastWord).count() > 0) {
+ words.prepend(words.last().append(QChar(',')));
+ words.remove(words.fromLast());
+ }
+
+ // now move the word
+ // adding comma here when there had been a suffix is because it was originally split with space or comma
+ words.prepend(words.last().append(QChar(',')));
+ words.remove(words.fromLast());
+
+ // update last word regexp
+ lastWord.setPattern(QChar('^') + QRegExp::escape(words.last()) + QChar('$'));
+
+ // this is probably just something for me, limited to english
+ while(Config::surnamePrefixList().grep(lastWord).count() > 0) {
+ words.prepend(words.last());
+ words.remove(words.fromLast());
+ lastWord.setPattern(QChar('^') + QRegExp::escape(words.last()) + QChar('$'));
+ }
+
+ names << words.join(QChar(' ')) + tail;
+ } else {
+ names << name + tail;
+ }
+ }
+
+ return names.join(QString::fromLatin1("; "));
+}
+
+QString Field::formatDate(const QString& date_) {
+ // internally, this is "year-month-day"
+ // any of the three may be empty
+ // if they're not digits, return the original string
+ bool empty = true;
+ // for empty year, use current
+ // for empty month or date, use 1
+ QStringList s = QStringList::split('-', date_, true);
+ bool ok = true;
+ int y = s.count() > 0 ? s[0].toInt(&ok) : QDate::currentDate().year();
+ if(ok) {
+ empty = false;
+ } else {
+ y = QDate::currentDate().year();
+ }
+ int m = s.count() > 1 ? s[1].toInt(&ok) : 1;
+ if(ok) {
+ empty = false;
+ } else {
+ m = 1;
+ }
+ int d = s.count() > 2 ? s[2].toInt(&ok) : 1;
+ if(ok) {
+ empty = false;
+ } else {
+ d = 1;
+ }
+ // rather use ISO date formatting than locale formatting for now. Primarily, it makes sorting just work.
+ return empty ? date_ : QDate(y, m, d).toString(Qt::ISODate);
+ // use short form
+// return KGlobal::locale()->formatDate(date, true);
+}
+
+QString Field::capitalize(QString str_) {
+ // regexp to split words
+ static const QRegExp rx(QString::fromLatin1("[-\\s,.;]"));
+
+ if(str_.isEmpty()) {
+ return str_;
+ }
+ // first letter is always capitalized
+ str_.replace(0, 1, str_.at(0).upper());
+
+ // special case for french words like l'espace
+
+ int pos = str_.find(rx, 1);
+ int nextPos;
+
+ QRegExp wordRx;
+ wordRx.setCaseSensitive(false);
+
+ QStringList notCap = Config::noCapitalizationList();
+ // don't capitalize the surname prefixes
+ // does this hold true everywhere other than english?
+ notCap += Config::surnamePrefixList();
+
+ QString word = str_.mid(0, pos);
+ // now check to see if words starts with apostrophe list
+ for(QStringList::ConstIterator it = s_articlesApos.begin(); it != s_articlesApos.end(); ++it) {
+ if(word.lower().startsWith(*it)) {
+ uint l = (*it).length();
+ str_.replace(l, 1, str_.at(l).upper());
+ break;
+ }
+ }
+
+ while(pos > -1) {
+ // also need to compare against list of non-capitalized words
+ nextPos = str_.find(rx, pos+1);
+ if(nextPos == -1) {
+ nextPos = str_.length();
+ }
+ word = str_.mid(pos+1, nextPos-pos-1);
+ bool aposMatch = false;
+ // now check to see if words starts with apostrophe list
+ for(QStringList::ConstIterator it = s_articlesApos.begin(); it != s_articlesApos.end(); ++it) {
+ if(word.lower().startsWith(*it)) {
+ uint l = (*it).length();
+ str_.replace(pos+l+1, 1, str_.at(pos+l+1).upper());
+ aposMatch = true;
+ break;
+ }
+ }
+
+ if(!aposMatch) {
+ wordRx.setPattern(QChar('^') + QRegExp::escape(word) + QChar('$'));
+ if(notCap.grep(wordRx).isEmpty() && nextPos-pos > 1) {
+ str_.replace(pos+1, 1, str_.at(pos+1).upper());
+ }
+ }
+
+ pos = str_.find(rx, pos+1);
+ }
+ return str_;
+}
+
+QString Field::sortKeyTitle(const QString& title_) {
+ const QString lower = title_.lower();
+ const QStringList& articles = Config::articleList();
+ for(QStringList::ConstIterator it = articles.begin(); it != articles.end(); ++it) {
+ // assume white space is already stripped
+ // the articles are already in lower-case
+ if(lower.startsWith(*it + QChar(' '))) {
+ return title_.mid((*it).length() + 1);
+ }
+ }
+ // check apostrophes, too
+ for(QStringList::ConstIterator it = s_articlesApos.begin(); it != s_articlesApos.end(); ++it) {
+ if(lower.startsWith(*it)) {
+ return title_.mid((*it).length());
+ }
+ }
+ return title_;
+}
+
+// articles should all be in lower-case
+void Field::articlesUpdated() {
+ const QStringList articles = Config::articleList();
+ s_articlesApos.clear();
+ for(QStringList::ConstIterator it = articles.begin(); it != articles.end(); ++it) {
+ if((*it).endsWith(QChar('\''))) {
+ s_articlesApos += (*it);
+ }
+ }
+}
+
+// if these are changed, then CollectionFieldsDialog should be checked since it
+// checks for equality against some of these strings
+Field::FieldMap Field::typeMap() {
+ FieldMap map;
+ map[Field::Line] = i18n("Simple Text");
+ map[Field::Para] = i18n("Paragraph");
+ map[Field::Choice] = i18n("Choice");
+ map[Field::Bool] = i18n("Checkbox");
+ map[Field::Number] = i18n("Number");
+ map[Field::URL] = i18n("URL");
+ map[Field::Table] = i18n("Table");
+ map[Field::Image] = i18n("Image");
+ map[Field::Dependent] = i18n("Dependent");
+// map[Field::ReadOnly] = i18n("Read Only");
+ map[Field::Date] = i18n("Date");
+ map[Field::Rating] = i18n("Rating");
+ return map;
+}
+
+// just for formatting's sake
+QStringList Field::typeTitles() {
+ const FieldMap& map = typeMap();
+ QStringList list;
+ list.append(map[Field::Line]);
+ list.append(map[Field::Para]);
+ list.append(map[Field::Choice]);
+ list.append(map[Field::Bool]);
+ list.append(map[Field::Number]);
+ list.append(map[Field::URL]);
+ list.append(map[Field::Date]);
+ list.append(map[Field::Table]);
+ list.append(map[Field::Image]);
+ list.append(map[Field::Rating]);
+ list.append(map[Field::Dependent]);
+ return list;
+}
+
+QStringList Field::split(const QString& string_, bool allowEmpty_) {
+ return string_.isEmpty() ? QStringList() : QStringList::split(s_delimiter, string_, allowEmpty_);
+}
+
+void Field::addAllowed(const QString& value_) {
+ if(m_type != Choice) {
+ return;
+ }
+ if(m_allowed.findIndex(value_) == -1) {
+ m_allowed += value_;
+ }
+}
+
+void Field::setProperty(const QString& key_, const QString& value_) {
+ m_properties.insert(key_, value_);
+}
+
+void Field::setPropertyList(const StringMap& props_) {
+ m_properties = props_;
+}
+
+void Field::convertOldRating(Data::FieldPtr field_) {
+ if(field_->type() != Data::Field::Choice) {
+ return; // nothing to do
+ }
+
+ if(field_->name() != Latin1Literal("rating")
+ && field_->property(QString::fromLatin1("rating")) != Latin1Literal("true")) {
+ return; // nothing to do
+ }
+
+ int min = 10;
+ int max = 1;
+ bool ok;
+ const QStringList& allow = field_->allowed();
+ for(QStringList::ConstIterator it = allow.begin(); it != allow.end(); ++it) {
+ int n = Tellico::toUInt(*it, &ok);
+ if(!ok) {
+ return; // no need to convert
+ }
+ min = QMIN(min, n);
+ max = QMAX(max, n);
+ }
+ max = QMIN(max, 10);
+ if(min >= max) {
+ min = 1;
+ max = 5;
+ }
+ field_->setProperty(QString::fromLatin1("minimum"), QString::number(min));
+ field_->setProperty(QString::fromLatin1("maximum"), QString::number(max));
+ field_->setProperty(QString::fromLatin1("rating"), QString::null);
+ field_->setType(Rating);
+}
+
+// static
+long Field::getID() {
+ static long id = 0;
+ return ++id;
+}
+
+void Field::stripArticles(QString& value) {
+ const QStringList articles = Config::articleList();
+ if(articles.isEmpty()) {
+ return;
+ }
+ for(QStringList::ConstIterator it = articles.begin(); it != articles.end(); ++it) {
+ QRegExp rx(QString::fromLatin1("\\b") + *it + QString::fromLatin1("\\b"));
+ value.remove(rx);
+ }
+ value = value.stripWhiteSpace();
+ value.remove(QRegExp(QString::fromLatin1(",$")));
+}
diff --git a/src/field.h b/src/field.h
new file mode 100644
index 0000000..c9f00da
--- /dev/null
+++ b/src/field.h
@@ -0,0 +1,395 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FIELD_H
+#define TELLICO_FIELD_H
+
+#include "datavectors.h"
+
+#include <qstringlist.h>
+#include <qstring.h>
+#include <qregexp.h>
+
+namespace Tellico {
+ namespace Data {
+
+/**
+ * The Field class encapsulates all the possible properties of a entry.
+ *
+ * A field can be one of eleven types. It has a name, a title, and a category,
+ * along with some flags characterizing certain properties
+ *
+ * @author Robby Stephenson
+ */
+class Field : public KShared {
+public:
+ /**
+ * The possible field types. A Line is represented by a KLineEdit,
+ * a Para is a QMultiLineEdit encompassing multiple lines, a Choice is
+ * limited to set values shown in a KComboBox, and a Bool is either true
+ * or not and is thus a QCheckBox. A Number type is an integer, though it used
+ * to be a Year. A ReadOnly is a hidden value. A URL is obvious, too.
+ * A Table looks like a small spreadsheet with one column, and a Table2
+ * type has two columns. An Image points to a QImage. A Dependent field
+ * depends on the values of other attributes. A Date contains a date.
+ *
+ * Don't forget to change Field::typeMap().
+ *
+ * @see KLineEdit
+ * @see QTextEdit
+ * @see KComboBox
+ * @see QCheckBox
+ * @see QTable
+ **/
+ enum Type {
+ Undef = 0,
+ Line = 1,
+ Para = 2,
+ Choice = 3,
+ Bool = 4,
+ ReadOnly = 5,
+ Number = 6,
+ URL = 7,
+ Table = 8,
+ Table2 = 9, // deprecated in favor of property("columns")
+ Image = 10,
+ Dependent = 11,
+ Date = 12,
+ // Michael Zimmermann used 13 for his Keyword field, so go ahead and skip it
+ Rating = 14 // similar to a Choice field, but allowed values are numbers only
+ // if you add your own field type, best to start at a high number
+ // say 100, to ensure uniqueness
+ };
+ typedef QMap<Field::Type, QString> FieldMap;
+
+ /**
+ * The field flags. The properties should be bit-wise OR'd together.
+ *
+ * @li AllowCompletion - Include a completion object in the lineedit.
+ * @li AllowMultiple - Multiple values are allowed in one field and are
+ * separated by a semi-colon (";").
+ * @li AllowGrouped - Entries may be grouped by this field.
+ * @li NoDelete - The user may not delete this field.
+ */
+ enum FieldFlags {
+ AllowMultiple = 1 << 0, // allow multiple values, separated by a semi-colon
+ AllowGrouped = 1 << 1, // this field can be used to group entries
+ AllowCompletion = 1 << 2, // allow auto-completion
+ NoDelete = 1 << 3 // don't allow user to delete this field
+ };
+
+ /**
+ * The field formatting flags.
+ *
+ * @li FormatTitle - The field should be formatted as a title
+ * @li FormatName - The field should be formatted as a personal name
+ * @li FormatDate - The field should be formatted as a date.
+ * @li FormatPlain - The field only be formatted with capitalization.
+ * @li FormatNone - The field should not be formatted.
+ */
+ enum FormatFlag {
+ FormatPlain = 0, // format plain, allows capitalization
+ FormatTitle = 1, // format as a title, i.e. shift articles to end
+ FormatName = 2, // format as a personal full name
+ FormatDate = 3, // format as a date
+ FormatNone = 4 // no format, i.e. no capitalization allowed
+ };
+
+ /**
+ * The constructor for all types except Choice. The default type is Line.
+ * By default, the field category is set to "General", and should be modified
+ * using the @ref setCategory() method.
+ *
+ * @param name The field name
+ * @param title The field title
+ * @param type The field type
+ */
+ Field(const QString& name, const QString& title, Type type = Line);
+ /**
+ * The constructor for Choice types attributes.
+ * By default, the field category is set to "General", and should be modified
+ * using the @ref setCategory() method.
+ *
+ * @param name The field name
+ * @param title The field title
+ * @param allowed The allowed values of the field
+ */
+ Field(const QString& name, const QString& title, const QStringList& allowed);
+ /**
+ * The copy constructor
+ */
+ Field(const Field& field);
+ /**
+ * The assignment operator
+ */
+ Field& operator=(const Field& field);
+ /**
+ * Destructor
+ */
+ ~Field();
+
+ /**
+ * Returns the id of the field.
+ *
+ * @return The id
+ */
+ long id() const { return m_id; }
+ /**
+ * Returns the name of the field.
+ *
+ * @return The field name
+ */
+ const QString& name() const { return m_name; }
+ /**
+ * Sets the name of the field. This should only be changed before the field is added
+ * to a collection, i.e. before any entries use it, etc.
+ *
+ * @param name The field name
+ */
+ void setName(const QString& name) { m_name = name; }
+ /**
+ * Returns the title of the field.
+ *
+ * @return The field title
+ */
+ const QString& title() const { return m_title; }
+ /**
+ * Sets the title of the field.
+ *
+ * @param title The field title
+ */
+ void setTitle(const QString& title);
+ /**
+ * Returns the category of the field.
+ *
+ * @return The field category
+ */
+ const QString& category() const { return m_category; }
+ /**
+ * Sets the category of the field.
+ *
+ * @param category The field category
+ */
+ void setCategory(const QString& category);
+ /**
+ * Returns the name of the field.
+ *
+ * @return The field name
+ */
+ const QStringList& allowed() const { return m_allowed; }
+ /**
+ * Sets the allowed values of the field.
+ *
+ * @param allowed The allowed values
+ */
+ void setAllowed(const QStringList& allowed) { m_allowed = allowed; }
+ /**
+ * Add a value to the allowed list
+ *
+ * @param value The value to allow
+ */
+ void addAllowed(const QString& value);
+ /**
+ * Returns the type of the field.
+ *
+ * @return The field type
+ */
+ Type type() const { return m_type; }
+ /**
+ * Sets the type of the field. Be careful with this!
+ *
+ * @param type The field type
+ */
+ void setType(Type type);
+ /**
+ * Returns the flags for the field.
+ *
+ * @return The field flags
+ */
+ int flags() const { return m_flags; }
+ /**
+ * Sets the flags of the field. The value is
+ * set to the argument, so old flags are effectively removed.
+ *
+ * @param flags The field flags
+ */
+ void setFlags(int flags);
+ /**
+ * Returns the formatting flag for the field.
+ *
+ * @return The format flag
+ */
+ FormatFlag formatFlag() const { return m_formatFlag; }
+ /**
+ * Sets the formatting flag of the field.
+ *
+ * @param flag The field flag
+ */
+ void setFormatFlag(FormatFlag flag);
+ /**
+ * Returns the description for the field.
+ *
+ * @return The field description
+ */
+ const QString& description() const { return m_desc; }
+ /**
+ * Sets the description of the field.
+ *
+ * @param desc The field description
+ */
+ void setDescription(const QString& desc) { m_desc = desc; }
+ /**
+ * Returns the default value for the field.
+ *
+ * @return The field default value
+ */
+ const QString& defaultValue() const;
+ /**
+ * Sets the default value of the field.
+ *
+ * @param value The field default value
+ */
+ void setDefaultValue(const QString& value);
+ /**
+ * Some attributes are always a category by themselves.
+ *
+ * @return Whether the field is th eonly member of its category
+ */
+ bool isSingleCategory() const;
+ /**
+ * Extends a field with an additional key and value property pair.
+ *
+ * @param key The property key
+ * @param value The property value
+ */
+ void setProperty(const QString& key, const QString& value);
+ /**
+ * Sets all the extended properties. Any existing ones get erased.
+ *
+ * @param properties The property list
+ */
+ void setPropertyList(const StringMap& properties);
+ /**
+ * Return a property value.
+ *
+ * @param key The property key
+ * @returnThe property value
+ */
+ const QString& property(const QString& key) const { return m_properties[key]; }
+ /**
+ * Return the list of properties.
+ *
+ * @return The property list
+ */
+ const StringMap& propertyList() const { return m_properties; }
+ /**
+ * Return a vector of all the fields on which the value of this field depends.
+ * Returns an empty vector for non-Dpendent fields
+ */
+ FieldVec dependsOn(CollPtr coll) const;
+ QStringList dependsOn() const;
+
+ /*************************** STATIC **********************************/
+
+ /**
+ * A wrapper method around all the format functions. The flags
+ * determine which is called on the string.
+ */
+ static QString format(const QString& value, FormatFlag flag);
+ /**
+ * A convenience function to format a string as a title.
+ * At the moment, this means that some articles such as "the" are placed
+ * at the end of the title. If autoCapitalize() is true, the title is capitalized.
+ *
+ * @param title The string to be formatted
+ */
+ static QString formatTitle(const QString& title);
+ /**
+ * A convenience function to format a string as a personal name.
+ * At the moment, this means that the name is split at the last white space,
+ * and the last name is moved in front. If multiple=true, then the string
+ * is split using a semi-colon (";"), and each string is formatted and then
+ * joined back together. If autoCapitalize() is true, the names are capitalized.
+ *
+ * @param name The string to be formatted
+ * @param multiple A boolean indicating if the string can contain multiple values
+ */
+ static QString formatName(const QString& name, bool multiple=true);
+ /**
+ * A convenience function to format a string as a date.
+ *
+ * @param date The string to be formatted
+ */
+ static QString formatDate(const QString& date);
+ /**
+ * Helper method to fix capitalization.
+ *
+ * @param str String to fix
+ */
+ static QString capitalize(QString str);
+ /**
+ * Return the key to be used for sorting titles
+ */
+ static QString sortKeyTitle(const QString& title);
+ /**
+ * Returns a mapping of the FieldType enum to translated titles for the types.
+ */
+ static FieldMap typeMap();
+ /**
+ * Returns a list of the titles of the field types.
+ */
+ static QStringList typeTitles();
+ /**
+ * Splits a string into multiple values;
+ *
+ * @param string The string to be split
+ */
+ static QStringList split(const QString& string, bool allowEmpty);
+ /**
+ * Returns the delimiter used to split field values
+ *
+ * @return The delimeter regexp
+ */
+ static const QRegExp& delimiter() { return s_delimiter; }
+ /**
+ * reset if the field is a rating field used for syntax version 7 and earlier */
+ static void convertOldRating(Data::FieldPtr field);
+ static void stripArticles(QString& value);
+ static void articlesUpdated();
+
+private:
+ /*
+ * Gets the preferred ID of the collection. Currently, it just gets incremented as
+ * new collections are created.
+ */
+ static long getID();
+
+ long m_id;
+ QString m_name;
+ QString m_title;
+ QString m_category;
+ QString m_desc;
+ Type m_type;
+ QStringList m_allowed;
+ int m_flags;
+ FormatFlag m_formatFlag;
+ StringMap m_properties;
+
+ // need to remember articles with apostrophes for capitalization
+ static QStringList s_articlesApos;
+ static QRegExp s_delimiter;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/fieldcompletion.cpp b/src/fieldcompletion.cpp
new file mode 100644
index 0000000..cfaf894
--- /dev/null
+++ b/src/fieldcompletion.cpp
@@ -0,0 +1,73 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "fieldcompletion.h"
+#include "field.h"
+
+using Tellico::FieldCompletion;
+
+FieldCompletion::FieldCompletion(bool multiple_) : KCompletion(), m_multiple(multiple_) {
+}
+
+QString FieldCompletion::makeCompletion(const QString& string_) {
+ if(completionMode() == KGlobalSettings::CompletionNone) {
+ m_beginText.truncate(0);
+ return QString::null;
+ }
+
+ if(!m_multiple) {
+ return KCompletion::makeCompletion(string_);
+ }
+
+ static QRegExp rx = Data::Field::delimiter();
+ int pos = rx.searchRev(string_);
+ if(pos == -1) {
+ m_beginText.truncate(0);
+ return KCompletion::makeCompletion(string_);
+ }
+
+ pos += rx.matchedLength();
+ QString final = string_.mid(pos);
+ m_beginText = string_.mid(0, pos);
+ return m_beginText + KCompletion::makeCompletion(final);
+}
+
+void FieldCompletion::clear() {
+ m_beginText.truncate(0);
+ KCompletion::clear();
+}
+
+void FieldCompletion::postProcessMatch(QString* match_) const {
+ if(m_multiple) {
+ match_->prepend(m_beginText);
+ }
+}
+
+void FieldCompletion::postProcessMatches(QStringList* matches_) const {
+ if(m_multiple) {
+ for(QStringList::Iterator it = matches_->begin(); it != matches_->end(); ++it) {
+ (*it).prepend(m_beginText);
+ }
+ }
+}
+
+void FieldCompletion::postProcessMatches(KCompletionMatches* matches_) const {
+ if(m_multiple) {
+ for(KCompletionMatches::Iterator it = matches_->begin(); it != matches_->end(); ++it) {
+ (*it).value().prepend(m_beginText);
+ }
+ }
+}
+
+
+#include "fieldcompletion.moc"
diff --git a/src/fieldcompletion.h b/src/fieldcompletion.h
new file mode 100644
index 0000000..14296f3
--- /dev/null
+++ b/src/fieldcompletion.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICOFIELDCOMPLETION_H
+#define TELLICOFIELDCOMPLETION_H
+
+#include <kcompletion.h>
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class FieldCompletion : public KCompletion {
+Q_OBJECT
+
+public:
+ FieldCompletion(bool multiple);
+
+ void setMultiple(bool m) { m_multiple = m; }
+ virtual QString makeCompletion(const QString& string);
+ virtual void clear();
+
+protected:
+ virtual void postProcessMatch(QString* match) const;
+ virtual void postProcessMatches(QStringList* matches) const;
+ virtual void postProcessMatches(KCompletionMatches* matches) const;
+
+private:
+ bool m_multiple;
+ QString m_beginText;
+};
+
+} // end namespace
+#endif
diff --git a/src/filehandler.cpp b/src/filehandler.cpp
new file mode 100644
index 0000000..ce5501a
--- /dev/null
+++ b/src/filehandler.cpp
@@ -0,0 +1,418 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "filehandler.h"
+#include "tellico_kernel.h"
+#include "image.h"
+#include "tellico_strings.h"
+#include "tellico_utils.h"
+#include "tellico_debug.h"
+#include "core/netaccess.h"
+
+#include <kurl.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kio/netaccess.h>
+#include <ktempfile.h>
+#include <ksavefile.h>
+#include <kapplication.h>
+#include <kfileitem.h>
+#include <kio/chmodjob.h>
+#include <kfilterdev.h>
+
+#include <qdom.h>
+#include <qfile.h>
+
+using Tellico::FileHandler;
+
+class FileHandler::ItemDeleter : public QObject {
+public:
+ ItemDeleter(KIO::Job* job, KFileItem* item) : QObject(), m_job(job), m_item(item) {
+ FileHandler::s_deleterList.append(this);
+ connect(job, SIGNAL(result(KIO::Job*)), SLOT(deleteLater()));
+ }
+ ~ItemDeleter() {
+ FileHandler::s_deleterList.removeRef(this);
+ if(m_job) m_job->kill();
+ delete m_item; m_item = 0;
+ }
+private:
+ QGuardedPtr<KIO::Job> m_job;
+ KFileItem* m_item;
+};
+
+QPtrList<FileHandler::ItemDeleter> FileHandler::s_deleterList;
+
+FileHandler::FileRef::FileRef(const KURL& url_, bool quiet_, bool allowCompressed_) : m_device(0), m_isValid(false) {
+ if(url_.isEmpty()) {
+ return;
+ }
+
+ if(!Tellico::NetAccess::download(url_, m_filename, Kernel::self()->widget())) {
+ myDebug() << "FileRef::FileRef() - can't download " << url_ << endl;
+ QString s = KIO::NetAccess::lastErrorString();
+ if(!s.isEmpty()) {
+ myDebug() << s << endl;
+ }
+ if(!quiet_) {
+ Kernel::self()->sorry(i18n(errorLoad).arg(url_.fileName()));
+ }
+ return;
+ }
+
+/*
+ QFile* file = new QFile(m_filename);
+ if(file->exists()) {
+ m_isValid = true;
+ m_device = file;
+ } else {
+ delete file;
+ }
+*/
+ if(allowCompressed_) {
+ m_device = KFilterDev::deviceForFile(m_filename);
+ } else {
+ m_device = new QFile(m_filename);
+ }
+ m_isValid = true;
+}
+
+FileHandler::FileRef::~FileRef() {
+ if(!m_filename.isEmpty()) {
+ Tellico::NetAccess::removeTempFile(m_filename);
+ }
+ if(m_device) {
+ m_device->close();
+ }
+ delete m_device;
+ m_device = 0;
+ m_isValid = false;
+}
+
+bool FileHandler::FileRef::open(bool quiet_) {
+ if(!isValid()) {
+ return false;
+ }
+ if(!m_device || !m_device->open(IO_ReadOnly)) {
+ if(!quiet_) {
+ KURL u;
+ u.setPath(fileName());
+ Kernel::self()->sorry(i18n(errorLoad).arg(u.fileName()));
+ }
+ delete m_device;
+ m_device = 0;
+ m_isValid = false;
+ return false;
+ }
+ return true;
+}
+
+FileHandler::FileRef* FileHandler::fileRef(const KURL& url_, bool quiet_) {
+ return new FileRef(url_, quiet_);
+}
+
+QString FileHandler::readTextFile(const KURL& url_, bool quiet_/*=false*/, bool useUTF8_ /*false*/, bool compress_/*=false*/) {
+ FileRef f(url_, quiet_, compress_);
+ if(!f.isValid()) {
+ return QString::null;
+ }
+
+ if(f.open(quiet_)) {
+ QTextStream stream(f.file());
+ if(useUTF8_) {
+ stream.setEncoding(QTextStream::UnicodeUTF8);
+ }
+ return stream.read();
+ }
+ return QString();
+}
+
+QDomDocument FileHandler::readXMLFile(const KURL& url_, bool processNamespace_, bool quiet_) {
+ FileRef f(url_, quiet_);
+ if(!f.isValid()) {
+ return QDomDocument();
+ }
+
+ QDomDocument doc;
+ QString errorMsg;
+ int errorLine, errorColumn;
+ if(!f.open(quiet_)) {
+ return QDomDocument();
+ }
+ if(!doc.setContent(f.file(), processNamespace_, &errorMsg, &errorLine, &errorColumn)) {
+ if(!quiet_) {
+ QString details = i18n("There is an XML parsing error in line %1, column %2.").arg(errorLine).arg(errorColumn);
+ details += QString::fromLatin1("\n");
+ details += i18n("The error message from Qt is:");
+ details += QString::fromLatin1("\n\t") + errorMsg;
+ GUI::CursorSaver cs(Qt::arrowCursor);
+ KMessageBox::detailedSorry(Kernel::self()->widget(), i18n(errorLoad).arg(url_.fileName()), details);
+ }
+ return QDomDocument();
+ }
+ return doc;
+}
+
+QByteArray FileHandler::readDataFile(const KURL& url_, bool quiet_) {
+ FileRef f(url_, quiet_);
+ if(!f.isValid()) {
+ return QByteArray();
+ }
+
+ f.open(quiet_);
+ return f.file()->readAll();
+}
+
+Tellico::Data::Image* FileHandler::readImageFile(const KURL& url_, bool quiet_, const KURL& referrer_) {
+ if(url_.isLocalFile()) {
+ return readImageFile(url_, quiet_);
+ }
+
+ KTempFile tmpFile;
+ KURL tmpURL;
+ tmpURL.setPath(tmpFile.name());
+ tmpFile.setAutoDelete(true);
+
+ KIO::Job* job = KIO::file_copy(url_, tmpURL, -1, true /* overwrite */);
+ job->addMetaData(QString::fromLatin1("referrer"), referrer_.url());
+
+ if(!KIO::NetAccess::synchronousRun(job, Kernel::self()->widget())) {
+ if(!quiet_) {
+ Kernel::self()->sorry(i18n(errorLoad).arg(url_.fileName()));
+ }
+ return 0;
+ }
+ return readImageFile(tmpURL, quiet_);
+}
+
+Tellico::Data::Image* FileHandler::readImageFile(const KURL& url_, bool quiet_) {
+ FileRef f(url_, quiet_);
+ if(!f.isValid()) {
+ return 0;
+ }
+
+ Data::Image* img = new Data::Image(f.fileName());
+ if(img->isNull() && !quiet_) {
+ QString str = i18n("Tellico is unable to load the image - %1.").arg(url_.fileName());
+ Kernel::self()->sorry(str);
+ }
+ return img;
+}
+
+bool FileHandler::queryExists(const KURL& url_) {
+ if(url_.isEmpty() || !KIO::NetAccess::exists(url_, false, Kernel::self()->widget())) {
+ return true;
+ }
+
+ // we always overwrite the current URL without asking
+ if(url_ != Kernel::self()->URL()) {
+ GUI::CursorSaver cs(Qt::arrowCursor);
+ QString str = i18n("A file named \"%1\" already exists. "
+ "Are you sure you want to overwrite it?").arg(url_.fileName());
+ int want_continue = KMessageBox::warningContinueCancel(Kernel::self()->widget(), str,
+ i18n("Overwrite File?"),
+ i18n("Overwrite"));
+
+ if(want_continue == KMessageBox::Cancel) {
+ return false;
+ }
+ }
+
+ KURL backup(url_);
+ backup.setPath(backup.path() + QString::fromLatin1("~"));
+
+ bool success = true;
+ if(url_.isLocalFile()) {
+ // KSaveFile messes up users and groups
+ // the user is always reset to the current user
+ KFileItemList list;
+ int perm = -1;
+ QString grp;
+ if(KIO::NetAccess::exists(url_, false, Kernel::self()->widget())) {
+ KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url_, true);
+ perm = item.permissions();
+ grp = item.group();
+
+ KFileItem* backupItem = new KFileItem(KFileItem::Unknown, KFileItem::Unknown, backup, true);
+ list.append(backupItem);
+ }
+
+ success = KSaveFile::backupFile(url_.path());
+ if(!list.isEmpty()) {
+ // have to leave the user alone
+ KIO::Job* job = KIO::chmod(list, perm, 0, QString(), grp, true, false);
+ new ItemDeleter(job, list.first());
+ }
+ } else {
+ KIO::NetAccess::del(backup, Kernel::self()->widget()); // might fail if backup doesn't exist, that's ok
+ success = KIO::NetAccess::file_copy(url_, backup, -1 /* permissions */, true /* overwrite */,
+ false /* resume */, Kernel::self()->widget());
+ }
+ if(!success) {
+ Kernel::self()->sorry(i18n(errorWrite).arg(url_.fileName() + '~'));
+ }
+ return success;
+}
+
+bool FileHandler::writeTextURL(const KURL& url_, const QString& text_, bool encodeUTF8_, bool force_, bool quiet_) {
+ if((!force_ && !queryExists(url_)) || text_.isNull()) {
+ if(text_.isNull()) {
+ myDebug() << "FileHandler::writeTextURL() - null string for " << url_ << endl;
+ }
+ return false;
+ }
+
+ if(url_.isLocalFile()) {
+ // KSaveFile messes up users and groups
+ // the user is always reset to the current user
+ KFileItemList list;
+ int perm = -1;
+ QString grp;
+ if(KIO::NetAccess::exists(url_, false, Kernel::self()->widget())) {
+ KFileItem* item = new KFileItem(KFileItem::Unknown, KFileItem::Unknown, url_, true);
+ list.append(item);
+ perm = item->permissions();
+ grp = item->group();
+ }
+
+ KSaveFile f(url_.path());
+ if(f.status() != 0) {
+ if(!quiet_) {
+ Kernel::self()->sorry(i18n(errorWrite).arg(url_.fileName()));
+ }
+ return false;
+ }
+ bool success = FileHandler::writeTextFile(f, text_, encodeUTF8_);
+ if(!list.isEmpty()) {
+ // have to leave the user alone
+ KIO::Job* job = KIO::chmod(list, perm, 0, QString(), grp, true, false);
+ new ItemDeleter(job, list.first());
+ }
+ return success;
+ }
+
+ // save to remote file
+ KTempFile tempfile;
+ KSaveFile f(tempfile.name());
+ if(f.status() != 0) {
+ tempfile.unlink();
+ if(!quiet_) {
+ Kernel::self()->sorry(i18n(errorWrite).arg(url_.fileName()));
+ }
+ return false;
+ }
+
+ bool success = FileHandler::writeTextFile(f, text_, encodeUTF8_);
+ if(success) {
+ bool uploaded = KIO::NetAccess::upload(tempfile.name(), url_, Kernel::self()->widget());
+ if(!uploaded) {
+ tempfile.unlink();
+ if(!quiet_) {
+ Kernel::self()->sorry(i18n(errorUpload).arg(url_.fileName()));
+ }
+ success = false;
+ }
+ }
+ tempfile.unlink();
+
+ return success;
+}
+
+bool FileHandler::writeTextFile(KSaveFile& f_, const QString& text_, bool encodeUTF8_) {
+ QTextStream* t = f_.textStream();
+ if(encodeUTF8_) {
+ t->setEncoding(QTextStream::UnicodeUTF8);
+ } else {
+ t->setEncoding(QTextStream::Locale);
+ }
+// kdDebug() << "-----------------------------" << endl
+// << text_ << endl
+// << "-----------------------------" << endl;
+ (*t) << text_;
+ bool success = f_.close();
+#ifndef NDEBUG
+ if(!success) {
+ myDebug() << "FileHandler::writeTextFile() - status = " << f_.status();
+ }
+#endif
+ return success;
+}
+
+bool FileHandler::writeDataURL(const KURL& url_, const QByteArray& data_, bool force_, bool quiet_) {
+ if(!force_ && !queryExists(url_)) {
+ return false;
+ }
+
+ if(url_.isLocalFile()) {
+ // KSaveFile messes up users and groups
+ // the user is always reset to the current user
+ KFileItemList list;
+ int perm = -1;
+ QString grp;
+ if(KIO::NetAccess::exists(url_, false, Kernel::self()->widget())) {
+ KFileItem* item = new KFileItem(KFileItem::Unknown, KFileItem::Unknown, url_, true);
+ list.append(item);
+ perm = item->permissions();
+ grp = item->group();
+ }
+
+ KSaveFile f(url_.path());
+ if(f.status() != 0) {
+ if(!quiet_) {
+ Kernel::self()->sorry(i18n(errorWrite).arg(url_.fileName()));
+ }
+ return false;
+ }
+ bool success = FileHandler::writeDataFile(f, data_);
+ if(!list.isEmpty()) {
+ // have to leave the user alone
+ KIO::Job* job = KIO::chmod(list, perm, 0, QString(), grp, true, false);
+ new ItemDeleter(job, list.first());
+ }
+ return success;
+ }
+
+ // save to remote file
+ KTempFile tempfile;
+ KSaveFile f(tempfile.name());
+ if(f.status() != 0) {
+ if(!quiet_) {
+ Kernel::self()->sorry(i18n(errorWrite).arg(url_.fileName()));
+ }
+ return false;
+ }
+
+ bool success = FileHandler::writeDataFile(f, data_);
+ if(success) {
+ success = KIO::NetAccess::upload(tempfile.name(), url_, Kernel::self()->widget());
+ if(!success && !quiet_) {
+ Kernel::self()->sorry(i18n(errorUpload).arg(url_.fileName()));
+ }
+ }
+ tempfile.unlink();
+
+ return success;
+}
+
+bool FileHandler::writeDataFile(KSaveFile& f_, const QByteArray& data_) {
+// myDebug() << "FileHandler::writeDataFile()" << endl;
+ QDataStream* s = f_.dataStream();
+ s->writeRawBytes(data_.data(), data_.size());
+ return f_.close();
+}
+
+void FileHandler::clean() {
+ s_deleterList.setAutoDelete(true);
+ s_deleterList.clear();
+ s_deleterList.setAutoDelete(false);
+}
diff --git a/src/filehandler.h b/src/filehandler.h
new file mode 100644
index 0000000..9000478
--- /dev/null
+++ b/src/filehandler.h
@@ -0,0 +1,171 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef FILEHANDLER_H
+#define FILEHANDLER_H
+
+#include <qstring.h>
+#include <qcstring.h> // needed for QByteArray
+#include <qptrlist.h>
+
+class KURL;
+class KSaveFile;
+class KFileItem;
+namespace KIO {
+ class Job;
+}
+
+class QDomDocument;
+class QIODevice;
+
+namespace Tellico {
+ class ImageFactory;
+ namespace Data {
+ class Image;
+ }
+
+/**
+ * The FileHandler class contains some utility functions for reading files.
+ *
+ * @author Robby Stephenson
+ */
+class FileHandler {
+
+friend class ImageFactory;
+
+public:
+ /**
+ * An internal class to handle KIO stuff. Exposed so a FileRef pointer
+ * can be returned from FileHandler.
+ */
+ class FileRef {
+ public:
+ bool open(bool quiet=false);
+ QIODevice* file() const { return m_device; }
+ const QString& fileName() const { return m_filename; }
+ bool isValid() const { return m_isValid; }
+ ~FileRef();
+
+ private:
+ friend class FileHandler;
+ FileRef(const KURL& url, bool quiet=false, bool allowCompressed=false);
+ QIODevice* m_device;
+ QString m_filename;
+ bool m_isValid;
+ };
+ friend class FileRef;
+
+ /**
+ * Creates a FileRef for a given url. It's not meant to be used by methods in the class,
+ * Rather by a class wanting direct access to a file. The caller takes ownership of the pointer.
+ *
+ * @param url The url
+ * @param quiet Whether error messages should be shown
+ * @return The fileref
+ */
+ static FileRef* fileRef(const KURL& url, bool quiet=false);
+ /**
+ * Read contents of a file into a string.
+ *
+ * @param url The URL of the file
+ * @param quiet whether the importer should report errors or not
+ * @param useUTF8 Whether the file should be read as UTF8 or use user locale
+ * @param allowCompressed Whether to check if the file is compressed or not
+ * @return A string containing the contents of a file
+ */
+ static QString readTextFile(const KURL& url, bool quiet=false, bool useUTF8=false, bool allowCompressed=false);
+ /**
+ * Read contents of an XML file into a QDomDocument.
+ *
+ * @param url The URL of the file
+ * @param processNamespace Whether to process the namespace of the XML file
+ * @param quiet Whether error messages should be shown
+ * @return A QDomDocument containing the contents of a file
+ */
+ static QDomDocument readXMLFile(const KURL& url, bool processNamespace, bool quiet=false);
+ /**
+ * Read contents of a data file into a QByteArray.
+ *
+ * @param url The URL of the file
+ * @param quiet Whether error messages should be shown
+ * @return A QByteArray of the file's contents
+ */
+ static QByteArray readDataFile(const KURL& url, bool quiet=false);
+ /**
+ * Writes the contents of a string to a url. If the file already exists, a "~" is appended
+ * and the existing file is moved. If the file is remote, a temporary file is written and
+ * then uploaded.
+ *
+ * @param url The url
+ * @param text The text
+ * @param encodeUTF8 Whether to use UTF-8 encoding, or Locale
+ * @param force Whether to force the write
+ * @return A boolean indicating success
+ */
+ static bool writeTextURL(const KURL& url, const QString& text, bool encodeUTF8, bool force=false, bool quiet=false);
+ /**
+ * Writes data to a url. If the file already exists, a "~" is appended
+ * and the existing file is moved. If the file is remote, a temporary file is written and
+ * then uploaded.
+ *
+ * @param url The url
+ * @param data The data
+ * @param force Whether to force the write
+ * @return A boolean indicating success
+ */
+ static bool writeDataURL(const KURL& url, const QByteArray& data, bool force=false, bool quiet=false);
+ /**
+ * Checks to see if a URL exists already, and if so, queries the user.
+ *
+ * @param url The target URL
+ * @return True if it is ok to continue, false otherwise.
+ */
+ static bool queryExists(const KURL& url);
+ static void clean();
+
+private:
+ class ItemDeleter;
+ friend class ItemDeleter;
+ static QPtrList<ItemDeleter> s_deleterList;
+
+ /**
+ * Read contents of a file into an image. It's private since everything should use the
+ * ImageFactory methods.
+ *
+ * @param url The URL of the file
+ * @param quiet If errors should be quiet
+ * @return The image
+ */
+ static Data::Image* readImageFile(const KURL& url, bool quiet=false);
+ static Data::Image* readImageFile(const KURL& url, bool quiet, const KURL& referrer);
+ /**
+ * Writes the contents of a string to a file.
+ *
+ * @param file The file object
+ * @param text The string
+ * @param encodeUTF8 Whether to use UTF-8 encoding, or Locale
+ * @return A boolean indicating success
+ */
+ static bool writeTextFile(KSaveFile& file, const QString& text, bool encodeUTF8);
+ /**
+ * Writes data to a file.
+ *
+ * @param file The file object
+ * @param data The data
+ * @return A boolean indicating success
+ */
+ static bool writeDataFile(KSaveFile& file, const QByteArray& data);
+};
+
+} // end namespace
+#endif
diff --git a/src/filter.cpp b/src/filter.cpp
new file mode 100644
index 0000000..9672937
--- /dev/null
+++ b/src/filter.cpp
@@ -0,0 +1,137 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "filter.h"
+#include "entry.h"
+
+#include "tellico_debug.h"
+
+#include <qregexp.h>
+
+using Tellico::Filter;
+using Tellico::FilterRule;
+
+FilterRule::FilterRule() : m_function(FuncEquals) {
+}
+
+FilterRule::FilterRule(const QString& fieldName_, const QString& pattern_, Function func_)
+ : m_fieldName(fieldName_), m_function(func_), m_pattern(pattern_) {
+}
+
+bool FilterRule::matches(Data::EntryPtr entry_) const {
+ switch (m_function) {
+ case FuncEquals:
+ return equals(entry_);
+ case FuncNotEquals:
+ return !equals(entry_);
+ case FuncContains:
+ return contains(entry_);
+ case FuncNotContains:
+ return !contains(entry_);
+ case FuncRegExp:
+ return matchesRegExp(entry_);
+ case FuncNotRegExp:
+ return !matchesRegExp(entry_);
+ default:
+ kdWarning() << "FilterRule::matches() - invalid function!" << endl;
+ break;
+ }
+ return true;
+}
+
+bool FilterRule::equals(Data::EntryPtr entry_) const {
+ // empty field name means search all
+ if(m_fieldName.isEmpty()) {
+ QStringList list = entry_->fieldValues() + entry_->formattedFieldValues();
+ for(QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) {
+ if(QString::compare((*it).lower(), m_pattern.lower()) == 0) {
+ return true;
+ }
+ }
+ } else {
+ return QString::compare(entry_->field(m_fieldName).lower(), m_pattern.lower()) == 0
+ || QString::compare(entry_->formattedField(m_fieldName).lower(), m_pattern.lower()) == 0;
+ }
+
+ return false;
+}
+
+bool FilterRule::contains(Data::EntryPtr entry_) const {
+ // empty field name means search all
+ if(m_fieldName.isEmpty()) {
+ QStringList list = entry_->fieldValues() + entry_->formattedFieldValues();
+ // match is true if any strings match
+ for(QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) {
+ if((*it).find(m_pattern, 0, false) >= 0) {
+ return true;
+ }
+ }
+ } else {
+ return entry_->field(m_fieldName).find(m_pattern, 0, false) >= 0
+ || entry_->formattedField(m_fieldName).find(m_pattern, 0, false) >= 0;
+ }
+
+ return false;
+}
+
+bool FilterRule::matchesRegExp(Data::EntryPtr entry_) const {
+ QRegExp rx(m_pattern, false);
+ // empty field name means search all
+ if(m_fieldName.isEmpty()) {
+ QStringList list = entry_->fieldValues() + entry_->formattedFieldValues();
+ for(QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) {
+ if((*it).find(rx) >= 0) {
+ return true;
+ break;
+ }
+ }
+ } else {
+ return entry_->field(m_fieldName).find(rx) >= 0
+ || entry_->formattedField(m_fieldName).find(rx) >= 0;
+ }
+
+ return false;
+}
+
+
+/*******************************************************/
+
+Filter::Filter(const Filter& other_) : QPtrList<FilterRule>(), KShared(), m_op(other_.op()), m_name(other_.name()) {
+ for(QPtrListIterator<FilterRule> it(other_); it.current(); ++it) {
+ append(new FilterRule(*it.current()));
+ }
+ setAutoDelete(true);
+}
+
+bool Filter::matches(Data::EntryPtr entry_) const {
+ if(isEmpty()) {
+ return true;
+ }
+
+ bool match = false;
+ for(QPtrListIterator<FilterRule> it(*this); it.current(); ++it) {
+ if(it.current()->matches(entry_)) {
+ if(m_op == Filter::MatchAny) {
+ return true;
+ } else {
+ match = true;
+ }
+ } else {
+ if(m_op == Filter::MatchAll) {
+ return false;
+ }
+ }
+ }
+
+ return match;
+}
diff --git a/src/filter.h b/src/filter.h
new file mode 100644
index 0000000..57997bf
--- /dev/null
+++ b/src/filter.h
@@ -0,0 +1,130 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FILTER_H
+#define TELLICO_FILTER_H
+
+#include "datavectors.h"
+
+#include <ksharedptr.h>
+
+#include <qptrlist.h>
+#include <qstring.h>
+
+namespace Tellico {
+ namespace Data {
+ class Entry;
+ }
+
+/**
+ * @author Robby Stephenson
+ */
+class FilterRule {
+
+public:
+ /**
+ * Operators for comparison of field and contents.
+ * If you change the order or contents of the enum: do not forget
+ * to change matches() and @ref FilterRuleWidget::initLists(), too.
+ */
+ enum Function {
+ FuncContains=0, FuncNotContains,
+ FuncEquals, FuncNotEquals,
+ FuncRegExp, FuncNotRegExp
+ };
+
+ FilterRule();
+ FilterRule(const QString& fieldName, const QString& text, Function func);
+
+ /**
+ * A rule is empty if the pattern text is empty
+ */
+ bool isEmpty() const { return m_pattern.isEmpty(); }
+ /**
+ * This is the primary function of the rule.
+ *
+ * @return Returns true if the entry is matched by the rule.
+ */
+ bool matches(Data::EntryPtr entry) const;
+
+ /**
+ * Return filter function. This can be any of the operators
+ * defined in @ref Function.
+ */
+ Function function() const { return m_function; }
+ /**
+ * Set filter function.
+ */
+ void setFunction(Function func) { m_function = func; }
+ /**
+ * Return field name
+ */
+ const QString& fieldName() const { return m_fieldName; }
+ /**
+ * Set field name
+ */
+ void setFieldName(const QString& fieldName) { m_fieldName = fieldName; }
+ /**
+ * Return pattern
+ */
+ const QString& pattern() const { return m_pattern; }
+ /**
+ * Set pattern
+ */
+// void setPattern(const QString& pattern) { m_pattern = pattern; }
+
+private:
+ bool equals(Data::EntryPtr entry) const;
+ bool contains(Data::EntryPtr entry) const;
+ bool matchesRegExp(Data::EntryPtr entry) const;
+
+ QString m_fieldName;
+ Function m_function;
+ QString m_pattern;
+};
+
+/**
+ * Borrows from KMSearchPattern by Marc Mutz
+ *
+ * @author Robby Stephenson
+ */
+class Filter : public QPtrList<FilterRule>, public KShared {
+
+public:
+ enum FilterOp {
+ MatchAny,
+ MatchAll
+ };
+ typedef KSharedPtr<Filter> Ptr;
+
+ Filter(FilterOp op) : QPtrList<FilterRule>(), m_op(op) { setAutoDelete(true); }
+ Filter(const Filter& other);
+
+ void setMatch(FilterOp op) { m_op = op; }
+ FilterOp op() const { return m_op; }
+ bool matches(Data::EntryPtr entry) const;
+
+ void setName(const QString& name) { m_name = name; }
+ const QString& name() const { return m_name; }
+
+ uint count() const { return QPtrList<FilterRule>::count(); } // disambiguate
+
+private:
+ Filter& operator=(const Filter& other);
+
+ FilterOp m_op;
+ QString m_name;
+};
+
+} // end namespace
+#endif
diff --git a/src/filterdialog.cpp b/src/filterdialog.cpp
new file mode 100644
index 0000000..ab65490
--- /dev/null
+++ b/src/filterdialog.cpp
@@ -0,0 +1,428 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+// The layout borrows heavily from kmsearchpatternedit.cpp in kmail
+// which is authored by Marc Mutz <Marc@Mutz.com> under the GPL
+
+#include "filterdialog.h"
+#include "tellico_kernel.h"
+#include "document.h"
+#include "collection.h"
+#include "fieldcompletion.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+#include <kcombobox.h>
+#include <klineedit.h>
+#include <kpushbutton.h>
+#include <kparts/componentfactory.h>
+#include <kregexpeditorinterface.h>
+#include <kiconloader.h>
+
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qradiobutton.h>
+#include <qvbuttongroup.h>
+#include <qhbox.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qapplication.h>
+
+using Tellico::FilterRuleWidget;
+using Tellico::FilterRuleWidgetLister;
+using Tellico::FilterDialog;
+
+FilterRuleWidget::FilterRuleWidget(FilterRule* rule_, QWidget* parent_, const char* name_/*=0*/)
+ : QHBox(parent_, name_), m_editRegExp(0), m_editRegExpDialog(0) {
+ initLists();
+ initWidget();
+
+ if(rule_) {
+ setRule(rule_);
+ } else {
+ reset();
+ }
+}
+
+void FilterRuleWidget::initLists() {
+ //---------- initialize list of filter fields
+ if(m_ruleFieldList.isEmpty()) {
+ m_ruleFieldList.append('<' + i18n("Any Field") + '>');
+ m_ruleFieldList += Kernel::self()->fieldTitles();
+ }
+
+ //---------- initialize list of filter operators
+ if(m_ruleFuncList.isEmpty()) {
+ // also see FilterRule::matches() and FilterRule::Function
+ // if you change the following strings!
+ m_ruleFuncList.append(i18n("contains"));
+ m_ruleFuncList.append(i18n("does not contain"));
+ m_ruleFuncList.append(i18n("equals"));
+ m_ruleFuncList.append(i18n("does not equal"));
+ m_ruleFuncList.append(i18n("matches regexp"));
+ m_ruleFuncList.append(i18n("does not match regexp"));
+ }
+}
+
+void FilterRuleWidget::initWidget() {
+ setSpacing(4);
+
+ m_ruleField = new KComboBox(this);
+ connect(m_ruleField, SIGNAL(activated(int)), SIGNAL(signalModified()));
+ connect(m_ruleField, SIGNAL(activated(int)), SLOT(slotRuleFieldChanged(int)));
+
+ m_ruleFunc = new KComboBox(this);
+ connect(m_ruleFunc, SIGNAL(activated(int)), SIGNAL(signalModified()));
+ m_ruleValue = new KLineEdit(this);
+ connect(m_ruleValue, SIGNAL(textChanged(const QString&)), SIGNAL(signalModified()));
+
+ if(!KTrader::self()->query(QString::fromLatin1("KRegExpEditor/KRegExpEditor")).isEmpty()) {
+ m_editRegExp = new KPushButton(i18n("Edit..."), this);
+ connect(m_editRegExp, SIGNAL(clicked()), this, SLOT(slotEditRegExp()));
+ connect(m_ruleFunc, SIGNAL(activated(int)), this, SLOT(slotRuleFunctionChanged(int)));
+ slotRuleFunctionChanged(m_ruleFunc->currentItem());
+ }
+
+ m_ruleField->insertStringList(m_ruleFieldList);
+ // don't show sliders when popping up this menu
+// m_ruleField->setSizeLimit(m_ruleField->count());
+// m_ruleField->adjustSize();
+
+ m_ruleFunc->insertStringList(m_ruleFuncList);
+// m_ruleFunc->adjustSize();
+
+// connect(m_ruleField, SIGNAL(textChanged(const QString &)),
+// this, SIGNAL(fieldChanged(const QString &)));
+// connect(m_ruleValue, SIGNAL(textChanged(const QString &)),
+// this, SIGNAL(contentsChanged(const QString &)));
+}
+
+void FilterRuleWidget::slotEditRegExp() {
+ if(m_editRegExpDialog == 0) {
+ m_editRegExpDialog = KParts::ComponentFactory::createInstanceFromQuery<QDialog>(QString::fromLatin1("KRegExpEditor/KRegExpEditor"),
+ QString::null, this);
+ }
+
+ KRegExpEditorInterface* iface = static_cast<KRegExpEditorInterface *>(m_editRegExpDialog->qt_cast(QString::fromLatin1("KRegExpEditorInterface")));
+ if(iface) {
+ iface->setRegExp(m_ruleValue->text());
+ if(m_editRegExpDialog->exec() == QDialog::Accepted) {
+ m_ruleValue->setText(iface->regExp());
+ }
+ }
+}
+
+void FilterRuleWidget::slotRuleFieldChanged(int which_) {
+ Q_UNUSED(which_);
+ QString fieldTitle = m_ruleField->currentText();
+ if(fieldTitle.isEmpty() || fieldTitle[0] == '<') {
+ m_ruleValue->setCompletionObject(0);
+ return;
+ }
+ Data::FieldPtr field = Data::Document::self()->collection()->fieldByTitle(fieldTitle);
+ if(field && (field->flags() & Data::Field::AllowCompletion)) {
+ FieldCompletion* completion = new FieldCompletion(field->flags() & Data::Field::AllowMultiple);
+ completion->setItems(Kernel::self()->valuesByFieldName(field->name()));
+ completion->setIgnoreCase(true);
+ m_ruleValue->setCompletionObject(completion);
+ m_ruleValue->setAutoDeleteCompletionObject(true);
+ } else {
+ m_ruleValue->setCompletionObject(0);
+ }
+}
+
+void FilterRuleWidget::slotRuleFunctionChanged(int which_) {
+ // The 5th and 6th functions are for regexps
+ m_editRegExp->setEnabled(which_ == 4 || which_ == 5);
+}
+
+void FilterRuleWidget::setRule(const FilterRule* rule_) {
+ if(!rule_) {
+ reset();
+ return;
+ }
+
+ blockSignals(true);
+
+ if(rule_->fieldName().isEmpty()) {
+ m_ruleField->setCurrentItem(0); // "All Fields"
+ } else {
+ m_ruleField->setCurrentText(Kernel::self()->fieldTitleByName(rule_->fieldName()));
+ }
+
+ //--------------set function and contents
+ m_ruleFunc->setCurrentItem(static_cast<int>(rule_->function()));
+ m_ruleValue->setText(rule_->pattern());
+
+ if(m_editRegExp) {
+ slotRuleFunctionChanged(static_cast<int>(rule_->function()));
+ }
+
+ blockSignals(false);
+}
+
+Tellico::FilterRule* FilterRuleWidget::rule() const {
+ QString field; // empty string
+ if(m_ruleField->currentItem() > 0) { // 0 is "All Fields", field is empty
+ field = Kernel::self()->fieldNameByTitle(m_ruleField->currentText());
+ }
+
+ return new FilterRule(field, m_ruleValue->text().stripWhiteSpace(),
+ static_cast<FilterRule::Function>(m_ruleFunc->currentItem()));
+}
+
+void FilterRuleWidget::reset() {
+// kdDebug() << "FilterRuleWidget::reset()" << endl;
+ blockSignals(true);
+
+ m_ruleField->setCurrentItem(0);
+ m_ruleFunc->setCurrentItem(0);
+ m_ruleValue->clear();
+
+ if(m_editRegExp) {
+ m_editRegExp->setEnabled(false);
+ }
+
+ blockSignals(false);
+}
+
+void FilterRuleWidget::setFocus() {
+ m_ruleValue->setFocus();
+}
+
+/***************************************************************/
+
+namespace {
+ static const int FILTER_MIN_RULE_WIDGETS = 1;
+ static const int FILTER_MAX_RULES = 8;
+}
+
+FilterRuleWidgetLister::FilterRuleWidgetLister(QWidget* parent_, const char* name_)
+ : KWidgetLister(FILTER_MIN_RULE_WIDGETS, FILTER_MAX_RULES, parent_, name_) {
+// slotClear();
+}
+
+void FilterRuleWidgetLister::setFilter(Filter::Ptr filter_) {
+// if(mWidgetList.first()) { // move this below next 'if'?
+// mWidgetList.first()->blockSignals(true);
+// }
+
+ if(filter_->isEmpty()) {
+ slotClear();
+// mWidgetList.first()->blockSignals(false);
+ return;
+ }
+
+ const int count = static_cast<int>(filter_->count());
+ if(count > mMaxWidgets) {
+ myDebug() << "FilterRuleWidgetLister::setFilter() - more rules than allowed!" << endl;
+ }
+
+ // set the right number of widgets
+ setNumberOfShownWidgetsTo(QMAX(count, mMinWidgets));
+
+ // load the actions into the widgets
+ QPtrListIterator<QWidget> wIt(mWidgetList);
+ for(QPtrListIterator<FilterRule> rIt(*filter_); rIt.current() && wIt.current(); ++rIt, ++wIt) {
+ static_cast<FilterRuleWidget*>(*wIt)->setRule(*rIt);
+ }
+ for( ; wIt.current(); ++wIt) { // clear any remaining
+ static_cast<FilterRuleWidget*>(*wIt)->reset();
+ }
+
+// mWidgetList.first()->blockSignals(false);
+}
+
+void FilterRuleWidgetLister::reset() {
+ slotClear();
+}
+
+void FilterRuleWidgetLister::setFocus() {
+ if(!mWidgetList.isEmpty()) {
+ mWidgetList.getFirst()->setFocus();
+ }
+}
+
+QWidget* FilterRuleWidgetLister::createWidget(QWidget* parent_) {
+ QWidget* w = new FilterRuleWidget(static_cast<Tellico::FilterRule*>(0), parent_);
+ connect(w, SIGNAL(signalModified()), SIGNAL(signalModified()));
+ return w;
+}
+
+void FilterRuleWidgetLister::clearWidget(QWidget* widget_) {
+ if(widget_) {
+ static_cast<FilterRuleWidget*>(widget_)->reset();
+ }
+}
+
+const QPtrList<QWidget>& FilterRuleWidgetLister::widgetList() const {
+ return mWidgetList;
+}
+
+/***************************************************************/
+
+namespace {
+ static const int FILTER_MIN_WIDTH = 600;
+}
+
+// modal dialog so I don't have to worry about updating stuff
+// don't show apply button if not saving, i.e. just modifying existing filter
+FilterDialog::FilterDialog(Mode mode_, QWidget* parent_, const char* name_/*=0*/)
+ : KDialogBase(parent_, name_, true,
+ (mode_ == CreateFilter ? i18n("Advanced Filter") : i18n("Modify Filter")),
+ (mode_ == CreateFilter ? Help|Ok|Apply|Cancel : Help|Ok|Cancel),
+ Ok, false),
+ m_filter(0), m_mode(mode_), m_saveFilter(0) {
+ init();
+}
+
+void FilterDialog::init() {
+ QWidget* page = new QWidget(this);
+ setMainWidget(page);
+ QVBoxLayout* topLayout = new QVBoxLayout(page, 0, KDialog::spacingHint());
+
+ QGroupBox* m_matchGroup = new QGroupBox(1, Qt::Horizontal, i18n("Filter Criteria"), page);
+ topLayout->addWidget(m_matchGroup);
+
+ QVButtonGroup* bg = new QVButtonGroup(m_matchGroup);
+ bg->setFrameShape(QFrame::NoFrame);
+ bg->setInsideMargin(0);
+ m_matchAll = new QRadioButton(i18n("Match a&ll of the following"), bg);
+ m_matchAny = new QRadioButton(i18n("Match an&y of the following"), bg);
+ m_matchAll->setChecked(true);
+ connect(bg, SIGNAL(clicked(int)), SLOT(slotFilterChanged()));
+
+ m_ruleLister = new FilterRuleWidgetLister(m_matchGroup);
+ connect(m_ruleLister, SIGNAL(widgetRemoved()), SLOT(slotShrink()));
+ connect(m_ruleLister, SIGNAL(signalModified()), SLOT(slotFilterChanged()));
+ m_ruleLister->setFocus();
+
+ QHBoxLayout* blay = new QHBoxLayout(topLayout);
+ blay->addWidget(new QLabel(i18n("Filter name:"), page));
+
+ m_filterName = new KLineEdit(page);
+ blay->addWidget(m_filterName);
+ connect(m_filterName, SIGNAL(textChanged(const QString&)), SLOT(slotFilterChanged()));
+
+ // only when creating a new filter can it be saved
+ if(m_mode == CreateFilter) {
+ m_saveFilter = new KPushButton(SmallIconSet(QString::fromLatin1("filter")), i18n("&Save Filter"), page);
+ blay->addWidget(m_saveFilter);
+ m_saveFilter->setEnabled(false);
+ connect(m_saveFilter, SIGNAL(clicked()), SLOT(slotSaveFilter()));
+ enableButtonApply(false);
+ }
+ enableButtonOK(false); // disable at start
+ actionButton(Help)->setDefault(false); // Help automatically becomes default when OK is disabled
+ actionButton(Cancel)->setDefault(true); // Help automatically becomes default when OK is disabled
+ setMinimumWidth(QMAX(minimumWidth(), FILTER_MIN_WIDTH));
+ setHelp(QString::fromLatin1("filter-dialog"));
+}
+
+Tellico::FilterPtr FilterDialog::currentFilter() {
+ if(!m_filter) {
+ m_filter = new Filter(Filter::MatchAny);
+ }
+
+ if(m_matchAll->isChecked()) {
+ m_filter->setMatch(Filter::MatchAll);
+ } else {
+ m_filter->setMatch(Filter::MatchAny);
+ }
+
+ m_filter->clear(); // deletes all old rules
+ for(QPtrListIterator<QWidget> it(m_ruleLister->widgetList()); it.current(); ++it) {
+ FilterRuleWidget* rw = static_cast<FilterRuleWidget*>(it.current());
+ FilterRule* rule = rw->rule();
+ if(rule && !rule->isEmpty()) {
+ m_filter->append(rule);
+ }
+ }
+ // only set name if it has rules
+ if(!m_filter->isEmpty()) {
+ m_filter->setName(m_filterName->text());
+ }
+ return m_filter;
+}
+
+void FilterDialog::setFilter(FilterPtr filter_) {
+ if(!filter_) {
+ slotClear();
+ return;
+ }
+
+ if(filter_->op() == Filter::MatchAll) {
+ m_matchAll->setChecked(true);
+ } else {
+ m_matchAny->setChecked(true);
+ }
+
+ m_ruleLister->setFilter(filter_);
+ m_filterName->setText(filter_->name());
+ m_filter = filter_;
+}
+
+void FilterDialog::slotOk() {
+ slotApply();
+ accept();
+}
+
+void FilterDialog::slotApply() {
+ emit signalUpdateFilter(currentFilter());
+}
+
+void FilterDialog::slotClear() {
+// kdDebug() << "FilterDialog::slotClear()" << endl;
+ m_matchAll->setChecked(true);
+ m_ruleLister->reset();
+ m_filterName->clear();
+}
+
+void FilterDialog::slotShrink() {
+ updateGeometry();
+ QApplication::sendPostedEvents();
+ resize(width(), sizeHint().height());
+}
+
+void FilterDialog::slotFilterChanged() {
+ bool emptyFilter = currentFilter()->isEmpty();
+ if(m_saveFilter) {
+ m_saveFilter->setEnabled(!m_filterName->text().isEmpty() && !emptyFilter);
+ enableButtonApply(!emptyFilter);
+ }
+ enableButtonOK(!emptyFilter);
+ actionButton(Ok)->setDefault(!emptyFilter);
+}
+
+void FilterDialog::slotSaveFilter() {
+ // non-op if editing an existing filter
+ if(m_mode != CreateFilter) {
+ return;
+ }
+
+ // in this case, currentFilter() either creates a new filter or
+ // updates the current one. If creating a new one, then I want to copy it
+ bool wasEmpty = (m_filter == 0);
+ FilterPtr filter = new Filter(*currentFilter());
+ if(wasEmpty) {
+ m_filter = filter;
+ }
+ // this keeps the saving completely decoupled from the filter setting in the detailed view
+ if(filter->isEmpty()) {
+ m_filter = 0;
+ return;
+ }
+ Kernel::self()->addFilter(filter);
+}
+
+#include "filterdialog.moc"
diff --git a/src/filterdialog.h b/src/filterdialog.h
new file mode 100644
index 0000000..f2d21a6
--- /dev/null
+++ b/src/filterdialog.h
@@ -0,0 +1,170 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef FILTERDIALOG_H
+#define FILTERDIALOG_H
+
+// kwidgetlister is copied from kdepim/libkdenetwork cvs
+#include "gui/kwidgetlister.h"
+#include "filter.h"
+#include "datavectors.h"
+
+#include <kdialogbase.h>
+
+#include <qhbox.h>
+#include <qstring.h>
+#include <qstringlist.h>
+
+class KComboBox;
+class KLineEdit;
+class KPushButton;
+
+class QRadioButton;
+class QDialog;
+
+namespace Tellico {
+ class FilterDialog;
+
+/**
+ * A widget to edit a single FilterRule.
+ * It consists of a read-only @ref KComboBox for the field,
+ * a read-only @ref KComboBox for the function and
+ * a @ref KLineEdit for the content or the pattern (in case of regexps).
+ *
+ * This class borrows heavily from KMSearchRule in kmail by Marc Mutz
+ *
+ * @author Robby Stephenson
+ */
+class FilterRuleWidget : public QHBox {
+Q_OBJECT
+
+public:
+ /**
+ * Constructor. You give a @ref FilterRule as parameter, which will
+ * be used to initialize the widget.
+ */
+ FilterRuleWidget(FilterRule* rule, QWidget* parent, const char* name=0);
+
+ /**
+ * Set the rule. The rule is accepted regardless of the return
+ * value of @ref FilterRule::isEmpty. This widget makes a shallow
+ * copy of @p rule and operates directly on it. If @p rule is
+ * 0, the widget resets itself, takes user input, but does essentially
+ * nothing. If you pass 0, you should probably disable it.
+ */
+ void setRule(const FilterRule* rule);
+ /**
+ * Return a reference to the currently worked-on @ref FilterRule.
+ */
+ FilterRule* rule() const;
+ /**
+ * Resets the rule currently worked on and updates the widget accordingly.
+ */
+ void reset();
+
+signals:
+ void signalModified();
+
+public slots:
+ void setFocus();
+
+protected slots:
+ void slotEditRegExp();
+ void slotRuleFieldChanged(int which);
+ void slotRuleFunctionChanged(int which);
+
+private:
+ void initLists();
+ void initWidget();
+
+ KComboBox* m_ruleField;
+ KComboBox* m_ruleFunc;
+ KLineEdit* m_ruleValue;
+ KPushButton* m_editRegExp;
+ QDialog* m_editRegExpDialog;
+ QStringList m_ruleFieldList;
+ QStringList m_ruleFuncList;
+};
+
+class FilterRuleWidgetLister : public KWidgetLister {
+Q_OBJECT
+
+public:
+ FilterRuleWidgetLister(QWidget* parent, const char* name=0);
+
+ const QPtrList<QWidget>& widgetList() const;
+ void setFilter(Filter::Ptr filter);
+
+public slots:
+ void reset();
+ virtual void setFocus();
+
+signals:
+ void signalModified();
+
+protected:
+ virtual void clearWidget(QWidget* widget);
+ virtual QWidget* createWidget(QWidget* parent);
+};
+
+/**
+ * @author Robby Stephenson
+ */
+class FilterDialog : public KDialogBase {
+Q_OBJECT
+
+public:
+ enum Mode {
+ CreateFilter,
+ ModifyFilter
+ };
+
+ /**
+ * The constructor sets up the dialog.
+ *
+ * @param parent A pointer to the parent widget
+ * @param name The widget name
+ */
+ FilterDialog(Mode mode, QWidget* parent, const char* name=0);
+
+ FilterPtr currentFilter();
+ void setFilter(FilterPtr filter);
+
+public slots:
+ void slotClear();
+
+protected slots:
+ virtual void slotOk();
+ virtual void slotApply();
+ void slotShrink();
+ void slotFilterChanged();
+ void slotSaveFilter();
+
+signals:
+ void signalUpdateFilter(Tellico::FilterPtr);
+ void signalCollectionModified();
+
+private:
+ void init();
+
+ FilterPtr m_filter;
+ const Mode m_mode;
+ QRadioButton* m_matchAll;
+ QRadioButton* m_matchAny;
+ FilterRuleWidgetLister* m_ruleLister;
+ KLineEdit* m_filterName;
+ KPushButton* m_saveFilter;
+};
+
+} // end namespace
+#endif
diff --git a/src/filteritem.cpp b/src/filteritem.cpp
new file mode 100644
index 0000000..68f5eaf
--- /dev/null
+++ b/src/filteritem.cpp
@@ -0,0 +1,36 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "filteritem.h"
+#include "tellico_kernel.h"
+
+#include <kiconloader.h>
+
+#include <qpixmap.h>
+
+using Tellico::FilterItem;
+
+FilterItem::FilterItem(GUI::ListView* parent_, Filter::Ptr filter_)
+ : GUI::CountedItem(parent_), m_filter(filter_) {
+ setText(0, filter_->name());
+ setPixmap(0, SmallIcon(QString::fromLatin1("filter")));
+}
+
+void FilterItem::updateFilter(Filter::Ptr filter_) {
+ m_filter = filter_;
+ setText(0, m_filter->name());
+}
+
+void FilterItem::doubleClicked() {
+ Kernel::self()->modifyFilter(m_filter);
+}
diff --git a/src/filteritem.h b/src/filteritem.h
new file mode 100644
index 0000000..c777b5a
--- /dev/null
+++ b/src/filteritem.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef FILTERITEM_H
+#define FILTERITEM_H
+
+#include "gui/counteditem.h"
+#include "filter.h"
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class FilterItem : public GUI::CountedItem {
+public:
+ FilterItem(GUI::ListView* parent, Tellico::Filter::Ptr filter);
+
+ virtual bool isFilterItem() const { return true; }
+ Filter::Ptr filter() { return m_filter; }
+ void updateFilter(Filter::Ptr filter);
+
+ virtual void doubleClicked();
+
+private:
+ Filter::Ptr m_filter;
+};
+
+}
+
+#endif
diff --git a/src/filterview.cpp b/src/filterview.cpp
new file mode 100644
index 0000000..8bb9deb
--- /dev/null
+++ b/src/filterview.cpp
@@ -0,0 +1,266 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "filterview.h"
+#include "controller.h"
+#include "entry.h"
+#include "collection.h"
+#include "document.h"
+#include "entryitem.h"
+#include "tellico_kernel.h"
+#include "listviewcomparison.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <kiconloader.h>
+
+#include <qheader.h>
+
+using Tellico::FilterView;
+
+FilterView::FilterView(QWidget* parent_, const char* name_) : GUI::ListView(parent_, name_), m_notSortedYet(true) {
+ addColumn(i18n("Filter"));
+ header()->setStretchEnabled(true, 0);
+ setResizeMode(QListView::NoColumn);
+ setRootIsDecorated(true);
+ setShowSortIndicator(true);
+ setTreeStepSize(15);
+ setFullWidth(true);
+
+ connect(this, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)),
+ SLOT(contextMenuRequested(QListViewItem*, const QPoint&, int)));
+}
+
+bool FilterView::isSelectable(GUI::ListViewItem* item_) const {
+ if(!GUI::ListView::isSelectable(item_)) {
+ return false;
+ }
+
+ // because the popup menu has modify and delete, only
+ // allow one filter item to get selected
+ if(item_->isFilterItem()) {
+ return selectedItems().isEmpty();
+ }
+
+ return true;
+}
+
+void FilterView::contextMenuRequested(QListViewItem* item_, const QPoint& point_, int) {
+ if(!item_) {
+ return;
+ }
+
+ GUI::ListViewItem* item = static_cast<GUI::ListViewItem*>(item_);
+ if(item->isFilterItem()) {
+ KPopupMenu menu(this);
+ menu.insertItem(SmallIconSet(QString::fromLatin1("filter")),
+ i18n("Modify Filter"), this, SLOT(slotModifyFilter()));
+ menu.insertItem(SmallIconSet(QString::fromLatin1("editdelete")),
+ i18n("Delete Filter"), this, SLOT(slotDeleteFilter()));
+ menu.exec(point_);
+ }
+}
+
+// this gets called when header() is clicked, so cycle through
+void FilterView::setSorting(int col_, bool asc_) {
+ if(asc_ && !m_notSortedYet) {
+ if(sortStyle() == ListView::SortByText) {
+ setSortStyle(ListView::SortByCount);
+ } else {
+ setSortStyle(ListView::SortByText);
+ }
+ }
+ if(sortStyle() == ListView::SortByText) {
+ setColumnText(0, i18n("Filter"));
+ } else {
+ setColumnText(0, i18n("Filter (Sort by Count)"));
+ }
+ m_notSortedYet = false;
+ ListView::setSorting(col_, asc_);
+}
+
+void FilterView::addCollection(Data::CollPtr coll_) {
+ FilterVec filters = coll_->filters();
+ for(FilterVec::Iterator it = filters.begin(); it != filters.end(); ++it) {
+ addFilter(it);
+ }
+ Data::FieldPtr f = coll_->fieldByName(QString::fromLatin1("title"));
+ if(f) {
+ setComparison(0, ListViewComparison::create(f));
+ }
+}
+
+void FilterView::addEntries(Data::EntryVec entries_) {
+ for(QListViewItem* item = firstChild(); item; item = item->nextSibling()) {
+ Filter::Ptr filter = static_cast<FilterItem*>(item)->filter();
+ for(Data::EntryVecIt it = entries_.begin(); it != entries_.end(); ++it) {
+ if(filter && filter->matches(it.data())) {
+ new EntryItem(static_cast<FilterItem*>(item), it);
+ }
+ }
+ }
+}
+
+void FilterView::modifyEntries(Data::EntryVec entries_) {
+ for(Data::EntryVecIt it = entries_.begin(); it != entries_.end(); ++it) {
+ modifyEntry(it);
+ }
+}
+
+void FilterView::modifyEntry(Data::EntryPtr entry_) {
+ for(QListViewItem* item = firstChild(); item; item = item->nextSibling()) {
+ bool hasEntry = false;
+ QListViewItem* entryItem = 0;
+ // iterate over all children and find item with matching entry pointers
+ for(QListViewItem* i = item->firstChild(); i; i = i->nextSibling()) {
+ if(static_cast<EntryItem*>(i)->entry() == entry_) {
+ i->setText(0, entry_->title());
+ // only one item per filter will match
+ hasEntry = true;
+ entryItem = i;
+ break;
+ }
+ }
+ // now, if the entry was there but no longer matches, delete it
+ // if the entry was not there but does match, add it
+ Filter::Ptr filter = static_cast<FilterItem*>(item)->filter();
+ if(hasEntry && !filter->matches(static_cast<EntryItem*>(entryItem)->entry())) {
+ delete entryItem;
+ } else if(!hasEntry && filter->matches(entry_)) {
+ new EntryItem(static_cast<FilterItem*>(item), entry_);
+ }
+ }
+}
+
+void FilterView::removeEntries(Data::EntryVec entries_) {
+ // the group modified signal gets handles separately, this is just for filters
+ for(QListViewItem* item = firstChild(); item; item = item->nextSibling()) {
+ // iterate over all children and delete items with matching entry pointers
+ QListViewItem* c1 = item->firstChild();
+ while(c1) {
+ if(entries_.contains(static_cast<EntryItem*>(c1)->entry())) {
+ QListViewItem* c2 = c1;
+ c1 = c1->nextSibling();
+ delete c2;
+ } else {
+ c1 = c1->nextSibling();
+ }
+ }
+ }
+}
+
+void FilterView::addField(Data::CollPtr, Data::FieldPtr) {
+ resetComparisons();
+}
+
+void FilterView::modifyField(Data::CollPtr, Data::FieldPtr, Data::FieldPtr) {
+ resetComparisons();
+}
+
+void FilterView::removeField(Data::CollPtr, Data::FieldPtr) {
+ resetComparisons();
+}
+
+void FilterView::addFilter(FilterPtr filter_) {
+ FilterItem* filterItem = new FilterItem(this, filter_);
+
+ Data::EntryVec entries = Data::Document::self()->filteredEntries(filter_);
+ for(Data::EntryVecIt it = entries.begin(); it != entries.end(); ++it) {
+ new EntryItem(filterItem, it); // text gets set in constructor
+ }
+}
+
+void FilterView::slotModifyFilter() {
+ GUI::ListViewItem* item = static_cast<GUI::ListViewItem*>(currentItem());
+ if(!item || !item->isFilterItem()) {
+ return;
+ }
+
+ Kernel::self()->modifyFilter(static_cast<FilterItem*>(item)->filter());
+}
+
+void FilterView::slotDeleteFilter() {
+ GUI::ListViewItem* item = static_cast<GUI::ListViewItem*>(currentItem());
+ if(!item || !item->isFilterItem()) {
+ return;
+ }
+
+ Kernel::self()->removeFilter(static_cast<FilterItem*>(item)->filter());
+}
+
+void FilterView::removeFilter(FilterPtr filter_) {
+ // paranoia
+ if(!filter_) {
+ return;
+ }
+
+ // find the item for this filter
+ // cheating a bit, it's probably the current one
+ GUI::ListViewItem* found = 0;
+ GUI::ListViewItem* cur = static_cast<GUI::ListViewItem*>(currentItem());
+ if(cur && cur->isFilterItem() && static_cast<FilterItem*>(cur)->filter() == filter_) {
+ // found it!
+ found = cur;
+ } else {
+ // iterate over all filter items
+ for(QListViewItem* item = firstChild(); item; item = item->nextSibling()) {
+ if(static_cast<FilterItem*>(item)->filter() == filter_) {
+ found = static_cast<FilterItem*>(item);
+ break;
+ }
+ }
+ }
+
+ // not found
+ if(!found) {
+ myDebug() << "GroupView::modifyFilter() - not found" << endl;
+ return;
+ }
+
+ delete found;
+}
+
+void FilterView::slotSelectionChanged() {
+ GUI::ListView::slotSelectionChanged();
+
+ GUI::ListViewItem* item = selectedItems().getFirst();
+ if(item && item->isFilterItem()) {
+ Controller::self()->slotUpdateFilter(static_cast<FilterItem*>(item)->filter());
+ }
+}
+
+void FilterView::resetComparisons() {
+ // this is only allowed when the view is not empty, so we can grab a collection ptr
+ if(childCount() == 0) {
+ return;
+ }
+ QListViewItem* item = firstChild();
+ while(item && item->childCount() == 0) {
+ item = item->nextSibling();
+ }
+ if(!item) {
+ return;
+ }
+ item = item->firstChild();
+ Data::CollPtr coll = static_cast<EntryItem*>(item)->entry()->collection();
+ if(!coll) {
+ return;
+ }
+ Data::FieldPtr f = coll->fieldByName(QString::fromLatin1("title"));
+ if(f) {
+ setComparison(0, ListViewComparison::create(f));
+ }
+}
+
+#include "filterview.moc"
diff --git a/src/filterview.h b/src/filterview.h
new file mode 100644
index 0000000..85674e5
--- /dev/null
+++ b/src/filterview.h
@@ -0,0 +1,83 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_FILTERVIEW_H
+#define TELLICO_FILTERVIEW_H
+
+#include "gui/listview.h"
+#include "observer.h"
+#include "filteritem.h"
+
+#include <qdict.h>
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class FilterView : public GUI::ListView, public Observer {
+Q_OBJECT
+
+public:
+ FilterView(QWidget* parent, const char* name=0);
+
+ virtual bool isSelectable(GUI::ListViewItem*) const;
+
+ void addCollection(Data::CollPtr coll);
+
+ virtual void addEntries(Data::EntryVec entries);
+ virtual void modifyEntry(Data::EntryPtr entry);
+ virtual void modifyEntries(Data::EntryVec entries);
+ virtual void removeEntries(Data::EntryVec entries);
+
+ virtual void addField(Data::CollPtr, Data::FieldPtr);
+ virtual void modifyField(Data::CollPtr, Data::FieldPtr, Data::FieldPtr);
+ virtual void removeField(Data::CollPtr, Data::FieldPtr);
+
+ virtual void addFilter(FilterPtr filter);
+ virtual void modifyFilter(FilterPtr) {}
+ virtual void removeFilter(FilterPtr filter);
+
+protected slots:
+ virtual void slotSelectionChanged();
+
+private slots:
+ /**
+ * Handles the appearance of the popup menu.
+ *
+ * @param item A pointer to the item underneath the mouse
+ * @param point The location point
+ * @param col The column number, not currently used
+ */
+ void contextMenuRequested(QListViewItem* item, const QPoint& point, int col);
+
+ /**
+ * Modify a saved filter
+ */
+ void slotModifyFilter();
+ /**
+ * Delete a saved filter
+ */
+ void slotDeleteFilter();
+
+private:
+ virtual void setSorting(int column, bool ascending = true);
+ void resetComparisons();
+
+ bool m_notSortedYet;
+ QDict<FilterItem> m_itemDict;
+};
+
+} // end namespace
+
+#endif
diff --git a/src/groupiterator.cpp b/src/groupiterator.cpp
new file mode 100644
index 0000000..21f0db2
--- /dev/null
+++ b/src/groupiterator.cpp
@@ -0,0 +1,34 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "groupiterator.h"
+#include "entrygroupitem.h"
+
+using Tellico::GroupIterator;
+
+GroupIterator::GroupIterator(const QListView* view_) {
+ // groups are the first children in the group view
+ m_item = static_cast<GUI::ListViewItem*>(view_->firstChild());
+}
+
+GroupIterator& GroupIterator::operator++() {
+ m_item = static_cast<GUI::ListViewItem*>(m_item->nextSibling());
+ return *this;
+}
+
+Tellico::Data::EntryGroup* GroupIterator::group() {
+ if(!m_item || !m_item->isEntryGroupItem()) {
+ return 0;
+ }
+ return static_cast<EntryGroupItem*>(m_item)->group();
+}
diff --git a/src/groupiterator.h b/src/groupiterator.h
new file mode 100644
index 0000000..a77b7ea
--- /dev/null
+++ b/src/groupiterator.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_GROUPITERATOR_H
+#define TELLICO_GROUPITERATOR_H
+
+class QListView;
+
+namespace Tellico {
+ namespace Data {
+ class EntryGroup;
+ }
+ namespace GUI {
+ class ListViewItem;
+ }
+
+/**
+ * @author Robby Stephenson
+ */
+class GroupIterator{
+public:
+ GroupIterator(const QListView* view);
+
+ GroupIterator& operator++();
+ Data::EntryGroup* group();
+
+private:
+ GUI::ListViewItem* m_item;
+};
+
+}
+
+#endif
diff --git a/src/groupview.cpp b/src/groupview.cpp
new file mode 100644
index 0000000..67b1a40
--- /dev/null
+++ b/src/groupview.cpp
@@ -0,0 +1,495 @@
+/***************************************************************************
+ copyright : (C) 2001-2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "groupview.h"
+#include "collection.h"
+#include "document.h"
+#include "field.h"
+#include "filter.h"
+#include "controller.h"
+#include "entryitem.h"
+#include "entrygroupitem.h"
+#include "entry.h"
+#include "field.h"
+#include "filter.h"
+#include "tellico_kernel.h"
+#include "listviewcomparison.h"
+#include "../tellico_debug.h"
+
+#include <kpopupmenu.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kaction.h>
+
+#include <qstringlist.h>
+#include <qcolor.h>
+#include <qregexp.h>
+#include <qheader.h>
+
+using Tellico::GroupView;
+
+GroupView::GroupView(QWidget* parent_, const char* name_/*=0*/)
+ : GUI::ListView(parent_, name_), m_notSortedYet(true), m_coll(0) {
+ addColumn(QString::null); // header text gets updated later
+ header()->setStretchEnabled(true, 0);
+ setResizeMode(QListView::NoColumn);
+ setRootIsDecorated(true);
+ setShowSortIndicator(true);
+ setTreeStepSize(15);
+ setFullWidth(true);
+
+ connect(this, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)),
+ SLOT(contextMenuRequested(QListViewItem*, const QPoint&, int)));
+
+ connect(this, SIGNAL(expanded(QListViewItem*)),
+ SLOT(slotExpanded(QListViewItem*)));
+
+ connect(this, SIGNAL(collapsed(QListViewItem*)),
+ SLOT(slotCollapsed(QListViewItem*)));
+
+ m_groupOpenPixmap = SmallIcon(QString::fromLatin1("folder_open"));
+ m_groupClosedPixmap = SmallIcon(QString::fromLatin1("folder"));
+}
+
+Tellico::EntryGroupItem* GroupView::addGroup(Data::EntryGroup* group_) {
+ if(group_->isEmpty()) {
+ return 0;
+ }
+ int type = -1;
+ if(m_coll && m_coll->hasField(group_->fieldName())) {
+ type = m_coll->fieldByName(group_->fieldName())->type();
+ }
+ EntryGroupItem* item = new EntryGroupItem(this, group_, type);
+ if(group_->groupName() == i18n(Data::Collection::s_emptyGroupTitle)) {
+ item->setPixmap(0, SmallIcon(QString::fromLatin1("folder_red")));
+ item->setSortWeight(10);
+ } else {
+ item->setPixmap(0, m_groupClosedPixmap);
+ }
+
+ m_groupDict.insert(group_->groupName(), item);
+ item->setExpandable(!group_->isEmpty());
+
+ return item;
+}
+
+void GroupView::slotReset() {
+ clear();
+ m_groupDict.clear();
+}
+
+void GroupView::removeCollection(Data::CollPtr coll_) {
+ if(!coll_) {
+ kdWarning() << "GroupView::removeCollection() - null coll pointer!" << endl;
+ return;
+ }
+
+// myDebug() << "GroupView::removeCollection() - " << coll_->title() << endl;
+
+ blockSignals(true);
+ slotReset();
+ blockSignals(false);
+}
+
+void GroupView::slotModifyGroups(Data::CollPtr coll_, PtrVector<Data::EntryGroup> groups_) {
+ if(!coll_ || groups_.isEmpty()) {
+ kdWarning() << "GroupView::slotModifyGroups() - null coll or group pointer!" << endl;
+ return;
+ }
+
+ for(PtrVector<Data::EntryGroup>::Iterator group = groups_.begin(); group != groups_.end(); ++group) {
+ // if the entries aren't grouped by field of the modified group,
+ // we don't care, so return
+ if(m_groupBy != group->fieldName()) {
+ continue;
+ }
+
+// myDebug() << "GroupView::slotModifyGroups() - " << group->fieldName() << "/" << group->groupName() << endl;
+ EntryGroupItem* par = m_groupDict.find(group->groupName());
+ if(par) {
+ if(group->isEmpty()) {
+ m_groupDict.remove(par->text(0));
+ delete par;
+ continue;
+ }
+ // the group might get deleted and recreated out from under us,
+ // so do a sanity check
+ par->setGroup(group.ptr());
+ } else {
+ if(group->isEmpty()) {
+ myDebug() << "GroupView::slotModifyGroups() - trying to add empty group" << endl;
+ continue;
+ }
+ par = addGroup(group.ptr());
+ }
+
+ setUpdatesEnabled(false);
+ bool open = par->isOpen();
+ par->setOpen(false); // closing and opening the item will clear the items
+ par->setOpen(open);
+ setUpdatesEnabled(true);
+ }
+ // don't want any selected
+ clearSelection();
+ sort(); // in case the count changed, or group name
+}
+
+// don't 'shadow' QListView::setSelected
+void GroupView::setEntrySelected(Data::EntryPtr entry_) {
+// myDebug() << "GroupView::slotSetSelected()" << endl;
+ // if entry_ is null pointer, set no selected
+ if(!entry_) {
+ // don't move this one outside the block since it calls setCurrentItem(0)
+ clearSelection();
+ return;
+ }
+
+ // if the selected entry is the same as the current one, just return
+ GUI::ListViewItem* it = static_cast<GUI::ListViewItem*>(currentItem());
+ if(it && it->isEntryItem() && entry_ == static_cast<EntryItem*>(it)->entry()) {
+ return;
+ }
+
+ // have to find a group whose field is the same as currently shown
+ if(m_groupBy.isEmpty()) {
+ myDebug() << "GroupView::slotSetSelected() - no group field" << endl;
+ return;
+ }
+
+ const Data::EntryGroup* group = 0;
+ for(PtrVector<Data::EntryGroup>::ConstIterator it = entry_->groups().begin(); it != entry_->groups().end(); ++it) {
+ if(it->fieldName() == m_groupBy) {
+ group = it.ptr();
+ break;
+ }
+ }
+ if(!group) {
+ myDebug() << "GroupView::slotSetSelected() - entry is not in any current groups!" << endl;
+ return;
+ }
+
+ EntryGroupItem* groupItem = m_groupDict.find(group->groupName());
+ if(!groupItem) {
+ return;
+ }
+
+ clearSelection();
+ for(QListViewItem* item = groupItem->firstChild(); item; item = item->nextSibling()) {
+ EntryItem* entryItem = static_cast<EntryItem*>(item);
+ if(entryItem->entry() == entry_) {
+ blockSignals(true);
+ setSelected(item, true);
+ setCurrentItem(item);
+ blockSignals(false);
+ ensureItemVisible(item);
+ return;
+ }
+ }
+}
+
+void GroupView::slotExpandAll(int depth_/*=-1*/) {
+ if(childCount() == 0) {
+ return;
+ }
+ setSiblingsOpen(depth_, true);
+}
+
+void GroupView::slotCollapseAll(int depth_/*=-1*/) {
+ if(childCount() == 0) {
+ return;
+ }
+ setSiblingsOpen(depth_, false);
+}
+
+void GroupView::setSiblingsOpen(int depth_, bool open_) {
+ QListViewItem* item = 0;
+
+ if(depth_ == -1) {
+ item = currentItem();
+ if(!item) {
+ return;
+ }
+ depth_ = item->depth();
+ }
+
+ switch(depth_) {
+ case 0:
+ item = firstChild();
+ break;
+
+ case 1:
+ item = firstChild()->firstChild();
+ break;
+
+ default:
+ return;
+ }
+
+ for( ; item; item = item->nextSibling()) {
+ item->setOpen(open_);
+ }
+}
+
+void GroupView::contextMenuRequested(QListViewItem* item_, const QPoint& point_, int) {
+ if(!item_) {
+ return;
+ }
+
+ KPopupMenu menu(this);
+ GUI::ListViewItem* item = static_cast<GUI::ListViewItem*>(item_);
+ if(item->isEntryGroupItem()) {
+ menu.insertItem(SmallIconSet(QString::fromLatin1("2downarrow")),
+ i18n("Expand All Groups"), this, SLOT(slotExpandAll()));
+ menu.insertItem(SmallIconSet(QString::fromLatin1("2uparrow")),
+ i18n("Collapse All Groups"), this, SLOT(slotCollapseAll()));
+ menu.insertItem(SmallIconSet(QString::fromLatin1("filter")),
+ i18n("Filter by Group"), this, SLOT(slotFilterGroup()));
+ } else if(item->isEntryItem()) {
+ Controller::self()->plugEntryActions(&menu);
+ }
+ menu.exec(point_);
+}
+
+void GroupView::slotCollapsed(QListViewItem* item_) {
+ // only change icon for group items
+ if(static_cast<GUI::ListViewItem*>(item_)->isEntryGroupItem()) {
+ if(item_->text(0) == i18n(Data::Collection::s_emptyGroupTitle)) {
+ item_->setPixmap(0, SmallIcon(QString::fromLatin1("folder_red")));
+ } else {
+ item_->setPixmap(0, m_groupClosedPixmap);
+ }
+ static_cast<GUI::ListViewItem*>(item_)->clear();
+ }
+}
+
+void GroupView::slotExpanded(QListViewItem* item_) {
+ EntryGroupItem* item = static_cast<EntryGroupItem*>(item_);
+ // only change icon for group items
+ if(!item->isEntryGroupItem()) {
+ return;
+ }
+
+ setUpdatesEnabled(false);
+ if(item->text(0) == i18n(Data::Collection::s_emptyGroupTitle)) {
+ item->setPixmap(0, SmallIcon(QString::fromLatin1("folder_red_open")));
+ } else {
+ item->setPixmap(0, m_groupOpenPixmap);
+ }
+
+ Data::EntryGroup* group = item->group();
+ if(!group) {
+ myDebug() << "GroupView::slotExpanded() - no entry group! - " << item->text(0) << endl;
+ } else {
+ for(Data::EntryVecIt entryIt = group->begin(); entryIt != group->end(); ++entryIt) {
+ new EntryItem(item, entryIt);
+ }
+ }
+
+ setUpdatesEnabled(true);
+ triggerUpdate();
+}
+
+void GroupView::addCollection(Data::CollPtr coll_) {
+// myDebug() << "GroupView::addCollection()" << endl;
+ if(!coll_) {
+ kdWarning() << "GroupView::addCollection() - null coll pointer!" << endl;
+ return;
+ }
+
+ m_coll = coll_;
+ // if the collection doesn't have the grouped field, and it's not the pseudo-group,
+ // change it to default
+ if(m_groupBy.isEmpty() || (!coll_->hasField(m_groupBy) && m_groupBy != Data::Collection::s_peopleGroupName)) {
+ m_groupBy = coll_->defaultGroupField();
+ }
+
+ // when the coll gets set for the first time, the pixmaps need to be updated
+ if((m_coll->hasField(m_groupBy) && m_coll->fieldByName(m_groupBy)->formatFlag() == Data::Field::FormatName)
+ || m_groupBy == Data::Collection::s_peopleGroupName) {
+ m_groupOpenPixmap = UserIcon(QString::fromLatin1("person-open"));
+ m_groupClosedPixmap = UserIcon(QString::fromLatin1("person"));
+ }
+
+ Data::FieldPtr f = coll_->fieldByName(QString::fromLatin1("title"));
+ if(f) {
+ setComparison(0, ListViewComparison::create(f));
+ }
+
+ updateHeader();
+ populateCollection();
+
+ slotCollapseAll();
+// myDebug() << "GroupView::addCollection - done" << endl;
+}
+
+void GroupView::setGroupField(const QString& groupField_) {
+// myDebug() << "GroupView::setGroupField - " << groupField_ << endl;
+ if(groupField_.isEmpty() || groupField_ == m_groupBy) {
+ return;
+ }
+
+ m_groupBy = groupField_;
+ if(!m_coll) {
+ return; // can't do anything yet, but still need to set the variable
+ }
+ if((m_coll->hasField(groupField_) && m_coll->fieldByName(groupField_)->formatFlag() == Data::Field::FormatName)
+ || groupField_ == Data::Collection::s_peopleGroupName) {
+ m_groupOpenPixmap = UserIcon(QString::fromLatin1("person-open"));
+ m_groupClosedPixmap = UserIcon(QString::fromLatin1("person"));
+ } else {
+ m_groupOpenPixmap = SmallIcon(QString::fromLatin1("folder_open"));
+ m_groupClosedPixmap = SmallIcon(QString::fromLatin1("folder"));
+ }
+ updateHeader();
+ populateCollection();
+}
+
+void GroupView::populateCollection() {
+ if(!m_coll) {
+ return;
+ }
+
+// myDebug() << "GroupView::populateCollection() - " << m_groupBy << endl;
+ if(m_groupBy.isEmpty()) {
+ m_groupBy = m_coll->defaultGroupField();
+ }
+
+ setUpdatesEnabled(false);
+ clear(); // delete all groups
+ m_groupDict.clear();
+
+ // if there's no group field, just return
+ if(m_groupBy.isEmpty()) {
+ setUpdatesEnabled(true);
+ return;
+ }
+
+ Data::EntryGroupDict* dict = m_coll->entryGroupDictByName(m_groupBy);
+ if(!dict) { // could happen if m_groupBy is non empty, but there are no entries with a value
+ return;
+ }
+
+ // iterate over all the groups in the dict
+ // e.g. if the dict is "author", loop over all the author groups
+ for(QDictIterator<Data::EntryGroup> it(*dict); it.current(); ++it) {
+ addGroup(it.current());
+ }
+
+ setUpdatesEnabled(true);
+ triggerUpdate();
+}
+
+void GroupView::slotFilterGroup() {
+ const GUI::ListViewItemList& items = selectedItems();
+ GUI::ListViewItem* item = items.getFirst();
+ // only works for entry groups
+ if(!item || !item->isEntryGroupItem()) {
+ return;
+ }
+
+ FilterPtr filter = new Filter(Filter::MatchAny);
+
+ for(GUI::ListViewItemListIt it(items); it.current(); ++it) {
+ if(static_cast<EntryGroupItem*>(it.current())->count() == 0) { //ignore empty items
+ continue;
+ }
+ // need to check for people group
+ if(m_groupBy == Data::Collection::s_peopleGroupName) {
+ Data::EntryPtr entry = static_cast<EntryItem*>(it.current()->firstChild())->entry();
+ Data::FieldVec fields = entry->collection()->peopleFields();
+ for(Data::FieldVec::Iterator fIt = fields.begin(); fIt != fields.end(); ++fIt) {
+ filter->append(new FilterRule(fIt->name(), it.current()->text(0), FilterRule::FuncContains));
+ }
+ } else {
+ QString s = it.current()->text(0);
+ if(s != i18n(Data::Collection::s_emptyGroupTitle)) {
+ filter->append(new FilterRule(m_groupBy, it.current()->text(0), FilterRule::FuncContains));
+ }
+ }
+ }
+
+ if(!filter->isEmpty()) {
+ emit signalUpdateFilter(filter);
+ }
+}
+
+// this gets called when header() is clicked, so cycle through
+void GroupView::setSorting(int col_, bool asc_) {
+ if(asc_ && !m_notSortedYet) { // cycle through after ascending
+ if(sortStyle() == ListView::SortByText) {
+ setSortStyle(ListView::SortByCount);
+ } else {
+ setSortStyle(ListView::SortByText);
+ }
+ }
+ updateHeader();
+ m_notSortedYet = false;
+ ListView::setSorting(col_, asc_);
+}
+
+void GroupView::addField(Data::CollPtr, Data::FieldPtr) {
+ resetComparisons();
+}
+
+void GroupView::modifyField(Data::CollPtr, Data::FieldPtr, Data::FieldPtr newField_) {
+ if(newField_->name() == m_groupBy) {
+ updateHeader(newField_);
+ }
+ // if the grouping changed at all, our groups got deleted out from under us
+ // so check first pointer, too. The groups could be deleted if the format type
+ // changes, too, so not enough just to check group flag
+ if(childCount() > 0 && static_cast<EntryGroupItem*>(firstChild())->group() == 0) {
+ populateCollection();
+ }
+ resetComparisons();
+}
+
+void GroupView::removeField(Data::CollPtr, Data::FieldPtr) {
+ resetComparisons();
+}
+
+void GroupView::updateHeader(Data::FieldPtr field_/*=0*/) {
+ QString t = field_ ? field_->title() : groupTitle();
+ if(sortStyle() == ListView::SortByText) {
+ setColumnText(0, t);
+ } else {
+ setColumnText(0, i18n("%1 (Sort by Count)").arg(t));
+ }
+}
+
+QString GroupView::groupTitle() {
+ QString title;
+ if(!m_coll || m_groupBy.isEmpty()) {
+ title = i18n("Group Name Header", "Group");
+ } else {
+ Data::FieldPtr f = m_coll->fieldByName(m_groupBy);
+ if(f) {
+ title = f->title();
+ } else if(m_groupBy == Data::Collection::s_peopleGroupName) {
+ title = i18n("People");
+ }
+ }
+ return title;
+}
+
+void GroupView::resetComparisons() {
+ if(!m_coll) {
+ return;
+ }
+ Data::FieldPtr f = m_coll->fieldByName(QString::fromLatin1("title"));
+ if(f) {
+ setComparison(0, ListViewComparison::create(f));
+ }
+}
+
+#include "groupview.moc"
diff --git a/src/groupview.h b/src/groupview.h
new file mode 100644
index 0000000..4ead256
--- /dev/null
+++ b/src/groupview.h
@@ -0,0 +1,198 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef GROUPVIEW_H
+#define GROUPVIEW_H
+
+#include "gui/listview.h"
+#include "observer.h"
+
+#include <qdict.h>
+#include <qpixmap.h>
+
+namespace Tellico {
+ namespace Data {
+ class EntryGroup;
+ }
+ class Filter;
+ class EntryGroupItem;
+ class GroupIterator;
+
+/**
+ * The GroupView shows the entries grouped, as well as the saved filters.
+ *
+ * There is one root item for each collection in the document. The entries are grouped
+ * by the field defined by each collection. A @ref QDict is used to keep track of the
+ * group items.
+ *
+ * @see Tellico::Data::Collection
+ *
+ * @author Robby Stephenson
+ */
+class GroupView : public GUI::ListView, public Observer {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor sets up the single column, and initializes the popup menu.
+ *
+ * @param parent A pointer to the parent widget
+ * @param name The widget name
+ */
+ GroupView(QWidget* parent, const char* name=0);
+
+ /**
+ * Returns the name of the field by which the entries are grouped
+ *
+ * @return The field name
+ */
+ const QString& groupBy() const { return m_groupBy; }
+ /**
+ * Sets the name of the field by which the entries are grouped
+ *
+ * @param groupFieldName The field name
+ */
+ void setGroupField(const QString& groupFieldName);
+ /**
+ * Adds a collection, along with all all the groups for the collection in
+ * the groupFieldribute. This method gets called as well when the groupFieldribute
+ * is changed, since it essentially repopulates the listview.
+ *
+ * @param coll A pointer to the collection being added
+ */
+ void addCollection(Data::CollPtr coll);
+ /**
+ * Removes a root collection item, and all of its children.
+ *
+ * @param coll A pointer to the collection
+ */
+ void removeCollection(Data::CollPtr coll);
+ /**
+ * Selects the first item which refers to a certain entry.
+ *
+ * @param entry A pointer to the entry
+ */
+ void setEntrySelected(Data::EntryPtr entry);
+ /**
+ * Refresh all the items for the collection.
+ *
+ * @return The item for the collection
+ */
+ void populateCollection();
+
+ virtual void addField(Data::CollPtr, Data::FieldPtr);
+ virtual void modifyField(Data::CollPtr coll, Data::FieldPtr oldField, Data::FieldPtr newField);
+ virtual void removeField(Data::CollPtr, Data::FieldPtr);
+
+public slots:
+ /**
+ * Resets the list view, clearing and deleting all items.
+ */
+ void slotReset();
+ /**
+ * Adds or removes listview items when groups are modified.
+ *
+ * @param coll A pointer to the collection of the gorup
+ * @param groups A vector of pointers to the modified groups
+ */
+ void slotModifyGroups(Tellico::Data::CollPtr coll, PtrVector<Tellico::Data::EntryGroup> groups);
+ /**
+ * Expands all items at a certain depth. If depth is -1, the current selected item
+ * is expanded. If depth is equal to either 0 or 1, then all items at that depth
+ * are expanded.
+ *
+ * @param depth The depth value
+ */
+ void slotExpandAll(int depth=-1);
+ /**
+ * Collapses all items at a certain depth. If depth is -1, the current selected item
+ * is collapsed. If depth is equal to either 0 or 1, then all items at that depth
+ * are collapsed.
+ *
+ * @param depth The depth value
+ */
+ void slotCollapseAll(int depth=-1);
+
+private:
+ /**
+ * Inserts a listviewitem for a given group
+ *
+ * @param group The group to be added
+ * @return A pointer to the created @ ref ParentItem
+ */
+ EntryGroupItem* addGroup(Data::EntryGroup* group);
+ /**
+ * Traverse all siblings at a certain depth, setting them open or closed. If depth is -1,
+ * then the depth of the @ref currentItem() is used.
+ *
+ * @param depth Desired depth
+ * @param open Whether the item should be open or not
+ */
+ void setSiblingsOpen(int depth, bool open);
+
+private slots:
+ /**
+ * Handles the appearance of the popup menu, determining which of the three (collection,
+ * group, or entry) menus to display.
+ *
+ * @param item A pointer to the item underneath the mouse
+ * @param point The location point
+ * @param col The column number, not currently used
+ */
+ void contextMenuRequested(QListViewItem* item, const QPoint& point, int col);
+ /**
+ * Handles changing the icon when an item is expanded, depended on whether it refers
+ * to a collection, a group, or an entry.
+ *
+ * @param item A pointer to the expanded list item
+ */
+ void slotExpanded(QListViewItem* item);
+ /**
+ * Handles changing the icon when an item is collapsed, depended on whether it refers
+ * to a collection, a group, or an entry.
+ *
+ * @param item A pointer to the collapse list item
+ */
+ void slotCollapsed(QListViewItem* item);
+ /**
+ * Filter by group
+ */
+ void slotFilterGroup();
+
+signals:
+ /**
+ * Signals a desire to filter the view.
+ *
+ * @param filter A pointer to the filter
+ */
+ void signalUpdateFilter(Tellico::FilterPtr filter);
+
+private:
+ friend class GroupIterator;
+
+ virtual void setSorting(int column, bool ascending = true);
+ void resetComparisons();
+ QString groupTitle();
+ void updateHeader(Data::FieldPtr field=0);
+
+ bool m_notSortedYet;
+ Data::CollPtr m_coll;
+ QDict<EntryGroupItem> m_groupDict;
+ QString m_groupBy;
+
+ QPixmap m_groupOpenPixmap;
+ QPixmap m_groupClosedPixmap;
+};
+
+} // end namespace
+#endif
diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am
new file mode 100644
index 0000000..cb6f5e8
--- /dev/null
+++ b/src/gui/Makefile.am
@@ -0,0 +1,43 @@
+AM_CPPFLAGS = $(all_includes)
+
+noinst_LIBRARIES = libgui.a
+libgui_a_SOURCES = combobox.cpp counteditem.cpp datewidget.cpp \
+ tabcontrol.cpp kwidgetlister.cpp stringmapdialog.cpp listview.cpp richtextlabel.cpp \
+ lineedit.cpp boolfieldwidget.cpp choicefieldwidget.cpp linefieldwidget.cpp \
+ numberfieldwidget.cpp parafieldwidget.cpp urlfieldwidget.cpp tablefieldwidget.cpp \
+ imagefieldwidget.cpp datefieldwidget.cpp imagewidget.cpp fieldwidget.cpp ratingwidget.cpp \
+ ratingfieldwidget.cpp overlaywidget.cpp progress.cpp listboxtext.cpp collectiontypecombo.cpp \
+ previewdialog.cpp
+
+libgui_a_METASOURCES = AUTO
+KDE_OPTIONS = noautodist
+EXTRA_DIST = combobox.h combobox.cpp \
+counteditem.h counteditem.cpp \
+datewidget.h datewidget.cpp \
+kwidgetlister.h kwidgetlister.cpp \
+listview.h listview.cpp \
+richtextlabel.h richtextlabel.cpp \
+stringmapdialog.h stringmapdialog.cpp \
+tabcontrol.h tabcontrol.cpp \
+lineedit.h lineedit.cpp \
+boolfieldwidget.h boolfieldwidget.cpp \
+choicefieldwidget.h choicefieldwidget.cpp \
+datefieldwidget.h datefieldwidget.cpp \
+imagefieldwidget.h imagefieldwidget.cpp \
+linefieldwidget.h linefieldwidget.cpp \
+numberfieldwidget.h numberfieldwidget.cpp \
+parafieldwidget.h parafieldwidget.cpp \
+tablefieldwidget.h tablefieldwidget.cpp \
+urlfieldwidget.h urlfieldwidget.cpp \
+ratingwidget.h ratingwidget.cpp \
+imagewidget.h imagewidget.cpp \
+fieldwidget.h fieldwidget.cpp \
+ratingfieldwidget.h ratingfieldwidget.cpp \
+overlaywidget.h overlaywidget.cpp \
+progress.h progress.cpp \
+listboxtext.h listboxtext.cpp \
+collectiontypecombo.h collectiontypecombo.cpp \
+previewdialog.h previewdialog.cpp
+
+CLEANFILES = *~
+
diff --git a/src/gui/boolfieldwidget.cpp b/src/gui/boolfieldwidget.cpp
new file mode 100644
index 0000000..5a8e88b
--- /dev/null
+++ b/src/gui/boolfieldwidget.cpp
@@ -0,0 +1,61 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "boolfieldwidget.h"
+#include "../field.h"
+#include "../latin1literal.h"
+
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qlayout.h>
+
+using Tellico::GUI::BoolFieldWidget;
+
+BoolFieldWidget::BoolFieldWidget(Data::FieldPtr field_, QWidget* parent_, const char* name_/*=0*/)
+ : FieldWidget(field_, parent_, name_) {
+
+ m_checkBox = new QCheckBox(this);
+ connect(m_checkBox, SIGNAL(clicked()), SIGNAL(modified()));
+ registerWidget();
+}
+
+QString BoolFieldWidget::text() const {
+ if(m_checkBox->isChecked()) {
+ return QString::fromLatin1("true");
+ }
+
+ return QString();
+}
+
+void BoolFieldWidget::setText(const QString& text_) {
+ blockSignals(true);
+
+ m_checkBox->blockSignals(true);
+ // be lax, don't have to check for "1" or "true"
+ // just check for a non-empty string
+ m_checkBox->setChecked(!text_.isEmpty());
+ m_checkBox->blockSignals(false);
+
+ blockSignals(false);
+}
+
+void BoolFieldWidget::clear() {
+ m_checkBox->setChecked(false);
+ editMultiple(false);
+}
+
+QWidget* BoolFieldWidget::widget() {
+ return m_checkBox;
+}
+
+#include "boolfieldwidget.moc"
diff --git a/src/gui/boolfieldwidget.h b/src/gui/boolfieldwidget.h
new file mode 100644
index 0000000..81af5a6
--- /dev/null
+++ b/src/gui/boolfieldwidget.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef BOOLFIELDWIDGET_H
+#define BOOLFIELDWIDGET_H
+
+#include "fieldwidget.h"
+#include "../datavectors.h"
+
+class QCheckBox;
+class QString;
+
+namespace Tellico {
+ namespace GUI {
+
+/**
+ * @author Robby Stephenson
+ */
+class BoolFieldWidget : public FieldWidget {
+Q_OBJECT
+
+public:
+ BoolFieldWidget(Data::FieldPtr field, QWidget* parent, const char* name=0);
+ virtual ~BoolFieldWidget() {}
+
+ virtual QString text() const;
+ virtual void setText(const QString& text);
+
+public slots:
+ virtual void clear();
+
+protected:
+ virtual QWidget* widget();
+
+private:
+ QCheckBox* m_checkBox;
+};
+
+ } // end GUI namespace
+} // end namespace
+#endif
diff --git a/src/gui/choicefieldwidget.cpp b/src/gui/choicefieldwidget.cpp
new file mode 100644
index 0000000..e9c6870
--- /dev/null
+++ b/src/gui/choicefieldwidget.cpp
@@ -0,0 +1,69 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "choicefieldwidget.h"
+#include "../field.h"
+
+#include <kcombobox.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+
+using Tellico::GUI::ChoiceFieldWidget;
+
+ChoiceFieldWidget::ChoiceFieldWidget(Data::FieldPtr field_, QWidget* parent_, const char* name_/*=0*/)
+ : FieldWidget(field_, parent_, name_), m_comboBox(0) {
+
+ m_comboBox = new KComboBox(this);
+ connect(m_comboBox, SIGNAL(activated(int)), SIGNAL(modified()));
+ // always have empty choice
+ m_comboBox->insertItem(QString::null);
+ m_comboBox->insertStringList(field_->allowed());
+ m_comboBox->setMinimumWidth(5*fontMetrics().maxWidth());
+
+ registerWidget();
+}
+
+QString ChoiceFieldWidget::text() const {
+ return m_comboBox->currentText();
+}
+
+void ChoiceFieldWidget::setText(const QString& text_) {
+ blockSignals(true);
+
+ m_comboBox->blockSignals(true);
+ m_comboBox->setCurrentItem(text_);
+ m_comboBox->blockSignals(false);
+
+ blockSignals(false);
+}
+
+void ChoiceFieldWidget::clear() {
+ m_comboBox->setCurrentItem(0); // first item is empty
+ editMultiple(false);
+}
+
+void ChoiceFieldWidget::updateFieldHook(Data::FieldPtr, Data::FieldPtr newField_) {
+ QString value = text();
+ m_comboBox->clear();
+ // always have empty choice
+ m_comboBox->insertItem(QString::null);
+ m_comboBox->insertStringList(newField_->allowed());
+ m_comboBox->setCurrentText(value);
+}
+
+QWidget* ChoiceFieldWidget::widget() {
+ return m_comboBox;
+}
+
+#include "choicefieldwidget.moc"
diff --git a/src/gui/choicefieldwidget.h b/src/gui/choicefieldwidget.h
new file mode 100644
index 0000000..a2c40f5
--- /dev/null
+++ b/src/gui/choicefieldwidget.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef CHOICEFIELDWIDGET_H
+#define CHOICEFIELDWIDGET_H
+
+#include "fieldwidget.h"
+#include "../datavectors.h"
+
+class KComboBox;
+
+namespace Tellico {
+ namespace GUI {
+
+/**
+ * @author Robby Stephenson
+ */
+class ChoiceFieldWidget : public FieldWidget {
+Q_OBJECT
+
+public:
+ ChoiceFieldWidget(Data::FieldPtr field, QWidget* parent, const char* name=0);
+ virtual ~ChoiceFieldWidget() {}
+
+ virtual QString text() const;
+ virtual void setText(const QString& text);
+
+public slots:
+ virtual void clear();
+
+protected:
+ virtual QWidget* widget();
+ virtual void updateFieldHook(Data::FieldPtr oldField, Data::FieldPtr newField);
+
+private:
+ KComboBox* m_comboBox;
+};
+
+ } // end GUI namespace
+} // end namespace
+#endif
diff --git a/src/gui/collectiontypecombo.cpp b/src/gui/collectiontypecombo.cpp
new file mode 100644
index 0000000..66749a3
--- /dev/null
+++ b/src/gui/collectiontypecombo.cpp
@@ -0,0 +1,53 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "collectiontypecombo.h"
+#include "../collection.h"
+#include "../collectionfactory.h"
+
+using Tellico::GUI::CollectionTypeCombo;
+
+CollectionTypeCombo::CollectionTypeCombo(QWidget* parent_) : ComboBox(parent_) {
+ reset();
+}
+
+void CollectionTypeCombo::reset() {
+ clear();
+ // I want to sort the collection names
+ const CollectionNameMap nameMap = CollectionFactory::nameMap();
+ QMap<QString, int> rNameMap;
+ for(CollectionNameMap::ConstIterator it = nameMap.begin(); it != nameMap.end(); ++it) {
+ rNameMap.insert(it.data(), it.key());
+ }
+ const QValueList<int> collTypes = rNameMap.values();
+ const QStringList collNames = rNameMap.keys();
+ int custom = -1;
+ const int total = collTypes.count();
+ // when i equals the size, then go back and do custom
+ for(int i = 0; i <= total; ++i) {
+ // put custom last
+ if(custom > -1 && count() >= total) {
+ break; // already done it!
+ } else if(i == total) {
+ i = custom;
+ } else if(collTypes[i] == Data::Collection::Base) {
+ custom = i;
+ continue;
+ }
+ insertItem(collNames[i], collTypes[i]);
+ }
+}
+
+void CollectionTypeCombo::setCurrentType(int type_) {
+ setCurrentData(type_);
+}
diff --git a/src/gui/collectiontypecombo.h b/src/gui/collectiontypecombo.h
new file mode 100644
index 0000000..8d3ef80
--- /dev/null
+++ b/src/gui/collectiontypecombo.h
@@ -0,0 +1,33 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_GUI_COLLECTIONTYPECOMBO_H
+#define TELLICO_GUI_COLLECTIONTYPECOMBO_H
+
+#include "combobox.h"
+
+namespace Tellico {
+
+namespace GUI {
+
+class CollectionTypeCombo : public ComboBox {
+public:
+ CollectionTypeCombo(QWidget* parent);
+ void reset();
+ void setCurrentType(int type);
+ int currentType() const { return currentData().toInt(); }
+};
+
+ }
+}
+#endif
diff --git a/src/gui/combobox.cpp b/src/gui/combobox.cpp
new file mode 100644
index 0000000..1aff29b
--- /dev/null
+++ b/src/gui/combobox.cpp
@@ -0,0 +1,71 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "combobox.h"
+
+#include <kdebug.h>
+
+using Tellico::GUI::ComboBox;
+
+ComboBox::ComboBox(QWidget* parent_) : KComboBox(parent_) {
+ setEditable(false);
+}
+
+void ComboBox::clear() {
+ KComboBox::clear();
+ m_data.clear();
+}
+
+void ComboBox::insertItem(const QString& s_, const QVariant& t_, int idx_/* =-1 */) {
+ KComboBox::insertItem(s_, idx_);
+ if(idx_ < 0) {
+ m_data.push_back(t_);
+ } else {
+ while(idx_ > static_cast<int>(m_data.count())) {
+ m_data.push_back(QVariant());
+ }
+ m_data.insert(m_data.at(idx_), t_);
+ }
+}
+
+void ComboBox::insertItems(const QStringList& s_, const QValueList<QVariant>& t_, int idx_ /*=-1*/) {
+ if(s_.count() != t_.count()) {
+ kdWarning() << "ComboBox::insertItems() - must have equal number of items in list!" << endl;
+ return;
+ }
+
+ for(uint i = 0; i < s_.count(); ++i) {
+ insertItem(s_[i], t_[i], idx_+i);
+ }
+}
+
+const QVariant& ComboBox::currentData() const {
+ return data(currentItem());
+}
+
+const QVariant& ComboBox::data(uint idx_) const {
+ if(idx_ >= m_data.count()) {
+ static QVariant t; // inescapable
+ return t;
+ }
+ return m_data[idx_];
+}
+
+void ComboBox::setCurrentData(const QVariant& data_) {
+ for(uint i = 0; i < m_data.count(); ++i) {
+ if(m_data[i] == data_) {
+ setCurrentItem(i);
+ break;
+ }
+ }
+}
diff --git a/src/gui/combobox.h b/src/gui/combobox.h
new file mode 100644
index 0000000..d02dbb8
--- /dev/null
+++ b/src/gui/combobox.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_GUI_COMBOBOX_H
+#define TELLICO_GUI_COMBOBOX_H
+
+#include <kcombobox.h>
+
+#include <qvariant.h>
+#include <qvaluelist.h>
+
+class QString;
+
+namespace Tellico {
+ namespace GUI {
+
+/**
+ * A combobox for mapping a QVariant to each item.
+ *
+ * @author Robby Stephenson
+ */
+class ComboBox : public KComboBox {
+public:
+ ComboBox(QWidget* parent_);
+
+ void clear();
+ const QVariant& currentData() const;
+ const QVariant& data(uint index) const;
+ void insertItem(const QString& string, const QVariant& datum, int index = -1);
+ void insertItems(const QStringList& strings, const QValueList<QVariant>& data, int index = -1);
+
+ // set current item to match data
+ void setCurrentData(const QVariant& data);
+
+private:
+ QValueList<QVariant> m_data;
+};
+
+ } // end namespace
+} //end namespace
+
+#endif
diff --git a/src/gui/counteditem.cpp b/src/gui/counteditem.cpp
new file mode 100644
index 0000000..08b4f25
--- /dev/null
+++ b/src/gui/counteditem.cpp
@@ -0,0 +1,113 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "counteditem.h"
+#include "../tellico_utils.h"
+#include "../tellico_debug.h"
+
+#include <kglobalsettings.h>
+#include <kstringhandler.h>
+
+#include <qpainter.h>
+#include <qpixmap.h>
+
+using Tellico::GUI::CountedItem;
+
+int CountedItem::compare(QListViewItem* item_, int col_, bool asc_) const {
+ GUI::ListView* lv = listView();
+ GUI::CountedItem* item = static_cast<GUI::CountedItem*>(item_);
+ if(lv->sortStyle() == GUI::ListView::SortByCount) {
+ if(count() < item->count()) {
+ return -1;
+ } else if(count() > item->count()) {
+ return 1;
+ } else {
+ return GUI::ListViewItem::compare(item, col_, asc_);
+ }
+ }
+ // for now, only other style is by text
+ return GUI::ListViewItem::compare(item, col_, asc_);
+}
+
+void CountedItem::paintCell(QPainter* p_, const QColorGroup& cg_,
+ int column_, int width_, int align_) {
+ if(!p_) {
+ return;
+ }
+
+ // always paint the cell
+
+ // show count is only for first column
+ if(column_ != 0) {
+ ListViewItem::paintCell(p_, cg_, column_, width_, align_);
+ return;
+ }
+
+ // set a catchable text so that we can have our own implementation (see further down)
+ // but still benefit from KListView::paintCell
+ QString oldText = text(column_);
+// if(oldText.isEmpty()) {
+ if(oldText == '\t') {
+ return; // avoid endless loop!
+ }
+
+ setText(column_, QChar('\t'));
+ ListViewItem::paintCell(p_, cg_, column_, width_, align_);
+ setText(column_, oldText);
+
+ int marg = listView()->itemMargin();
+ int r = marg;
+ const QPixmap* icon = pixmap(column_);
+ if(icon) {
+ r += icon->width() + marg;
+ }
+
+ QFontMetrics fm = p_->fontMetrics();
+ QString numText = QString::fromLatin1(" (%1)").arg(count());
+ // don't call CountedListViewItem::width() because that includes the count already
+ int w = ListViewItem::width(fm, listView(), column_);
+ int countWidth = fm.width(numText);
+ if(w+marg+r+countWidth > width_) {
+ oldText = KStringHandler::rPixelSqueeze(oldText, fm, width_-marg-r-countWidth);
+ }
+ if(isSelected()) {
+ p_->setPen(cg_.highlightedText());
+ } else {
+ p_->setPen(cg_.text());
+ }
+ QRect br(0, height(), r, 0);
+ if(!oldText.isEmpty() && !oldText.startsWith(QChar('\t'))) {
+ p_->drawText(r, 0, width_-marg-r, height(), align_ | AlignVCenter, oldText, -1, &br);
+ }
+
+ if(isSelected()) {
+ p_->setPen(cg_.highlightedText());
+ } else {
+ if(!Tellico::contrastColor.isValid()) {
+ updateContrastColor(cg_);
+ }
+ p_->setPen(Tellico::contrastColor);
+ }
+ p_->drawText(br.right(), 0, width_-marg-br.right(), height(), align_ | Qt::AlignVCenter, numText);
+}
+
+int CountedItem::width(const QFontMetrics& fm_, const QListView* lv_, int column_) const {
+ int w = ListViewItem::width(fm_, lv_, column_);
+
+ // show count is only for first column
+ if(column_ == 0) {
+ QString numText = QString::fromLatin1(" (%1)").arg(count());
+ w += fm_.width(numText) + 2; // add a little pad
+ }
+ return w;
+}
diff --git a/src/gui/counteditem.h b/src/gui/counteditem.h
new file mode 100644
index 0000000..9ea0138
--- /dev/null
+++ b/src/gui/counteditem.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef COUNTEDITEM_H
+#define COUNTEDITEM_H
+
+#include "listview.h"
+
+class QPainter;
+class QColorGroup;
+class QFontMetrics;
+
+namespace Tellico {
+ namespace GUI {
+
+/**
+ * @author Robby Stephenson
+ */
+class CountedItem : public GUI::ListViewItem {
+public:
+ CountedItem(ListView* parent) : ListViewItem(parent) {}
+ CountedItem(ListViewItem* parent) : ListViewItem(parent) {}
+
+ virtual int compare(QListViewItem* item, int col, bool ascending) const;
+ /**
+ * Paints the cell, adding the number count.
+ */
+ virtual void paintCell(QPainter* p, const QColorGroup& cg,
+ int column, int width, int align);
+ virtual int width(const QFontMetrics& fm, const QListView* lv, int c) const;
+
+ virtual int count() const { return childCount(); }
+ virtual int realChildCount() const { return count(); }
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/gui/datefieldwidget.cpp b/src/gui/datefieldwidget.cpp
new file mode 100644
index 0000000..d0609d6
--- /dev/null
+++ b/src/gui/datefieldwidget.cpp
@@ -0,0 +1,52 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "datefieldwidget.h"
+#include "datewidget.h"
+#include "../field.h"
+
+using Tellico::GUI::DateFieldWidget;
+
+DateFieldWidget::DateFieldWidget(Data::FieldPtr field_, QWidget* parent_, const char* name_/*=0*/)
+ : FieldWidget(field_, parent_, name_) {
+
+ m_widget = new DateWidget(this);
+ connect(m_widget, SIGNAL(signalModified()), SIGNAL(modified()));
+
+ registerWidget();
+}
+
+QString DateFieldWidget::text() const {
+ return m_widget->text();
+}
+
+void DateFieldWidget::setText(const QString& text_) {
+ blockSignals(true);
+ m_widget->blockSignals(true);
+
+ m_widget->setDate(text_);
+
+ m_widget->blockSignals(false);
+ blockSignals(false);
+}
+
+void DateFieldWidget::clear() {
+ m_widget->clear();
+ editMultiple(false);
+}
+
+QWidget* DateFieldWidget::widget() {
+ return m_widget;
+}
+
+#include "datefieldwidget.moc"
diff --git a/src/gui/datefieldwidget.h b/src/gui/datefieldwidget.h
new file mode 100644
index 0000000..e3c2d55
--- /dev/null
+++ b/src/gui/datefieldwidget.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef DATEFIELDWIDGET_H
+#define DATEFIELDWIDGET_H
+
+#include "fieldwidget.h"
+#include "../datavectors.h"
+
+class QString;
+
+namespace Tellico {
+ namespace GUI {
+ class DateWidget;
+
+/**
+ * @author Robby Stephenson
+ */
+class DateFieldWidget : public FieldWidget {
+Q_OBJECT
+
+public:
+ DateFieldWidget(Data::FieldPtr field, QWidget* parent, const char* name=0);
+ virtual ~DateFieldWidget() {}
+
+ virtual QString text() const;
+ virtual void setText(const QString& text);
+
+public slots:
+ virtual void clear();
+
+protected:
+ virtual QWidget* widget();
+
+private:
+ DateWidget* m_widget;
+};
+
+ } // end GUI namespace
+} // end namespace
+#endif
diff --git a/src/gui/datewidget.cpp b/src/gui/datewidget.cpp
new file mode 100644
index 0000000..42e2d4c
--- /dev/null
+++ b/src/gui/datewidget.cpp
@@ -0,0 +1,279 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+// this class borrows heavily from kdateedit.h in the kdepim module
+// which is Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
+// and published under the LGPL
+
+#include "datewidget.h"
+
+#include <kdebug.h>
+#include <kcombobox.h>
+#include <kpushbutton.h>
+#include <kdatepicker.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kglobalsettings.h>
+#include <kcalendarsystem.h>
+
+#include <qvbox.h>
+#include <qlayout.h>
+
+using Tellico::GUI::SpinBox;
+using Tellico::GUI::DateWidget;
+
+SpinBox::SpinBox(int min, int max, QWidget *parent) : QSpinBox(min, max, 1, parent)
+{
+ editor()->setAlignment(AlignRight);
+ // I want to be able to omit the day
+ // an empty string just removes the special value, so set white space
+ setSpecialValueText(QChar(' '));
+}
+
+DateWidget::DateWidget(QWidget* parent_, const char* name_) : QWidget(parent_, name_) {
+ QHBoxLayout* l = new QHBoxLayout(this, 0, 4);
+
+ KLocale* locale = KGlobal::locale();
+
+ // 0 allows empty value
+ m_daySpin = new SpinBox(0, 31, this);
+ l->addWidget(m_daySpin, 1);
+
+ m_monthCombo = new KComboBox(false, this);
+ l->addWidget(m_monthCombo, 1);
+ // allow empty item
+ m_monthCombo->insertItem(QString::null);
+ QDate d;
+ for(int i = 1; ; ++i) {
+ QString str = locale->calendar()->monthName(i, locale->calendar()->year(d));
+ if(str.isNull()) {
+ break;
+ }
+ m_monthCombo->insertItem(str);
+ }
+
+ m_yearSpin = new SpinBox(locale->calendar()->minValidYear(),
+ locale->calendar()->maxValidYear(), this);
+ l->addWidget(m_yearSpin, 1);
+
+ connect(m_daySpin, SIGNAL(valueChanged(int)), SLOT(slotDateChanged()));
+ connect(m_monthCombo, SIGNAL(activated(int)), SLOT(slotDateChanged()));
+ connect(m_yearSpin, SIGNAL(valueChanged(int)), SLOT(slotDateChanged()));
+
+ m_dateButton = new KPushButton(this);
+ m_dateButton->setIconSet(SmallIconSet(QString::fromLatin1("date")));
+ connect(m_dateButton, SIGNAL(clicked()), SLOT(slotShowPicker()));
+ l->addWidget(m_dateButton, 0);
+
+ m_frame = new QVBox(0, 0, WType_Popup);
+ m_frame->setFrameStyle(QFrame::PopupPanel | QFrame::Raised);
+ m_frame->setLineWidth(3);
+ m_frame->hide();
+
+ m_picker = new KDatePicker(m_frame, 0); // must include name to get correct constructor
+ connect(m_picker, SIGNAL(dateEntered(QDate)), SLOT(slotDateEntered(QDate)));
+ connect(m_picker, SIGNAL(dateSelected(QDate)), SLOT(slotDateSelected(QDate)));
+}
+
+void DateWidget::slotDateChanged() {
+ int day = m_daySpin->value();
+ day = QMIN(QMAX(day, m_daySpin->minValue()), m_daySpin->maxValue());
+
+ int m = m_monthCombo->currentItem();
+ m = QMIN(QMAX(m, 0), m_monthCombo->count()-1);
+
+ int y = m_yearSpin->value();
+ y = QMIN(QMAX(y, m_yearSpin->minValue()), m_yearSpin->maxValue());
+
+ // if all are valid, set this date
+ if(day > m_daySpin->minValue() && m > 0 && y > m_yearSpin->minValue()) {
+ QDate d(y, m, day);
+ setDate(d);
+ }
+ emit signalModified();
+}
+
+QDate DateWidget::date() const {
+ // possible for either day, month, or year to be empty
+ // in which case a null date is returned
+ int day = m_daySpin->value();
+ // min value is the empty one
+ if(day == m_daySpin->minValue()) {
+ return QDate();
+ }
+ int month = m_monthCombo->currentItem();
+ if(month == 0) {
+ return QDate();
+ }
+ int year = m_yearSpin->value();
+ if(year == m_yearSpin->minValue()) {
+ return QDate();
+ }
+ return QDate(year, month, day);
+}
+
+QString DateWidget::text() const {
+ // possible for either day, month, or year to be empty
+ // but not all three
+ bool empty = true;
+ // format is "year-month-day"
+ QString s;
+ if(m_yearSpin->value() > m_yearSpin->minValue()) {
+ s += QString::number(m_yearSpin->value());
+ empty = false;
+ }
+ s += '-';
+ // first item is empty
+ if(m_monthCombo->currentItem() > 0) {
+ s += QString::number(m_monthCombo->currentItem());
+ empty = false;
+ }
+ s += '-';
+ if(m_daySpin->value() > m_daySpin->minValue()) {
+ s += QString::number(m_daySpin->value());
+ empty = false;
+ }
+ return empty ? QString() : s;
+}
+
+void DateWidget::setDate(const QDate& date_) {
+ m_daySpin->blockSignals(true);
+ m_monthCombo->blockSignals(true);
+ m_yearSpin->blockSignals(true);
+
+ const KCalendarSystem * calendar = KGlobal::locale()->calendar();
+ m_daySpin->setMaxValue(calendar->daysInMonth(date_));
+ m_daySpin->setValue(calendar->day(date_));
+ m_monthCombo->setCurrentItem(calendar->month(date_)); // don't subtract 1 since there's the blank first item
+ m_yearSpin->setValue(calendar->year(date_));
+
+ m_daySpin->blockSignals(false);
+ m_monthCombo->blockSignals(false);
+ m_yearSpin->blockSignals(false);
+}
+
+void DateWidget::setDate(const QString& date_) {
+ m_daySpin->blockSignals(true);
+ m_monthCombo->blockSignals(true);
+ m_yearSpin->blockSignals(true);
+
+ QStringList s = QStringList::split('-', date_, true);
+ bool ok = true;
+ int y = s.count() > 0 ? s[0].toInt(&ok) : m_yearSpin->minValue();
+ if(!ok) {
+ y = m_yearSpin->minValue();
+ ok = true;
+ }
+ y = QMIN(QMAX(y, m_yearSpin->minValue()), m_yearSpin->maxValue());
+ m_yearSpin->setValue(y);
+
+ int m = s.count() > 1 ? s[1].toInt(&ok) : 0;
+ if(!ok) {
+ m = 0;
+ ok = true;
+ }
+ m = QMIN(QMAX(m, 0), m_monthCombo->count()-1);
+ m_monthCombo->setCurrentItem(m);
+
+ // need to update number of days in month
+ // for now set date to 1
+ QDate date(y, (m == 0 ? 1 : m), 1);
+ m_daySpin->blockSignals(true);
+ m_daySpin->setMaxValue(KGlobal::locale()->calendar()->daysInMonth(date));
+ m_daySpin->blockSignals(false);
+
+ int day = s.count() > 2 ? s[2].toInt(&ok) : m_daySpin->minValue();
+ if(!ok) {
+ day = m_daySpin->minValue();
+ }
+ day = QMIN(QMAX(day, m_daySpin->minValue()), m_daySpin->maxValue());
+ m_daySpin->setValue(day);
+
+ m_daySpin->blockSignals(false);
+ m_monthCombo->blockSignals(false);
+ m_yearSpin->blockSignals(false);
+
+ // if all are valid, set this date
+ if(day > m_daySpin->minValue() && m > 0 && y > m_yearSpin->minValue()) {
+ QDate d(y, m, day);
+ m_picker->blockSignals(true);
+ m_picker->setDate(d);
+ m_picker->blockSignals(false);
+ }
+}
+
+void DateWidget::clear() {
+ m_daySpin->blockSignals(true);
+ m_monthCombo->blockSignals(true);
+ m_yearSpin->blockSignals(true);
+ m_picker->blockSignals(true);
+
+ m_daySpin->setValue(m_daySpin->minValue());
+ m_monthCombo->setCurrentItem(0);
+ m_yearSpin->setValue(m_yearSpin->minValue());
+ m_picker->setDate(QDate::currentDate());
+
+ m_daySpin->blockSignals(false);
+ m_monthCombo->blockSignals(false);
+ m_yearSpin->blockSignals(false);
+ m_picker->blockSignals(false);
+}
+
+void DateWidget::slotShowPicker() {
+ QRect desk = KGlobalSettings::desktopGeometry(this);
+ QPoint popupPoint = mapToGlobal(QPoint(0, 0));
+
+ int dateFrameHeight = m_frame->sizeHint().height();
+ if(popupPoint.y() + height() + dateFrameHeight > desk.bottom()) {
+ popupPoint.setY(popupPoint.y() - dateFrameHeight);
+ } else {
+ popupPoint.setY(popupPoint.y() + height());
+ }
+ int dateFrameWidth = m_frame->sizeHint().width();
+ if(popupPoint.x() + dateFrameWidth > desk.right()) {
+ popupPoint.setX(desk.right() - dateFrameWidth);
+ }
+
+ if(popupPoint.x() < desk.left()) {
+ popupPoint.setX( desk.left());
+ }
+ if(popupPoint.y() < desk.top()) {
+ popupPoint.setY(desk.top());
+ }
+
+ m_frame->move(popupPoint);
+
+ QDate d = date();
+ if(d.isValid()) {
+ m_picker->setDate(d);
+ }
+
+ m_frame->show();
+}
+
+void DateWidget::slotDateSelected(QDate date_) {
+ if(date_.isValid()) {
+ setDate(date_);
+ emit signalModified();
+ m_frame->hide();
+ }
+}
+
+void DateWidget::slotDateEntered(QDate date_) {
+ if(date_.isValid()) {
+ setDate(date_);
+ emit signalModified();
+ }
+}
+
+#include "datewidget.moc"
diff --git a/src/gui/datewidget.h b/src/gui/datewidget.h
new file mode 100644
index 0000000..93d7bcb
--- /dev/null
+++ b/src/gui/datewidget.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICODATEWIDGET_H
+#define TELLICODATEWIDGET_H
+
+#include <qspinbox.h>
+#include <qdatetime.h>
+
+class KComboBox;
+class KPushButton;
+class KDatePicker;
+
+class QVBox;
+class QString;
+
+namespace Tellico {
+ namespace GUI {
+
+class SpinBox : public QSpinBox {
+Q_OBJECT
+
+public:
+ SpinBox(int min, int max, QWidget *parent);
+};
+
+/**
+ * @author Robby Stephenson
+ */
+class DateWidget : public QWidget {
+Q_OBJECT
+
+public:
+ DateWidget(QWidget* parent, const char* name = 0);
+ ~DateWidget() {}
+
+ QDate date() const;
+ QString text() const;
+ void setDate(const QDate& date);
+ void setDate(const QString& date);
+ void clear();
+
+signals:
+ void signalModified();
+
+private slots:
+ void slotDateChanged();
+ void slotShowPicker();
+ void slotDateSelected(QDate newDate);
+ void slotDateEntered(QDate newDate);
+
+private:
+ SpinBox* m_daySpin;
+ KComboBox* m_monthCombo;
+ SpinBox* m_yearSpin;
+ KPushButton* m_dateButton;
+
+ QVBox* m_frame;
+ KDatePicker* m_picker;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/gui/fieldwidget.cpp b/src/gui/fieldwidget.cpp
new file mode 100644
index 0000000..6a9fc66
--- /dev/null
+++ b/src/gui/fieldwidget.cpp
@@ -0,0 +1,201 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "fieldwidget.h"
+#include "linefieldwidget.h"
+#include "parafieldwidget.h"
+#include "boolfieldwidget.h"
+#include "choicefieldwidget.h"
+#include "numberfieldwidget.h"
+#include "urlfieldwidget.h"
+#include "imagefieldwidget.h"
+#include "datefieldwidget.h"
+#include "tablefieldwidget.h"
+#include "ratingfieldwidget.h"
+#include "../field.h"
+
+#include <kdebug.h>
+#include <kurllabel.h>
+#include <klocale.h>
+
+#include <qlayout.h>
+#include <qwhatsthis.h>
+#include <qregexp.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qstyle.h>
+#include <qtimer.h>
+
+namespace {
+ // if you change this, update numberfieldwidget, too
+ const int FIELD_EDIT_WIDGET_INDEX = 2;
+}
+
+using Tellico::GUI::FieldWidget;
+
+const QRegExp FieldWidget::s_semiColon = QRegExp(QString::fromLatin1("\\s*;\\s*"));
+
+FieldWidget* FieldWidget::create(Data::FieldPtr field_, QWidget* parent_, const char* name_) {
+ switch (field_->type()) {
+ case Data::Field::Line:
+ return new GUI::LineFieldWidget(field_, parent_, name_);
+
+ case Data::Field::Para:
+ return new GUI::ParaFieldWidget(field_, parent_, name_);
+
+ case Data::Field::Bool:
+ return new GUI::BoolFieldWidget(field_, parent_, name_);
+
+ case Data::Field::Number:
+ return new GUI::NumberFieldWidget(field_, parent_, name_);
+
+ case Data::Field::Choice:
+ return new GUI::ChoiceFieldWidget(field_, parent_, name_);
+
+ case Data::Field::Table:
+ case Data::Field::Table2:
+ return new GUI::TableFieldWidget(field_, parent_, name_);
+
+ case Data::Field::Date:
+ return new GUI::DateFieldWidget(field_, parent_, name_);
+
+ case Data::Field::URL:
+ return new GUI::URLFieldWidget(field_, parent_, name_);
+
+ case Data::Field::Image:
+ return new GUI::ImageFieldWidget(field_, parent_, name_);
+
+ case Data::Field::Rating:
+ return new GUI::RatingFieldWidget(field_, parent_, name_);
+
+ case Data::Field::ReadOnly:
+ case Data::Field::Dependent:
+ kdWarning() << "FieldWidget::create() - read-only/dependent field, this shouldn't have been called" << endl;
+ return 0;
+
+ default:
+ kdWarning() << "FieldWidget::create() - unknown field type = " << field_->type() << endl;
+ return 0;
+ }
+}
+
+FieldWidget::FieldWidget(Data::FieldPtr field_, QWidget* parent_, const char* name_/*=0*/)
+ : QWidget(parent_, name_), m_field(field_) {
+ QHBoxLayout* l = new QHBoxLayout(this, 2, 2); // parent, margin, spacing
+ l->addSpacing(4); // add some more space in the columns between widgets
+ if(QCString(style().name()).lower().find("keramik", 0, false) > -1) {
+ l->setMargin(1);
+ }
+
+ Data::Field::Type type = field_->type();
+ QString s = i18n("Edit Label", "%1:").arg(field_->title());
+ if(type == Data::Field::URL) {
+ // set URL to null for now
+ m_label = new KURLLabel(QString::null, s, this);
+ } else {
+ m_label = new QLabel(s, this);
+ }
+ m_label->setFixedWidth(m_label->sizeHint().width());
+ l->addWidget(m_label);
+
+ // expands indicates if the edit widget should expand to full width of widget
+ m_expands = (type == Data::Field::Line
+ || type == Data::Field::Para
+ || type == Data::Field::Number
+ || type == Data::Field::URL
+ || type == Data::Field::Table
+ || type == Data::Field::Table2
+ || type == Data::Field::Image
+ || type == Data::Field::Date);
+
+ m_editMultiple = new QCheckBox(this);
+ m_editMultiple->setChecked(true);
+ m_editMultiple->setFixedWidth(m_editMultiple->sizeHint().width()); // don't let it have any extra space
+ connect(m_editMultiple, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
+ l->addWidget(m_editMultiple);
+
+ QWhatsThis::add(this, field_->description());
+ // after letting the subclass get created, insert default value
+ QTimer::singleShot(0, this, SLOT(insertDefault()));
+}
+
+void FieldWidget::insertDefault() {
+ setText(m_field->defaultValue());
+}
+
+bool FieldWidget::isEnabled() {
+ return widget()->isEnabled();
+}
+
+void FieldWidget::setEnabled(bool enabled_) {
+ if(enabled_ == isEnabled()) {
+ return;
+ }
+
+ widget()->setEnabled(enabled_);
+ m_editMultiple->setChecked(enabled_);
+}
+
+int FieldWidget::labelWidth() const {
+ return m_label->sizeHint().width();
+}
+
+void FieldWidget::setLabelWidth(int width_) {
+ m_label->setFixedWidth(width_);
+}
+
+bool FieldWidget::expands() const {
+ return m_expands;
+}
+
+void FieldWidget::editMultiple(bool show_) {
+ if(show_ == m_editMultiple->isShown()) {
+ return;
+ }
+
+ // FIXME: maybe modified should only be signaled when the button is toggle on
+ if(show_) {
+ m_editMultiple->show();
+ connect(m_editMultiple, SIGNAL(clicked()), this, SIGNAL(modified()));
+ } else {
+ m_editMultiple->hide();
+ disconnect(m_editMultiple, SIGNAL(clicked()), this, SIGNAL(modified()));
+ }
+ // the widget length needs to be updated since it gets shorter
+ widget()->updateGeometry();
+}
+
+void FieldWidget::registerWidget() {
+ QWidget* w = widget();
+ m_label->setBuddy(w);
+ if(w->isFocusEnabled()) {
+ setFocusProxy(w);
+ }
+
+ QHBoxLayout* l = static_cast<QHBoxLayout*>(layout());
+ l->insertWidget(FIELD_EDIT_WIDGET_INDEX, w, m_expands ? 1 : 0 /*stretch*/);
+ if(!m_expands) {
+ l->insertStretch(FIELD_EDIT_WIDGET_INDEX+1, 1 /*stretch*/);
+ }
+ updateGeometry();
+}
+
+void FieldWidget::updateField(Data::FieldPtr oldField_, Data::FieldPtr newField_) {
+ m_field = newField_;
+ m_label->setText(i18n("Edit Label", "%1:").arg(newField_->title()));
+ updateGeometry();
+ QWhatsThis::add(this, newField_->description());
+ updateFieldHook(oldField_, newField_);
+}
+
+#include "fieldwidget.moc"
diff --git a/src/gui/fieldwidget.h b/src/gui/fieldwidget.h
new file mode 100644
index 0000000..dd34ebb
--- /dev/null
+++ b/src/gui/fieldwidget.h
@@ -0,0 +1,91 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef FIELDWIDGET_H
+#define FIELDWIDGET_H
+
+#include "../datavectors.h"
+
+#include <qwidget.h>
+#include <qregexp.h>
+
+class QLabel;
+class QCheckBox;
+class QString;
+
+namespace Tellico {
+ namespace Data {
+ class Field;
+ }
+ namespace GUI {
+
+/**
+ * The FieldWidget class is a box that shows a label, then a widget which depends
+ * on the field type, and then a checkbox for multiple editing.
+ *
+ * @author Robby Stephenson
+ */
+class FieldWidget : public QWidget {
+Q_OBJECT
+
+public:
+ FieldWidget(Data::FieldPtr field, QWidget* parent, const char* name=0);
+ virtual ~FieldWidget() {}
+
+ Data::FieldPtr field() const { return m_field; }
+ virtual QString text() const = 0;
+ virtual void setText(const QString& text) = 0;
+
+ int labelWidth() const;
+ void setLabelWidth(int width);
+ bool isEnabled();
+ bool expands() const;
+ void editMultiple(bool show);
+ // calls updateFieldHook()
+ void updateField(Data::FieldPtr oldField, Data::FieldPtr newField);
+
+ // only used by LineFieldWidget, really
+ virtual void addCompletionObjectItem(const QString&) {}
+
+ // factory function
+ static FieldWidget* create(Data::FieldPtr field, QWidget* parent, const char* name=0);
+
+public slots:
+ virtual void insertDefault();
+ virtual void clear() = 0;
+ void setEnabled(bool enabled);
+
+signals:
+ virtual void modified();
+
+protected:
+ QLabel* label() { return m_label; } // needed so the URLField can handle clicks on the label
+ virtual QWidget* widget() = 0;
+ void registerWidget();
+
+ // not all widgets have to be updated when the field changes
+ virtual void updateFieldHook(Data::FieldPtr, Data::FieldPtr) {}
+
+ static const QRegExp s_semiColon;
+
+private:
+ Data::FieldPtr m_field;
+ QLabel* m_label;
+ QCheckBox* m_editMultiple;
+
+ bool m_expands;
+};
+
+ } // end GUI namespace
+} // end namespace
+#endif
diff --git a/src/gui/imagefieldwidget.cpp b/src/gui/imagefieldwidget.cpp
new file mode 100644
index 0000000..2cb9b40
--- /dev/null
+++ b/src/gui/imagefieldwidget.cpp
@@ -0,0 +1,54 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "imagefieldwidget.h"
+#include "imagewidget.h"
+#include "../field.h"
+#include "../latin1literal.h"
+
+using Tellico::GUI::ImageFieldWidget;
+
+ImageFieldWidget::ImageFieldWidget(Data::FieldPtr field_, QWidget* parent_, const char* name_/*=0*/)
+ : FieldWidget(field_, parent_, name_) {
+
+ m_widget = new ImageWidget(this);
+ m_widget->setLinkOnlyChecked(field_->property(QString::fromLatin1("link")) == Latin1Literal("true"));
+ connect(m_widget, SIGNAL(signalModified()), SIGNAL(modified()));
+
+ registerWidget();
+}
+
+QString ImageFieldWidget::text() const {
+ return m_widget->id();
+}
+
+void ImageFieldWidget::setText(const QString& text_) {
+ blockSignals(true);
+ m_widget->blockSignals(true);
+
+ m_widget->setImage(text_);
+
+ m_widget->blockSignals(false);
+ blockSignals(false);
+}
+
+void ImageFieldWidget::clear() {
+ m_widget->slotClear();
+ editMultiple(false);
+}
+
+QWidget* ImageFieldWidget::widget() {
+ return m_widget;
+}
+
+#include "imagefieldwidget.moc"
diff --git a/src/gui/imagefieldwidget.h b/src/gui/imagefieldwidget.h
new file mode 100644
index 0000000..b5ebea5
--- /dev/null
+++ b/src/gui/imagefieldwidget.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef IMAGEFIELDWIDGET_H
+#define IMAGEFIELDWIDGET_H
+
+#include "fieldwidget.h"
+#include "../datavectors.h"
+
+class QString;
+
+namespace Tellico {
+ namespace GUI {
+ class ImageWidget;
+
+/**
+ * @author Robby Stephenson
+ */
+class ImageFieldWidget : public FieldWidget {
+Q_OBJECT
+
+public:
+ ImageFieldWidget(Data::FieldPtr field, QWidget* parent, const char* name=0);
+ virtual ~ImageFieldWidget() {}
+
+ virtual QString text() const;
+ virtual void setText(const QString& text);
+
+public slots:
+ virtual void clear();
+
+protected:
+ virtual QWidget* widget();
+
+private:
+ ImageWidget* m_widget;
+};
+
+ } // end GUI namespace
+} // end namespace
+#endif
diff --git a/src/gui/imagewidget.cpp b/src/gui/imagewidget.cpp
new file mode 100644
index 0000000..92f75c3
--- /dev/null
+++ b/src/gui/imagewidget.cpp
@@ -0,0 +1,257 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "imagewidget.h"
+#include "../imagefactory.h"
+#include "../image.h"
+#include "../filehandler.h"
+#include "../tellico_debug.h"
+#include "../tellico_utils.h"
+
+#include <kfiledialog.h>
+#include <klocale.h>
+#include <kbuttonbox.h>
+#include <kurldrag.h>
+#include <kmessagebox.h>
+
+#include <qwmatrix.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qdragobject.h>
+#include <qapplication.h> // needed for drag distance
+
+namespace {
+ static const uint IMAGE_WIDGET_BUTTON_MARGIN = 8;
+ static const uint IMAGE_WIDGET_IMAGE_MARGIN = 4;
+ static const uint MAX_UNSCALED_WIDTH = 640;
+ static const uint MAX_UNSCALED_HEIGHT = 640;
+}
+
+using Tellico::GUI::ImageWidget;
+
+ImageWidget::ImageWidget(QWidget* parent_, const char* name_) : QWidget(parent_, name_) {
+ QHBoxLayout* l = new QHBoxLayout(this);
+ l->setMargin(IMAGE_WIDGET_BUTTON_MARGIN);
+ m_label = new QLabel(this);
+ m_label->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored));
+ m_label->setFrameStyle(QFrame::Panel | QFrame::Sunken);
+ m_label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
+ l->addWidget(m_label, 1);
+ l->addSpacing(IMAGE_WIDGET_BUTTON_MARGIN);
+
+ QVBoxLayout* boxLayout = new QVBoxLayout(l);
+ boxLayout->addStretch(1);
+
+ KButtonBox* box = new KButtonBox(this, Vertical);
+ box->addButton(i18n("Select Image..."), this, SLOT(slotGetImage()));
+ box->addButton(i18n("Clear"), this, SLOT(slotClear()));
+ box->layout();
+ boxLayout->addWidget(box);
+
+ boxLayout->addSpacing(8);
+ m_cbLinkOnly = new QCheckBox(i18n("Save link only"), this);
+ connect(m_cbLinkOnly, SIGNAL(clicked()), SLOT(slotLinkOnlyClicked()));
+ boxLayout->addWidget(m_cbLinkOnly);
+
+ boxLayout->addStretch(1);
+ slotClear();
+
+ // accept image drops
+ setAcceptDrops(true);
+}
+
+void ImageWidget::setImage(const QString& id_) {
+ if(id_.isEmpty()) {
+ slotClear();
+ return;
+ }
+ m_imageID = id_;
+ m_pixmap = ImageFactory::pixmap(id_, MAX_UNSCALED_WIDTH, MAX_UNSCALED_HEIGHT);
+ const bool link = ImageFactory::imageInfo(id_).linkOnly;
+ m_cbLinkOnly->setChecked(link);
+ m_cbLinkOnly->setEnabled(link);
+ // if we're using a link, then the original URL _is_ the id
+ m_originalURL = link ? id_ : KURL();
+ m_scaled = QPixmap();
+ scale();
+
+ update();
+}
+
+void ImageWidget::setLinkOnlyChecked(bool link_) {
+ m_cbLinkOnly->setChecked(link_);
+}
+
+void ImageWidget::slotClear() {
+// m_image = Data::Image();
+ m_imageID = QString();
+ m_pixmap = QPixmap();
+ m_scaled = m_pixmap;
+ m_originalURL = KURL();
+
+ m_label->setPixmap(m_scaled);
+ m_cbLinkOnly->setChecked(false);
+ m_cbLinkOnly->setEnabled(true);
+ update();
+ emit signalModified();
+}
+
+void ImageWidget::scale() {
+ int ww = m_label->width() - 2*IMAGE_WIDGET_IMAGE_MARGIN;
+ int wh = m_label->height() - 2*IMAGE_WIDGET_IMAGE_MARGIN;
+ int pw = m_pixmap.width();
+ int ph = m_pixmap.height();
+
+ if(ww < pw || wh < ph) {
+ int newWidth, newHeight;
+ if(pw*wh < ph*ww) {
+ newWidth = static_cast<int>(static_cast<double>(pw)*wh/static_cast<double>(ph));
+ newHeight = wh;
+ } else {
+ newWidth = ww;
+ newHeight = static_cast<int>(static_cast<double>(ph)*ww/static_cast<double>(pw));
+ }
+
+ QWMatrix wm;
+ wm.scale(static_cast<double>(newWidth)/pw, static_cast<double>(newHeight)/ph);
+ m_scaled = m_pixmap.xForm(wm);
+ } else {
+ m_scaled = m_pixmap;
+ }
+ m_label->setPixmap(m_scaled);
+}
+
+void ImageWidget::resizeEvent(QResizeEvent *) {
+ if(m_pixmap.isNull()) {
+ return;
+ }
+
+ scale();
+ update();
+}
+
+void ImageWidget::slotGetImage() {
+ KURL url = KFileDialog::getImageOpenURL(QString::null, this);
+ if(url.isEmpty() || !url.isValid()) {
+ return;
+ }
+ loadImage(url);
+}
+
+void ImageWidget::slotLinkOnlyClicked() {
+ if(m_imageID.isEmpty()) {
+ // nothing to do, it has an empty image;
+ return;
+ }
+
+ bool link = m_cbLinkOnly->isChecked();
+ // if the user is trying to link and can't before there's no information about the url
+ // the let him know that
+ if(link && m_originalURL.isEmpty()) {
+ KMessageBox::sorry(this, i18n("Saving a link is only possible for newly added images."));
+ m_cbLinkOnly->setChecked(false);
+ return;
+ }
+ // need to reset image id to be the original url
+ // if we're linking only, then we want the image id to be the same as the url
+ // so it needs to be added to the cache all over again
+ // probably could do this without downloading the image all over again,
+ // but I'm not going to do that right now
+ const QString& id = ImageFactory::addImage(m_originalURL, false, KURL(), link);
+ // same image, so no need to call setImage
+ m_imageID = id;
+ emit signalModified();
+}
+
+void ImageWidget::mousePressEvent(QMouseEvent* event_) {
+ // Only interested in LMB
+ if(event_->button() == Qt::LeftButton) {
+ // Store the position of the mouse press.
+ // check if position is inside the label
+ if(m_label->geometry().contains(event_->pos())) {
+ m_dragStart = event_->pos();
+ } else {
+ m_dragStart = QPoint();
+ }
+ }
+}
+
+void ImageWidget::mouseMoveEvent(QMouseEvent* event_) {
+ int delay = QApplication::startDragDistance();
+ // Only interested in LMB
+ if(event_->state() & Qt::LeftButton) {
+ // only allow drag is the image is non-null, and the drag start point isn't null and the user dragged far enough
+ if(!m_imageID.isEmpty() && !m_dragStart.isNull() && (m_dragStart - event_->pos()).manhattanLength() > delay) {
+ const Data::Image& img = ImageFactory::imageById(m_imageID);
+ if(!img.isNull()) {
+ QImageDrag* drag = new QImageDrag(img, this);
+ drag->dragCopy();
+ }
+ }
+ }
+}
+
+void ImageWidget::dragEnterEvent(QDragEnterEvent* event_) {
+ event_->accept(KURLDrag::canDecode(event_) || QImageDrag::canDecode(event_) || QTextDrag::canDecode(event_));
+}
+
+void ImageWidget::dropEvent(QDropEvent* event_) {
+ QImage image;
+ KURL::List urls;
+ QString text;
+
+ GUI::CursorSaver cs(Qt::busyCursor);
+ if(QImageDrag::decode(event_, image)) {
+ // Qt reads PNG data by default
+ const QString& id = ImageFactory::addImage(image, QString::fromLatin1("PNG"));
+ if(!id.isEmpty() && id != m_imageID) {
+ setImage(id);
+ emit signalModified();
+ }
+ } else if(KURLDrag::decode(event_, urls)) {
+ if(urls.isEmpty()) {
+ return;
+ }
+ // only care about the first one
+ const KURL& url = urls[0];
+ if(url.isEmpty() || !url.isValid()) {
+ return;
+ }
+// kdDebug() << "ImageWidget::dropEvent() - " << url.prettyURL() << endl;
+ loadImage(url);
+ } else if(QTextDrag::decode(event_, text)) {
+ KURL url(text);
+ if(url.isEmpty() || !url.isValid()) {
+ return;
+ }
+ loadImage(url);
+ }
+}
+
+void ImageWidget::loadImage(const KURL& url_) {
+ const bool link = m_cbLinkOnly->isChecked();
+
+ GUI::CursorSaver cs;
+ // if we're linking only, then we want the image id to be the same as the url
+ const QString& id = ImageFactory::addImage(url_, false, KURL(), link);
+ if(id != m_imageID) {
+ setImage(id);
+ emit signalModified();
+ }
+ // at the end, cause setImage() resets it
+ m_originalURL = url_;
+ m_cbLinkOnly->setEnabled(true);
+}
+
+#include "imagewidget.moc"
diff --git a/src/gui/imagewidget.h b/src/gui/imagewidget.h
new file mode 100644
index 0000000..7780be4
--- /dev/null
+++ b/src/gui/imagewidget.h
@@ -0,0 +1,78 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICOIMAGEWIDGET_H
+#define TELLICOIMAGEWIDGET_H
+
+#include <kurl.h>
+#include <qwidget.h>
+#include <qpixmap.h>
+#include <qpoint.h>
+
+class QLabel;
+class QResizeEvent;
+class QMouseEvent;
+class QDragEnterEvent;
+class QDropEvent;
+class QCheckBox;
+
+namespace Tellico {
+ namespace GUI {
+
+/**
+ * @author Robby Stephenson
+ */
+class ImageWidget : public QWidget {
+Q_OBJECT
+
+public:
+ ImageWidget(QWidget* parent, const char* name = 0);
+ virtual ~ImageWidget() {}
+
+ const QString& id() const { return m_imageID; }
+ void setImage(const QString& id);
+ void setLinkOnlyChecked(bool l);
+
+public slots:
+ void slotClear();
+
+signals:
+ void signalModified();
+
+protected:
+ virtual void resizeEvent(QResizeEvent* ev);
+ virtual void mousePressEvent(QMouseEvent* ev);
+ virtual void mouseMoveEvent(QMouseEvent* ev);
+ virtual void dragEnterEvent(QDragEnterEvent* ev);
+ virtual void dropEvent(QDropEvent* ev);
+
+private slots:
+ void slotGetImage();
+ void slotLinkOnlyClicked();
+
+private:
+ void scale();
+ void loadImage(const KURL& url);
+
+ QString m_imageID;
+ QPixmap m_pixmap;
+ QPixmap m_scaled;
+ QLabel* m_label;
+ QCheckBox* m_cbLinkOnly;
+ KURL m_originalURL;
+ QPoint m_dragStart;
+};
+
+ } // end GUI namespace
+} // end namespace
+#endif
diff --git a/src/gui/kwidgetlister.cpp b/src/gui/kwidgetlister.cpp
new file mode 100644
index 0000000..80bf31b
--- /dev/null
+++ b/src/gui/kwidgetlister.cpp
@@ -0,0 +1,178 @@
+/* -*- c++ -*-
+ kwidgetlister.cpp
+
+ This file is part of libkdenetwork.
+ Copyright (c) 2001 Marc Mutz <mutz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifh Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this library with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "kwidgetlister.h"
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kpushbutton.h>
+#include <kiconloader.h>
+
+#include <qlayout.h>
+#include <qhbox.h>
+
+#include <assert.h>
+
+KWidgetLister::KWidgetLister( int minWidgets, int maxWidgets, QWidget *parent, const char* name )
+ : QWidget( parent, name )
+{
+ mWidgetList.setAutoDelete(TRUE);
+
+ mMinWidgets = QMAX( minWidgets, 1 );
+ mMaxWidgets = QMAX( maxWidgets, mMinWidgets + 1 );
+
+ //--------- the button box
+ mLayout = new QVBoxLayout(this, 0, 4);
+ mButtonBox = new QHBox(this);
+ mButtonBox->setSpacing(4);
+ mLayout->addWidget( mButtonBox );
+
+ mBtnMore = new KPushButton( i18n("more widgets","More"), mButtonBox );
+ mBtnMore->setIconSet(SmallIconSet(QString::fromLatin1("down")));
+ mButtonBox->setStretchFactor( mBtnMore, 0 );
+
+ mBtnFewer = new KPushButton( i18n("fewer widgets","Fewer"), mButtonBox );
+ mBtnFewer->setIconSet(SmallIconSet(QString::fromLatin1("up")));
+ mButtonBox->setStretchFactor( mBtnFewer, 0 );
+
+ QWidget *spacer = new QWidget( mButtonBox );
+ mButtonBox->setStretchFactor( spacer, 1 );
+
+ mBtnClear = new KPushButton( i18n("clear widgets","Clear"), mButtonBox );
+ mBtnClear->setIconSet(SmallIconSet(QString::fromLatin1("locationbar_erase")));
+ mButtonBox->setStretchFactor( mBtnClear, 0 );
+
+ //---------- connect everything
+ connect( mBtnMore, SIGNAL(clicked()),
+ this, SLOT(slotMore()) );
+ connect( mBtnFewer, SIGNAL(clicked()),
+ this, SLOT(slotFewer()) );
+ connect( mBtnClear, SIGNAL(clicked()),
+ this, SLOT(slotClear()) );
+
+ enableControls();
+}
+
+KWidgetLister::~KWidgetLister()
+{
+}
+
+void KWidgetLister::slotMore()
+{
+ // the class should make certain that slotMore can't
+ // be called when mMaxWidgets are on screen.
+ assert( (int)mWidgetList.count() < mMaxWidgets );
+
+ addWidgetAtEnd();
+ // adjustSize();
+ enableControls();
+}
+
+void KWidgetLister::slotFewer()
+{
+ // the class should make certain that slotFewer can't
+ // be called when mMinWidgets are on screen.
+ assert( (int)mWidgetList.count() > mMinWidgets );
+
+ removeLastWidget();
+ // adjustSize();
+ enableControls();
+}
+
+void KWidgetLister::slotClear()
+{
+ setNumberOfShownWidgetsTo( mMinWidgets );
+
+ // clear remaining widgets
+ QPtrListIterator<QWidget> it( mWidgetList );
+ for ( it.toFirst() ; it.current() ; ++it )
+ clearWidget( (*it) );
+
+ // adjustSize();
+ enableControls();
+ emit clearWidgets();
+}
+
+void KWidgetLister::addWidgetAtEnd(QWidget *w)
+{
+ if (!w) w = this->createWidget(this);
+
+ mLayout->insertWidget( mLayout->findWidget( mButtonBox ), w );
+ mWidgetList.append( w );
+ w->show();
+ enableControls();
+ emit widgetAdded();
+ emit widgetAdded(w);
+}
+
+void KWidgetLister::removeLastWidget()
+{
+ // The layout will take care that the
+ // widget is removed from screen, too.
+ mWidgetList.removeLast();
+ enableControls();
+ emit widgetRemoved();
+}
+
+void KWidgetLister::clearWidget( QWidget* /*aWidget*/ )
+{
+}
+
+QWidget* KWidgetLister::createWidget( QWidget* parent )
+{
+ return new QWidget( parent );
+}
+
+void KWidgetLister::setNumberOfShownWidgetsTo( int aNum )
+{
+ int superfluousWidgets = QMAX( (int)mWidgetList.count() - aNum, 0 );
+ int missingWidgets = QMAX( aNum - (int)mWidgetList.count(), 0 );
+
+ // remove superfluous widgets
+ for ( ; superfluousWidgets ; superfluousWidgets-- )
+ removeLastWidget();
+
+ // add missing widgets
+ for ( ; missingWidgets ; missingWidgets-- )
+ addWidgetAtEnd();
+}
+
+void KWidgetLister::enableControls()
+{
+ int count = mWidgetList.count();
+ bool isMaxWidgets = ( count >= mMaxWidgets );
+ bool isMinWidgets = ( count <= mMinWidgets );
+
+ mBtnMore->setEnabled( !isMaxWidgets );
+ mBtnFewer->setEnabled( !isMinWidgets );
+}
+
+#include "kwidgetlister.moc"
diff --git a/src/gui/kwidgetlister.h b/src/gui/kwidgetlister.h
new file mode 100644
index 0000000..e02b54c
--- /dev/null
+++ b/src/gui/kwidgetlister.h
@@ -0,0 +1,150 @@
+/* -*- c++ -*-
+ kwidgetlister.h
+
+ This file is part of libkdenetwork.
+ Copyright (c) 2001 Marc Mutz <mutz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifh Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this library with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef _KWIDGETLISTER_H_
+#define _KWIDGETLISTER_H_
+
+#include <qwidget.h>
+#include <qptrlist.h>
+
+class KPushButton;
+class QVBoxLayout;
+class QHBox;
+
+/** Simple widget that nonetheless does a lot of the dirty work for
+ the filter edit widgets (@ref KMSearchpatternEdit and @ref
+ KMFilterActionEdit). It provides a growable and shrinkable area
+ where widget may be displayed in rows. Widgets can be added by
+ hitting the provided 'More' button, removed by the 'Fewer' button
+ and cleared (e.g. reset, if an derived class implements that and
+ removed for all but @ref mMinWidgets).
+
+ To use this widget, derive from it with the template changed to
+ the type of widgets this class should list. Then reimplement @ref
+ addWidgetAtEnd, @ref removeLastWidget, calling the original
+ implementation as necessary. Instantate an object of the class and
+ put it in your dialog.
+
+ @short Widget that manages a list of other widgets (incl. 'more', 'fewer' and 'clear' buttons).
+ @author Marc Mutz <Marc@Mutz.com>
+ @see KMSearchPatternEdit::WidgetLister KMFilterActionEdit::WidgetLister
+
+*/
+
+class KWidgetLister : public QWidget
+{
+ Q_OBJECT
+public:
+ KWidgetLister( int minWidgets=1, int maxWidgets=8, QWidget* parent=0, const char* name=0 );
+ virtual ~KWidgetLister();
+
+protected slots:
+ /** Called whenever the user clicks on the 'more' button.
+ Reimplementations should call this method, because this
+ implementation does all the dirty work with adding the widgets
+ to the layout (through @ref addWidgetAtEnd) and enabling/disabling
+ the control buttons. */
+ virtual void slotMore();
+ /** Called whenever the user clicks on the 'fewer' button.
+ Reimplementations should call this method, because this
+ implementation does all the dirty work with removing the widgets
+ from the layout (through @ref removelastWidget) and
+ enabling/disabling the control buttons. */
+ virtual void slotFewer();
+ /** Called whenever the user clicks on the 'clear' button.
+ Reimplementations should call this method, because this
+ implementation does all the dirty work with removing all but
+ @ref mMinWidets widgets from the layout and enabling/disabling
+ the control buttons. */
+ virtual void slotClear();
+
+
+
+protected:
+ /** Adds a single widget. Doesn't care if there are already @ref
+ mMaxWidgets on screen and whether it should enable/disable any
+ controls. It simply does what it is asked to do. You want to
+ reimplement this method if you want to initialize the the widget
+ when showing it on screen. Make sure you call this
+ implementaion, though, since you cannot put the widget on screen
+ from derived classes (@p mLayout is private).
+ Make sure the parent of the QWidget to add is this KWidgetLister. */
+ virtual void addWidgetAtEnd(QWidget *w =0);
+ /** Removes a single (always the last) widget. Doesn't care if there
+ are still only @ref mMinWidgets left on screen and whether it
+ should enable/disable any controls. It simply does what it is
+ asked to do. You want to reimplement this method if you want to
+ save the the widget's state before removing it from screen. Make
+ sure you call this implementaion, though, since you should not
+ remove the widget from screen from derived classes. */
+ virtual void removeLastWidget();
+ /** Called to clear a given widget. The default implementation does
+ nothing. */
+ virtual void clearWidget( QWidget* );
+ /** Because QT 2.x does not support signals/slots in template
+ classes, we are forced to emulate this by forcing the
+ implementers of subclasses of KWidgetLister to reimplement this
+ function which replaces the "@p new @p T" call. */
+ virtual QWidget* createWidget( QWidget *parent );
+ /** Sets the number of widgets on scrren to exactly @p aNum. Doesn't
+ check if @p aNum is inside the range @p
+ [mMinWidgets,mMaxWidgets]. */
+ virtual void setNumberOfShownWidgetsTo( int aNum );
+ /** The list of widgets. Note that this list is set to auto-delete,
+ meaning that widgets that are removed from the screen by either
+ @ref slotFewer or @ref slotClear will be destroyed! */
+ QPtrList<QWidget> mWidgetList;
+ /** The minimum number of widgets that are to stay on screen. */
+ int mMinWidgets;
+ /** The maximum number of widgets that are to be shown on screen. */
+ int mMaxWidgets;
+
+signals:
+ /** This signal is emitted whenever a widget was added */
+ void widgetAdded();
+ /** This signal is emitted whenever a widget was added */
+ void widgetAdded(QWidget *);
+ /** This signal is emitted whenever a widget was removed */
+ void widgetRemoved();
+ /** This signal is emitted whenever the clear button is clicked */
+ void clearWidgets();
+
+private:
+ void enableControls();
+
+ KPushButton *mBtnMore, *mBtnFewer, *mBtnClear;
+ QVBoxLayout *mLayout;
+ QHBox *mButtonBox;
+};
+
+
+
+#endif /* _KWIDGETLISTER_H_ */
diff --git a/src/gui/lineedit.cpp b/src/gui/lineedit.cpp
new file mode 100644
index 0000000..6248880
--- /dev/null
+++ b/src/gui/lineedit.cpp
@@ -0,0 +1,150 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "lineedit.h"
+
+#include <kstdaction.h>
+#include <kactioncollection.h>
+#include <kspell.h>
+
+#include <qapplication.h>
+#include <qpainter.h>
+#include <qpopupmenu.h>
+
+using Tellico::GUI::LineEdit;
+
+LineEdit::LineEdit(QWidget* parent_, const char* name_) : KLineEdit(parent_, name_)
+ , m_drawHint(false)
+ , m_allowSpellCheck(false)
+ , m_enableSpellCheck(true)
+ , m_spell(0) {
+ m_spellAction = KStdAction::spelling(this, SLOT(slotCheckSpelling()), new KActionCollection(this));
+}
+
+void LineEdit::clear() {
+ KLineEdit::clear();
+ m_drawHint = true;
+ repaint();
+}
+
+void LineEdit::setText(const QString& text_) {
+ m_drawHint = text_.isEmpty();
+ repaint();
+ KLineEdit::setText(text_);
+}
+
+void LineEdit::setHint(const QString& hint_) {
+ m_hint = hint_;
+ m_drawHint = text().isEmpty();
+ repaint();
+}
+
+void LineEdit::focusInEvent(QFocusEvent* event_) {
+ if(m_drawHint) {
+ m_drawHint = false;
+ repaint();
+ }
+ KLineEdit::focusInEvent(event_);
+}
+
+void LineEdit::focusOutEvent(QFocusEvent* event_) {
+ if(text().isEmpty()) {
+ m_drawHint = true;
+ repaint();
+ }
+ KLineEdit::focusOutEvent(event_);
+}
+
+void LineEdit::drawContents(QPainter* painter_) {
+ // draw the regular line edit first
+ KLineEdit::drawContents(painter_);
+
+ // no need to draw anything else if in focus or no hint
+ if(hasFocus() || !m_drawHint || m_hint.isEmpty() || !text().isEmpty()) {
+ return;
+ }
+
+ // save current pen
+ QPen oldPen = painter_->pen();
+
+ // follow lead of kdepim and amarok, use disabled text color
+ painter_->setPen(palette().color(QPalette::Disabled, QColorGroup::Text));
+
+ QRect rect = contentsRect();
+ // again, follow kdepim and amarok lead, and pad by 2 pixels
+ rect.rLeft() += 2;
+ painter_->drawText(rect, AlignAuto | AlignVCenter, m_hint);
+
+ // reset pen
+ painter_->setPen(oldPen);
+}
+
+QPopupMenu* LineEdit::createPopupMenu() {
+ QPopupMenu* popup = KLineEdit::createPopupMenu();
+
+ if(!popup) {
+ return popup;
+ }
+
+ if(m_allowSpellCheck && echoMode() == QLineEdit::Normal && !isReadOnly()) {
+ popup->insertSeparator();
+
+ m_spellAction->plug(popup);
+ m_spellAction->setEnabled(m_enableSpellCheck && !text().isEmpty());
+ }
+
+ return popup;
+}
+
+void LineEdit::slotCheckSpelling() {
+ delete m_spell;
+ // re-use the action string to get translations
+ m_spell = new KSpell(this, m_spellAction->text(),
+ this, SLOT(slotSpellCheckReady(KSpell*)), 0, true, true);
+
+ connect(m_spell, SIGNAL(death()),
+ SLOT(spellCheckerFinished()));
+ connect(m_spell, SIGNAL(misspelling( const QString &, const QStringList &, unsigned int)),
+ SLOT(spellCheckerMisspelling( const QString &, const QStringList &, unsigned int)));
+ connect(m_spell, SIGNAL(corrected(const QString &, const QString &, unsigned int)),
+ SLOT(spellCheckerCorrected(const QString &, const QString &, unsigned int)));
+}
+
+void LineEdit::slotSpellCheckReady(KSpell* spell) {
+ spell->check(text());
+ connect(spell, SIGNAL(done(const QString&)), SLOT(slotSpellCheckDone(const QString&)));
+}
+
+void LineEdit::slotSpellCheckDone(const QString& newText) {
+ if(newText != text()) {
+ setText(newText);
+ }
+}
+
+void LineEdit::spellCheckerFinished() {
+ delete m_spell;
+ m_spell = 0;
+}
+
+void LineEdit::spellCheckerMisspelling(const QString &text, const QStringList&, unsigned int pos) {
+ setSelection(pos, pos + text.length());
+}
+
+void LineEdit::spellCheckerCorrected(const QString& oldWord, const QString& newWord, unsigned int pos) {
+ if(oldWord != newWord) {
+ setSelection(pos, pos + oldWord.length());
+ insert(newWord);
+ }
+}
+
+#include "lineedit.moc"
diff --git a/src/gui/lineedit.h b/src/gui/lineedit.h
new file mode 100644
index 0000000..af7d81b
--- /dev/null
+++ b/src/gui/lineedit.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_GUILINEEDIT_H
+#define TELLICO_GUILINEEDIT_H
+
+#include <klineedit.h>
+
+#include <qstring.h>
+
+class KAction;
+class KSpell;
+
+namespace Tellico {
+ namespace GUI {
+
+/**
+ * @author Robby Stephenson
+ */
+class LineEdit : public KLineEdit {
+Q_OBJECT
+
+public:
+ LineEdit(QWidget* parent = 0, const char* name = 0);
+
+ virtual void setText(const QString& text);
+ void setHint(const QString& hint);
+
+ // by default, spell check is not allowed, and no popupmenu item is created
+ void setAllowSpellCheck(bool b) { m_allowSpellCheck = b; }
+ // spell check may be allowed but disabled
+ void setEnableSpellCheck(bool b) { m_enableSpellCheck = b; }
+
+public slots:
+ void clear();
+
+protected:
+ virtual void focusInEvent(QFocusEvent* event);
+ virtual void focusOutEvent(QFocusEvent* event);
+ virtual void drawContents(QPainter* painter);
+ virtual QPopupMenu* createPopupMenu();
+
+private slots:
+ void slotCheckSpelling();
+ void slotSpellCheckReady(KSpell* spell);
+ void slotSpellCheckDone(const QString& text);
+ void spellCheckerMisspelling(const QString& text, const QStringList&, unsigned int pos);
+ void spellCheckerCorrected(const QString& oldText, const QString& newText, unsigned int pos);
+ void spellCheckerFinished();
+
+private:
+ QString m_hint;
+ bool m_drawHint;
+ KAction* m_spellAction;
+ bool m_allowSpellCheck;
+ bool m_enableSpellCheck;
+ KSpell* m_spell;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/gui/linefieldwidget.cpp b/src/gui/linefieldwidget.cpp
new file mode 100644
index 0000000..1535832
--- /dev/null
+++ b/src/gui/linefieldwidget.cpp
@@ -0,0 +1,90 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "linefieldwidget.h"
+#include "../field.h"
+#include "../isbnvalidator.h"
+#include "../fieldcompletion.h"
+#include "../latin1literal.h"
+#include "../tellico_kernel.h"
+#include "../gui/lineedit.h"
+
+using Tellico::GUI::LineFieldWidget;
+
+LineFieldWidget::LineFieldWidget(Data::FieldPtr field_, QWidget* parent_, const char* name_/*=0*/)
+ : FieldWidget(field_, parent_, name_) {
+
+ m_lineEdit = new GUI::LineEdit(this);
+ m_lineEdit->setAllowSpellCheck(true);
+ m_lineEdit->setEnableSpellCheck(field_->formatFlag() != Data::Field::FormatName);
+ connect(m_lineEdit, SIGNAL(textChanged(const QString&)), SIGNAL(modified()));
+
+ registerWidget();
+
+ if(field_->flags() & Data::Field::AllowCompletion) {
+ FieldCompletion* completion = new FieldCompletion(field_->flags() & Data::Field::AllowMultiple);
+ completion->setItems(Kernel::self()->valuesByFieldName(field_->name()));
+ completion->setIgnoreCase(true);
+ m_lineEdit->setCompletionObject(completion);
+ m_lineEdit->setAutoDeleteCompletionObject(true);
+ }
+
+ if(field_->name() == Latin1Literal("isbn")) {
+ m_lineEdit->setValidator(new ISBNValidator(this));
+ }
+}
+
+QString LineFieldWidget::text() const {
+ QString text = m_lineEdit->text();
+ if(field()->flags() & Data::Field::AllowMultiple) {
+ text.replace(s_semiColon, QString::fromLatin1("; "));
+ }
+ return text.stripWhiteSpace();
+}
+
+void LineFieldWidget::setText(const QString& text_) {
+ blockSignals(true);
+ m_lineEdit->blockSignals(true);
+ m_lineEdit->setText(text_);
+ m_lineEdit->blockSignals(false);
+ blockSignals(false);
+}
+
+void LineFieldWidget::clear() {
+ m_lineEdit->clear();
+ editMultiple(false);
+}
+
+void LineFieldWidget::addCompletionObjectItem(const QString& text_) {
+ m_lineEdit->completionObject()->addItem(text_);
+}
+
+void LineFieldWidget::updateFieldHook(Data::FieldPtr oldField_, Data::FieldPtr newField_) {
+ bool wasComplete = (oldField_->flags() & Data::Field::AllowCompletion);
+ bool isComplete = (newField_->flags() & Data::Field::AllowCompletion);
+ if(!wasComplete && isComplete) {
+ FieldCompletion* completion = new FieldCompletion(isComplete);
+ completion->setItems(Kernel::self()->valuesByFieldName(newField_->name()));
+ completion->setIgnoreCase(true);
+ m_lineEdit->setCompletionObject(completion);
+ m_lineEdit->setAutoDeleteCompletionObject(true);
+ } else if(wasComplete && !isComplete) {
+ m_lineEdit->completionObject()->clear();
+ }
+}
+
+QWidget* LineFieldWidget::widget() {
+ return m_lineEdit;
+}
+
+#include "linefieldwidget.moc"
diff --git a/src/gui/linefieldwidget.h b/src/gui/linefieldwidget.h
new file mode 100644
index 0000000..70dc175
--- /dev/null
+++ b/src/gui/linefieldwidget.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef LINEFIELDWIDGET_H
+#define LINEFIELDWIDGET_H
+
+#include "fieldwidget.h"
+#include "../datavectors.h"
+
+namespace Tellico {
+ namespace GUI {
+ class LineEdit;
+
+/**
+ * @author Robby Stephenson
+ */
+class LineFieldWidget : public FieldWidget {
+Q_OBJECT
+
+public:
+ LineFieldWidget(Data::FieldPtr field, QWidget* parent, const char* name=0);
+ virtual ~LineFieldWidget() {}
+
+ virtual QString text() const;
+ virtual void setText(const QString& text);
+ virtual void addCompletionObjectItem(const QString& text);
+
+public slots:
+ virtual void clear();
+
+protected:
+ virtual QWidget* widget();
+ virtual void updateFieldHook(Data::FieldPtr oldField, Data::FieldPtr newField);
+
+private:
+ GUI::LineEdit* m_lineEdit;
+};
+
+ } // end GUI namespace
+} // end namespace
+#endif
diff --git a/src/gui/listboxtext.cpp b/src/gui/listboxtext.cpp
new file mode 100644
index 0000000..8ec6fa2
--- /dev/null
+++ b/src/gui/listboxtext.cpp
@@ -0,0 +1,74 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : $EMAIL
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "listboxtext.h"
+#include "../tellico_utils.h"
+
+#include <qpainter.h>
+
+using Tellico::GUI::ListBoxText;
+
+ListBoxText::ListBoxText(QListBox* listbox_, const QString& text_)
+ : QListBoxText(listbox_, text_), m_colored(false) {
+}
+
+ListBoxText::ListBoxText(QListBox* listbox_, const QString& text_, QListBoxItem* after_)
+ : QListBoxText(listbox_, text_, after_), m_colored(false) {
+}
+
+int ListBoxText::width(const QListBox* listbox_) const {
+ if(m_colored) {
+ QFont font = listbox_->font();
+ font.setBold(true);
+ font.setItalic(true);
+ QFontMetrics fm(font);
+ return fm.width(text()) + 6;
+ } else {
+ return QListBoxText::width(listbox_);
+ }
+}
+
+// I don't want the height to change when colored
+// so all the items are at the same level for multi-column boxes
+int ListBoxText::height(const QListBox* listbox_) const {
+ return QListBoxText::height(listbox_);
+}
+
+void ListBoxText::setColored(bool colored_) {
+ if(m_colored != colored_) {
+ m_colored = colored_;
+ listBox()->triggerUpdate(false);
+ }
+}
+
+void ListBoxText::setText(const QString& text_) {
+ QListBoxText::setText(text_);
+ listBox()->triggerUpdate(true);
+}
+
+// mostly copied from QListBoxText::paint() in Qt 3.1.1
+void ListBoxText::paint(QPainter* painter_) {
+ if(m_colored) {
+ QFont font = painter_->font();
+ font.setBold(true);
+ font.setItalic(true);
+ painter_->setFont(font);
+ if(!isSelected()) {
+ painter_->setPen(Tellico::contrastColor);
+ }
+ }
+ int itemHeight = height(listBox());
+ QFontMetrics fm = painter_->fontMetrics();
+ int yPos = ((itemHeight - fm.height()) / 2) + fm.ascent();
+ painter_->drawText(3, yPos, text());
+}
diff --git a/src/gui/listboxtext.h b/src/gui/listboxtext.h
new file mode 100644
index 0000000..3cfe2db
--- /dev/null
+++ b/src/gui/listboxtext.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_GUI_LISTBOXTEXT_H
+#define TELLICO_GUI_LISTBOXTEXT_H
+
+#include <qlistbox.h>
+
+namespace Tellico {
+ namespace GUI {
+
+/**
+ * ListBoxText subclasses QListBoxText so that @ref setText() can be made public,
+ * and the font color can be changed
+ *
+ * @author Robby Stephenson
+ */
+class ListBoxText : public QListBoxText {
+public:
+ ListBoxText(QListBox* listbox, const QString& text);
+ ListBoxText(QListBox* listbox, const QString& text, QListBoxItem* after);
+
+ virtual int width(const QListBox* box) const;
+ virtual int height(const QListBox* box) const;
+
+ bool isColored() const { return m_colored; }
+ void setColored(bool colored);
+ void setText(const QString& text);
+
+protected:
+ virtual void paint(QPainter* painter);
+
+private:
+ bool m_colored;
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/gui/listview.cpp b/src/gui/listview.cpp
new file mode 100644
index 0000000..d93174c
--- /dev/null
+++ b/src/gui/listview.cpp
@@ -0,0 +1,347 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "listview.h"
+#include "../controller.h"
+#include "../tellico_utils.h"
+#include "../tellico_debug.h"
+
+#include <kapplication.h>
+
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qheader.h>
+
+using Tellico::GUI::ListView;
+using Tellico::GUI::ListViewItem;
+
+ListView::ListView(QWidget* parent_, const char* name_) : KListView(parent_, name_/*=0*/),
+ m_sortStyle(SortByText), m_isClear(true) {
+ setSelectionMode(QListView::Extended);
+ connect(this, SIGNAL(selectionChanged()),
+ SLOT(slotSelectionChanged()));
+ connect(this, SIGNAL(doubleClicked(QListViewItem*)),
+ SLOT(slotDoubleClicked(QListViewItem*)));
+#if !KDE_IS_VERSION(3,3,90)
+ m_shadeSortColumn = false;
+ // call it once to initialize
+ slotUpdateColors();
+#endif
+ connect(kapp, SIGNAL(kdisplayPaletteChanged()), SLOT(slotUpdateColors()));
+ m_comparisons.setAutoDelete(true);
+}
+
+ListView::~ListView() {
+}
+
+void ListView::clearSelection() {
+ if(m_selectedItems.isEmpty()) {
+ // nothing to do;
+ return;
+ }
+ bool b = signalsBlocked();
+ blockSignals(true);
+ selectAll(false);
+ blockSignals(b);
+ emit selectionChanged();
+}
+
+void ListView::updateSelected(ListViewItem* item_, bool selected_) {
+ if(selected_) {
+ m_selectedItems.append(item_);
+ } else {
+ m_selectedItems.removeRef(item_);
+ }
+}
+
+bool ListView::isSelectable(ListViewItem* item_) const {
+ // don't allow hidden items to be selected
+ if(!item_->isVisible()) {
+ return false;
+ }
+
+ // selecting multiple items is ok
+ // only when parent is open. Be careful to check for existence of parent
+ if(item_->parent() && !item_->parent()->isOpen()) {
+ return false;
+ }
+
+ // just selecting a single item is always ok
+ if(m_selectedItems.isEmpty()) {
+ return true;
+ }
+
+ // not allowed is something other than an entry is selected and current is entry
+ if(m_selectedItems.getFirst()->isEntryItem() != item_->isEntryItem()) {
+ return false;
+ }
+
+ return true;
+}
+
+int ListView::firstVisibleColumn() const {
+ int col = 0;
+ while(col < columns() && columnWidth(header()->mapToSection(col)) == 0) {
+ ++col;
+ }
+ if(col == columns()) {
+ return -1;
+ }
+ return header()->mapToSection(col);
+}
+
+int ListView::lastVisibleColumn() const {
+ int col = columns()-1;
+ while(col < columns() && columnWidth(header()->mapToSection(col)) == 0) {
+ --col;
+ }
+ if(col == columns()) {
+ return -1;
+ }
+ return header()->mapToSection(col);
+}
+
+void ListView::setColumnText(int column, const QString& label) {
+ ListViewComparison* comp = m_comparisons.take(columnText(column));
+ KListView::setColumnText(column, label);
+ if(comp) {
+ m_comparisons.insert(columnText(column), comp);
+ }
+}
+
+void ListView::setComparison(int column, ListViewComparison* comp) {
+ if(comp) {
+ m_comparisons.replace(columnText(column), comp);
+ }
+}
+
+void ListView::removeComparison(int column) {
+ m_comparisons.remove(columnText(column));
+}
+
+void ListView::clearComparisons() {
+ m_comparisons.clear();
+}
+
+int ListView::compare(int col, const GUI::ListViewItem* item1, GUI::ListViewItem* item2, bool asc) {
+ if(col >= 0 && col < static_cast<int>(m_comparisons.count())) {
+ ListViewComparison* com = m_comparisons.find(columnText(col));
+ if(com) {
+ return com->compare(col, item1, item2, asc);
+ }
+ }
+ return 0;
+}
+
+#if !KDE_IS_VERSION(3,3,90)
+void ListView::setShadeSortColumn(bool shade_) {
+ if(m_shadeSortColumn != shade_) {
+ m_shadeSortColumn = shade_;
+ repaint();
+ }
+}
+#endif
+
+void ListView::slotUpdateColors() {
+#if !KDE_IS_VERSION(3,3,90)
+ m_backColor2 = viewport()->colorGroup().base();
+ if(m_backColor2 == Qt::black) {
+ m_backColor2 = QColor(50, 50, 50); // dark gray
+ } else {
+ int h,s,v;
+ m_backColor2.hsv(&h, &s, &v);
+ if(v > 175) {
+ m_backColor2 = m_backColor2.dark(105);
+ } else {
+ m_backColor2 = m_backColor2.light(120);
+ }
+ }
+
+ m_altColor2 = alternateBackground();
+ if(m_altColor2 == Qt::black) {
+ m_altColor2 = QColor(50, 50, 50); // dark gray
+ } else {
+ int h,s,v;
+ m_altColor2.hsv(&h, &s, &v);
+ if(v > 175) {
+ m_altColor2 = m_altColor2.dark(105);
+ } else {
+ m_altColor2 = m_altColor2.light(120);
+ }
+ }
+#endif
+ Tellico::updateContrastColor(viewport()->colorGroup());
+ repaint();
+}
+
+void ListView::slotSelectionChanged() {
+ if(m_selectedItems.isEmpty()) {
+ if(m_isClear) {
+ return; // nothing to do
+ }
+ m_isClear = true;
+ Controller::self()->slotClearSelection();
+ return;
+ }
+ m_isClear = false;
+
+ Data::EntryVec entries;
+ // now just find all the children or grandchildren that are entry items
+ for(GUI::ListViewItemListIt it(m_selectedItems); it.current(); ++it) {
+ Data::EntryVec more = it.current()->entries();
+ for(Data::EntryVecIt entry = more.begin(); entry != more.end(); ++entry) {
+ if(!entries.contains(entry)) {
+ entries.append(entry);
+ }
+ }
+ }
+// Controller::self()->slotUpdateCurrent(entries); // just update current, don't change selection
+ Controller::self()->slotUpdateSelection(this, entries);
+}
+
+void ListView::slotDoubleClicked(QListViewItem* item_) {
+ if(!item_) {
+ return;
+ }
+
+ // if it has children, just open it
+ // but some items delay children creation
+ if(static_cast<ListViewItem*>(item_)->realChildCount() > 0) {
+ item_->setOpen(!item_->isOpen());
+ }
+
+ GUI::ListViewItem* item = static_cast<GUI::ListViewItem*>(item_);
+ item->doubleClicked();
+}
+
+void ListView::drawContentsOffset(QPainter* p, int ox, int oy, int cx, int cy, int cw, int ch) {
+ bool oldUpdatesEnabled = isUpdatesEnabled();
+ setUpdatesEnabled(false);
+ KListView::drawContentsOffset(p, ox, oy, cx, cy, cw, ch);
+ setUpdatesEnabled(oldUpdatesEnabled);
+}
+
+/* ****************** ListViewItem ********************* */
+
+ListViewItem::~ListViewItem() {
+ // I think there's a bug in qt where the children of this item are deleted after the item itself
+ // as a result, there is no listView() pointer for the children, that obvious causes
+ // a problem with updating the selection. So we MUST call clear() here ourselves!
+ clear();
+ // be sure to remove from selected list when it's deleted
+ ListView* lv = listView();
+ if(lv) {
+ lv->updateSelected(this, false);
+ }
+}
+
+void ListViewItem::clear() {
+ QListViewItem* item = firstChild();
+ while(item) {
+ delete item;
+ item = firstChild();
+ }
+}
+
+int ListViewItem::compare(QListViewItem* item_, int col_, bool asc_) const {
+ int res = compareWeight(item_, col_, asc_);
+ if(res != 0) {
+ return res;
+ }
+ res = listView()->compare(col_, this, static_cast<GUI::ListViewItem*>(item_), asc_);
+ return res == 0 ? KListViewItem::compare(item_, col_, asc_) : res;
+}
+
+int ListViewItem::compareWeight(QListViewItem* item_, int col_, bool asc_) const {
+ Q_UNUSED(col_);
+ // I want the sorting to be independent of sort order
+ GUI::ListViewItem* i = static_cast<GUI::ListViewItem*>(item_);
+ int res = 0;
+ if(m_sortWeight < i->sortWeight()) {
+ res = -1;
+ } else if(m_sortWeight > i->sortWeight()) {
+ res = 1;
+ }
+ if(asc_) {
+ res *= -1; // reverse, heavier weights will come first always
+ }
+ return res;
+}
+
+void ListViewItem::setSelected(bool s_) {
+ ListView* lv = listView();
+ if(!lv) {
+ return;
+ }
+ if(s_ && !lv->isSelectable(this)) {
+ return;
+ }
+ if(s_ != isSelected()) {
+ lv->updateSelected(this, s_);
+ KListViewItem::setSelected(s_);
+ }
+}
+
+QColor ListViewItem::backgroundColor(int column_) {
+#if KDE_IS_VERSION(3,3,90)
+ return KListViewItem::backgroundColor(column_);
+#else
+ ListView* view = listView();
+ if(view->columns() > 1 && view->shadeSortColumn() && column_ == view->sortColumn()) {
+ return isAlternate() ? view->alternateBackground2() : view->background2();
+ }
+ return isAlternate() ? view->alternateBackground() : view->viewport()->colorGroup().base();
+#endif
+}
+
+void ListViewItem::paintCell(QPainter* p_, const QColorGroup& cg_,
+ int column_, int width_, int align_) {
+ // taken from klistview.cpp
+ // I can't call KListViewItem::paintCell since KListViewItem::backgroundCOlor(int) is
+ // not virtual. I need to be sure to call ListViewItem::backgroundColor(int);
+ QColorGroup cg = cg_;
+ const QPixmap* pm = listView()->viewport()->backgroundPixmap();
+ if(pm && !pm->isNull()) {
+ cg.setBrush(QColorGroup::Base, QBrush(backgroundColor(column_), *pm));
+ QPoint o = p_->brushOrigin();
+ p_->setBrushOrigin(o.x()-listView()->contentsX(), o.y()-listView()->contentsY());
+ } else {
+ cg.setColor(listView()->viewport()->backgroundMode() == Qt::FixedColor ?
+ QColorGroup::Background : QColorGroup::Base,
+ backgroundColor(column_));
+ }
+
+ // don't call KListViewItem::paintCell() since that also does alternate painting, etc...
+ QListViewItem::paintCell(p_, cg, column_, width_, align_);
+
+ // borrowed from amarok, draw line to left of cell
+ if(!isSelected()) {
+ p_->setPen(QPen(listView()->alternateBackground(), 0, Qt::SolidLine));
+ p_->drawLine(width_-1, 0, width_-1, height()-1);
+ }
+}
+
+Tellico::Data::EntryVec ListViewItem::entries() const {
+ Data::EntryVec entries;
+ for(QListViewItem* child = firstChild(); child; child = child->nextSibling()) {
+ Data::EntryVec more = static_cast<GUI::ListViewItem*>(child)->entries();
+ for(Data::EntryVecIt entry = more.begin(); entry != more.end(); ++entry) {
+ if(!entries.contains(entry)) {
+ entries.append(entry);
+ }
+ }
+ }
+ return entries;
+}
+
+#include "listview.moc"
diff --git a/src/gui/listview.h b/src/gui/listview.h
new file mode 100644
index 0000000..4c5ade7
--- /dev/null
+++ b/src/gui/listview.h
@@ -0,0 +1,180 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_LISTVIEW_H
+#define TELLICO_LISTVIEW_H
+
+#include "../datavectors.h"
+#include "../listviewcomparison.h"
+
+#include <klistview.h>
+#include <kdeversion.h>
+
+#include <qdict.h>
+
+namespace Tellico {
+ class ListViewComparison;
+ namespace GUI {
+
+class ListViewItem;
+typedef QPtrList<ListViewItem> ListViewItemList;
+typedef QPtrListIterator<ListViewItem> ListViewItemListIt;
+
+/**
+ * A ListView keeps track of the selected items and allows subclasses to determine
+ * whether child items may be selected or not. In addition, it provides alternating
+ * background colors and shaded sort columns.
+ *
+ * @see GroupView
+ * @see DetailedListView
+ *
+ * @author Robby Stephenson
+ */
+class ListView : public KListView {
+Q_OBJECT
+
+friend class ListViewItem; // needed so the ListViewItem d'tor can update selection list
+
+public:
+ enum SortStyle {
+ SortByText = 0, // don't change these values, they're saved as ints in the config
+ SortByCount = 1
+ };
+
+ ListView(QWidget* parent, const char* name = 0);
+ virtual ~ListView();
+
+ void clearSelection();
+ /**
+ * Returns a list of the currently selected items;
+ *
+ * @return The list of selected items
+ */
+ const ListViewItemList& selectedItems() const { return m_selectedItems; }
+ /**
+ * Used to determine whether an item may be selected without having to setSelectable on
+ * every child item.
+ *
+ * @return Whether the item may be selected
+ */
+ virtual bool isSelectable(ListViewItem*) const;
+ SortStyle sortStyle() const { return m_sortStyle; }
+ void setSortStyle(SortStyle style) { m_sortStyle = style; }
+
+ int firstVisibleColumn() const;
+ int lastVisibleColumn() const;
+
+ virtual void setColumnText(int column, const QString& label);
+
+ void setComparison(int column, ListViewComparison* comp);
+ void removeComparison(int column);
+ void clearComparisons();
+ virtual int compare(int col, const GUI::ListViewItem* item1, GUI::ListViewItem* item2, bool asc);
+
+#if !KDE_IS_VERSION(3,3,90)
+ // taken from KDE bug 59791
+ void setShadeSortColumn(bool shade_);
+ bool shadeSortColumn() const { return m_shadeSortColumn; }
+ const QColor& background2() const { return m_backColor2; }
+ const QColor& alternateBackground2() const { return m_altColor2; }
+#endif
+
+protected slots:
+ /**
+ * Handles everything when an item is selected. The proper signal is emitted, depending
+ * on whether the item refers to a collection, a group, or a entry.
+ */
+ virtual void slotSelectionChanged();
+
+protected:
+ virtual void drawContentsOffset(QPainter* p, int ox, int oy, int cx, int cy, int cw, int ch);
+
+private slots:
+ void slotUpdateColors();
+ void slotDoubleClicked(QListViewItem* item);
+
+private:
+ /**
+ * Updates the pointer list.
+ *
+ * @param item The item being selected or deselected
+ * @param s Selected or not
+ */
+ void updateSelected(ListViewItem* item, bool s);
+
+ SortStyle m_sortStyle;
+ bool m_isClear;
+ ListViewItemList m_selectedItems;
+ QDict<ListViewComparison> m_comparisons;
+#if !KDE_IS_VERSION(3,3,90)
+ bool m_shadeSortColumn;
+ QColor m_backColor2;
+ QColor m_altColor2;
+#endif
+};
+
+/**
+ * The ListViewItem keeps track of what kind of specialized listview item it is, as
+ * well as taking care of the selection tracking.
+ *
+ * @author Robby Stephenson
+ */
+class ListViewItem : public KListViewItem {
+public:
+ ListViewItem(ListView* parent) : KListViewItem(parent), m_sortWeight(-1) {}
+ ListViewItem(ListView* parent, QListViewItem* after) : KListViewItem(parent, after), m_sortWeight(-1) {}
+ ListViewItem(ListViewItem* parent) : KListViewItem(parent), m_sortWeight(-1) {}
+ ListViewItem(ListView* parent, const QString& text) : KListViewItem(parent, text), m_sortWeight(-1) {}
+ ListViewItem(ListViewItem* parent, const QString& text) : KListViewItem(parent, text), m_sortWeight(-1) {}
+ virtual ~ListViewItem();
+
+ virtual int realChildCount() const { return childCount(); }
+ virtual void clear();
+
+ virtual bool isEntryGroupItem() const { return false; }
+ virtual bool isEntryItem() const { return false; }
+ virtual bool isFilterItem() const { return false; }
+ virtual bool isBorrowerItem() const { return false; }
+ virtual bool isLoanItem() const { return false; }
+
+ int sortWeight() const { return m_sortWeight; }
+ void setSortWeight(int w) { m_sortWeight = w; }
+ virtual int compare(QListViewItem* item, int col, bool ascending) const;
+
+ virtual void setSelected(bool selected);
+ /**
+ * Returns the background color for the column, which depends on whether the item
+ * is an alternate row and whether the column is selected.
+ *
+ * @param column The column number
+ * @param alternate The alternate row color can be forced
+ */
+ virtual QColor backgroundColor(int column); // not virtual in KListViewItem!!!
+ virtual void paintCell(QPainter* painter, const QColorGroup& colorGroup,
+ int column, int width, int alignment);
+
+ ListView* listView () const { return static_cast<ListView*>(KListViewItem::listView()); }
+
+ virtual void doubleClicked() {}
+ virtual Data::EntryVec entries() const;
+
+private:
+ int compareWeight(QListViewItem* item, int col, bool ascending) const;
+
+ int m_sortWeight;
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/gui/numberfieldwidget.cpp b/src/gui/numberfieldwidget.cpp
new file mode 100644
index 0000000..027b1e9
--- /dev/null
+++ b/src/gui/numberfieldwidget.cpp
@@ -0,0 +1,143 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "numberfieldwidget.h"
+#include "datewidget.h"
+#include "../field.h"
+
+#include <klineedit.h>
+
+#include <qlayout.h>
+#include <qvalidator.h>
+
+using Tellico::GUI::NumberFieldWidget;
+
+NumberFieldWidget::NumberFieldWidget(Data::FieldPtr field_, QWidget* parent_, const char* name_/*=0*/)
+ : FieldWidget(field_, parent_, name_), m_lineEdit(0), m_spinBox(0) {
+
+ if(field_->flags() & Data::Field::AllowMultiple) {
+ initLineEdit();
+ } else {
+ initSpinBox();
+ }
+
+ registerWidget();
+}
+
+void NumberFieldWidget::initLineEdit() {
+ m_lineEdit = new KLineEdit(this);
+ connect(m_lineEdit, SIGNAL(textChanged(const QString&)), SIGNAL(modified()));
+ // connect(kl, SIGNAL(returnPressed(const QString&)), this, SLOT(slotHandleReturn()));
+
+ // regexp is any number of digits followed optionally by any number of
+ // groups of a semi-colon followed optionally by a space, followed by digits
+ QRegExp rx(QString::fromLatin1("-?\\d*(; ?-?\\d*)*"));
+ m_lineEdit->setValidator(new QRegExpValidator(rx, this));
+}
+
+void NumberFieldWidget::initSpinBox() {
+ // intentionally allow only positive numbers
+ m_spinBox = new GUI::SpinBox(-1, INT_MAX, this);
+ connect(m_spinBox, SIGNAL(valueChanged(int)), SIGNAL(modified()));
+ // QSpinBox doesn't emit valueChanged if you edit the value with
+ // the lineEdit until you change the keyboard focus
+ connect(m_spinBox->child("qt_spinbox_edit"), SIGNAL(textChanged(const QString&)), SIGNAL(modified()));
+ // I want to allow no value, so set space as special text. Empty text is ignored
+ m_spinBox->setSpecialValueText(QChar(' '));
+}
+
+QString NumberFieldWidget::text() const {
+ if(isSpinBox()) {
+ // minValue = special empty text
+ if(m_spinBox->value() > m_spinBox->minValue()) {
+ return QString::number(m_spinBox->value());
+ }
+ return QString();
+ }
+
+ QString text = m_lineEdit->text();
+ if(field()->flags() & Data::Field::AllowMultiple) {
+ text.replace(s_semiColon, QString::fromLatin1("; "));
+ }
+ return text.simplifyWhiteSpace();
+}
+
+void NumberFieldWidget::setText(const QString& text_) {
+ blockSignals(true);
+
+ if(isSpinBox()) {
+ bool ok;
+ int n = text_.toInt(&ok);
+ if(ok) {
+ // did just allow positive
+ if(n < 0) {
+ m_spinBox->setMinValue(INT_MIN+1);
+ }
+ m_spinBox->blockSignals(true);
+ m_spinBox->setValue(n);
+ m_spinBox->blockSignals(false);
+ }
+ } else {
+ m_lineEdit->blockSignals(true);
+ m_lineEdit->setText(text_);
+ m_lineEdit->blockSignals(false);
+ }
+
+ blockSignals(false);
+}
+
+void NumberFieldWidget::clear() {
+ if(isSpinBox()) {
+ // show empty special value text
+ m_spinBox->setValue(m_spinBox->minValue());
+ } else {
+ m_lineEdit->clear();
+ }
+ editMultiple(false);
+}
+
+void NumberFieldWidget::updateFieldHook(Data::FieldPtr, Data::FieldPtr newField_) {
+ bool wasLineEdit = !isSpinBox();
+ bool nowLineEdit = newField_->flags() & Data::Field::AllowMultiple;
+
+ if(wasLineEdit == nowLineEdit) {
+ return;
+ }
+
+ QString value = text();
+ if(wasLineEdit && !nowLineEdit) {
+ layout()->remove(m_lineEdit);
+ delete m_lineEdit;
+ m_lineEdit = 0;
+ initSpinBox();
+ } else if(!wasLineEdit && nowLineEdit) {
+ layout()->remove(m_spinBox);
+ delete m_spinBox;
+ m_spinBox = 0;
+ initLineEdit();
+ }
+
+ // should really be FIELD_EDIT_WIDGET_INDEX from fieldwidget.cpp
+ static_cast<QBoxLayout*>(layout())->insertWidget(2, widget(), 1 /*stretch*/);
+ widget()->show();
+ setText(value);
+}
+
+QWidget* NumberFieldWidget::widget() {
+ if(isSpinBox()) {
+ return m_spinBox;
+ }
+ return m_lineEdit;
+}
+
+#include "numberfieldwidget.moc"
diff --git a/src/gui/numberfieldwidget.h b/src/gui/numberfieldwidget.h
new file mode 100644
index 0000000..c0fed9d
--- /dev/null
+++ b/src/gui/numberfieldwidget.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef NUMBERFIELDWIDGET_H
+#define NUMBERFIELDWIDGET_H
+
+class KLineEdit;
+
+#include "fieldwidget.h"
+#include "../datavectors.h"
+
+namespace Tellico {
+ namespace GUI {
+ class SpinBox;
+
+/**
+ * @author Robby Stephenson
+ */
+class NumberFieldWidget : public FieldWidget {
+Q_OBJECT
+
+public:
+ NumberFieldWidget(Data::FieldPtr field, QWidget* parent, const char* name=0);
+ virtual ~NumberFieldWidget() {}
+
+ virtual QString text() const;
+ virtual void setText(const QString& text);
+
+public slots:
+ virtual void clear();
+
+protected:
+ virtual QWidget* widget();
+ virtual void updateFieldHook(Data::FieldPtr oldField, Data::FieldPtr newField);
+
+private:
+ bool isSpinBox() const { return (m_spinBox != 0); }
+ void initLineEdit();
+ void initSpinBox();
+
+ KLineEdit* m_lineEdit;
+ SpinBox* m_spinBox;
+};
+
+ } // end GUI namespace
+} // end namespace
+#endif
diff --git a/src/gui/overlaywidget.cpp b/src/gui/overlaywidget.cpp
new file mode 100644
index 0000000..6214ca8
--- /dev/null
+++ b/src/gui/overlaywidget.cpp
@@ -0,0 +1,104 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "overlaywidget.h"
+
+#include <qlayout.h>
+
+using Tellico::GUI::OverlayWidget;
+
+OverlayWidget::OverlayWidget(QWidget* parent, QWidget* anchor) : QFrame(parent)
+ , m_anchor(anchor)
+ , m_corner(TopRight) {
+ m_anchor->installEventFilter(this);
+ reposition();
+ hide();
+}
+
+void OverlayWidget::setCorner(Corner corner_) {
+ if(corner_ == m_corner) {
+ return;
+ }
+ m_corner = corner_;
+ reposition();
+}
+
+void OverlayWidget::addWidget(QWidget* widget_) {
+ layout()->add(widget_);
+ adjustSize();
+}
+
+void OverlayWidget::reposition() {
+ if(!m_anchor) {
+ return;
+ }
+
+ setMaximumSize(parentWidget()->size());
+ adjustSize();
+
+ QPoint p;
+
+ switch(m_corner) {
+ case BottomLeft:
+ p.setX(0);
+ p.setY(m_anchor->height());
+ break;
+
+ case BottomRight:
+ p.setX(m_anchor->width() - width());
+ p.setY(m_anchor->height());
+ break;
+
+ case TopLeft:
+ p.setX(0);
+ p.setY(-1 * height());
+ break;
+
+ case TopRight:
+ p.setX(m_anchor->width() - width());
+ p.setY(-1 * height());
+ }
+
+ // Position in the toplevelwidget's coordinates
+ QPoint pTopLevel = m_anchor->mapTo(topLevelWidget(), p);
+ // Position in the widget's parentWidget coordinates
+ QPoint pParent = parentWidget()->mapFrom(topLevelWidget(), pTopLevel);
+ // keep it on the screen
+ if(pParent.x() < 0) {
+ pParent.rx() = 0;
+ }
+ move(pParent);
+}
+
+bool OverlayWidget::eventFilter(QObject* object_, QEvent* event_) {
+ if(object_ == m_anchor && (event_->type() == QEvent::Move || event_->type() == QEvent::Resize)) {
+ reposition();
+ }
+
+ return QFrame::eventFilter(object_, event_);
+}
+
+void OverlayWidget::resizeEvent(QResizeEvent* event_) {
+ reposition();
+ QFrame::resizeEvent(event_);
+}
+
+bool OverlayWidget::event(QEvent* event_) {
+ if(event_->type() == QEvent::ChildInserted) {
+ adjustSize();
+ }
+
+ return QFrame::event(event_);
+}
+
+#include "overlaywidget.moc"
diff --git a/src/gui/overlaywidget.h b/src/gui/overlaywidget.h
new file mode 100644
index 0000000..7b4453e
--- /dev/null
+++ b/src/gui/overlaywidget.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+// much of this code is adapted from libkdepim
+// which is GPL licensed, Copyright (c) 2004 David Faure
+
+#ifndef TELLICO_GUI_OVERLAYWIDGET_H
+#define TELLICO_GUI_OVERLAYWIDGET_H
+
+#include <qframe.h>
+
+namespace Tellico {
+ namespace GUI {
+
+/**
+ * @author Robby Stephenson
+ */
+class OverlayWidget : public QFrame {
+Q_OBJECT
+
+public:
+ OverlayWidget(QWidget* parent, QWidget* anchor);
+
+ void setCorner(Corner corner);
+ Corner corner() const { return m_corner; }
+
+ void addWidget(QWidget* widget);
+
+protected:
+ void resizeEvent(QResizeEvent* event);
+ bool eventFilter(QObject* object, QEvent* event);
+ bool event(QEvent* event);
+
+private:
+ void reposition();
+
+ QWidget* m_anchor;
+ Corner m_corner;
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/gui/parafieldwidget.cpp b/src/gui/parafieldwidget.cpp
new file mode 100644
index 0000000..9941e34
--- /dev/null
+++ b/src/gui/parafieldwidget.cpp
@@ -0,0 +1,63 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "parafieldwidget.h"
+#include "../field.h"
+#include "../latin1literal.h"
+
+#include <ktextedit.h>
+
+using Tellico::GUI::ParaFieldWidget;
+
+ParaFieldWidget::ParaFieldWidget(Data::FieldPtr field_, QWidget* parent_, const char* name_/*=0*/)
+ : FieldWidget(field_, parent_, name_) {
+
+ m_textEdit = new KTextEdit(this);
+ m_textEdit->setTextFormat(Qt::PlainText);
+ if(field_->property(QString::fromLatin1("spellcheck")) != Latin1Literal("false")) {
+ m_textEdit->setCheckSpellingEnabled(true);
+ }
+ connect(m_textEdit, SIGNAL(textChanged()), SIGNAL(modified()));
+
+ registerWidget();
+}
+
+QString ParaFieldWidget::text() const {
+ QString text = m_textEdit->text();
+ text.replace('\n', QString::fromLatin1("<br/>"));
+ return text;
+}
+
+void ParaFieldWidget::setText(const QString& text_) {
+ blockSignals(true);
+ m_textEdit->blockSignals(true);
+
+ QRegExp rx(QString::fromLatin1("<br/?>"), false /*case-sensitive*/);
+ QString s = text_;
+ s.replace(rx, QChar('\n'));
+ m_textEdit->setText(s);
+
+ m_textEdit->blockSignals(false);
+ blockSignals(false);
+}
+
+void ParaFieldWidget::clear() {
+ m_textEdit->clear();
+ editMultiple(false);
+}
+
+QWidget* ParaFieldWidget::widget() {
+ return m_textEdit;
+}
+
+#include "parafieldwidget.moc"
diff --git a/src/gui/parafieldwidget.h b/src/gui/parafieldwidget.h
new file mode 100644
index 0000000..ac9801f
--- /dev/null
+++ b/src/gui/parafieldwidget.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef PARAFIELDWIDGET_H
+#define PARAFIELDWIDGET_H
+
+#include "fieldwidget.h"
+#include "../datavectors.h"
+
+class KTextEdit;
+
+namespace Tellico {
+ namespace GUI {
+
+/**
+ * @author Robby Stephenson
+ */
+class ParaFieldWidget : public FieldWidget {
+Q_OBJECT
+
+public:
+ ParaFieldWidget(Data::FieldPtr field, QWidget* parent, const char* name=0);
+ virtual ~ParaFieldWidget() {}
+
+ virtual QString text() const;
+ virtual void setText(const QString& text);
+
+public slots:
+ virtual void clear();
+
+protected:
+ virtual QWidget* widget();
+
+private:
+ KTextEdit* m_textEdit;
+};
+
+ } // end GUI namespace
+} // end namespace
+#endif
diff --git a/src/gui/previewdialog.cpp b/src/gui/previewdialog.cpp
new file mode 100644
index 0000000..4c0d8e1
--- /dev/null
+++ b/src/gui/previewdialog.cpp
@@ -0,0 +1,56 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "previewdialog.h"
+#include "../entryview.h"
+#include "../entry.h"
+#include "../imagefactory.h" // for StyleOptions
+
+#include <klocale.h>
+#include <ktempdir.h>
+#include <khtmlview.h>
+
+using Tellico::GUI::PreviewDialog;
+
+PreviewDialog::PreviewDialog(QWidget* parent_)
+ : KDialogBase(parent_, "template preview dialog", false /* modal */,
+ i18n("Template Preview"), KDialogBase::Ok)
+ , m_tempDir(new KTempDir()) {
+ m_tempDir->setAutoDelete(true);
+ connect(this, SIGNAL(finished()), SLOT(delayedDestruct()));
+
+ m_view = new EntryView(this);
+ setMainWidget(m_view->view());
+ setInitialSize(QSize(600, 500));
+}
+
+PreviewDialog::~PreviewDialog() {
+ delete m_tempDir;
+ m_tempDir = 0;
+}
+
+void PreviewDialog::setXSLTFile(const QString& file_) {
+ m_view->setXSLTFile(file_);
+}
+
+void PreviewDialog::setXSLTOptions(StyleOptions options_) {
+ options_.imgDir = m_tempDir->name(); // images always get written to temp dir
+ ImageFactory::createStyleImages(options_);
+ m_view->setXSLTOptions(options_);
+}
+
+void PreviewDialog::showEntry(Data::EntryPtr entry_) {
+ m_view->showEntry(entry_);
+}
+
+#include "previewdialog.moc"
diff --git a/src/gui/previewdialog.h b/src/gui/previewdialog.h
new file mode 100644
index 0000000..a386a94
--- /dev/null
+++ b/src/gui/previewdialog.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_GUI_PREVIEWDIALOG_H
+#define TELLICO_GUI_PREVIEWDIALOG_H
+
+#include <kdialogbase.h>
+
+#include "../datavectors.h"
+
+class KTempDir;
+
+namespace Tellico {
+ class EntryView;
+ class StyleOptions;
+
+ namespace GUI {
+
+class PreviewDialog : public KDialogBase {
+Q_OBJECT
+
+public:
+ PreviewDialog(QWidget* parent);
+ ~PreviewDialog();
+
+ void setXSLTFile(const QString& file);
+ void setXSLTOptions(StyleOptions options);
+ void showEntry(Data::EntryPtr entry);
+
+private:
+ KTempDir* m_tempDir;
+ EntryView* m_view;
+};
+
+ }
+}
+#endif
diff --git a/src/gui/progress.cpp b/src/gui/progress.cpp
new file mode 100644
index 0000000..36baaf1
--- /dev/null
+++ b/src/gui/progress.cpp
@@ -0,0 +1,33 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "progress.h"
+#include "../tellico_debug.h"
+
+using Tellico::GUI::Progress;
+
+Progress::Progress(QWidget* parent_) : KProgress(parent_) {
+}
+
+Progress::Progress(int totalSteps_, QWidget* parent_) : KProgress(totalSteps_, parent_) {
+}
+
+bool Progress::isDone() const {
+ return progress() == totalSteps();
+}
+
+void Progress::setDone() {
+ setProgress(totalSteps());
+}
+
+#include "progress.moc"
diff --git a/src/gui/progress.h b/src/gui/progress.h
new file mode 100644
index 0000000..b58de2f
--- /dev/null
+++ b/src/gui/progress.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_GUI_PROGRESS_H
+#define TELLICO_GUI_PROGRESS_H
+
+#include <kprogress.h>
+
+namespace Tellico {
+ namespace GUI {
+
+/**
+ * @author Robby Stephenson
+ */
+class Progress : public KProgress {
+Q_OBJECT
+
+public:
+ Progress(QWidget* parent);
+ Progress(int totalSteps, QWidget* parent);
+
+ bool isDone() const;
+ void setDone();
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/gui/ratingfieldwidget.cpp b/src/gui/ratingfieldwidget.cpp
new file mode 100644
index 0000000..4b0de71
--- /dev/null
+++ b/src/gui/ratingfieldwidget.cpp
@@ -0,0 +1,59 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "ratingfieldwidget.h"
+#include "ratingwidget.h"
+#include "../field.h"
+
+using Tellico::GUI::RatingFieldWidget;
+
+RatingFieldWidget::RatingFieldWidget(Data::FieldPtr field_, QWidget* parent_, const char* name_/*=0*/)
+ : FieldWidget(field_, parent_, name_) {
+ m_rating = new RatingWidget(field_, this);
+ connect(m_rating, SIGNAL(modified()), SIGNAL(modified()));
+
+ registerWidget();
+}
+
+QString RatingFieldWidget::text() const {
+ return m_rating->text();
+}
+
+void RatingFieldWidget::setText(const QString& text_) {
+ blockSignals(true);
+
+ m_rating->blockSignals(true);
+ m_rating->setText(text_);
+ m_rating->blockSignals(false);
+
+ blockSignals(false);
+
+ if(m_rating->text() != text_) {
+ emit modified();
+ }
+}
+
+void RatingFieldWidget::clear() {
+ m_rating->clear();
+ editMultiple(false);
+}
+
+void RatingFieldWidget::updateFieldHook(Data::FieldPtr, Data::FieldPtr newField_) {
+ m_rating->updateField(newField_);
+}
+
+QWidget* RatingFieldWidget::widget() {
+ return m_rating;
+}
+
+#include "ratingfieldwidget.moc"
diff --git a/src/gui/ratingfieldwidget.h b/src/gui/ratingfieldwidget.h
new file mode 100644
index 0000000..369dbec
--- /dev/null
+++ b/src/gui/ratingfieldwidget.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef RATINGFIELDWIDGET_H
+#define RATINGFIELDWIDGET_H
+
+#include "fieldwidget.h"
+#include "../datavectors.h"
+
+namespace Tellico {
+ namespace GUI {
+ class RatingWidget;
+
+/**
+ * @author Robby Stephenson
+ */
+class RatingFieldWidget : public FieldWidget {
+Q_OBJECT
+
+public:
+ RatingFieldWidget(Data::FieldPtr field, QWidget* parent, const char* name=0);
+ virtual ~RatingFieldWidget() {}
+
+ virtual QString text() const;
+ virtual void setText(const QString& text);
+
+public slots:
+ virtual void clear();
+
+protected:
+ virtual QWidget* widget();
+ virtual void updateFieldHook(Data::FieldPtr oldField, Data::FieldPtr newField);
+
+private:
+ RatingWidget* m_rating;
+};
+
+ } // end GUI namespace
+} // end namespace
+#endif
diff --git a/src/gui/ratingwidget.cpp b/src/gui/ratingwidget.cpp
new file mode 100644
index 0000000..4921f21
--- /dev/null
+++ b/src/gui/ratingwidget.cpp
@@ -0,0 +1,170 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "ratingwidget.h"
+#include "../field.h"
+#include "../latin1literal.h"
+#include "../tellico_utils.h"
+#include "../tellico_debug.h"
+
+#include <kiconloader.h>
+
+#include <qintdict.h>
+#include <qlayout.h>
+
+namespace {
+ static const int RATING_WIDGET_MAX_ICONS = 10; // same as in Field::ratingValues()
+ static const int RATING_WIDGET_MAX_STAR_SIZE = 24;
+}
+
+using Tellico::GUI::RatingWidget;
+
+const QPixmap& RatingWidget::pixmap(const QString& value_) {
+ static QIntDict<QPixmap> pixmaps;
+ if(pixmaps.isEmpty()) {
+ pixmaps.insert(-1, new QPixmap());
+ }
+ bool ok;
+ int n = Tellico::toUInt(value_, &ok);
+ if(!ok || n < 1 || n > 10) {
+ return *pixmaps[-1];
+ }
+ if(pixmaps[n]) {
+ return *pixmaps[n];
+ }
+
+ QString picName = QString::fromLatin1("stars%1").arg(n);
+ QPixmap* pix = new QPixmap(UserIcon(picName));
+ pixmaps.insert(n, pix);
+ return *pix;
+}
+
+RatingWidget::RatingWidget(Data::FieldPtr field_, QWidget* parent_, const char* name_/*=0*/)
+ : QHBox(parent_, name_), m_field(field_), m_currIndex(-1) {
+ m_pixOn = UserIcon(QString::fromLatin1("star_on"));
+ m_pixOff = UserIcon(QString::fromLatin1("star_off"));
+ setSpacing(0);
+
+ // find maximum width and height
+ int w = QMAX(RATING_WIDGET_MAX_STAR_SIZE, QMAX(m_pixOn.width(), m_pixOff.width()));
+ int h = QMAX(RATING_WIDGET_MAX_STAR_SIZE, QMAX(m_pixOn.height(), m_pixOff.height()));
+ for(int i = 0; i < RATING_WIDGET_MAX_ICONS; ++i) {
+ QLabel* l = new QLabel(this);
+ l->setFixedSize(w, h);
+ m_widgets.append(l);
+ }
+ init();
+
+ QBoxLayout* l = dynamic_cast<QBoxLayout*>(layout());
+ if(l) {
+ l->addStretch(1);
+ }
+}
+
+void RatingWidget::init() {
+ updateBounds();
+ m_total = QMIN(m_max, static_cast<int>(m_widgets.count()));
+ uint i = 0;
+ for( ; static_cast<int>(i) < m_total; ++i) {
+ m_widgets.at(i)->setPixmap(m_pixOff);
+ }
+ for( ; i < m_widgets.count(); ++i) {
+ m_widgets.at(i)->setPixmap(QPixmap());
+ }
+ update();
+}
+
+void RatingWidget::updateBounds() {
+ bool ok; // not used;
+ m_min = Tellico::toUInt(m_field->property(QString::fromLatin1("minimum")), &ok);
+ m_max = Tellico::toUInt(m_field->property(QString::fromLatin1("maximum")), &ok);
+ if(m_max > RATING_WIDGET_MAX_ICONS) {
+ myDebug() << "RatingWidget::updateBounds() - max is too high: " << m_max << endl;
+ m_max = RATING_WIDGET_MAX_ICONS;
+ }
+ if(m_min < 1) {
+ m_min = 1;
+ }
+}
+
+void RatingWidget::update() {
+ int i = 0;
+ for( ; i <= m_currIndex; ++i) {
+ m_widgets.at(i)->setPixmap(m_pixOn);
+ }
+ for( ; i < m_total; ++i) {
+ m_widgets.at(i)->setPixmap(m_pixOff);
+ }
+
+ QHBox::update();
+}
+
+void RatingWidget::mousePressEvent(QMouseEvent* event_) {
+ // only react to left button
+ if(event_->button() != Qt::LeftButton) {
+ return;
+ }
+
+ int idx;
+ QWidget* child = childAt(event_->pos());
+ if(child) {
+ idx = m_widgets.findRef(static_cast<QLabel*>(child));
+ // if the widget is clicked beyond the maximum value, clear it
+ // remember total and min are values, but index is zero-based!
+ if(idx > m_total-1) {
+ idx = -1;
+ } else if(idx < m_min-1) {
+ idx = m_min-1; // limit to minimum, remember index is zero-based
+ }
+ } else {
+ idx = -1;
+ }
+ if(m_currIndex != idx) {
+ m_currIndex = idx;
+ update();
+ emit modified();
+ }
+}
+
+void RatingWidget::clear() {
+ m_currIndex = -1;
+ update();
+}
+
+QString RatingWidget::text() const {
+ // index is index of the list, which is zero-based. Add 1!
+ return m_currIndex == -1 ? QString::null : QString::number(m_currIndex+1);
+}
+
+void RatingWidget::setText(const QString& text_) {
+ bool ok;
+ // text is value, subtract one to get index
+ m_currIndex = Tellico::toUInt(text_, &ok)-1;
+ if(ok) {
+ if(m_currIndex > m_total-1) {
+ m_currIndex = -1;
+ } else if(m_currIndex < m_min-1) {
+ m_currIndex = m_min-1; // limit to minimum, remember index is zero-based
+ }
+ } else {
+ m_currIndex = -1;
+ }
+ update();
+}
+
+void RatingWidget::updateField(Data::FieldPtr field_) {
+ m_field = field_;
+ init();
+}
+
+#include "ratingwidget.moc"
diff --git a/src/gui/ratingwidget.h b/src/gui/ratingwidget.h
new file mode 100644
index 0000000..99665b3
--- /dev/null
+++ b/src/gui/ratingwidget.h
@@ -0,0 +1,75 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef RATINGWIDGET_H
+#define RATINGWIDGET_H
+
+#include "../datavectors.h"
+
+#include <qhbox.h>
+#include <qptrlist.h>
+#include <qlabel.h>
+#include <qpixmap.h>
+
+namespace Tellico {
+ namespace Data {
+ class Field;
+ }
+ namespace GUI {
+
+/**
+ * @author Robby Stephenson
+ */
+class RatingWidget : public QHBox {
+Q_OBJECT
+
+typedef QPtrList<QLabel> LabelList;
+
+public:
+ RatingWidget(Data::FieldPtr field, QWidget* parent, const char* name = 0);
+
+ void clear();
+ QString text() const;
+ void setText(const QString& text);
+ void updateField(Data::FieldPtr field);
+
+ static const QPixmap& pixmap(const QString& value);
+
+public slots:
+ void update();
+
+signals:
+ void modified();
+
+protected:
+ virtual void mousePressEvent(QMouseEvent* e);
+
+private:
+ void init();
+ void updateBounds();
+
+ Data::ConstFieldPtr m_field;
+ LabelList m_widgets;
+
+ int m_currIndex;
+ int m_total;
+ int m_min;
+ int m_max;
+
+ QPixmap m_pixOn;
+ QPixmap m_pixOff;
+};
+
+ } // end GUI namespace
+} // end namespace
+#endif
diff --git a/src/gui/richtextlabel.cpp b/src/gui/richtextlabel.cpp
new file mode 100644
index 0000000..a4cdde4
--- /dev/null
+++ b/src/gui/richtextlabel.cpp
@@ -0,0 +1,47 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "richtextlabel.h"
+
+#include <kdebug.h>
+
+#include <qlayout.h>
+
+using Tellico::GUI::RichTextLabel;
+
+RichTextLabel::RichTextLabel(QWidget* parent) : QTextEdit(parent) {
+ init();
+}
+
+RichTextLabel::RichTextLabel(const QString& text, QWidget* parent) : QTextEdit(text, QString::null, parent) {
+ init();
+}
+
+QSize RichTextLabel::sizeHint() const {
+ return minimumSizeHint();
+}
+
+void RichTextLabel::init() {
+ setReadOnly(true);
+ setTextFormat(Qt::RichText);
+
+ setFrameShape(QFrame::NoFrame);
+ viewport()->setMouseTracking(false);
+
+ setPaper(colorGroup().background());
+
+ setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding));
+ viewport()->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding));
+}
+
+#include "richtextlabel.moc"
diff --git a/src/gui/richtextlabel.h b/src/gui/richtextlabel.h
new file mode 100644
index 0000000..f45a328
--- /dev/null
+++ b/src/gui/richtextlabel.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_GUI_RICHTEXTLABEL_H
+#define TELLICO_GUI_RICHTEXTLABEL_H
+
+#include <qtextedit.h>
+
+namespace Tellico {
+ namespace GUI {
+
+/**
+ * @author Robby Stephenson
+ */
+class RichTextLabel : public QTextEdit {
+Q_OBJECT
+
+public:
+ RichTextLabel(QWidget* parent);
+ RichTextLabel(const QString& text, QWidget* parent);
+
+ virtual QSize sizeHint() const;
+
+private:
+ void init();
+ // redefine these to disable selection
+ void contentsMousePressEvent(QMouseEvent*) {}
+ void contentsMouseMoveEvent(QMouseEvent*) {}
+ void contentsMouseReleaseEvent(QMouseEvent*) {}
+ void contentsMouseDoubleClickEvent(QMouseEvent*) {}
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/gui/stringmapdialog.cpp b/src/gui/stringmapdialog.cpp
new file mode 100644
index 0000000..4a5374f
--- /dev/null
+++ b/src/gui/stringmapdialog.cpp
@@ -0,0 +1,125 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "stringmapdialog.h"
+
+#include <klistview.h>
+#include <klocale.h>
+#include <klineedit.h>
+#include <kbuttonbox.h>
+#include <kiconloader.h>
+
+#include <qlayout.h>
+#include <qheader.h>
+#include <qhbox.h>
+#include <qwhatsthis.h>
+#include <qpushbutton.h>
+
+using Tellico::StringMapDialog;
+
+StringMapDialog::StringMapDialog(const QMap<QString, QString>& map_, QWidget* parent_, const char* name_/*=0*/, bool modal_/*=false*/)
+ : KDialogBase(parent_, name_, modal_, QString::null, Ok|Cancel) {
+ QWidget* page = new QWidget(this);
+ QVBoxLayout* l = new QVBoxLayout(page, 0, KDialog::spacingHint());
+
+ m_listView = new KListView(page);
+ m_listView->setAllColumnsShowFocus(true);
+ m_listView->setShowSortIndicator(true);
+ m_listView->addColumn(QString::null);
+ m_listView->addColumn(QString::null);
+ m_listView->header()->hide(); // hide header since neither column has a label initially
+ m_listView->setColumnWidthMode(0, QListView::Maximum);
+ m_listView->setColumnWidthMode(1, QListView::Maximum);
+ m_listView->setResizeMode(QListView::AllColumns);
+ connect(m_listView, SIGNAL(currentChanged(QListViewItem*)), SLOT(slotUpdate(QListViewItem*)));
+ connect(m_listView, SIGNAL(clicked(QListViewItem*)), SLOT(slotUpdate(QListViewItem*)));
+ l->addWidget(m_listView);
+
+ QHBox* box = new QHBox(page);
+ box->setMargin(4);
+ box->setSpacing(KDialog::spacingHint());
+
+ m_edit1 = new KLineEdit(box);
+ m_edit1->setFocus();
+ m_edit2 = new KLineEdit(box);
+ KButtonBox* bb = new KButtonBox(box);
+ bb->addStretch();
+ QPushButton* btn = bb->addButton(i18n("&Set"), this, SLOT(slotAdd()));
+ btn->setIconSet(BarIcon(QString::fromLatin1("filenew"), KIcon::SizeSmall));
+ btn = bb->addButton(i18n("&Delete"), this, SLOT(slotDelete()));
+ btn->setIconSet(BarIcon(QString::fromLatin1("editdelete"), KIcon::SizeSmall));
+
+ l->addWidget(box);
+ l->addStretch(1);
+ setMainWidget(page);
+
+ for(QMap<QString, QString>::ConstIterator it = map_.begin(); it != map_.end(); ++it) {
+ if(!it.data().isEmpty()) {
+ (void) new KListViewItem(m_listView, it.key(), it.data());
+ }
+ }
+
+ setMinimumWidth(400);
+ enableButtonSeparator(true);
+}
+
+void StringMapDialog::slotAdd() {
+ QString s1 = m_edit1->text();
+ QString s2 = m_edit2->text();
+ if(s1.isEmpty() && s2.isEmpty()) {
+ return;
+ }
+ QListViewItem* item = m_listView->currentItem();
+ if(item && s1 == item->text(0)) { // only update values if same key
+ item->setText(1, s2);
+ } else {
+ item = new KListViewItem(m_listView, s1, s2);
+ }
+ m_listView->ensureItemVisible(item);
+ m_listView->setSelected(item, true);
+ m_listView->setCurrentItem(item);
+}
+
+void StringMapDialog::slotDelete() {
+ delete m_listView->currentItem();
+ m_edit1->clear();
+ m_edit2->clear();
+ m_listView->setSelected(m_listView->currentItem(), true);
+}
+
+void StringMapDialog::slotUpdate(QListViewItem* item_) {
+ if(item_) {
+ m_edit1->setText(item_->text(0));
+ m_edit2->setText(item_->text(1));
+ m_listView->header()->adjustHeaderSize();
+ } else {
+ m_edit1->clear();
+ m_edit2->clear();
+ }
+}
+
+void StringMapDialog::setLabels(const QString& label1_, const QString& label2_) {
+ m_listView->header()->setLabel(0, label1_);
+ m_listView->header()->setLabel(1, label2_);
+ m_listView->header()->show();
+}
+
+QMap<QString, QString> StringMapDialog::stringMap() {
+ QMap<QString, QString> map;
+ for(QListViewItem* item = m_listView->firstChild(); item; item = item->nextSibling()) {
+ map.insert(item->text(0), item->text(1));
+ }
+ return map;
+}
+
+#include "stringmapdialog.moc"
diff --git a/src/gui/stringmapdialog.h b/src/gui/stringmapdialog.h
new file mode 100644
index 0000000..311df70
--- /dev/null
+++ b/src/gui/stringmapdialog.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef STRINGMAPDIALOG_H
+#define STRINGMAPDIALOG_H
+
+class KLineEdit;
+class KListView;
+class QListViewItem;
+
+#include <kdialogbase.h>
+
+template <typename T1, typename T2>
+class QMap;
+
+namespace Tellico {
+
+/**
+ * @short A simple dialog for editing a map between two strings.
+ *
+ * A \ref KListView is used with the map keys in the first column and
+ * the map values in the second. Two edit boxes are below the list view.
+ * When an item is selected, the key-value is pair is placed in the edit
+ * boxes. Add and Delete buttons are used to add a new pair, or to remove
+ * an existing one.
+ *
+ * @author Robby Stephenson
+ */
+class StringMapDialog : public KDialogBase {
+Q_OBJECT
+
+public:
+ StringMapDialog(const QMap<QString, QString>& stringMap, QWidget* parent, const char* name=0, bool modal=false);
+
+ /**
+ * Sets the titles for the key and value columns.
+ *
+ * @param label1 The name of the key string
+ * @param label2 The name of the value string
+ */
+ void setLabels(const QString& label1, const QString& label2);
+ /**
+ * Returns the modified string map.
+ *
+ * @return The modified string map
+ */
+ QMap<QString, QString> stringMap();
+
+private slots:
+ void slotAdd();
+ void slotDelete();
+ void slotUpdate(QListViewItem* item);
+
+protected:
+ KListView* m_listView;
+ KLineEdit* m_edit1;
+ KLineEdit* m_edit2;
+};
+
+} // end namespace
+#endif
diff --git a/src/gui/tabcontrol.cpp b/src/gui/tabcontrol.cpp
new file mode 100644
index 0000000..145f632
--- /dev/null
+++ b/src/gui/tabcontrol.cpp
@@ -0,0 +1,77 @@
+/***************************************************************************
+ copyright : (C) 2002-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "tabcontrol.h"
+
+#include <qtabbar.h>
+#include <qobjectlist.h>
+
+using Tellico::GUI::TabControl;
+
+TabControl::TabControl(QWidget* parent_, const char* name_/*=0*/)
+ : QTabWidget(parent_, name_) {
+}
+
+QTabBar* TabControl::tabBar() const {
+ return QTabWidget::tabBar();
+}
+
+void TabControl::setFocusToFirstChild() {
+ QWidget* page = currentPage();
+ Q_ASSERT(page);
+ QObjectList* list = page->queryList("QWidget");
+ for(QObjectListIt it(*list); it.current(); ++it) {
+ QWidget* w = static_cast<QWidget*>(it.current());
+ if(w->isFocusEnabled()) {
+ w->setFocus();
+ break;
+ }
+ }
+ delete list;
+}
+
+// have to loop backwards since count() gets decremented on delete
+void TabControl::clear() {
+ for(int i = count(); i > 0; --i) {
+ QWidget* w = page(i-1);
+ if(w) {
+ removePage(w);
+ delete w;
+ }
+ }
+}
+
+void TabControl::setTabBarHidden(bool hide_) {
+ QWidget* rightcorner = cornerWidget(TopRight);
+ QWidget* leftcorner = cornerWidget(TopLeft);
+
+ if(hide_) {
+ if(leftcorner) {
+ leftcorner->hide();
+ }
+ if(rightcorner) {
+ rightcorner->hide();
+ }
+ tabBar()->hide();
+ } else {
+ tabBar()->show();
+ if(leftcorner) {
+ leftcorner->show();
+ }
+ if(rightcorner) {
+ rightcorner->show();
+ }
+ }
+}
+
+#include "tabcontrol.moc"
diff --git a/src/gui/tabcontrol.h b/src/gui/tabcontrol.h
new file mode 100644
index 0000000..20d22f5
--- /dev/null
+++ b/src/gui/tabcontrol.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ copyright : (C) 2002-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TABCONTROL_H
+#define TABCONTROL_H
+
+#include <qtabwidget.h>
+
+namespace Tellico {
+ namespace GUI {
+
+/**
+ * @author Robby Stephenson
+ */
+class TabControl : public QTabWidget {
+Q_OBJECT
+
+public:
+ /**
+ * Constructor
+ */
+ TabControl(QWidget* parent, const char* name=0);
+
+ QTabBar* tabBar() const;
+ void setTabBarHidden(bool hide);
+
+ /**
+ * Sets the focus to the first focusable widget on the current page.
+ */
+ void setFocusToFirstChild();
+
+public slots:
+ void clear();
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/gui/tablefieldwidget.cpp b/src/gui/tablefieldwidget.cpp
new file mode 100644
index 0000000..30f89b4
--- /dev/null
+++ b/src/gui/tablefieldwidget.cpp
@@ -0,0 +1,330 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "tablefieldwidget.h"
+#include "../field.h"
+#include "../tellico_utils.h"
+#include "../tellico_kernel.h"
+
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <kiconloader.h>
+#include <kinputdialog.h>
+
+#include <qtable.h>
+
+namespace {
+ static const int MIN_TABLE_ROWS = 5;
+ static const int MAX_TABLE_COLS = 10;
+}
+
+using Tellico::GUI::TableFieldWidget;
+
+TableFieldWidget::TableFieldWidget(Data::FieldPtr field_, QWidget* parent_, const char* name_/*=0*/)
+ : FieldWidget(field_, parent_, name_), m_field(field_), m_row(-1), m_col(-1) {
+
+ bool ok;
+ m_columns = Tellico::toUInt(field_->property(QString::fromLatin1("columns")), &ok);
+ if(!ok) {
+ m_columns = 1;
+ } else {
+ m_columns = QMIN(m_columns, MAX_TABLE_COLS); // max of 5 columns
+ }
+
+ m_table = new QTable(MIN_TABLE_ROWS, m_columns, this);
+ labelColumns(m_field);
+ // allow renaming of column titles
+ m_table->horizontalHeader()->setClickEnabled(true);
+ m_table->horizontalHeader()->installEventFilter(this);
+
+ m_table->verticalHeader()->setClickEnabled(true);
+ m_table->verticalHeader()->installEventFilter(this);
+ connect(m_table->verticalHeader(), SIGNAL(indexChange(int, int, int)), SIGNAL(modified()));
+
+ m_table->setDragEnabled(false);
+ m_table->setFocusStyle(QTable::FollowStyle);
+ m_table->setRowMovingEnabled(true); // rows can be moved
+ m_table->setColumnMovingEnabled(false); // columns remain fixed
+
+ m_table->setColumnStretchable(m_columns-1, true);
+ m_table->adjustColumn(m_columns-1);
+ m_table->setSelectionMode(QTable::NoSelection);
+ m_table->setHScrollBarMode(QScrollView::AlwaysOff);
+
+ connect(m_table, SIGNAL(valueChanged(int, int)), SIGNAL(modified()));
+ connect(m_table, SIGNAL(currentChanged(int, int)), SLOT(slotCheckRows(int, int)));
+ connect(m_table, SIGNAL(valueChanged(int, int)), SLOT(slotResizeColumn(int, int)));
+ connect(m_table, SIGNAL(contextMenuRequested(int, int, const QPoint&)), SLOT(contextMenu(int, int, const QPoint&)));
+
+ registerWidget();
+}
+
+QString TableFieldWidget::text() const {
+ QString text, str, rstack, cstack, rowStr;
+ for(int row = 0; row < m_table->numRows(); ++row) {
+ rowStr.truncate(0);
+ cstack.truncate(0);
+ for(int col = 0; col < m_table->numCols(); ++col) {
+ str = m_table->text(row, col).simplifyWhiteSpace();
+ if(str.isEmpty()) {
+ cstack += QString::fromLatin1("::");
+ } else {
+ rowStr += cstack + str + QString::fromLatin1("::");
+ cstack.truncate(0);
+ }
+ }
+ if(rowStr.isEmpty()) {
+ rstack += QString::fromLatin1("; ");
+ } else {
+ rowStr.truncate(rowStr.length()-2); // remove last semi-colon and space
+ text += rstack + rowStr + QString::fromLatin1("; ");
+ rstack.truncate(0);
+ }
+ }
+ if(!text.isEmpty()) {
+ text.truncate(text.length()-2); // remove last semi-colon and space
+ }
+
+ // now reduce number of rows if necessary
+ bool loop = true;
+ for(int row = m_table->numRows()-1; loop && row > MIN_TABLE_ROWS; --row) {
+ bool empty = true;
+ for(int col = 0; col < m_table->numCols(); ++col) {
+ if(!m_table->text(row, col).isEmpty()) {
+ empty = false;
+ break;
+ }
+ }
+ if(empty) {
+ m_table->removeRow(row);
+ } else {
+ loop = false;
+ }
+ }
+ return text;
+}
+
+void TableFieldWidget::setText(const QString& text_) {
+ QStringList list = Data::Field::split(text_, true);
+ // add additional rows if needed
+ if(static_cast<int>(list.count()) > m_table->numRows()) {
+ m_table->insertRows(m_table->numRows(), list.count()-m_table->numRows());
+ }
+ int row;
+ for(row = 0; row < static_cast<int>(list.count()); ++row) {
+ for(int col = 0; col < m_table->numCols(); ++col) {
+ m_table->setText(row, col, list[row].section(QString::fromLatin1("::"), col, col));
+ }
+ m_table->showRow(row);
+ }
+ // remove any un-needed rows
+ int minRow = QMAX(row, MIN_TABLE_ROWS);
+ for(row = m_table->numRows()-1; row >= minRow; --row) {
+ m_table->removeRow(row);
+ }
+ // adjust all columns
+ for(int col = 0; col < m_table->numCols()-1; ++col) {
+ m_table->adjustColumn(col);
+ }
+}
+
+void TableFieldWidget::clear() {
+ bool wasEmpty = true;
+ for(int row = 0; row < m_table->numRows(); ++row) {
+ if(!emptyRow(row)) {
+ wasEmpty = false;
+ }
+ for(int col = 0; col < m_table->numCols(); ++col) {
+ m_table->setText(row, col, QString::null);
+ }
+ if(row >= MIN_TABLE_ROWS) {
+ m_table->removeRow(row);
+ --row;
+ }
+ }
+ editMultiple(false);
+ if(!wasEmpty) {
+ emit modified();
+ }
+}
+
+QWidget* TableFieldWidget::widget() {
+ return m_table;
+}
+
+void TableFieldWidget::slotCheckRows(int row_, int) {
+ if(row_ == m_table->numRows()-1 && !emptyRow(row_)) { // if is last row and row above is not empty
+ m_table->insertRows(m_table->numRows());
+ }
+}
+
+void TableFieldWidget::slotResizeColumn(int, int col_) {
+ m_table->adjustColumn(col_);
+}
+
+void TableFieldWidget::slotRenameColumn() {
+ if(m_col < 0 || m_col >= m_columns) {
+ return;
+ }
+ QString name = m_table->horizontalHeader()->label(m_col);
+ bool ok;
+ QString newName = KInputDialog::getText(i18n("Rename Column"), i18n("New column name:"),
+ name, &ok, this);
+ if(ok && !newName.isEmpty()) {
+ Data::FieldPtr newField = new Data::Field(*m_field);
+ newField->setProperty(QString::fromLatin1("column%1").arg(m_col+1), newName);
+ if(Kernel::self()->modifyField(newField)) {
+ m_field = newField;
+ labelColumns(m_field);
+ }
+ }
+}
+
+bool TableFieldWidget::emptyRow(int row_) const {
+ for(int col = 0; col < m_table->numCols(); ++col) {
+ if(!m_table->text(row_, col).isEmpty()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void TableFieldWidget::labelColumns(Data::FieldPtr field_) {
+ for(int i = 0; i < m_columns; ++i) {
+ QString s = field_->property(QString::fromLatin1("column%1").arg(i+1));
+ if(s.isEmpty()) {
+ s = i18n("Column %1").arg(i+1);
+ }
+ m_table->horizontalHeader()->setLabel(i, s);
+ }
+}
+
+void TableFieldWidget::updateFieldHook(Data::FieldPtr, Data::FieldPtr newField_) {
+ bool ok;
+ m_columns = Tellico::toUInt(newField_->property(QString::fromLatin1("columns")), &ok);
+ if(!ok) {
+ m_columns = 1;
+ } else {
+ m_columns = QMIN(m_columns, MAX_TABLE_COLS); // max of 5 columns
+ }
+ if(m_columns != m_table->numCols()) {
+ m_table->setNumCols(m_columns);
+ }
+ m_table->horizontalHeader()->adjustHeaderSize();
+ labelColumns(newField_);
+}
+
+bool TableFieldWidget::eventFilter(QObject* obj_, QEvent* ev_) {
+ if(ev_->type() == QEvent::MouseButtonPress
+ && static_cast<QMouseEvent*>(ev_)->button() == Qt::RightButton) {
+ if(obj_ == m_table->horizontalHeader()) {
+ QMouseEvent* ev = static_cast<QMouseEvent*>(ev_);
+ // might be scrolled
+ int pos = ev->x() + m_table->horizontalHeader()->offset();
+ int col = m_table->horizontalHeader()->sectionAt(pos);
+ if(col >= m_columns) {
+ return false;
+ }
+ m_row = -1;
+ m_col = col;
+ KPopupMenu menu(this);
+ menu.insertItem(SmallIconSet(QString::fromLatin1("edit")), i18n("Rename Column..."),
+ this, SLOT(slotRenameColumn()));
+ menu.exec(ev->globalPos());
+ return true;
+ } else if(obj_ == m_table->verticalHeader()) {
+ QMouseEvent* ev = static_cast<QMouseEvent*>(ev_);
+ // might be scrolled
+ int pos = ev->y() + m_table->verticalHeader()->offset();
+ int row = m_table->verticalHeader()->sectionAt(pos);
+ if(row < 0 || row > m_table->numRows()-1) {
+ return false;
+ }
+ m_row = row;
+ m_col = -1;
+ // show regular right-click menu
+ contextMenu(m_row, m_col, ev->globalPos());
+ return true;
+ }
+ }
+ return FieldWidget::eventFilter(obj_, ev_);
+}
+
+void TableFieldWidget::contextMenu(int row_, int col_, const QPoint& p_) {
+ // might get called with col == -1 for clicking on vertical header
+ // but a negative row means clicking outside bounds of table
+ if(row_ < 0) {
+ return;
+ }
+ m_row = row_;
+ m_col = col_;
+
+ int id;
+ KPopupMenu menu(this);
+ menu.insertItem(SmallIconSet(QString::fromLatin1("insrow")), i18n("Insert Row"),
+ this, SLOT(slotInsertRow()));
+ menu.insertItem(SmallIconSet(QString::fromLatin1("remrow")), i18n("Remove Row"),
+ this, SLOT(slotRemoveRow()));
+ id = menu.insertItem(SmallIconSet(QString::fromLatin1("1uparrow")), i18n("Move Row Up"),
+ this, SLOT(slotMoveRowUp()));
+ if(m_row == 0) {
+ menu.setItemEnabled(id, false);
+ }
+ id = menu.insertItem(SmallIconSet(QString::fromLatin1("1downarrow")), i18n("Move Row Down"),
+ this, SLOT(slotMoveRowDown()));
+ if(m_row == m_table->numRows()-1) {
+ menu.setItemEnabled(id, false);
+ }
+ menu.insertSeparator();
+ id = menu.insertItem(SmallIconSet(QString::fromLatin1("edit")), i18n("Rename Column..."),
+ this, SLOT(slotRenameColumn()));
+ if(m_col < 0 || m_col > m_columns-1) {
+ menu.setItemEnabled(id, false);
+ }
+ menu.insertSeparator();
+ menu.insertItem(SmallIconSet(QString::fromLatin1("locationbar_erase")), i18n("Clear Table"),
+ this, SLOT(clear()));
+ menu.exec(p_);
+}
+
+void TableFieldWidget::slotInsertRow() {
+ if(m_row > -1) {
+ m_table->insertRows(m_row);
+ emit modified();
+ }
+}
+
+void TableFieldWidget::slotRemoveRow() {
+ if(m_row > -1) {
+ m_table->removeRow(m_row);
+ emit modified();
+ }
+}
+
+void TableFieldWidget::slotMoveRowUp() {
+ if(m_row > 0) {
+ m_table->swapRows(m_row, m_row-1, true);
+ m_table->updateContents();
+ emit modified();
+ }
+}
+
+void TableFieldWidget::slotMoveRowDown() {
+ if(m_row < m_table->numRows()-1) {
+ m_table->swapRows(m_row, m_row+1, true);
+ m_table->updateContents();
+ emit modified();
+ }
+}
+
+#include "tablefieldwidget.moc"
diff --git a/src/gui/tablefieldwidget.h b/src/gui/tablefieldwidget.h
new file mode 100644
index 0000000..da9157d
--- /dev/null
+++ b/src/gui/tablefieldwidget.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TABLEFIELDWIDGET_H
+#define TABLEFIELDWIDGET_H
+
+class QTable;
+class QEvent;
+
+#include "fieldwidget.h"
+#include "../datavectors.h"
+
+namespace Tellico {
+ namespace GUI {
+
+/**
+ * @author Robby Stephenson
+ */
+class TableFieldWidget : public FieldWidget {
+Q_OBJECT
+
+public:
+ TableFieldWidget(Data::FieldPtr field, QWidget* parent, const char* name=0);
+ virtual ~TableFieldWidget() {}
+
+ virtual QString text() const;
+ virtual void setText(const QString& text);
+
+ /**
+ * Event filter used to popup the menu
+ */
+ bool eventFilter(QObject* obj, QEvent* ev);
+
+public slots:
+ virtual void clear();
+
+protected:
+ virtual QWidget* widget();
+ virtual void updateFieldHook(Data::FieldPtr oldField, Data::FieldPtr newField);
+
+private slots:
+ void contextMenu(int row, int col, const QPoint& p);
+ void slotCheckRows(int row, int col);
+ void slotResizeColumn(int row, int col);
+ void slotRenameColumn();
+ void slotInsertRow();
+ void slotRemoveRow();
+ void slotMoveRowUp();
+ void slotMoveRowDown();
+
+private:
+ bool emptyRow(int row) const;
+ void labelColumns(Data::FieldPtr field);
+
+ QTable* m_table;
+ int m_columns;
+ Data::FieldPtr m_field;
+ int m_row;
+ int m_col;
+};
+
+ } // end GUI namespace
+} // end namespace
+#endif
diff --git a/src/gui/urlfieldwidget.cpp b/src/gui/urlfieldwidget.cpp
new file mode 100644
index 0000000..f3c2afd
--- /dev/null
+++ b/src/gui/urlfieldwidget.cpp
@@ -0,0 +1,98 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "urlfieldwidget.h"
+#include "../field.h"
+#include "../latin1literal.h"
+#include "../tellico_kernel.h"
+
+#include <klineedit.h>
+#include <kurlrequester.h>
+#include <kurllabel.h>
+
+using Tellico::GUI::URLFieldWidget;
+
+// subclass of KURLCompletion is needed so the KURLLabel
+// can open relative links. I don't want to have to have to update
+// the base directory of the completion every time a new document is opened
+QString URLFieldWidget::URLCompletion::makeCompletion(const QString& text_) {
+ // KURLCompletion::makeCompletion() uses an internal variable instead
+ // of calling KURLCompletion::dir() so need to set the base dir before completing
+ setDir(Kernel::self()->URL().directory());
+ return KURLCompletion::makeCompletion(text_);
+}
+
+URLFieldWidget::URLFieldWidget(Data::FieldPtr field_, QWidget* parent_, const char* name_/*=0*/)
+ : FieldWidget(field_, parent_, name_), m_run(0) {
+
+ m_requester = new KURLRequester(this);
+ m_requester->lineEdit()->setCompletionObject(new URLCompletion());
+ m_requester->lineEdit()->setAutoDeleteCompletionObject(true);
+ connect(m_requester, SIGNAL(textChanged(const QString&)), SIGNAL(modified()));
+ connect(m_requester, SIGNAL(textChanged(const QString&)), label(), SLOT(setURL(const QString&)));
+ connect(label(), SIGNAL(leftClickedURL(const QString&)), SLOT(slotOpenURL(const QString&)));
+ registerWidget();
+
+ // special case, remember if it's a relative url
+ m_isRelative = field_->property(QString::fromLatin1("relative")) == Latin1Literal("true");
+}
+
+URLFieldWidget::~URLFieldWidget() {
+ if(m_run) {
+ m_run->abort();
+ }
+}
+
+QString URLFieldWidget::text() const {
+ if(m_isRelative) {
+ return KURL::relativeURL(Kernel::self()->URL(), m_requester->url());
+ }
+ // for comparison purposes and to be consistent with the file listing importer
+ // I want the full url here, including the protocol
+ // the requester only returns the path, so create a KURL
+ return KURL(m_requester->url()).url();
+}
+
+void URLFieldWidget::setText(const QString& text_) {
+ blockSignals(true);
+
+ m_requester->blockSignals(true);
+ m_requester->setURL(text_);
+ m_requester->blockSignals(false);
+ static_cast<KURLLabel*>(label())->setURL(text_);
+
+ blockSignals(false);
+}
+
+void URLFieldWidget::clear() {
+ m_requester->clear();
+ editMultiple(false);
+}
+
+void URLFieldWidget::updateFieldHook(Data::FieldPtr, Data::FieldPtr newField_) {
+ m_isRelative = newField_->property(QString::fromLatin1("relative")) == Latin1Literal("true");
+}
+
+void URLFieldWidget::slotOpenURL(const QString& url_) {
+ if(url_.isEmpty()) {
+ return;
+ }
+ // just in case, interpret string relative to document url
+ m_run = new KRun(KURL(Kernel::self()->URL(), url_));
+}
+
+QWidget* URLFieldWidget::widget() {
+ return m_requester;
+}
+
+#include "urlfieldwidget.moc"
diff --git a/src/gui/urlfieldwidget.h b/src/gui/urlfieldwidget.h
new file mode 100644
index 0000000..70e9505
--- /dev/null
+++ b/src/gui/urlfieldwidget.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef URLFIELDWIDGET_H
+#define URLFIELDWIDGET_H
+
+class KURLRequester;
+
+#include "fieldwidget.h"
+
+#include <krun.h>
+#include <kurlcompletion.h>
+
+#include <qguardedptr.h>
+
+namespace Tellico {
+ namespace GUI {
+
+/**
+ * @author Robby Stephenson
+ */
+class URLFieldWidget : public FieldWidget {
+Q_OBJECT
+
+public:
+ URLFieldWidget(Data::FieldPtr field, QWidget* parent, const char* name=0);
+ virtual ~URLFieldWidget();
+
+ virtual QString text() const;
+ virtual void setText(const QString& text);
+
+public slots:
+ virtual void clear();
+
+protected:
+ virtual QWidget* widget();
+ virtual void updateFieldHook(Data::FieldPtr oldField, Data::FieldPtr newField);
+
+protected slots:
+ void slotOpenURL(const QString& url);
+
+private:
+ class URLCompletion : public KURLCompletion {
+ public:
+ URLCompletion() : KURLCompletion() {}
+ virtual QString makeCompletion(const QString& text);
+ };
+
+ KURLRequester* m_requester;
+ bool m_isRelative : 1;
+ QGuardedPtr<KRun> m_run;
+};
+
+ } // end GUI namespace
+} // end namespace
+#endif
diff --git a/src/image.cpp b/src/image.cpp
new file mode 100644
index 0000000..35e14cb
--- /dev/null
+++ b/src/image.cpp
@@ -0,0 +1,162 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "image.h"
+#include "imagefactory.h"
+#include "tellico_debug.h"
+
+#include <kmdcodec.h>
+#include <kpixmapio.h>
+#include <kstaticdeleter.h>
+
+#include <qbuffer.h>
+#include <qregexp.h>
+
+using Tellico::Data::Image;
+using Tellico::Data::ImageInfo;
+
+KPixmapIO* Image::s_pixmapIO = 0;
+static KStaticDeleter<KPixmapIO> staticKPixmapIODeleter;
+KPixmapIO* Image::io() {
+ if(!s_pixmapIO) {
+ staticKPixmapIODeleter.setObject(s_pixmapIO, new KPixmapIO());
+ }
+ return s_pixmapIO;
+}
+
+Image::Image() : QImage(), m_id(QString::null), m_linkOnly(false) {
+}
+
+// I'm using the MD5 hash as the id. I consider it rather unlikely that two images in one
+// collection could ever have the same hash, and this lets me do a fast comparison of two images
+// simply by comparing their ids.
+Image::Image(const QString& filename_) : QImage(filename_), m_linkOnly(false) {
+ m_format = QImage::imageFormat(filename_);
+ calculateID();
+}
+
+Image::Image(const QImage& img_, const QString& format_) : QImage(img_), m_format(format_), m_linkOnly(false) {
+ calculateID();
+}
+
+Image::Image(const QByteArray& data_, const QString& format_, const QString& id_)
+ : QImage(data_), m_id(idClean(id_)), m_format(format_), m_linkOnly(false) {
+ if(isNull()) {
+ m_id = QString();
+ }
+}
+
+Image::~Image() {
+}
+
+QByteArray Image::byteArray() const {
+ return byteArray(*this, outputFormat(m_format));
+}
+
+bool Image::isNull() const {
+ // 1x1 images are considered null for Tellico. Amazon returns some like that.
+ return QImage::isNull() || (width() < 2 && height() < 2);
+}
+
+QPixmap Image::convertToPixmap() const {
+ return io()->convertToPixmap(*this);
+}
+
+QPixmap Image::convertToPixmap(int w_, int h_) const {
+ if(w_ < width() || h_ < height()) {
+ return io()->convertToPixmap(this->smoothScale(w_, h_, ScaleMin));
+ } else {
+ return io()->convertToPixmap(*this);
+ }
+}
+
+QCString Image::outputFormat(const QCString& inputFormat) {
+ QStrList list = QImage::outputFormats();
+ for(QStrListIterator it(list); it.current(); ++it) {
+ if(inputFormat == it.current()) {
+ return inputFormat;
+ }
+ }
+// myDebug() << "Image::outputFormat() - writing " << inputFormat << " as PNG" << endl;
+ return "PNG";
+}
+
+QByteArray Image::byteArray(const QImage& img_, const QCString& outputFormat_) {
+ QByteArray ba;
+ QBuffer buf(ba);
+ buf.open(IO_WriteOnly);
+ QImageIO iio(&buf, outputFormat_);
+ iio.setImage(img_);
+ iio.write();
+ buf.close();
+ return ba;
+}
+
+QString Image::idClean(const QString& id_) {
+ static const QRegExp rx('[' + QRegExp::escape(QString::fromLatin1("/@<>#\"&%?={}|^~[]'`\\:+")) + ']');
+ QString clean = id_;
+ return clean.remove(rx);
+}
+
+void Image::setID(const QString& id_) {
+ m_id = id_;
+}
+
+void Image::calculateID() {
+ // the id will eventually be used as a filename
+ if(!isNull()) {
+ KMD5 md5(byteArray());
+ m_id = QString::fromLatin1(md5.hexDigest()) + QString::fromLatin1(".") + QString::fromLatin1(m_format).lower();
+ m_id = idClean(m_id);
+ }
+}
+
+/******************************************************/
+
+ImageInfo::ImageInfo(const Image& img_)
+ : id(img_.id())
+ , format(img_.format())
+ , linkOnly(img_.linkOnly())
+ , m_width(img_.width())
+ , m_height(img_.height()) {
+}
+
+ImageInfo::ImageInfo(const QString& id_, const QCString& format_, int w_, int h_, bool l_)
+ : id(id_)
+ , format(format_)
+ , linkOnly(l_)
+ , m_width(w_)
+ , m_height(h_) {
+}
+
+int ImageInfo::width(bool loadIfNecessary) const {
+ if(m_width < 1 && loadIfNecessary) {
+ const Image& img = ImageFactory::imageById(id);
+ if(!img.isNull()) {
+ m_width = img.width();
+ m_height = img.height();
+ }
+ }
+ return m_width;
+}
+
+int ImageInfo::height(bool loadIfNecessary) const {
+ if(m_height < 1 && loadIfNecessary) {
+ const Image& img = ImageFactory::imageById(id);
+ if(!img.isNull()) {
+ m_width = img.width();
+ m_height = img.height();
+ }
+ }
+ return m_height;
+}
diff --git a/src/image.h b/src/image.h
new file mode 100644
index 0000000..9545500
--- /dev/null
+++ b/src/image.h
@@ -0,0 +1,99 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef IMAGE_H
+#define IMAGE_H
+
+#include <qimage.h>
+#include <qstring.h>
+
+class KPixmapIO;
+
+namespace Tellico {
+ class ImageFactory;
+ class FileHandler;
+
+ namespace Data {
+
+/**
+ * @author Robby Stephenson
+ */
+class Image : public QImage {
+
+friend class Tellico::ImageFactory;
+friend class Tellico::FileHandler;
+
+public:
+ ~Image();
+
+ const QString& id() const { return m_id; };
+ const QCString& format() const { return m_format; };
+ QByteArray byteArray() const;
+ bool isNull() const;
+ bool linkOnly() const { return m_linkOnly; }
+ void setLinkOnly(bool l) { m_linkOnly = l; }
+
+ QPixmap convertToPixmap() const;
+ QPixmap convertToPixmap(int width, int height) const;
+
+ static QCString outputFormat(const QCString& inputFormat);
+ static QByteArray byteArray(const QImage& img, const QCString& outputFormat);
+ static QString idClean(const QString& id);
+
+private:
+ Image();
+ explicit Image(const QString& filename);
+ Image(const QImage& image, const QString& format);
+ Image(const QByteArray& data, const QString& format, const QString& id);
+
+ //disable copy
+ Image(const Image&);
+ Image& operator=(const Image&);
+
+ void setID(const QString& id);
+ void calculateID();
+
+ QString m_id;
+ QCString m_format;
+ bool m_linkOnly : 1;
+
+ static KPixmapIO* s_pixmapIO;
+ static KPixmapIO* io();
+};
+
+class ImageInfo {
+public:
+ ImageInfo() {}
+ explicit ImageInfo(const Image& img);
+ ImageInfo(const QString& id, const QCString& format, int w, int h, bool link);
+ bool isNull() const { return id.isEmpty(); }
+ QString id;
+ QCString format;
+ bool linkOnly : 1;
+
+ int width(bool loadIfNecessary=true) const;
+ int height(bool loadIfNecessary=true) const;
+
+private:
+ mutable int m_width;
+ mutable int m_height;
+};
+
+ } // end namespace
+} // end namespace
+
+inline bool operator== (const Tellico::Data::Image& img1, const Tellico::Data::Image& img2) {
+ return img1.id() == img2.id();
+}
+
+#endif
diff --git a/src/imagefactory.cpp b/src/imagefactory.cpp
new file mode 100644
index 0000000..00a980a
--- /dev/null
+++ b/src/imagefactory.cpp
@@ -0,0 +1,611 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "imagefactory.h"
+#include "image.h"
+#include "document.h"
+#include "filehandler.h"
+#include "tellico_utils.h"
+#include "tellico_kernel.h"
+#include "core/tellico_config.h"
+#include "tellico_debug.h"
+
+#include <ktempdir.h>
+#include <kapplication.h>
+#include <kimageeffect.h>
+
+#include <qfile.h>
+#include <qdir.h>
+
+#define RELEASE_IMAGES
+
+using Tellico::ImageFactory;
+
+bool ImageFactory::s_needInit = true;
+const Tellico::Data::Image ImageFactory::s_null;
+
+QDict<Tellico::Data::Image> ImageFactory::s_imageDict;
+// since most images get turned into pixmaps quickly, use 10 megs
+// for images and 10 megs for pixmaps
+QCache<Tellico::Data::Image> ImageFactory::s_imageCache(10 * 1024 * 1024);
+QCache<QPixmap> ImageFactory::s_pixmapCache(10 * 1024 * 1024);
+// this image info map is just for big images that don't fit
+// in the cache, so that don't have to be continually reloaded to get info
+QMap<QString, Tellico::Data::ImageInfo> ImageFactory::s_imageInfoMap;
+Tellico::StringSet ImageFactory::s_imagesInTmpDir;
+Tellico::StringSet ImageFactory::s_imagesToRelease;
+KTempDir* ImageFactory::s_tmpDir = 0;
+QString ImageFactory::s_localDir;
+
+void ImageFactory::init() {
+ if(!s_needInit) {
+ return;
+ }
+ s_imageDict.setAutoDelete(true);
+ s_imageCache.setAutoDelete(true);
+ s_imageCache.setMaxCost(Config::imageCacheSize());
+ s_pixmapCache.setAutoDelete(true);
+ s_needInit = false;
+}
+
+QString ImageFactory::tempDir() {
+ if(!s_tmpDir) {
+ s_tmpDir = new KTempDir();
+ s_tmpDir->setAutoDelete(true);
+ }
+ return s_tmpDir->name();
+}
+
+QString ImageFactory::dataDir() {
+ static const QString dataDir = Tellico::saveLocation(QString::fromLatin1("data/"));
+ return dataDir;
+}
+
+QString ImageFactory::localDir() {
+ if(s_localDir.isEmpty()) {
+ return dataDir();
+ }
+ return s_localDir;
+}
+
+QString ImageFactory::addImage(const KURL& url_, bool quiet_, const KURL& refer_, bool link_) {
+ return addImageImpl(url_, quiet_, refer_, link_).id();
+}
+
+const Tellico::Data::Image& ImageFactory::addImageImpl(const KURL& url_, bool quiet_, const KURL& refer_, bool link_) {
+ if(url_.isEmpty() || !url_.isValid()) {
+ return s_null;
+ }
+// myLog() << "ImageFactory::addImageImpl(KURL) - " << url_.prettyURL() << endl;
+ Data::Image* img = refer_.isEmpty()
+ ? FileHandler::readImageFile(url_, quiet_)
+ : FileHandler::readImageFile(url_, quiet_, refer_);
+ if(!img) {
+ myLog() << "ImageFactory::addImageImpl() - image not found: " << url_.prettyURL() << endl;
+ return s_null;
+ }
+ if(img->isNull()) {
+ delete img;
+ return s_null;
+ }
+
+ if(link_) {
+ img->setLinkOnly(true);
+ img->setID(url_.url());
+ }
+
+ if(hasImage(img->id())) {
+// myDebug() << "### ImageFactory::addImageImpl() - hasImage() is true!" << endl;
+ const Data::Image& img2 = imageById(img->id());
+ if(!img2.isNull()) {
+ delete img;
+ return img2;
+ }
+ }
+
+ if(!link_) {
+ s_imageDict.insert(img->id(), img);
+ }
+ s_imageInfoMap.insert(img->id(), Data::ImageInfo(*img));
+ return *img;
+}
+
+QString ImageFactory::addImage(const QImage& image_, const QString& format_) {
+ return addImageImpl(image_, format_).id();
+}
+
+QString ImageFactory::addImage(const QPixmap& pix_, const QString& format_) {
+ return addImageImpl(pix_.convertToImage(), format_).id();
+}
+
+const Tellico::Data::Image& ImageFactory::addImageImpl(const QImage& image_, const QString& format_) {
+ Data::Image* img = new Data::Image(image_, format_);
+ if(hasImage(img->id())) {
+ const Data::Image& img2 = imageById(img->id());
+ if(!img2.isNull()) {
+ delete img;
+ return img2;
+ }
+ }
+ if(img->isNull()) {
+ delete img;
+ return s_null;
+ }
+ s_imageDict.insert(img->id(), img);
+ s_imageInfoMap.insert(img->id(), Data::ImageInfo(*img));
+ return *img;
+}
+
+QString ImageFactory::addImage(const QByteArray& data_, const QString& format_, const QString& id_) {
+ return addImageImpl(data_, format_, id_).id();
+}
+
+const Tellico::Data::Image& ImageFactory::addImageImpl(const QByteArray& data_, const QString& format_,
+ const QString& id_) {
+ if(id_.isEmpty()) {
+ return s_null;
+ }
+
+ // do not call imageById(), it causes infinite looping with Document::loadImage()
+ Data::Image* img = s_imageCache.find(id_);
+ if(img) {
+ myLog() << "ImageFactory::addImageImpl(QByteArray) - already exists in cache: " << id_ << endl;
+ return *img;
+ }
+
+ img = s_imageDict.find(id_);
+ if(img) {
+ myLog() << "ImageFactory::addImageImpl(QByteArray) - already exists in dict: " << id_ << endl;
+ return *img;
+ }
+
+ img = new Data::Image(data_, format_, id_);
+ if(img->isNull()) {
+ myDebug() << "ImageFactory::addImageImpl(QByteArray) - NULL IMAGE!!!!!" << endl;
+ delete img;
+ return s_null;
+ }
+
+// myLog() << "ImageFactory::addImageImpl(QByteArray) - " << data_.size()
+// << " bytes, format = " << format_
+// << ", id = "<< img->id() << endl;
+
+ s_imageDict.insert(img->id(), img);
+ s_imageInfoMap.insert(img->id(), Data::ImageInfo(*img));
+ return *img;
+}
+
+const Tellico::Data::Image& ImageFactory::addCachedImageImpl(const QString& id_, CacheDir dir_) {
+// myLog() << "ImageFactory::addCachedImageImpl() - dir = " << (dir_ == DataDir ? "DataDir" : "TmpDir" )
+// << "; id = " << id_ << endl;
+ KURL u;
+ if(dir_ == DataDir) {
+ u.setPath(dataDir() + id_);
+ } else if(dir_ == LocalDir) {
+ u.setPath(localDir() + id_);
+ } else{ // Temp
+ u.setPath(tempDir() + id_);
+ }
+
+ QString newID = addImage(u, true);
+ if(newID.isEmpty()) {
+ myLog() << "ImageFactory::addCachedImageImpl() - null image loaded" << endl;
+ return s_null;
+ }
+
+ // the id probably got changed, so reset it
+ // addImage() already inserted it in the dict
+ Data::Image* img = s_imageDict.take(newID);
+ if(!img) {
+ kdWarning() << "ImageFactory::addCachedImageImpl() - no image in dict - very bad!" << endl;
+ return s_null;
+ }
+ if(img->isNull()) {
+ kdWarning() << "ImageFactory::addCachedImageImpl() - null image in dict, should never happen!" << endl;
+ delete img;
+ return s_null;
+ }
+ img->setID(id_);
+ s_imageInfoMap.remove(newID);
+ s_imageInfoMap.insert(img->id(), Data::ImageInfo(*img));
+
+ if(s_imageCache.insert(img->id(), img, img->numBytes())) {
+// myLog() << "ImageFactory::addCachedImageImpl() - removing from dict: " << img->id() << endl;
+ } else {
+ // can't hold it in the cache
+ kdWarning() << "Tellico's image cache is unable to hold the image, it might be too big!" << endl;
+ kdWarning() << "Image name is " << img->id() << endl;
+ kdWarning() << "Image size is " << img->numBytes() << endl;
+ kdWarning() << "Max cache size is " << s_imageCache.maxCost() << endl;
+
+ // add it back to the dict, but add the image to the list of
+ // images to release later. Necessary to avoid a memory leak since new Image()
+ // was called, we need to keep the pointer
+ s_imageDict.insert(img->id(), img);
+ s_imagesToRelease.add(img->id());
+ }
+ return *img;
+}
+
+bool ImageFactory::writeImage(const QString& id_, const KURL& targetDir_, bool force_) {
+// myLog() << "ImageFactory::writeImage() - target = " << targetDir_.url() << id_ << endl;
+ if(targetDir_.isEmpty()) {
+ myDebug() << "ImageFactory::writeImage() - empty target dir!" << endl;
+ return false;
+ }
+
+ const Data::Image& img = imageById(id_);
+ if(img.isNull()) {
+// myDebug() << "ImageFactory::writeImage() - null image: " << id_ << endl;
+ return false;
+ }
+
+ if(img.linkOnly()) {
+// myLog() << "ImageFactory::writeImage() - " << id_ << ": link only, not writing!" << endl;
+ return true;
+ }
+
+ KURL target = targetDir_;
+ target.addPath(id_);
+
+ return FileHandler::writeDataURL(target, img.byteArray(), force_);
+}
+
+bool ImageFactory::writeCachedImage(const QString& id_, CacheDir dir_, bool force_ /*=false*/) {
+ if(id_.isEmpty()) {
+ return false;
+ }
+// myLog() << "ImageFactory::writeCachedImage() - dir = " << (dir_ == DataDir ? "DataDir" : "TmpDir" )
+// << "; id = " << id_ << endl;
+
+ QString path = ( dir_ == DataDir ? dataDir() : dir_ == TempDir ? tempDir() : localDir() );
+
+ // images in the temp directory are erased every session, so we can track
+ // whether they've already been written with a simple string set.
+ // images in the data directory are persistent, so we have to check the
+ // actual file existence
+ bool exists = ( dir_ == TempDir ? s_imagesInTmpDir.has(id_) : QFile::exists(path + id_));
+
+ if(!force_ && exists) {
+// myDebug() << "...writeCachedImage() - exists = true: " << id_ << endl;
+ } else if(!force_ && !exists && dir_ == LocalDir) {
+ QDir dir(localDir());
+ if(!dir.exists()) {
+ myDebug() << "ImageFactory::writeCachedImage() - creating " << s_localDir << endl;
+ dir.mkdir(localDir());
+ }
+ } else {
+// myLog() << "ImageFactory::writeCachedImage() - dir = " << (dir_ == DataDir ? "DataDir" : "TmpDir" )
+// << "; id = " << id_ << endl;
+ }
+ // only write if it doesn't exist
+ bool success = (!force_ && exists) || writeImage(id_, path, true /* force */);
+
+ if(success) {
+ if(dir_ == TempDir) {
+ s_imagesInTmpDir.add(id_);
+ }
+
+ // remove from dict and add to cache
+ // it might not be in dict though
+ Data::Image* img = s_imageDict.take(id_);
+ if(img && s_imageCache.insert(img->id(), img, img->numBytes())) {
+ s_imageInfoMap.remove(id_);
+ } else if(img) {
+// myLog() << "ImageFactory::writeCachedImage() - failed writing image to cache: " << id_ << endl;
+// myLog() << "ImageFactory::writeCachedImage() - removed from dict, deleting: " << img->id() << endl;
+// myLog() << "ImageFactory::writeCachedImage() - current dict size: " << s_imageDict.count() << endl;
+ // can't insert it in the cache, so put it back in the dict
+ // No, it's written to disk now, so we're safe
+// s_imageDict.insert(img->id(), img);
+ delete img;
+ }
+ }
+ return success;
+}
+
+const Tellico::Data::Image& ImageFactory::imageById(const QString& id_) {
+ if(id_.isEmpty()) {
+ myDebug() << "ImageFactory::imageById() - empty id" << endl;
+ return s_null;
+ }
+// myLog() << "ImageFactory::imageById() - " << id_ << endl;
+
+ // can't think of a better place to regularly check for images to release
+ // but don't release image that just got asked for
+ s_imagesToRelease.remove(id_);
+ releaseImages();
+
+ // first check the cache, used for images that are in the data file, or are only temporary
+ // then the dict, used for images downloaded, but not yet saved anywhere
+ Data::Image* img = s_imageCache.find(id_);
+ if(img) {
+// myLog() << "...imageById() - found in cache" << endl;
+ return *img;
+ }
+
+ img = s_imageDict.find(id_);
+ if(img) {
+// myLog() << "...imageById() - found in dict" << endl;
+ return *img;
+ }
+
+ // if the image is link only, we need to load it
+ // but can't call imageInfo() since that might recurse into imageById()
+ // also, the image info cache might not have it so check if the
+ // id is a valid absolute url
+ // yeah, it's probably slow
+ if((s_imageInfoMap.contains(id_) && s_imageInfoMap[id_].linkOnly) || !KURL::isRelativeURL(id_)) {
+ KURL u = id_;
+ if(u.isValid()) {
+ return addImageImpl(u, false, KURL(), true);
+ }
+ }
+
+ // the document does a delayed loading of the images, sometimes
+ // so an image could be in the tmp dir and not be in the cache
+ // or it could be too big for the cache
+ if(s_imagesInTmpDir.has(id_)) {
+ const Data::Image& img2 = addCachedImageImpl(id_, TempDir);
+ if(!img2.isNull()) {
+// myLog() << "...imageById() - found in tmp dir" << endl;
+ return img2;
+ } else {
+ myLog() << "ImageFactory::imageById() - img in tmpDir list but not actually there: " << id_ << endl;
+ s_imagesInTmpDir.remove(id_);
+ }
+ }
+
+ // try to do a delayed loading of the image
+ if(Data::Document::self()->loadImage(id_)) {
+ // loadImage() could insert in either the cache or the dict!
+ img = s_imageCache.find(id_);
+ if(!img) {
+ img = s_imageDict.find(id_);
+ }
+ if(img) {
+// myLog() << "...imageById() - found in doc" << endl;
+ // go ahead and write image to disk so we don't have to keep it in memory
+ // calling pixmap() could be loading all the covers, and we don't want one
+ // to get pushed out of the cache yet
+ if(!s_imagesInTmpDir.has(id_)) {
+ writeCachedImage(id_, TempDir);
+ }
+ return *img;
+ }
+ }
+
+ // don't check Config::writeImagesInFile(), someday we might have problems
+ // and the image will exist in the data dir, but the app thinks everything should
+ // be in the zip file instead
+ bool exists = QFile::exists(dataDir() + id_);
+ if(exists) {
+ // if we're loading from the application data dir, but images are being saved in the
+ // data file instead, then consider the document to be modified since it needs
+ // the image saved
+ if(Config::imageLocation() != Config::ImagesInAppDir) {
+ Data::Document::self()->slotSetModified(true);
+ }
+ const Data::Image& img2 = addCachedImageImpl(id_, DataDir);
+ if(img2.isNull()) {
+ myDebug() << "ImageFactory::imageById() - tried to add from DataDir, but failed: " << id_ << endl;
+ } else {
+// myLog() << "...imageById() - found in data dir" << endl;
+ return img2;
+ }
+ }
+ // if localDir() == DataDir(), then there's nothing left to check
+ if(localDir() == dataDir()) {
+ return s_null;
+ }
+ exists = QFile::exists(localDir() + id_);
+ if(exists) {
+ // if we're loading from the application data dir, but images are being saved in the
+ // data file instead, then consider the document to be modified since it needs
+ // the image saved
+ if(Config::imageLocation() != Config::ImagesInLocalDir) {
+ Data::Document::self()->slotSetModified(true);
+ }
+ const Data::Image& img2 = addCachedImageImpl(id_, LocalDir);
+ if(img2.isNull()) {
+ myDebug() << "ImageFactory::imageById() - tried to add from LocalDir, but failed: " << id_ << endl;
+ } else {
+// myLog() << "...imageById() - found in data dir" << endl;
+ return img2;
+ }
+ }
+ myDebug() << "***ImageFactory::imageById() - not found: " << id_ << endl;
+ return s_null;
+}
+
+Tellico::Data::ImageInfo ImageFactory::imageInfo(const QString& id_) {
+ if(s_imageInfoMap.contains(id_)) {
+ return s_imageInfoMap[id_];
+ }
+
+ const Data::Image& img = imageById(id_);
+ if(img.isNull()) {
+ return Data::ImageInfo();
+ }
+ return Data::ImageInfo(img);
+}
+
+void ImageFactory::cacheImageInfo(const Data::ImageInfo& info) {
+ s_imageInfoMap.insert(info.id, info);
+}
+
+bool ImageFactory::validImage(const QString& id_) {
+ // don't try s_imageInfoMap[id_] cause it inserts an empty image info
+ return s_imageInfoMap.contains(id_) || hasImage(id_) || !imageById(id_).isNull();
+}
+
+QPixmap ImageFactory::pixmap(const QString& id_, int width_, int height_) {
+ if(id_.isEmpty()) {
+ return QPixmap();
+ }
+
+ const QString key = id_ + '|' + QString::number(width_) + '|' + QString::number(height_);
+ QPixmap* pix = s_pixmapCache.find(key);
+ if(pix) {
+ return *pix;
+ }
+
+ const Data::Image& img = imageById(id_);
+ if(img.isNull()) {
+ return QPixmap();
+ }
+
+ if(width_ > 0 && height_ > 0) {
+ pix = new QPixmap(img.convertToPixmap(width_, height_));
+ } else {
+ pix = new QPixmap(img.convertToPixmap());
+ }
+
+ // pixmap size is w x h x d, divided by 8 bits
+ if(!s_pixmapCache.insert(key, pix, pix->width()*pix->height()*pix->depth()/8)) {
+ kdWarning() << "ImageFactory::pixmap() - can't save in cache: " << id_ << endl;
+ kdWarning() << "### Current pixmap size is " << (pix->width()*pix->height()*pix->depth()/8) << endl;
+ kdWarning() << "### Max pixmap cache size is " << s_pixmapCache.maxCost() << endl;
+ QPixmap pix2(*pix);
+ delete pix;
+ return pix2;
+ }
+ return *pix;
+}
+
+void ImageFactory::clean(bool deleteTempDirectory_) {
+ // the dict and caches all auto-delete
+ s_imagesToRelease.clear();
+ s_imageDict.clear();
+ s_imageInfoMap.clear();
+ s_imageCache.clear();
+ s_pixmapCache.clear();
+ if(deleteTempDirectory_) {
+ s_imagesInTmpDir.clear();
+ delete s_tmpDir;
+ s_tmpDir = 0;
+ }
+}
+
+void ImageFactory::createStyleImages(const StyleOptions& opt_) {
+ const int collType = Kernel::self()->collectionType();
+
+ const QColor& baseColor = opt_.baseColor.isValid()
+ ? opt_.baseColor
+ : Config::templateBaseColor(collType);
+ const QColor& highColor = opt_.highlightedBaseColor.isValid()
+ ? opt_.highlightedBaseColor
+ : Config::templateHighlightedBaseColor(collType);
+
+ const QColor& bgc1 = Tellico::blendColors(baseColor, highColor, 30);
+ const QColor& bgc2 = Tellico::blendColors(baseColor, highColor, 50);
+
+ const QString bgname = QString::fromLatin1("gradient_bg.png");
+ QImage bgImage = KImageEffect::gradient(QSize(400, 1), bgc1, baseColor,
+ KImageEffect::PipeCrossGradient);
+ bgImage = KImageEffect::rotate(bgImage, KImageEffect::Rotate90);
+
+ const QString hdrname = QString::fromLatin1("gradient_header.png");
+ QImage hdrImage = KImageEffect::unbalancedGradient(QSize(1, 10), highColor, bgc2,
+ KImageEffect::VerticalGradient, 100, -100);
+
+ if(opt_.imgDir.isEmpty()) {
+ // write the style images both to the tmp dir and the data dir
+ // doesn't really hurt and lets the user switch back and forth
+ ImageFactory::removeImage(bgname, true /*delete */);
+ ImageFactory::addImageImpl(Data::Image::byteArray(bgImage, "PNG"), QString::fromLatin1("PNG"), bgname);
+ ImageFactory::writeCachedImage(bgname, DataDir, true /*force*/);
+ ImageFactory::writeCachedImage(bgname, TempDir, true /*force*/);
+
+ ImageFactory::removeImage(hdrname, true /*delete */);
+ ImageFactory::addImageImpl(Data::Image::byteArray(hdrImage, "PNG"), QString::fromLatin1("PNG"), hdrname);
+ ImageFactory::writeCachedImage(hdrname, DataDir, true /*force*/);
+ ImageFactory::writeCachedImage(hdrname, TempDir, true /*force*/);
+ } else {
+ bgImage.save(opt_.imgDir + bgname, "PNG");
+ hdrImage.save(opt_.imgDir + hdrname, "PNG");
+ }
+}
+
+void ImageFactory::removeImage(const QString& id_, bool deleteImage_) {
+ //be careful using this
+ s_imageDict.remove(id_);
+ s_imageCache.remove(id_);
+ s_imagesInTmpDir.remove(id_);
+
+ if(deleteImage_) {
+ // remove from both data dir and temp dir
+ QFile::remove(dataDir() + id_);
+ QFile::remove(tempDir() + id_);
+ }
+}
+
+Tellico::StringSet ImageFactory::imagesNotInCache() {
+ StringSet set;
+ for(QDictIterator<Tellico::Data::Image> it(s_imageDict); it.current(); ++it) {
+ if(s_imageCache.find(it.currentKey()) == 0) {
+ set.add(it.currentKey());
+ }
+ }
+ return set;
+}
+
+bool ImageFactory::hasImage(const QString& id_) {
+ return s_imageCache.find(id_, false) || s_imageDict.find(id_);
+}
+
+// the purpose here is to remove images from the dict if they're is on the disk somewhere,
+// either in tempDir() or in dataDir(). The use for this is for calling pixmap() on an
+// image too big to stay in the cache. Then it stays in the dict forever.
+void ImageFactory::releaseImages() {
+#ifdef RELEASE_IMAGES
+ if(s_imagesToRelease.isEmpty()) {
+ return;
+ }
+
+ const QStringList images = s_imagesToRelease.toList();
+ for(QStringList::ConstIterator it = images.begin(); it != images.end(); ++it) {
+ s_imagesToRelease.remove(*it);
+ if(!s_imageDict.find(*it)) {
+ continue;
+ }
+// myLog() << "ImageFactory::releaseImage() - id = " << *it << endl;
+ if(QFile::exists(dataDir() + *it)) {
+// myDebug() << "...exists in dataDir() - removing from dict" << endl;
+ s_imageDict.remove(*it);
+ } else if(QFile::exists(tempDir() + *it)) {
+// myDebug() << "...exists in tempDir() - removing from dict" << endl;
+ s_imageDict.remove(*it);
+ }
+ }
+#endif
+}
+
+void ImageFactory::setLocalDirectory(const KURL& url_) {
+ if(url_.isEmpty()) {
+ return;
+ }
+ if(!url_.isLocalFile()) {
+ myWarning() << "ImageFactory::setLocalDirectory() - Tellico can only save images to local disk" << endl;
+ myWarning() << "unable to save to " << url_ << endl;
+ } else {
+ s_localDir = url_.directory(false);
+ // could have already been set once
+ if(!url_.fileName().contains(QString::fromLatin1("_files"))) {
+ s_localDir += url_.fileName().section('.', 0, 0) + QString::fromLatin1("_files/");
+ }
+ myLog() << "ImageFactory::setLocalDirectory() - local dir = " << s_localDir << endl;
+ }
+}
+
+#undef RELEASE_IMAGES
diff --git a/src/imagefactory.h b/src/imagefactory.h
new file mode 100644
index 0000000..efb3009
--- /dev/null
+++ b/src/imagefactory.h
@@ -0,0 +1,195 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef IMAGEFACTORY_H
+#define IMAGEFACTORY_H
+
+#include "stringset.h"
+
+#include <kurl.h>
+
+#include <qcolor.h>
+#include <qcache.h>
+
+class KTempDir;
+
+namespace Tellico {
+ namespace Data {
+ class Image;
+ class ImageInfo;
+ }
+
+class StyleOptions {
+public:
+ QString fontFamily;
+ int fontSize;
+ QColor baseColor;
+ QColor textColor;
+ QColor highlightedBaseColor;
+ QColor highlightedTextColor;
+ QString imgDir;
+};
+
+/**
+ * @author Robby Stephenson
+ */
+class ImageFactory {
+public:
+ enum CacheDir {
+ TempDir,
+ DataDir,
+ LocalDir
+ };
+
+ /**
+ * setup some of the static members
+ */
+ static void init();
+
+ /**
+ * Returns the temporary directory where image files are saved
+ *
+ * @return The full path
+ */
+ static QString tempDir();
+ static QString dataDir();
+
+ /**
+ * Add an image, reading it from a URL, which is the case when adding a new image from the
+ * @ref ImageWidget.
+ *
+ * @param url The URL of the image, anything KIO can handle
+ * @param quiet If any error should not be reported.
+ * @return The image id, empty if null
+ */
+ static QString addImage(const KURL& url, bool quiet=false,
+ const KURL& referrer = KURL(), bool linkOnly=false);
+ /**
+ * Add an image, reading it from a regular QImage, which is the case when dragging and dropping
+ * an image in the @ref ImageWidget. The format has to be included, since the QImage doesn't
+ * 'know' what format it came from.
+ *
+ * @param image The qimage
+ * @param format The image format, probably "PNG"
+ * @return The image id, empty if null
+ */
+ static QString addImage(const QImage& image, const QString& format);
+ static QString addImage(const QPixmap& image, const QString& format);
+ /**
+ * Add an image, reading it from data, which is the case when reading from the data file. The
+ * @p id isn't strictly needed, since it can be reconstructed from the image data and format, but
+ * since it's already known, go ahead and use it.
+ *
+ * @param data The image data
+ * @param format The image format, from Qt's output format list
+ * @param id The internal id of the image
+ * @return The image id, empty if null
+ */
+ static QString addImage(const QByteArray& data, const QString& format, const QString& id);
+
+ /**
+ * Writes an image to a file. ImageFactory keeps track of which images were already written
+ * if the location is the same as the tempdir.
+ *
+ * @param id The ID of the image to be written
+ * @param targetDir The directory to write the image to, if empty, the tempdir is used.
+ * @param force Force the image to be written, even if it already has been
+ * @return Whether the save was successful
+ */
+ static bool writeImage(const QString& id, const KURL& targetDir, bool force=false);
+ static bool writeCachedImage(const QString& id, CacheDir dir, bool force = false);
+
+ /**
+ * Returns an image reference given its id. If none is found, a null image
+ * is returned.
+ *
+ * @param id The image id
+ * @return The image referencenter
+ */
+ static const Data::Image& imageById(const QString& id);
+ static Data::ImageInfo imageInfo(const QString& id);
+ static void cacheImageInfo(const Data::ImageInfo& info);
+ // basically returns !imageById().isNull()
+ static bool validImage(const QString& id);
+
+ static QPixmap pixmap(const QString& id, int w, int h);
+
+ /**
+ * Clear the image cache and dict
+ * if deleteTempDirectory = true, then clean the temp dir and remove all temporary image files
+ */
+ static void clean(bool deleteTempDirectory);
+ /**
+ * Creates the gradient images used in the entry view.
+ */
+ static void createStyleImages(const StyleOptions& options = StyleOptions());
+
+ static void removeImage(const QString& id_, bool deleteImage);
+ static StringSet imagesNotInCache();
+
+ static void setLocalDirectory(const KURL& url);
+ // local save directory
+ static QString localDir();
+
+private:
+ /**
+ * Add an image, reading it from a URL, which is the case when adding a new image from the
+ * @ref ImageWidget.
+ *
+ * @param url The URL of the image, anything KIO can handle
+ * @param quiet If any error should not be reported.
+ * @return The image
+ */
+ static const Data::Image& addImageImpl(const KURL& url, bool quiet=false,
+ const KURL& referrer = KURL(), bool linkOnly = false);
+ /**
+ * Add an image, reading it from a regular QImage, which is the case when dragging and dropping
+ * an image in the @ref ImageWidget. The format has to be included, since the QImage doesn't
+ * 'know' what format it came from.
+ *
+ * @param image The qimage
+ * @param format The image format, probably "PNG"
+ * @return The image
+ */
+ static const Data::Image& addImageImpl(const QImage& image, const QString& format);
+ /**
+ * Add an image, reading it from data, which is the case when reading from the data file. The
+ * @p id isn't strictly needed, since it can be reconstructed from the image data and format, but
+ * since it's already known, go ahead and use it.
+ *
+ * @param data The image data
+ * @param format The image format, from Qt's output format list
+ * @param id The internal id of the image
+ * @return The image
+ */
+ static const Data::Image& addImageImpl(const QByteArray& data, const QString& format, const QString& id);
+
+ static const Data::Image& addCachedImageImpl(const QString& id, CacheDir dir);
+ static bool hasImage(const QString& id);
+ static void releaseImages();
+
+ static bool s_needInit;
+ static QDict<Data::Image> s_imageDict;
+ static QCache<Data::Image> s_imageCache;
+ static QCache<QPixmap> s_pixmapCache;
+ static QMap<QString, Data::ImageInfo> s_imageInfoMap;
+ static StringSet s_imagesInTmpDir; // the id's of the images written to tmp directory
+ static StringSet s_imagesToRelease;
+ static KTempDir* s_tmpDir;
+ static QString s_localDir;
+ static const Data::Image s_null;
+};
+
+} // end namespace
+
+#endif
diff --git a/src/importdialog.cpp b/src/importdialog.cpp
new file mode 100644
index 0000000..07e0ec1
--- /dev/null
+++ b/src/importdialog.cpp
@@ -0,0 +1,382 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "importdialog.h"
+#include "document.h"
+#include "tellico_kernel.h"
+#include "tellico_debug.h"
+#include "collection.h"
+
+#include "translators/importer.h"
+#include "translators/tellicoimporter.h"
+#include "translators/bibteximporter.h"
+#include "translators/bibtexmlimporter.h"
+#include "translators/csvimporter.h"
+#include "translators/xsltimporter.h"
+#include "translators/audiofileimporter.h"
+#include "translators/alexandriaimporter.h"
+#include "translators/freedbimporter.h"
+#include "translators/risimporter.h"
+#include "translators/gcfilmsimporter.h"
+#include "translators/filelistingimporter.h"
+#include "translators/amcimporter.h"
+#include "translators/griffithimporter.h"
+#include "translators/pdfimporter.h"
+#include "translators/referencerimporter.h"
+#include "translators/deliciousimporter.h"
+
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+#include <qlayout.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+#include <qwhatsthis.h>
+#include <qtimer.h>
+
+// really according to taste or computer speed
+const unsigned Tellico::Import::Importer::s_stepSize = 20;
+
+using Tellico::ImportDialog;
+
+ImportDialog::ImportDialog(Import::Format format_, const KURL::List& urls_, QWidget* parent_, const char* name_)
+ : KDialogBase(parent_, name_, true /*modal*/, i18n("Import Options"), Ok|Cancel),
+ m_coll(0),
+ m_importer(importer(format_, urls_)) {
+ QWidget* widget = new QWidget(this);
+ QVBoxLayout* topLayout = new QVBoxLayout(widget, 0, spacingHint());
+
+ QButtonGroup* bg = new QButtonGroup(1, Qt::Horizontal, i18n("Import Options"), widget);
+ topLayout->addWidget(bg, 0);
+ m_radioReplace = new QRadioButton(i18n("&Replace current collection"), bg);
+ QWhatsThis::add(m_radioReplace, i18n("Replace the current collection with the contents "
+ "of the imported file."));
+ m_radioAppend = new QRadioButton(i18n("A&ppend to current collection"), bg);
+ QWhatsThis::add(m_radioAppend, i18n("Append the contents of the imported file to the "
+ "current collection. This is only possible when the "
+ "collection types match."));
+ m_radioMerge = new QRadioButton(i18n("&Merge with current collection"), bg);
+ QWhatsThis::add(m_radioMerge, i18n("Merge the contents of the imported file to the "
+ "current collection. This is only possible when the "
+ "collection types match. Entries must match exactly "
+ "in order to be merged."));
+ if(m_importer->canImport(Kernel::self()->collectionType())) {
+ // append by default?
+ m_radioAppend->setChecked(true);
+ } else {
+ m_radioReplace->setChecked(true);
+ m_radioAppend->setEnabled(false);
+ m_radioMerge->setEnabled(false);
+ }
+
+ QWidget* w = m_importer->widget(widget, "importer_widget");
+// m_importer->readOptions(KGlobal::config());
+ if(w) {
+ topLayout->addWidget(w, 0);
+ }
+
+ connect(bg, SIGNAL(clicked(int)), m_importer, SLOT(slotActionChanged(int)));
+
+ topLayout->addStretch();
+ setMainWidget(widget);
+
+ KGuiItem ok = KStdGuiItem::ok();
+ ok.setText(i18n("&Import"));
+ setButtonOK(ok);
+
+ // want to grab default button action, too
+ // since the importer might do something with widgets, don't just call it, do it after layout is done
+ QTimer::singleShot(0, this, SLOT(slotUpdateAction()));
+}
+
+ImportDialog::~ImportDialog() {
+ delete m_importer;
+ m_importer = 0;
+}
+
+Tellico::Data::CollPtr ImportDialog::collection() {
+ if(m_importer && !m_coll) {
+ m_coll = m_importer->collection();
+ }
+ return m_coll;
+}
+
+QString ImportDialog::statusMessage() const {
+ return m_importer ? m_importer->statusMessage() : QString::null;
+}
+
+Tellico::Import::Action ImportDialog::action() const {
+ if(m_radioReplace->isChecked()) {
+ return Import::Replace;
+ } else if(m_radioAppend->isChecked()) {
+ return Import::Append;
+ } else {
+ return Import::Merge;
+ }
+}
+
+// static
+Tellico::Import::Importer* ImportDialog::importer(Import::Format format_, const KURL::List& urls_) {
+#define CHECK_SIZE if(urls_.size() > 1) kdWarning() << "ImportDialog::importer() - only importing first URL" << endl
+ KURL firstURL = urls_.isEmpty() ? KURL() : urls_[0];
+ Import::Importer* importer = 0;
+ switch(format_) {
+ case Import::TellicoXML:
+ CHECK_SIZE;
+ importer = new Import::TellicoImporter(firstURL);
+ break;
+
+ case Import::Bibtex:
+ importer = new Import::BibtexImporter(urls_);
+ break;
+
+ case Import::Bibtexml:
+ CHECK_SIZE;
+ importer = new Import::BibtexmlImporter(firstURL);
+ break;
+
+ case Import::CSV:
+ CHECK_SIZE;
+ importer = new Import::CSVImporter(firstURL);
+ break;
+
+ case Import::XSLT:
+ CHECK_SIZE;
+ importer = new Import::XSLTImporter(firstURL);
+ break;
+
+ case Import::MODS:
+ CHECK_SIZE;
+ importer = new Import::XSLTImporter(firstURL);
+ {
+ QString xsltFile = locate("appdata", QString::fromLatin1("mods2tellico.xsl"));
+ if(!xsltFile.isEmpty()) {
+ KURL u;
+ u.setPath(xsltFile);
+ static_cast<Import::XSLTImporter*>(importer)->setXSLTURL(u);
+ } else {
+ kdWarning() << "ImportDialog::importer - unable to find mods2tellico.xml!" << endl;
+ }
+ }
+ break;
+
+ case Import::AudioFile:
+ CHECK_SIZE;
+ importer = new Import::AudioFileImporter(firstURL);
+ break;
+
+ case Import::Alexandria:
+ CHECK_SIZE;
+ importer = new Import::AlexandriaImporter();
+ break;
+
+ case Import::FreeDB:
+ CHECK_SIZE;
+ importer = new Import::FreeDBImporter();
+ break;
+
+ case Import::RIS:
+ importer = new Import::RISImporter(urls_);
+ break;
+
+ case Import::GCfilms:
+ CHECK_SIZE;
+ importer = new Import::GCfilmsImporter(firstURL);
+ break;
+
+ case Import::FileListing:
+ CHECK_SIZE;
+ importer = new Import::FileListingImporter(firstURL);
+ break;
+
+ case Import::AMC:
+ CHECK_SIZE;
+ importer = new Import::AMCImporter(firstURL);
+ break;
+
+ case Import::Griffith:
+ importer = new Import::GriffithImporter();
+ break;
+
+ case Import::PDF:
+ importer = new Import::PDFImporter(urls_);
+ break;
+
+ case Import::Referencer:
+ CHECK_SIZE;
+ importer = new Import::ReferencerImporter(firstURL);
+ break;
+
+ case Import::Delicious:
+ CHECK_SIZE;
+ importer = new Import::DeliciousImporter(firstURL);
+ break;
+
+ case Import::GRS1:
+ myDebug() << "ImportDialog::importer() - GRS1 not implemented" << endl;
+ break;
+ }
+#ifndef NDEBUG
+ if(!importer) {
+ kdWarning() << "ImportDialog::importer() - importer not created!" << endl;
+ }
+#endif
+ return importer;
+#undef CHECK_SIZE
+}
+
+// static
+QString ImportDialog::fileFilter(Import::Format format_) {
+ QString text;
+ switch(format_) {
+ case Import::TellicoXML:
+ text = i18n("*.tc *.bc|Tellico Files (*.tc)") + QChar('\n');
+ text += i18n("*.xml|XML Files (*.xml)") + QChar('\n');
+ break;
+
+ case Import::Bibtex:
+ text = i18n("*.bib|Bibtex Files (*.bib)") + QChar('\n');
+ break;
+
+ case Import::CSV:
+ text = i18n("*.csv|CSV Files (*.csv)") + QChar('\n');
+ break;
+
+ case Import::Bibtexml:
+ case Import::XSLT:
+ text = i18n("*.xml|XML Files (*.xml)") + QChar('\n');
+ break;
+
+ case Import::MODS:
+ case Import::Delicious:
+ text = i18n("*.xml|XML Files (*.xml)") + QChar('\n');
+ break;
+
+ case Import::RIS:
+ text = i18n("*.ris|RIS Files (*.ris)") + QChar('\n');
+ break;
+
+ case Import::GCfilms:
+ text = i18n("*.gcs|GCstar Data Files (*.gcs)") + QChar('\n');
+ text += i18n("*.gcf|GCfilms Data Files (*.gcf)") + QChar('\n');
+ break;
+
+ case Import::AMC:
+ text = i18n("*.amc|AMC Data Files (*.amc)") + QChar('\n');
+ break;
+
+ case Import::PDF:
+ text = i18n("*.pdf|PDF Files (*.pdf)") + QChar('\n');
+ break;
+
+ case Import::Referencer:
+ text = i18n("*.reflib|Referencer Files (*.reflib)") + QChar('\n');
+ break;
+
+ case Import::AudioFile:
+ case Import::Alexandria:
+ case Import::FreeDB:
+ case Import::FileListing:
+ case Import::GRS1:
+ case Import::Griffith:
+ break;
+ }
+
+ return text + i18n("*|All Files");
+}
+
+// audio files are imported by directory
+// alexandria is a defined location, as is freedb
+// all others are files
+Tellico::Import::Target ImportDialog::importTarget(Import::Format format_) {
+ switch(format_) {
+ case Import::AudioFile:
+ case Import::FileListing:
+ return Import::Dir;
+ case Import::Griffith:
+ case Import::Alexandria:
+ case Import::FreeDB:
+ return Import::None;
+ default:
+ return Import::File;
+ }
+}
+
+Tellico::Import::FormatMap ImportDialog::formatMap() {
+ // at one point, these were translated, but after some thought
+ // I decided they were likely to be the same in any language
+ // transliteration is unlikely
+ Import::FormatMap map;
+ map[Import::TellicoXML] = QString::fromLatin1("Tellico");
+ map[Import::Bibtex] = QString::fromLatin1("Bibtex");
+ map[Import::Bibtexml] = QString::fromLatin1("Bibtexml");
+// map[Import::CSV] = QString::fromLatin1("CSV");
+ map[Import::MODS] = QString::fromLatin1("MODS");
+ map[Import::RIS] = QString::fromLatin1("RIS");
+ map[Import::GCfilms] = QString::fromLatin1("GCstar");
+ map[Import::AMC] = QString::fromLatin1("AMC");
+ map[Import::Griffith] = QString::fromLatin1("Griffith");
+ map[Import::PDF] = QString::fromLatin1("PDF");
+ map[Import::Referencer] = QString::fromLatin1("Referencer");
+ map[Import::Delicious ] = QString::fromLatin1("Delicious Library");
+ return map;
+}
+
+bool ImportDialog::formatImportsText(Import::Format format_) {
+ return format_ != Import::AMC &&
+ format_ != Import::Griffith &&
+ format_ != Import::PDF;
+}
+
+QString ImportDialog::startDir(Import::Format format_) {
+ if(format_ == Import::GCfilms) {
+ QDir dir = QDir::home();
+ // able to cd if exists and readable
+ if(dir.cd(QString::fromLatin1(".local/share/gcfilms/"))) {
+ return dir.absPath();
+ }
+ }
+ return QString::fromLatin1(":import");
+}
+
+void ImportDialog::slotOk() {
+ // some importers, like the CSV importer, can validate their settings
+ if(!m_importer || m_importer->validImport()) {
+ KDialogBase::slotOk();
+ } else {
+ myLog() << "ImportDialog::slotOk() - not a valid import" << endl;
+ }
+}
+
+void ImportDialog::slotUpdateAction() {
+ // distasteful hack
+ // selectedId() is new in QT 3.2
+// m_importer->slotActionChanged(dynamic_cast<QButtonGroup*>(m_radioAppend->parentWidget())->selectedId());
+ QButtonGroup* bg = static_cast<QButtonGroup*>(m_radioAppend->parentWidget());
+ m_importer->slotActionChanged(bg->id(bg->selected()));
+}
+
+// static
+Tellico::Data::CollPtr ImportDialog::importURL(Import::Format format_, const KURL& url_) {
+ Import::Importer* imp = importer(format_, url_);
+ Data::CollPtr c = imp->collection();
+ if(!c && !imp->statusMessage().isEmpty()) {
+ Kernel::self()->sorry(imp->statusMessage());
+ }
+ delete imp;
+ return c;
+}
+
+
+#include "importdialog.moc"
diff --git a/src/importdialog.h b/src/importdialog.h
new file mode 100644
index 0000000..3802436
--- /dev/null
+++ b/src/importdialog.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef IMPORTDIALOG_H
+#define IMPORTDIALOG_H
+
+#include "translators/translators.h"
+#include "datavectors.h"
+
+#include <kdialogbase.h>
+#include <kurl.h>
+
+class QRadioButton;
+class QCheckBox;
+class QShowEvent;
+
+namespace Tellico {
+ namespace Import {
+ class Importer;
+ typedef QMap<Import::Format, QString> FormatMap;
+ }
+
+/**
+ * @author Robby Stephenson
+ */
+class ImportDialog : public KDialogBase {
+Q_OBJECT
+
+public:
+ ImportDialog(Import::Format format, const KURL::List& urls, QWidget* parent, const char* name);
+ ~ImportDialog();
+
+ Data::CollPtr collection();
+ QString statusMessage() const;
+ Import::Action action() const;
+
+ static QString fileFilter(Import::Format format);
+ static Import::Target importTarget(Import::Format format);
+ static QString startDir(Import::Format format);
+ static Import::FormatMap formatMap();
+ static bool formatImportsText(Import::Format format);
+
+ static Import::Importer* importer(Import::Format format, const KURL::List& urls);
+ static Data::CollPtr importURL(Import::Format format, const KURL& url);
+
+protected:
+ virtual void slotOk();
+
+private slots:
+ void slotUpdateAction();
+
+private:
+ Data::CollPtr m_coll;
+ Import::Importer* m_importer;
+ QRadioButton* m_radioAppend;
+ QRadioButton* m_radioReplace;
+ QRadioButton* m_radioMerge;
+};
+
+} // end namespace
+#endif
diff --git a/src/isbnvalidator.cpp b/src/isbnvalidator.cpp
new file mode 100644
index 0000000..91ed099
--- /dev/null
+++ b/src/isbnvalidator.cpp
@@ -0,0 +1,478 @@
+/***************************************************************************
+ copyright : (C) 2002-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "isbnvalidator.h"
+#include "tellico_debug.h"
+
+using Tellico::ISBNValidator;
+
+//static
+QString ISBNValidator::isbn10(QString isbn13) {
+ if(!isbn13.startsWith(QString::fromLatin1("978"))) {
+ myDebug() << "ISBNValidator::isbn10() - can't convert, must start with 978: " << isbn13 << endl;
+ return isbn13;
+ }
+ isbn13 = isbn13.mid(3);
+ isbn13.remove('-');
+ // remove checksum
+ isbn13.truncate(isbn13.length()-1);
+ // add new checksum
+ isbn13 += checkSum10(isbn13);
+ staticFixup(isbn13);
+ return isbn13;
+}
+
+QString ISBNValidator::isbn13(QString isbn10) {
+ isbn10.remove('-');
+ if(isbn10.startsWith(QString::fromLatin1("978")) ||
+ isbn10.startsWith(QString::fromLatin1("979"))) {
+ return isbn10;
+ }
+ // remove checksum
+ isbn10.truncate(isbn10.length()-1);
+ // begins with 978
+ isbn10.prepend(QString::fromLatin1("978"));
+ // add new checksum
+ isbn10 += checkSum13(isbn10);
+ staticFixup(isbn10);
+ return isbn10;
+}
+
+QString ISBNValidator::cleanValue(QString isbn) {
+ isbn.remove(QRegExp(QString::fromLatin1("[^xX0123456789]")));
+ return isbn;
+}
+
+ISBNValidator::ISBNValidator(QObject* parent_, const char* name_/*=0*/)
+ : QValidator(parent_, name_) {
+}
+
+QValidator::State ISBNValidator::validate(QString& input_, int& pos_) const {
+ if(input_.startsWith(QString::fromLatin1("978")) ||
+ input_.startsWith(QString::fromLatin1("979"))) {
+ return validate13(input_, pos_);
+ } else {
+ return validate10(input_, pos_);
+ }
+}
+
+void ISBNValidator::fixup(QString& input_) const {
+ return staticFixup(input_);
+}
+
+void ISBNValidator::staticFixup(QString& input_) {
+ if((input_.startsWith(QString::fromLatin1("978"))
+ || input_.startsWith(QString::fromLatin1("979")))
+ && input_.contains(QRegExp(QString::fromLatin1("\\d"))) > 10) {
+ return fixup13(input_);
+ }
+ return fixup10(input_);
+}
+
+QValidator::State ISBNValidator::validate10(QString& input_, int& pos_) const {
+ // first check to see if it's a "perfect" ISBN
+ // A perfect ISBN has 9 digits plus either an 'X' or another digit
+ // A perfect ISBN may have 2 or 3 hyphens
+ // The final digit or 'X' is the correct check sum
+ static const QRegExp isbn(QString::fromLatin1("(\\d-?){9,11}-[\\dX]"));
+ uint len = input_.length();
+/*
+ // Don't do this since the hyphens may be in the wrong place, can't put that in a regexp
+ if(isbn.exactMatch(input_) // put the exactMatch() first since I use matchedLength() later
+ && (len == 12 || len == 13)
+ && input_[len-1] == checkSum(input_)) {
+ return QValidator::Acceptable;
+ }
+*/
+ // two easy invalid cases are too many hyphens and the 'X' not in the last position
+ if(input_.contains('-') > 3
+ || input_.contains('X', false) > 1
+ || (input_.find('X', 0, false) != -1 && input_[len-1].upper() != 'X')) {
+ return QValidator::Invalid;
+ }
+
+ // remember if the cursor is at the end
+ bool atEnd = (pos_ == static_cast<int>(len));
+
+ // fix the case where the user attempts to delete a character from a non-checksum
+ // position; the solution is to delete the checksum, but only if it's X
+ if(!atEnd && input_[len-1].upper() == 'X') {
+ input_.truncate(len-1);
+ --len;
+ }
+
+ // fix the case where the user attempts to delete the checksum; the
+ // solution is to delete the last digit as well
+ static const QRegExp digit(QString::fromLatin1("\\d"));
+ if(atEnd && input_.contains(digit) == 9 && input_[len-1] == '-') {
+ input_.truncate(len-2);
+ pos_ -= 2;
+ len -= 2;
+ }
+
+ // now fixup the hyphens and maybe add a checksum
+ fixup10(input_);
+ len = input_.length(); // might have changed in fixup()
+ if(atEnd) {
+ pos_ = len;
+ }
+
+ if(isbn.exactMatch(input_) && (len == 12 || len == 13)) {
+ return QValidator::Acceptable;
+ } else {
+ return QValidator::Intermediate;
+ }
+}
+
+QValidator::State ISBNValidator::validate13(QString& input_, int& pos_) const {
+ // first check to see if it's a "perfect" ISBN13
+ // A perfect ISBN13 has 13 digits
+ // A perfect ISBN13 may have 3 or 4 hyphens
+ // The final digit is the correct check sum
+ static const QRegExp isbn(QString::fromLatin1("(\\d-?){13,17}"));
+ uint len = input_.length();
+
+ const uint countX = input_.contains('X', false);
+ // two easy invalid cases are too many hyphens or 'X'
+ if(input_.contains('-') > 4 || countX > 1) {
+ return QValidator::Invalid;
+ }
+
+ // now, it's not certain that we're getting a EAN-13,
+ // it could be a ISBN-10 from Nigeria or Indonesia
+ if(countX > 0 && (input_[len-1].upper() != 'X' || len > 13)) {
+ return QValidator::Invalid;
+ }
+
+ // remember if the cursor is at the end
+ bool atEnd = (pos_ == static_cast<int>(len));
+
+ // fix the case where the user attempts to delete a character from a non-checksum
+ // position; the solution is to delete the checksum, but only if it's X
+ if(!atEnd && input_[len-1].upper() == 'X') {
+ input_.truncate(len-1);
+ --len;
+ }
+
+ // fix the case where the user attempts to delete the checksum; the
+ // solution is to delete the last digit as well
+ static const QRegExp digit(QString::fromLatin1("\\d"));
+ const uint countN = input_.contains(digit);
+ if(atEnd && (countN == 12 || countN == 9) && input_[len-1] == '-') {
+ input_.truncate(len-2);
+ pos_ -= 2;
+ len -= 2;
+ }
+
+ // now fixup the hyphens and maybe add a checksum
+ if(countN > 10) {
+ fixup13(input_);
+ } else {
+ fixup10(input_);
+ }
+
+ len = input_.length(); // might have changed in fixup()
+ if(atEnd) {
+ pos_ = len;
+ }
+
+ if(isbn.exactMatch(input_)) {
+ return QValidator::Acceptable;
+ } else {
+ return QValidator::Intermediate;
+ }
+}
+
+void ISBNValidator::fixup10(QString& input_) {
+ if(input_.isEmpty()) {
+ return;
+ }
+
+ //replace "x" with "X"
+ input_.replace('x', QString::fromLatin1("X"));
+
+ // remove invalid chars
+ static const QRegExp badChars(QString::fromLatin1("[^\\d-X]"));
+ input_.remove(badChars);
+
+ // special case for EAN values that start with 978 or 979. That's the case
+ // for things like barcode readers that essentially 'type' the string at
+ // once. The simulated typing has already caused the input to be normalized,
+ // so strip that off, as well as the generated checksum. Then continue as normal.
+ // If someone were to input a regular 978- or 979- ISBN _including_ the
+ // checksum, it will be regarded as barcode input and the input will be stripped accordingly.
+ // I consider the likelihood that someone wants to input an EAN to be higher than someone
+ // using a Nigerian ISBN and not noticing that the checksum gets added automatically.
+ if(input_.length() > 12
+ && (input_.startsWith(QString::fromLatin1("978"))
+ || input_.startsWith(QString::fromLatin1("979")))) {
+ // Strip the first 4 characters (the invalid publisher)
+ input_ = input_.right(input_.length() - 3);
+ }
+
+ // hyphen placement for some languages publishers is well-defined
+ // remove all hyphens, and insert them ourselves
+ // some countries have ill-defined second hyphen positions, and if
+ // the user inserts one, then be sure to put it back
+
+ // Find the first hyphen. If there is none,
+ // input_.find('-') returns -1 and hyphen2_position = 0
+ int hyphen2_position = input_.find('-') + 1;
+
+ // Find the second one. If none, hyphen2_position = -2
+ hyphen2_position = input_.find('-', hyphen2_position) - 1;
+
+ // The second hyphen can not be in the last characters
+ if(hyphen2_position >= 9) {
+ hyphen2_position = 0;
+ }
+
+ // Remove all existing hyphens. We will insert ours.
+ input_.remove('-');
+ // the only place that 'X' can be is last spot
+ for(int xpos = input_.find('X'); xpos > -1; xpos = input_.find('X', xpos+1)) {
+ if(xpos < 9) { // remove if not 10th char
+ input_.remove(xpos, 1);
+ --xpos;
+ }
+ }
+ input_.truncate(10);
+
+ // If we can find it, add the checksum
+ // but only if not started with 978 or 979
+ if(input_.length() > 8
+ && !input_.startsWith(QString::fromLatin1("978"))
+ && !input_.startsWith(QString::fromLatin1("979"))) {
+ input_[9] = checkSum10(input_);
+ }
+
+ ulong range = input_.leftJustify(9, '0', true).toULong();
+
+ // now find which band the range falls in
+ uint band = 0;
+ while(range >= bands[band].MaxValue) {
+ ++band;
+ }
+
+ // if we have space to put the first hyphen, do it
+ if(input_.length() > bands[band].First) {
+ input_.insert(bands[band].First, '-');
+ }
+
+ //add 1 since one "-" has already been inserted
+ if(bands[band].Mid != 0) {
+ hyphen2_position = bands[band].Mid;
+ if(static_cast<int>(input_.length()) > (hyphen2_position + 1)) {
+ input_.insert(hyphen2_position + 1, '-');
+ }
+ // or put back user's hyphen
+ } else if(hyphen2_position > 0 && static_cast<int>(input_.length()) >= (hyphen2_position + 1)) {
+ input_.insert(hyphen2_position + 1, '-');
+ }
+
+ // add a "-" before the checkdigit and another one if the middle "-" exists
+ uint trueLast = bands[band].Last + 1 + (hyphen2_position > 0 ? 1 : 0);
+ if(input_.length() > trueLast) {
+ input_.insert(trueLast, '-');
+ }
+}
+
+void ISBNValidator::fixup13(QString& input_) {
+ if(input_.isEmpty()) {
+ return;
+ }
+
+ // remove invalid chars
+ static const QRegExp badChars(QString::fromLatin1("[^\\d-]"));
+ input_.remove(badChars);
+
+ // hyphen placement for some languages publishers is well-defined
+ // remove all hyphens, and insert them ourselves
+ // some countries have ill-defined second hyphen positions, and if
+ // the user inserts one, then be sure to put it back
+
+ QString after = input_.mid(3);
+ if(after[0] == '-') {
+ after = after.mid(1);
+ }
+
+ // Find the first hyphen. If there is none,
+ // input_.find('-') returns -1 and hyphen2_position = 0
+ int hyphen2_position = after.find('-') + 1;
+
+ // Find the second one. If none, hyphen2_position = -2
+ hyphen2_position = after.find('-', hyphen2_position) - 1;
+
+ // The second hyphen can not be in the last characters
+ if(hyphen2_position >= 9) {
+ hyphen2_position = 0;
+ }
+
+ // Remove all existing hyphens. We will insert ours.
+ after.remove('-');
+ after.truncate(10);
+
+ // add the checksum
+ if(after.length() > 8) {
+ after[9] = checkSum13(input_.left(3) + after);
+ }
+
+ ulong range = after.leftJustify(9, '0', true).toULong();
+
+ // now find which band the range falls in
+ uint band = 0;
+ while(range >= bands[band].MaxValue) {
+ ++band;
+ }
+
+ // if we have space to put the first hyphen, do it
+ if(after.length() > bands[band].First) {
+ after.insert(bands[band].First, '-');
+ }
+
+ //add 1 since one "-" has already been inserted
+ if(bands[band].Mid != 0) {
+ hyphen2_position = bands[band].Mid;
+ if(static_cast<int>(after.length()) > (hyphen2_position + 1)) {
+ after.insert(hyphen2_position + 1, '-');
+ }
+ // or put back user's hyphen
+ } else if(hyphen2_position > 0 && static_cast<int>(after.length()) >= (hyphen2_position + 1)) {
+ after.insert(hyphen2_position + 1, '-');
+ }
+
+ // add a "-" before the checkdigit and another one if the middle "-" exists
+ uint trueLast = bands[band].Last + 1 + (hyphen2_position > 0 ? 1 : 0);
+ if(after.length() > trueLast) {
+ after.insert(trueLast, '-');
+ }
+ input_ = input_.left(3) + '-' + after;
+}
+
+QChar ISBNValidator::checkSum10(const QString& input_) {
+ uint sum = 0;
+ uint multiplier = 10;
+
+ // hyphens are already gone, only use first nine digits
+ for(uint i = 0; i < input_.length() && multiplier > 1; ++i) {
+ sum += input_[i].digitValue() * multiplier--;
+ }
+ sum %= 11;
+ sum = 11-sum;
+
+ QChar c;
+ if(sum == 10) {
+ c = 'X';
+ } else if(sum == 11) {
+ c = '0';
+ } else {
+ c = QString::number(sum)[0];
+ }
+ return c;
+}
+
+QChar ISBNValidator::checkSum13(const QString& input_) {
+ uint sum = 0;
+
+ const uint len = QMIN(12, input_.length());
+ // hyphens are already gone, only use first twelve digits
+ for(uint i = 0; i < len; ++i) {
+ sum += input_[i].digitValue() * (1 + 2*(i%2));
+ // multiplier goes 1, 3, 1, 3, etc...
+ }
+ sum %= 10;
+ sum = 10-sum;
+
+ QChar c;
+ if(sum == 10) {
+ c = '0';
+ } else {
+ c = QString::number(sum)[0];
+ }
+ return c;
+}
+
+// ISBN code from Regis Boudin
+#define ISBNGRP_1DIGIT(digit, max, middle, last) \
+ {((digit)*100000000) + (max), 1, middle, last}
+#define ISBNGRP_2DIGIT(digit, max, middle, last) \
+ {((digit)*10000000) + ((max)/10), 2, middle, last}
+#define ISBNGRP_3DIGIT(digit, max, middle, last) \
+ {((digit)*1000000) + ((max)/100), 3, middle, last}
+#define ISBNGRP_4DIGIT(digit, max, middle, last) \
+ {((digit)*100000) + ((max)/1000), 4, middle, last}
+#define ISBNGRP_5DIGIT(digit, max, middle, last) \
+ {((digit)*10000) + ((max)/10000), 5, middle, last}
+
+#define ISBNPUB_2DIGIT(grp) (((grp)+1)*1000000)
+#define ISBNPUB_3DIGIT(grp) (((grp)+1)*100000)
+#define ISBNPUB_4DIGIT(grp) (((grp)+1)*10000)
+#define ISBNPUB_5DIGIT(grp) (((grp)+1)*1000)
+#define ISBNPUB_6DIGIT(grp) (((grp)+1)*100)
+#define ISBNPUB_7DIGIT(grp) (((grp)+1)*10)
+#define ISBNPUB_8DIGIT(grp) (((grp)+1)*1)
+
+// how to format an ISBN, after categorising it into a range of numbers.
+struct ISBNValidator::isbn_band ISBNValidator::bands[] = {
+ /* Groups 0 & 1 : English */
+ ISBNGRP_1DIGIT(0, ISBNPUB_2DIGIT(19), 3, 9),
+ ISBNGRP_1DIGIT(0, ISBNPUB_3DIGIT(699), 4, 9),
+ ISBNGRP_1DIGIT(0, ISBNPUB_4DIGIT(8499), 5, 9),
+ ISBNGRP_1DIGIT(0, ISBNPUB_5DIGIT(89999), 6, 9),
+ ISBNGRP_1DIGIT(0, ISBNPUB_6DIGIT(949999), 7, 9),
+ ISBNGRP_1DIGIT(0, ISBNPUB_7DIGIT(9999999), 8, 9),
+
+ ISBNGRP_1DIGIT(1, ISBNPUB_5DIGIT(54999), 6, 9),
+ ISBNGRP_1DIGIT(1, ISBNPUB_5DIGIT(86979), 6, 9),
+ ISBNGRP_1DIGIT(1, ISBNPUB_6DIGIT(998999), 7, 9),
+ ISBNGRP_1DIGIT(1, ISBNPUB_7DIGIT(9999999), 8, 9),
+ /* Group 2 : French */
+ ISBNGRP_1DIGIT(2, ISBNPUB_2DIGIT(19), 3, 9),
+ ISBNGRP_1DIGIT(2, ISBNPUB_3DIGIT(349), 4, 9),
+ ISBNGRP_1DIGIT(2, ISBNPUB_5DIGIT(39999), 6, 9),
+ ISBNGRP_1DIGIT(2, ISBNPUB_3DIGIT(699), 4, 9),
+ ISBNGRP_1DIGIT(2, ISBNPUB_4DIGIT(8399), 5, 9),
+ ISBNGRP_1DIGIT(2, ISBNPUB_5DIGIT(89999), 6, 9),
+ ISBNGRP_1DIGIT(2, ISBNPUB_6DIGIT(949999), 7, 9),
+ ISBNGRP_1DIGIT(2, ISBNPUB_7DIGIT(9999999), 8, 9),
+
+ /* Group 2 : German */
+ ISBNGRP_1DIGIT(3, ISBNPUB_2DIGIT(19), 3, 9),
+ ISBNGRP_1DIGIT(3, ISBNPUB_3DIGIT(699), 4, 9),
+ ISBNGRP_1DIGIT(3, ISBNPUB_4DIGIT(8499), 5, 9),
+ ISBNGRP_1DIGIT(3, ISBNPUB_5DIGIT(89999), 6, 9),
+ ISBNGRP_1DIGIT(3, ISBNPUB_6DIGIT(949999), 7, 9),
+ ISBNGRP_1DIGIT(3, ISBNPUB_7DIGIT(9999999), 8, 9),
+
+ ISBNGRP_1DIGIT(7, ISBNPUB_2DIGIT(99), 0, 9),
+ /* Group 80 : Czech */
+ ISBNGRP_2DIGIT(80, ISBNPUB_2DIGIT(19), 4, 9),
+ ISBNGRP_2DIGIT(80, ISBNPUB_3DIGIT(699), 5, 9),
+ ISBNGRP_2DIGIT(80, ISBNPUB_4DIGIT(8499), 6, 9),
+ ISBNGRP_2DIGIT(80, ISBNPUB_5DIGIT(89999), 7, 9),
+ ISBNGRP_2DIGIT(80, ISBNPUB_6DIGIT(949999), 8, 9),
+
+ /* Group 90 * Netherlands */
+ ISBNGRP_2DIGIT(90, ISBNPUB_2DIGIT(19), 4, 9),
+ ISBNGRP_2DIGIT(90, ISBNPUB_3DIGIT(499), 5, 9),
+ ISBNGRP_2DIGIT(90, ISBNPUB_4DIGIT(6999), 6, 9),
+ ISBNGRP_2DIGIT(90, ISBNPUB_5DIGIT(79999), 7, 9),
+ ISBNGRP_2DIGIT(90, ISBNPUB_6DIGIT(849999), 8, 9),
+ ISBNGRP_2DIGIT(90, ISBNPUB_4DIGIT(8999), 6, 9),
+ ISBNGRP_2DIGIT(90, ISBNPUB_7DIGIT(9999999), 9, 9),
+
+ ISBNGRP_2DIGIT(94, ISBNPUB_2DIGIT(99), 0, 9),
+ ISBNGRP_3DIGIT(993, ISBNPUB_2DIGIT(99), 0, 9),
+ ISBNGRP_4DIGIT(9989, ISBNPUB_2DIGIT(99), 0, 9),
+ ISBNGRP_5DIGIT(99999, ISBNPUB_2DIGIT(99), 0, 9)
+};
diff --git a/src/isbnvalidator.h b/src/isbnvalidator.h
new file mode 100644
index 0000000..763f7ff
--- /dev/null
+++ b/src/isbnvalidator.h
@@ -0,0 +1,148 @@
+/***************************************************************************
+ copyright : (C) 2002-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef ISBNVALIDATOR_H
+#define ISBNVALIDATOR_H
+
+#include <qvalidator.h>
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ *
+ * @see http://www.isbn.org/standards/home/isbn/international/hyphenation-instructions.asp
+ * @see http://www.eblong.com/zarf/bookscan/
+ * @see http://doc.trolltech.com/qq/qq01-seriously-weird-qregexp.html
+ */
+class ISBNValidator : public QValidator {
+public:
+ ISBNValidator(QObject* parent, const char* name=0);
+
+ /**
+ * Certain conditions are checked. Character, length and position
+ * restrictions are checked. Certain cases where the user is deleting
+ * characters are caught and compensated for. The string is then passed to
+ * @ref fixup. Finally, the text is @ref Valid if it is a certain length and
+ * @ref Intermediate if not.
+ *
+ * @param input The text to validate
+ * @param pos The position of the cursor
+ * @return The condition of the text
+ */
+ virtual QValidator::State validate(QString& input, int& pos) const;
+
+ /**
+ * The input string is examined. Hyphens are inserted appropriately,
+ * and the checksum is calculated.
+ *
+ * For correct presentation, the 10 digits of an ISBN must
+ * be divided, by hyphens, into four parts:
+ * @li Part 1: The country or group of countries identifier
+ * @li Part 2: The publisher identifier
+ * @li Part 3: The title identifier
+ * @li Part 4: The check digit
+ * For details
+ * @see http://www.isbn.org/standards/home/isbn/international/hyphenation-instructions.asp
+ * For info on group codes
+ * @see http://www.isbn.spk-berlin.de/html/prefix/allpref.htm
+ * For info on French language publisher codes
+ * @see http://www.afnil.org
+ * <pre>
+ * Group Identifiers First Hyphen After
+ * -----------------------------------------
+ * 0........7 1st digit
+ * 80.......94 2nd "
+ * 950......993 3rd "
+ * 9940.....9989 4th "
+ * 99900....99999 5th "
+ *
+ * Group Insert Hyphens
+ * Identifier "0" After
+ * -----------------------------------------
+ * 00.......19 1st 3rd 9th digit
+ * 200......699 " 4th "
+ * 7000.....8499 " 5th "
+ * 85000....89999 " 6th "
+ * 900000...949999 " 7th "
+ * 9500000..9999999 " 8th "
+ *
+ *
+ * Group Insert Hyphens
+ * Identifier "1" After
+ * ----------------------------------------
+ * 0........54999 illegal
+ * 55000....86979 1st 6th 9th digit
+ * 869800...998999 " 7th "
+ * 9990000..9999999 " 8th "
+ *
+ *
+ * Group Insert Hyphens
+ * Identifier "2" After
+ * -----------------------------------------
+ * 00.......19 1st 3rd 9th digit
+ * 200......349 " 4th "
+ * 34000....39999 " 6th "
+ * 400......699 " 4th "
+ * 7000.....8399 " 5th "
+ * 84000....89999 " 6th "
+ * 900000...949999 " 7th "
+ * 9500000..9999999 " 8th "
+ *
+ * The position of the hyphens are determined by the publisher
+ * prefix range established by each national agency in accordance
+ * with the industry needs. The knowledge of the prefix ranges for
+ * each country or group of countries is necessary to develop the
+ * hyphenation output program. For groups 3 through 99999, the hyphenation
+ * rules are currently unknown. So just leave out the hyphen between
+ * the publisher and title for now, but allow it if the user inserts it.
+ * </pre>
+ *
+ * @param input The raw string, hyphens included
+ */
+ virtual void fixup(QString& input) const;
+ static void staticFixup(QString& input);
+
+ static QString isbn10(QString isbn13);
+ static QString isbn13(QString isbn10);
+ static QString cleanValue(QString isbn);
+
+private:
+ static struct isbn_band {
+ unsigned long MaxValue;
+ unsigned int First;
+ unsigned int Mid;
+ unsigned int Last;
+ } bands[];
+
+ QValidator::State validate10(QString& input, int& pos) const;
+ QValidator::State validate13(QString& input, int& pos) const;
+
+ static void fixup10(QString& input);
+ static void fixup13(QString& input);
+
+ /**
+ * This function calculates and returns the ISBN checksum. The
+ * algorithm is based on some code by Andrew Plotkin, available at
+ * http://www.eblong.com/zarf/bookscan/
+ *
+ * @see http://www.eblong.com/zarf/bookscan/
+ *
+ * @param input The raw string, with no hyphens
+ */
+ static QChar checkSum10(const QString& input);
+ static QChar checkSum13(const QString& input);
+};
+
+} // end namespace
+#endif
diff --git a/src/iso5426converter.cpp b/src/iso5426converter.cpp
new file mode 100644
index 0000000..bac132a
--- /dev/null
+++ b/src/iso5426converter.cpp
@@ -0,0 +1,883 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+// This class is adapted from Iso5426ToUnicode from the MARC4J project, available
+// from http://marc4j.tigris.org, with the following notice:
+// * Copyright (C) 2002 Bas Peters (mail@bpeters.com)
+// * Copyright (C) 2002 Yves Pratter (ypratter@club-internet.fr)
+//
+// That source was released under the terms of the GNU Lesser General Public
+// License, version 2.1. In accordance with Condition 3 of that license,
+// I am applying the terms of the GNU General Public License to the source
+// code, and including a large portion of it here
+
+#include "iso5426converter.h"
+#include "tellico_debug.h"
+
+#include <qstring.h>
+
+using Tellico::Iso5426Converter;
+
+QString Iso5426Converter::toUtf8(const QCString& text_) {
+ const uint len = text_.length();
+ QString result;
+ result.reserve(len);
+ uint pos = 0;
+ for(uint i = 0; i < len; ++i) {
+ uchar c = text_[i];
+ if(isAscii(c)) {
+ result[pos++] = c;
+ } else if(isCombining(c) && hasNext(i, len)) {
+ // this is a hack
+ // use the diaeresis instead of umlaut
+ // works for SUDOC
+ if(c == 0xC9) {
+ c = 0xC8;
+ }
+ QChar d = getCombiningChar(c * 256 + text_[i + 1]);
+ if(!d.isNull()) {
+ result[pos++] = d;
+ ++i;
+ } else {
+ result[pos++] = getChar(c);
+ }
+ } else {
+ result[pos++] = getChar(c);
+ }
+ }
+ result.squeeze();
+ return result;
+}
+
+inline
+bool Iso5426Converter::hasNext(uint pos, uint len) {
+ return pos < (len - 1);
+}
+
+inline
+bool Iso5426Converter::isAscii(uchar c) {
+ return c <= 0x7F;
+}
+
+inline
+bool Iso5426Converter::isCombining(uchar c) {
+ return c >= 0xC0 && c <= 0xDF;
+}
+
+// Source : http://www.itscj.ipsj.or.jp/ISO-IR/053.pdf
+QChar Iso5426Converter::getChar(uchar c) {
+ switch(c) {
+ case 0xA1:
+ return 0x00A1; // 2/1 inverted exclamation mark
+ case 0xA2:
+ return 0x201C; // 2/2 left low double quotation mark
+ case 0xA3:
+ return 0x00A3; // 2/3 pound sign
+ case 0xA4:
+ return 0x0024; // 2/4 dollar sign
+ case 0xA5:
+ return 0x00A5; // 2/5 yen sign
+ case 0xA6:
+ return 0x2020; // 2/6 single dagger
+ case 0xA7:
+ return 0x00A7; // 2/7 paragraph (section)
+ case 0xA8:
+ return 0x2032; // 2/8 prime
+ case 0xA9:
+ return 0x2018; // 2/9 left high single quotation mark
+ case 0xAA:
+ return 0x201C; // 2/10 left high double quotation mark
+ case 0xAB:
+ return 0x00AB; // 2/11 left angle quotation mark
+ case 0xAC:
+ return 0x266D; // 2/12 music flat
+ case 0xAD:
+ return 0x00A9; // 2/13 copyright sign
+ case 0xAE:
+ return 0x2117; // 2/14 sound recording copyright sign
+ case 0xAF:
+ return 0x00AE; // 2/15 trade mark sign
+
+ case 0xB0:
+ return 0x0639; // 3/0 ayn [ain]
+ case 0xB1:
+ return 0x0623; // 3/1 alif/hamzah [alef with hamza above]
+ case 0xB2:
+ return 0x2018; // 3/2 left low single quotation mark
+ // 3/3 (this position shall not be used)
+ // 3/4 (this position shall not be used)
+ // 3/5 (this position shall not be used)
+ case 0xB6:
+ return 0x2021; // 3/6 double dagger
+ case 0xB7:
+ return 0x00B7; // 3/7 middle dot
+ case 0xB8:
+ return 0x2033; // 3/8 double prime
+ case 0xB9:
+ return 0x2019; // 3/9 right high single quotation mark
+ case 0xBA:
+ return 0x201D; // 3/10 right high double quotation mark
+ case 0xBB:
+ return 0x00BB; // 3/11 right angle quotation mark
+ case 0xBC:
+ return 0x266F; // 3/12 musical sharp
+ case 0xBD:
+ return 0x02B9; // 3/13 mjagkij znak
+ case 0xBE:
+ return 0x02BA; // 3/14 tverdyj znak
+ case 0xBF:
+ return 0x00BF; // 3/15 inverted question mark
+
+ // 4/0 to 5/15 diacritic characters
+
+ // 6/0 (this position shall not be used)
+ case 0xE1:
+ return 0x00C6; // 6/1 CAPITAL DIPHTHONG A WITH E
+ case 0xE2:
+ return 0x0110; // 6/2 CAPITAL LETTER D WITH STROKE
+ // 6/3 (this position shall not be used)
+ // 6/4 (this position shall not be used)
+ // 6/5 (this position shall not be used)
+ case 0xE6:
+ return 0x0132; // 6/6 CAPITAL LETTER IJ
+ // 6/7 (this position shall not be used)
+ case 0xE8:
+ return 0x0141; // 6/8 CAPITAL LETTER L WITH STROKE
+ case 0xE9:
+ return 0x00D8; // 6/9 CAPITAL LETTER O WITH SOLIDUS [oblique stroke]
+ case 0xEA:
+ return 0x0152; // 6/10 CAPITAL DIPHTONG OE
+ // 6/11 (this position shall not be used)
+ case 0xEC:
+ return 0x00DE; // 6/12 CAPITAL LETTER THORN
+ // 6/13 (this position shall not be used)
+ // 6/14 (this position shall not be used)
+ // 6/15 (this position shall not be used)
+
+ // 7/0 (this position shall not be used)
+ case 0xF1:
+ return 0x00E6; // 7/1 small diphthong a with e
+ // 7/4 (this position shall not be used)
+ case 0xF5:
+ return 0x0131; // 7/5 small letter i without dot
+ case 0xF6:
+ return 0x0133; // 7/6 small letter ij
+ // 7/7 (this position shall not be used)
+ case 0xF8:
+ return 0x0142; // 7/8 small letter l with stroke
+ case 0xF9:
+ return 0x00F8; // 7/9 small letter o with solidus (oblique stroke)
+ case 0xFA:
+ return 0x0153; // 7/10 small diphtong oe
+ case 0xFB:
+ return 0x00DF; // 7/11 small letter sharp s
+ case 0xFC:
+ return 0x00FE; // 7/12 small letter thorn
+ // 7/13 (this position shall not be used)
+ // 7/14 (this position shall not be used)
+ default:
+ return c;
+ }
+}
+
+QChar Iso5426Converter::getCombiningChar(uint c) {
+ switch(c) {
+ // 4/0 low rising tone mark
+ case 0xC041:
+ return 0x1EA2; // CAPITAL A WITH HOOK ABOVE
+ case 0xC045:
+ return 0x1EBA; // CAPITAL E WITH HOOK ABOVE
+ case 0xC049:
+ return 0x1EC8; // CAPITAL I WITH HOOK ABOVE
+ case 0xC04F:
+ return 0x1ECE; // CAPITAL O WITH HOOK ABOVE
+ case 0xC055:
+ return 0x1EE6; // CAPITAL U WITH HOOK ABOVE
+ case 0xC059:
+ return 0x1EF6; // CAPITAL Y WITH HOOK ABOVE
+ case 0xC061:
+ return 0x1EA3; // small a with hook above
+ case 0xC065:
+ return 0x1EBB; // small e with hook above
+ case 0xC069:
+ return 0x1EC9; // small i with hook above
+ case 0xC06F:
+ return 0x1ECF; // small o with hook above
+ case 0xC075:
+ return 0x1EE7; // small u with hook above
+ case 0xC079:
+ return 0x1EF7; // small y with hook above
+
+ // 4/1 grave accent
+ case 0xC141:
+ return 0x00C0; // CAPITAL A WITH GRAVE ACCENT
+ case 0xC145:
+ return 0x00C8; // CAPITAL E WITH GRAVE ACCENT
+ case 0xC149:
+ return 0x00CC; // CAPITAL I WITH GRAVE ACCENT
+ case 0xC14F:
+ return 0x00D2; // CAPITAL O WITH GRAVE ACCENT
+ case 0xC155:
+ return 0x00D9; // CAPITAL U WITH GRAVE ACCENT
+ case 0xC157:
+ return 0x1E80; // CAPITAL W WITH GRAVE
+ case 0xC159:
+ return 0x1EF2; // CAPITAL Y WITH GRAVE
+ case 0xC161:
+ return 0x00E0; // small a with grave accent
+ case 0xC165:
+ return 0x00E8; // small e with grave accent
+ case 0xC169:
+ return 0x00EC; // small i with grave accent
+ case 0xC16F:
+ return 0x00F2; // small o with grave accent
+ case 0xC175:
+ return 0x00F9; // small u with grave accent
+ case 0xC177:
+ return 0x1E81; // small w with grave
+ case 0xC179:
+ return 0x1EF3; // small y with grave
+
+ // 4/2 acute accent
+ case 0xC241:
+ return 0x00C1; // CAPITAL A WITH ACUTE ACCENT
+ case 0xC243:
+ return 0x0106; // CAPITAL C WITH ACUTE ACCENT
+ case 0xC245:
+ return 0x00C9; // CAPITAL E WITH ACUTE ACCENT
+ case 0xC247:
+ return 0x01F4; // CAPITAL G WITH ACUTE
+ case 0xC249:
+ return 0x00CD; // CAPITAL I WITH ACUTE ACCENT
+ case 0xC24B:
+ return 0x1E30; // CAPITAL K WITH ACUTE
+ case 0xC24C:
+ return 0x0139; // CAPITAL L WITH ACUTE ACCENT
+ case 0xC24D:
+ return 0x1E3E; // CAPITAL M WITH ACUTE
+ case 0xC24E:
+ return 0x0143; // CAPITAL N WITH ACUTE ACCENT
+ case 0xC24F:
+ return 0x00D3; // CAPITAL O WITH ACUTE ACCENT
+ case 0xC250:
+ return 0x1E54; // CAPITAL P WITH ACUTE
+ case 0xC252:
+ return 0x0154; // CAPITAL R WITH ACUTE ACCENT
+ case 0xC253:
+ return 0x015A; // CAPITAL S WITH ACUTE ACCENT
+ case 0xC255:
+ return 0x00DA; // CAPITAL U WITH ACUTE ACCENT
+ case 0xC257:
+ return 0x1E82; // CAPITAL W WITH ACUTE
+ case 0xC259:
+ return 0x00DD; // CAPITAL Y WITH ACUTE ACCENT
+ case 0xC25A:
+ return 0x0179; // CAPITAL Z WITH ACUTE ACCENT
+ case 0xC261:
+ return 0x00E1; // small a with acute accent
+ case 0xC263:
+ return 0x0107; // small c with acute accent
+ case 0xC265:
+ return 0x00E9; // small e with acute accent
+ case 0xC267:
+ return 0x01F5; // small g with acute
+ case 0xC269:
+ return 0x00ED; // small i with acute accent
+ case 0xC26B:
+ return 0x1E31; // small k with acute
+ case 0xC26C:
+ return 0x013A; // small l with acute accent
+ case 0xC26D:
+ return 0x1E3F; // small m with acute
+ case 0xC26E:
+ return 0x0144; // small n with acute accent
+ case 0xC26F:
+ return 0x00F3; // small o with acute accent
+ case 0xC270:
+ return 0x1E55; // small p with acute
+ case 0xC272:
+ return 0x0155; // small r with acute accent
+ case 0xC273:
+ return 0x015B; // small s with acute accent
+ case 0xC275:
+ return 0x00FA; // small u with acute accent
+ case 0xC277:
+ return 0x1E83; // small w with acute
+ case 0xC279:
+ return 0x00FD; // small y with acute accent
+ case 0xC27A:
+ return 0x017A; // small z with acute accent
+ case 0xC2E1:
+ return 0x01FC; // CAPITAL AE WITH ACUTE
+ case 0xC2F1:
+ return 0x01FD; // small ae with acute
+
+ // 4/3 circumflex accent
+ case 0xC341:
+ return 0x00C2; // CAPITAL A WITH CIRCUMFLEX ACCENT
+ case 0xC343:
+ return 0x0108; // CAPITAL C WITH CIRCUMFLEX
+ case 0xC345:
+ return 0x00CA; // CAPITAL E WITH CIRCUMFLEX ACCENT
+ case 0xC347:
+ return 0x011C; // CAPITAL G WITH CIRCUMFLEX
+ case 0xC348:
+ return 0x0124; // CAPITAL H WITH CIRCUMFLEX
+ case 0xC349:
+ return 0x00CE; // CAPITAL I WITH CIRCUMFLEX ACCENT
+ case 0xC34A:
+ return 0x0134; // CAPITAL J WITH CIRCUMFLEX
+ case 0xC34F:
+ return 0x00D4; // CAPITAL O WITH CIRCUMFLEX ACCENT
+ case 0xC353:
+ return 0x015C; // CAPITAL S WITH CIRCUMFLEX
+ case 0xC355:
+ return 0x00DB; // CAPITAL U WITH CIRCUMFLEX
+ case 0xC357:
+ return 0x0174; // CAPITAL W WITH CIRCUMFLEX
+ case 0xC359:
+ return 0x0176; // CAPITAL Y WITH CIRCUMFLEX
+ case 0xC35A:
+ return 0x1E90; // CAPITAL Z WITH CIRCUMFLEX
+ case 0xC361:
+ return 0x00E2; // small a with circumflex accent
+ case 0xC363:
+ return 0x0109; // small c with circumflex
+ case 0xC365:
+ return 0x00EA; // small e with circumflex accent
+ case 0xC367:
+ return 0x011D; // small g with circumflex
+ case 0xC368:
+ return 0x0125; // small h with circumflex
+ case 0xC369:
+ return 0x00EE; // small i with circumflex accent
+ case 0xC36A:
+ return 0x0135; // small j with circumflex
+ case 0xC36F:
+ return 0x00F4; // small o with circumflex accent
+ case 0xC373:
+ return 0x015D; // small s with circumflex
+ case 0xC375:
+ return 0x00FB; // small u with circumflex
+ case 0xC377:
+ return 0x0175; // small w with circumflex
+ case 0xC379:
+ return 0x0177; // small y with circumflex
+ case 0xC37A:
+ return 0x1E91; // small z with circumflex
+
+ // 4/4 tilde
+ case 0xC441:
+ return 0x00C3; // CAPITAL A WITH TILDE
+ case 0xC445:
+ return 0x1EBC; // CAPITAL E WITH TILDE
+ case 0xC449:
+ return 0x0128; // CAPITAL I WITH TILDE
+ case 0xC44E:
+ return 0x00D1; // CAPITAL N WITH TILDE
+ case 0xC44F:
+ return 0x00D5; // CAPITAL O WITH TILDE
+ case 0xC455:
+ return 0x0168; // CAPITAL U WITH TILDE
+ case 0xC456:
+ return 0x1E7C; // CAPITAL V WITH TILDE
+ case 0xC459:
+ return 0x1EF8; // CAPITAL Y WITH TILDE
+ case 0xC461:
+ return 0x00E3; // small a with tilde
+ case 0xC465:
+ return 0x1EBD; // small e with tilde
+ case 0xC469:
+ return 0x0129; // small i with tilde
+ case 0xC46E:
+ return 0x00F1; // small n with tilde
+ case 0xC46F:
+ return 0x00F5; // small o with tilde
+ case 0xC475:
+ return 0x0169; // small u with tilde
+ case 0xC476:
+ return 0x1E7D; // small v with tilde
+ case 0xC479:
+ return 0x1EF9; // small y with tilde
+
+ // 4/5 macron
+ case 0xC541:
+ return 0x0100; // CAPITAL A WITH MACRON
+ case 0xC545:
+ return 0x0112; // CAPITAL E WITH MACRON
+ case 0xC547:
+ return 0x1E20; // CAPITAL G WITH MACRON
+ case 0xC549:
+ return 0x012A; // CAPITAL I WITH MACRON
+ case 0xC54F:
+ return 0x014C; // CAPITAL O WITH MACRON
+ case 0xC555:
+ return 0x016A; // CAPITAL U WITH MACRON
+ case 0xC561:
+ return 0x0101; // small a with macron
+ case 0xC565:
+ return 0x0113; // small e with macron
+ case 0xC567:
+ return 0x1E21; // small g with macron
+ case 0xC569:
+ return 0x012B; // small i with macron
+ case 0xC56F:
+ return 0x014D; // small o with macron
+ case 0xC575:
+ return 0x016B; // small u with macron
+ case 0xC5E1:
+ return 0x01E2; // CAPITAL AE WITH MACRON
+ case 0xC5F1:
+ return 0x01E3; // small ae with macron
+
+ // 4/6 breve
+ case 0xC641:
+ return 0x0102; // CAPITAL A WITH BREVE
+ case 0xC645:
+ return 0x0114; // CAPITAL E WITH BREVE
+ case 0xC647:
+ return 0x011E; // CAPITAL G WITH BREVE
+ case 0xC649:
+ return 0x012C; // CAPITAL I WITH BREVE
+ case 0xC64F:
+ return 0x014E; // CAPITAL O WITH BREVE
+ case 0xC655:
+ return 0x016C; // CAPITAL U WITH BREVE
+ case 0xC661:
+ return 0x0103; // small a with breve
+ case 0xC665:
+ return 0x0115; // small e with breve
+ case 0xC667:
+ return 0x011F; // small g with breve
+ case 0xC669:
+ return 0x012D; // small i with breve
+ case 0xC66F:
+ return 0x014F; // small o with breve
+ case 0xC675:
+ return 0x016D; // small u with breve
+
+ // 4/7 dot above
+ case 0xC742:
+ return 0x1E02; // CAPITAL B WITH DOT ABOVE
+ case 0xC743:
+ return 0x010A; // CAPITAL C WITH DOT ABOVE
+ case 0xC744:
+ return 0x1E0A; // CAPITAL D WITH DOT ABOVE
+ case 0xC745:
+ return 0x0116; // CAPITAL E WITH DOT ABOVE
+ case 0xC746:
+ return 0x1E1E; // CAPITAL F WITH DOT ABOVE
+ case 0xC747:
+ return 0x0120; // CAPITAL G WITH DOT ABOVE
+ case 0xC748:
+ return 0x1E22; // CAPITAL H WITH DOT ABOVE
+ case 0xC749:
+ return 0x0130; // CAPITAL I WITH DOT ABOVE
+ case 0xC74D:
+ return 0x1E40; // CAPITAL M WITH DOT ABOVE
+ case 0xC74E:
+ return 0x1E44; // CAPITAL N WITH DOT ABOVE
+ case 0xC750:
+ return 0x1E56; // CAPITAL P WITH DOT ABOVE
+ case 0xC752:
+ return 0x1E58; // CAPITAL R WITH DOT ABOVE
+ case 0xC753:
+ return 0x1E60; // CAPITAL S WITH DOT ABOVE
+ case 0xC754:
+ return 0x1E6A; // CAPITAL T WITH DOT ABOVE
+ case 0xC757:
+ return 0x1E86; // CAPITAL W WITH DOT ABOVE
+ case 0xC758:
+ return 0x1E8A; // CAPITAL X WITH DOT ABOVE
+ case 0xC759:
+ return 0x1E8E; // CAPITAL Y WITH DOT ABOVE
+ case 0xC75A:
+ return 0x017B; // CAPITAL Z WITH DOT ABOVE
+ case 0xC762:
+ return 0x1E03; // small b with dot above
+ case 0xC763:
+ return 0x010B; // small c with dot above
+ case 0xC764:
+ return 0x1E0B; // small d with dot above
+ case 0xC765:
+ return 0x0117; // small e with dot above
+ case 0xC766:
+ return 0x1E1F; // small f with dot above
+ case 0xC767:
+ return 0x0121; // small g with dot above
+ case 0xC768:
+ return 0x1E23; // small h with dot above
+ case 0xC76D:
+ return 0x1E41; // small m with dot above
+ case 0xC76E:
+ return 0x1E45; // small n with dot above
+ case 0xC770:
+ return 0x1E57; // small p with dot above
+ case 0xC772:
+ return 0x1E59; // small r with dot above
+ case 0xC773:
+ return 0x1E61; // small s with dot above
+ case 0xC774:
+ return 0x1E6B; // small t with dot above
+ case 0xC777:
+ return 0x1E87; // small w with dot above
+ case 0xC778:
+ return 0x1E8B; // small x with dot above
+ case 0xC779:
+ return 0x1E8F; // small y with dot above
+ case 0xC77A:
+ return 0x017C; // small z with dot above
+
+ // 4/8 trema, diaresis
+ case 0xC820:
+ return 0x00A8; // diaeresis
+ case 0xC841:
+ return 0x00C4; // CAPITAL A WITH DIAERESIS
+ case 0xC845:
+ return 0x00CB; // CAPITAL E WITH DIAERESIS
+ case 0xC848:
+ return 0x1E26; // CAPITAL H WITH DIAERESIS
+ case 0xC849:
+ return 0x00CF; // CAPITAL I WITH DIAERESIS
+ case 0xC84F:
+ return 0x00D6; // CAPITAL O WITH DIAERESIS
+ case 0xC855:
+ return 0x00DC; // CAPITAL U WITH DIAERESIS
+ case 0xC857:
+ return 0x1E84; // CAPITAL W WITH DIAERESIS
+ case 0xC858:
+ return 0x1E8C; // CAPITAL X WITH DIAERESIS
+ case 0xC859:
+ return 0x0178; // CAPITAL Y WITH DIAERESIS
+ case 0xC861:
+ return 0x00E4; // small a with diaeresis
+ case 0xC865:
+ return 0x00EB; // small e with diaeresis
+ case 0xC868:
+ return 0x1E27; // small h with diaeresis
+ case 0xC869:
+ return 0x00EF; // small i with diaeresis
+ case 0xC86F:
+ return 0x00F6; // small o with diaeresis
+ case 0xC874:
+ return 0x1E97; // small t with diaeresis
+ case 0xC875:
+ return 0x00FC; // small u with diaeresis
+ case 0xC877:
+ return 0x1E85; // small w with diaeresis
+ case 0xC878:
+ return 0x1E8D; // small x with diaeresis
+ case 0xC879:
+ return 0x00FF; // small y with diaeresis
+
+ // 4/9 umlaut
+ case 0xC920:
+ return 0x00A8; // [diaeresis]
+
+ // 4/10 circle above
+ case 0xCA41:
+ return 0x00C5; // CAPITAL A WITH RING ABOVE
+ case 0xCAAD:
+ return 0x016E; // CAPITAL U WITH RING ABOVE
+ case 0xCA61:
+ return 0x00E5; // small a with ring above
+ case 0xCA75:
+ return 0x016F; // small u with ring above
+ case 0xCA77:
+ return 0x1E98; // small w with ring above
+ case 0xCA79:
+ return 0x1E99; // small y with ring above
+
+ // 4/11 high comma off centre
+
+ // 4/12 inverted high comma centred
+
+ // 4/13 double acute accent
+ case 0xCD4F:
+ return 0x0150; // CAPITAL O WITH DOUBLE ACUTE
+ case 0xCD55:
+ return 0x0170; // CAPITAL U WITH DOUBLE ACUTE
+ case 0xCD6F:
+ return 0x0151; // small o with double acute
+ case 0xCD75:
+ return 0x0171; // small u with double acute
+
+ // 4/14 horn
+ case 0xCE54:
+ return 0x01A0; // LATIN CAPITAL LETTER O WITH HORN
+ case 0xCE55:
+ return 0x01AF; // LATIN CAPITAL LETTER U WITH HORN
+ case 0xCE74:
+ return 0x01A1; // latin small letter o with horn
+ case 0xCE75:
+ return 0x01B0; // latin small letter u with horn
+
+ // 4/15 caron (hacek)
+ case 0xCF41:
+ return 0x01CD; // CAPITAL A WITH CARON
+ case 0xCF43:
+ return 0x010C; // CAPITAL C WITH CARON
+ case 0xCF44:
+ return 0x010E; // CAPITAL D WITH CARON
+ case 0xCF45:
+ return 0x011A; // CAPITAL E WITH CARON
+ case 0xCF47:
+ return 0x01E6; // CAPITAL G WITH CARON
+ case 0xCF49:
+ return 0x01CF; // CAPITAL I WITH CARON
+ case 0xCF4B:
+ return 0x01E8; // CAPITAL K WITH CARON
+ case 0xCF4C:
+ return 0x013D; // CAPITAL L WITH CARON
+ case 0xCF4E:
+ return 0x0147; // CAPITAL N WITH CARON
+ case 0xCF4F:
+ return 0x01D1; // CAPITAL O WITH CARON
+ case 0xCF52:
+ return 0x0158; // CAPITAL R WITH CARON
+ case 0xCF53:
+ return 0x0160; // CAPITAL S WITH CARON
+ case 0xCF54:
+ return 0x0164; // CAPITAL T WITH CARON
+ case 0xCF55:
+ return 0x01D3; // CAPITAL U WITH CARON
+ case 0xCF5A:
+ return 0x017D; // CAPITAL Z WITH CARON
+ case 0xCF61:
+ return 0x01CE; // small a with caron
+ case 0xCF63:
+ return 0x010D; // small c with caron
+ case 0xCF64:
+ return 0x010F; // small d with caron
+ case 0xCF65:
+ return 0x011B; // small e with caron
+ case 0xCF67:
+ return 0x01E7; // small g with caron
+ case 0xCF69:
+ return 0x01D0; // small i with caron
+ case 0xCF6A:
+ return 0x01F0; // small j with caron
+ case 0xCF6B:
+ return 0x01E9; // small k with caron
+ case 0xCF6C:
+ return 0x013E; // small l with caron
+ case 0xCF6E:
+ return 0x0148; // small n with caron
+ case 0xCF6F:
+ return 0x01D2; // small o with caron
+ case 0xCF72:
+ return 0x0159; // small r with caron
+ case 0xCF73:
+ return 0x0161; // small s with caron
+ case 0xCF74:
+ return 0x0165; // small t with caron
+ case 0xCF75:
+ return 0x01D4; // small u with caron
+ case 0xCF7A:
+ return 0x017E; // small z with caron
+
+ // 5/0 cedilla
+ case 0xD020:
+ return 0x00B8; // cedilla
+ case 0xD043:
+ return 0x00C7; // CAPITAL C WITH CEDILLA
+ case 0xD044:
+ return 0x1E10; // CAPITAL D WITH CEDILLA
+ case 0xD047:
+ return 0x0122; // CAPITAL G WITH CEDILLA
+ case 0xD048:
+ return 0x1E28; // CAPITAL H WITH CEDILLA
+ case 0xD04B:
+ return 0x0136; // CAPITAL K WITH CEDILLA
+ case 0xD04C:
+ return 0x013B; // CAPITAL L WITH CEDILLA
+ case 0xD04E:
+ return 0x0145; // CAPITAL N WITH CEDILLA
+ case 0xD052:
+ return 0x0156; // CAPITAL R WITH CEDILLA
+ case 0xD053:
+ return 0x015E; // CAPITAL S WITH CEDILLA
+ case 0xD054:
+ return 0x0162; // CAPITAL T WITH CEDILLA
+ case 0xD063:
+ return 0x00E7; // small c with cedilla
+ case 0xD064:
+ return 0x1E11; // small d with cedilla
+ case 0xD067:
+ return 0x0123; // small g with cedilla
+ case 0xD068:
+ return 0x1E29; // small h with cedilla
+ case 0xD06B:
+ return 0x0137; // small k with cedilla
+ case 0xD06C:
+ return 0x013C; // small l with cedilla
+ case 0xD06E:
+ return 0x0146; // small n with cedilla
+ case 0xD072:
+ return 0x0157; // small r with cedilla
+ case 0xD073:
+ return 0x015F; // small s with cedilla
+ case 0xD074:
+ return 0x0163; // small t with cedilla
+
+ // 5/1 rude
+
+ // 5/2 hook to left
+
+ // 5/3 ogonek (hook to right)
+ case 0xD320:
+ return 0x02DB; // ogonek
+ case 0xD341:
+ return 0x0104; // CAPITAL A WITH OGONEK
+ case 0xD345:
+ return 0x0118; // CAPITAL E WITH OGONEK
+ case 0xD349:
+ return 0x012E; // CAPITAL I WITH OGONEK
+ case 0xD34F:
+ return 0x01EA; // CAPITAL O WITH OGONEK
+ case 0xD355:
+ return 0x0172; // CAPITAL U WITH OGONEK
+ case 0xD361:
+ return 0x0105; // small a with ogonek
+ case 0xD365:
+ return 0x0119; // small e with ogonek
+ case 0xD369:
+ return 0x012F; // small i with ogonek
+ case 0xD36F:
+ return 0x01EB; // small o with ogonek
+ case 0xD375:
+ return 0x0173; // small u with ogonek
+
+ // 5/4 circle below
+ case 0xD441:
+ return 0x1E00; // CAPITAL A WITH RING BELOW
+ case 0xD461:
+ return 0x1E01; // small a with ring below
+
+ // 5/5 half circle below
+ case 0xF948:
+ return 0x1E2A; // CAPITAL H WITH BREVE BELOW
+ case 0xF968:
+ return 0x1E2B; // small h with breve below
+
+ // 5/6 dot below
+ case 0xD641:
+ return 0x1EA0; // CAPITAL A WITH DOT BELOW
+ case 0xD642:
+ return 0x1E04; // CAPITAL B WITH DOT BELOW
+ case 0xD644:
+ return 0x1E0C; // CAPITAL D WITH DOT BELOW
+ case 0xD645:
+ return 0x1EB8; // CAPITAL E WITH DOT BELOW
+ case 0xD648:
+ return 0x1E24; // CAPITAL H WITH DOT BELOW
+ case 0xD649:
+ return 0x1ECA; // CAPITAL I WITH DOT BELOW
+ case 0xD64B:
+ return 0x1E32; // CAPITAL K WITH DOT BELOW
+ case 0xD64C:
+ return 0x1E36; // CAPITAL L WITH DOT BELOW
+ case 0xD64D:
+ return 0x1E42; // CAPITAL M WITH DOT BELOW
+ case 0xD64E:
+ return 0x1E46; // CAPITAL N WITH DOT BELOW
+ case 0xD64F:
+ return 0x1ECC; // CAPITAL O WITH DOT BELOW
+ case 0xD652:
+ return 0x1E5A; // CAPITAL R WITH DOT BELOW
+ case 0xD653:
+ return 0x1E62; // CAPITAL S WITH DOT BELOW
+ case 0xD654:
+ return 0x1E6C; // CAPITAL T WITH DOT BELOW
+ case 0xD655:
+ return 0x1EE4; // CAPITAL U WITH DOT BELOW
+ case 0xD656:
+ return 0x1E7E; // CAPITAL V WITH DOT BELOW
+ case 0xD657:
+ return 0x1E88; // CAPITAL W WITH DOT BELOW
+ case 0xD659:
+ return 0x1EF4; // CAPITAL Y WITH DOT BELOW
+ case 0xD65A:
+ return 0x1E92; // CAPITAL Z WITH DOT BELOW
+ case 0xD661:
+ return 0x1EA1; // small a with dot below
+ case 0xD662:
+ return 0x1E05; // small b with dot below
+ case 0xD664:
+ return 0x1E0D; // small d with dot below
+ case 0xD665:
+ return 0x1EB9; // small e with dot below
+ case 0xD668:
+ return 0x1E25; // small h with dot below
+ case 0xD669:
+ return 0x1ECB; // small i with dot below
+ case 0xD66B:
+ return 0x1E33; // small k with dot below
+ case 0xD66C:
+ return 0x1E37; // small l with dot below
+ case 0xD66D:
+ return 0x1E43; // small m with dot below
+ case 0xD66E:
+ return 0x1E47; // small n with dot below
+ case 0xD66F:
+ return 0x1ECD; // small o with dot below
+ case 0xD672:
+ return 0x1E5B; // small r with dot below
+ case 0xD673:
+ return 0x1E63; // small s with dot below
+ case 0xD674:
+ return 0x1E6D; // small t with dot below
+ case 0xD675:
+ return 0x1EE5; // small u with dot below
+ case 0xD676:
+ return 0x1E7F; // small v with dot below
+ case 0xD677:
+ return 0x1E89; // small w with dot below
+ case 0xD679:
+ return 0x1EF5; // small y with dot below
+ case 0xD67A:
+ return 0x1E93; // small z with dot below
+
+ // 5/7 double dot below
+ case 0xD755:
+ return 0x1E72; // CAPITAL U WITH DIAERESIS BELOW
+ case 0xD775:
+ return 0x1E73; // small u with diaeresis below
+
+ // 5/8 underline
+ case 0xD820:
+ return 0x005F; // underline
+
+ // 5/9 double underline
+ case 0xD920:
+ return 0x2017; // double underline
+
+ // 5/10 small low vertical bar
+ case 0xDA20:
+ return 0x02CC; //
+
+ // 5/11 circumflex below
+
+ // 5/12 (this position shall not be used)
+
+ // 5/13 left half of ligature sign and of double tilde
+
+ // 5/14 right half of ligature sign
+
+ // 5/15 right half of double tilde
+
+ default:
+ myDebug() << "Iso5426Converter::getCombiningChar() - no match for " << c << endl;
+ return QChar();
+ }
+}
diff --git a/src/iso5426converter.h b/src/iso5426converter.h
new file mode 100644
index 0000000..6bd1fd3
--- /dev/null
+++ b/src/iso5426converter.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_ISO5426CONVERTER_H
+#define TELLICO_ISO5426CONVERTER_H
+
+class QCString;
+class QString;
+class QChar;
+
+#include <qglobal.h>
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class Iso5426Converter {
+public:
+ static QString toUtf8(const QCString& text);
+
+private:
+ static bool hasNext(uint pos, uint len);
+ static bool isAscii(uchar c);
+ static bool isCombining(uchar c);
+
+ static QChar getChar(uchar c);
+ static QChar getCombiningChar(uint i);
+};
+
+} // end namespace
+
+#endif
diff --git a/src/iso6937converter.cpp b/src/iso6937converter.cpp
new file mode 100644
index 0000000..3a3bcfb
--- /dev/null
+++ b/src/iso6937converter.cpp
@@ -0,0 +1,597 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+// This class is adapted from Iso6937ToUnicode from the MARC4J project, available
+// from http://marc4j.tigris.org, with the following notice:
+// * Copyright (C) 2002 Bas Peters (mail@bpeters.com)
+// * Copyright (C) 2002 Yves Pratter (ypratter@club-internet.fr)
+//
+// That source was released under the terms of the GNU Lesser General Public
+// License, version 2.1. In accordance with Condition 3 of that license,
+// I am applying the terms of the GNU General Public License to the source
+// code, and including a large portion of it here
+
+#include "iso6937converter.h"
+#include "tellico_debug.h"
+
+#include <qstring.h>
+
+using Tellico::Iso6937Converter;
+
+QString Iso6937Converter::toUtf8(const QCString& text_) {
+ const uint len = text_.length();
+ QString result;
+ result.reserve(len);
+ uint pos = 0;
+ for(uint i = 0; i < len; ++i) {
+ uchar c = text_[i];
+ if(isAscii(c)) {
+ result[pos++] = c;
+ } else if(isCombining(c) && hasNext(i, len)) {
+ QChar d = getCombiningChar(c * 256 + text_[i + 1]);
+ if(!d.isNull()) {
+ result[pos++] = d;
+ ++i;
+ } else {
+ result[pos++] = getChar(c);
+ }
+ } else {
+ result[pos++] = getChar(c);
+ }
+ }
+ result.squeeze();
+ return result;
+}
+
+inline
+bool Iso6937Converter::hasNext(uint pos, uint len) {
+ return pos < (len - 1);
+}
+
+inline
+bool Iso6937Converter::isAscii(uchar c) {
+ return c <= 0x7F;
+}
+
+inline
+bool Iso6937Converter::isCombining(uchar c) {
+ return c >= 0xC0 && c <= 0xDF;
+}
+
+// Source : http://anubis.dkuug.dk/JTC1/SC2/WG3/docs/6937cd.pdf
+QChar Iso6937Converter::getChar(uchar c) {
+ switch(c) {
+ case 0xA0:
+ return 0x00A0; // 10/00 NO-BREAK SPACE
+ case 0xA1:
+ return 0x00A1; // 10/01 INVERTED EXCLAMATION MARK
+ case 0xA2:
+ return 0x00A2; // 10/02 CENT SIGN
+ case 0xA3:
+ return 0x00A3; // 10/03 POUND SIGN
+ // 10/04 (This position shall not be used)
+ case 0xA5:
+ return 0x00A5; // 10/05 YEN SIGN
+ // 10/06 (This position shall not be used)
+ case 0xA7:
+ return 0x00A7; // 10/07 SECTION SIGN
+ case 0xA8:
+ return 0x00A4; // 10/08 CURRENCY SIGN
+ case 0xA9:
+ return 0x2018; // 10/09 LEFT SINGLE QUOTATION MARK
+ case 0xAA:
+ return 0x201C; // 10/10 LEFT DOUBLE QUOTATION MARK
+ case 0xAB:
+ return 0x00AB; // 10/11 LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+ case 0xAC:
+ return 0x2190; // 10/12 LEFTWARDS ARROW
+ case 0xAD:
+ return 0x2191; // 10/13 UPWARDS ARROW
+ case 0xAE:
+ return 0x2192; // 10/14 RIGHTWARDS ARROW
+ case 0xAF:
+ return 0x2193; // 10/15 DOWNWARDS ARROW
+
+ case 0xB0:
+ return 0x00B0; // 11/00 DEGREE SIGN
+ case 0xB1:
+ return 0x00B1; // 11/01 PLUS-MINUS SIGN
+ case 0xB2:
+ return 0x00B2; // 11/02 SUPERSCRIPT TWO
+ case 0xB3:
+ return 0x00B3; // 11/03 SUPERSCRIPT THREE
+ case 0xB4:
+ return 0x00D7; // 11/04 MULTIPLICATION SIGN
+ case 0xB5:
+ return 0x00B5; // 11/05 MICRO SIGN
+ case 0xB6:
+ return 0x00B6; // 11/06 PILCROW SIGN
+ case 0xB7:
+ return 0x00B7; // 11/07 MIDDLE DOT
+ case 0xB8:
+ return 0x00F7; // 11/08 DIVISION SIGN
+ case 0xB9:
+ return 0x2019; // 11/09 RIGHT SINGLE QUOTATION MARK
+ case 0xBA:
+ return 0x201D; // 11/10 RIGHT DOUBLE QUOTATION MARK
+ case 0xBB:
+ return 0x00BB; // 11/11 RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+ case 0xBC:
+ return 0x00BC; // 11/12 VULGAR FRACTION ONE QUARTER
+ case 0xBD:
+ return 0x00BD; // 11/13 VULGAR FRACTION ONE HALF
+ case 0xBE:
+ return 0x00BE; // 11/14 VULGAR FRACTION THREE QUARTERS
+ case 0xBF:
+ return 0x00BF; // 11/15 INVERTED QUESTION MARK
+
+ // 4/0 to 5/15 diacritic characters
+
+ case 0xD0:
+ return 0x2015; // 13/00 HORIZONTAL BAR
+ case 0xD1:
+ return 0x00B9; // 13/01 SUPERSCRIPT ONE
+ case 0xD2:
+ return 0x2117; // 13/02 REGISTERED SIGN
+ case 0xD3:
+ return 0x00A9; // 13/03 COPYRIGHT SIGN
+ case 0xD4:
+ return 0x00AE; // 13/04 TRADE MARK SIGN
+ case 0xD5:
+ return 0x266A; // 13/05 EIGHTH NOTE
+ case 0xD6:
+ return 0x00AC; // 13/06 NOT SIGN
+ case 0xD7:
+ return 0x00A6; // 13/07 BROKEN BAR
+ // 13/08 (This position shall not be used)
+ // 13/09 (This position shall not be used)
+ // 13/10 (This position shall not be used)
+ // 13/11 (This position shall not be used)
+ case 0xDC:
+ return 0x215B; // 13/12 VULGAR FRACTION ONE EIGHTH
+ case 0xDF:
+ return 0x215E; // 13/15 VULGAR FRACTION SEVEN EIGHTHS
+
+ case 0xE0:
+ return 0x2126; // 14/00 OHM SIGN
+ case 0xE1:
+ return 0x00C6; // 14/01 LATIN CAPITAL LETTER AE
+ case 0xE2:
+ return 0x0110; // 14/02 LATIN CAPITAL LETTER D WITH STROKE
+ case 0xE3:
+ return 0x00AA; // 14/03 FEMININE ORDINAL INDICATOR
+ case 0xE4:
+ return 0x0126; // 14/04 LATIN CAPITAL LETTER H WITH STROKE
+ // 14/05 (This position shall not be used)
+ case 0xE6:
+ return 0x0132; // 14/06 LATIN CAPITAL LIGATURE IJ
+ case 0xE7:
+ return 0x013F; // 14/07 LATIN CAPITAL LETTER L WITH MIDDLE DOT
+ case 0xE8:
+ return 0x0141; // 14/08 LATIN CAPITAL LETTER L WITH STROKE
+ case 0xE9:
+ return 0x00D8; // 14/09 LATIN CAPITAL LETTER O WITH STROKE
+ case 0xEA:
+ return 0x0152; // 14/10 LATIN CAPITAL LIGATURE OE
+ case 0xEB:
+ return 0x00BA; // 14/11 MASCULINE ORDINAL INDICATOR
+ case 0xEC:
+ return 0x00DE; // 14/12 LATIN CAPITAL LETTER THORN
+ case 0xED:
+ return 0x0166; // 14/13 LATIN CAPITAL LETTER T WITH STROKE
+ case 0xEE:
+ return 0x014A; // 14/14 LATIN CAPITAL LETTER ENG
+ case 0xEF:
+ return 0x0149; // 14/15 LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
+
+ case 0xF0:
+ return 0x0138; // 15/00 LATIN SMALL LETTER KRA
+ case 0xF1:
+ return 0x00E6; // 15/01 LATIN SMALL LETTER AE
+ case 0xF2:
+ return 0x0111; // 15/02 LATIN SMALL LETTER D WITH STROKE
+ case 0xF3:
+ return 0x00F0; // 15/03 LATIN SMALL LETTER ETH
+ case 0xF4:
+ return 0x0127; // 15/04 LATIN SMALL LETTER H WITH STROKE
+ case 0xF5:
+ return 0x0131; // 15/05 LATIN SMALL LETTER DOTLESS I
+ case 0xF6:
+ return 0x0133; // 15/06 LATIN SMALL LIGATURE IJ
+ case 0xF7:
+ return 0x0140; // 15/07 LATIN SMALL LETTER L WITH MIDDLE DOT
+ case 0xF8:
+ return 0x0142; // 15/08 LATIN SMALL LETTER L WITH STROKE
+ case 0xF9:
+ return 0x00F8; // 15/09 LATIN SMALL LETTER O WITH STROKE
+ case 0xFA:
+ return 0x0153; // 15/10 LATIN SMALL LIGATURE OE
+ case 0xFB:
+ return 0x00DF; // 15/11 LATIN SMALL LETTER SHARP S
+ case 0xFC:
+ return 0x00FE; // 15/12 LATIN SMALL LETTER THORN
+ case 0xFD:
+ return 0x0167; // 15/13 LATIN SMALL LETTER T WITH STROKE
+ case 0xFE:
+ return 0x014B; // 15/14 LATIN SMALL LETTER ENG
+ case 0xFF:
+ return 0x00AD; // 15/15 SOFT HYPHEN$
+ default:
+ return c;
+ }
+}
+
+QChar Iso6937Converter::getCombiningChar(uint c) {
+ switch(c) {
+ // 12/00 (This position shall not be used)
+
+ // 12/01 non-spacing grave accent
+ case 0xC141:
+ return 0x00C0; // LATIN CAPITAL LETTER A WITH GRAVE
+ case 0xC145:
+ return 0x00C8; // LATIN CAPITAL LETTER E WITH GRAVE
+ case 0xC149:
+ return 0x00CC; // LATIN CAPITAL LETTER I WITH GRAVE
+ case 0xC14F:
+ return 0x00D2; // LATIN CAPITAL LETTER O WITH GRAVE
+ case 0xC155:
+ return 0x00D9; // LATIN CAPITAL LETTER U WITH GRAVE
+ case 0xC161:
+ return 0x00E0; // LATIN SMALL LETTER A WITH GRAVE
+ case 0xC165:
+ return 0x00E8; // LATIN SMALL LETTER E WITH GRAVE
+ case 0xC169:
+ return 0x00EC; // LATIN SMALL LETTER I WITH GRAVE
+ case 0xC16F:
+ return 0x00F2; // LATIN SMALL LETTER O WITH GRAVE
+ case 0xC175:
+ return 0x00F9; // LATIN SMALL LETTER U WITH GRAVE
+
+ // 12/02 non-spacing acute accent
+ case 0xC220:
+ return 0x00B4; // ACUTE ACCENT
+ case 0xC241:
+ return 0x00C1; // LATIN CAPITAL LETTER A WITH ACUTE
+ case 0xC243:
+ return 0x0106; // LATIN CAPITAL LETTER C WITH ACUTE
+ case 0xC245:
+ return 0x00C9; // LATIN CAPITAL LETTER E WITH ACUTE
+ case 0xC249:
+ return 0x00CD; // LATIN CAPITAL LETTER I WITH ACUTE
+ case 0xC24C:
+ return 0x0139; // LATIN CAPITAL LETTER L WITH ACUTE
+ case 0xC24E:
+ return 0x0143; // LATIN CAPITAL LETTER N WITH ACUTE
+ case 0xC24F:
+ return 0x00D3; // LATIN CAPITAL LETTER O WITH ACUTE
+ case 0xC252:
+ return 0x0154; // LATIN CAPITAL LETTER R WITH ACUTE
+ case 0xC253:
+ return 0x015A; // LATIN CAPITAL LETTER S WITH ACUTE
+ case 0xC255:
+ return 0x00DA; // LATIN CAPITAL LETTER U WITH ACUTE
+ case 0xC259:
+ return 0x00DD; // LATIN CAPITAL LETTER Y WITH ACUTE
+ case 0xC25A:
+ return 0x0179; // LATIN CAPITAL LETTER Z WITH ACUTE
+ case 0xC261:
+ return 0x00E1; // LATIN SMALL LETTER A WITH ACUTE
+ case 0xC263:
+ return 0x0107; // LATIN SMALL LETTER C WITH ACUTE
+ case 0xC265:
+ return 0x00E9; // LATIN SMALL LETTER E WITH ACUTE
+ case 0xC267:
+ return 0x01F5; // LATIN SMALL LETTER G WITH CEDILLA(4)
+ case 0xC269:
+ return 0x00ED; // LATIN SMALL LETTER I WITH ACUTE
+ case 0xC26C:
+ return 0x013A; // LATIN SMALL LETTER L WITH ACUTE
+ case 0xC26E:
+ return 0x0144; // LATIN SMALL LETTER N WITH ACUTE
+ case 0xC26F:
+ return 0x00F3; // LATIN SMALL LETTER O WITH ACUTE
+ case 0xC272:
+ return 0x0155; // LATIN SMALL LETTER R WITH ACUTE
+ case 0xC273:
+ return 0x015B; // LATIN SMALL LETTER S WITH ACUTE
+ case 0xC275:
+ return 0x00FA; // LATIN SMALL LETTER U WITH ACUTE
+ case 0xC279:
+ return 0x00FD; // LATIN SMALL LETTER Y WITH ACUTE
+ case 0xC27A:
+ return 0x017A; // LATIN SMALL LETTER Z WITH ACUTE
+
+ // 12/03 non-spacing circumflex accent
+ case 0xC341:
+ return 0x00C2; // LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+ case 0xC343:
+ return 0x0108; // LATIN CAPITAL LETTER C WITH CIRCUMFLEX
+ case 0xC345:
+ return 0x00CA; // LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+ case 0xC347:
+ return 0x011C; // LATIN CAPITAL LETTER G WITH CIRCUMFLEX
+ case 0xC348:
+ return 0x0124; // LATIN CAPITAL LETTER H WITH CIRCUMFLEX
+ case 0xC349:
+ return 0x00CE; // LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+ case 0xC34A:
+ return 0x0134; // LATIN CAPITAL LETTER J WITH CIRCUMFLEX
+ case 0xC34F:
+ return 0x00D4; // LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+ case 0xC353:
+ return 0x015C; // LATIN CAPITAL LETTER S WITH CIRCUMFLEX
+ case 0xC355:
+ return 0x00DB; // LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+ case 0xC357:
+ return 0x0174; // LATIN CAPITAL LETTER W WITH CIRCUMFLEX
+ case 0xC359:
+ return 0x0176; // LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
+ case 0xC361:
+ return 0x00E2; // LATIN SMALL LETTER A WITH CIRCUMFLEX
+ case 0xC363:
+ return 0x0109; // LATIN SMALL LETTER C WITH CIRCUMFLEX
+ case 0xC365:
+ return 0x00EA; // LATIN SMALL LETTER E WITH CIRCUMFLEX
+ case 0xC367:
+ return 0x011D; // LATIN SMALL LETTER G WITH CIRCUMFLEX
+ case 0xC368:
+ return 0x0125; // LATIN SMALL LETTER H WITH CIRCUMFLEX
+ case 0xC369:
+ return 0x00EE; // LATIN SMALL LETTER I WITH CIRCUMFLEX
+ case 0xC36A:
+ return 0x0135; // LATIN SMALL LETTER J WITH CIRCUMFLEX
+ case 0xC36F:
+ return 0x00F4; // LATIN SMALL LETTER O WITH CIRCUMFLEX
+ case 0xC373:
+ return 0x015D; // LATIN SMALL LETTER S WITH CIRCUMFLEX
+ case 0xC375:
+ return 0x00FB; // LATIN SMALL LETTER U WITH CIRCUMFLEX
+ case 0xC377:
+ return 0x0175; // LATIN SMALL LETTER W WITH CIRCUMFLEX
+ case 0xC379:
+ return 0x0177; // LATIN SMALL LETTER Y WITH CIRCUMFLEX
+
+ // 12/04 non-spacing tilde
+ case 0xC441:
+ return 0x00C3; // LATIN CAPITAL LETTER A WITH TILDE
+ case 0xC449:
+ return 0x0128; // LATIN CAPITAL LETTER I WITH TILDE
+ case 0xC44E:
+ return 0x00D1; // LATIN CAPITAL LETTER N WITH TILDE
+ case 0xC44F:
+ return 0x00D5; // LATIN CAPITAL LETTER O WITH TILDE
+ case 0xC455:
+ return 0x0168; // LATIN CAPITAL LETTER U WITH TILDE
+ case 0xC461:
+ return 0x00E3; // LATIN SMALL LETTER A WITH TILDE
+ case 0xC469:
+ return 0x0129; // LATIN SMALL LETTER I WITH TILDE
+ case 0xC46E:
+ return 0x00F1; // LATIN SMALL LETTER N WITH TILDE
+ case 0xC46F:
+ return 0x00F5; // LATIN SMALL LETTER O WITH TILDE
+ case 0xC475:
+ return 0x0169; // LATIN SMALL LETTER U WITH TILDE
+
+ // 12/05 non-spacing macron
+ case 0xC541:
+ return 0x0100; // LATIN CAPITAL LETTER A WITH MACRON
+ case 0xC545:
+ return 0x0112; // LATIN CAPITAL LETTER E WITH MACRON
+ case 0xC549:
+ return 0x012A; // LATIN CAPITAL LETTER I WITH MACRON
+ case 0xC54F:
+ return 0x014C; // LATIN CAPITAL LETTER O WITH MACRON
+ case 0xC555:
+ return 0x016A; // LATIN CAPITAL LETTER U WITH MACRON
+ case 0xC561:
+ return 0x0101; // LATIN SMALL LETTER A WITH MACRON
+ case 0xC565:
+ return 0x0113; // LATIN SMALL LETTER E WITH MACRON
+ case 0xC569:
+ return 0x012B; // LATIN SMALL LETTER I WITH MACRON
+ case 0xC56F:
+ return 0x014D; // LATIN SMALL LETTER O WITH MACRON
+ case 0xC575:
+ return 0x016B; // LATIN SMALL LETTER U WITH MACRON
+
+ // 12/06 non-spacing breve
+ case 0xC620:
+ return 0x02D8; // BREVE
+ case 0xC641:
+ return 0x0102; // LATIN CAPITAL LETTER A WITH BREVE
+ case 0xC647:
+ return 0x011E; // LATIN CAPITAL LETTER G WITH BREVE
+ case 0xC655:
+ return 0x016C; // LATIN CAPITAL LETTER U WITH BREVE
+ case 0xC661:
+ return 0x0103; // LATIN SMALL LETTER A WITH BREVE
+ case 0xC667:
+ return 0x011F; // LATIN SMALL LETTER G WITH BREVE
+ case 0xC675:
+ return 0x016D; // LATIN SMALL LETTER U WITH BREVE
+
+ // 12/07 non-spacing dot above
+ case 0xC743:
+ return 0x010A; // LATIN CAPITAL LETTER C WITH DOT ABOVE
+ case 0xC745:
+ return 0x0116; // LATIN CAPITAL LETTER E WITH DOT ABOVE
+ case 0xC747:
+ return 0x0120; // LATIN CAPITAL LETTER G WITH DOT ABOVE
+ case 0xC749:
+ return 0x0130; // LATIN CAPITAL LETTER I WITH DOT ABOVE
+ case 0xC75A:
+ return 0x017B; // LATIN CAPITAL LETTER Z WITH DOT ABOVE
+ case 0xC763:
+ return 0x010B; // LATIN SMALL LETTER C WITH DOT ABOVE
+ case 0xC765:
+ return 0x0117; // LATIN SMALL LETTER E WITH DOT ABOVE
+ case 0xC767:
+ return 0x0121; // LATIN SMALL LETTER G WITH DOT ABOVE
+ case 0xC77A:
+ return 0x017C; // LATIN SMALL LETTER Z WITH DOT ABOVE
+
+ // 12/08 non-spacing diaeresis
+ case 0xC820:
+ return 0x00A8; // DIAERESIS
+ case 0xC841:
+ return 0x00C4; // LATIN CAPITAL LETTER A WITH DIAERESIS
+ case 0xC845:
+ return 0x00CB; // LATIN CAPITAL LETTER E WITH DIAERESIS
+ case 0xC849:
+ return 0x00CF; // LATIN CAPITAL LETTER I WITH DIAERESIS
+ case 0xC84F:
+ return 0x00D6; // LATIN CAPITAL LETTER O WITH DIAERESIS
+ case 0xC855:
+ return 0x00DC; // LATIN CAPITAL LETTER U WITH DIAERESIS
+ case 0xC859:
+ return 0x0178; // LATIN CAPITAL LETTER Y WITH DIAERESIS
+ case 0xC861:
+ return 0x00E4; // LATIN SMALL LETTER A WITH DIAERESIS
+ case 0xC865:
+ return 0x00EB; // LATIN SMALL LETTER E WITH DIAERESIS
+ case 0xC869:
+ return 0x00EF; // LATIN SMALL LETTER I WITH DIAERESIS
+ case 0xC86F:
+ return 0x00F6; // LATIN SMALL LETTER O WITH DIAERESIS
+ case 0xC875:
+ return 0x00FC; // LATIN SMALL LETTER U WITH DIAERESIS
+ case 0xC879:
+ return 0x00FF; // LATIN SMALL LETTER Y WITH DIAERESIS
+
+ // 12/09 (This position shall not be used)
+
+ // 12/10 non-spacing ring above
+ case 0xCA20:
+ return 0x02DA; // RING ABOVE
+ case 0xCA41:
+ return 0x00C5; // LATIN CAPITAL LETTER A WITH RING ABOVE
+ case 0xCAAD:
+ return 0x016E; // LATIN CAPITAL LETTER U WITH RING ABOVE
+ case 0xCA61:
+ return 0x00E5; // LATIN SMALL LETTER A WITH RING ABOVE
+ case 0xCA75:
+ return 0x016F; // LATIN SMALL LETTER U WITH RING ABOVE
+
+ // 12/11 non-spacing cedilla
+ case 0xCB20:
+ return 0x00B8; // CEDILLA
+ case 0xCB43:
+ return 0x00C7; // LATIN CAPITAL LETTER C WITH CEDILLA
+ case 0xCB47:
+ return 0x0122; // LATIN CAPITAL LETTER G WITH CEDILLA
+ case 0xCB4B:
+ return 0x0136; // LATIN CAPITAL LETTER K WITH CEDILLA
+ case 0xCB4C:
+ return 0x013B; // LATIN CAPITAL LETTER L WITH CEDILLA
+ case 0xCB4E:
+ return 0x0145; // LATIN CAPITAL LETTER N WITH CEDILLA
+ case 0xCB52:
+ return 0x0156; // LATIN CAPITAL LETTER R WITH CEDILLA
+ case 0xCB53:
+ return 0x015E; // LATIN CAPITAL LETTER S WITH CEDILLA
+ case 0xCB54:
+ return 0x0162; // LATIN CAPITAL LETTER T WITH CEDILLA
+ case 0xCB63:
+ return 0x00E7; // LATIN SMALL LETTER C WITH CEDILLA
+ // case 0xCB67: return 0x0123; // small g with cedilla
+ case 0xCB6B:
+ return 0x0137; // LATIN SMALL LETTER K WITH CEDILLA
+ case 0xCB6C:
+ return 0x013C; // LATIN SMALL LETTER L WITH CEDILLA
+ case 0xCB6E:
+ return 0x0146; // LATIN SMALL LETTER N WITH CEDILLA
+ case 0xCB72:
+ return 0x0157; // LATIN SMALL LETTER R WITH CEDILLA
+ case 0xCB73:
+ return 0x015F; // LATIN SMALL LETTER S WITH CEDILLA
+ case 0xCB74:
+ return 0x0163; // LATIN SMALL LETTER T WITH CEDILLA
+
+ // 12/12 (This position shall not be used)
+
+ // 12/13 non-spacing double acute accent
+ case 0xCD4F:
+ return 0x0150; // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+ case 0xCD55:
+ return 0x0170; // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+ case 0xCD6F:
+ return 0x0151; // LATIN SMALL LETTER O WITH DOUBLE ACUTE
+ case 0xCD75:
+ return 0x0171; // LATIN SMALL LETTER U WITH DOUBLE ACUTE
+
+ // 12/14 non-spacing ogonek
+ case 0xCE20:
+ return 0x02DB; // ogonek
+ case 0xCE41:
+ return 0x0104; // LATIN CAPITAL LETTER A WITH OGONEK
+ case 0xCE45:
+ return 0x0118; // LATIN CAPITAL LETTER E WITH OGONEK
+ case 0xCE49:
+ return 0x012E; // LATIN CAPITAL LETTER I WITH OGONEK
+ case 0xCE55:
+ return 0x0172; // LATIN CAPITAL LETTER U WITH OGONEK
+ case 0xCE61:
+ return 0x0105; // LATIN SMALL LETTER A WITH OGONEK
+ case 0xCE65:
+ return 0x0119; // LATIN SMALL LETTER E WITH OGONEK
+ case 0xCE69:
+ return 0x012F; // LATIN SMALL LETTER I WITH OGONEK
+ case 0xCE75:
+ return 0x0173; // LATIN SMALL LETTER U WITH OGONEK
+
+ // 12/15 non-spacing caron
+ case 0xCF20:
+ return 0x02C7; // CARON
+ case 0xCF43:
+ return 0x010C; // LATIN CAPITAL LETTER C WITH CARON
+ case 0xCF44:
+ return 0x010E; // LATIN CAPITAL LETTER D WITH CARON
+ case 0xCF45:
+ return 0x011A; // LATIN CAPITAL LETTER E WITH CARON
+ case 0xCF4C:
+ return 0x013D; // LATIN CAPITAL LETTER L WITH CARON
+ case 0xCF4E:
+ return 0x0147; // LATIN CAPITAL LETTER N WITH CARON
+ case 0xCF52:
+ return 0x0158; // LATIN CAPITAL LETTER R WITH CARON
+ case 0xCF53:
+ return 0x0160; // LATIN CAPITAL LETTER S WITH CARON
+ case 0xCF54:
+ return 0x0164; // LATIN CAPITAL LETTER T WITH CARON
+ case 0xCF5A:
+ return 0x017D; // LATIN CAPITAL LETTER Z WITH CARON
+ case 0xCF63:
+ return 0x010D; // LATIN SMALL LETTER C WITH CARON
+ case 0xCF64:
+ return 0x010F; // LATIN SMALL LETTER D WITH CARON
+ case 0xCF65:
+ return 0x011B; // LATIN SMALL LETTER E WITH CARON
+ case 0xCF6C:
+ return 0x013E; // LATIN SMALL LETTER L WITH CARON
+ case 0xCF6E:
+ return 0x0148; // LATIN SMALL LETTER N WITH CARON
+ case 0xCF72:
+ return 0x0159; // LATIN SMALL LETTER R WITH CARON
+ case 0xCF73:
+ return 0x0161; // LATIN SMALL LETTER S WITH CARON
+ case 0xCF74:
+ return 0x0165; // LATIN SMALL LETTER T WITH CARON
+ case 0xCF7A:
+ return 0x017E; // LATIN SMALL LETTER Z WITH CARON
+
+ default:
+ myDebug() << "Iso6937Converter::getCombiningChar() - no match for " << c << endl;
+ return QChar();
+ }
+}
diff --git a/src/iso6937converter.h b/src/iso6937converter.h
new file mode 100644
index 0000000..1d168ba
--- /dev/null
+++ b/src/iso6937converter.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_ISO6937CONVERTER_H
+#define TELLICO_ISO6937CONVERTER_H
+
+class QCString;
+class QString;
+class QChar;
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class Iso6937Converter {
+public:
+ static QString toUtf8(const QCString& text);
+
+private:
+ static bool hasNext(unsigned int pos, unsigned int len);
+ static bool isAscii(unsigned char c);
+ static bool isCombining(unsigned char c);
+
+ static QChar getChar(unsigned char c);
+ static QChar getCombiningChar(unsigned int c);
+};
+
+} // end namespace
+
+#endif
diff --git a/src/latin1literal.h b/src/latin1literal.h
new file mode 100644
index 0000000..03e2293
--- /dev/null
+++ b/src/latin1literal.h
@@ -0,0 +1,90 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+// this code was original published to the kde-core-devel email list
+// copyright 2003 Harri Porten <porten@kde.org>
+// Originally licensed under LGPL, included here under GPL v2
+
+#ifndef LATIN1LITERAL_H
+#define LATIN1LITERAL_H
+
+#include <qstring.h>
+
+namespace Tellico {
+
+/**
+ * A class for explicit marking of string literals encoded in the ISO
+ * 8859-1 character set. Allows for efficient, still (in terms of the
+ * chosen encoding) safe comparison with QString instances. To be used
+ * like this:
+ *
+ * \code
+ * QString s = .....
+ * if (s == Latin1Literal("o")) { ..... }
+ * \endcode
+ *
+ */
+#define Latin1Literal(s) \
+ Tellico::Latin1LiteralInternal((s), sizeof(s)/sizeof(char)-1)
+
+class Latin1LiteralInternal {
+
+public:
+ Latin1LiteralInternal(const char* s, size_t l)
+ : str(s), len(s ? l : (size_t)-1) { }
+
+ // this is lazy, leave these public since I can't figure out
+ // how to declare a friend function that works for gcc 2.95
+ const char* str;
+ size_t len;
+};
+
+} // end namespace
+
+inline
+bool operator==(const QString& s1, const Tellico::Latin1LiteralInternal& s2) {
+ const QChar* uc = s1.unicode();
+ const char* c = s2.str;
+ if(!c || !uc) {
+ return (!c && !uc);
+ }
+
+ const size_t& l = s2.len;
+ if(s1.length() != l) {
+ return false;
+ }
+
+ for(size_t i = 0; i < l; ++i, ++uc, ++c) {
+ if(uc->unicode() != static_cast<uchar>(*c)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+inline
+bool operator!=(const QString& s1, const Tellico::Latin1LiteralInternal& s2) {
+ return !(s1 == s2);
+}
+
+inline
+bool operator==(const Tellico::Latin1LiteralInternal& s1, const QString& s2) {
+ return s2 == s1;
+}
+
+inline
+bool operator!=(const Tellico::Latin1LiteralInternal& s1, const QString& s2) {
+ return !(s2 == s1);
+}
+
+#endif
diff --git a/src/lccnvalidator.cpp b/src/lccnvalidator.cpp
new file mode 100644
index 0000000..8c47931
--- /dev/null
+++ b/src/lccnvalidator.cpp
@@ -0,0 +1,74 @@
+/***************************************************************************
+ copyright : (C) 2008 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "lccnvalidator.h"
+#include "tellico_debug.h"
+
+using Tellico::LCCNValidator;
+
+LCCNValidator::LCCNValidator(QObject* parent_) : QRegExpValidator(parent_) {
+ QRegExp rx(QString::fromLatin1("[a-z ]{0,3}"
+ "("
+ "\\d{2}-?\\d{1,6}"
+ "|"
+ "\\d{4}-?\\d{1,6}"
+ ")"
+ " ?\\w*"));
+ setRegExp(rx);
+}
+
+// static
+QString LCCNValidator::formalize(const QString& value_) {
+ const int len = value_.length();
+ // first remove alpha prefix
+ QString alpha;
+ for(int pos = 0; pos < len; ++pos) {
+ QChar c = value_.at(pos);
+ if(c.isNumber()) {
+ break;
+ }
+ alpha += value_.at(pos);
+ }
+ QString afterAlpha = value_.mid(alpha.length());
+ alpha = alpha.stripWhiteSpace(); // possible to have a space at the end
+
+ QString year;
+ QString serial;
+ // have to be able to differentiate 2 and 4-digit years, first check for hyphen position
+ int pos = afterAlpha.find('-');
+ if(pos > -1) {
+ year = afterAlpha.section('-', 0, 0);
+ serial = afterAlpha.section('-', 1);
+ } else {
+ // make two assumptions, the user will never have a book from the year 1920
+ // or from any year after 2100. Reasonable, right?
+ // so if the string starts with '20' we take the first 4 digits as the year
+ // otherwise the first 2
+ if(afterAlpha.startsWith(QString::fromLatin1("20"))) {
+ year = afterAlpha.left(4);
+ serial = afterAlpha.mid(4);
+ } else {
+ year = afterAlpha.left(2);
+ serial = afterAlpha.mid(2);
+ }
+ }
+
+ // now check for non digits in the serial
+ pos = 0;
+ for( ; pos < serial.length() && serial.at(pos).isNumber(); ++pos) { ; }
+ QString suffix = serial.mid(pos);
+ serial = serial.left(pos);
+ // serial must be left-padded with zeros to 6 characters
+ serial = serial.rightJustify(6, '0');
+ return alpha + year + serial + suffix;
+}
diff --git a/src/lccnvalidator.h b/src/lccnvalidator.h
new file mode 100644
index 0000000..60ab807
--- /dev/null
+++ b/src/lccnvalidator.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ copyright : (C) 2008 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_LCCNVALIDATOR_H
+#define TELLICO_LCCNVALIDATOR_H
+
+#include <qvalidator.h>
+
+namespace Tellico {
+
+/**
+ * Library of Congress Controll Number validator
+ *
+ * see http://www.loc.gov/marc/lccn_structure.html
+ *
+ * These are all valid
+ * - 89-456
+ * - 2001-1114
+ * - gm 71-2450
+ */
+class LCCNValidator : public QRegExpValidator {
+
+public:
+ LCCNValidator(QObject* parent);
+
+ /**
+ * Returns the formalized version as dictated by LOC search
+ * http://catalog.loc.gov/help/number.htm
+ */
+ static QString formalize(const QString& value);
+};
+
+}
+#endif
diff --git a/src/listviewcomparison.cpp b/src/listviewcomparison.cpp
new file mode 100644
index 0000000..9bdd10c
--- /dev/null
+++ b/src/listviewcomparison.cpp
@@ -0,0 +1,279 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "listviewcomparison.h"
+#include "latin1literal.h"
+#include "field.h"
+#include "collection.h"
+#include "document.h"
+#include "entryitem.h"
+
+#include <qlistview.h>
+#include <qiconview.h>
+#include <qpixmap.h>
+#include <qdatetime.h>
+
+namespace {
+ int compareFloat(const QString& s1, const QString& s2) {
+ bool ok1, ok2;
+ float n1 = s1.toFloat(&ok1);
+ float n2 = s2.toFloat(&ok2);
+ return (ok1 && ok2) ? static_cast<int>(n1-n2) : 0;
+ }
+}
+
+Tellico::ListViewComparison* Tellico::ListViewComparison::create(Data::FieldPtr field_) {
+ return create(Data::ConstFieldPtr(field_.data()));
+}
+
+Tellico::ListViewComparison* Tellico::ListViewComparison::create(Data::ConstFieldPtr field_) {
+ if(field_->type() == Data::Field::Number) {
+ return new NumberComparison(field_);
+ } else if(field_->type() == Data::Field::Image ||
+ field_->type() == Data::Field::Rating ||
+ field_->type() == Data::Field::Bool) {
+ // bool and ratings only have an image
+ return new PixmapComparison(field_);
+ } else if(field_->type() == Data::Field::Dependent) {
+ return new DependentComparison(field_);
+ } else if(field_->type() == Data::Field::Date || field_->formatFlag() == Data::Field::FormatDate) {
+ return new ISODateComparison(field_);
+ } else if(field_->formatFlag() == Data::Field::FormatTitle) {
+ // Dependent could be title, so put this test after
+ return new TitleComparison(field_);
+ } else if(field_->property(QString::fromLatin1("lcc")) == Latin1Literal("true") ||
+ (field_->name() == Latin1Literal("lcc") &&
+ Data::Document::self()->collection() &&
+ (Data::Document::self()->collection()->type() == Data::Collection::Book ||
+ Data::Document::self()->collection()->type() == Data::Collection::Bibtex))) {
+ // allow LCC comparison if LCC property is set, or if the name is lcc for a book or bibliography collection
+ return new LCCComparison(field_);
+ }
+ return new StringComparison(field_);
+}
+
+Tellico::ListViewComparison::ListViewComparison(Data::ConstFieldPtr field) : m_fieldName(field->name()) {
+}
+
+int Tellico::ListViewComparison::compare(int col_,
+ const GUI::ListViewItem* item1_,
+ const GUI::ListViewItem* item2_,
+ bool asc_)
+{
+ return compare(item1_->key(col_, asc_), item2_->key(col_, asc_));
+}
+
+int Tellico::ListViewComparison::compare(const QIconViewItem* item1_,
+ const QIconViewItem* item2_)
+{
+ return compare(item1_->key(), item2_->key());
+}
+
+Tellico::StringComparison::StringComparison(Data::ConstFieldPtr field) : ListViewComparison(field) {
+}
+
+int Tellico::StringComparison::compare(const QString& str1_, const QString& str2_) {
+ return str1_.localeAwareCompare(str2_);
+}
+
+Tellico::TitleComparison::TitleComparison(Data::ConstFieldPtr field) : ListViewComparison(field) {
+}
+
+int Tellico::TitleComparison::compare(const QString& str1_, const QString& str2_) {
+ const QString title1 = Data::Field::sortKeyTitle(str1_);
+ const QString title2 = Data::Field::sortKeyTitle(str2_);
+ return title1.localeAwareCompare(title2);
+}
+
+Tellico::NumberComparison::NumberComparison(Data::ConstFieldPtr field) : ListViewComparison(field) {
+}
+
+int Tellico::NumberComparison::compare(const QString& str1_, const QString& str2_) {
+ // by default, an empty string would get sorted before "1" because toFloat() turns it into "0"
+ // I want the empty strings to be at the end
+ bool ok1, ok2;
+ // use section in case of multiple values
+ float num1 = str1_.section(';', 0, 0).toFloat(&ok1);
+ float num2 = str2_.section(';', 0, 0).toFloat(&ok2);
+ if(ok1 && ok2) {
+ return static_cast<int>(num1 - num2);
+ } else if(ok1 && !ok2) {
+ return -1;
+ } else if(!ok1 && ok2) {
+ return 1;
+ }
+ return 0;
+}
+
+// for details on the LCC comparison, see
+// http://www.mcgees.org/2001/08/08/sort-by-library-of-congress-call-number-in-perl/
+
+Tellico::LCCComparison::LCCComparison(Data::ConstFieldPtr field) : StringComparison(field),
+ m_regexp(QString::fromLatin1("^([A-Z]+)(\\d+(?:\\.\\d+)?)\\.?([A-Z]*)(\\d*)\\.?([A-Z]*)(\\d*)(?: (\\d\\d\\d\\d))?")) {
+}
+
+int Tellico::LCCComparison::compare(const QString& str1_, const QString& str2_) {
+// myDebug() << "LCCComparison::compare() - " << str1_ << " to " << str2_ << endl;
+ int pos1 = m_regexp.search(str1_);
+ const QStringList cap1 = m_regexp.capturedTexts();
+ int pos2 = m_regexp.search(str2_);
+ const QStringList cap2 = m_regexp.capturedTexts();
+ if(pos1 > -1 && pos2 > -1) {
+ int res = compareLCC(cap1, cap2);
+// myLog() << "...result = " << res << endl;
+ return res;
+ }
+ return StringComparison::compare(str1_, str2_);
+}
+
+int Tellico::LCCComparison::compareLCC(const QStringList& cap1, const QStringList& cap2) const {
+ // the first item in the list is the full match, so start array index at 1
+ int res = 0;
+ return (res = cap1[1].compare(cap2[1])) != 0 ? res :
+ (res = compareFloat(cap1[2], cap2[2])) != 0 ? res :
+ (res = cap1[3].compare(cap2[3])) != 0 ? res :
+ (res = compareFloat(QString::fromLatin1("0.") + cap1[4],
+ QString::fromLatin1("0.") + cap2[4])) != 0 ? res :
+ (res = cap1[5].compare(cap2[5])) != 0 ? res :
+ (res = compareFloat(QString::fromLatin1("0.") + cap1[6],
+ QString::fromLatin1("0.") + cap2[6])) != 0 ? res :
+ (res = compareFloat(cap1[7], cap2[7])) != 0 ? res : 0;
+}
+
+Tellico::PixmapComparison::PixmapComparison(Data::ConstFieldPtr field) : ListViewComparison(field) {
+}
+
+int Tellico::PixmapComparison::compare(int col_,
+ const GUI::ListViewItem* item1_,
+ const GUI::ListViewItem* item2_,
+ bool asc_)
+{
+ Q_UNUSED(asc_);
+ const QPixmap* pix1 = item1_->pixmap(col_);
+ const QPixmap* pix2 = item2_->pixmap(col_);
+ if(pix1 && !pix1->isNull()) {
+ if(pix2 && !pix2->isNull()) {
+ // large images come first
+ return pix1->width() - pix2->width();
+ }
+ return 1;
+ } else if(pix2 && !pix2->isNull()) {
+ return -1;
+ }
+ return 0;
+}
+
+int Tellico::PixmapComparison::compare(const QIconViewItem* item1_,
+ const QIconViewItem* item2_)
+{
+ const QPixmap* pix1 = item1_->pixmap();
+ const QPixmap* pix2 = item2_->pixmap();
+ if(pix1 && !pix1->isNull()) {
+ if(pix2 && !pix2->isNull()) {
+ // large images come first
+ return pix1->width() - pix2->width();
+ }
+ return 1;
+ } else if(pix2 && !pix2->isNull()) {
+ return -1;
+ }
+ return 0;
+}
+
+Tellico::DependentComparison::DependentComparison(Data::ConstFieldPtr field) : StringComparison(field) {
+ Data::FieldVec fields = field->dependsOn(Data::Document::self()->collection());
+ for(Data::FieldVecIt f = fields.begin(); f != fields.end(); ++f) {
+ m_comparisons.append(create(f));
+ }
+ m_comparisons.setAutoDelete(true);
+}
+
+int Tellico::DependentComparison::compare(int col_,
+ const GUI::ListViewItem* item1_,
+ const GUI::ListViewItem* item2_,
+ bool asc_)
+{
+ Q_UNUSED(col_);
+ Q_UNUSED(asc_);
+ for(QPtrListIterator<ListViewComparison> it(m_comparisons); it.current(); ++it) {
+ int res = it.current()->compare(col_, item1_, item2_, asc_);
+ if(res != 0) {
+ return res;
+ }
+ }
+ return ListViewComparison::compare(col_, item1_, item2_, asc_);
+}
+
+int Tellico::DependentComparison::compare(const QIconViewItem* item1_,
+ const QIconViewItem* item2_)
+{
+ for(QPtrListIterator<ListViewComparison> it(m_comparisons); it.current(); ++it) {
+ int res = it.current()->compare(item1_, item2_);
+ if(res != 0) {
+ return res;
+ }
+ }
+ return ListViewComparison::compare(item1_, item2_);
+}
+
+Tellico::ISODateComparison::ISODateComparison(Data::ConstFieldPtr field) : ListViewComparison(field) {
+}
+
+int Tellico::ISODateComparison::compare(const QString& str1, const QString& str2) {
+ if(str1.isEmpty()) {
+ return str2.isEmpty() ? 0 : -1;
+ }
+ if(str2.isEmpty()) { // str1 is not
+ return 1;
+ }
+ // modelled after Field::formatDate()
+ // so dates would sort as expected without padding month and day with zero
+ // and accounting for "current year - 1 - 1" default scheme
+ QStringList dlist1 = QStringList::split('-', str1, true);
+ bool ok = true;
+ int y1 = dlist1.count() > 0 ? dlist1[0].toInt(&ok) : QDate::currentDate().year();
+ if(!ok) {
+ y1 = QDate::currentDate().year();
+ }
+ int m1 = dlist1.count() > 1 ? dlist1[1].toInt(&ok) : 1;
+ if(!ok) {
+ m1 = 1;
+ }
+ int d1 = dlist1.count() > 2 ? dlist1[2].toInt(&ok) : 1;
+ if(!ok) {
+ d1 = 1;
+ }
+ QDate date1(y1, m1, d1);
+
+ QStringList dlist2 = QStringList::split('-', str2, true);
+ int y2 = dlist2.count() > 0 ? dlist2[0].toInt(&ok) : QDate::currentDate().year();
+ if(!ok) {
+ y2 = QDate::currentDate().year();
+ }
+ int m2 = dlist2.count() > 1 ? dlist2[1].toInt(&ok) : 1;
+ if(!ok) {
+ m2 = 1;
+ }
+ int d2 = dlist2.count() > 2 ? dlist2[2].toInt(&ok) : 1;
+ if(!ok) {
+ d2 = 1;
+ }
+ QDate date2(y2, m2, d2);
+
+ if(date1 < date2) {
+ return -1;
+ } else if(date1 > date2) {
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/listviewcomparison.h b/src/listviewcomparison.h
new file mode 100644
index 0000000..4c0ed43
--- /dev/null
+++ b/src/listviewcomparison.h
@@ -0,0 +1,116 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_LISTVIEWCOMPARISON_H
+#define TELLICO_LISTVIEWCOMPARISON_H
+
+#include "datavectors.h"
+
+#include <qregexp.h>
+
+class QStringList;
+class QIconViewItem;
+
+namespace Tellico {
+ namespace GUI {
+ class ListViewItem;
+ }
+
+class ListViewComparison {
+public:
+ ListViewComparison(Data::ConstFieldPtr field);
+ virtual ~ListViewComparison() {}
+
+ const QString& fieldName() const { return m_fieldName; }
+
+ virtual int compare(int col, const GUI::ListViewItem* item1, const GUI::ListViewItem* item2, bool asc);
+ virtual int compare(const QIconViewItem* item1, const QIconViewItem* item2);
+
+ static ListViewComparison* create(Data::FieldPtr field);
+ static ListViewComparison* create(Data::ConstFieldPtr field);
+
+protected:
+ virtual int compare(const QString& str1, const QString& str2) = 0;
+
+private:
+ QString m_fieldName;
+};
+
+class StringComparison : public ListViewComparison {
+public:
+ StringComparison(Data::ConstFieldPtr field);
+
+protected:
+ virtual int compare(const QString& str1, const QString& str2);
+};
+
+class TitleComparison : public ListViewComparison {
+public:
+ TitleComparison(Data::ConstFieldPtr field);
+
+protected:
+ virtual int compare(const QString& str1, const QString& str2);
+};
+
+class NumberComparison : public ListViewComparison {
+public:
+ NumberComparison(Data::ConstFieldPtr field);
+
+protected:
+ virtual int compare(const QString& str1, const QString& str2);
+};
+
+class LCCComparison : public StringComparison {
+public:
+ LCCComparison(Data::ConstFieldPtr field);
+
+protected:
+ virtual int compare(const QString& str1, const QString& str2);
+
+private:
+ int compareLCC(const QStringList& cap1, const QStringList& cap2) const;
+ QRegExp m_regexp;
+};
+
+class PixmapComparison : public ListViewComparison {
+public:
+ PixmapComparison(Data::ConstFieldPtr field);
+
+ virtual int compare(int col, const GUI::ListViewItem* item1, const GUI::ListViewItem* item2, bool asc);
+ virtual int compare(const QIconViewItem* item1, const QIconViewItem* item2);
+
+protected:
+ virtual int compare(const QString&, const QString&) { return 0; }
+};
+
+class DependentComparison : public StringComparison {
+public:
+ DependentComparison(Data::ConstFieldPtr field);
+
+ virtual int compare(int col, const GUI::ListViewItem* item1, const GUI::ListViewItem* item2, bool asc);
+ virtual int compare(const QIconViewItem* item1, const QIconViewItem* item2);
+
+private:
+ QPtrList<ListViewComparison> m_comparisons;
+};
+
+class ISODateComparison : public ListViewComparison {
+public:
+ ISODateComparison(Data::ConstFieldPtr field);
+
+protected:
+ virtual int compare(const QString& str1, const QString& str2);
+};
+
+}
+#endif
diff --git a/src/loandialog.cpp b/src/loandialog.cpp
new file mode 100644
index 0000000..e34ecc7
--- /dev/null
+++ b/src/loandialog.cpp
@@ -0,0 +1,268 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "loandialog.h"
+#include "borrowerdialog.h"
+#include "gui/datewidget.h"
+#include "gui/richtextlabel.h"
+#include "collection.h"
+#include "commands/addloans.h"
+#include "commands/modifyloans.h"
+
+#include <config.h>
+
+#include <klocale.h>
+#include <klineedit.h>
+#include <kpushbutton.h>
+#include <ktextedit.h>
+#include <kiconloader.h>
+#include <kabc/stdaddressbook.h>
+
+#include <qlayout.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qwhatsthis.h>
+
+using Tellico::LoanDialog;
+
+LoanDialog::LoanDialog(const Data::EntryVec& entries_, QWidget* parent_, const char* name_/*=0*/)
+ : KDialogBase(parent_, name_, true, i18n("Loan Dialog"), Ok|Cancel),
+ m_mode(Add), m_borrower(0), m_entries(entries_), m_loan(0) {
+ init();
+}
+
+LoanDialog::LoanDialog(Data::LoanPtr loan_, QWidget* parent_, const char* name_/*=0*/)
+ : KDialogBase(parent_, name_, true, i18n("Modify Loan"), Ok|Cancel),
+ m_mode(Modify), m_borrower(loan_->borrower()), m_loan(loan_) {
+ m_entries.append(m_loan->entry());
+
+ init();
+
+ m_borrowerEdit->setText(m_loan->borrower()->name());
+ m_loanDate->setDate(m_loan->loanDate());
+ if(m_loan->dueDate().isValid()) {
+ m_dueDate->setDate(m_loan->dueDate());
+ m_addEvent->setEnabled(true);
+ if(m_loan->inCalendar()) {
+ m_addEvent->setChecked(true);
+ }
+ }
+ m_note->setText(m_loan->note());
+}
+
+void LoanDialog::init() {
+ QWidget* mainWidget = new QWidget(this, "LoanDialog mainWidget");
+ setMainWidget(mainWidget);
+ QGridLayout* topLayout = new QGridLayout(mainWidget, 7, 2, 0, KDialog::spacingHint());
+
+ QHBox* hbox = new QHBox(mainWidget);
+ hbox->setSpacing(KDialog::spacingHint());
+ QLabel* pixLabel = new QLabel(hbox);
+ pixLabel->setPixmap(DesktopIcon(QString::fromLatin1("tellico"), 64));
+ pixLabel->setAlignment(Qt::AlignAuto | Qt::AlignTop);
+ hbox->setStretchFactor(pixLabel, 0);
+
+ QString entryString = QString::fromLatin1("<qt><p>");
+ if(m_mode == Add) {
+ entryString += i18n("The following items are being checked out:");
+ entryString += QString::fromLatin1("</p><ol>");
+ for(Data::EntryVec::ConstIterator entry = m_entries.constBegin(); entry != m_entries.constEnd(); ++entry) {
+ entryString += QString::fromLatin1("<li>") + entry->title() + QString::fromLatin1("</li>");
+ }
+ } else {
+ entryString += i18n("The following item is on-loan:");
+ entryString += QString::fromLatin1("</p><ol>");
+ entryString += QString::fromLatin1("<li>") + m_loan->entry()->title() + QString::fromLatin1("</li>");
+ }
+ entryString += QString::fromLatin1("</ol></qt>");
+ GUI::RichTextLabel* entryLabel = new GUI::RichTextLabel(entryString, hbox);
+ hbox->setStretchFactor(entryLabel, 1);
+
+ topLayout->addMultiCellWidget(hbox, 0, 0, 0, 1);
+
+ QLabel* l = new QLabel(i18n("&Lend to:"), mainWidget);
+ topLayout->addWidget(l, 1, 0);
+ hbox = new QHBox(mainWidget);
+ hbox->setSpacing(KDialog::spacingHint());
+ topLayout->addWidget(hbox, 1, 1);
+ m_borrowerEdit = new KLineEdit(hbox);
+ l->setBuddy(m_borrowerEdit);
+ m_borrowerEdit->completionObject()->setIgnoreCase(true);
+ connect(m_borrowerEdit, SIGNAL(textChanged(const QString&)),
+ SLOT(slotBorrowerNameChanged(const QString&)));
+ actionButton(Ok)->setEnabled(false); // disable until a name is entered
+ KPushButton* pb = new KPushButton(SmallIconSet(QString::fromLatin1("kaddressbook")), QString::null, hbox);
+ connect(pb, SIGNAL(clicked()), SLOT(slotGetBorrower()));
+ QString whats = i18n("Enter the name of the person borrowing the items from you. "
+ "Clicking the button allows you to select from your address book.");
+ QWhatsThis::add(l, whats);
+ QWhatsThis::add(hbox, whats);
+ // only enable for new loans
+ if(m_mode == Modify) {
+ m_borrowerEdit->setEnabled(false);
+ pb->setEnabled(false);
+ }
+
+ l = new QLabel(i18n("&Loan date:"), mainWidget);
+ topLayout->addWidget(l, 2, 0);
+ m_loanDate = new GUI::DateWidget(mainWidget);
+ m_loanDate->setDate(QDate::currentDate());
+ l->setBuddy(m_loanDate);
+ topLayout->addWidget(m_loanDate, 2, 1);
+ whats = i18n("The check-out date is the date that you lent the items. By default, "
+ "today's date is used.");
+ QWhatsThis::add(l, whats);
+ QWhatsThis::add(m_loanDate, whats);
+ // only enable for new loans
+ if(m_mode == Modify) {
+ m_loanDate->setEnabled(false);
+ }
+
+ l = new QLabel(i18n("D&ue date:"), mainWidget);
+ topLayout->addWidget(l, 3, 0);
+ m_dueDate = new GUI::DateWidget(mainWidget);
+ l->setBuddy(m_dueDate);
+ topLayout->addWidget(m_dueDate, 3, 1);
+ // valid due dates will enable the calendar adding checkbox
+ connect(m_dueDate, SIGNAL(signalModified()), SLOT(slotDueDateChanged()));
+ whats = i18n("The due date is when the items are due to be returned. The due date "
+ "is not required, unless you want to add the loan to your active calendar.");
+ QWhatsThis::add(l, whats);
+ QWhatsThis::add(m_dueDate, whats);
+
+ l = new QLabel(i18n("&Note:"), mainWidget);
+ topLayout->addWidget(l, 4, 0);
+ m_note = new KTextEdit(mainWidget);
+ l->setBuddy(m_note);
+ topLayout->addMultiCellWidget(m_note, 5, 5, 0, 1);
+ topLayout->setRowStretch(5, 1);
+ whats = i18n("You can add notes about the loan, as well.");
+ QWhatsThis::add(l, whats);
+ QWhatsThis::add(m_note, whats);
+
+ m_addEvent = new QCheckBox(i18n("&Add a reminder to the active calendar"), mainWidget);
+ topLayout->addMultiCellWidget(m_addEvent, 6, 6, 0, 1);
+ m_addEvent->setEnabled(false); // gets enabled when valid due date is entered
+ QWhatsThis::add(m_addEvent, i18n("<qt>Checking this box will add a <em>To-do</em> item "
+ "to your active calendar, which can be viewed using KOrganizer. "
+ "The box is only active if you set a due date."));
+
+ resize(configDialogSize(QString::fromLatin1("Loan Dialog Options")));
+
+ KABC::AddressBook* abook = KABC::StdAddressBook::self(true);
+ connect(abook, SIGNAL(addressBookChanged(AddressBook*)),
+ SLOT(slotLoadAddressBook()));
+ connect(abook, SIGNAL(loadingFinished(Resource*)),
+ SLOT(slotLoadAddressBook()));
+ slotLoadAddressBook();
+}
+
+LoanDialog::~LoanDialog() {
+ saveDialogSize(QString::fromLatin1("Loan Dialog Options"));
+}
+
+void LoanDialog::slotBorrowerNameChanged(const QString& str_) {
+ actionButton(Ok)->setEnabled(!str_.isEmpty());
+}
+
+void LoanDialog::slotDueDateChanged() {
+#ifdef HAVE_KCAL
+ m_addEvent->setEnabled(m_dueDate->date().isValid());
+#endif
+}
+
+void LoanDialog::slotGetBorrower() {
+ Data::BorrowerPtr borrower = BorrowerDialog::getBorrower(this);
+ if(borrower) {
+ m_borrowerEdit->setText(borrower->name());
+ m_uid = borrower->uid();
+ }
+}
+
+void LoanDialog::slotLoadAddressBook() {
+ m_borrowerEdit->completionObject()->clear();
+
+ const KABC::AddressBook* const abook = KABC::StdAddressBook::self(true);
+ for(KABC::AddressBook::ConstIterator it = abook->begin(), end = abook->end();
+ it != end; ++it) {
+ m_borrowerEdit->completionObject()->addItem((*it).realName());
+ }
+
+ // add current borrowers, too
+ QStringList items = m_borrowerEdit->completionObject()->items();
+ Data::BorrowerVec borrowers = m_entries.begin()->collection()->borrowers();
+ for(Data::BorrowerVec::ConstIterator it = borrowers.constBegin(), end = borrowers.constEnd();
+ it != end; ++it) {
+ if(items.findIndex(it->name()) == -1) {
+ m_borrowerEdit->completionObject()->addItem(it->name());
+ }
+ }
+}
+
+KCommand* LoanDialog::createCommand() {
+ // first, check to see if the borrower is empty
+ QString name = m_borrowerEdit->text();
+ if(name.isEmpty()) {
+ return 0;
+ }
+
+ // ok, first handle creating new loans
+ if(m_mode == Add) {
+ return addLoansCommand();
+ } else {
+ return modifyLoansCommand();
+ }
+}
+
+KCommand* LoanDialog::addLoansCommand() {
+ if(m_entries.isEmpty()) {
+ return 0;
+ }
+
+ const QString name = m_borrowerEdit->text();
+
+ // see if there's a borrower with this name already
+ m_borrower = 0;
+ Data::BorrowerVec borrowers = m_entries.begin()->collection()->borrowers();
+ for(Data::BorrowerVec::Iterator it = borrowers.begin(); it != borrowers.end(); ++it) {
+ if(it->name() == name) {
+ m_borrower = it;
+ break;
+ }
+ }
+
+ if(!m_borrower) {
+ m_borrower = new Data::Borrower(name, m_uid);
+ }
+
+ Data::LoanVec loans;
+ for(Data::EntryVecIt entry = m_entries.begin(); entry != m_entries.end(); ++entry) {
+ loans.append(new Data::Loan(entry, m_loanDate->date(), m_dueDate->date(), m_note->text()));
+ }
+
+ return new Command::AddLoans(m_borrower, loans, m_addEvent->isChecked());
+}
+
+KCommand* LoanDialog::modifyLoansCommand() {
+ if(!m_loan) {
+ return 0;
+ }
+
+ Data::LoanPtr newLoan = new Data::Loan(*m_loan);
+ newLoan->setDueDate(m_dueDate->date());
+ newLoan->setNote(m_note->text());
+ return new Command::ModifyLoans(m_loan, newLoan, m_addEvent->isChecked());
+}
+
+#include "loandialog.moc"
diff --git a/src/loandialog.h b/src/loandialog.h
new file mode 100644
index 0000000..b51abf0
--- /dev/null
+++ b/src/loandialog.h
@@ -0,0 +1,82 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef LOANDIALOG_H
+#define LOANDIALOG_H
+
+class KLineEdit;
+class KTextEdit;
+class KCommand;
+class QCheckBox;
+
+#include "datavectors.h"
+#include "borrower.h"
+
+#include <kdialogbase.h>
+
+namespace Tellico {
+ namespace GUI {
+ class DateWidget;
+ }
+
+/**
+ * @author Robby Stephenson
+ */
+class LoanDialog : public KDialogBase {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor sets up the dialog.
+ *
+ * @param parent A pointer to the parent widget
+ * @param name The widget name
+ */
+ LoanDialog(const Data::EntryVec& entries, QWidget* parent, const char* name=0);
+ LoanDialog(Data::LoanPtr loan, QWidget* parent, const char* name=0);
+ virtual ~LoanDialog();
+
+ KCommand* createCommand();
+
+private slots:
+ void slotBorrowerNameChanged(const QString& str);
+ void slotGetBorrower();
+ void slotLoadAddressBook();
+ void slotDueDateChanged();
+
+private:
+ void init();
+ KCommand* addLoansCommand();
+ KCommand* modifyLoansCommand();
+
+ enum Mode {
+ Add,
+ Modify
+ };
+
+ const Mode m_mode;
+ Data::BorrowerPtr m_borrower;
+ Data::EntryVec m_entries;
+ Data::LoanPtr m_loan;
+
+ KLineEdit* m_borrowerEdit;
+ GUI::DateWidget* m_loanDate;
+ GUI::DateWidget* m_dueDate;
+ KTextEdit* m_note;
+ QCheckBox* m_addEvent;
+
+ QString m_uid;
+};
+
+} // end namespace
+#endif
diff --git a/src/loanitem.cpp b/src/loanitem.cpp
new file mode 100644
index 0000000..744397d
--- /dev/null
+++ b/src/loanitem.cpp
@@ -0,0 +1,26 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "loanitem.h"
+#include "entry.h"
+#include "tellico_kernel.h"
+
+using Tellico::LoanItem;
+
+LoanItem::LoanItem(GUI::CountedItem* parent_, Tellico::Data::LoanPtr loan_)
+ : Tellico::EntryItem(parent_, loan_->entry()), m_loan(loan_) {
+}
+
+void LoanItem::doubleClicked() {
+ Kernel::self()->modifyLoan(m_loan);
+}
diff --git a/src/loanitem.h b/src/loanitem.h
new file mode 100644
index 0000000..5e79139
--- /dev/null
+++ b/src/loanitem.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_LOANITEM_H
+#define TELLICO_LOANITEM_H
+
+#include "entryitem.h"
+#include "borrower.h"
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class LoanItem : public Tellico::EntryItem {
+public:
+ LoanItem(GUI::CountedItem* parent, Data::LoanPtr loan);
+
+ virtual bool isLoanItem() const { return true; }
+ Data::LoanPtr loan() { return m_loan; }
+
+ virtual void doubleClicked();
+
+private:
+ Data::LoanPtr m_loan;
+};
+
+}
+
+#endif
diff --git a/src/loanview.cpp b/src/loanview.cpp
new file mode 100644
index 0000000..875f267
--- /dev/null
+++ b/src/loanview.cpp
@@ -0,0 +1,234 @@
+/***************************************************************************
+ copyright : (C) 2005-2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "loanview.h"
+#include "loanitem.h"
+#include "controller.h"
+#include "borrower.h"
+#include "entry.h"
+#include "collection.h"
+#include "tellico_kernel.h"
+#include "tellico_debug.h"
+#include "listviewcomparison.h"
+
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <kiconloader.h>
+
+#include <qheader.h>
+
+using Tellico::LoanView;
+
+LoanView::LoanView(QWidget* parent_, const char* name_) : GUI::ListView(parent_, name_), m_notSortedYet(true) {
+ addColumn(i18n("Borrower"));
+ header()->setStretchEnabled(true, 0);
+ setResizeMode(QListView::NoColumn);
+ setRootIsDecorated(true);
+ setShowSortIndicator(true);
+ setTreeStepSize(15);
+ setFullWidth(true);
+
+ connect(this, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)),
+ SLOT(contextMenuRequested(QListViewItem*, const QPoint&, int)));
+
+ connect(this, SIGNAL(expanded(QListViewItem*)),
+ SLOT(slotExpanded(QListViewItem*)));
+
+ connect(this, SIGNAL(collapsed(QListViewItem*)),
+ SLOT(slotCollapsed(QListViewItem*)));
+}
+
+bool LoanView::isSelectable(GUI::ListViewItem* item_) const {
+ if(!GUI::ListView::isSelectable(item_)) {
+ return false;
+ }
+
+ // because the popup menu has modify, only
+ // allow one loan item to get selected
+ if(item_->isLoanItem()) {
+ return selectedItems().isEmpty();
+ }
+
+ return true;
+}
+
+void LoanView::contextMenuRequested(QListViewItem* item_, const QPoint& point_, int) {
+ if(!item_) {
+ return;
+ }
+
+ GUI::ListViewItem* item = static_cast<GUI::ListViewItem*>(item_);
+ if(item->isLoanItem()) {
+ KPopupMenu menu(this);
+ menu.insertItem(SmallIconSet(QString::fromLatin1("2downarrow")),
+ i18n("Check-in"), this, SLOT(slotCheckIn()));
+ menu.insertItem(SmallIconSet(QString::fromLatin1("2downarrow")),
+ i18n("Modify Loan..."), this, SLOT(slotModifyLoan()));
+ menu.exec(point_);
+ }
+}
+
+// this gets called when header() is clicked, so cycle through
+void LoanView::setSorting(int col_, bool asc_) {
+ if(asc_ && !m_notSortedYet) {
+ if(sortStyle() == ListView::SortByText) {
+ setSortStyle(ListView::SortByCount);
+ } else {
+ setSortStyle(ListView::SortByText);
+ }
+ }
+ if(sortStyle() == ListView::SortByText) {
+ setColumnText(0, i18n("Borrower"));
+ } else {
+ setColumnText(0, i18n("Borrower (Sort by Count)"));
+ }
+ m_notSortedYet = false;
+ ListView::setSorting(col_, asc_);
+}
+
+void LoanView::addCollection(Data::CollPtr coll_) {
+ Data::BorrowerVec borrowers = coll_->borrowers();
+ for(Data::BorrowerVec::Iterator it = borrowers.begin(); it != borrowers.end(); ++it) {
+ addBorrower(it);
+ }
+ Data::FieldPtr f = coll_->fieldByName(QString::fromLatin1("title"));
+ if(f) {
+ setComparison(0, ListViewComparison::create(f));
+ }
+}
+
+void LoanView::addField(Data::CollPtr, Data::FieldPtr) {
+ resetComparisons();
+}
+
+void LoanView::modifyField(Data::CollPtr, Data::FieldPtr, Data::FieldPtr) {
+ resetComparisons();
+}
+
+void LoanView::removeField(Data::CollPtr, Data::FieldPtr) {
+ resetComparisons();
+}
+
+void LoanView::addBorrower(Data::BorrowerPtr borrower_) {
+ if(!borrower_ || borrower_->isEmpty()) {
+ return;
+ }
+
+ BorrowerItem* borrowerItem = new BorrowerItem(this, borrower_);
+ borrowerItem->setExpandable(!borrower_->loans().isEmpty());
+ m_itemDict.insert(borrower_->name(), borrowerItem);
+}
+
+void LoanView::modifyBorrower(Data::BorrowerPtr borrower_) {
+ if(!borrower_) {
+ return;
+ }
+
+ BorrowerItem* borrowerItem = m_itemDict[borrower_->name()];
+ if(!borrowerItem) {
+ myDebug() << "LoanView::modifyBorrower() - borrower was never added" << endl;
+ return;
+ }
+
+ if(borrower_->isEmpty()) {
+ m_itemDict.remove(borrower_->name());
+ delete borrowerItem;
+ return;
+ }
+
+ bool open = borrowerItem->isOpen();
+ borrowerItem->setOpen(false);
+ borrowerItem->setOpen(open);
+}
+
+void LoanView::slotCollapsed(QListViewItem* item_) {
+ // only change icon for group items
+ if(static_cast<GUI::ListViewItem*>(item_)->isBorrowerItem()) {
+ static_cast<GUI::ListViewItem*>(item_)->clear();
+ }
+}
+
+void LoanView::slotExpanded(QListViewItem* item_) {
+ // only change icon for group items
+ if(!static_cast<GUI::ListViewItem*>(item_)->isBorrowerItem()) {
+ kdWarning() << "GroupView::slotExpanded() - non entry group item - " << item_->text(0) << endl;
+ return;
+ }
+
+ setUpdatesEnabled(false);
+
+ BorrowerItem* item = static_cast<BorrowerItem*>(item_);
+ Data::LoanVec loans = item->borrower()->loans();
+ for(Data::LoanVec::Iterator it = loans.begin(); it != loans.end(); ++it) {
+ new LoanItem(item, it);
+ }
+
+ setUpdatesEnabled(true);
+ triggerUpdate();
+}
+
+void LoanView::slotCheckIn() {
+ GUI::ListViewItem* item = selectedItems().getFirst();
+ if(!item || !item->isLoanItem()) {
+ return;
+ }
+
+ Data::EntryVec entries;
+ // need a copy since we may be deleting
+ GUI::ListViewItemList list = selectedItems();
+ for(GUI::ListViewItemListIt it(list); it.current(); ++it) {
+ Data::EntryPtr entry = static_cast<LoanItem*>(it.current())->entry();
+ if(!entry) {
+ myDebug() << "LoanView::slotCheckIn() - no entry!" << endl;
+ continue;
+ }
+ entries.append(entry);
+ }
+
+ Controller::self()->slotCheckIn(entries);
+ Controller::self()->slotClearSelection(); // so the checkout menu item gets disabled
+}
+
+void LoanView::slotModifyLoan() {
+ GUI::ListViewItem* item = selectedItems().getFirst();
+ if(!item || !item->isLoanItem()) {
+ return;
+ }
+
+ Kernel::self()->modifyLoan(static_cast<LoanItem*>(item)->loan());
+}
+
+void LoanView::resetComparisons() {
+ // this is only allowed when the view is not empty, so we can grab a collection ptr
+ if(childCount() == 0) {
+ return;
+ }
+ Data::EntryVec entries = static_cast<BorrowerItem*>(firstChild())->entries();
+ if(entries.isEmpty()) {
+ return;
+ }
+ Data::EntryPtr entry = entries[0];
+ if(!entry) {
+ return;
+ }
+ Data::CollPtr coll = entry->collection();
+ if(!coll) {
+ return;
+ }
+ Data::FieldPtr f = coll->fieldByName(QString::fromLatin1("title"));
+ if(f) {
+ setComparison(0, ListViewComparison::create(f));
+ }
+}
+
+#include "loanview.moc"
diff --git a/src/loanview.h b/src/loanview.h
new file mode 100644
index 0000000..59e4df4
--- /dev/null
+++ b/src/loanview.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+ copyright : (C) 2005-2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_LOANVIEW_H
+#define TELLICO_LOANVIEW_H
+
+#include "gui/listview.h"
+#include "observer.h"
+#include "borroweritem.h"
+
+#include <qdict.h>
+
+namespace Tellico {
+ namespace Data {
+ class Borrower;
+ }
+
+/**
+ * @author Robby Stephenson
+ */
+class LoanView : public GUI::ListView, public Observer {
+Q_OBJECT
+
+public:
+ LoanView(QWidget* parent, const char* name=0);
+
+ virtual bool isSelectable(GUI::ListViewItem*) const;
+
+ virtual void addCollection(Data::CollPtr coll);
+
+ virtual void addField(Data::CollPtr, Data::FieldPtr);
+ virtual void modifyField(Data::CollPtr, Data::FieldPtr, Data::FieldPtr);
+ virtual void removeField(Data::CollPtr, Data::FieldPtr);
+
+ virtual void addBorrower(Data::BorrowerPtr);
+ virtual void modifyBorrower(Data::BorrowerPtr);
+
+private slots:
+ /**
+ * Handles the appearance of the popup menu.
+ *
+ * @param item A pointer to the item underneath the mouse
+ * @param point The location point
+ * @param col The column number, not currently used
+ */
+ void contextMenuRequested(QListViewItem* item, const QPoint& point, int col);
+ void slotExpanded(QListViewItem* item);
+ void slotCollapsed(QListViewItem* item);
+ void slotCheckIn();
+ void slotModifyLoan();
+
+private:
+ virtual void setSorting(int column, bool ascending = true);
+ void resetComparisons();
+
+ bool m_notSortedYet;
+ QDict<BorrowerItem> m_itemDict;
+};
+
+} // end namespace
+
+#endif
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..f0b57c4
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,88 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "mainwindow.h"
+#include "translators/translators.h" // needed for file type enum
+
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <klocale.h>
+
+namespace {
+ static const char* description = I18N_NOOP("Tellico - a collection manager for KDE");
+ static const char* version = VERSION;
+
+ static KCmdLineOptions options[] = {
+ { "nofile", I18N_NOOP("Do not reopen the last open file"), 0 },
+ { "bibtex", I18N_NOOP("Import <filename> as a bibtex file"), 0 },
+ { "mods", I18N_NOOP("Import <filename> as a MODS file"), 0 },
+ { "ris", I18N_NOOP("Import <filename> as a RIS file"), 0 },
+ { "+[filename]", I18N_NOOP("File to open"), 0 },
+ KCmdLineLastOption
+ };
+}
+
+int main(int argc, char* argv[]) {
+ KAboutData aboutData("tellico", "Tellico",
+ version, description, KAboutData::License_GPL,
+ "(c) 2001-2007, Robby Stephenson", 0,
+ "http://www.periapsis.org/tellico/", "tellico-users@forge.novell.com");
+ aboutData.addAuthor("Robby Stephenson", 0, "robby@periapsis.org");
+ aboutData.addCredit("Mathias Monnerville", I18N_NOOP("Data source scripts"),
+ 0, 0);
+ aboutData.addCredit("Virginie Quesnay", I18N_NOOP("Icons"),
+ 0, 0);
+ aboutData.addCredit("Greg Ward", I18N_NOOP("Author of btparse library"),
+ 0, "http://www.gerg.ca");
+ aboutData.addCredit("Amarok", I18N_NOOP("Code examples and general inspiration"),
+ 0, "http://amarok.kde.org");
+ aboutData.addCredit("Robert Gamble", I18N_NOOP("Author of libcsv library"),
+ 0, 0);
+ aboutData.addCredit("Valentin Lavrinenko", I18N_NOOP("Author of rtf2html library"),
+ 0, 0);
+
+ KCmdLineArgs::init(argc, argv, &aboutData);
+ KCmdLineArgs::addCmdLineOptions(options);
+
+ KApplication app;
+
+ if(app.isRestored()) {
+ RESTORE(Tellico::MainWindow);
+ } else {
+ Tellico::MainWindow* tellico = new Tellico::MainWindow();
+ tellico->show();
+ tellico->slotShowTipOfDay(false);
+
+ KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
+ if(args->count() > 0) {
+ if(args->isSet("bibtex")) {
+ tellico->importFile(Tellico::Import::Bibtex, args->url(0), Tellico::Import::Replace);
+ } else if(args->isSet("mods")) {
+ tellico->importFile(Tellico::Import::MODS, args->url(0), Tellico::Import::Replace);
+ } else if(args->isSet("ris")) {
+ tellico->importFile(Tellico::Import::RIS, args->url(0), Tellico::Import::Replace);
+ } else {
+ tellico->slotFileOpen(args->url(0));
+ }
+ } else {
+ // bit of a hack, I just want the --nofile option
+ // if --nofile is NOT passed, then the file option is set
+ // is it's set, then go ahead and check for opening previous file
+ tellico->initFileOpen(!args->isSet("file"));
+ }
+ args->clear(); // some memory savings
+ }
+
+ return app.exec();
+}
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
new file mode 100644
index 0000000..bb5db7a
--- /dev/null
+++ b/src/mainwindow.cpp
@@ -0,0 +1,2391 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "mainwindow.h"
+#include "tellico_kernel.h"
+#include "document.h"
+#include "detailedlistview.h"
+#include "entryeditdialog.h"
+#include "groupview.h"
+#include "viewstack.h"
+#include "collection.h"
+#include "entry.h"
+#include "configdialog.h"
+#include "entryitem.h"
+#include "filter.h"
+#include "filterdialog.h"
+#include "collectionfieldsdialog.h"
+#include "controller.h"
+#include "importdialog.h"
+#include "exportdialog.h"
+#include "filehandler.h" // needed so static mainWindow variable can be set
+#include "gui/stringmapdialog.h"
+#include "translators/htmlexporter.h" // for printing
+#include "entryview.h"
+#include "entryiconview.h"
+#include "imagefactory.h" // needed so tmp files can get cleaned
+#include "collections/bibtexcollection.h" // needed for bibtex string macro dialog
+#include "translators/bibtexhandler.h" // needed for bibtex options
+#include "fetchdialog.h"
+#include "reportdialog.h"
+#include "tellico_strings.h"
+#include "filterview.h"
+#include "loanview.h"
+#include "gui/tabcontrol.h"
+#include "gui/lineedit.h"
+#include "tellico_utils.h"
+#include "tellico_debug.h"
+#include "entryiconfactory.h"
+#include "statusbar.h"
+#include "fetch/fetchmanager.h"
+#include "cite/actionmanager.h"
+#include "core/tellico_config.h"
+#include "core/drophandler.h"
+#include "latin1literal.h"
+
+#include <kapplication.h>
+#include <kcombobox.h>
+#include <kiconloader.h>
+#include <kfiledialog.h>
+#include <kmenubar.h>
+#include <ktoolbar.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kstdaction.h>
+#include <kwin.h>
+#include <kprogress.h>
+#include <kprinter.h>
+#include <khtmlview.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+#include <ktip.h>
+#include <krecentdocument.h>
+#include <kedittoolbar.h>
+#include <kkeydialog.h>
+#include <kio/netaccess.h>
+#include <dcopclient.h>
+#include <kaction.h>
+
+#include <qsplitter.h>
+//#include <qpainter.h>
+#include <qsignalmapper.h>
+#include <qtimer.h>
+#include <qmetaobject.h> // needed for copy, cut, paste slots
+#include <qwhatsthis.h>
+#include <qvbox.h>
+
+// the null string and bool are dummy arguments
+#define MIME_ICON(s) \
+ KMimeType::mimeType(QString::fromLatin1(s))->icon(QString::null, false)
+
+namespace {
+ static const int MAIN_WINDOW_MIN_WIDTH = 600;
+ //static const int PRINTED_PAGE_OVERLAP = 0;
+ static const int MAX_IMAGES_WARN_PERFORMANCE = 200;
+}
+
+using Tellico::MainWindow;
+
+MainWindow::MainWindow(QWidget* parent_/*=0*/, const char* name_/*=0*/) : KMainWindow(parent_, name_),
+ ApplicationInterface(),
+ m_updateAll(0),
+ m_statusBar(0),
+ m_editDialog(0),
+ m_groupView(0),
+ m_filterView(0),
+ m_loanView(0),
+ m_configDlg(0),
+ m_filterDlg(0),
+ m_collFieldsDlg(0),
+ m_stringMacroDlg(0),
+ m_fetchDlg(0),
+ m_reportDlg(0),
+ m_queuedFilters(0),
+ m_initialized(false),
+ m_newDocument(true) {
+
+ if(!kapp->dcopClient()->isRegistered()) {
+ kapp->dcopClient()->registerAs("tellico");
+ kapp->dcopClient()->setDefaultObject(objId());
+ }
+
+ m_fetchActions.setAutoDelete(true); // these are the fetcher actions
+
+ Controller::init(this); // the only time this is ever called!
+ // has to be after controller init
+ Kernel::init(this); // the only time this is ever called!
+
+ setIcon(DesktopIcon(QString::fromLatin1("tellico")));
+
+ // initialize the status bar and progress bar
+ initStatusBar();
+
+ // create a document, which also creates an empty book collection
+ // must be done before the different widgets are created
+ initDocument();
+
+ // set up all the actions, some connect to the document, so this must be after initDocument()
+ initActions();
+
+ // create the different widgets in the view, some widgets connect to actions, so must be after initActions()
+ initView();
+
+ // The edit dialog is not created until after the main window is initialized, so it can be a child.
+ // So don't make any connections, don't read options for it until initFileOpen
+ readOptions();
+
+ setAcceptDrops(true);
+ DropHandler* drophandler = new DropHandler(this);
+ installEventFilter(drophandler);
+
+ MARK_LINE;
+ QTimer::singleShot(0, this, SLOT(slotInit()));
+}
+
+void MainWindow::slotInit() {
+ MARK;
+ if(m_editDialog) {
+ return;
+ }
+ m_editDialog = new EntryEditDialog(this, "editdialog");
+ Controller::self()->addObserver(m_editDialog);
+
+ m_toggleEntryEditor->setChecked(Config::showEditWidget());
+ slotToggleEntryEditor();
+
+ initConnections();
+ ImageFactory::init();
+
+ // disable OOO menu item if library is not available
+ action("cite_openoffice")->setEnabled(Cite::ActionManager::isEnabled(Cite::CiteOpenOffice));
+}
+
+void MainWindow::initStatusBar() {
+ MARK;
+ m_statusBar = new Tellico::StatusBar(this);
+}
+
+void MainWindow::initActions() {
+ MARK;
+ /*************************************************
+ * File->New menu
+ *************************************************/
+ QSignalMapper* collectionMapper = new QSignalMapper(this);
+ connect(collectionMapper, SIGNAL(mapped(int)),
+ this, SLOT(slotFileNew(int)));
+
+ KActionMenu* fileNewMenu = new KActionMenu(actionCollection(), "file_new_collection");
+ fileNewMenu->setText(i18n("New"));
+// fileNewMenu->setIconSet(BarIconSet(QString::fromLatin1("filenew"))); // doesn't work
+ fileNewMenu->setIconSet(BarIcon(QString::fromLatin1("filenew")));
+ fileNewMenu->setToolTip(i18n("Create a new collection"));
+ fileNewMenu->setDelayed(false);
+
+ KAction* action = new KAction(actionCollection(), "new_book_collection");
+ action->setText(i18n("New &Book Collection"));
+ action->setIconSet(UserIconSet(QString::fromLatin1("book")));
+ action->setToolTip(i18n("Create a new book collection"));
+ fileNewMenu->insert(action);
+ connect(action, SIGNAL(activated()), collectionMapper, SLOT(map()));
+ collectionMapper->setMapping(action, Data::Collection::Book);
+
+ action = new KAction(actionCollection(), "new_bibtex_collection");
+ action->setText(i18n("New B&ibliography"));
+ action->setIconSet(UserIconSet(QString::fromLatin1("bibtex")));
+ action->setToolTip(i18n("Create a new bibtex bibliography"));
+ fileNewMenu->insert(action);
+ connect(action, SIGNAL(activated()), collectionMapper, SLOT(map()));
+ collectionMapper->setMapping(action, Data::Collection::Bibtex);
+
+ action = new KAction(actionCollection(), "new_comic_book_collection");
+ action->setText(i18n("New &Comic Book Collection"));
+ action->setIconSet(UserIconSet(QString::fromLatin1("comic")));
+ action->setToolTip(i18n("Create a new comic book collection"));
+ fileNewMenu->insert(action);
+ connect(action, SIGNAL(activated()), collectionMapper, SLOT(map()));
+ collectionMapper->setMapping(action, Data::Collection::ComicBook);
+
+ action = new KAction(actionCollection(), "new_video_collection");
+ action->setText(i18n("New &Video Collection"));
+ action->setIconSet(UserIconSet(QString::fromLatin1("video")));
+ action->setToolTip(i18n("Create a new video collection"));
+ fileNewMenu->insert(action);
+ connect(action, SIGNAL(activated()), collectionMapper, SLOT(map()));
+ collectionMapper->setMapping(action, Data::Collection::Video);
+
+ action = new KAction(actionCollection(), "new_music_collection");
+ action->setText(i18n("New &Music Collection"));
+ action->setIconSet(UserIconSet(QString::fromLatin1("album")));
+ action->setToolTip(i18n("Create a new music collection"));
+ fileNewMenu->insert(action);
+ connect(action, SIGNAL(activated()), collectionMapper, SLOT(map()));
+ collectionMapper->setMapping(action, Data::Collection::Album);
+
+ action = new KAction(actionCollection(), "new_coin_collection");
+ action->setText(i18n("New C&oin Collection"));
+ action->setIconSet(UserIconSet(QString::fromLatin1("coin")));
+ action->setToolTip(i18n("Create a new coin collection"));
+ fileNewMenu->insert(action);
+ connect(action, SIGNAL(activated()), collectionMapper, SLOT(map()));
+ collectionMapper->setMapping(action, Data::Collection::Coin);
+
+ action = new KAction(actionCollection(), "new_stamp_collection");
+ action->setText(i18n("New &Stamp Collection"));
+ action->setIconSet(UserIconSet(QString::fromLatin1("stamp")));
+ action->setToolTip(i18n("Create a new stamp collection"));
+ fileNewMenu->insert(action);
+ connect(action, SIGNAL(activated()), collectionMapper, SLOT(map()));
+ collectionMapper->setMapping(action, Data::Collection::Stamp);
+
+ action = new KAction(actionCollection(), "new_card_collection");
+ action->setText(i18n("New C&ard Collection"));
+ action->setIconSet(UserIconSet(QString::fromLatin1("card")));
+ action->setToolTip(i18n("Create a new trading card collection"));
+ fileNewMenu->insert(action);
+ connect(action, SIGNAL(activated()), collectionMapper, SLOT(map()));
+ collectionMapper->setMapping(action, Data::Collection::Card);
+
+ action = new KAction(actionCollection(), "new_wine_collection");
+ action->setText(i18n("New &Wine Collection"));
+ action->setIconSet(UserIconSet(QString::fromLatin1("wine")));
+ action->setToolTip(i18n("Create a new wine collection"));
+ fileNewMenu->insert(action);
+ connect(action, SIGNAL(activated()), collectionMapper, SLOT(map()));
+ collectionMapper->setMapping(action, Data::Collection::Wine);
+
+ action = new KAction(actionCollection(), "new_game_collection");
+ action->setText(i18n("New &Game Collection"));
+ action->setIconSet(UserIconSet(QString::fromLatin1("game")));
+ action->setToolTip(i18n("Create a new game collection"));
+ fileNewMenu->insert(action);
+ connect(action, SIGNAL(activated()), collectionMapper, SLOT(map()));
+
+ collectionMapper->setMapping(action, Data::Collection::Game);
+ action = new KAction(actionCollection(), "new_boardgame_collection");
+ action->setText(i18n("New Boa&rd Game Collection"));
+ action->setIconSet(UserIconSet(QString::fromLatin1("boardgame")));
+ action->setToolTip(i18n("Create a new board game collection"));
+ fileNewMenu->insert(action);
+ connect(action, SIGNAL(activated()), collectionMapper, SLOT(map()));
+ collectionMapper->setMapping(action, Data::Collection::BoardGame);
+
+ action = new KAction(actionCollection(), "new_file_catalog");
+ action->setText(i18n("New &File Catalog"));
+ action->setIconSet(UserIconSet(QString::fromLatin1("file")));
+ action->setToolTip(i18n("Create a new file catalog"));
+ fileNewMenu->insert(action);
+ connect(action, SIGNAL(activated()), collectionMapper, SLOT(map()));
+ collectionMapper->setMapping(action, Data::Collection::File);
+
+ action = new KAction(actionCollection(), "new_custom_collection");
+ action->setText(i18n("New C&ustom Collection"));
+ action->setIconSet(UserIconSet(QString::fromLatin1("filenew")));
+ action->setToolTip(i18n("Create a new custom collection"));
+ fileNewMenu->insert(action);
+ connect(action, SIGNAL(activated()), collectionMapper, SLOT(map()));
+ collectionMapper->setMapping(action, Data::Collection::Base);
+
+ /*************************************************
+ * File menu
+ *************************************************/
+ action = KStdAction::open(this, SLOT(slotFileOpen()), actionCollection());
+ action->setToolTip(i18n("Open an existing document"));
+ m_fileOpenRecent = KStdAction::openRecent(this, SLOT(slotFileOpenRecent(const KURL&)), actionCollection());
+ m_fileOpenRecent->setToolTip(i18n("Open a recently used file"));
+ m_fileSave = KStdAction::save(this, SLOT(slotFileSave()), actionCollection());
+ m_fileSave->setToolTip(i18n("Save the document"));
+ action = KStdAction::saveAs(this, SLOT(slotFileSaveAs()), actionCollection());
+ action->setToolTip(i18n("Save the document as a different file..."));
+ action = KStdAction::print(this, SLOT(slotFilePrint()), actionCollection());
+ action->setToolTip(i18n("Print the contents of the document..."));
+ action = KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection());
+ action->setToolTip(i18n("Quit the application"));
+
+/**************** Import Menu ***************************/
+
+ QSignalMapper* importMapper = new QSignalMapper(this);
+ connect(importMapper, SIGNAL(mapped(int)),
+ this, SLOT(slotFileImport(int)));
+
+ KActionMenu* importMenu = new KActionMenu(actionCollection(), "file_import");
+ importMenu->setText(i18n("&Import"));
+ importMenu->setIconSet(BarIconSet(QString::fromLatin1("fileimport")));
+ importMenu->setToolTip(i18n("Import collection data from other formats"));
+ importMenu->setDelayed(false);
+
+ action = new KAction(actionCollection(), "file_import_tellico");
+ action->setText(i18n("Import Tellico Data..."));
+ action->setToolTip(i18n("Import another Tellico data file"));
+ action->setIcon(QString::fromLatin1("tellico"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::TellicoXML);
+
+ action = new KAction(actionCollection(), "file_import_csv");
+ action->setText(i18n("Import CSV Data..."));
+ action->setToolTip(i18n("Import a CSV file"));
+ action->setIcon(MIME_ICON("text/x-csv"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::CSV);
+
+ action = new KAction(actionCollection(), "file_import_mods");
+ action->setText(i18n("Import MODS Data..."));
+ action->setToolTip(i18n("Import a MODS data file"));
+ action->setIcon(MIME_ICON("text/xml"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::MODS);
+
+ action = new KAction(actionCollection(), "file_import_alexandria");
+ action->setText(i18n("Import Alexandria Data..."));
+ action->setToolTip(i18n("Import data from the Alexandria book collection manager"));
+ action->setIcon(QString::fromLatin1("alexandria"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::Alexandria);
+
+ action = new KAction(actionCollection(), "file_import_delicious");
+ action->setText(i18n("Import Delicious Library Data..."));
+ action->setToolTip(i18n("Import data from Delicious Library"));
+ action->setIcon(MIME_ICON("text/xml"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::Delicious);
+
+ action = new KAction(actionCollection(), "file_import_referencer");
+ action->setText(i18n("Import Referencer Data..."));
+ action->setToolTip(i18n("Import data from Referencer"));
+ action->setIcon(QString::fromLatin1("referencer"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::Referencer);
+
+ action = new KAction(actionCollection(), "file_import_bibtex");
+ action->setText(i18n("Import Bibtex Data..."));
+ action->setToolTip(i18n("Import a bibtex bibliography file"));
+ action->setIcon(MIME_ICON("text/x-bibtex"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::Bibtex);
+
+ action = new KAction(actionCollection(), "file_import_bibtexml");
+ action->setText(i18n("Import Bibtexml Data..."));
+ action->setToolTip(i18n("Import a Bibtexml bibliography file"));
+ action->setIcon(MIME_ICON("text/xml"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::Bibtexml);
+
+ action = new KAction(actionCollection(), "file_import_ris");
+ action->setText(i18n("Import RIS Data..."));
+ action->setToolTip(i18n("Import an RIS reference file"));
+ action->setIcon(MIME_ICON("application/x-research-info-systems"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::RIS);
+
+ action = new KAction(actionCollection(), "file_import_pdf");
+ action->setText(i18n("Import PDF File..."));
+ action->setToolTip(i18n("Import a PDF file"));
+ action->setIcon(MIME_ICON("application/pdf"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::PDF);
+
+ action = new KAction(actionCollection(), "file_import_audiofile");
+ action->setText(i18n("Import Audio File Metadata..."));
+ action->setToolTip(i18n("Import meta-data from audio files"));
+ action->setIcon(MIME_ICON("audio/x-mp3"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::AudioFile);
+#ifndef HAVE_TAGLIB
+ action->setEnabled(false);
+#endif
+
+ action = new KAction(actionCollection(), "file_import_freedb");
+ action->setText(i18n("Import Audio CD Data..."));
+ action->setToolTip(i18n("Import audio CD information"));
+ action->setIcon(MIME_ICON("media/audiocd"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::FreeDB);
+#ifndef HAVE_KCDDB
+ action->setEnabled(false);
+#endif
+
+ action = new KAction(actionCollection(), "file_import_gcfilms");
+ action->setText(i18n("Import GCstar Data..."));
+ action->setToolTip(i18n("Import a GCstar data file"));
+ action->setIcon(QString::fromLatin1("gcstar"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::GCfilms);
+
+ action = new KAction(actionCollection(), "file_import_griffith");
+ action->setText(i18n("Import Griffith Data..."));
+ action->setToolTip(i18n("Import a Griffith database"));
+ action->setIcon(QString::fromLatin1("griffith"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::Griffith);
+
+ action = new KAction(actionCollection(), "file_import_amc");
+ action->setText(i18n("Import Ant Movie Catalog Data..."));
+ action->setToolTip(i18n("Import an Ant Movie Catalog data file"));
+ action->setIcon(MIME_ICON("application/x-crossover-amc"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::AMC);
+
+ action = new KAction(actionCollection(), "file_import_filelisting");
+ action->setText(i18n("Import File Listing..."));
+ action->setToolTip(i18n("Import information about files in a folder"));
+ action->setIcon(MIME_ICON("inode/directory"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::FileListing);
+
+ action = new KAction(actionCollection(), "file_import_xslt");
+ action->setText(i18n("Import XSL Transform..."));
+ action->setToolTip(i18n("Import using an XSL Transform"));
+ action->setIcon(MIME_ICON("text/x-xslt"));
+ importMenu->insert(action);
+ connect(action, SIGNAL(activated()), importMapper, SLOT(map()));
+ importMapper->setMapping(action, Import::XSLT);
+
+/**************** Export Menu ***************************/
+
+ QSignalMapper* exportMapper = new QSignalMapper(this);
+ connect(exportMapper, SIGNAL(mapped(int)),
+ this, SLOT(slotFileExport(int)));
+
+ KActionMenu* exportMenu = new KActionMenu(actionCollection(), "file_export");
+ exportMenu->setText(i18n("&Export"));
+ exportMenu->setIconSet(BarIconSet(QString::fromLatin1("fileexport")));
+ exportMenu->setToolTip(i18n("Export the collection data to other formats"));
+ exportMenu->setDelayed(false);
+
+ action = new KAction(actionCollection(), "file_export_xml");
+ action->setText(i18n("Export to XML..."));
+ action->setToolTip(i18n("Export to a Tellico XML file"));
+ action->setIcon(QString::fromLatin1("tellico"));
+ exportMenu->insert(action);
+ connect(action, SIGNAL(activated()), exportMapper, SLOT(map()));
+ exportMapper->setMapping(action, Export::TellicoXML);
+
+ action = new KAction(actionCollection(), "file_export_zip");
+ action->setText(i18n("Export to Zip..."));
+ action->setToolTip(i18n("Export to a Tellico Zip file"));
+ action->setIcon(QString::fromLatin1("tellico"));
+ exportMenu->insert(action);
+ connect(action, SIGNAL(activated()), exportMapper, SLOT(map()));
+ exportMapper->setMapping(action, Export::TellicoZip);
+
+ action = new KAction(actionCollection(), "file_export_html");
+ action->setText(i18n("Export to HTML..."));
+ action->setToolTip(i18n("Export to an HTML file"));
+ action->setIcon(MIME_ICON("text/html"));
+ exportMenu->insert(action);
+ connect(action, SIGNAL(activated()), exportMapper, SLOT(map()));
+ exportMapper->setMapping(action, Export::HTML);
+
+ action = new KAction(actionCollection(), "file_export_csv");
+ action->setText(i18n("Export to CSV..."));
+ action->setToolTip(i18n("Export to a comma-separated values file"));
+ action->setIcon(MIME_ICON("text/x-csv"));
+ exportMenu->insert(action);
+ connect(action, SIGNAL(activated()), exportMapper, SLOT(map()));
+ exportMapper->setMapping(action, Export::CSV);
+
+ action = new KAction(actionCollection(), "file_export_pilotdb");
+ action->setText(i18n("Export to PilotDB..."));
+ action->setToolTip(i18n("Export to a PilotDB database"));
+ action->setIcon(MIME_ICON("application/vnd.palm"));
+ exportMenu->insert(action);
+ connect(action, SIGNAL(activated()), exportMapper, SLOT(map()));
+ exportMapper->setMapping(action, Export::PilotDB);
+
+ action = new KAction(actionCollection(), "file_export_alexandria");
+ action->setText(i18n("Export to Alexandria..."));
+ action->setToolTip(i18n("Export to an Alexandria library"));
+ action->setIcon(QString::fromLatin1("alexandria"));
+ exportMenu->insert(action);
+ connect(action, SIGNAL(activated()), exportMapper, SLOT(map()));
+ exportMapper->setMapping(action, Export::Alexandria);
+
+ action = new KAction(actionCollection(), "file_export_bibtex");
+ action->setText(i18n("Export to Bibtex..."));
+ action->setToolTip(i18n("Export to a bibtex file"));
+ action->setIcon(MIME_ICON("text/x-bibtex"));
+ exportMenu->insert(action);
+ connect(action, SIGNAL(activated()), exportMapper, SLOT(map()));
+ exportMapper->setMapping(action, Export::Bibtex);
+
+ action = new KAction(actionCollection(), "file_export_bibtexml");
+ action->setText(i18n("Export to Bibtexml..."));
+ action->setToolTip(i18n("Export to a Bibtexml file"));
+ action->setIcon(MIME_ICON("text/xml"));
+ exportMenu->insert(action);
+ connect(action, SIGNAL(activated()), exportMapper, SLOT(map()));
+ exportMapper->setMapping(action, Export::Bibtexml);
+
+ action = new KAction(actionCollection(), "file_export_onix");
+ action->setText(i18n("Export to ONIX..."));
+ action->setToolTip(i18n("Export to an ONIX file"));
+ action->setIcon(MIME_ICON("text/xml"));
+ exportMenu->insert(action);
+ connect(action, SIGNAL(activated()), exportMapper, SLOT(map()));
+ exportMapper->setMapping(action, Export::ONIX);
+
+ action = new KAction(actionCollection(), "file_export_gcfilms");
+ action->setText(i18n("Export to GCfilms..."));
+ action->setToolTip(i18n("Export to a GCfilms data file"));
+ action->setIcon(QString::fromLatin1("gcstar"));
+ exportMenu->insert(action);
+ connect(action, SIGNAL(activated()), exportMapper, SLOT(map()));
+ exportMapper->setMapping(action, Export::GCfilms);
+
+#if 0
+ QString dummy1 = i18n("Export to GCstar...");
+ QString dummy2 = i18n("Export to a GCstar data file");
+#endif
+
+ action = new KAction(actionCollection(), "file_export_xslt");
+ action->setText(i18n("Export XSL Transform..."));
+ action->setToolTip(i18n("Export using an XSL Transform"));
+ action->setIcon(MIME_ICON("text/x-xslt"));
+ exportMenu->insert(action);
+ connect(action, SIGNAL(activated()), exportMapper, SLOT(map()));
+ exportMapper->setMapping(action, Export::XSLT);
+
+ /*************************************************
+ * Edit menu
+ *************************************************/
+ action = KStdAction::cut(this, SLOT(slotEditCut()), actionCollection());
+ action->setToolTip(i18n("Cut the selected text and puts it in the clipboard"));
+ action = KStdAction::copy(this, SLOT(slotEditCopy()), actionCollection());
+ action->setToolTip(i18n("Copy the selected text to the clipboard"));
+ action = KStdAction::paste(this, SLOT(slotEditPaste()), actionCollection());
+ action->setToolTip(i18n("Paste the clipboard contents"));
+ action = KStdAction::selectAll(this, SLOT(slotEditSelectAll()), actionCollection());
+ action->setToolTip(i18n("Select all the entries in the collection"));
+ action = KStdAction::deselect(this, SLOT(slotEditDeselect()), actionCollection());
+ action->setToolTip(i18n("Deselect all the entries in the collection"));
+
+ action = new KAction(i18n("Internet Search..."), QString::fromLatin1("wizard"), CTRL + Key_M,
+ this, SLOT(slotShowFetchDialog()),
+ actionCollection(), "edit_search_internet");
+ action->setToolTip(i18n("Search the internet..."));
+
+ action = new KAction(i18n("Advanced &Filter..."), QString::fromLatin1("filter"), CTRL + Key_J,
+ this, SLOT(slotShowFilterDialog()),
+ actionCollection(), "filter_dialog");
+ action->setToolTip(i18n("Filter the collection"));
+
+ /*************************************************
+ * Collection menu
+ *************************************************/
+ m_newEntry = new KAction(i18n("&New Entry..."), QString::fromLatin1("filenew"), CTRL + Key_N,
+ this, SLOT(slotNewEntry()),
+ actionCollection(), "coll_new_entry");
+ m_newEntry->setToolTip(i18n("Create a new entry"));
+ m_editEntry = new KAction(i18n("&Edit Entry..."), QString::fromLatin1("edit"), CTRL + Key_E,
+ this, SLOT(slotShowEntryEditor()),
+ actionCollection(), "coll_edit_entry");
+ m_editEntry->setToolTip(i18n("Edit the selected entries"));
+ m_copyEntry = new KAction(i18n("D&uplicate Entry"), QString::fromLatin1("editcopy"), CTRL + Key_Y,
+ Controller::self(), SLOT(slotCopySelectedEntries()),
+ actionCollection(), "coll_copy_entry");
+ m_copyEntry->setToolTip(i18n("Copy the selected entries"));
+ m_deleteEntry = new KAction(i18n("&Delete Entry"), QString::fromLatin1("editdelete"), CTRL + Key_D,
+ Controller::self(), SLOT(slotDeleteSelectedEntries()),
+ actionCollection(), "coll_delete_entry");
+ m_deleteEntry->setToolTip(i18n("Delete the selected entries"));
+ m_mergeEntry = new KAction(i18n("&Merge Entries"), QString::fromLatin1("editcopy"), CTRL + Key_G,
+ Controller::self(), SLOT(slotMergeSelectedEntries()),
+ actionCollection(), "coll_merge_entry");
+ m_mergeEntry->setToolTip(i18n("Merge the selected entries"));
+ m_mergeEntry->setEnabled(false); // gets enabled when more than 1 entry is selected
+
+ action = new KAction(i18n("&Generate Reports..."), QString::fromLatin1("document"), 0, this,
+ SLOT(slotShowReportDialog()),
+ actionCollection(), "coll_reports");
+ action->setToolTip(i18n("Generate collection reports"));
+ m_checkOutEntry = new KAction(i18n("Check-&out..."), QString::fromLatin1("2uparrow"), 0,
+ Controller::self(), SLOT(slotCheckOut()),
+ actionCollection(), "coll_checkout");
+ m_checkOutEntry->setToolTip(i18n("Check-out the selected items"));
+ m_checkInEntry = new KAction(i18n("Check-&in"), QString::fromLatin1("2downarrow"), 0,
+ Controller::self(), SLOT(slotCheckIn()),
+ actionCollection(), "coll_checkin");
+ m_checkInEntry->setToolTip(i18n("Check-in the selected items"));
+
+ action = new KAction(i18n("&Rename Collection..."), QString::fromLatin1("editclear"), CTRL + Key_R,
+ this, SLOT(slotRenameCollection()),
+ actionCollection(), "coll_rename_collection");
+ action->setToolTip(i18n("Rename the collection"));
+ action = new KAction(i18n("Collection &Fields..."), QString::fromLatin1("edit"), CTRL + Key_U,
+ this, SLOT(slotShowCollectionFieldsDialog()),
+ actionCollection(), "coll_fields");
+ action->setToolTip(i18n("Modify the collection fields"));
+ action = new KAction(i18n("Convert to &Bibliography"), 0,
+ this, SLOT(slotConvertToBibliography()),
+ actionCollection(), "coll_convert_bibliography");
+ action->setToolTip(i18n("Convert a book collection to a bibliography"));
+ action->setIconSet(UserIconSet(QString::fromLatin1("bibtex")));
+ action = new KAction(i18n("String &Macros..."), QString::fromLatin1("view_text"), 0,
+ this, SLOT(slotShowStringMacroDialog()),
+ actionCollection(), "coll_string_macros");
+ action->setToolTip(i18n("Edit the bibtex string macros"));
+
+ QSignalMapper* citeMapper = new QSignalMapper(this);
+ connect(citeMapper, SIGNAL(mapped(int)),
+ this, SLOT(slotCiteEntry(int)));
+
+ action = new KAction(actionCollection(), "cite_clipboard");
+ action->setText(i18n("Copy Bibtex to Cli&pboard"));
+ action->setToolTip(i18n("Copy bibtex citations to the clipboard"));
+ action->setIcon(QString::fromLatin1("editpaste"));
+ connect(action, SIGNAL(activated()), citeMapper, SLOT(map()));
+ citeMapper->setMapping(action, Cite::CiteClipboard);
+
+ action = new KAction(actionCollection(), "cite_lyxpipe");
+ action->setText(i18n("Cite Entry in &LyX"));
+ action->setToolTip(i18n("Cite the selected entries in LyX"));
+ action->setIcon(QString::fromLatin1("lyx"));
+ connect(action, SIGNAL(activated()), citeMapper, SLOT(map()));
+ citeMapper->setMapping(action, Cite::CiteLyxpipe);
+
+ action = new KAction(actionCollection(), "cite_openoffice");
+ action->setText(i18n("Ci&te Entry in OpenOffice.org"));
+ action->setToolTip(i18n("Cite the selected entries in OpenOffice.org"));
+ action->setIcon(QString::fromLatin1("ooo-writer"));
+ connect(action, SIGNAL(activated()), citeMapper, SLOT(map()));
+ citeMapper->setMapping(action, Cite::CiteOpenOffice);
+
+ QSignalMapper* updateMapper = new QSignalMapper(this, "update_mapper");
+ connect(updateMapper, SIGNAL(mapped(const QString&)),
+ Controller::self(), SLOT(slotUpdateSelectedEntries(const QString&)));
+
+ m_updateEntryMenu = new KActionMenu(i18n("&Update Entry"), actionCollection(), "coll_update_entry");
+// m_updateEntryMenu->setIconSet(BarIconSet(QString::fromLatin1("fileexport")));
+ m_updateEntryMenu->setDelayed(false);
+
+ m_updateAll = new KAction(actionCollection(), "update_entry_all");
+ m_updateAll->setText(i18n("All Sources"));
+ m_updateAll->setToolTip(i18n("Update entry data from all available sources"));
+// m_updateEntryMenu->insert(action);
+ connect(m_updateAll, SIGNAL(activated()), updateMapper, SLOT(map()));
+ updateMapper->setMapping(m_updateAll, QString::fromLatin1("_all"));
+
+ /*************************************************
+ * Settings menu
+ *************************************************/
+ setStandardToolBarMenuEnabled(true);
+ createStandardStatusBarAction();
+ KStdAction::configureToolbars(this, SLOT(slotConfigToolbar()), actionCollection());
+ KStdAction::keyBindings(this, SLOT(slotConfigKeys()), actionCollection());
+ m_toggleGroupWidget = new KToggleAction(i18n("Show Grou&p View"), 0,
+ this, SLOT(slotToggleGroupWidget()),
+ actionCollection(), "toggle_group_widget");
+ m_toggleGroupWidget->setToolTip(i18n("Enable/disable the group view"));
+ m_toggleGroupWidget->setCheckedState(i18n("Hide Grou&p View"));
+
+ m_toggleEntryEditor = new KToggleAction(i18n("Show Entry &Editor"), 0,
+ this, SLOT(slotToggleEntryEditor()),
+ actionCollection(), "toggle_edit_widget");
+ m_toggleEntryEditor->setToolTip(i18n("Enable/disable the editor"));
+ m_toggleEntryEditor->setCheckedState(i18n("Hide Entry &Editor"));
+
+ m_toggleEntryView = new KToggleAction(i18n("Show Entry &View"), 0,
+ this, SLOT(slotToggleEntryView()),
+ actionCollection(), "toggle_entry_view");
+ m_toggleEntryView->setToolTip(i18n("Enable/disable the entry view"));
+ m_toggleEntryView->setCheckedState(i18n("Hide Entry &View"));
+
+ KStdAction::preferences(this, SLOT(slotShowConfigDialog()), actionCollection());
+
+ /*************************************************
+ * Help menu
+ *************************************************/
+ KStdAction::tipOfDay(this, SLOT(slotShowTipOfDay()), actionCollection(), "tipOfDay");
+
+ /*************************************************
+ * Collection Toolbar
+ *************************************************/
+ (void) new KAction(i18n("Change Grouping"), CTRL + Key_G,
+ this, SLOT(slotGroupLabelActivated()),
+ actionCollection(), "change_entry_grouping_accel");
+
+ m_entryGrouping = new KSelectAction(i18n("&Group Selection"), 0, this,
+ SLOT(slotChangeGrouping()),
+ actionCollection(), "change_entry_grouping");
+ m_entryGrouping->setToolTip(i18n("Change the grouping of the collection"));
+
+ (void) new KAction(i18n("Filter"), CTRL + Key_F,
+ this, SLOT(slotFilterLabelActivated()),
+ actionCollection(), "quick_filter_accel");
+ (void) new KAction(i18n("Clear Filter"), QString::fromLatin1("locationbar_erase"), 0,
+ this, SLOT(slotClearFilter()),
+ actionCollection(), "quick_filter_clear");
+
+ m_quickFilter = new GUI::LineEdit();
+ m_quickFilter->setHint(i18n("Filter here...")); // same text as kdepim and amarok
+ // about 10 characters wide
+ m_quickFilter->setFixedWidth(m_quickFilter->fontMetrics().maxWidth()*10);
+ // want to update every time the filter text changes
+ connect(m_quickFilter, SIGNAL(textChanged(const QString&)),
+ this, SLOT(slotQueueFilter()));
+
+ KWidgetAction* wAction = new KWidgetAction(m_quickFilter, i18n("Filter"), 0, 0, 0,
+ actionCollection(), "quick_filter");
+ wAction->setToolTip(i18n("Filter the collection"));
+ wAction->setShortcutConfigurable(false);
+ wAction->setAutoSized(true);
+
+ // show tool tips in status bar
+ actionCollection()->setHighlightingEnabled(true);
+ connect(actionCollection(), SIGNAL(actionStatusText(const QString &)),
+ SLOT(slotStatusMsg(const QString &)));
+ connect(actionCollection(), SIGNAL(clearStatusText()),
+ SLOT(slotClearStatus()));
+
+#ifdef UIFILE
+ kdWarning() << "MainWindow::initActions() - change createGUI() call!" << endl;
+ createGUI(UIFILE, false);
+#else
+ createGUI(QString::null, false);
+#endif
+}
+
+void MainWindow::initDocument() {
+ MARK;
+ Data::Document* doc = Data::Document::self();
+
+ KConfigGroup config(KGlobal::config(), "General Options");
+ doc->setLoadAllImages(config.readBoolEntry("Load All Images", false));
+
+ // allow status messages from the document
+ connect(doc, SIGNAL(signalStatusMsg(const QString&)),
+ SLOT(slotStatusMsg(const QString&)));
+
+ // do stuff that changes when the doc is modified
+ connect(doc, SIGNAL(signalModified(bool)),
+ SLOT(slotEnableModifiedActions(bool)));
+
+ connect(Kernel::self()->commandHistory(), SIGNAL(commandExecuted()),
+ doc, SLOT(slotSetModified()));
+ connect(Kernel::self()->commandHistory(), SIGNAL(documentRestored()),
+ doc, SLOT(slotDocumentRestored()));
+}
+
+void MainWindow::initView() {
+ MARK;
+ m_split = new QSplitter(Qt::Horizontal, this);
+ setCentralWidget(m_split);
+
+ m_viewTabs = new GUI::TabControl(m_split);
+ m_viewTabs->setTabBarHidden(true);
+ m_groupView = new GroupView(m_viewTabs, "groupview");
+ Controller::self()->addObserver(m_groupView);
+ m_viewTabs->addTab(m_groupView, SmallIcon(QString::fromLatin1("folder")), i18n("Groups"));
+ QWhatsThis::add(m_groupView, i18n("<qt>The <i>Group View</i> sorts the entries into groupings "
+ "based on a selected field.</qt>"));
+
+ m_rightSplit = new QSplitter(Qt::Vertical, m_split);
+
+ m_detailedView = new DetailedListView(m_rightSplit, "detailedlistview");
+ Controller::self()->addObserver(m_detailedView);
+ QWhatsThis::add(m_detailedView, i18n("<qt>The <i>Column View</i> shows the value of multiple fields "
+ "for each entry.</qt>"));
+ connect(Data::Document::self(), SIGNAL(signalCollectionImagesLoaded(Tellico::Data::CollPtr)),
+ m_detailedView, SLOT(slotRefreshImages()));
+
+ m_viewStack = new ViewStack(m_rightSplit, "viewstack");
+ Controller::self()->addObserver(m_viewStack->iconView());
+ connect(m_viewStack->entryView(), SIGNAL(signalAction(const KURL&)),
+ SLOT(slotURLAction(const KURL&)));
+
+ setMinimumWidth(MAIN_WINDOW_MIN_WIDTH);
+}
+
+void MainWindow::initConnections() {
+ // have to toggle the menu item if the dialog gets closed
+ connect(m_editDialog, SIGNAL(finished()),
+ this, SLOT(slotEditDialogFinished()));
+
+ // let the group view call filters, too
+ connect(m_groupView, SIGNAL(signalUpdateFilter(Tellico::FilterPtr)),
+ Controller::self(), SLOT(slotUpdateFilter(Tellico::FilterPtr)));
+}
+
+void MainWindow::initFileOpen(bool nofile_) {
+ MARK;
+ slotInit();
+ // check to see if most recent file should be opened
+ bool happyStart = false;
+ if(!nofile_ && Config::reopenLastFile()) {
+ // Config::lastOpenFile() is the full URL, protocol included
+ KURL lastFile(Config::lastOpenFile()); // empty string is actually ok, it gets handled
+ if(!lastFile.isEmpty() && lastFile.isValid()) {
+ slotFileOpen(lastFile);
+ happyStart = true;
+ }
+ }
+ if(!happyStart) {
+ // the document is created with an initial book collection, continue with that
+ Controller::self()->slotCollectionAdded(Data::Document::self()->collection());
+
+ m_fileSave->setEnabled(false);
+ slotEnableOpenedActions();
+ slotEnableModifiedActions(false);
+
+ slotEntryCount();
+
+ const int type = Kernel::self()->collectionType();
+ QString welcomeFile = locate("appdata", QString::fromLatin1("welcome.html"));
+ QString text = FileHandler::readTextFile(welcomeFile);
+ text.replace(QString::fromLatin1("$FGCOLOR$"), Config::templateTextColor(type).name());
+ text.replace(QString::fromLatin1("$BGCOLOR$"), Config::templateBaseColor(type).name());
+ text.replace(QString::fromLatin1("$COLOR1$"), Config::templateHighlightedTextColor(type).name());
+ text.replace(QString::fromLatin1("$COLOR2$"), Config::templateHighlightedBaseColor(type).name());
+ text.replace(QString::fromLatin1("$IMGDIR$"), QFile::encodeName(ImageFactory::tempDir()));
+ text.replace(QString::fromLatin1("$BANNER$"),
+ i18n("Welcome to the Tellico Collection Manager"));
+ text.replace(QString::fromLatin1("$WELCOMETEXT$"),
+ i18n("<h3>Tellico is a tool for managing collections of books, "
+ "videos, music, and whatever else you want to catalog.</h3>"
+ "<h3>New entries can be added to your collection by "
+ "<a href=\"tc:///coll_new_entry\">entering data manually</a> or by "
+ "<a href=\"tc:///edit_search_internet\">downloading data</a> from "
+ "various Internet sources.</h3>"));
+ m_viewStack->entryView()->showText(text);
+ }
+ m_initialized = true;
+}
+
+// These are general options.
+// The options that can be changed in the "Configuration..." dialog
+// are taken care of by the ConfigDialog object.
+void MainWindow::saveOptions() {
+// myDebug() << "MainWindow::saveOptions()" << endl;
+
+ saveMainWindowSettings(KGlobal::config(), QString::fromLatin1("Main Window Options"));
+
+ Config::setShowGroupWidget(m_toggleGroupWidget->isChecked());
+ Config::setShowEditWidget(m_toggleEntryEditor->isChecked());
+ Config::setShowEntryView(m_toggleEntryView->isChecked());
+
+ m_fileOpenRecent->saveEntries(KGlobal::config(), QString::fromLatin1("Recent Files"));
+ if(!isNewDocument()) {
+ Config::setLastOpenFile(Data::Document::self()->URL().url());
+ }
+
+ if(m_groupView->isShown()) {
+ Config::setMainSplitterSizes(m_split->sizes());
+ }
+ if(m_viewStack->isShown()) {
+ // badly named option, but no need to change
+ Config::setSecondarySplitterSizes(m_rightSplit->sizes());
+ }
+
+ Config::setGroupViewSortColumn(m_groupView->sortStyle()); // ok to use SortColumn key, save semantics
+ Config::setGroupViewSortAscending(m_groupView->ascendingSort());
+
+ if(m_loanView) {
+ Config::setLoanViewSortAscending(m_loanView->sortStyle()); // ok to use SortColumn key, save semantics
+ Config::setLoanViewSortAscending(m_loanView->ascendingSort());
+ }
+
+ if(m_filterView) {
+ Config::setFilterViewSortAscending(m_filterView->sortStyle()); // ok to use SortColumn key, save semantics
+ Config::setFilterViewSortAscending(m_filterView->ascendingSort());
+ }
+
+ // this is used in the EntryEditDialog constructor, too
+ m_editDialog->saveDialogSize(QString::fromLatin1("Edit Dialog Options"));
+
+ saveCollectionOptions(Data::Document::self()->collection());
+ Config::writeConfig();
+}
+
+void MainWindow::readCollectionOptions(Data::CollPtr coll_) {
+ KConfigGroup group(KGlobal::config(), QString::fromLatin1("Options - %1").arg(coll_->typeName()));
+
+ QString defaultGroup = coll_->defaultGroupField();
+ QString entryGroup;
+ if(coll_->type() != Data::Collection::Base) {
+ entryGroup = group.readEntry("Group By", defaultGroup);
+ } else {
+ KURL url = Kernel::self()->URL();
+ for(uint i = 0; i < Config::maxCustomURLSettings(); ++i) {
+ KURL u = group.readEntry(QString::fromLatin1("URL_%1").arg(i));
+ if(url == u) {
+ entryGroup = group.readEntry(QString::fromLatin1("Group By_%1").arg(i), defaultGroup);
+ break;
+ }
+ }
+ // fall back to old setting
+ if(entryGroup.isEmpty()) {
+ entryGroup = group.readEntry("Group By", defaultGroup);
+ }
+ }
+ if(entryGroup.isEmpty() || !coll_->entryGroups().contains(entryGroup)) {
+ entryGroup = defaultGroup;
+ }
+ m_groupView->setGroupField(entryGroup);
+
+ QString entryXSLTFile = Config::templateName(coll_->type());
+ if(entryXSLTFile.isEmpty()) {
+ entryXSLTFile = QString::fromLatin1("Fancy"); // should never happen, but just in case
+ }
+ m_viewStack->entryView()->setXSLTFile(entryXSLTFile + QString::fromLatin1(".xsl"));
+
+ // make sure the right combo element is selected
+ slotUpdateCollectionToolBar(coll_);
+}
+
+void MainWindow::saveCollectionOptions(Data::CollPtr coll_) {
+ // don't save initial collection options, or empty collections
+ if(!coll_ || coll_->entryCount() == 0 || isNewDocument()) {
+ return;
+ }
+
+ int configIndex = -1;
+ KConfigGroup config(KGlobal::config(), QString::fromLatin1("Options - %1").arg(coll_->typeName()));
+ QString groupName;
+ if(m_entryGrouping->currentItem() > -1 &&
+ static_cast<int>(coll_->entryGroups().count()) > m_entryGrouping->currentItem()) {
+ groupName = Kernel::self()->fieldNameByTitle(m_entryGrouping->currentText());
+ if(coll_->type() != Data::Collection::Base) {
+ config.writeEntry("Group By", groupName);
+ }
+ }
+
+ if(coll_->type() == Data::Collection::Base) {
+ // all of this is to have custom settings on a per file basis
+ KURL url = Kernel::self()->URL();
+ QValueList<KURL> urls = QValueList<KURL>() << url;
+ QStringList groupBys = QStringList() << groupName;
+ for(uint i = 0; i < Config::maxCustomURLSettings(); ++i) {
+ KURL u = config.readEntry(QString::fromLatin1("URL_%1").arg(i));
+ QString g = config.readEntry(QString::fromLatin1("Group By_%1").arg(i));
+ if(!u.isEmpty() && url != u) {
+ urls.append(u);
+ groupBys.append(g);
+ } else if(!u.isEmpty()) {
+ configIndex = i;
+ }
+ }
+ uint limit = QMIN(urls.count(), Config::maxCustomURLSettings());
+ for(uint i = 0; i < limit; ++i) {
+ config.writeEntry(QString::fromLatin1("URL_%1").arg(i), urls[i].url());
+ config.writeEntry(QString::fromLatin1("Group By_%1").arg(i), groupBys[i]);
+ }
+ }
+ m_detailedView->saveConfig(coll_, configIndex);
+}
+
+void MainWindow::readOptions() {
+// myDebug() << "MainWindow::readOptions()" << endl;
+
+ applyMainWindowSettings(KGlobal::config(), QString::fromLatin1("Main Window Options"));
+
+ QValueList<int> splitList = Config::mainSplitterSizes();
+ if(!splitList.empty()) {
+ m_split->setSizes(splitList);
+ }
+
+ splitList = Config::secondarySplitterSizes();
+ if(!splitList.empty()) {
+ m_rightSplit->setSizes(splitList);
+ }
+
+ m_viewStack->iconView()->setMaxAllowedIconWidth(Config::maxIconSize());
+
+ connect(toolBar("collectionToolBar"), SIGNAL(modechange()), SLOT(slotUpdateToolbarIcons()));
+
+ m_toggleGroupWidget->setChecked(Config::showGroupWidget());
+ slotToggleGroupWidget();
+
+ m_toggleEntryView->setChecked(Config::showEntryView());
+ slotToggleEntryView();
+
+ // initialize the recent file list
+ m_fileOpenRecent->loadEntries(KGlobal::config(), QString::fromLatin1("Recent Files"));
+
+ // sort by count if column = 1
+ int sortStyle = Config::groupViewSortColumn();
+ m_groupView->setSortStyle(static_cast<GUI::ListView::SortStyle>(sortStyle));
+ bool sortAscending = Config::groupViewSortAscending();
+ m_groupView->setSortOrder(sortAscending ? Qt::Ascending : Qt::Descending);
+
+ m_detailedView->setPixmapSize(Config::maxPixmapWidth(), Config::maxPixmapHeight());
+
+ bool useBraces = Config::useBraces();
+ if(useBraces) {
+ BibtexHandler::s_quoteStyle = BibtexHandler::BRACES;
+ } else {
+ BibtexHandler::s_quoteStyle = BibtexHandler::QUOTES;
+ }
+
+ // Don't read any options for the edit dialog here, since it's not yet initialized.
+ // Put them in init()
+}
+
+void MainWindow::saveProperties(KConfig* cfg_) {
+ if(!isNewDocument() && !Data::Document::self()->isModified()) {
+ // saving to tempfile not necessary
+ } else {
+ KURL url = Data::Document::self()->URL();
+ cfg_->writeEntry("filename", url.url());
+ cfg_->writeEntry("modified", Data::Document::self()->isModified());
+ QString tempname = KURL::encode_string(kapp->tempSaveName(url.url()));
+ KURL tempurl;
+ tempurl.setPath(tempname);
+ Data::Document::self()->saveDocument(tempurl);
+ }
+}
+
+void MainWindow::readProperties(KConfig* cfg_) {
+ QString filename = cfg_->readEntry(QString::fromLatin1("filename"));
+ bool modified = cfg_->readBoolEntry(QString::fromLatin1("modified"), false);
+ if(modified) {
+ bool canRecover;
+ QString tempname = kapp->checkRecoverFile(filename, canRecover);
+
+ if(canRecover) {
+ KURL tempurl;
+ tempurl.setPath(tempname);
+ Data::Document::self()->openDocument(tempurl);
+ Data::Document::self()->slotSetModified(true);
+ updateCaption(true);
+ QFile::remove(tempname);
+ }
+ } else {
+ if(!filename.isEmpty()) {
+ KURL url;
+ url.setPath(filename);
+ Data::Document::self()->openDocument(url);
+ updateCaption(false);
+ }
+ }
+}
+
+bool MainWindow::queryClose() {
+ // in case we're still loading the images, cancel that
+ Data::Document::self()->cancelImageWriting();
+ return m_editDialog->queryModified() && Data::Document::self()->saveModified();
+}
+
+bool MainWindow::queryExit() {
+ FileHandler::clean();
+ ImageFactory::clean(true);
+ saveOptions();
+ return true;
+}
+
+void MainWindow::slotFileNew(int type_) {
+ slotStatusMsg(i18n("Creating new document..."));
+
+ // close the fields dialog
+ slotHideCollectionFieldsDialog();
+
+ if(m_editDialog->queryModified() && Data::Document::self()->saveModified()) {
+ // remove filter and loan tabs, they'll get re-added if needed
+ if(m_filterView) {
+ m_viewTabs->removePage(m_filterView);
+ Controller::self()->removeObserver(m_filterView);
+ delete m_filterView;
+ m_filterView = 0;
+ }
+ if(m_loanView) {
+ m_viewTabs->removePage(m_loanView);
+ Controller::self()->removeObserver(m_loanView);
+ delete m_loanView;
+ m_loanView = 0;
+ }
+ m_viewTabs->setTabBarHidden(true);
+ Data::Document::self()->newDocument(type_);
+ m_fileOpenRecent->setCurrentItem(-1);
+ slotEnableOpenedActions();
+ slotEnableModifiedActions(false);
+ m_newDocument = true;
+ ImageFactory::clean(false);
+ }
+
+ StatusBar::self()->clearStatus();
+}
+
+void MainWindow::slotFileOpen() {
+ slotStatusMsg(i18n("Opening file..."));
+
+ if(m_editDialog->queryModified() && Data::Document::self()->saveModified()) {
+ QString filter = i18n("*.tc *.bc|Tellico Files (*.tc)");
+ filter += QString::fromLatin1("\n");
+ filter += i18n("*.xml|XML Files (*.xml)");
+ filter += QString::fromLatin1("\n");
+ filter += i18n("*|All Files");
+ // keyword 'open'
+ KURL url = KFileDialog::getOpenURL(QString::fromLatin1(":open"), filter,
+ this, i18n("Open File"));
+ if(!url.isEmpty() && url.isValid()) {
+ slotFileOpen(url);
+ }
+ }
+ StatusBar::self()->clearStatus();
+}
+
+void MainWindow::slotFileOpen(const KURL& url_) {
+ slotStatusMsg(i18n("Opening file..."));
+
+ // close the fields dialog
+ slotHideCollectionFieldsDialog();
+
+ // there seems to be a race condition at start between slotInit() and initFileOpen()
+ // which means the edit dialog might not have been created yet
+ if((!m_editDialog || m_editDialog->queryModified()) && Data::Document::self()->saveModified()) {
+ if(openURL(url_)) {
+ m_fileOpenRecent->addURL(url_);
+ m_fileOpenRecent->setCurrentItem(-1);
+ }
+ }
+
+ StatusBar::self()->clearStatus();
+}
+
+void MainWindow::slotFileOpenRecent(const KURL& url_) {
+ slotStatusMsg(i18n("Opening file..."));
+
+ // close the fields dialog
+ slotHideCollectionFieldsDialog();
+
+ if(m_editDialog->queryModified() && Data::Document::self()->saveModified()) {
+ if(!openURL(url_)) {
+ m_fileOpenRecent->removeURL(url_);
+ m_fileOpenRecent->setCurrentItem(-1);
+ }
+ } else {
+ // the KAction shouldn't be checked now
+ m_fileOpenRecent->setCurrentItem(-1);
+ }
+
+ StatusBar::self()->clearStatus();
+}
+
+void MainWindow::openFile(const QString& file_) {
+ KURL url = KURL::fromPathOrURL(file_);
+ if(!url.isEmpty() && url.isValid()) {
+ slotFileOpen(url);
+ }
+}
+
+bool MainWindow::openURL(const KURL& url_) {
+// myDebug() << "MainWindow::openURL() - " << url_.prettyURL() << endl;
+
+ // try to open document
+ GUI::CursorSaver cs(Qt::waitCursor);
+
+ bool success = Data::Document::self()->openDocument(url_);
+
+ if(success) {
+ m_quickFilter->clear();
+ slotEnableOpenedActions();
+ m_newDocument = false;
+ slotEnableModifiedActions(Data::Document::self()->isModified()); // doc might add some stuff
+ } else if(!m_initialized) {
+ // special case on startup when openURL() is called with a command line argument
+ // and that URL can't be opened. The window still needs to be initialized
+ // the doc object is created with an initial book collection, continue with that
+ Controller::self()->slotCollectionAdded(Data::Document::self()->collection());
+
+ m_fileSave->setEnabled(false);
+ slotEnableOpenedActions();
+ slotEnableModifiedActions(false);
+
+ slotEntryCount();
+ }
+ // slotFileOpen(URL) gets called when opening files on the command line
+ // so go ahead and make sure m_initialized is set.
+ m_initialized = true;
+
+ // remove filter and loan tabs, they'll get re-added if needed
+ if(m_filterView && m_filterView->childCount() == 0) {
+ m_viewTabs->removePage(m_filterView);
+ Controller::self()->removeObserver(m_filterView);
+ delete m_filterView;
+ m_filterView = 0;
+ }
+ if(m_loanView && m_loanView->childCount() == 0) {
+ m_viewTabs->removePage(m_loanView);
+ Controller::self()->removeObserver(m_loanView);
+ delete m_loanView;
+ m_loanView = 0;
+ }
+ Controller::self()->hideTabs(); // does conditional check
+
+ return success;
+}
+
+void MainWindow::slotFileSave() {
+ fileSave();
+}
+
+bool MainWindow::fileSave() {
+ if(!m_editDialog->queryModified()) {
+ return false;
+ }
+ slotStatusMsg(i18n("Saving file..."));
+
+ bool ret = true;
+ if(isNewDocument()) {
+ ret = fileSaveAs();
+ } else {
+ // special check: if there are more than 200 images AND the "Write Images In File" config key
+ // is not set, then warn user that performance may suffer, and write result
+ if(Config::imageLocation() == Config::ImagesInFile &&
+ Config::askWriteImagesInFile() &&
+ Data::Document::self()->imageCount() > MAX_IMAGES_WARN_PERFORMANCE) {
+ QString msg = i18n("<qt><p>You are saving a file with many images, which causes Tellico to "
+ "slow down significantly. Do you want to save the images separately in "
+ "Tellico's data directory to improve performance?</p><p>Your choice can "
+ "always be changed in the configuration dialog.</p></qt>");
+
+ KGuiItem yes(i18n("Save Images Separately"));
+ KGuiItem no(i18n("Save Images in File"));
+
+ int res = KMessageBox::warningYesNo(this, msg, QString::null /* caption */, yes, no);
+ if(res == KMessageBox::No) {
+ Config::setImageLocation(Config::ImagesInAppDir);
+ }
+ Config::setAskWriteImagesInFile(false);
+ }
+
+ GUI::CursorSaver cs(Qt::waitCursor);
+ if(Data::Document::self()->saveDocument(Data::Document::self()->URL())) {
+ m_newDocument = false;
+ updateCaption(false);
+ m_fileSave->setEnabled(false);
+ m_detailedView->resetEntryStatus();
+ } else {
+ ret = false;
+ }
+ }
+
+ StatusBar::self()->clearStatus();
+ return ret;
+}
+
+void MainWindow::slotFileSaveAs() {
+ fileSaveAs();
+}
+
+bool MainWindow::fileSaveAs() {
+ if(!m_editDialog->queryModified()) {
+ return false;
+ }
+
+ slotStatusMsg(i18n("Saving file with a new filename..."));
+
+ QString filter = i18n("*.tc *.bc|Tellico Files (*.tc)");
+ filter += QChar('\n');
+ filter += i18n("*|All Files");
+
+ // keyword 'open'
+ KFileDialog dlg(QString::fromLatin1(":open"), filter, this, "filedialog", true);
+ dlg.setCaption(i18n("Save As"));
+ dlg.setOperationMode(KFileDialog::Saving);
+
+ int result = dlg.exec();
+ if(result == QDialog::Rejected) {
+ StatusBar::self()->clearStatus();
+ return false;
+ }
+
+ bool ret = true;
+ KURL url = dlg.selectedURL();
+ if(!url.isEmpty() && url.isValid()) {
+ GUI::CursorSaver cs(Qt::waitCursor);
+ if(Data::Document::self()->saveDocument(url)) {
+ KRecentDocument::add(url);
+ m_fileOpenRecent->addURL(url);
+ updateCaption(false);
+ m_newDocument = false;
+ m_fileSave->setEnabled(false);
+ m_detailedView->resetEntryStatus();
+ } else {
+ ret = false;
+ }
+ }
+
+ StatusBar::self()->clearStatus();
+ return ret;
+}
+
+void MainWindow::slotFilePrint() {
+ slotStatusMsg(i18n("Printing..."));
+
+ bool printGrouped = Config::printGrouped();
+ bool printHeaders = Config::printFieldHeaders();
+ int imageWidth = Config::maxImageWidth();
+ int imageHeight = Config::maxImageHeight();
+
+ // If the collection is being filtered, warn the user
+ if(m_detailedView->filter() != 0) {
+ QString str = i18n("The collection is currently being filtered to show a limited subset of "
+ "the entries. Only the visible entries will be printed. Continue?");
+ int ret = KMessageBox::warningContinueCancel(this, str, QString::null, KStdGuiItem::print(),
+ QString::fromLatin1("WarnPrintVisible"));
+ if(ret == KMessageBox::Cancel) {
+ StatusBar::self()->clearStatus();
+ return;
+ }
+ }
+
+ GUI::CursorSaver cs(Qt::waitCursor);
+
+ Export::HTMLExporter exporter(Data::Document::self()->collection());
+ // only print visible entries
+ exporter.setEntries(m_detailedView->visibleEntries());
+ exporter.setXSLTFile(QString::fromLatin1("tellico-printing.xsl"));
+ exporter.setPrintHeaders(printHeaders);
+ exporter.setPrintGrouped(printGrouped);
+ exporter.setGroupBy(Controller::self()->expandedGroupBy());
+ if(!printGrouped) { // the sort titles are only used if the entries are not grouped
+ exporter.setSortTitles(Controller::self()->sortTitles());
+ }
+ exporter.setColumns(m_detailedView->visibleColumns());
+ exporter.setMaxImageSize(imageWidth, imageHeight);
+
+ slotStatusMsg(i18n("Processing document..."));
+ if(Config::printFormatted()) {
+ exporter.setOptions(Export::ExportUTF8 | Export::ExportFormatted);
+ } else {
+ exporter.setOptions(Export::ExportUTF8);
+ }
+ QString html = exporter.text();
+ if(html.isEmpty()) {
+ XSLTError();
+ StatusBar::self()->clearStatus();
+ return;
+ }
+
+ // don't have busy cursor when showing the print dialog
+ cs.restore();
+// myDebug() << html << endl;
+ slotStatusMsg(i18n("Printing..."));
+ doPrint(html);
+
+ StatusBar::self()->clearStatus();
+}
+
+void MainWindow::slotFileQuit() {
+ slotStatusMsg(i18n("Exiting..."));
+
+ // this gets called in queryExit() anyway
+ //saveOptions();
+ close();
+
+ StatusBar::self()->clearStatus();
+}
+
+void MainWindow::slotEditCut() {
+ activateEditSlot(SLOT(cut()));
+}
+
+void MainWindow::slotEditCopy() {
+ activateEditSlot(SLOT(copy()));
+}
+
+void MainWindow::slotEditPaste() {
+ activateEditSlot(SLOT(paste()));
+}
+
+void MainWindow::activateEditSlot(const char* slot_) {
+ // the edit widget is the only one that copies, cuts, and pastes
+ QWidget* w;
+ if(m_editDialog->isVisible()) {
+ w = m_editDialog->focusWidget();
+ } else {
+ w = kapp->focusWidget();
+ }
+
+ if(w && w->isVisible()) {
+ QMetaObject* meta = w->metaObject();
+
+ int idx = meta->findSlot(slot_ + 1, true);
+ if(idx > -1) {
+ w->qt_invoke(idx, 0);
+ }
+ }
+}
+
+void MainWindow::slotEditSelectAll() {
+ m_detailedView->selectAllVisible();
+}
+
+void MainWindow::slotEditDeselect() {
+ Controller::self()->slotUpdateSelection(0, Data::EntryVec());
+}
+
+void MainWindow::slotConfigToolbar() {
+ saveMainWindowSettings(KGlobal::config(), QString::fromLatin1("Main Window Options"));
+#ifdef UIFILE
+ KEditToolbar dlg(actionCollection(), UIFILE);
+#else
+ KEditToolbar dlg(actionCollection());
+#endif
+ connect(&dlg, SIGNAL(newToolbarConfig()), this, SLOT(slotNewToolbarConfig()));
+ dlg.exec();
+}
+
+void MainWindow::slotNewToolbarConfig() {
+ applyMainWindowSettings(KGlobal::config(), QString::fromLatin1("Main Window Options"));
+#ifdef UIFILE
+ createGUI(UIFILE, false);
+#else
+ createGUI(QString::null, false);
+#endif
+}
+
+void MainWindow::slotConfigKeys() {
+ KKeyDialog::configure(actionCollection());
+}
+
+void MainWindow::slotToggleGroupWidget() {
+ if(m_toggleGroupWidget->isChecked()) {
+ m_viewTabs->show();
+ } else {
+ m_viewTabs->hide();
+ }
+}
+
+void MainWindow::slotToggleEntryEditor() {
+ if(m_toggleEntryEditor->isChecked()) {
+ m_editDialog->show();
+ } else {
+ m_editDialog->hide();
+ }
+}
+
+void MainWindow::slotToggleEntryView() {
+ if(m_toggleEntryView->isChecked()) {
+ m_viewStack->show();
+ } else {
+ m_viewStack->hide();
+ }
+}
+
+void MainWindow::slotShowConfigDialog() {
+ if(!m_configDlg) {
+ m_configDlg = new ConfigDialog(this);
+ m_configDlg->show();
+ m_configDlg->readConfiguration();
+ connect(m_configDlg, SIGNAL(signalConfigChanged()),
+ SLOT(slotHandleConfigChange()));
+ connect(m_configDlg, SIGNAL(finished()),
+ SLOT(slotHideConfigDialog()));
+ } else {
+ KWin::activateWindow(m_configDlg->winId());
+ m_configDlg->show();
+ }
+}
+
+void MainWindow::slotHideConfigDialog() {
+ if(m_configDlg) {
+ m_configDlg->delayedDestruct();
+ m_configDlg = 0;
+ }
+}
+
+void MainWindow::slotShowTipOfDay(bool force_/*=true*/) {
+ QString tipfile = locate("appdata", QString::fromLatin1("tellico.tips"));
+ KTipDialog::showTip(this, tipfile, force_);
+}
+
+void MainWindow::slotStatusMsg(const QString& text_) {
+ m_statusBar->setStatus(text_);
+}
+
+void MainWindow::slotClearStatus() {
+ StatusBar::self()->clearStatus();
+}
+
+void MainWindow::slotEntryCount() {
+ Data::CollPtr coll = Data::Document::self()->collection();
+ if(!coll) {
+ return;
+ }
+
+ int count = coll->entryCount();
+ QString text = i18n("Total entries: %1").arg(count);
+
+ int selectCount = Controller::self()->selectedEntries().count();
+ int filterCount = m_detailedView->visibleItems();
+ // if more than one book is selected, add the number of selected books
+ if(filterCount < count && selectCount > 1) {
+ text += QChar(' ');
+ text += i18n("(%1 filtered; %2 selected)").arg(filterCount).arg(selectCount);
+ } else if(filterCount < count) {
+ text += QChar(' ');
+ text += i18n("(%1 filtered)").arg(filterCount);
+ } else if(selectCount > 1) {
+ text += QChar(' ');
+ text += i18n("(%1 selected)").arg(selectCount);
+ }
+
+ m_statusBar->setCount(text);
+}
+
+void MainWindow::slotEnableOpenedActions() {
+ slotUpdateToolbarIcons();
+
+ // collapse all the groups (depth=1)
+ m_groupView->slotCollapseAll(1);
+
+ updateCollectionActions();
+
+ // close the filter dialog when a new collection is opened
+ slotHideFilterDialog();
+ slotHideStringMacroDialog();
+}
+
+void MainWindow::slotEnableModifiedActions(bool modified_ /*= true*/) {
+ updateCaption(modified_);
+ updateCollectionActions();
+ m_fileSave->setEnabled(modified_);
+}
+
+void MainWindow::slotHandleConfigChange() {
+ const int imageLocation = Config::imageLocation();
+ const bool autoCapitalize = Config::autoCapitalization();
+ const bool autoFormat = Config::autoFormat();
+ QStringList articles = Config::articleList();
+ QStringList nocaps = Config::noCapitalizationList();
+ QStringList suffixes = Config::nameSuffixList();
+ QStringList prefixes = Config::surnamePrefixList();
+
+ m_configDlg->saveConfiguration();
+
+ // only modified if there are entries and image location is changed
+ if(imageLocation != Config::imageLocation() && !Data::Document::self()->isEmpty()) {
+ Data::Document::self()->slotSetModified();
+ }
+
+ if(autoCapitalize != Config::autoCapitalization() ||
+ autoFormat != Config::autoFormat() ||
+ articles != Config::articleList() ||
+ nocaps != Config::noCapitalizationList() ||
+ suffixes != Config::nameSuffixList() ||
+ prefixes != Config::surnamePrefixList()) {
+ // invalidate all groups
+ Data::Document::self()->collection()->invalidateGroups();
+ // refreshing the title causes the group view to refresh
+ Controller::self()->slotRefreshField(Data::Document::self()->collection()->fieldByName(QString::fromLatin1("title")));
+ }
+
+ QString entryXSLTFile = Config::templateName(Kernel::self()->collectionType());
+ m_viewStack->entryView()->setXSLTFile(entryXSLTFile + QString::fromLatin1(".xsl"));
+}
+
+void MainWindow::slotUpdateCollectionToolBar(Data::CollPtr coll_) {
+// myDebug() << "MainWindow::updateCollectionToolBar()" << endl;
+
+ if(!coll_) {
+ kdWarning() << "MainWindow::slotUpdateCollectionToolBar() - no collection pointer!" << endl;
+ return;
+ }
+
+ QString current = m_groupView->groupBy();
+ if(current.isEmpty() || !coll_->entryGroups().contains(current)) {
+ current = coll_->defaultGroupField();
+ }
+
+ const QStringList groups = coll_->entryGroups();
+ if(groups.isEmpty()) {
+ m_entryGrouping->clear();
+ return;
+ }
+
+ QMap<QString, QString> groupMap; // use a map so they get sorted
+ for(QStringList::ConstIterator groupIt = groups.begin(); groupIt != groups.end(); ++groupIt) {
+ // special case for people "pseudo-group"
+ if(*groupIt == Data::Collection::s_peopleGroupName) {
+ groupMap.insert(*groupIt, QString::fromLatin1("<") + i18n("People") + QString::fromLatin1(">"));
+ } else {
+ groupMap.insert(*groupIt, coll_->fieldTitleByName(*groupIt));
+ }
+ }
+
+ QStringList names = groupMap.keys();
+ int index = names.findIndex(current);
+ if(index == -1) {
+ current = names[0];
+ index = 0;
+ }
+ QStringList titles = groupMap.values();
+ m_entryGrouping->setItems(titles);
+ m_entryGrouping->setCurrentItem(index);
+ // in case the current grouping field get modified to be non-grouping...
+ m_groupView->setGroupField(current); // don't call slotChangeGrouping() since it adds an undo item
+
+ // this isn't really proper, but works so the combo box width gets adjusted
+ const int len = m_entryGrouping->containerCount();
+ for(int i = 0; i < len; ++i) {
+ KToolBar* tb = dynamic_cast<KToolBar*>(m_entryGrouping->container(i));
+ if(tb) {
+ KComboBox* cb = tb->getCombo(m_entryGrouping->itemId(i));
+ if(cb) {
+ // qt caches the combobox size and never recalculates the sizeHint()
+ // the source code recommends calling setFont to invalidate the sizeHint
+ cb->setFont(cb->font());
+ cb->updateGeometry();
+ }
+ }
+ }
+}
+
+void MainWindow::slotChangeGrouping() {
+// myDebug() << "MainWindow::slotChangeGrouping()" << endl;
+ QString title = m_entryGrouping->currentText();
+
+ QString groupName = Kernel::self()->fieldNameByTitle(title);
+ if(groupName.isEmpty()) {
+ if(title == QString::fromLatin1("<") + i18n("People") + QString::fromLatin1(">")) {
+ groupName = Data::Collection::s_peopleGroupName;
+ } else {
+ groupName = Data::Document::self()->collection()->defaultGroupField();
+ }
+ }
+ m_groupView->setGroupField(groupName);
+ m_viewTabs->showPage(m_groupView);
+}
+
+void MainWindow::slotShowReportDialog() {
+// myDebug() << "MainWindow::slotShowReport()" << endl;
+ if(!m_reportDlg) {
+ m_reportDlg = new ReportDialog(this);
+ connect(m_reportDlg, SIGNAL(finished()),
+ SLOT(slotHideReportDialog()));
+ } else {
+ KWin::activateWindow(m_reportDlg->winId());
+ }
+ m_reportDlg->show();
+}
+
+void MainWindow::slotHideReportDialog() {
+ if(m_reportDlg) {
+ m_reportDlg->delayedDestruct();
+ m_reportDlg = 0;
+ }
+}
+
+void MainWindow::doPrint(const QString& html_) {
+ KHTMLPart w ;
+ w.setJScriptEnabled(false);
+ w.setJavaEnabled(false);
+ w.setMetaRefreshEnabled(false);
+ w.setPluginsEnabled(false);
+ w.begin(Data::Document::self()->URL());
+ w.write(html_);
+ w.end();
+
+// the problem with doing my own layout is that the text gets truncated, both at the
+// top and at the bottom. Even adding the overlap parameter, there were problems.
+// KHTMLView takes care of that with a truncatedAt() parameter, but that's hidden in
+// the khtml::render_root class. So for now, just use the KHTMLView::print() method.
+#if 1
+ w.view()->print();
+#else
+ KPrinter* printer = new KPrinter(QPrinter::PrinterResolution);
+
+ if(printer->setup(this, i18n("Print %1").arg(Data::Document::self()->URL().prettyURL()))) {
+ printer->setFullPage(false);
+ printer->setCreator(QString::fromLatin1("Tellico"));
+ printer->setDocName(Data::Document::self()->URL().prettyURL());
+
+ QPainter *p = new QPainter;
+ p->begin(printer);
+
+ // mostly taken from KHTMLView::print()
+ QString headerLeft = KGlobal::locale()->formatDate(QDate::currentDate(), false);
+ QString headerRight = Data::Document::self()->URL().prettyURL();
+ QString footerMid;
+
+ QFont headerFont(QString::fromLatin1("helvetica"), 8);
+ p->setFont(headerFont);
+ const int lspace = p->fontMetrics().lineSpacing();
+ const int headerHeight = (lspace * 3) / 2;
+
+ QPaintDeviceMetrics metrics(printer);
+ const int pageHeight = metrics.height() - 2*headerHeight;
+ const int pageWidth = metrics.width();
+
+// myDebug() << "MainWindow::doPrint() - pageHeight = " << pageHeight << ""
+// "; contentsHeight = " << w->view()->contentsHeight() << endl;
+
+ int top = 0;
+ int page = 1;
+
+ bool more = true;
+ while(more) {
+ p->setPen(Qt::black);
+ p->setFont(headerFont);
+
+ footerMid = i18n("Page %1").arg(page);
+
+ p->drawText(0, 0, pageWidth, lspace, Qt::AlignLeft, headerLeft);
+ p->drawText(0, 0, pageWidth, lspace, Qt::AlignRight, headerRight);
+ p->drawText(0, pageHeight+headerHeight, pageWidth, lspace, Qt::AlignHCenter, footerMid);
+
+ w->paint(p, QRect(0, -top + 2*headerHeight, pageWidth, pageHeight+top), top, &more);
+
+ top += pageHeight - PRINTED_PAGE_OVERLAP;
+
+ if(more) {
+ printer->newPage();
+ page++;
+ }
+// p->resetXForm();
+ }
+ // stop painting, this will automatically send the print data to the printer
+ p->end();
+ delete p;
+ }
+
+ delete printer;
+#endif
+}
+
+void MainWindow::XSLTError() {
+ QString str = i18n("Tellico encountered an error in XSLT processing.") + QChar('\n');
+ str += i18n("Please check your installation.");
+ Kernel::self()->sorry(str);
+}
+
+void MainWindow::slotShowFilterDialog() {
+ if(!m_filterDlg) {
+ m_filterDlg = new FilterDialog(FilterDialog::CreateFilter, this); // allow saving
+ m_filterDlg->setFilter(m_detailedView->filter());
+ m_quickFilter->setEnabled(false);
+ connect(m_filterDlg, SIGNAL(signalCollectionModified()),
+ Data::Document::self(), SLOT(slotSetModified()));
+ connect(m_filterDlg, SIGNAL(signalUpdateFilter(Tellico::FilterPtr)),
+ m_quickFilter, SLOT(clear()));
+ connect(m_filterDlg, SIGNAL(signalUpdateFilter(Tellico::FilterPtr)),
+ Controller::self(), SLOT(slotUpdateFilter(Tellico::FilterPtr)));
+ connect(m_filterDlg, SIGNAL(finished()),
+ SLOT(slotHideFilterDialog()));
+ } else {
+ KWin::activateWindow(m_filterDlg->winId());
+ }
+ m_filterDlg->show();
+}
+
+void MainWindow::slotHideFilterDialog() {
+// m_quickFilter->blockSignals(false);
+ m_quickFilter->setEnabled(true);
+ if(m_filterDlg) {
+ m_filterDlg->delayedDestruct();
+ m_filterDlg = 0;
+ }
+}
+
+void MainWindow::slotQueueFilter() {
+ m_queuedFilters++;
+ QTimer::singleShot(200, this, SLOT(slotUpdateFilter()));
+}
+
+void MainWindow::slotUpdateFilter() {
+ m_queuedFilters--;
+ if(m_queuedFilters > 0) {
+ return;
+ }
+
+ setFilter(m_quickFilter->text());
+}
+
+void MainWindow::setFilter(const QString& text_) {
+ QString text = text_.stripWhiteSpace();
+ Filter::Ptr filter = 0;
+ if(!text.isEmpty()) {
+ filter = new Filter(Filter::MatchAll);
+ QString fieldName = QString::null;
+ // if the text contains '=' assume it's a field name or title
+ if(text.find('=') > -1) {
+ fieldName = text.section('=', 0, 0).stripWhiteSpace();
+ text = text.section('=', 1).stripWhiteSpace();
+ // check that the field name might be a title
+ if(!Data::Document::self()->collection()->hasField(fieldName)) {
+ fieldName = Data::Document::self()->collection()->fieldNameByTitle(fieldName);
+ }
+ }
+ // if the text contains any non-word characters, assume it's a regexp
+ // but \W in qt is letter, number, or '_', I want to be a bit less strict
+ QRegExp rx(QString::fromLatin1("[^\\w\\s-']"));
+ if(text.find(rx) == -1) {
+ // split by whitespace, and add rules for each word
+ QStringList tokens = QStringList::split(QRegExp(QString::fromLatin1("\\s")), text);
+ for(QStringList::Iterator it = tokens.begin(); it != tokens.end(); ++it) {
+ // an empty field string means check every field
+ filter->append(new FilterRule(fieldName, *it, FilterRule::FuncContains));
+ }
+ } else {
+ // if it isn't valid, hold off on applying the filter
+ QRegExp tx(text);
+ if(!tx.isValid()) {
+ myDebug() << "MainWindow::slotUpdateFilter() - invalid regexp: " << text << endl;
+ return;
+ }
+ filter->append(new FilterRule(fieldName, text, FilterRule::FuncRegExp));
+ }
+ // also want to update the line edit in case the filter was set by DCOP
+ if(m_quickFilter->text().isEmpty() && m_quickFilter->text() != text_) {
+ m_quickFilter->setText(text_);
+ }
+ }
+ // only update filter if one exists or did exist
+ if(filter || m_detailedView->filter()) {
+ Controller::self()->slotUpdateFilter(filter);
+ }
+}
+
+void MainWindow::slotShowCollectionFieldsDialog() {
+ if(!m_collFieldsDlg) {
+ m_collFieldsDlg = new CollectionFieldsDialog(Data::Document::self()->collection(), this);
+ connect(m_collFieldsDlg, SIGNAL(finished()),
+ SLOT(slotHideCollectionFieldsDialog()));
+ } else {
+ KWin::activateWindow(m_collFieldsDlg->winId());
+ }
+ m_collFieldsDlg->show();
+}
+
+void MainWindow::slotHideCollectionFieldsDialog() {
+ if(m_collFieldsDlg) {
+ m_collFieldsDlg->delayedDestruct();
+ m_collFieldsDlg = 0;
+ }
+}
+
+void MainWindow::slotFileImport(int format_) {
+ slotStatusMsg(i18n("Importing data..."));
+ m_quickFilter->clear();
+
+ Import::Format format = static_cast<Import::Format>(format_);
+ bool checkURL = true;
+ KURL url;
+ switch(ImportDialog::importTarget(format)) {
+ case Import::File:
+ url = KFileDialog::getOpenURL(ImportDialog::startDir(format), ImportDialog::fileFilter(format),
+ this, i18n("Import File"));
+ break;
+
+ case Import::Dir:
+ // TODO: allow remote audiofile importing
+ url.setPath(KFileDialog::getExistingDirectory(ImportDialog::startDir(format),
+ this, i18n("Import Directory")));
+ break;
+
+ case Import::None:
+ default:
+ checkURL = false;
+ break;
+ }
+
+ if(checkURL) {
+ bool ok = !url.isEmpty() && url.isValid() && KIO::NetAccess::exists(url, true, this);
+ if(!ok) {
+ StatusBar::self()->clearStatus();
+ return;
+ }
+ }
+ importFile(format, url);
+ StatusBar::self()->clearStatus();
+}
+
+void MainWindow::slotFileExport(int format_) {
+ slotStatusMsg(i18n("Exporting data..."));
+
+ Export::Format format = static_cast<Export::Format>(format_);
+ ExportDialog dlg(format, Data::Document::self()->collection(), this, "exportdialog");
+
+ if(dlg.exec() == QDialog::Rejected) {
+ StatusBar::self()->clearStatus();
+ return;
+ }
+
+ switch(ExportDialog::exportTarget(format)) {
+ case Export::None:
+ dlg.exportURL();
+ break;
+
+ case Export::Dir:
+ myDebug() << "MainWindow::slotFileExport() - ExportDir not implemented!" << endl;
+ break;
+
+ case Export::File:
+ {
+ KFileDialog fileDlg(QString::fromLatin1(":export"), dlg.fileFilter(), this, "filedialog", true);
+ fileDlg.setCaption(i18n("Export As"));
+ fileDlg.setOperationMode(KFileDialog::Saving);
+
+ if(fileDlg.exec() == QDialog::Rejected) {
+ StatusBar::self()->clearStatus();
+ return;
+ }
+
+ KURL url = fileDlg.selectedURL();
+ if(!url.isEmpty() && url.isValid()) {
+ GUI::CursorSaver cs(Qt::waitCursor);
+ dlg.exportURL(url);
+ }
+ }
+ break;
+ }
+
+ StatusBar::self()->clearStatus();
+}
+
+void MainWindow::slotShowStringMacroDialog() {
+ if(Data::Document::self()->collection()->type() != Data::Collection::Bibtex) {
+ return;
+ }
+
+ if(!m_stringMacroDlg) {
+ const Data::BibtexCollection* c = static_cast<Data::BibtexCollection*>(Data::Document::self()->collection().data());
+ m_stringMacroDlg = new StringMapDialog(c->macroList(), this, "StringMacroDialog", false);
+ m_stringMacroDlg->setCaption(i18n("String Macros"));
+ m_stringMacroDlg->setLabels(i18n("Macro"), i18n("String"));
+ connect(m_stringMacroDlg, SIGNAL(finished()), SLOT(slotHideStringMacroDialog()));
+ connect(m_stringMacroDlg, SIGNAL(okClicked()), SLOT(slotStringMacroDialogOk()));
+ } else {
+ KWin::activateWindow(m_stringMacroDlg->winId());
+ }
+ m_stringMacroDlg->show();
+}
+
+void MainWindow::slotHideStringMacroDialog() {
+ if(m_stringMacroDlg) {
+ m_stringMacroDlg->delayedDestruct();
+ m_stringMacroDlg = 0;
+ }
+}
+
+void MainWindow::slotStringMacroDialogOk() {
+ // no point in checking if collection is bibtex, as dialog would never have been created
+ if(m_stringMacroDlg) {
+ static_cast<Data::BibtexCollection*>(Data::Document::self()->collection().data())->setMacroList(m_stringMacroDlg->stringMap());
+ Data::Document::self()->slotSetModified(true);
+ }
+}
+
+void MainWindow::slotNewEntry() {
+ m_toggleEntryEditor->setChecked(true);
+ slotToggleEntryEditor();
+ m_editDialog->slotHandleNew();
+}
+
+void MainWindow::slotEditDialogFinished() {
+ m_toggleEntryEditor->setChecked(false);
+}
+
+void MainWindow::slotShowEntryEditor() {
+ m_toggleEntryEditor->setChecked(true);
+ m_editDialog->show();
+
+ KWin::activateWindow(m_editDialog->winId());
+}
+
+void MainWindow::slotConvertToBibliography() {
+ // only book collections can be converted to bibtex
+ Data::CollPtr coll = Data::Document::self()->collection();
+ if(!coll || coll->type() != Data::Collection::Book) {
+ return;
+ }
+
+ GUI::CursorSaver cs;
+
+ Data::CollPtr newColl = Data::BibtexCollection::convertBookCollection(coll);
+ if(newColl) {
+ m_newDocument = true;
+ Kernel::self()->replaceCollection(newColl);
+ m_fileOpenRecent->setCurrentItem(-1);
+ slotUpdateToolbarIcons();
+ updateCollectionActions();
+ } else {
+ kdWarning() << "MainWindow::slotConvertToBibliography() - ERROR: no bibliography created!" << endl;
+ }
+}
+
+void MainWindow::slotCiteEntry(int action_) {
+ StatusBar::self()->setStatus(i18n("Creating citations..."));
+ Cite::ActionManager::self()->cite(static_cast<Cite::CiteAction>(action_), Controller::self()->selectedEntries());
+ StatusBar::self()->clearStatus();
+}
+
+void MainWindow::slotShowFetchDialog() {
+ if(!m_fetchDlg) {
+ m_fetchDlg = new FetchDialog(this);
+ connect(m_fetchDlg, SIGNAL(finished()), SLOT(slotHideFetchDialog()));
+ connect(Controller::self(), SIGNAL(collectionAdded(int)), m_fetchDlg, SLOT(slotResetCollection()));
+ } else {
+ KWin::activateWindow(m_fetchDlg->winId());
+ }
+ m_fetchDlg->show();
+}
+
+void MainWindow::slotHideFetchDialog() {
+ if(m_fetchDlg) {
+ m_fetchDlg->delayedDestruct();
+ m_fetchDlg = 0;
+ }
+}
+
+bool MainWindow::importFile(Import::Format format_, const KURL& url_, Import::Action action_) {
+ // try to open document
+ GUI::CursorSaver cs(Qt::waitCursor);
+
+ bool failed = false;
+ Data::CollPtr coll;
+ if(!url_.isEmpty() && url_.isValid() && KIO::NetAccess::exists(url_, true, this)) {
+ coll = ImportDialog::importURL(format_, url_);
+ } else {
+ Kernel::self()->sorry(i18n(errorLoad).arg(url_.fileName()));
+ failed = true;
+ }
+
+ if(!coll && !m_initialized) {
+ // special case on startup when openURL() is called with a command line argument
+ // and that URL can't be opened. The window still needs to be initialized
+ // the doc object is created with an initial book collection, continue with that
+ Controller::self()->slotCollectionAdded(Data::Document::self()->collection());
+ m_fileSave->setEnabled(false);
+ slotEnableOpenedActions();
+ slotEnableModifiedActions(false);
+ slotEntryCount();
+ m_fileOpenRecent->setCurrentItem(-1);
+ m_initialized = true;
+ failed = true;
+ } else if(coll) {
+ // this is rather dumb, but I'm too lazy to find the bug
+ // if the document isn't initialized, then Tellico crashes
+ // since Document::replaceCollection() ends up calling lots of stuff that isn't initialized
+ if(!m_initialized) {
+ Controller::self()->slotCollectionAdded(Data::Document::self()->collection());
+ m_initialized = true;
+ }
+ failed = !importCollection(coll, action_);
+ }
+
+ StatusBar::self()->clearStatus();
+ return !failed; // return true means success
+}
+
+bool MainWindow::exportCollection(Export::Format format_, const KURL& url_) {
+ if(!url_.isValid()) {
+ myDebug() << "MainWindow::exportCollection() - invalid URL: " << url_.url() << endl;
+ return false;
+ }
+
+ GUI::CursorSaver cs;
+ const Data::CollPtr c = Data::Document::self()->collection();
+ if(!c) {
+ return false;
+ }
+
+ // only bibliographies can export to bibtex or bibtexml
+ bool isBibtex = (c->type() == Data::Collection::Bibtex);
+ if(!isBibtex && (format_ == Export::Bibtex || format_ == Export::Bibtexml)) {
+ return false;
+ }
+ // only books and bibliographies can export to alexandria
+ bool isBook = (c->type() == Data::Collection::Book);
+ if(!isBibtex && !isBook && format_ == Export::Alexandria) {
+ return false;
+ }
+
+ bool success = ExportDialog::exportCollection(format_, url_);
+ return success;
+}
+
+bool MainWindow::showEntry(long id) {
+ Data::EntryPtr entry = Data::Document::self()->collection()->entryById(id);
+ if(entry) {
+ m_viewStack->showEntry(entry);
+ }
+ return entry != 0;
+}
+
+void MainWindow::addFilterView() {
+ if(m_filterView) {
+ return;
+ }
+
+ m_filterView = new FilterView(m_viewTabs, "filterview");
+ Controller::self()->addObserver(m_filterView);
+ m_viewTabs->insertTab(m_filterView, SmallIcon(QString::fromLatin1("filter")), i18n("Filters"), 1);
+ QWhatsThis::add(m_filterView, i18n("<qt>The <i>Filter View</i> shows the entries which meet certain "
+ "filter rules.</qt>"));
+
+ int sortStyle = Config::filterViewSortColumn();
+ m_filterView->setSortStyle(static_cast<GUI::ListView::SortStyle>(sortStyle));
+ bool sortAscending = Config::filterViewSortAscending();
+ m_filterView->setSortOrder(sortAscending ? Qt::Ascending : Qt::Descending);
+}
+
+void MainWindow::addLoanView() {
+ if(m_loanView) {
+ return;
+ }
+
+ m_loanView = new LoanView(m_viewTabs, "loanview");
+ Controller::self()->addObserver(m_loanView);
+ m_viewTabs->insertTab(m_loanView, SmallIcon(QString::fromLatin1("kaddressbook")), i18n("Loans"), 2);
+ QWhatsThis::add(m_loanView, i18n("<qt>The <i>Loan View</i> shows a list of all the people who "
+ "have borrowed items from your collection.</qt>"));
+
+ int sortStyle = Config::loanViewSortColumn();
+ m_loanView->setSortStyle(static_cast<GUI::ListView::SortStyle>(sortStyle));
+ bool sortAscending = Config::loanViewSortAscending();
+ m_loanView->setSortOrder(sortAscending ? Qt::Ascending : Qt::Descending);
+}
+
+void MainWindow::updateCaption(bool modified_) {
+ QString caption;
+ if(Data::Document::self()->collection()) {
+ caption = Data::Document::self()->collection()->title();
+ }
+ if(!m_newDocument) {
+ if(!caption.isEmpty()) {
+ caption += QString::fromLatin1(" - ");
+ }
+ KURL u = Data::Document::self()->URL();
+ if(u.isLocalFile()) {
+ // for new files, the path is set to /Untitled in Data::Document
+ if(u.path() == '/' + i18n("Untitled")) {
+ caption += u.fileName();
+ } else {
+ caption += u.path();
+ }
+ } else {
+ caption += u.prettyURL();
+ }
+ }
+ setCaption(caption, modified_);
+}
+
+void MainWindow::slotUpdateToolbarIcons() {
+ // myDebug() << "MainWindow::slotUpdateToolbarIcons() " << endl;
+ // first change the icon for the menu item
+ m_newEntry->setIconSet(UserIconSet(Kernel::self()->collectionTypeName()));
+
+ // since the toolbar icon is probably a different size than the menu item icon
+ // superimpose it on the "mime_empty" icon
+ KToolBar* tb = toolBar("collectionToolBar");
+ if(!tb) {
+ return;
+ }
+
+ for(int i = 0; i < tb->count(); ++i) {
+ if(m_newEntry->isPlugged(tb, tb->idAt(i))) {
+ QIconSet icons;
+ icons.installIconFactory(new EntryIconFactory(tb->iconSize()));
+ tb->setButtonIconSet(tb->idAt(i), icons);
+ break;
+ }
+ }
+}
+
+void MainWindow::slotGroupLabelActivated() {
+ // need entry grouping combo id
+ KToolBar* tb = toolBar("collectionToolBar");
+ if(!tb) {
+ return;
+ }
+
+ for(int i = 0; i < tb->count(); ++i) {
+ if(m_entryGrouping->isPlugged(tb, tb->idAt(i))) {
+ KComboBox* combo = tb->getCombo(tb->idAt(i));
+ if(combo) {
+ combo->popup();
+ break;
+ }
+ }
+ }
+}
+
+void MainWindow::slotFilterLabelActivated() {
+ m_quickFilter->setFocus();
+ m_quickFilter->selectAll();
+}
+
+void MainWindow::slotClearFilter() {
+ m_quickFilter->clear();
+ slotQueueFilter();
+}
+
+void MainWindow::slotRenameCollection() {
+ Kernel::self()->renameCollection();
+}
+
+void MainWindow::updateCollectionActions() {
+ if(!Data::Document::self()->collection()) {
+ return;
+ }
+
+ stateChanged(QString::fromLatin1("collection_reset"));
+ Data::Collection::Type type = Data::Document::self()->collection()->type();
+ switch(type) {
+ case Data::Collection::Book:
+ stateChanged(QString::fromLatin1("is_book"));
+ break;
+ case Data::Collection::Bibtex:
+ stateChanged(QString::fromLatin1("is_bibliography"));
+ break;
+ case Data::Collection::Video:
+ stateChanged(QString::fromLatin1("is_video"));
+ break;
+ default:
+ break;
+ }
+ Controller::self()->updateActions();
+ // special case when there are no available data sources
+ if(m_fetchActions.isEmpty() && m_updateAll) {
+ m_updateAll->setEnabled(false);
+ }
+}
+
+void MainWindow::updateEntrySources() {
+ QSignalMapper* mapper = ::qt_cast<QSignalMapper*>(child("update_mapper"));
+ if(!mapper) {
+ kdWarning() << "MainWindow::updateEntrySources() - no update mapper!" << endl;
+ return;
+ }
+
+ unplugActionList(QString::fromLatin1("update_entry_actions"));
+ for(QPtrListIterator<KAction> it(m_fetchActions); it.current(); ++it) {
+ it.current()->unplugAll();
+ mapper->removeMappings(it.current());
+ }
+ // autoDelete() all actions, which removes them from the actionCollection()
+ m_fetchActions.clear();
+
+ Fetch::FetcherVec vec = Fetch::Manager::self()->fetchers(Kernel::self()->collectionType());
+ for(Fetch::FetcherVec::Iterator it = vec.begin(); it != vec.end(); ++it) {
+ KAction* action = new KAction(actionCollection());
+ action->setText(it->source());
+ action->setToolTip(i18n("Update entry data from %1").arg(it->source()));
+ action->setIconSet(Fetch::Manager::fetcherIcon(it.data()));
+ connect(action, SIGNAL(activated()), mapper, SLOT(map()));
+ mapper->setMapping(action, it->source());
+ m_fetchActions.append(action);
+ }
+
+ plugActionList(QString::fromLatin1("update_entry_actions"), m_fetchActions);
+}
+
+void MainWindow::importFile(Import::Format format_, const KURL::List& urls_) {
+ KURL::List urls = urls_;
+ // update as DropHandler and Importer classes are updated
+ if(urls_.count() > 1 &&
+ format_ != Import::Bibtex &&
+ format_ != Import::RIS &&
+ format_ != Import::PDF) {
+ KURL u = urls_.front();
+ QString url = u.isLocalFile() ? u.path() : u.prettyURL();
+ Kernel::self()->sorry(i18n("Tellico can only import one file of this type at a time. "
+ "Only %1 will be imported.").arg(url));
+ urls.clear();
+ urls = u;
+ }
+
+ ImportDialog dlg(format_, urls, this, "importdlg");
+ if(dlg.exec() != QDialog::Accepted) {
+ return;
+ }
+
+// if edit dialog is saved ok and if replacing, then the doc is saved ok
+ if(m_editDialog->queryModified() &&
+ (dlg.action() != Import::Replace || Data::Document::self()->saveModified())) {
+ GUI::CursorSaver cs(Qt::waitCursor);
+ Data::CollPtr coll = dlg.collection();
+ if(!coll) {
+ if(!dlg.statusMessage().isEmpty()) {
+ Kernel::self()->sorry(dlg.statusMessage());
+ }
+ return;
+ }
+ importCollection(coll, dlg.action());
+ }
+}
+
+bool MainWindow::importCollection(Data::CollPtr coll_, Import::Action action_) {
+ bool failed = false;
+ switch(action_) {
+ case Import::Append:
+ {
+ // only append if match, but special case importing books into bibliographies
+ Data::CollPtr c = Data::Document::self()->collection();
+ if(c->type() == coll_->type()
+ || (c->type() == Data::Collection::Bibtex && coll_->type() == Data::Collection::Book)) {
+ Kernel::self()->appendCollection(coll_);
+ slotEnableModifiedActions(true);
+ } else {
+ Kernel::self()->sorry(i18n(errorAppendType));
+ failed = true;
+ }
+ }
+ break;
+
+ case Import::Merge:
+ {
+ // only merge if match, but special case importing books into bibliographies
+ Data::CollPtr c = Data::Document::self()->collection();
+ if(c->type() == coll_->type()
+ || (c->type() == Data::Collection::Bibtex && coll_->type() == Data::Collection::Book)) {
+ Kernel::self()->mergeCollection(coll_);
+ slotEnableModifiedActions(true);
+ } else {
+ Kernel::self()->sorry(i18n(errorMergeType));
+ failed = true;
+ }
+ }
+ break;
+
+ default: // replace
+ Kernel::self()->replaceCollection(coll_);
+ m_fileOpenRecent->setCurrentItem(-1);
+ m_newDocument = true;
+ slotEnableOpenedActions();
+ slotEnableModifiedActions(false);
+ break;
+ }
+ return !failed;
+}
+
+void MainWindow::slotURLAction(const KURL& url_) {
+ Q_ASSERT(url_.protocol() == Latin1Literal("tc"));
+ QString actionName = url_.fileName();
+ KAction* action = this->action(actionName);
+ if(action) {
+ action->activate();
+ } else {
+ myWarning() << "MainWindow::slotURLAction() - unknown action: " << actionName << endl;
+ }
+}
+
+#include "mainwindow.moc"
diff --git a/src/mainwindow.h b/src/mainwindow.h
new file mode 100644
index 0000000..96ed71a
--- /dev/null
+++ b/src/mainwindow.h
@@ -0,0 +1,534 @@
+/***************************************************************************
+ copyright : (C) 2001-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_MAINWINDOW_H
+#define TELLICO_MAINWINDOW_H
+
+#include <config.h>
+
+#include "core/dcopinterface.h"
+#include "translators/translators.h"
+#include "datavectors.h"
+
+#include <kmainwindow.h>
+
+class KToolBar;
+class KURL;
+class KAction;
+class KSelectAction;
+class KToggleAction;
+class KRecentFilesAction;
+class KActionMenu;
+class KDialogBase;
+
+class QCloseEvent;
+class QSplitter;
+class QListViewItem;
+
+namespace Tellico {
+// forward declarations
+ namespace GUI {
+ class LineEdit;
+ class TabControl;
+ }
+ class Controller;
+ class ViewStack;
+ class DetailedListView;
+ class FilterDialog;
+ class EntryEditDialog;
+ class GroupView;
+ class FilterView;
+ class LoanView;
+ class ConfigDialog;
+ class CollectionFieldsDialog;
+ class StringMapDialog;
+ class EntryItem;
+ class FetchDialog;
+ class ReportDialog;
+ class StatusBar;
+ class DropHandler;
+
+/**
+ * The base class for Tellico application windows. It sets up the main
+ * window and reads the config file as well as providing a menubar, toolbar
+ * and statusbar. Tellico reimplements the methods that KMainWindow provides
+ * for main window handling and supports full session management as well as
+ * using KActions.
+ * @see KMainWindow
+ * @see KApplication
+ * @see KConfig
+ *
+ * @author Robby Stephenson
+ */
+class MainWindow : public KMainWindow, public ApplicationInterface {
+Q_OBJECT
+
+friend class Controller;
+friend class DropHandler;
+
+public:
+ /**
+ * The main window constructor, calls all init functions to create the application.
+ */
+ MainWindow(QWidget* parent=0, const char* name=0);
+
+ /**
+ * Opens the initial file.
+ *
+ * @param nofile If true, even if the config option to reopen last file is set, no file is opened
+ */
+ void initFileOpen(bool nofile);
+ /**
+ * Saves the document
+ *
+ * @return Returns @p true if successful
+ */
+ bool fileSave();
+ /**
+ * Saves a document by a new filename
+ *
+ * @return Returns @p true if successful
+ */
+ bool fileSaveAs();
+ /**
+ * @return Returns whether the current collection is still the non-saved default one
+ */
+ bool isNewDocument() const { return m_newDocument; }
+ /**
+ * Used by main() and DCOP to import file.
+ *
+ * @param format The file format
+ * @param url The url
+ */
+ virtual bool importFile(Import::Format format, const KURL& url, Import::Action action);
+ /**
+ * Used by DCOP to export to a file.
+ */
+ virtual bool exportCollection(Export::Format format, const KURL& url);
+ /**
+ * Used by DCOP
+ */
+ virtual void openFile(const QString& file);
+ virtual void setFilter(const QString& text);
+ virtual bool showEntry(long id);
+
+public slots:
+ /**
+ * Initializes some stuff after the object is created.
+ */
+ void slotInit();
+ /**
+ * Cleans up everything and then opens a new document.
+ *
+ * @param type Type of collection to add
+ */
+ void slotFileNew(int type);
+ /**
+ * Opens a file and loads it into the document
+ */
+ void slotFileOpen();
+ /**
+ * Opens a file by URL and loads it into the document
+ *
+ * @param url The url to open
+ */
+ void slotFileOpen(const KURL& url);
+ /**
+ * Opens a file from the recent files menu
+ *
+ * @param url The url sent by the RecentFilesAction
+ */
+ void slotFileOpenRecent(const KURL& url);
+ /**
+ * Saves the document
+ */
+ void slotFileSave();
+ /**
+ * Saves a document by a new filename
+ */
+ void slotFileSaveAs();
+ /**
+ * Prints the current document.
+ */
+ void slotFilePrint();
+ /**
+ * Quits the application.
+ */
+ void slotFileQuit();
+ /**
+ * Puts the marked text/object into the clipboard and removes it from the document.
+ */
+ void slotEditCut();
+ /*
+ * Puts the marked text/object into the clipboard.
+ */
+ void slotEditCopy();
+ /**
+ * Pastes the clipboard into the document.
+ */
+ void slotEditPaste();
+ /**
+ * Selects all the entries in the collection.
+ */
+ void slotEditSelectAll();
+ /**
+ * Deselects all the entries in the collection.
+ */
+ void slotEditDeselect();
+ /**
+ * Toggles the group widget.
+ */
+ void slotToggleGroupWidget();
+ /**
+ * Toggles the edit widget.
+ */
+ void slotToggleEntryEditor();
+ /**
+ * Toggles the edit widget.
+ */
+ void slotToggleEntryView();
+ /**
+ * Shows the configuration dialog for the application.
+ */
+ void slotShowConfigDialog();
+ /**
+ * Hides the configuration dialog for the application.
+ */
+ void slotHideConfigDialog();
+ /**
+ * Shows the fetch dialog.
+ */
+ void slotShowFetchDialog();
+ /**
+ * Hides the fetch dialog.
+ */
+ void slotHideFetchDialog();
+ /**
+ * Changes the statusbar contents for the standard label permanently,
+ * used to indicate current actions being made.
+ *
+ * @param text The text that is displayed in the statusbar
+ */
+ void slotStatusMsg(const QString& text);
+ void slotClearStatus();
+ /**
+ * Shows the configuration window for the toolbars.
+ */
+ void slotConfigToolbar();
+ /**
+ * Updates the toolbars;
+ */
+ void slotNewToolbarConfig();
+ /**
+ * Shows the configuration window for the key bindgins.
+ */
+ void slotConfigKeys();
+ /**
+ * Updates the entry count in the status bar.
+ */
+ void slotEntryCount();
+ /**
+ * Handles updating everything when the configuration is changed
+ * via the configuration dialog. This slot is called when the OK or Apply
+ * button is clicked in the dialog
+ */
+ void slotHandleConfigChange();
+ /**
+ * Changes the grouping of the entries in the @ref GroupView. The current value
+ * of the combobox in the toolbar is used.
+ */
+ void slotChangeGrouping();
+ /**
+ * Imports data.
+ *
+ * @param format The import format
+ */
+ void slotFileImport(int format);
+ /**
+ * Exports the current document.
+ *
+ * @param format The export format
+ */
+ void slotFileExport(int format);
+ /**
+ * Shows the filter dialog for the application.
+ */
+ void slotShowFilterDialog();
+ /**
+ * Hides the filter dialog for the application.
+ */
+ void slotHideFilterDialog();
+ /**
+ * Shows the collection properties dialog for the application.
+ */
+ void slotShowCollectionFieldsDialog();
+ /**
+ * Hides the collection properties dialog for the application.
+ */
+ void slotHideCollectionFieldsDialog();
+ /**
+ * Shows the "Tip of the Day" dialog.
+ *
+ * @param force Whether the configuration setting should be ignored
+ */
+ void slotShowTipOfDay(bool force=true);
+ /**
+ * Shows the string macro editor dialog for the application.
+ */
+ void slotShowStringMacroDialog();
+ /**
+ * Hides the string macro editor dialog for the application.
+ */
+ void slotHideStringMacroDialog();
+ /**
+ * Handle a url that indicates some actino should be taken
+ */
+ void slotURLAction(const KURL& url);
+
+private:
+ /**
+ * Saves the general options like all toolbar positions and status as well as the
+ * geometry and the recent file list to the configuration file.
+ */
+ void saveOptions();
+ /**
+ * Reads the specific options.
+ */
+ void readOptions();
+ /**
+ * Initializes the KActions of the application
+ */
+ void initActions();
+ /**
+ * Sets up the statusbar for the main window by initializing a status label
+ * and inserting a progress bar and entry counter.
+ */
+ void initStatusBar();
+ /**
+ * Initiates the view, setting up all the dock windows and so on.
+ */
+ void initView();
+ /**
+ * Initiates the document.
+ */
+ void initDocument();
+ /**
+ * Initiates all the signal and slot connections between major objects in the view.
+ */
+ void initConnections();
+ /**
+ * Initiates shutdown
+ */
+// void closeEvent(QCloseEvent *e);
+ /**
+ * Saves the window properties for each open window during session end to the
+ * session config file, including saving the currently opened file by a temporary
+ * filename provided by KApplication.
+ * @see KMainWindow::saveProperties
+ *
+ * @param cfg The config class with the properties to restore
+ */
+ void saveProperties(KConfig* cfg);
+ /**
+ * Reads the session config file and restores the application's state including
+ * the last opened files and documents by reading the temporary files saved by
+ * @ref saveProperties().
+ * @see KMainWindow::readProperties
+ *
+ * @param cfg The config class with the properties to restore
+ */
+ void readProperties(KConfig* cfg);
+ /**
+ * Called before the window is closed, either by the user or indirectely by the
+ * session manager.
+ *
+ * The purpose of this function is to prepare the window in a way that it is safe to close it,
+ * i.e. without the user losing some data.
+ * @see KMainWindow::queryClose
+ */
+ bool queryClose();
+ /**
+ * Called before the very last window is closed, either by the user
+ * or indirectly by the session manager.
+ * @see KMainWindow::queryExit
+ */
+ bool queryExit();
+ /**
+ * Actual method used when opening a URL. Updating for the list views is turned off
+ * as well as sorting, in order to more quickly load the document.
+ *
+ * @param url The url to open
+ */
+ bool openURL(const KURL& url);
+ /*
+ * Helper method to handle the printing duties.
+ *
+ * @param html The HTML string representing the doc to print
+ */
+ void doPrint(const QString& html);
+
+ void XSLTError();
+ /**
+ * Helper function to activate a slot in the edit widget.
+ * Primarily used for copy, cut, and paste.
+ *
+ * @param slot The slot name
+ */
+ void activateEditSlot(const char* slot);
+ void addFilterView();
+ void addLoanView();
+ void updateCaption(bool modified);
+ void updateCollectionActions();
+ void updateEntrySources();
+
+private slots:
+ /**
+ * Updates the actions when a file is opened.
+ */
+ void slotEnableOpenedActions();
+ /**
+ * Updates the save action and the caption when the document is modified.
+ */
+ void slotEnableModifiedActions(bool modified = true);
+ /**
+ * Read the options specific to a collection
+ *
+ * @param coll The collection pointer
+ */
+ void readCollectionOptions(Tellico::Data::CollPtr coll);
+ /**
+ * Saves the options relevant for a collection. I was having problems with the collection
+ * being destructed before I could save info.
+ *
+ * @param coll A pointer to the collection
+ */
+ void saveCollectionOptions(Tellico::Data::CollPtr coll);
+ /**
+ * Queue a filter update. The timer adds a 200 millisecond delay before actually
+ * updating the filter.
+ */
+ void slotQueueFilter();
+ /**
+ * Update the filter to match any field with text. If a non-word character appears, the
+ * text is interpreted as a regexp.
+ */
+ void slotUpdateFilter();
+ /**
+ * Updates the collection toolbar.
+ */
+ void slotUpdateCollectionToolBar(Tellico::Data::CollPtr coll);
+ /**
+ * Make sure the edit dialog is visible and start a new entry.
+ */
+ void slotNewEntry();
+ /**
+ * Handle the entry editor dialog being closed.
+ */
+ void slotEditDialogFinished();
+ /**
+ * Handle the Ok button being clicked in the string macros dialog.
+ */
+ void slotStringMacroDialogOk();
+ /**
+ * Since I use an application icon in the toolbar, I need to change its size whenever
+ * the toolbar changes mode
+ */
+ void slotUpdateToolbarIcons();
+ /**
+ * Convert current collection to a bibliography.
+ */
+ void slotConvertToBibliography();
+ /**
+ * Send a citation for the selected entries
+ */
+ void slotCiteEntry(int action);
+ /**
+ * Show the entry editor and update menu item.
+ */
+ void slotShowEntryEditor();
+ /**
+ * Show the report window.
+ */
+ void slotShowReportDialog();
+ void slotGroupLabelActivated();
+ /**
+ * Show the report window.
+ */
+ void slotHideReportDialog();
+ /**
+ * Focus the filter
+ */
+ void slotFilterLabelActivated();
+ void slotClearFilter();
+ void slotRenameCollection();
+
+private:
+ void importFile(Import::Format format, const KURL::List& kurls);
+ bool importCollection(Data::CollPtr coll, Import::Action action);
+
+ // the reason that I have to keep pointers to all these
+ // is because they get plugged into menus later in Controller
+ KRecentFilesAction* m_fileOpenRecent;
+ KAction* m_fileSave;
+ KAction* m_newEntry;
+ KAction* m_editEntry;
+ KAction* m_copyEntry;
+ KAction* m_deleteEntry;
+ KAction* m_mergeEntry;
+ KActionMenu* m_updateEntryMenu;
+ KAction* m_updateAll;
+ KAction* m_checkInEntry;
+ KAction* m_checkOutEntry;
+ KToggleAction* m_toggleGroupWidget;
+ KToggleAction* m_toggleEntryEditor;
+ KToggleAction* m_toggleEntryView;
+
+ KSelectAction* m_entryGrouping;
+ GUI::LineEdit* m_quickFilter;
+
+ // m_split is used between the stuff on the left and stuff on the right
+ QSplitter* m_split;
+ // m_leftSplit is used between detailed view and entry view
+ QSplitter* m_rightSplit;
+
+ Tellico::StatusBar* m_statusBar;
+
+ DetailedListView* m_detailedView;
+ EntryEditDialog* m_editDialog;
+ GUI::TabControl* m_viewTabs;
+ GroupView* m_groupView;
+ FilterView* m_filterView;
+ LoanView* m_loanView;
+ ViewStack* m_viewStack;
+
+ ConfigDialog* m_configDlg;
+ FilterDialog* m_filterDlg;
+ CollectionFieldsDialog* m_collFieldsDlg;
+ StringMapDialog* m_stringMacroDlg;
+ FetchDialog* m_fetchDlg;
+ ReportDialog* m_reportDlg;
+
+ QPtrList<KAction> m_fetchActions;
+ CollectionInterface m_collInterface;
+
+ // keep track of the number of queued filter updates
+ uint m_queuedFilters;
+
+ // keep track whether everything gets initialized
+ bool m_initialized : 1;
+ // need to keep track of whether the current collection has never been saved
+ bool m_newDocument : 1;
+};
+
+} // end namespace
+#endif // TELLICO_MAINWINDOW_H
diff --git a/src/newstuff/Makefile.am b/src/newstuff/Makefile.am
new file mode 100644
index 0000000..9054dcb
--- /dev/null
+++ b/src/newstuff/Makefile.am
@@ -0,0 +1,18 @@
+noinst_LIBRARIES = libnewstuff.a
+
+libnewstuff_a_METASOURCES = AUTO
+
+libnewstuff_a_SOURCES = manager.cpp dialog.cpp newscript.cpp providerloader.cpp
+
+CLEANFILES = *~
+
+EXTRA_DIST = \
+manager.h manager.cpp \
+dialog.h dialog.cpp \
+newscript.h newscript.cpp \
+providerloader.h providerloader.cpp
+
+AM_CPPFLAGS = $(all_includes)
+
+KDE_OPTIONS = noautodist
+
diff --git a/src/newstuff/dialog.cpp b/src/newstuff/dialog.cpp
new file mode 100644
index 0000000..c13a249
--- /dev/null
+++ b/src/newstuff/dialog.cpp
@@ -0,0 +1,477 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "dialog.h"
+#include "providerloader.h"
+#include "../gui/listview.h"
+#include "../latin1literal.h"
+#include "../tellico_utils.h"
+#include "../tellico_debug.h"
+
+#include <klocale.h>
+#include <kpushbutton.h>
+#include <kconfig.h>
+#include <kiconloader.h>
+#include <kstatusbar.h>
+#include <kio/job.h>
+#include <kio/netaccess.h>
+#include <kaccelmanager.h>
+#include <knewstuff/entry.h>
+#include <knewstuff/provider.h>
+#include <ktempfile.h>
+
+#include <qlabel.h>
+#include <qtextedit.h>
+#include <qlayout.h>
+#include <qwhatsthis.h>
+#include <qregexp.h>
+#include <qvbox.h>
+#include <qimage.h>
+#include <qtimer.h>
+#include <qprogressbar.h>
+
+#if KDE_IS_VERSION(3,4,90)
+#define ENTRYNAME(e) e->name(m_lang)
+#define ENTRYSUMM(e) e->summary(m_lang)
+#define ENTRYEMAIL(e) e->authorEmail()
+#else
+#define ENTRYNAME(e) e->name()
+#define ENTRYSUMM(e) e->summary()
+#define ENTRYEMAIL(e) QString()
+#endif
+
+namespace {
+ static const int NEW_STUFF_MIN_WIDTH = 600;
+ static const int NEW_STUFF_MIN_HEIGHT = 400;
+ static const int PROGRESS_STATUS_ID = 0;
+}
+
+using Tellico::NewStuff::Dialog;
+
+class Dialog::Item : public GUI::ListViewItem {
+public:
+ Item(GUI::ListView* parent) : GUI::ListViewItem(parent) {}
+
+ InstallStatus status() const { return m_status; }
+ void setStatus(InstallStatus status) {
+ m_status = status;
+ if(m_status == Current) {
+ setPixmap(0, SmallIcon(QString::fromLatin1("ok")));
+ } else if(m_status == OldVersion) {
+ setPixmap(0, SmallIcon(QString::fromLatin1("reload")));
+ }
+ }
+
+ QString key(int col, bool asc) const {
+ if(col == 2 || col == 3) {
+ QString s;
+ s.sprintf("%08d", text(col).toInt());
+ return s;
+ } else if(col == 4) {
+ QString s;
+ QDate date = KGlobal::locale()->readDate(text(col));
+ s.sprintf("%08d", date.year() * 366 + date.dayOfYear());
+ return s;
+ }
+ return GUI::ListViewItem::key(col, asc);
+ }
+
+private:
+ InstallStatus m_status;
+};
+
+Dialog::Dialog(NewStuff::DataType type_, QWidget* parent_)
+ : KDialogBase(KDialogBase::Plain, i18n("Get Hot New Stuff"), 0, (KDialogBase::ButtonCode)0, parent_)
+ , m_manager(new Manager(this))
+ , m_type(type_)
+ , m_timer(new QTimer(this))
+ , m_cursorSaver(new GUI::CursorSaver())
+ , m_tempPreviewImage(0)
+ , m_lastPreviewItem(0) {
+
+ m_lang = KGlobal::locale()->language();
+
+ QFrame* frame = plainPage();
+ QBoxLayout* boxLayout = new QVBoxLayout(frame, 0, KDialog::spacingHint());
+
+ m_split = new QSplitter(Qt::Vertical, frame);
+ boxLayout->addWidget(m_split);
+
+ m_listView = new GUI::ListView(m_split);
+ m_listView->setAllColumnsShowFocus(true);
+ m_listView->setSelectionMode(QListView::Single);
+ m_listView->addColumn(i18n("Name"));
+ m_listView->addColumn(i18n("Version"));
+ m_listView->addColumn(i18n("Rating"));
+ m_listView->addColumn(i18n("Downloads"));
+ m_listView->addColumn(i18n("Release Date"));
+ m_listView->setSorting(2, false);
+ m_listView->setResizeMode(QListView::AllColumns);
+ connect(m_listView, SIGNAL(clicked(QListViewItem*)), SLOT(slotSelected(QListViewItem*)));
+ QWhatsThis::add(m_listView, i18n("This is a list of all the items available for download. "
+ "Previously installed items have a checkmark icon, while "
+ "items with new version available have an update icon"));
+
+ QWidget* widget = new QWidget(m_split);
+ QBoxLayout* boxLayout2 = new QVBoxLayout(widget, 0, KDialog::spacingHint());
+
+ m_iconLabel = new QLabel(widget);
+ m_iconLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
+ m_iconLabel->setMargin(0);
+
+ m_nameLabel = new QLabel(widget);
+ QFont font = m_nameLabel->font();
+ font.setBold(true);
+ font.setItalic(true);
+ m_nameLabel->setFont(font);
+ QWhatsThis::add(m_nameLabel, i18n("The name and license of the selected item"));
+
+ m_infoLabel = new QLabel(widget);
+ QWhatsThis::add(m_infoLabel, i18n("The author of the selected item"));
+
+ m_install = new KPushButton(i18n("Install"), widget);
+ m_install->setIconSet(SmallIconSet(QString::fromLatin1("knewstuff")));
+ m_install->setEnabled(false);
+ connect(m_install, SIGNAL(clicked()), SLOT(slotInstall()));
+
+ // the button's text changes later
+ // I don't want it resizing, so figure out the maximum size and set that
+ m_install->polish();
+ int maxWidth = m_install->sizeHint().width();
+ int maxHeight = m_install->sizeHint().height();
+ m_install->setGuiItem(KGuiItem(i18n("Update"), SmallIconSet(QString::fromLatin1("knewstuff"))));
+ maxWidth = QMAX(maxWidth, m_install->sizeHint().width());
+ maxHeight = QMAX(maxHeight, m_install->sizeHint().height());
+ m_install->setMinimumWidth(maxWidth);
+ m_install->setMinimumHeight(maxHeight);
+
+ QPixmap pix;
+ if(m_type == EntryTemplate) {
+ pix = DesktopIcon(QString::fromLatin1("looknfeel"), KIcon::SizeLarge);
+ QWhatsThis::add(m_install, i18n("Download and install the selected template."));
+ } else {
+ pix = UserIcon(QString::fromLatin1("script"));
+ QWhatsThis::add(m_install, i18n("Download and install the selected script. Some scripts "
+ "may need to be configured after being installed."));
+ }
+ m_iconLabel->setPixmap(pix);
+
+ QBoxLayout* boxLayout3 = new QHBoxLayout(boxLayout2);
+
+ QBoxLayout* boxLayout4 = new QVBoxLayout(boxLayout3);
+ boxLayout4->addWidget(m_iconLabel);
+ boxLayout4->addStretch(10);
+
+ boxLayout3->addSpacing(4);
+
+ QBoxLayout* boxLayout5 = new QVBoxLayout(boxLayout3);
+ boxLayout5->addWidget(m_nameLabel);
+ boxLayout5->addWidget(m_infoLabel);
+ boxLayout5->addStretch(10);
+
+ boxLayout3->addStretch(10);
+
+ QBoxLayout* boxLayout6 = new QVBoxLayout(boxLayout3);
+ boxLayout6->addWidget(m_install);
+ boxLayout6->addStretch(10);
+
+ m_descLabel = new QTextEdit(widget);
+ m_descLabel->setReadOnly(true);
+ m_descLabel->setTextFormat(Qt::RichText);
+ m_descLabel->setPaper(colorGroup().background());
+ m_descLabel->setMinimumHeight(5 * fontMetrics().height());
+ boxLayout2->addWidget(m_descLabel, 10);
+ QWhatsThis::add(m_descLabel, i18n("A description of the selected item is shown here."));
+
+ QHBox* box = new QHBox(frame, "statusbox");
+ boxLayout->addWidget(box);
+ box->setSpacing(KDialog::spacingHint());
+
+ m_statusBar = new KStatusBar(box, "statusbar");
+ m_statusBar->insertItem(QString::null, PROGRESS_STATUS_ID, 1, false);
+ m_statusBar->setItemAlignment(PROGRESS_STATUS_ID, AlignLeft | AlignVCenter);
+ m_progress = new QProgressBar(m_statusBar, "progress");
+ m_progress->setTotalSteps(0);
+ m_progress->setFixedHeight(fontMetrics().height()+2);
+ m_statusBar->addWidget(m_progress, 0, true);
+
+ KPushButton* closeButton = new KPushButton(KStdGuiItem::close(), box);
+ connect(closeButton, SIGNAL(clicked()), SLOT(slotClose()));
+ closeButton->setFocus();
+
+ connect(m_timer, SIGNAL(timeout()), SLOT(slotMoveProgress()));
+
+ setMinimumWidth(QMAX(minimumWidth(), NEW_STUFF_MIN_WIDTH));
+ setMinimumHeight(QMAX(minimumHeight(), NEW_STUFF_MIN_HEIGHT));
+ resize(configDialogSize(QString::fromLatin1("NewStuff Dialog Options")));
+
+ KConfigGroup dialogConfig(KGlobal::config(), "NewStuff Dialog Options");
+ QValueList<int> splitList = dialogConfig.readIntListEntry("Splitter Sizes");
+ if(!splitList.empty()) {
+ m_split->setSizes(splitList);
+ }
+
+ setStatus(i18n("Downloading information..."));
+
+ ProviderLoader* loader = new Tellico::NewStuff::ProviderLoader(this);
+ connect(loader, SIGNAL(providersLoaded(QPtrList<KNS::Provider>*)), SLOT(slotProviders(QPtrList<KNS::Provider>*)));
+ connect(loader, SIGNAL(percent(KIO::Job*, unsigned long)), SLOT(slotShowPercent(KIO::Job*, unsigned long)));
+ connect(loader, SIGNAL(error()), SLOT(slotProviderError()));
+
+ KConfigGroup config(KGlobal::config(), "KNewStuff");
+ QString prov = config.readEntry("ProvidersUrl");
+ if(prov.isEmpty()) {
+ if(m_type == EntryTemplate) {
+ prov = QString::fromLatin1("http://periapsis.org/tellico/newstuff/tellicotemplates-providers.php");
+ QString alt = QString::fromLatin1("http://download.kde.org/khotnewstuff/tellicotemplates-providers.xml");
+ loader->setAlternativeProvider(alt);
+ } else {
+ prov = QString::fromLatin1("http://periapsis.org/tellico/newstuff/tellicoscripts-providers.php");
+ }
+ }
+ if(m_type == EntryTemplate) {
+ m_typeName = QString::fromLatin1("tellico/entry-template");
+ } else {
+ m_typeName = QString::fromLatin1("tellico/data-source");
+ }
+ loader->load(m_typeName, prov);
+
+ KAcceleratorManager::manage(this);
+}
+
+Dialog::~Dialog() {
+ delete m_cursorSaver;
+ m_cursorSaver = 0;
+
+ saveDialogSize(QString::fromLatin1("NewStuff Dialog Options"));
+ KConfigGroup config(KGlobal::config(), "NewStuff Dialog Options");
+ config.writeEntry("Splitter Sizes", m_split->sizes());
+}
+
+void Dialog::slotProviderError() {
+ if(m_listView->childCount() == 0) {
+ myDebug() << "NewStuff::Dialog::slotCheckError() - no available items" << endl;
+ setStatus(QString());
+
+ delete m_cursorSaver;
+ m_cursorSaver = 0;
+ }
+}
+
+void Dialog::slotProviders(QPtrList<KNS::Provider>* list_) {
+ for(KNS::Provider* prov = list_->first(); prov; prov = list_->next()) {
+ KIO::TransferJob* job = KIO::get(prov->downloadUrl());
+ m_jobs[job] = prov;
+ connect(job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)));
+ connect(job, SIGNAL(result(KIO::Job*)), SLOT(slotResult(KIO::Job*)));
+ connect(job, SIGNAL(percent(KIO::Job*, unsigned long)),
+ SLOT(slotShowPercent(KIO::Job*, unsigned long)));
+ }
+}
+
+void Dialog::slotData(KIO::Job* job_, const QByteArray& data_) {
+ QDataStream stream(m_data[job_], IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(data_.data(), data_.size());
+}
+
+void Dialog::slotResult(KIO::Job* job_) {
+// myDebug() << "NewStuff::Dialog::slotResult()" << endl;
+ QDomDocument dom;
+ if(!dom.setContent(m_data[job_])) {
+ KNS::Provider* prov = m_jobs[job_];
+ KURL u = prov ? prov->downloadUrl() : KURL();
+ myDebug() << "NewStuff::Dialog::slotResult() - can't load result: " << u.url() << endl;
+ m_jobs.remove(job_);
+ if(m_jobs.isEmpty()) {
+ setStatus(i18n("Ready."));
+ delete m_cursorSaver;
+ m_cursorSaver = 0;
+ }
+ return;
+ }
+
+ QDomElement knewstuff = dom.documentElement();
+
+ for(QDomNode pn = knewstuff.firstChild(); !pn.isNull(); pn = pn.nextSibling()) {
+ QDomElement stuff = pn.toElement();
+ if(stuff.isNull()) {
+ continue;
+ }
+
+ if(stuff.tagName() == Latin1Literal("stuff")) {
+ KNS::Entry* entry = new KNS::Entry(stuff);
+ if(!entry->type().isEmpty() && entry->type() != m_typeName) {
+ myLog() << "NewStuff::Dialog::slotResult() - type mismatch, skipping " << ENTRYNAME(entry) << endl;
+ continue;
+ }
+
+ addEntry(entry);
+ }
+ }
+ m_jobs.remove(job_);
+ if(m_jobs.isEmpty()) {
+ setStatus(i18n("Ready."));
+ delete m_cursorSaver;
+ m_cursorSaver = 0;
+ }
+}
+
+void Dialog::addEntry(KNS::Entry* entry_) {
+ if(!entry_) {
+ return;
+ }
+
+ Item* item = new Item(m_listView);
+ item->setText(0, ENTRYNAME(entry_));
+ item->setText(1, entry_->version());
+ item->setText(2, QString::number(entry_->rating()));
+ item->setText(3, QString::number(entry_->downloads()));
+ item->setText(4, KGlobal::locale()->formatDate(entry_->releaseDate(), true /*short format */));
+ item->setStatus(NewStuff::Manager::installStatus(entry_));
+ m_entryMap.insert(item, entry_);
+
+ if(!m_listView->selectedItem()) {
+ m_listView->setSelected(item, true);
+ slotSelected(item);
+ }
+}
+
+void Dialog::slotSelected(QListViewItem* item_) {
+ if(!item_) {
+ return;
+ }
+
+ KNS::Entry* entry = m_entryMap[item_];
+ if(!entry) {
+ return;
+ }
+
+ KURL preview = entry->preview(m_lang);
+ if(!preview.isEmpty() && preview.isValid()) {
+ delete m_tempPreviewImage;
+ m_tempPreviewImage = new KTempFile();
+ m_tempPreviewImage->setAutoDelete(true);
+ KURL dest;
+ dest.setPath(m_tempPreviewImage->name());
+ KIO::FileCopyJob* job = KIO::file_copy(preview, dest, -1, true, false, false);
+ connect(job, SIGNAL(result(KIO::Job*)), SLOT(slotPreviewResult(KIO::Job*)));
+ connect(job, SIGNAL(percent(KIO::Job*, unsigned long)),
+ SLOT(slotShowPercent(KIO::Job*, unsigned long)));
+ m_lastPreviewItem = item_;
+ }
+ QPixmap pix = m_type == EntryTemplate
+ ? DesktopIcon(QString::fromLatin1("looknfeel"), KIcon::SizeLarge)
+ : UserIcon(QString::fromLatin1("script"));
+ m_iconLabel->setPixmap(pix);
+
+ QString license = entry->license();
+ if(!license.isEmpty()) {
+ license.prepend('(').append(')');
+ }
+ QString name = QString::fromLatin1("%1 %2").arg(ENTRYNAME(entry)).arg(license);
+ QFont font = m_nameLabel->font();
+ font.setBold(true);
+ font.setItalic(false);
+ m_nameLabel->setFont(font);
+ m_nameLabel->setText(name);
+
+ m_infoLabel->setText(entry->author());
+
+ QString desc = entry->summary(m_lang);
+ desc.replace(QRegExp(QString::fromLatin1("\\n")), QString::fromLatin1("<br>"));
+ m_descLabel->setText(desc);
+
+ InstallStatus installed = static_cast<Item*>(item_)->status();
+ m_install->setText(installed == OldVersion ? i18n("Update Stuff", "Update") : i18n("Install"));
+ m_install->setEnabled(installed != Current);
+}
+
+void Dialog::slotInstall() {
+ QListViewItem* item = m_listView->currentItem();
+ if(!item) {
+ return;
+ }
+
+ KNS::Entry* entry = m_entryMap[item];
+ if(!entry) {
+ return;
+ }
+
+ delete m_cursorSaver;
+ m_cursorSaver = new GUI::CursorSaver();
+ setStatus(i18n("Installing item..."));
+ m_progress->show();
+ m_timer->start(100);
+ connect(m_manager, SIGNAL(signalInstalled(KNS::Entry*)), SLOT(slotDoneInstall(KNS::Entry*)));
+ m_manager->install(m_type, entry);
+ delete m_cursorSaver;
+ m_cursorSaver = 0;
+}
+
+void Dialog::slotDoneInstall(KNS::Entry* entry_) {
+ QMap<QListViewItem*, KNS::Entry*>::Iterator it;
+ for(it = m_entryMap.begin(); entry_ && it != m_entryMap.end(); ++it) {
+ if(it.data() == entry_) {
+ InstallStatus installed = Manager::installStatus(entry_);
+ static_cast<Item*>(it.key())->setStatus(installed);
+ m_install->setEnabled(installed != Current);
+ break;
+ }
+ }
+ delete m_cursorSaver;
+ m_cursorSaver = 0;
+ setStatus(i18n("Ready."));
+ m_timer->stop();
+ m_progress->hide();
+}
+
+void Dialog::slotMoveProgress() {
+ m_progress->setProgress(m_progress->progress()+5);
+}
+
+void Dialog::setStatus(const QString& text_) {
+ m_statusBar->changeItem(QChar(' ') + text_, PROGRESS_STATUS_ID);
+}
+
+void Dialog::slotShowPercent(KIO::Job*, unsigned long pct_) {
+ if(pct_ >= 100) {
+ m_progress->hide();
+ } else {
+ m_progress->show();
+ m_progress->setProgress(static_cast<int>(pct_), 100);
+ }
+}
+
+void Dialog::slotPreviewResult(KIO::Job* job_) {
+ KIO::FileCopyJob* job = static_cast<KIO::FileCopyJob*>(job_);
+ if(job->error()) {
+ return;
+ }
+ QString tmpFile = job->destURL().path(); // might be different than m_tempPreviewImage->name()
+ QPixmap pix(tmpFile);
+
+ if(!pix.isNull()) {
+ if(pix.width() > 64 || pix.height() > 64) {
+ pix.convertFromImage(pix.convertToImage().smoothScale(64, 64, QImage::ScaleMin));
+ }
+ // only set label if it's still current
+ if(m_listView->selectedItem() == m_lastPreviewItem) {
+ m_iconLabel->setPixmap(pix);
+ }
+ }
+ delete m_tempPreviewImage;
+ m_tempPreviewImage = 0;
+}
+
+#include "dialog.moc"
diff --git a/src/newstuff/dialog.h b/src/newstuff/dialog.h
new file mode 100644
index 0000000..f1c5e48
--- /dev/null
+++ b/src/newstuff/dialog.h
@@ -0,0 +1,101 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_NEWSTUFF_DIALOG_H
+#define TELLICO_NEWSTUFF_DIALOG_H
+
+#include "manager.h"
+
+#include <kdialogbase.h>
+
+class KPushButton;
+class KStatusBar;
+namespace KIO {
+ class Job;
+}
+namespace KNS {
+ class Entry;
+ class Provider;
+}
+
+class QProgressBar;
+class QSplitter;
+class QLabel;
+class QTextEdit;
+
+namespace Tellico {
+ namespace GUI {
+ class ListView;
+ class CursorSaver;
+ }
+
+ namespace NewStuff {
+
+class Dialog : public KDialogBase {
+Q_OBJECT
+
+public:
+ Dialog(DataType type, QWidget* parent);
+ virtual ~Dialog();
+
+ QPtrList<DataSourceInfo> dataSourceInfo() const { return m_manager->dataSourceInfo(); }
+
+private slots:
+ void slotProviders(QPtrList<KNS::Provider>* list);
+ void slotData(KIO::Job* job, const QByteArray& data);
+ void slotResult(KIO::Job* job);
+ void slotPreviewResult(KIO::Job* job);
+
+ void slotShowPercent(KIO::Job* job, unsigned long percent);
+
+ void slotSelected(QListViewItem* item);
+ void slotInstall();
+ void slotDoneInstall(KNS::Entry* entry);
+
+ void slotProviderError();
+ void slotMoveProgress();
+
+private:
+ class Item;
+
+ void setStatus(const QString& status);
+ void addEntry(KNS::Entry* entry);
+
+ Manager* const m_manager;
+ DataType m_type;
+ QString m_lang;
+ QString m_typeName;
+
+ QSplitter* m_split;
+ GUI::ListView* m_listView;
+ QLabel* m_iconLabel;
+ QLabel* m_nameLabel;
+ QLabel* m_infoLabel;
+ QTextEdit* m_descLabel;
+ KPushButton* m_install;
+ KStatusBar* m_statusBar;
+ QProgressBar* m_progress;
+ QTimer* m_timer;
+ GUI::CursorSaver* m_cursorSaver;
+ KTempFile* m_tempPreviewImage;
+
+ QMap<KIO::Job*, KNS::Provider*> m_jobs;
+ QMap<KIO::Job*, QByteArray> m_data;
+
+ QMap<QListViewItem*, KNS::Entry*> m_entryMap;
+ QListViewItem* m_lastPreviewItem;
+};
+
+ }
+}
+#endif
diff --git a/src/newstuff/manager.cpp b/src/newstuff/manager.cpp
new file mode 100644
index 0000000..3b7efbf
--- /dev/null
+++ b/src/newstuff/manager.cpp
@@ -0,0 +1,446 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "manager.h"
+#include "newscript.h"
+#include "../filehandler.h"
+#include "../tellico_debug.h"
+#include "../tellico_utils.h"
+#include "../tellico_kernel.h"
+#include "../fetch/fetch.h"
+
+#include <kurl.h>
+#include <ktar.h>
+#include <kglobal.h>
+#include <kio/netaccess.h>
+#include <kconfig.h>
+#include <ktempfile.h>
+#include <kio/job.h>
+#include <kfileitem.h>
+#include <kdeversion.h>
+#include <knewstuff/entry.h>
+#include <kstandarddirs.h>
+
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <qptrstack.h>
+#include <qvaluestack.h>
+#include <qwidget.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+using Tellico::NewStuff::Manager;
+
+Manager::Manager(QObject* parent_) : QObject(parent_), m_tempFile(0) {
+ m_infoList.setAutoDelete(true);
+}
+
+Manager::~Manager() {
+ delete m_tempFile;
+ m_tempFile = 0;
+}
+
+bool Manager::installTemplate(const KURL& url_, const QString& entryName_) {
+ FileHandler::FileRef* ref = FileHandler::fileRef(url_);
+
+ QString xslFile;
+ QStringList allFiles;
+
+ bool success = true;
+
+ // is there a better way to figure out if the url points to a XSL file or a tar archive
+ // than just trying to open it?
+ KTar archive(ref->fileName());
+ if(archive.open(IO_ReadOnly)) {
+ const KArchiveDirectory* archiveDir = archive.directory();
+ archiveDir->copyTo(Tellico::saveLocation(QString::fromLatin1("entry-templates/")));
+
+ allFiles = archiveFiles(archiveDir);
+ // remember files installed for template
+ xslFile = findXSL(archiveDir);
+ } else { // assume it's an xsl file
+ QString name = entryName_;
+ if(name.isEmpty()) {
+ name = url_.fileName();
+ }
+ if(!name.endsWith(QString::fromLatin1(".xsl"))) {
+ name += QString::fromLatin1(".xsl");
+ }
+ KURL dest;
+ dest.setPath(Tellico::saveLocation(QString::fromLatin1("entry-templates/")) + name);
+ success = true;
+ if(QFile::exists(dest.path())) {
+ myDebug() << "Manager::installTemplate() - " << dest.path() << " exists!" << endl;
+ success = false;
+ } else if(KIO::NetAccess::file_copy(url_, dest)) {
+ xslFile = dest.fileName();
+ allFiles += xslFile;
+ }
+ }
+
+ if(xslFile.isEmpty()) {
+ success = false;
+ } else {
+ // remove ".xsl"
+ xslFile.truncate(xslFile.length()-4);
+ KConfigGroup config(KGlobal::config(), "KNewStuffFiles");
+ config.writeEntry(xslFile, allFiles);
+ m_urlNameMap.insert(url_, xslFile);
+ }
+
+ checkCommonFile();
+
+ delete ref;
+ return success;
+}
+
+bool Manager::removeTemplate(const QString& name_) {
+ KConfigGroup fileGroup(KGlobal::config(), "KNewStuffFiles");
+ QStringList files = fileGroup.readListEntry(name_);
+ // at least, delete xsl file
+ if(files.isEmpty()) {
+ kdWarning() << "Manager::deleteTemplate() no file list found for " << name_ << endl;
+ files += name_;
+ }
+
+ bool success = true;
+ QString path = Tellico::saveLocation(QString::fromLatin1("entry-templates/"));
+ for(QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) {
+ if((*it).endsWith(QChar('/'))) {
+ // ok to not delete all directories
+ QDir().rmdir(path + *it);
+ } else {
+ success = success && QFile(path + *it).remove();
+ if(!success) {
+ myDebug() << "Manager::removeTemplate() - failed to remove " << (path+*it) << endl;
+ }
+ }
+ }
+
+ // remove config entries even if unsuccessful
+ fileGroup.deleteEntry(name_);
+ KConfigGroup statusGroup(KGlobal::config(), "KNewStuffStatus");
+ QString entryName = statusGroup.readEntry(name_);
+ statusGroup.deleteEntry(name_);
+ statusGroup.deleteEntry(entryName);
+
+ return success;
+}
+
+bool Manager::installScript(const KURL& url_) {
+ FileHandler::FileRef* ref = FileHandler::fileRef(url_);
+
+ KTar archive(ref->fileName());
+ if(!archive.open(IO_ReadOnly)) {
+ myDebug() << "Manager::installScript() - can't open tar file" << endl;
+ return false;
+ }
+
+ const KArchiveDirectory* archiveDir = archive.directory();
+
+ QString exeFile = findEXE(archiveDir);
+ if(exeFile.isEmpty()) {
+ myDebug() << "Manager::installScript() - no exe file found" << endl;
+ return false;
+ }
+
+ QFileInfo exeInfo(exeFile);
+ DataSourceInfo* info = new DataSourceInfo();
+
+ QString copyTarget = Tellico::saveLocation(QString::fromLatin1("data-sources/"));
+ QString scriptFolder;
+
+ // package could have a top-level directory or not
+ // it should have a directory...
+ const KArchiveEntry* firstEntry = archiveDir->entry(archiveDir->entries().first());
+ if(firstEntry->isFile()) {
+ copyTarget += exeInfo.baseName(true) + '/';
+ if(QFile::exists(copyTarget)) {
+ KURL u;
+ u.setPath(scriptFolder);
+ myLog() << "Manager::installScript() - deleting " << scriptFolder << endl;
+ KIO::NetAccess::del(u, Kernel::self()->widget());
+ info->isUpdate = true;
+ }
+ scriptFolder = copyTarget;
+ } else {
+ scriptFolder = copyTarget + firstEntry->name() + '/';
+ if(QFile::exists(copyTarget + exeFile)) {
+ info->isUpdate = true;
+ }
+ }
+
+ // overwrites stuff there
+ archiveDir->copyTo(copyTarget);
+
+ info->specFile = scriptFolder + exeInfo.baseName(true) + ".spec";
+ if(!QFile::exists(info->specFile)) {
+ myDebug() << "Manager::installScript() - no spec file for script! " << info->specFile << endl;
+ delete info;
+ return false;
+ }
+ info->sourceName = exeFile;
+ info->sourceExec = copyTarget + exeFile;
+ m_infoList.append(info);
+
+ KURL dest;
+ dest.setPath(info->sourceExec);
+ KFileItem item(KFileItem::Unknown, KFileItem::Unknown, dest, true);
+ ::chmod(QFile::encodeName(dest.path()), item.permissions() | S_IXUSR);
+
+ {
+ KConfig spec(info->specFile, false, false);
+ // update name
+ info->sourceName = spec.readEntry("Name", info->sourceName);
+ spec.writePathEntry("ExecPath", info->sourceExec);
+ spec.writeEntry("NewStuffName", info->sourceName);
+ spec.writeEntry("DeleteOnRemove", true);
+ }
+
+ {
+ KConfigGroup config(KGlobal::config(), "KNewStuffFiles");
+ config.writeEntry(info->sourceName, archiveFiles(archiveDir));
+ m_urlNameMap.insert(url_, info->sourceName);
+ }
+
+
+// myDebug() << "Manager::installScript() - exeFile = " << exeFile << endl;
+// myDebug() << "Manager::installScript() - sourceExec = " << info->sourceExec << endl;
+// myDebug() << "Manager::installScript() - sourceName = " << info->sourceName << endl;
+// myDebug() << "Manager::installScript() - specFile = " << info->specFile << endl;
+
+ delete ref;
+ return true;
+}
+
+bool Manager::removeScript(const QString& name_) {
+ KConfigGroup fileGroup(KGlobal::config(), "KNewStuffFiles");
+ QStringList files = fileGroup.readListEntry(name_);
+
+ bool success = true;
+ QString path = Tellico::saveLocation(QString::fromLatin1("data-sources/"));
+ for(QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) {
+ if((*it).endsWith(QChar('/'))) {
+ // ok to not delete all directories
+ QDir().rmdir(path + *it);
+ } else {
+ success = success && QFile(path + *it).remove();
+ if(!success) {
+ myDebug() << "Manager::removeScript() - failed to remove " << (path+*it) << endl;
+ }
+ }
+ }
+
+ // remove config entries even if unsuccessful
+ fileGroup.deleteEntry(name_);
+ KConfigGroup statusGroup(KGlobal::config(), "KNewStuffStatus");
+ QString entryName = statusGroup.readEntry(name_);
+ statusGroup.deleteEntry(name_);
+ statusGroup.deleteEntry(entryName);
+
+ return success;
+}
+
+Tellico::NewStuff::InstallStatus Manager::installStatus(KNS::Entry* entry_) {
+ KConfigGroup config(KGlobal::config(), "KNewStuffStatus");
+ QString datestring = config.readEntry(entry_->name());
+ if(datestring.isEmpty()) {
+ return NotInstalled;
+ }
+
+ QDate date = QDate::fromString(datestring, Qt::ISODate);
+ if(!date.isValid()) {
+ return NotInstalled;
+ }
+ if(date < entry_->releaseDate()) {
+ return OldVersion;
+ }
+
+ // also check that executable files exists
+ KConfigGroup fileGroup(KGlobal::config(), "KNewStuffFiles");
+ QStringList files = fileGroup.readListEntry(entry_->name());
+ QString path = Tellico::saveLocation(QString::fromLatin1("data-sources/"));
+ for(QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) {
+ if(!QFile::exists(path + *it)) {
+ return NotInstalled;
+ }
+ }
+ return Current;
+}
+
+QStringList Manager::archiveFiles(const KArchiveDirectory* dir_, const QString& path_) {
+ QStringList list;
+
+ const QStringList dirEntries = dir_->entries();
+ for(QStringList::ConstIterator it = dirEntries.begin(); it != dirEntries.end(); ++it) {
+ const QString& entry = *it;
+ const KArchiveEntry* curEntry = dir_->entry(entry);
+ if(curEntry->isFile()) {
+ list += path_ + entry;
+ } else if(curEntry->isDirectory()) {
+ list += archiveFiles(static_cast<const KArchiveDirectory*>(curEntry), path_ + entry + '/');
+ // add directory AFTER contents, since we delete from the top down later
+ list += path_ + entry + '/';
+ }
+ }
+
+ return list;
+}
+
+// don't recurse, the .xsl must be in top directory
+QString Manager::findXSL(const KArchiveDirectory* dir_) {
+ const QStringList entries = dir_->entries();
+ for(QStringList::ConstIterator it = entries.begin(); it != entries.end(); ++it) {
+ const QString& entry = *it;
+ if(entry.endsWith(QString::fromLatin1(".xsl"))) {
+ return entry;
+ }
+ }
+ return QString();
+}
+
+QString Manager::findEXE(const KArchiveDirectory* dir_) {
+ QPtrStack<KArchiveDirectory> dirStack;
+ QValueStack<QString> dirNameStack;
+
+ dirStack.push(dir_);
+ dirNameStack.push(QString());
+
+ do {
+ const QString dirName = dirNameStack.pop();
+ const KArchiveDirectory* curDir = dirStack.pop();
+ const QStringList entries = curDir->entries();
+ for(QStringList::ConstIterator it = entries.begin(); it != entries.end(); ++it) {
+ const QString& entry = *it;
+ const KArchiveEntry* archEntry = curDir->entry(entry);
+
+ if(archEntry->isFile() && (archEntry->permissions() & S_IEXEC)) {
+ return dirName + entry;
+ } else if(archEntry->isDirectory()) {
+ dirStack.push(static_cast<const KArchiveDirectory*>(archEntry));
+ dirNameStack.push(dirName + entry + '/');
+ }
+ }
+ } while(!dirStack.isEmpty());
+
+ return QString();
+}
+
+void Manager::install(DataType type_, KNS::Entry* entry_) {
+ if(m_tempFile) {
+ delete m_tempFile;
+ }
+ m_tempFile = new KTempFile();
+ m_tempFile->setAutoDelete(true);
+
+ KURL destination;
+ destination.setPath(m_tempFile->name());
+ KIO::FileCopyJob* job = KIO::file_copy(entry_->payload(), destination, -1, true);
+ connect(job, SIGNAL(result(KIO::Job*)), SLOT(slotDownloadJobResult(KIO::Job*)));
+ m_jobMap.insert(job, EntryPair(entry_, type_));
+}
+
+void Manager::slotDownloadJobResult(KIO::Job* job_) {
+ KIO::FileCopyJob* job = static_cast<KIO::FileCopyJob*>(job_);
+ if(job->error()) {
+ GUI::CursorSaver cs(Qt::arrowCursor);
+ delete m_tempFile;
+ m_tempFile = 0;
+ job->showErrorDialog(Kernel::self()->widget());
+ emit signalInstalled(0); // still need to notify dialog that install failed
+ return;
+ }
+
+ KNS::Entry* entry = m_jobMap[job_].first;
+ DataType type = m_jobMap[job_].second;
+
+ bool deleteTempFile = true;
+ if(type == EntryTemplate) {
+ installTemplate(job->destURL(), entry->name());
+ } else {
+#if KDE_IS_VERSION(3,3,90)
+ // needed so the GPG signature can be checked
+ NewScript* newScript = new NewScript(this, Kernel::self()->widget());
+ connect(newScript, SIGNAL(installFinished()), this, SLOT(slotInstallFinished()));
+ // need to delete temp file if install was not a success
+ // if it was a success, it gets deleted later
+ deleteTempFile = !newScript->install(job->destURL().path());
+ m_scriptEntryMap.insert(newScript, entry);
+#endif
+ // if failed, emit empty signal now
+ if(deleteTempFile) {
+ emit signalInstalled(0);
+ }
+ }
+ if(deleteTempFile) {
+ delete m_tempFile;
+ m_tempFile = 0;
+ }
+}
+
+void Manager::slotInstallFinished() {
+ const NewScript* newScript = ::qt_cast<const NewScript*>(sender());
+ if(newScript && newScript->successfulInstall()) {
+ const QString name = m_urlNameMap[newScript->url()];
+ KNS::Entry* entry = m_scriptEntryMap[newScript];
+ KConfigGroup config(KGlobal::config(), "KNewStuffStatus");
+ // have to keep a config entry that maps the name of the file to the name
+ // of the newstuff entry, so we can track which entries are installed
+ // name and entry-name() are probably the same for scripts, but not a problem
+ config.writeEntry(name, entry->name());
+ config.writeEntry(entry->name(), entry->releaseDate().toString(Qt::ISODate));
+ config.sync();
+ emit signalInstalled(entry);
+ } else {
+ emit signalInstalled(0);
+ kdWarning() << "Manager::slotInstallFinished() - Failed to install" << endl;
+ }
+ delete m_tempFile;
+ m_tempFile = 0;
+}
+
+bool Manager::checkCommonFile() {
+ // look for a file that gets installed to know the installation directory
+ // need to check timestamps
+ QString userDataDir = Tellico::saveLocation(QString::null);
+ QString userCommonFile = userDataDir + '/' + QString::fromLatin1("tellico-common.xsl");
+ if(QFile::exists(userCommonFile)) {
+ // check timestamps
+ // pics/tellico.png is not likely to be in a user directory
+ QString installDir = KGlobal::dirs()->findResourceDir("appdata", QString::fromLatin1("pics/tellico.png"));
+ QString installCommonFile = installDir + '/' + QString::fromLatin1("tellico-common.xsl");
+#ifndef NDEBUG
+ if(userCommonFile == installCommonFile) {
+ kdWarning() << "Manager::checkCommonFile() - install location is same as user location" << endl;
+ }
+#endif
+ QFileInfo installInfo(installCommonFile);
+ QFileInfo userInfo(userCommonFile);
+ if(installInfo.lastModified() > userInfo.lastModified()) {
+ // the installed file has been modified more recently than the user's
+ // remove user's tellico-common.xsl file so it gets copied again
+ myLog() << "Manager::checkCommonFile() - removing " << userCommonFile << endl;
+ myLog() << "Manager::checkCommonFile() - copying " << installCommonFile << endl;
+ QFile::remove(userCommonFile);
+ } else {
+ return true;
+ }
+ }
+ KURL src, dest;
+ src.setPath(KGlobal::dirs()->findResource("appdata", QString::fromLatin1("tellico-common.xsl")));
+ dest.setPath(userCommonFile);
+ return KIO::NetAccess::file_copy(src, dest);
+}
+
+#include "manager.moc"
diff --git a/src/newstuff/manager.h b/src/newstuff/manager.h
new file mode 100644
index 0000000..4102be3
--- /dev/null
+++ b/src/newstuff/manager.h
@@ -0,0 +1,101 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_NEWSTUFF_MANAGER_H
+#define TELLICO_NEWSTUFF_MANAGER_H
+
+class KArchiveDirectory;
+class KURL;
+class KTempFile;
+
+#include <qobject.h>
+#include <qptrlist.h>
+
+class QStringList;
+
+namespace KNS {
+ class Entry;
+}
+namespace KIO {
+ class Job;
+}
+
+namespace Tellico {
+ namespace NewStuff {
+
+class NewScript;
+
+enum DataType {
+ EntryTemplate,
+ DataScript
+};
+
+enum InstallStatus {
+ NotInstalled,
+ OldVersion,
+ Current
+};
+
+struct DataSourceInfo {
+ DataSourceInfo() : isUpdate(false) {}
+ QString specFile; // full path of .spec file
+ QString sourceName;
+ QString sourceExec; // full executable path of script
+ bool isUpdate : 1; // whether the info is for an updated source
+};
+
+class Manager : public QObject {
+Q_OBJECT
+
+public:
+ Manager(QObject* parent);
+ ~Manager();
+
+ void install(DataType type, KNS::Entry* entry);
+ QPtrList<DataSourceInfo> dataSourceInfo() const { return m_infoList; }
+
+ bool installTemplate(const KURL& url, const QString& entryName = QString::null);
+ bool removeTemplate(const QString& name);
+
+ bool installScript(const KURL& url);
+ bool removeScript(const QString& name);
+
+ static InstallStatus installStatus(KNS::Entry* entry);
+ static bool checkCommonFile();
+
+signals:
+ void signalInstalled(KNS::Entry* entry);
+
+private slots:
+ void slotDownloadJobResult(KIO::Job* job);
+ void slotInstallFinished();
+
+private:
+ static QStringList archiveFiles(const KArchiveDirectory* dir,
+ const QString& path = QString::null);
+
+ static QString findXSL(const KArchiveDirectory* dir);
+ static QString findEXE(const KArchiveDirectory* dir);
+
+ typedef QPair<KNS::Entry*, DataType> EntryPair;
+ QMap<KIO::Job*, EntryPair> m_jobMap;
+ QMap<KURL, QString> m_urlNameMap;
+ QMap<const NewScript*, KNS::Entry*> m_scriptEntryMap;
+ QPtrList<DataSourceInfo> m_infoList;
+ KTempFile* m_tempFile;
+};
+
+ }
+}
+
+#endif
diff --git a/src/newstuff/newscript.cpp b/src/newstuff/newscript.cpp
new file mode 100644
index 0000000..045f881
--- /dev/null
+++ b/src/newstuff/newscript.cpp
@@ -0,0 +1,48 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "newscript.h"
+#include "manager.h"
+
+#include <kurl.h>
+
+#include <qwidget.h>
+
+using Tellico::NewStuff::NewScript;
+
+NewScript::NewScript(Manager* manager_, QWidget* parentWidget_)
+#if KDE_IS_VERSION(3,3,90)
+ : KNewStuffSecure(QString::fromLatin1("tellico/data-source"), parentWidget_)
+#else
+ : QObject(parentWidget_)
+#endif
+ , m_manager(manager_), m_success(false) {
+}
+
+void NewScript::installResource() {
+ // m_tarName is protected in superclass
+ KURL u;
+ u.setPath(m_tarName);
+ m_success = m_manager->installScript(u);
+ m_url = u;
+}
+
+#if KDE_IS_VERSION(3,3,90)
+#include <knewstuff/knewstuffsecure.h>
+#define SUPERCLASS KNewStuffSecure
+#else
+#define SUPERCLASS QObject
+#endif
+
+#include "newscript.moc"
+#undef SUPERCLASS
diff --git a/src/newstuff/newscript.h b/src/newstuff/newscript.h
new file mode 100644
index 0000000..8bc3154
--- /dev/null
+++ b/src/newstuff/newscript.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_NEWSTUFF_NEWSCRIPT_H
+#define TELLICO_NEWSTUFF_NEWSCRIPT_H
+
+#include <kdeversion.h>
+#include <kurl.h>
+
+#if KDE_IS_VERSION(3,3,90)
+#include <knewstuff/knewstuffsecure.h>
+#define SUPERCLASS KNewStuffSecure
+#else
+#define SUPERCLASS QObject
+#endif
+
+#include <qobject.h>
+
+namespace Tellico {
+ namespace NewStuff {
+
+class Manager;
+
+class NewScript : public SUPERCLASS {
+Q_OBJECT
+
+public:
+ NewScript(Manager* manager, QWidget* parentWidget = 0);
+ virtual ~NewScript() {}
+
+ const KURL& url() const { return m_url; }
+ bool successfulInstall() const { return m_success; }
+
+private:
+ virtual void installResource();
+
+ Manager* m_manager;
+#if !KDE_IS_VERSION(3,3,90)
+ // KNewStuffSecure has a protected variable
+ QString m_tarName;
+#endif
+ KURL m_url;
+ bool m_success : 1;
+};
+
+ }
+}
+
+#undef SUPERCLASS
+#endif
diff --git a/src/newstuff/providerloader.cpp b/src/newstuff/providerloader.cpp
new file mode 100644
index 0000000..b3f95ae
--- /dev/null
+++ b/src/newstuff/providerloader.cpp
@@ -0,0 +1,102 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+// this class is largely copied from kdelibs/knewstuff/provider.cpp
+// which is Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
+// and licensed under GPL v2, just like Tellico
+
+#include "providerloader.h"
+#include "../tellico_debug.h"
+#include "../latin1literal.h"
+
+#include <kio/job.h>
+#include <knewstuff/provider.h>
+#include <kglobal.h>
+#include <kconfig.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+
+#include <qdom.h>
+
+using Tellico::NewStuff::ProviderLoader;
+
+ProviderLoader::ProviderLoader( QWidget *parentWidget ) :
+ mParentWidget( parentWidget ), mTryAlt(true)
+{
+ mProviders.setAutoDelete( true );
+}
+
+void ProviderLoader::load( const QString &type, const QString &providersList )
+{
+ mProviders.clear();
+ mJobData.truncate(0);
+
+// myLog() << "ProviderLoader::load(): providersList: " << providersList << endl;
+
+ KIO::TransferJob *job = KIO::get( KURL( providersList ), false, false );
+ connect( job, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotJobResult( KIO::Job * ) ) );
+ connect( job, SIGNAL( data( KIO::Job *, const QByteArray & ) ),
+ SLOT( slotJobData( KIO::Job *, const QByteArray & ) ) );
+ connect( job, SIGNAL( percent (KIO::Job *, unsigned long) ),
+ SIGNAL( percent (KIO::Job *, unsigned long) ) );
+
+// job->dumpObjectInfo();
+}
+
+void ProviderLoader::slotJobData( KIO::Job *, const QByteArray &data )
+{
+ if ( data.size() == 0 ) return;
+ QCString str( data, data.size() + 1 );
+ mJobData.append( QString::fromUtf8( str ) );
+}
+
+void ProviderLoader::slotJobResult( KIO::Job *job )
+{
+ if ( job->error() ) {
+ job->showErrorDialog( mParentWidget );
+ if(mTryAlt && !mAltProvider.isEmpty()) {
+ mTryAlt = false;
+ load(QString(), mAltProvider);
+ } else {
+ emit error();
+ }
+ return;
+ }
+
+ QDomDocument doc;
+ if ( !doc.setContent( mJobData ) ) {
+ myDebug() << "ProviderLoader::slotJobResult() - error parsing providers list." << endl;
+ if(mTryAlt && !mAltProvider.isEmpty()) {
+ mTryAlt = false;
+ load(QString(), mAltProvider);
+ } else {
+ emit error();
+ }
+ return;
+ }
+
+ QDomElement providers = doc.documentElement();
+ QDomNode n;
+ for ( n = providers.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ QDomElement p = n.toElement();
+
+ if ( p.tagName() == Latin1Literal("provider") ) {
+ mProviders.append( new KNS::Provider( p ) );
+ }
+ }
+
+ emit providersLoaded( &mProviders );
+}
+
+#include "providerloader.moc"
diff --git a/src/newstuff/providerloader.h b/src/newstuff/providerloader.h
new file mode 100644
index 0000000..3d2968c
--- /dev/null
+++ b/src/newstuff/providerloader.h
@@ -0,0 +1,84 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+// this class is largely copied from kdelibs/knewstuff/provider.h
+// which is Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
+// and licensed under GPL v2, just like Tellico
+//
+// I want progress info for the download, and this was the
+// easiest way to get it
+
+#ifndef TELLICO_NEWSTUFF_PROVIDERLOADER_H
+#define TELLICO_NEWSTUFF_PROVIDERLOADER_H
+
+#include <qobject.h>
+#include <qptrlist.h>
+
+namespace KIO {
+ class Job;
+}
+namespace KNS {
+ class Provider;
+}
+
+namespace Tellico {
+ namespace NewStuff {
+
+class ProviderLoader : public QObject {
+Q_OBJECT
+public:
+ /**
+ * Constructor.
+ *
+ * @param parentWidget the parent widget
+ */
+ ProviderLoader( QWidget *parentWidget );
+
+ /**
+ * Starts asynchronously loading the list of providers of the
+ * specified type.
+ *
+ * @param type data type such as 'kdesktop/wallpaper'.
+ * @param providerList the URl to the list of providers; if empty
+ * we first try the ProvidersUrl from KGlobal::config, then we
+ * fall back to a hardcoded value.
+ */
+ void load( const QString &type, const QString &providerList = QString::null );
+
+ void setAlternativeProvider(const QString& alt) { mAltProvider = alt; }
+
+ signals:
+ /**
+ * Indicates that the list of providers has been successfully loaded.
+ */
+ void providersLoaded( QPtrList<KNS::Provider>* );
+ void percent(KIO::Job *job, unsigned long percent);
+ void error();
+
+ protected slots:
+ void slotJobData( KIO::Job *, const QByteArray & );
+ void slotJobResult( KIO::Job * );
+
+ private:
+ QWidget *mParentWidget;
+
+ QString mJobData;
+
+ QPtrList<KNS::Provider> mProviders;
+ QString mAltProvider;
+ bool mTryAlt;
+};
+
+ }
+}
+#endif
diff --git a/src/observer.h b/src/observer.h
new file mode 100644
index 0000000..f8f7661
--- /dev/null
+++ b/src/observer.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_OBSERVER_H
+#define TELLICO_OBSERVER_H
+
+#include "datavectors.h"
+
+namespace Tellico {
+ class Filter;
+
+/**
+ * @author Robby Stephenson
+ */
+class Observer {
+
+public:
+ virtual ~Observer() {}
+
+ virtual void addBorrower(Data::BorrowerPtr) {}
+ virtual void modifyBorrower(Data::BorrowerPtr) {}
+ // no removeBorrower()
+
+ virtual void addEntries(Data::EntryVec) {}
+ virtual void modifyEntries(Data::EntryVec) {}
+ virtual void removeEntries(Data::EntryVec) {}
+
+ virtual void addField(Data::CollPtr, Data::FieldPtr) {}
+ // coll, oldfield, newfield
+ virtual void modifyField(Data::CollPtr, Data::FieldPtr, Data::FieldPtr) {}
+ virtual void removeField(Data::CollPtr, Data::FieldPtr) {}
+
+ virtual void addFilter(FilterPtr) {}
+ virtual void modifyFilter(FilterPtr) {}
+ virtual void removeFilter(FilterPtr) {}
+};
+
+}
+
+#endif
diff --git a/src/progressmanager.cpp b/src/progressmanager.cpp
new file mode 100644
index 0000000..a487710
--- /dev/null
+++ b/src/progressmanager.cpp
@@ -0,0 +1,183 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "progressmanager.h"
+#include "tellico_debug.h"
+
+#include <qtimer.h>
+
+using Tellico::ProgressItem;
+using Tellico::ProgressManager;
+ProgressManager* ProgressManager::s_self = 0;
+
+ProgressItem::Done::~Done() {
+ ProgressManager::self()->setDone(m_object);
+}
+
+ProgressItem::ProgressItem(const QString& label_, bool canCancel_)
+ : m_label(label_)
+ , m_canCancel(canCancel_)
+ , m_progress(0)
+ , m_total(0)
+ , m_cancelled(false) {
+}
+
+ProgressItem::~ProgressItem() {
+// myDebug() << "~ProgressItem() - " << m_label << endl;
+}
+
+void ProgressItem::setProgress(uint steps_) {
+ m_progress = steps_;
+ emit signalProgress(this);
+
+ if(m_progress >= m_total) {
+ setDone();
+ }
+}
+
+void ProgressItem::setTotalSteps(uint steps_) {
+ m_total = steps_;
+ emit signalTotalSteps(this);
+}
+
+void ProgressItem::setDone() {
+ if(!m_cancelled) {
+ m_progress = m_total;
+ }
+ emit signalDone(this);
+ // make sure the deleting doesn't interfere with anything
+ QTimer::singleShot(3000, this, SLOT(deleteLater()));
+}
+
+void ProgressItem::cancel() {
+// myDebug() << "ProgressItem::cancel()" << endl;
+ if(!m_canCancel || m_cancelled) {
+ return;
+ }
+
+ m_cancelled = true;
+ emit signalCancelled(this);
+}
+
+ProgressManager::ProgressManager() : QObject() {
+}
+
+void ProgressManager::setProgress(const QObject* owner_, uint steps_) {
+ if(!m_items.contains(owner_)) {
+ return;
+ }
+
+ m_items[owner_] ->setProgress(steps_);
+// slotUpdateTotalProgress(); // called in ProgressItem::setProgress()
+// emit signalItemProgress(m_items[owner_]);
+}
+
+void ProgressManager::setTotalSteps(const QObject* owner_, uint steps_) {
+ if(!m_items.contains(owner_)) {
+ return;
+ }
+
+ m_items[owner_]->setTotalSteps(steps_);
+// updateTotalProgress(); // called in ProgressItem::setTotalSteps()
+}
+
+void ProgressManager::setDone(const QObject* owner_) {
+ if(!m_items.contains(owner_)) {
+ return;
+ }
+ setDone(m_items[owner_]);
+}
+
+void ProgressManager::setDone(ProgressItem* item_) {
+ if(!item_) {
+ myDebug() << "ProgressManager::setDone() - null ProgressItem!" << endl;
+ return;
+ }
+ item_->setDone();
+// updateTotalProgress();
+}
+
+void ProgressManager::slotItemDone(ProgressItem* item_) {
+// cancel ends up removing it from the map, so make a copy
+ ProgressMap map = m_items;
+ for(ProgressMap::Iterator it = map.begin(); it != map.end(); ++it) {
+ if(static_cast<ProgressItem*>(it.data()) == item_) {
+ m_items.remove(it.key());
+ break;
+ }
+ }
+ slotUpdateTotalProgress();
+// emit signalItemDone(item_);
+}
+
+ProgressItem& ProgressManager::newProgressItemImpl(const QObject* owner_,
+ const QString& label_,
+ bool canCancel_) {
+// myDebug() << "ProgressManager::newProgressItem() - " << owner_->className() << ":" << label_ << endl;
+ if(m_items.contains(owner_)) {
+ return *m_items[owner_];
+ }
+
+ ProgressItem* item = new ProgressItem(label_, canCancel_);
+ m_items.insert(owner_, item);
+
+ connect(item, SIGNAL(signalTotalSteps(ProgressItem*)), SLOT(slotUpdateTotalProgress()));
+ connect(item, SIGNAL(signalProgress(ProgressItem*)), SLOT(slotUpdateTotalProgress()));
+ connect(item, SIGNAL(signalDone(ProgressItem*)), SLOT(slotUpdateTotalProgress()));
+ connect(item, SIGNAL(signalDone(ProgressItem*)), SLOT(slotItemDone(ProgressItem*)));
+
+// connect(item, SIGNAL(signalProgress(ProgressItem*)), SIGNAL(signalItemProgress(ProgressItem*)));
+// emit signalItemAdded(item);
+ return *item;
+}
+
+void ProgressManager::slotUpdateTotalProgress() {
+ uint progress = 0;
+ uint total = 0;
+
+ for(ProgressMap::ConstIterator it = m_items.begin(); it != m_items.end(); ++it) {
+ if(it.data()) {
+ progress += (*it)->progress();
+ total += (*it)->totalSteps();
+ }
+ }
+
+ if(total == 0) {
+ emit signalTotalProgress(100);
+ return;
+ }
+
+ emit signalTotalProgress(100*progress/total);
+}
+
+void ProgressManager::slotCancelAll() {
+// cancel ends up removing it from the map, so make a copy
+ ProgressMap map = m_items;
+ for(ProgressMap::ConstIterator it = map.begin(), end = map.end(); it != end; ++it) {
+ if(it.data()) {
+ it.data()->cancel();
+ setDone(it.data());
+ }
+ }
+}
+
+bool ProgressManager::anyCanBeCancelled() const {
+ for(ProgressMap::ConstIterator it = m_items.begin(), end = m_items.end(); it != end; ++it) {
+ if(it.data() && it.data()->canCancel()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+#include "progressmanager.moc"
diff --git a/src/progressmanager.h b/src/progressmanager.h
new file mode 100644
index 0000000..5eaac3b
--- /dev/null
+++ b/src/progressmanager.h
@@ -0,0 +1,127 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+// much of this code is adapted from libkdepim
+// which is GPL licensed, Copyright (c) 2004 Till Adam
+
+#ifndef TELLICO_PROGRESSMANAGER_H
+#define TELLICO_PROGRESSMANAGER_H
+
+#include <qobject.h>
+#include <qmap.h>
+#include <qguardedptr.h>
+
+namespace Tellico {
+
+class ProgressManager;
+
+/**
+ * @author Robby Stephenson
+ */
+class ProgressItem : public QObject {
+Q_OBJECT
+
+friend class ProgressManager;
+
+public:
+ class Done {
+ public:
+ Done(const QObject* obj) : m_object(obj) {}
+ ~Done();
+ private:
+ const QObject* m_object;
+ };
+
+ bool canCancel() const { return m_canCancel; }
+ const QString& label() const { return m_label; }
+ void setLabel(const QString& label);
+
+// uint progress() const { return m_total ? (100*m_completed/m_total) : 0; }
+ uint progress() const { return m_progress; }
+ void setProgress(uint steps);
+ uint totalSteps() const { return m_total; }
+ void setTotalSteps(uint steps);
+ void setDone();
+
+ void cancel();
+
+signals:
+ void signalProgress(ProgressItem* item);
+ void signalDone(ProgressItem* item);
+ void signalCancelled(ProgressItem* item);
+ void signalTotalSteps(ProgressItem* item);
+
+protected:
+ /* Only to be used by the ProgressManager */
+ ProgressItem(const QString& label, bool canCancel);
+ virtual ~ProgressItem();
+
+private:
+ QString m_label;
+ bool m_canCancel;
+ uint m_progress;
+ uint m_total;
+ bool m_cancelled;
+};
+
+/**
+ * @author Robby Stephenson
+ */
+class ProgressManager : public QObject {
+Q_OBJECT
+
+public:
+ virtual ~ProgressManager() {}
+
+ static ProgressManager* self() { if(!s_self) s_self = new ProgressManager(); return s_self; }
+
+ ProgressItem& newProgressItem(const QObject* owner, const QString& label, bool canCancel = false) {
+ return newProgressItemImpl(owner, label, canCancel);
+ }
+
+ void setProgress(const QObject* owner, uint steps);
+ void setTotalSteps(const QObject* owner, uint steps);
+ void setDone(const QObject* owner);
+
+ bool anyCanBeCancelled() const;
+
+signals:
+// void signalItemAdded(ProgressItem* item);
+// void signalItemProgress(ProgressItem* item);
+// void signalItemDone(ProgressItem* item);
+// void signalItemCancelled(ProgressItem* item);
+ void signalTotalProgress(uint progress);
+
+public slots:
+ void slotCancelAll();
+
+private slots:
+ void slotItemDone(ProgressItem* item);
+ void slotUpdateTotalProgress();
+
+private:
+ ProgressManager();
+ ProgressManager(const ProgressManager&); // no copies
+
+ ProgressItem& newProgressItemImpl(const QObject* owner, const QString& label, bool canCancel);
+ void setDone(ProgressItem* item);
+
+ typedef QMap<QGuardedPtr<const QObject>, QGuardedPtr<ProgressItem> > ProgressMap;
+ ProgressMap m_items;
+
+ static ProgressManager* s_self;
+};
+
+} // end namespace
+
+#endif
diff --git a/src/ptrvector.h b/src/ptrvector.h
new file mode 100644
index 0000000..1dd66ea
--- /dev/null
+++ b/src/ptrvector.h
@@ -0,0 +1,322 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_PTRVECTOR_H
+#define TELLICO_PTRVECTOR_H
+
+#include <kdebug.h>
+#include <ksharedptr.h>
+
+#include <qvaluevector.h>
+
+namespace Tellico {
+
+template <class T> class Vector;
+template <class T> class VectorIterator;
+template <class T> class VectorConstIterator;
+template <class T> bool operator==(const VectorIterator<T>& left, const VectorIterator<T>& right);
+template <class T> bool operator!=(const VectorIterator<T>& left, const VectorIterator<T>& right);
+template <class T> bool operator==(const VectorConstIterator<T>& left, const VectorConstIterator<T>& right);
+template <class T> bool operator!=(const VectorConstIterator<T>& left, const VectorConstIterator<T>& right);
+
+template <class T>
+class VectorIterator {
+public:
+ VectorIterator() : m_vector(0), m_index(0) {}
+ VectorIterator(Vector<T>* vector, size_t index) : m_vector(vector), m_index(index) {}
+ VectorIterator(const VectorIterator<T>& other) : m_vector(other.m_vector), m_index(other.m_index) {}
+
+// operator T*() { return m_vector->at(m_index).data(); }
+ operator KSharedPtr<T>() { return m_vector->at(m_index); }
+ T* operator->() { return m_vector->at(m_index).data(); }
+ T& operator*() { return *m_vector->at(m_index); }
+ T* data() { return m_vector->at(m_index).data(); }
+
+ VectorIterator& operator++() { ++m_index; return *this; }
+ VectorIterator& operator--() { --m_index; return *this; }
+
+ friend bool operator==(const VectorIterator<T>& left, const VectorIterator<T>& right)
+ { return left.m_vector == right.m_vector && left.m_index == right.m_index; }
+ friend bool operator!=(const VectorIterator<T>& left, const VectorIterator<T>& right)
+ { return left.m_vector != right.m_vector || left.m_index != right.m_index; }
+
+ bool nextEnd() const { return m_index == m_vector->count()-1; }
+
+private:
+ friend class Vector<T>;
+ Vector<T>* m_vector;
+ size_t m_index;
+};
+
+template <class T>
+class VectorConstIterator {
+public:
+ VectorConstIterator() : m_vector(0), m_index(0) {}
+ VectorConstIterator(const Vector<T>* vector, size_t index) : m_vector(vector), m_index(index) {}
+ VectorConstIterator(const VectorIterator<T>& other) : m_vector(other.m_vector), m_index(other.m_index) {}
+
+// operator const T*() { return m_vector->at(m_index).data(); }
+ operator KSharedPtr<const T>() { return m_vector->at(m_index); }
+ const T* operator->() const { return m_vector->at(m_index).data(); }
+ const T& operator*() const { return *m_vector->at(m_index); }
+ const T* data() const { return m_vector->at(m_index).data(); }
+
+ VectorConstIterator& operator++() { ++m_index; return *this; }
+ VectorConstIterator& operator--() { --m_index; return *this; }
+
+ friend bool operator==(const VectorConstIterator<T>& left, const VectorConstIterator<T>& right)
+ { return left.m_vector == right.m_vector && left.m_index == right.m_index; }
+ friend bool operator!=(const VectorConstIterator<T>& left, const VectorConstIterator<T>& right)
+ { return left.m_vector != right.m_vector || left.m_index != right.m_index; }
+
+ bool nextEnd() const { return m_index == m_vector->count()-1; }
+
+private:
+ friend class Vector<T>;
+ const Vector<T>* m_vector;
+ size_t m_index;
+};
+
+template <class T>
+class Vector {
+public:
+ typedef KSharedPtr<T> Ptr;
+ typedef VectorIterator<T> Iterator;
+ typedef VectorConstIterator<T> ConstIterator;
+
+ Vector() {}
+ Vector(Ptr t) { append(t); }
+ Vector(const Vector<T>& v) : m_baseVector(v.m_baseVector) {}
+ Vector& operator=(const Vector<T>& other) {
+ if(this != &other) {
+ m_baseVector = other.m_baseVector;
+ }
+ return *this;
+ }
+
+ bool operator== (const Vector<T>& x) const { return x.m_baseVector == m_baseVector; }
+ bool isEmpty() const { return m_baseVector.empty(); }
+ size_t count() const { return m_baseVector.size(); }
+
+ Ptr& operator[](size_t i) { return m_baseVector[i]; }
+ const Ptr& operator[](size_t i) const { return m_baseVector[i]; }
+
+ Ptr& at(size_t i, bool* ok = 0) { return m_baseVector.at(i, ok); }
+ const Ptr& at(size_t i, bool* ok = 0) const { return m_baseVector.at(i, ok); }
+
+ Iterator begin() { return Iterator(this, 0); }
+ ConstIterator begin() const { return ConstIterator(this, 0); }
+ ConstIterator constBegin() const { return ConstIterator(this, 0); }
+ Iterator end() { return Iterator(this, count()); }
+ ConstIterator end() const { return ConstIterator(this, count()); }
+ ConstIterator constEnd() const { return ConstIterator(this, count()); }
+
+ Ptr& front() { return at(0); }
+ const Ptr& front() const { return at(0); }
+ Ptr& back() { return at(count()-1); }
+ const Ptr& back() const { return at(count()-1); }
+
+ void clear() { m_baseVector.clear(); }
+ void append(Ptr t) { m_baseVector.append(t); }
+ void append(Vector<T> v);
+
+ void insert(Iterator pos, Ptr t) {
+ m_baseVector.insert(&m_baseVector[pos.m_index], t);
+ }
+
+ Iterator find(Ptr t) {
+ for(size_t i = 0; i < count(); ++i) {
+ if(m_baseVector[i].data() == t) {
+ return Iterator(this, i);
+ }
+ }
+ return end();
+ }
+
+ bool contains(Ptr t) const { return qFind(m_baseVector.begin(), m_baseVector.end(), Ptr(t)) != m_baseVector.end(); }
+ bool remove(const Ptr& t) {
+ Ptr* it = qFind(m_baseVector.begin(), m_baseVector.end(), t);
+ if(it == m_baseVector.end()) return false;
+ m_baseVector.erase(it);
+ return true;
+ }
+
+private:
+ QValueVector<Ptr> m_baseVector;
+};
+
+template <class T> class PtrVector;
+template <class T> class PtrVectorIterator;
+template <class T> class PtrVectorConstIterator;
+template <class T> bool operator==(const PtrVectorIterator<T>& left, const PtrVectorIterator<T>& right);
+template <class T> bool operator!=(const PtrVectorIterator<T>& left, const PtrVectorIterator<T>& right);
+template <class T> bool operator==(const PtrVectorConstIterator<T>& left, const PtrVectorConstIterator<T>& right);
+template <class T> bool operator!=(const PtrVectorConstIterator<T>& left, const PtrVectorConstIterator<T>& right);
+
+template <class T>
+class PtrVectorIterator {
+public:
+ PtrVectorIterator() : m_vector(0), m_index(0) {}
+ PtrVectorIterator(const PtrVector<T>* vector, size_t index) : m_vector(vector), m_index(index) {}
+ PtrVectorIterator(const PtrVectorIterator<T>& other) : m_vector(other.m_vector), m_index(other.m_index) {}
+
+ T* operator->() { return &m_vector->at(m_index); }
+ T& operator*() { return m_vector->at(m_index); }
+
+ T* ptr() { return &m_vector->at(m_index); }
+
+ PtrVectorIterator& operator++() { ++m_index; return *this; }
+ PtrVectorIterator& operator--() { --m_index; return *this; }
+
+ friend bool operator==(const PtrVectorIterator<T>& left, const PtrVectorIterator<T>& right)
+ { return left.m_vector == right.m_vector && left.m_index == right.m_index; }
+ friend bool operator!=(const PtrVectorIterator<T>& left, const PtrVectorIterator<T>& right)
+ { return left.m_vector != right.m_vector || left.m_index != right.m_index; }
+
+private:
+ const PtrVector<T>* m_vector;
+ size_t m_index;
+};
+
+template <class T>
+class PtrVectorConstIterator {
+public:
+ PtrVectorConstIterator() : m_vector(0), m_index(0) {}
+ PtrVectorConstIterator(const PtrVector<T>* vector, size_t index) : m_vector(vector), m_index(index) {}
+ PtrVectorConstIterator(const PtrVectorConstIterator<T>& other) : m_vector(other.m_vector), m_index(other.m_index) {}
+
+ const T* operator->() const { return &m_vector->at(m_index); }
+ const T& operator*() const { return m_vector->at(m_index); }
+
+ const T* ptr() const { return &m_vector->at(m_index); }
+
+ PtrVectorConstIterator& operator++() { ++m_index; return *this; }
+ PtrVectorConstIterator& operator--() { --m_index; return *this; }
+
+ friend bool operator==(const PtrVectorConstIterator<T>& left, const PtrVectorConstIterator<T>& right)
+ { return left.m_vector == right.m_vector && left.m_index == right.m_index; }
+ friend bool operator!=(const PtrVectorConstIterator<T>& left, const PtrVectorConstIterator<T>& right)
+ { return left.m_vector != right.m_vector || left.m_index != right.m_index; }
+
+private:
+ const PtrVector<T>* m_vector;
+ size_t m_index;
+};
+
+/**
+ * @author Robby Stephenson
+ */
+template <class T>
+class PtrVector {
+
+public:
+ typedef Tellico::PtrVectorIterator<T> Iterator;
+ typedef Tellico::PtrVectorConstIterator<T> ConstIterator;
+
+ PtrVector() : m_autoDelete(false) {}
+ PtrVector(const PtrVector<T>& other) : m_baseVector(other.m_baseVector), m_autoDelete(false) {}
+ PtrVector& operator=(const PtrVector<T>& other) {
+ if(this != &other) {
+ m_baseVector = other.m_baseVector;
+ m_autoDelete = false;
+ }
+ return *this;
+ }
+ ~PtrVector() { if(m_autoDelete) clear(); }
+
+ size_t count() const { return m_baseVector.size(); }
+ bool isEmpty() const { return m_baseVector.empty(); }
+ bool autoDelete() const { return m_autoDelete; }
+ void setAutoDelete(bool b) { m_autoDelete = b; }
+
+ T& operator[](size_t n) const { check(n); return *m_baseVector[n]; }
+ T& at(size_t n) const { check(n); return *m_baseVector.at(n); }
+
+ Iterator begin() { return Iterator(this, 0); }
+ ConstIterator begin() const { return ConstIterator(this, 0); }
+ ConstIterator constBegin() const { return ConstIterator(this, 0); }
+ Iterator end() { return Iterator(this, count()); }
+ ConstIterator end() const { return ConstIterator(this, count()); }
+ ConstIterator constEnd() const { return ConstIterator(this, count()); }
+
+ T* front() { return count() > 0 ? m_baseVector.at(0) : 0; }
+ const T* front() const { return count() > 0 ? m_baseVector.at(0) : 0; }
+ T* back() { return count() > 0 ? m_baseVector.at(count()-1) : 0; }
+ const T* back() const { return count() > 0 ? m_baseVector.at(count()-1) : 0; }
+
+ void clear() { while(remove(begin())) { ; } }
+
+ void push_back(T* ptr) { m_baseVector.push_back(ptr); }
+ bool remove(T* ptr);
+ bool remove(Iterator it);
+ bool contains(const T* ptr) const;
+
+private:
+#ifndef NDEBUG
+ void check(size_t n) const { if(n >= count()) kdDebug() << "PtrVector() - bad index" << endl; }
+#else
+ void check(size_t) const {}
+#endif
+
+ QValueVector<T*> m_baseVector;
+ bool m_autoDelete : 1;
+};
+
+}
+
+template <class T>
+void Tellico::Vector<T>::append(Tellico::Vector<T> v) {
+ typename Tellico::Vector<T>::Iterator it;
+ for(it = v.begin(); it != v.end(); ++it) {
+ append(it.data());
+ }
+}
+
+template <class T>
+bool Tellico::PtrVector<T>::remove(T* t) {
+ if(!t) {
+ return false;
+ }
+ T** ptr = qFind(m_baseVector.begin(), m_baseVector.end(), t);
+ if(ptr == m_baseVector.end()) {
+ return false;
+ }
+ if(m_autoDelete) {
+ delete *ptr;
+ }
+ m_baseVector.erase(ptr);
+ // in case the pointer is in the vector multiple times
+ while(remove(t)) {
+ kdDebug() << "PtrVector::remove() - pointer was duplicated in vector" << endl;
+ }
+ return true;
+}
+
+template <class T>
+bool Tellico::PtrVector<T>::remove(Iterator it) {
+ if(it == end()) {
+ return false;
+ }
+ return remove(it.ptr());
+}
+
+template <class T>
+bool Tellico::PtrVector<T>::contains(const T* t) const {
+ if(!t) {
+ return false;
+ }
+ const T* const* ptr = qFind(m_baseVector.begin(), m_baseVector.end(), t);
+ return ptr != m_baseVector.end();
+}
+
+#endif
diff --git a/src/reportdialog.cpp b/src/reportdialog.cpp
new file mode 100644
index 0000000..ee879de
--- /dev/null
+++ b/src/reportdialog.cpp
@@ -0,0 +1,220 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "reportdialog.h"
+#include "translators/htmlexporter.h"
+#include "imagefactory.h"
+#include "tellico_kernel.h"
+#include "collection.h"
+#include "document.h"
+#include "entry.h"
+#include "controller.h"
+#include "tellico_utils.h"
+#include "tellico_debug.h"
+#include "gui/combobox.h"
+#include "core/tellico_config.h"
+
+#include <klocale.h>
+#include <khtml_part.h>
+#include <khtmlview.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kapplication.h>
+#include <kpushbutton.h>
+#include <kiconloader.h>
+#include <ksortablevaluelist.h>
+#include <kfiledialog.h>
+
+#include <qlayout.h>
+#include <qfile.h>
+#include <qlabel.h>
+#include <qfileinfo.h>
+#include <qtimer.h>
+
+namespace {
+ static const int REPORT_MIN_WIDTH = 600;
+ static const int REPORT_MIN_HEIGHT = 420;
+}
+
+using Tellico::ReportDialog;
+
+// default button is going to be used as a print button, so it's separated
+ReportDialog::ReportDialog(QWidget* parent_, const char* name_/*=0*/)
+ : KDialogBase(parent_, name_, false, i18n("Collection Report"), Close, Close),
+ m_exporter(0) {
+ QWidget* mainWidget = new QWidget(this, "ReportDialog mainWidget");
+ setMainWidget(mainWidget);
+ QVBoxLayout* topLayout = new QVBoxLayout(mainWidget, 0, KDialog::spacingHint());
+
+ QHBoxLayout* hlay = new QHBoxLayout(topLayout);
+ QLabel* l = new QLabel(i18n("&Report template:"), mainWidget);
+ hlay->addWidget(l);
+
+// KStandardDirs::findAllResources(const char *type, const QString &filter, bool recursive, bool uniq)
+ QStringList files = KGlobal::dirs()->findAllResources("appdata", QString::fromLatin1("report-templates/*.xsl"),
+ false, true);
+ KSortableValueList<QString, QString> templates;
+ for(QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) {
+ QFileInfo fi(*it);
+ QString file = fi.fileName();
+ QString name = file.section('.', 0, -2);
+ name.replace('_', ' ');
+ QString title = i18n((name + QString::fromLatin1(" XSL Template")).utf8(), name.utf8());
+ templates.insert(title, file);
+ }
+ templates.sort();
+ m_templateCombo = new GUI::ComboBox(mainWidget);
+ for(KSortableValueList<QString, QString>::iterator it = templates.begin(); it != templates.end(); ++it) {
+ m_templateCombo->insertItem((*it).index(), (*it).value());
+ }
+ hlay->addWidget(m_templateCombo);
+ l->setBuddy(m_templateCombo);
+
+ KPushButton* pb1 = new KPushButton(SmallIconSet(QString::fromLatin1("exec")), i18n("&Generate"), mainWidget);
+ hlay->addWidget(pb1);
+ connect(pb1, SIGNAL(clicked()), SLOT(slotGenerate()));
+
+ hlay->addStretch();
+
+ KPushButton* pb2 = new KPushButton(KStdGuiItem::saveAs(), mainWidget);
+ hlay->addWidget(pb2);
+ connect(pb2, SIGNAL(clicked()), SLOT(slotSaveAs()));
+
+ KPushButton* pb3 = new KPushButton(KStdGuiItem::print(), mainWidget);
+ hlay->addWidget(pb3);
+ connect(pb3, SIGNAL(clicked()), SLOT(slotPrint()));
+
+ m_HTMLPart = new KHTMLPart(mainWidget);
+ m_HTMLPart->setJScriptEnabled(false);
+ m_HTMLPart->setJavaEnabled(false);
+ m_HTMLPart->setMetaRefreshEnabled(false);
+ m_HTMLPart->setPluginsEnabled(false);
+ topLayout->addWidget(m_HTMLPart->view());
+
+ QString text = QString::fromLatin1("<html><style>p{font-weight:bold;width:50%;"
+ "margin:20% auto auto auto;text-align:center;"
+ "background:white;color:%1;}</style><body><p>").arg(contrastColor.name())
+ + i18n("Select a report template and click <em>Generate</em>.") + ' '
+ + i18n("Some reports may take several seconds to generate for large collections.");
+ + QString::fromLatin1("</p></body></html>");
+ m_HTMLPart->begin();
+ m_HTMLPart->write(text);
+ m_HTMLPart->end();
+
+ setMinimumWidth(QMAX(minimumWidth(), REPORT_MIN_WIDTH));
+ setMinimumHeight(QMAX(minimumHeight(), REPORT_MIN_HEIGHT));
+ resize(configDialogSize(QString::fromLatin1("Report Dialog Options")));
+}
+
+ReportDialog::~ReportDialog() {
+ delete m_exporter;
+ m_exporter = 0;
+
+ saveDialogSize(QString::fromLatin1("Report Dialog Options"));
+}
+
+void ReportDialog::slotGenerate() {
+ GUI::CursorSaver cs(Qt::waitCursor);
+
+ QString fileName = QString::fromLatin1("report-templates/") + m_templateCombo->currentData().toString();
+ QString xsltFile = locate("appdata", fileName);
+ if(xsltFile.isEmpty()) {
+ kdWarning() << "ReportDialog::setXSLTFile() - can't locate " << m_templateCombo->currentData().toString() << endl;
+ return;
+ }
+ // if it's the same XSL file, no need to reload the XSLTHandler, just refresh
+ if(xsltFile == m_xsltFile) {
+ slotRefresh();
+ return;
+ }
+
+ m_xsltFile = xsltFile;
+
+ delete m_exporter;
+ m_exporter = new Export::HTMLExporter();
+ m_exporter->setXSLTFile(m_xsltFile);
+ m_exporter->setPrintHeaders(false); // the templates should take care of this themselves
+ m_exporter->setPrintGrouped(true); // allow templates to take advantage of added DOM
+
+ slotRefresh();
+}
+
+void ReportDialog::slotRefresh() {
+ if(!m_exporter) {
+ kdWarning() << "ReportDialog::slotRefresh() - no exporter" << endl;
+ return;
+ }
+
+ m_exporter->setGroupBy(Controller::self()->expandedGroupBy());
+ m_exporter->setSortTitles(Controller::self()->sortTitles());
+ m_exporter->setColumns(Controller::self()->visibleColumns());
+ // only print visible entries
+ m_exporter->setEntries(Controller::self()->visibleEntries());
+
+ long options = Export::ExportUTF8 | Export::ExportComplete | Export::ExportImages;
+ if(Config::autoFormat()) {
+ options |= Export::ExportFormatted;
+ }
+ m_exporter->setOptions(options);
+
+ // by setting the xslt file as the URL, any images referenced in the xslt "theme" can be found
+ // by simply using a relative path in the xslt file
+ KURL u;
+ u.setPath(m_xsltFile);
+ m_HTMLPart->begin(u);
+ m_HTMLPart->write(m_exporter->text());
+#if 0
+ QFile f(QString::fromLatin1("/tmp/test.html"));
+ if(f.open(IO_WriteOnly)) {
+ QTextStream t(&f);
+ t << m_exporter->text();
+ }
+ f.close();
+#endif
+ m_HTMLPart->end();
+ // is this needed?
+// view()->layout();
+}
+
+// actually the print button
+void ReportDialog::slotPrint() {
+ m_HTMLPart->view()->print();
+}
+
+void ReportDialog::slotSaveAs() {
+ QString filter = i18n("*.html|HTML Files (*.html)") + QChar('\n') + i18n("*|All Files");
+ KURL u = KFileDialog::getSaveURL(QString::null, filter, this);
+ if(!u.isEmpty() && u.isValid()) {
+ KConfigGroup config(KGlobal::config(), "ExportOptions");
+ bool encode = config.readBoolEntry("EncodeUTF8", true);
+ int oldOpt = m_exporter->options();
+
+ // turn utf8 off
+ long options = oldOpt & ~Export::ExportUTF8;
+ // now turn it on if true
+ if(encode) {
+ options |= Export::ExportUTF8;
+ }
+
+ KURL oldURL = m_exporter->url();
+ m_exporter->setOptions(options);
+ m_exporter->setURL(u);
+
+ m_exporter->exec();
+
+ m_exporter->setURL(oldURL);
+ m_exporter->setOptions(oldOpt);
+ }
+}
+
+#include "reportdialog.moc"
diff --git a/src/reportdialog.h b/src/reportdialog.h
new file mode 100644
index 0000000..758c2d6
--- /dev/null
+++ b/src/reportdialog.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef REPORTDIALOG_H
+#define REPORTDIALOG_H
+
+#include <kdialogbase.h>
+
+class KHTMLPart;
+
+namespace Tellico {
+ namespace Export {
+ class HTMLExporter;
+ }
+ namespace GUI {
+ class ComboBox;
+ }
+
+/**
+ * @author Robby Stephenson
+ */
+class ReportDialog : public KDialogBase {
+Q_OBJECT
+
+public:
+ /**
+ * The constructor sets up the dialog.
+ *
+ * @param parent A pointer to the parent widget
+ * @param name The widget name
+ */
+ ReportDialog(QWidget* parent, const char* name=0);
+ virtual ~ReportDialog();
+
+public slots:
+ /**
+ * Regenerate the report.
+ */
+ void slotRefresh();
+
+private slots:
+ void slotGenerate();
+ void slotPrint();
+ void slotSaveAs();
+
+private:
+ KHTMLPart* m_HTMLPart;
+ GUI::ComboBox* m_templateCombo;
+ Export::HTMLExporter* m_exporter;
+ QString m_xsltFile;
+};
+
+} // end namespace
+#endif
diff --git a/src/rtf2html/Makefile.am b/src/rtf2html/Makefile.am
new file mode 100644
index 0000000..ea3d39f
--- /dev/null
+++ b/src/rtf2html/Makefile.am
@@ -0,0 +1,15 @@
+AM_CPPFLAGS = $(all_includes)
+
+noinst_LIBRARIES = librtf2html.a
+librtf2html_a_SOURCES = fmt_opts.cpp rtf2html.cpp rtf_keyword.cpp rtf_table.cpp
+
+librtf2html_a_METASOURCES = AUTO
+
+KDE_OPTIONS = noautodist
+
+EXTRA_DIST = common.h dbg_iter.h fmt_opts.h fmt_opts.cpp \
+rtf2html.h rtf2html.cpp rtf_keyword.h rtf_keyword.cpp \
+rtf_table.h rtf_table.cpp rtf_tools.h
+
+CLEANFILES = *~
+
diff --git a/src/rtf2html/common.h b/src/rtf2html/common.h
new file mode 100644
index 0000000..01b1f5b
--- /dev/null
+++ b/src/rtf2html/common.h
@@ -0,0 +1,38 @@
+/* This is RTF to HTML converter, implemented as a text filter, generally.
+ Copyright (C) 2003 Valentin Lavrinenko, vlavrinenko@users.sourceforge.net
+
+ available at http://rtf2html.sf.net
+
+ Original available under the terms of the GNU LGPL2, and according
+ to those terms, relicensed under the GNU GPL2 for inclusion in Tellico */
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#include <string>
+#include <sstream>
+#include <iomanip>
+
+inline std::string from_int(int value)
+{
+ std::ostringstream buf;
+ buf<<value;
+ return buf.str();
+}
+
+inline std::string hex(unsigned int value)
+{
+ std::ostringstream buf;
+ buf<<std::setw(2)<<std::setfill('0')<<std::hex<<value;
+ return buf.str();
+}
+
+#endif
diff --git a/src/rtf2html/dbg_iter.h b/src/rtf2html/dbg_iter.h
new file mode 100644
index 0000000..dfbccf2
--- /dev/null
+++ b/src/rtf2html/dbg_iter.h
@@ -0,0 +1,67 @@
+/* This is RTF to HTML converter, implemented as a text filter, generally.
+ Copyright (C) 2003 Valentin Lavrinenko, vlavrinenko@users.sourceforge.net
+
+ available at http://rtf2html.sf.net
+
+ Original available under the terms of the GNU LGPL2, and according
+ to those terms, relicensed under the GNU GPL2 for inclusion in Tellico */
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+namespace rtf {
+
+template <class T>
+class dbg_iter_mixin : public virtual T
+{
+ public:
+ int offset;
+ dbg_iter_mixin(const T& t) : T(t)
+ {}
+ T& operator=(const T& t)
+ {
+ return T::operator=(t);
+ }
+ dbg_iter_mixin& operator++ ()
+ {
+ ++offset;
+ T::operator++();
+ return *this;
+ }
+ dbg_iter_mixin operator++ (int i)
+ {
+ ++offset;
+ return T::operator++(i);
+ }
+ char operator *() const
+ {
+ T::value_type c=T::operator*();
+// std::cerr<<offset<<":"<<c<<std::endl;
+ return c;
+ }
+};
+
+template <class T>
+class dbg_iter : public dbg_iter_mixin<T>
+{
+ public:
+ dbg_iter(const T& t) : dbg_iter_mixin<T>(t)
+ {}
+};
+
+template<class T>
+class dbg_iter<std::istreambuf_iterator<T> > :
+ public virtual std::istreambuf_iterator<T>,
+ public dbg_iter_mixin<std::istreambuf_iterator<T> >
+{
+ public:
+ dbg_iter(std::basic_streambuf<T> *buf) : std::istreambuf_iterator<T>(buf)
+ {}
+};
+
+} \ No newline at end of file
diff --git a/src/rtf2html/fmt_opts.cpp b/src/rtf2html/fmt_opts.cpp
new file mode 100644
index 0000000..25a2f24
--- /dev/null
+++ b/src/rtf2html/fmt_opts.cpp
@@ -0,0 +1,221 @@
+/* This is RTF to HTML converter, implemented as a text filter, generally.
+ Copyright (C) 2003 Valentin Lavrinenko, vlavrinenko@users.sourceforge.net
+
+ available at http://rtf2html.sf.net
+
+ Original available under the terms of the GNU LGPL2, and according
+ to those terms, relicensed under the GNU GPL2 for inclusion in Tellico */
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "fmt_opts.h"
+
+using namespace rtf;
+
+std::string formatting_options::get_par_str() const
+{
+ std::string style;
+ switch (papAlign)
+ {
+ case formatting_options::align_right:
+ style+="text-align:right;";
+ break;
+ case formatting_options::align_center:
+ style+="text-align:center;";
+ break;
+ case formatting_options::align_justify:
+ style+="text-align:justify;";
+ default: break;
+ }
+ if (papFirst!=0)
+ {
+ style+="text-indent:";
+ style+=from_int(papFirst);
+ style+="pt;";
+ }
+ if (papLeft!=0)
+ {
+ style+="margin-left:";
+ style+=from_int(papLeft);
+ style+="pt;";
+ }
+ if (papRight!=0)
+ {
+ style+="margin-right:";
+ style+=from_int(papRight);
+ style+="pt;";
+ }
+ if (papBefore!=0)
+ {
+ style+="margin-top:";
+ style+=from_int(papBefore);
+ style+="pt;";
+ }
+ if (papAfter!=0)
+ {
+ style+="margin-bottom:";
+ style+=from_int(papAfter);
+ style+="pt;";
+ }
+ if (style.empty())
+ return std::string("<p>");
+ else
+ {
+ style.insert(0, "<p style=\"");
+ return style+"\">";
+ }
+}
+
+std::string formatter::format(const formatting_options &_opt)
+{
+ formatting_options last_opt, opt(_opt);
+ std::string result;
+ if (!opt_stack.empty())
+ {
+ int cnt=0;
+ fo_deque::reverse_iterator i;
+ for (i=opt_stack.rbegin(); i!=opt_stack.rend(); ++i)
+ {
+ if (*i==opt)
+ break;
+ ++cnt;
+ }
+ if (cnt==0)
+ return "";
+ if (i!=opt_stack.rend())
+ {
+ while (cnt--)
+ {
+ result+="</span>";
+ opt_stack.pop_back();
+ }
+ return result;
+ }
+ last_opt=opt_stack.back();
+ }
+ if (last_opt.chpVAlign!=formatting_options::va_normal
+ && last_opt.chpVAlign!=opt.chpVAlign)
+ {
+ int cnt=0;
+ fo_deque::reverse_iterator i;
+ for (i=opt_stack.rbegin(); i!=opt_stack.rend(); ++i)
+ {
+ if (i->chpVAlign==formatting_options::va_normal)
+ break;
+ ++cnt;
+ }
+ while (cnt--)
+ {
+ result+="</span>";
+ opt_stack.pop_back();
+ }
+ last_opt=opt_stack.empty()?formatting_options():opt_stack.back();
+ }
+ std::string style;
+ if (opt.chpBold!=last_opt.chpBold)
+ {
+ style+="font-weight:";
+ style+=opt.chpBold?"bold":"normal";
+ style+=";";
+ }
+ if (opt.chpItalic!=last_opt.chpItalic)
+ {
+ style+="font-style:";
+ style+=opt.chpItalic?"italic":"normal";
+ style+=";";
+ }
+ if (opt.chpUnderline!=last_opt.chpUnderline)
+ {
+ style+="text-decoration:";
+ style+=opt.chpUnderline?"underline":"none";
+ style+=";";
+ }
+ if (opt.chpVAlign!=formatting_options::va_normal)
+ opt.chpFontSize=(int)(0.7*(opt.chpFontSize?opt.chpFontSize:24));
+ if (opt.chpFontSize!=last_opt.chpFontSize)
+ {
+ style+="font-size:";
+ style+=from_int(opt.chpFontSize/2);
+ style+="pt;";
+ }
+ if (opt.chpVAlign!=last_opt.chpVAlign)
+ {
+ style+="vertical-align:";
+ style+=opt.chpVAlign==formatting_options::va_sub?"sub":"super";
+ style+=";";
+ }
+ if (opt.chpFColor!=last_opt.chpFColor)
+ {
+ style+="color:";
+ style+=opt.chpFColor.r>0?"#"+hex(opt.chpFColor.r&0xFF)
+ +hex(opt.chpFColor.g&0xFF)
+ +hex(opt.chpFColor.b&0xFF)
+ :"WindowText";
+ style+=";";
+ }
+ if (opt.chpBColor!=last_opt.chpBColor)
+ {
+ style+="background-color:";
+ style+=opt.chpBColor.r>0?"#"+hex(opt.chpBColor.r&0xFF)
+ +hex(opt.chpBColor.g&0xFF)
+ +hex(opt.chpBColor.b&0xFF)
+ :"Window";
+ style+=";";
+ }
+ if (opt.chpHighlight!=last_opt.chpHighlight)
+ {
+ style+="background-color:";
+ switch (opt.chpHighlight)
+ {
+ case 0: style+="Window"; break;
+ case 1: style+="black"; break;
+ case 2: style+="blue"; break;
+ case 3: style+="aqua"; break;
+ case 4: style+="lime"; break;
+ case 5: style+="fuchsia"; break;
+ case 6: style+="red"; break;
+ case 7: style+="yellow"; break;
+ case 9: style+="navy"; break;
+ case 10: style+="teal"; break;
+ case 11: style+="green"; break;
+ case 12: style+="purple"; break;
+ case 13: style+="maroon"; break;
+ case 14: style+="olive"; break;
+ case 15: style+="gray"; break;
+ case 16: style+="silver"; break;
+ }
+ style+=";";
+ }
+ if (opt.chpFont!=last_opt.chpFont)
+ {
+ style+="font-family:'";
+ style+=opt.chpFont.name.empty()?"serif":opt.chpFont.name;
+ style+="'";
+ switch (opt.chpFont.family)
+ {
+ case font::ff_serif: style+=", serif"; break;
+ case font::ff_sans_serif: style+=", sans-serif"; break;
+ case font::ff_cursive: style+=", cursive"; break;
+ case font::ff_fantasy: style+=", fantasy"; break;
+ case font::ff_monospace: style+=", monospace"; break;
+ default: break;
+ }
+ style+=";";
+ }
+ opt_stack.push_back(opt);
+ return result+"<span style=\""+style+"\">";
+}
+
+std::string formatter::close()
+{
+ std::string result;
+ for (fo_deque::iterator i=opt_stack.begin(); i!=opt_stack.end(); ++i)
+ result+="</span>";
+ return result;
+}
diff --git a/src/rtf2html/fmt_opts.h b/src/rtf2html/fmt_opts.h
new file mode 100644
index 0000000..6845d60
--- /dev/null
+++ b/src/rtf2html/fmt_opts.h
@@ -0,0 +1,154 @@
+/* This is RTF to HTML converter, implemented as a text filter, generally.
+ Copyright (C) 2003 Valentin Lavrinenko, vlavrinenko@users.sourceforge.net
+
+ available at http://rtf2html.sf.net
+
+ Original available under the terms of the GNU LGPL2, and according
+ to those terms, relicensed under the GNU GPL2 for inclusion in Tellico */
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef __FMT_OPTS_H__
+#define __FMT_OPTS_H__
+
+#include "common.h"
+#include <stack>
+#include <vector>
+#include <deque>
+#include <map>
+
+namespace rtf {
+
+struct color {
+ int r, g, b;
+ color() : r(-1), g(-1), b(-1) {}
+ bool operator==(const color &clr)
+ {
+ return r==clr.r && g==clr.g && b==clr.b;
+ }
+ bool operator!=(const color &clr)
+ {
+ return !(*this==clr);
+ }
+ color &operator=(const color &clr)
+ {
+ r=clr.r; g=clr.g; b=clr.b;
+ return *this;
+ }
+};
+
+typedef std::vector<color> colorvect;
+
+struct font {
+ enum font_family {ff_none, ff_serif, ff_sans_serif, ff_cursive,
+ ff_fantasy, ff_monospace};
+ font_family family;
+ std::string name;
+ int pitch;
+ int charset;
+ font() : family(ff_none), name(), pitch(0), charset(0) {}
+ bool operator==(const font &f)
+ {
+ return family==f.family && name==f.name;
+ }
+ bool operator!=(const font &f)
+ {
+ return !(*this==f);
+ }
+ font &operator=(const font &f)
+ {
+ family=f.family; name=f.name; pitch=f.pitch; charset=f.charset;
+ return *this;
+ }
+};
+
+typedef std::map<int, font> fontmap;
+
+struct formatting_options
+{
+ enum halign {align_left, align_right, align_center, align_justify, align_error};
+ enum valign {va_normal, va_sub, va_sup};
+ bool chpBold, chpItalic, chpUnderline;
+ valign chpVAlign;
+ int chpFontSize, chpHighlight;
+ color chpFColor, chpBColor;
+ font chpFont;
+ int papLeft, papRight, papFirst;
+ int papBefore, papAfter;
+ halign papAlign;
+ bool papInTbl;
+ formatting_options()
+ {
+ chpBold=chpItalic=chpUnderline=false;
+ chpVAlign=va_normal;
+ chpFontSize=chpHighlight=0;
+ papLeft=papRight=papFirst=papBefore=papAfter=0;
+ papAlign=align_left;
+ papInTbl=false;
+ }
+ bool operator==(const formatting_options &opt) // tests only for character options
+ {
+ return chpBold==opt.chpBold && chpItalic==opt.chpItalic
+ && chpUnderline==opt.chpUnderline && chpVAlign==opt.chpVAlign
+ && chpFontSize==opt.chpFontSize
+ && chpFColor==opt.chpFColor && chpBColor==opt.chpBColor
+ && chpHighlight==opt.chpHighlight && chpFont==opt.chpFont;
+ }
+ bool operator!=(const formatting_options &opt) // tests only for character options
+ {
+ return !(*this==opt);
+ }
+ formatting_options &operator=(const formatting_options &opt)
+ {
+ chpBold=opt.chpBold; chpItalic=opt.chpItalic;
+ chpUnderline=opt.chpUnderline; chpVAlign=opt.chpVAlign;
+ chpFontSize=opt.chpFontSize;
+ chpFColor=opt.chpFColor; chpBColor=opt.chpBColor;
+ chpHighlight=opt.chpHighlight; chpFont=opt.chpFont;
+ papLeft=opt.papLeft; papRight=opt.papRight;
+ papFirst=opt.papFirst; papBefore=opt.papBefore; papAfter=opt.papAfter;
+ papAlign=opt.papAlign; papInTbl=opt.papInTbl;
+ return *this;
+ }
+ std::string get_par_str() const;
+};
+
+typedef std::stack<formatting_options> fo_stack;
+
+typedef std::deque<formatting_options> fo_deque;
+
+class formatter {
+ private:
+ fo_deque opt_stack;
+ public:
+ std::string format(const formatting_options &opt);
+ std::string close();
+ void clear() { opt_stack.clear(); }
+};
+
+class html_text {
+ private:
+ const formatting_options &opt;
+ formatter fmt;
+ std::string text;
+ public:
+ html_text(const formatting_options &_opt) : opt(_opt) {}
+ const std::string &str() { return text; }
+ template <class T> void write(T s)
+ {
+ text+=fmt.format(opt)+s;
+ }
+ std::string close() { return fmt.close(); }
+// void write(char c) { write(std::string()+c); }
+ void clear() { text.clear(); fmt.clear(); }
+};
+
+}
+#endif
+
diff --git a/src/rtf2html/rtf2html.cpp b/src/rtf2html/rtf2html.cpp
new file mode 100644
index 0000000..4f29fe7
--- /dev/null
+++ b/src/rtf2html/rtf2html.cpp
@@ -0,0 +1,531 @@
+/* This is RTF to HTML converter, implemented as a text filter, generally.
+ Copyright (C) 2003 Valentin Lavrinenko, vlavrinenko@users.sourceforge.net
+
+ available at http://rtf2html.sf.net
+
+ Original available under the terms of the GNU LGPL2, and according
+ to those terms, relicensed under the GNU GPL2 for inclusion in Tellico */
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "rtf2html.h"
+#include "rtf_table.h"
+#include "rtf_tools.h"
+#include "rtf_keyword.h"
+#include "fmt_opts.h"
+
+#include <cstdlib>
+#include <stdexcept>
+#include <fstream>
+#include <iostream>
+#include <string>
+
+using Tellico::RTF2HTML;
+using namespace rtf;
+
+RTF2HTML::RTF2HTML(const QString& text) : m_text(text) {
+}
+
+QString RTF2HTML::toHTML() const {
+ std::string str_in = m_text;
+
+ std::string::iterator buf_in=str_in.begin(), buf_in_end=str_in.end();
+ colorvect colortbl;
+ fontmap fonttbl;
+ std::string title;
+
+ bool bAsterisk=false;
+ fo_stack foStack;
+ formatting_options cur_options;
+ std::string html;
+ html_text par_html(cur_options);
+
+ /* CellDefs in rtf are really queer. We'll keep a list of them in main()
+ and will give an iterator into this list to a row */
+ table_cell_defs_list CellDefsList;
+ table_cell_defs_list::iterator CurCellDefs;
+ table_cell_def* tcdCurCellDef=new table_cell_def;
+ table_cell* tcCurCell=new table_cell;
+ table_row* trCurRow=new table_row;
+ table* tblCurTable=new table;
+ int iLastRowLeft=0, iLastRowHeight=0;
+ std::string t_str;
+
+ bool bInTable=false;
+ int iDocWidth=12240;
+ int iMarginLeft=1800;
+ while(buf_in!=buf_in_end)
+ {
+ switch (*buf_in)
+ {
+ case '\\':
+ {
+ rtf_keyword kw(++buf_in);
+ if (kw.is_control_char())
+ switch (kw.control_char())
+ {
+ case '\\': case '{': case '}':
+ par_html.write(kw.control_char());
+ break;
+ case '\'':
+ {
+ std::string stmp(1,*buf_in++);
+ stmp+=*buf_in++;
+ int code=std::strtol(stmp.c_str(), NULL, 16);
+ switch (code)
+ {
+ case 167:
+ par_html.write("&bull;");
+ break;
+ case 188:
+ par_html.write("&hellip;");
+ break;
+ default:
+ par_html.write((char)code);
+ }
+ break;
+ }
+ case '*':
+ bAsterisk=true;
+ break;
+ case '~':
+ par_html.write("&nbsp;");
+ break;
+ case '\n':
+ par_html.write("<br><br>");
+ break;
+ }
+ else //kw.is_control_char
+ if (bAsterisk)
+ {
+ bAsterisk=false;
+ skip_group(buf_in);
+ }
+ else
+ {
+ switch (kw.keyword())
+ {
+ case rtf_keyword::rkw_filetbl:
+ case rtf_keyword::rkw_stylesheet:
+ case rtf_keyword::rkw_header:
+ case rtf_keyword::rkw_footer: case rtf_keyword::rkw_headerf:
+ case rtf_keyword::rkw_footerf: case rtf_keyword::rkw_pict:
+ case rtf_keyword::rkw_object:
+ // we'll skip such groups
+ skip_group(buf_in);
+ break;
+ // document title
+ case rtf_keyword::rkw_info:
+ {
+ int depth=1;
+ bool in_title=false;
+ while (depth>0)
+ {
+// std::cout<<std::string(buf_in).substr(0,20)<<"\t"<<depth<<std::endl;
+ switch (*buf_in)
+ {
+ case '\\':
+ {
+ rtf_keyword kw(++buf_in);
+ if (kw.keyword()==rtf_keyword::rkw_title)
+ in_title=true;
+ break;
+ }
+ case '{': ++depth; ++buf_in; break;
+ case '}': --depth; ++buf_in; in_title=false; break;
+ default: if (in_title) title+=*buf_in; ++buf_in; break;
+ }
+ }
+ break;
+ }
+ // color table
+ case rtf_keyword::rkw_colortbl:
+ {
+ color clr;
+ while (*buf_in!='}')
+ {
+ switch (*buf_in)
+ {
+ case '\\':
+ {
+ rtf_keyword kw(++buf_in);
+ switch (kw.keyword())
+ {
+ case rtf_keyword::rkw_red:
+ clr.r=kw.parameter();
+ break;
+ case rtf_keyword::rkw_green:
+ clr.g=kw.parameter();
+ break;
+ case rtf_keyword::rkw_blue:
+ clr.b=kw.parameter();
+ break;
+ default: break;
+ }
+ break;
+ }
+ case ';':
+ colortbl.push_back(clr);
+ ++buf_in;
+ break;
+ default:
+ ++buf_in;
+ break;
+ }
+ }
+ ++buf_in;
+ break;
+ }
+ // font table
+ case rtf_keyword::rkw_fonttbl:
+ {
+ font fnt;
+ int font_num;
+ bool full_name=false;
+ bool in_font=false;
+ while (! (*buf_in=='}' && !in_font))
+ {
+ switch (*buf_in)
+ {
+ case '\\':
+ {
+ rtf_keyword kw(++buf_in);
+ if (kw.is_control_char() && kw.control_char()=='*')
+ skip_group(buf_in);
+ else
+ switch (kw.keyword())
+ {
+ case rtf_keyword::rkw_f:
+ font_num=kw.parameter();
+ break;
+ case rtf_keyword::rkw_fprq:
+ fnt.pitch=kw.parameter();
+ break;
+ case rtf_keyword::rkw_fcharset:
+ fnt.charset=kw.parameter();
+ break;
+ case rtf_keyword::rkw_fnil:
+ fnt.family=font::ff_none;
+ break;
+ case rtf_keyword::rkw_froman:
+ fnt.family=font::ff_serif;
+ break;
+ case rtf_keyword::rkw_fswiss:
+ fnt.family=font::ff_sans_serif;
+ break;
+ case rtf_keyword::rkw_fmodern:
+ fnt.family=font::ff_monospace;
+ break;
+ case rtf_keyword::rkw_fscript:
+ fnt.family=font::ff_cursive;
+ break;
+ case rtf_keyword::rkw_fdecor:
+ fnt.family=font::ff_fantasy;
+ break;
+ default: break;
+ }
+ break;
+ }
+ case '{':
+ in_font=true;
+ ++buf_in;
+ break;
+ case '}':
+ in_font=false;
+ fonttbl.insert(std::make_pair(font_num, fnt));
+ fnt=font();
+ full_name=false;
+ ++buf_in;
+ break;
+ case ';':
+ full_name=true;
+ ++buf_in;
+ break;
+ default:
+ if (!full_name && in_font)
+ fnt.name+=*buf_in;
+ ++buf_in;
+ break;
+ }
+ }
+ ++buf_in;
+ break;
+ }
+ // special characters
+ case rtf_keyword::rkw_line: case rtf_keyword::rkw_softline:
+ par_html.write("<br>");
+ break;
+ case rtf_keyword::rkw_tab:
+ par_html.write("&nbsp;&nbsp;"); // maybe, this can be done better
+ break;
+ case rtf_keyword::rkw_enspace: case rtf_keyword::rkw_emspace:
+ par_html.write("&nbsp;");
+ break;
+ case rtf_keyword::rkw_qmspace:
+ par_html.write("&thinsp;");
+ break;
+ case rtf_keyword::rkw_endash:
+ par_html.write("&ndash;");
+ break;
+ case rtf_keyword::rkw_emdash:
+ par_html.write("&mdash;");
+ break;
+ case rtf_keyword::rkw_bullet:
+ par_html.write("&bull;");
+ break;
+ case rtf_keyword::rkw_lquote:
+ par_html.write("&lsquo;");
+ break;
+ case rtf_keyword::rkw_rquote:
+ par_html.write("&rsquo;");
+ break;
+ case rtf_keyword::rkw_ldblquote:
+ par_html.write("&ldquo;");
+ break;
+ case rtf_keyword::rkw_rdblquote:
+ par_html.write("&rdquo;");
+ break;
+ // paragraph formatting
+ case rtf_keyword::rkw_ql:
+ cur_options.papAlign=formatting_options::align_left;
+ break;
+ case rtf_keyword::rkw_qr:
+ cur_options.papAlign=formatting_options::align_right;
+ break;
+ case rtf_keyword::rkw_qc:
+ cur_options.papAlign=formatting_options::align_center;
+ break;
+ case rtf_keyword::rkw_qj:
+ cur_options.papAlign=formatting_options::align_justify;
+ break;
+ case rtf_keyword::rkw_fi:
+ cur_options.papFirst=(int)rint(kw.parameter()/20);
+ break;
+ case rtf_keyword::rkw_li:
+ cur_options.papLeft=(int)rint(kw.parameter()/20);
+ break;
+ case rtf_keyword::rkw_ri:
+ cur_options.papRight=(int)rint(kw.parameter()/20);
+ break;
+ case rtf_keyword::rkw_sb:
+ cur_options.papBefore=(int)rint(kw.parameter()/20);
+ break;
+ case rtf_keyword::rkw_sa:
+ cur_options.papAfter=(int)rint(kw.parameter()/20);
+ break;
+ case rtf_keyword::rkw_pard:
+ cur_options.papBefore=cur_options.papAfter=0;
+ cur_options.papLeft=cur_options.papRight=0;
+ cur_options.papFirst=0;
+ cur_options.papAlign=formatting_options::align_left;
+ cur_options.papInTbl=false;
+ break;
+ case rtf_keyword::rkw_par:
+ case rtf_keyword::rkw_sect:
+ t_str=cur_options.get_par_str()+par_html.str()
+ +"&nbsp;"+par_html.close()+"</p>\n";
+ if (!bInTable)
+ {
+ html+=t_str;
+ }
+ else
+ {
+ if (cur_options.papInTbl)
+ {
+ tcCurCell->Text+=t_str;
+ }
+ else
+ {
+ html+=tblCurTable->make()+t_str;
+ bInTable=false;
+ tblCurTable=new table;
+ }
+ }
+ par_html.clear();
+ break;
+ // character formatting
+ case rtf_keyword::rkw_super:
+ cur_options.chpVAlign=
+ kw.parameter()==0?formatting_options::va_normal
+ :formatting_options::va_sup;
+ break;
+ case rtf_keyword::rkw_sub:
+ cur_options.chpVAlign=
+ kw.parameter()==0?formatting_options::va_normal
+ :formatting_options::va_sub;
+ break;
+ case rtf_keyword::rkw_b:
+ cur_options.chpBold=!(kw.parameter()==0);
+ break;
+ case rtf_keyword::rkw_i:
+ cur_options.chpItalic=!(kw.parameter()==0);
+ break;
+ case rtf_keyword::rkw_ul:
+ cur_options.chpUnderline=!(kw.parameter()==0);
+ break;
+ case rtf_keyword::rkw_ulnone:
+ cur_options.chpUnderline=false;
+ break;
+ case rtf_keyword::rkw_fs:
+ cur_options.chpFontSize=kw.parameter();
+ break;
+ case rtf_keyword::rkw_cf:
+ cur_options.chpFColor=colortbl[kw.parameter()];
+ break;
+ case rtf_keyword::rkw_cb:
+ cur_options.chpBColor=colortbl[kw.parameter()];
+ break;
+ case rtf_keyword::rkw_highlight:
+ cur_options.chpHighlight=kw.parameter();
+ break;
+ case rtf_keyword::rkw_f:
+ cur_options.chpFont=fonttbl[kw.parameter()];
+ break;
+ case rtf_keyword::rkw_plain:
+ cur_options.chpBold=cur_options.chpItalic
+ =cur_options.chpUnderline=false;
+ cur_options.chpVAlign=formatting_options::va_normal;
+ cur_options.chpFontSize=cur_options.chpHighlight=0;
+ cur_options.chpFColor=cur_options.chpBColor=color();
+ cur_options.chpFont=font();
+ break;
+ // table formatting
+ case rtf_keyword::rkw_intbl:
+ cur_options.papInTbl=true;
+ break;
+ case rtf_keyword::rkw_trowd:
+ CurCellDefs=CellDefsList.insert(CellDefsList.end(),
+ table_cell_defs());
+ case rtf_keyword::rkw_row:
+ if (!trCurRow->Cells.empty())
+ {
+ trCurRow->CellDefs=CurCellDefs;
+ if (trCurRow->Left==-1000)
+ trCurRow->Left=iLastRowLeft;
+ if (trCurRow->Height==-1000)
+ trCurRow->Height=iLastRowHeight;
+ tblCurTable->push_back(trCurRow);
+ trCurRow=new table_row;
+ }
+ bInTable=true;
+ break;
+ case rtf_keyword::rkw_cell:
+ t_str=cur_options.get_par_str()+par_html.str()
+ +"&nbsp;"+par_html.close()+"</p>\n";
+ tcCurCell->Text+=t_str;
+ par_html.clear();
+ trCurRow->Cells.push_back(tcCurCell);
+ tcCurCell=new table_cell;
+ break;
+ case rtf_keyword::rkw_cellx:
+ tcdCurCellDef->Right=kw.parameter();
+ CurCellDefs->push_back(tcdCurCellDef);
+ tcdCurCellDef=new table_cell_def;
+ break;
+ case rtf_keyword::rkw_trleft:
+ trCurRow->Left=kw.parameter();
+ iLastRowLeft=kw.parameter();
+ break;
+ case rtf_keyword::rkw_trrh:
+ trCurRow->Height=kw.parameter();
+ iLastRowHeight=kw.parameter();
+ break;
+ case rtf_keyword::rkw_clvmgf:
+ tcdCurCellDef->FirstMerged=true;
+ break;
+ case rtf_keyword::rkw_clvmrg:
+ tcdCurCellDef->Merged=true;
+ break;
+ case rtf_keyword::rkw_clbrdrb:
+ tcdCurCellDef->BorderBottom=true;
+ tcdCurCellDef->ActiveBorder=&(tcdCurCellDef->BorderBottom);
+ break;
+ case rtf_keyword::rkw_clbrdrt:
+ tcdCurCellDef->BorderTop=true;
+ tcdCurCellDef->ActiveBorder=&(tcdCurCellDef->BorderTop);
+ break;
+ case rtf_keyword::rkw_clbrdrl:
+ tcdCurCellDef->BorderLeft=true;
+ tcdCurCellDef->ActiveBorder=&(tcdCurCellDef->BorderLeft);
+ break;
+ case rtf_keyword::rkw_clbrdrr:
+ tcdCurCellDef->BorderRight=true;
+ tcdCurCellDef->ActiveBorder=&(tcdCurCellDef->BorderRight);
+ break;
+ case rtf_keyword::rkw_brdrnone:
+ if (tcdCurCellDef->ActiveBorder!=NULL)
+ {
+ *(tcdCurCellDef->ActiveBorder)=false;
+ }
+ break;
+ case rtf_keyword::rkw_clvertalt:
+ tcdCurCellDef->VAlign=table_cell_def::valign_top;
+ break;
+ case rtf_keyword::rkw_clvertalc:
+ tcdCurCellDef->VAlign=table_cell_def::valign_center;
+ break;
+ case rtf_keyword::rkw_clvertalb:
+ tcdCurCellDef->VAlign=table_cell_def::valign_bottom;
+ break;
+ // page formatting
+ case rtf_keyword::rkw_paperw:
+ iDocWidth=kw.parameter();
+ break;
+ case rtf_keyword::rkw_margl:
+ iMarginLeft=kw.parameter();
+ break;
+ default: break;
+ }
+ }
+ break;
+ }
+ case '{':
+ // perform group opening actions here
+ foStack.push(cur_options);
+ ++buf_in;
+ break;
+ case '}':
+ // perform group closing actions here
+ cur_options=foStack.top();
+ foStack.pop();
+ ++buf_in;
+ break;
+ case 13:
+ case 10:
+ ++buf_in;
+ break;
+ case '<':
+ par_html.write("&lt;");
+ ++buf_in;
+ break;
+ case '>':
+ par_html.write("&gt;");
+ ++buf_in;
+ break;
+/* case ' ':
+ par_html.write("&ensp;");
+ ++buf_in;
+ break;*/
+ default:
+ par_html.write(*buf_in++);
+ }
+ }
+
+ t_str=cur_options.get_par_str()+par_html.str()
+ +"&nbsp;"+par_html.close()+"</p>\n";
+ html+=t_str;
+
+ delete tcCurCell;
+ delete trCurRow;
+ delete tblCurTable;
+ delete tcdCurCellDef;
+
+ return html;
+}
+
diff --git a/src/rtf2html/rtf2html.h b/src/rtf2html/rtf2html.h
new file mode 100644
index 0000000..a4e1d2f
--- /dev/null
+++ b/src/rtf2html/rtf2html.h
@@ -0,0 +1,28 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include <qstring.h>
+
+namespace Tellico {
+
+class RTF2HTML {
+public:
+ RTF2HTML(const QString& text);
+
+ QString toHTML() const;
+
+private:
+ QString m_text;
+};
+
+}
diff --git a/src/rtf2html/rtf_keyword.cpp b/src/rtf2html/rtf_keyword.cpp
new file mode 100644
index 0000000..ee4774c
--- /dev/null
+++ b/src/rtf2html/rtf_keyword.cpp
@@ -0,0 +1,107 @@
+/* This is RTF to HTML converter, implemented as a text filter, generally.
+ Copyright (C) 2003 Valentin Lavrinenko, vlavrinenko@users.sourceforge.net
+
+ available at http://rtf2html.sf.net
+
+ Original available under the terms of the GNU LGPL2, and according
+ to those terms, relicensed under the GNU GPL2 for inclusion in Tellico */
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "rtf_keyword.h"
+
+using namespace rtf;
+
+rtf_keyword::keyword_map::keyword_map() : base_class()
+{
+ insert(value_type("b", rkw_b));
+ insert(value_type("bin", rkw_bin));
+ insert(value_type("blue", rkw_blue));
+ insert(value_type("brdrnone", rkw_brdrnone));
+ insert(value_type("bullet", rkw_bullet));
+ insert(value_type("cb", rkw_cb));
+ insert(value_type("cell", rkw_cell));
+ insert(value_type("cellx", rkw_cellx));
+ insert(value_type("cf", rkw_cf));
+ insert(value_type("clbrdrb", rkw_clbrdrb));
+ insert(value_type("clbrdrl", rkw_clbrdrl));
+ insert(value_type("clbrdrr", rkw_clbrdrr));
+ insert(value_type("clbrdrt", rkw_clbrdrt));
+ insert(value_type("clvertalb", rkw_clvertalb));
+ insert(value_type("clvertalc", rkw_clvertalc));
+ insert(value_type("clvertalt", rkw_clvertalt));
+ insert(value_type("clvmgf", rkw_clvmgf));
+ insert(value_type("clvmrg", rkw_clvmrg));
+ insert(value_type("colortbl", rkw_colortbl));
+ insert(value_type("emdash", rkw_emdash));
+ insert(value_type("emspace", rkw_emspace));
+ insert(value_type("endash", rkw_endash));
+ insert(value_type("enspace", rkw_enspace));
+ insert(value_type("f", rkw_f));
+ insert(value_type("fprq", rkw_fprq));
+ insert(value_type("fcharset", rkw_fcharset));
+ insert(value_type("fnil", rkw_fnil));
+ insert(value_type("froman", rkw_froman));
+ insert(value_type("fswiss", rkw_fswiss));
+ insert(value_type("fmodern", rkw_fmodern));
+ insert(value_type("fscript", rkw_fscript));
+ insert(value_type("fdecor", rkw_fdecor));
+ insert(value_type("ftech", rkw_ftech));
+ insert(value_type("fbidi", rkw_fbidi));
+ insert(value_type("field", rkw_field));
+ insert(value_type("filetbl", rkw_filetbl));
+ insert(value_type("fldrslt", rkw_fldrslt));
+ insert(value_type("fonttbl", rkw_fonttbl));
+ insert(value_type("footer", rkw_footer));
+ insert(value_type("footerf", rkw_footerf));
+ insert(value_type("fs", rkw_fs));
+ insert(value_type("green", rkw_green));
+ insert(value_type("header", rkw_header));
+ insert(value_type("headerf", rkw_headerf));
+ insert(value_type("highlight", rkw_highlight));
+ insert(value_type("i", rkw_i));
+ insert(value_type("info", rkw_info));
+ insert(value_type("intbl", rkw_intbl));
+ insert(value_type("ldblquote", rkw_ldblquote));
+ insert(value_type("li", rkw_li));
+ insert(value_type("line", rkw_line));
+ insert(value_type("lquote", rkw_lquote));
+ insert(value_type("margl", rkw_margl));
+ insert(value_type("object", rkw_object));
+ insert(value_type("paperw", rkw_paperw));
+ insert(value_type("par", rkw_par));
+ insert(value_type("pard", rkw_pard));
+ insert(value_type("pict", rkw_pict));
+ insert(value_type("plain", rkw_plain));
+ insert(value_type("qc", rkw_qc));
+ insert(value_type("qj", rkw_qj));
+ insert(value_type("ql", rkw_ql));
+ insert(value_type("qr", rkw_qr));
+ insert(value_type("rdblquote", rkw_rdblquote));
+ insert(value_type("red", rkw_red));
+ insert(value_type("ri", rkw_ri));
+ insert(value_type("row", rkw_row));
+ insert(value_type("rquote", rkw_rquote));
+ insert(value_type("sa", rkw_sa));
+ insert(value_type("sb", rkw_sb));
+ insert(value_type("sect", rkw_sect));
+ insert(value_type("softline", rkw_softline));
+ insert(value_type("stylesheet", rkw_stylesheet));
+ insert(value_type("sub", rkw_sub));
+ insert(value_type("super", rkw_super));
+ insert(value_type("tab", rkw_tab));
+ insert(value_type("title", rkw_title));
+ insert(value_type("trleft", rkw_trleft));
+ insert(value_type("trowd", rkw_trowd));
+ insert(value_type("trrh", rkw_trrh));
+ insert(value_type("ul", rkw_ul));
+ insert(value_type("ulnone", rkw_ulnone));
+}
+
+rtf_keyword::keyword_map rtf_keyword::keymap;
diff --git a/src/rtf2html/rtf_keyword.h b/src/rtf2html/rtf_keyword.h
new file mode 100644
index 0000000..c510ea0
--- /dev/null
+++ b/src/rtf2html/rtf_keyword.h
@@ -0,0 +1 @@
+/* This is RTF to HTML converter, implemented as a text filter, generally. Copyright (C) 2003 Valentin Lavrinenko, vlavrinenko@users.sourceforge.net available at http://rtf2html.sf.net Original available under the terms of the GNU LGPL2, and according to those terms, relicensed under the GNU GPL2 for inclusion in Tellico */ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of version 2 of the GNU General Public License as * * published by the Free Software Foundation; * * * ***************************************************************************/ #ifndef __RTF_KEYWORD_H__ #define __RTF_KEYWORD_H__ #include <string> #include <map> #include <ctype.h> #include <cstdlib> namespace rtf { class rtf_keyword{ public: enum keyword_type {rkw_unknown, rkw_b, rkw_bin, rkw_blue, rkw_brdrnone, rkw_bullet, rkw_cb, rkw_cell, rkw_cellx, rkw_cf, rkw_clbrdrb, rkw_clbrdrl, rkw_clbrdrr, rkw_clbrdrt, rkw_clvertalb, rkw_clvertalc, rkw_clvertalt, rkw_clvmgf, rkw_clvmrg, rkw_colortbl, rkw_emdash, rkw_emspace, rkw_endash, rkw_enspace, rkw_fi, rkw_field, rkw_filetbl, rkw_f, rkw_fprq, rkw_fcharset, rkw_fnil, rkw_froman, rkw_fswiss, rkw_fmodern, rkw_fscript, rkw_fdecor, rkw_ftech, rkw_fbidi, rkw_fldrslt, rkw_fonttbl, rkw_footer, rkw_footerf, rkw_fs, rkw_green, rkw_header, rkw_headerf, rkw_highlight, rkw_i, rkw_info, rkw_intbl, rkw_ldblquote, rkw_li, rkw_line, rkw_lquote, rkw_margl, rkw_object, rkw_paperw, rkw_par, rkw_pard, rkw_pict, rkw_plain, rkw_qc, rkw_qj, rkw_ql, rkw_qmspace, rkw_qr, rkw_rdblquote, rkw_red, rkw_ri, rkw_row, rkw_rquote, rkw_sa, rkw_sb, rkw_sect, rkw_softline, rkw_stylesheet, rkw_sub, rkw_super, rkw_tab, rkw_title, rkw_trleft, rkw_trowd, rkw_trrh, rkw_ul, rkw_ulnone }; private: class keyword_map : public std::map<std::string, keyword_type> { private: typedef std::map<std::string, keyword_type> base_class; public: keyword_map(); }; private: static keyword_map keymap; std::string s_keyword; keyword_type e_keyword; int param; char ctrl_chr; bool is_ctrl_chr; public: // iter must point after the backslash starting the keyword. We don't check it. // after construction, iter points at the char following the keyword template <class InputIter> explicit rtf_keyword(InputIter &iter); bool is_control_char() const { return is_ctrl_chr; } const std::string &keyword_str() const { return s_keyword; } keyword_type keyword() const { return e_keyword; } int parameter() const { return param; } char control_char() const { return ctrl_chr; } }; template <class InputIter> rtf_keyword::rtf_keyword(InputIter &iter) { char curchar=*iter; is_ctrl_chr=!isalpha(curchar); if (is_ctrl_chr) { ctrl_chr=curchar; ++iter; } else { do s_keyword+=curchar; while (isalpha(curchar=*++iter)); std::string param_str; while (isdigit(curchar)||curchar=='-') { param_str+=curchar; curchar=*++iter; } if (param_str.empty()) param=-1; else param=std::atoi(param_str.c_str()); if (curchar==' ') ++iter; keyword_map::iterator kw_pos=keymap.find(s_keyword); if (kw_pos==keymap.end()) e_keyword=rkw_unknown; else e_keyword=kw_pos->second; } } } #endif \ No newline at end of file
diff --git a/src/rtf2html/rtf_table.cpp b/src/rtf2html/rtf_table.cpp
new file mode 100644
index 0000000..b5cdf7b
--- /dev/null
+++ b/src/rtf2html/rtf_table.cpp
@@ -0,0 +1,235 @@
+/* This is RTF to HTML converter, implemented as a text filter, generally.
+ Copyright (C) 2003 Valentin Lavrinenko, vlavrinenko@users.sourceforge.net
+
+ available at http://rtf2html.sf.net
+
+ Original available under the terms of the GNU LGPL2, and according
+ to those terms, relicensed under the GNU GPL2 for inclusion in Tellico */
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "rtf_table.h"
+#include <set>
+#include <ostream>
+#include <iostream>
+#include <stdexcept>
+#include <functional>
+#include <algorithm>
+
+using namespace rtf;
+
+typedef std::set<int> intset;
+
+template <class T, class C>
+std::basic_ostream<C>& operator<<(std::basic_ostream<C> &dest, std::set<T> &s)
+{
+ for (typename std::set<T>::iterator i=s.begin(); i!=s.end(); ++i)
+ dest<<*i<<" ";
+ return dest;
+}
+
+std::string table::make()
+{
+ std::string result;
+ intset pts;
+ iterator row, span_row, row2;
+ table_cell_defs::iterator cell_def, prev_cell_def, cell_def_2;
+ table_cells::iterator cell;
+ intset::iterator pt, ptp;
+ int left, right, colspan;
+ bool btop, bbottom, bleft, bright;
+ std::string style;
+ for (row=begin(); row!=end();)
+ {
+ if ((*row)->Cells.empty())
+ {
+ delete *row;
+ row=erase(row);
+ }
+ else
+ {
+ pts.insert((*row)->Left);
+ for (cell_def=(*row)->CellDefs->begin(); cell_def!=(*row)->CellDefs->end(); ++cell_def)
+ {
+ pts.insert((*cell_def)->Right);
+ }
+ ++row;
+ }
+ }
+ if (pts.empty())
+ {
+// throw std::logic_error("No CellDefs!");
+ }
+ pt=pts.begin();
+ ptp=pts.end();
+ ptp--;
+ result="<table border=0 width=";
+ result+=from_int((int)rint((*ptp-*pt)/15));
+ result+=" style=\"margin-left:";
+ result+=from_int((int)rint(*pt/15));
+ result+=";border-collapse: collapse;\">";
+ result+="<tr height=0>";
+ for (ptp=pt++=pts.begin(); pt!=pts.end(); ptp=pt++)
+ {
+ result+="<td width=";
+ result+=from_int((int)rint((*pt-*ptp)/15));
+ result+="></td>";
+ //coefficient may be different
+ }
+ result+="</tr>\n";
+
+ // first, we'll determine all the rowspans and leftsides
+ for (row=begin(); row!=end(); ++row)
+ {
+ if ((*row)->CellDefs->size()!=(*row)->Cells.size())
+// throw std::logic_error("Number of Cells and number of CellDefs are unequal!");
+ for (cell_def=(*row)->CellDefs->begin(), cell=(*row)->Cells.begin();
+ cell!=(*row)->Cells.end();
+ ++cell, prev_cell_def=cell_def++
+ )
+ {
+ if (cell_def==(*row)->CellDefs->begin())
+ (*cell_def)->Left=(*row)->Left;
+ else
+ (*cell_def)->Left=(*prev_cell_def)->Right;
+ if ((*cell_def)->FirstMerged)
+ {
+ for (span_row=row, ++span_row; span_row!=end();
+ ++span_row)
+ {
+ cell_def_2=
+ std::find_if((*span_row)->CellDefs->begin(),
+ (*span_row)->CellDefs->end(),
+ std::bind2nd(
+ std::mem_fun(&table_cell_def::right_equals),
+ (*cell_def)->Right));
+ if (cell_def_2==(*span_row)->CellDefs->end())
+ break;
+ if (!(*cell_def_2)->Merged)
+ break;
+ }
+ (*cell)->Rowspan=span_row-row;
+ }
+ }
+ }
+
+ for (row=begin(); row!=end(); ++row)
+ {
+ result+="<tr>";
+ pt=pts.find((*row)->Left);
+ if (pt==pts.end())
+// throw std::logic_error("No row.left point!");
+ if (pt!=pts.begin())
+ {
+ result+="<td colspan=";
+ result+=from_int(std::distance(pts.begin(), pt));
+ result+="></td>";
+ }
+ for (cell_def=(*row)->CellDefs->begin(), cell=(*row)->Cells.begin();
+ cell!=(*row)->Cells.end(); ++cell, ++cell_def)
+ {
+ ptp=pts.find((*cell_def)->Right);
+ if (ptp==pts.end())
+// throw std::logic_error("No celldef.right point!");
+ colspan=std::distance(pt, ptp);
+ pt=ptp;
+ if (!(*cell_def)->Merged)
+ {
+ result+="<td";
+ // analyzing borders
+ left=(*cell_def)->Left;
+ right=(*cell_def)->Right;
+ bbottom=(*cell_def)->BorderBottom;
+ btop=(*cell_def)->BorderTop;
+ bleft=(*cell_def)->BorderLeft;
+ bright=(*cell_def)->BorderRight;
+ span_row=row;
+ if ((*cell_def)->FirstMerged)
+ std::advance(span_row, (*cell)->Rowspan-1);
+ for (row2=row; row2!=span_row; ++row2)
+ {
+ cell_def_2=
+ std::find_if((*row2)->CellDefs->begin(),
+ (*row2)->CellDefs->end(),
+ std::bind2nd(
+ std::mem_fun(&table_cell_def::right_equals),
+ left));
+ if (cell_def_2!=(*row2)->CellDefs->end())
+ {
+ bleft=bleft && (*cell_def_2)->BorderRight;
+ }
+ cell_def_2=
+ std::find_if((*row2)->CellDefs->begin(),
+ (*row2)->CellDefs->end(),
+ std::bind2nd(
+ std::mem_fun(&table_cell_def::left_equals),
+ right));
+ if (cell_def_2!=(*row2)->CellDefs->end())
+ {
+ bright=bright && (*cell_def_2)->BorderLeft;
+ }
+ }
+
+ if (bbottom && btop && bleft && bright)
+ {
+ style="border:1px solid black;";
+ }
+ else
+ {
+ style="";
+ if (bbottom)
+ style+="border-bottom:1px solid black;";
+ if (btop)
+ style+="border-top:1px solid black;";
+ if (bleft)
+ style+="border-left:1px solid black;";
+ if (bright)
+ style+="border-right:1px solid black;";
+ }
+ if (!style.empty())
+ {
+ result+=" style=\"";
+ result+=style;
+ result+="\"";
+ }
+ if (colspan>1)
+ {
+ result+=" colspan=";
+ result+=from_int(colspan);
+ }
+ if ((*cell_def)->FirstMerged)
+ {
+ result+=" rowspan=";
+ result+=from_int((*cell)->Rowspan);
+ }
+
+ switch ((*cell_def)->VAlign)
+ {
+ case table_cell_def::valign_top:
+ result+=" valign=top";
+ break;
+ case table_cell_def::valign_bottom:
+ result+=" valign=bottom";
+ break;
+ default: break;
+ }
+
+ result+=">";
+ if ((*cell)->Text[0]>0)
+ result+=(*cell)->Text;
+ else
+ result+="&nbsp;";
+ result+="</td>";
+ }
+ }
+ result+="</tr>";
+ }
+ result+="</table>";
+ return result;
+}
diff --git a/src/rtf2html/rtf_table.h b/src/rtf2html/rtf_table.h
new file mode 100644
index 0000000..927cc40
--- /dev/null
+++ b/src/rtf2html/rtf_table.h
@@ -0,0 +1,90 @@
+/* This is RTF to HTML converter, implemented as a text filter, generally.
+ Copyright (C) 2003 Valentin Lavrinenko, vlavrinenko@users.sourceforge.net
+
+ available at http://rtf2html.sf.net
+
+ Original available under the terms of the GNU LGPL2, and according
+ to those terms, relicensed under the GNU GPL2 for inclusion in Tellico */
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef __RTF_H__
+#define __RTF_H__
+
+#include "common.h"
+#include <vector>
+#include <cmath>
+#include <list>
+#include <cstdlib>
+
+namespace rtf {
+
+struct table_cell
+{
+ int Rowspan;
+ std::string Text;
+ table_cell() : Rowspan(0) {}
+};
+
+struct table_cell_def
+{
+ enum valign {valign_top, valign_bottom, valign_center};
+ bool BorderTop, BorderBottom, BorderLeft, BorderRight;
+ bool *ActiveBorder;
+ int Right, Left;
+ bool Merged, FirstMerged;
+ valign VAlign;
+ table_cell_def()
+ {
+ BorderTop=BorderBottom=BorderLeft=BorderRight=Merged=FirstMerged=false;
+ ActiveBorder=NULL;
+ Right=Left=0;
+ VAlign=valign_top;
+ }
+ bool right_equals(int x) { return x==Right; }
+ bool left_equals(int x) { return x==Left; }
+};
+
+template <class T>
+class killing_ptr_vector : public std::vector<T*>
+{
+ public:
+ ~killing_ptr_vector()
+ {
+ for (typename killing_ptr_vector<T>::iterator i=this->begin(); i!=this->end(); ++i)
+ delete *i;
+ }
+};
+
+typedef killing_ptr_vector<table_cell> table_cells;
+typedef killing_ptr_vector<table_cell_def> table_cell_defs;
+
+typedef std::list<table_cell_defs> table_cell_defs_list;
+
+struct table_row
+{
+ table_cells Cells;
+ table_cell_defs_list::iterator CellDefs;
+ int Height;
+ int Left;
+ table_row() : Height(-1000), Left(-1000) {}
+};
+
+class table : public killing_ptr_vector<table_row>
+{
+ private:
+ typedef killing_ptr_vector<table_row> base_class;
+ public:
+ table() : base_class() {}
+ std::string make();
+};
+
+}
+
+#endif
diff --git a/src/rtf2html/rtf_tools.h b/src/rtf2html/rtf_tools.h
new file mode 100644
index 0000000..528549e
--- /dev/null
+++ b/src/rtf2html/rtf_tools.h
@@ -0,0 +1,65 @@
+/* This is RTF to HTML converter, implemented as a text filter, generally.
+ Copyright (C) 2003 Valentin Lavrinenko, vlavrinenko@users.sourceforge.net
+
+ available at http://rtf2html.sf.net
+
+ Original available under the terms of the GNU LGPL2, and according
+ to those terms, relicensed under the GNU GPL2 for inclusion in Tellico */
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef __RTF_TOOLS_H__
+#define __RTF_TOOLS_H__
+
+#include "common.h"
+#include "rtf_keyword.h"
+
+namespace rtf {
+
+template <class InputIter>
+void skip_group(InputIter &iter);
+
+
+/****************************************
+function assumes that file pointer points AFTER the opening brace
+and that the group is really closed. cs is caller's curchar.
+Returns the character that comes after the enclosing brace.
+*****************************************/
+
+template <class InputIter>
+void skip_group(InputIter &iter)
+{
+ int cnt=1;
+ while (cnt)
+ {
+ switch (*iter++)
+ {
+ case '{':
+ cnt++;
+ break;
+ case '}':
+ cnt--;
+ break;
+ case '\\':
+ {
+ rtf_keyword kw(iter);
+ if (!kw.is_control_char() && kw.keyword()==rtf_keyword::rkw_bin
+ && kw.parameter()>0)
+ {
+ std::advance(iter, kw.parameter());
+ }
+ break;
+ }
+ }
+ }
+}
+
+}
+
+#endif
diff --git a/src/statusbar.cpp b/src/statusbar.cpp
new file mode 100644
index 0000000..a21baca
--- /dev/null
+++ b/src/statusbar.cpp
@@ -0,0 +1,122 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "statusbar.h"
+#include "tellico_debug.h"
+#include "progressmanager.h"
+#include "tellico_debug.h"
+#include "gui/progress.h"
+
+#include <klocale.h>
+#include <kapplication.h>
+#include <kpushbutton.h>
+#include <kiconloader.h>
+
+#include <qobjectlist.h>
+#include <qpainter.h>
+#include <qstyle.h>
+#include <qtimer.h>
+#include <qtooltip.h>
+
+using Tellico::StatusBar;
+StatusBar* StatusBar::s_self = 0;
+
+StatusBar::StatusBar(QWidget* parent_) : KStatusBar(parent_) {
+ s_self = this;
+
+ // don't care about text and id
+ m_mainLabel = new KStatusBarLabel(QString(), 0, this);
+ m_mainLabel->setIndent(4);
+ m_mainLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ addWidget(m_mainLabel, 3 /*stretch*/, true /*permanent*/);
+
+ m_countLabel = new KStatusBarLabel(QString(), 1, this);
+ m_countLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ m_countLabel->setIndent(4);
+ addWidget(m_countLabel, 0, true);
+
+ m_progress = new GUI::Progress(100, this);
+ addWidget(m_progress, 1, true);
+ m_cancelButton = new KPushButton(SmallIcon(QString::fromLatin1("cancel")), QString::null, this);
+ QToolTip::add(m_cancelButton, i18n("Cancel"));
+ addWidget(m_cancelButton, 0, true);
+ m_progress->hide();
+ m_cancelButton->hide();
+
+ ProgressManager* pm = ProgressManager::self();
+ connect(pm, SIGNAL(signalTotalProgress(uint)), SLOT(slotProgress(uint)));
+ connect(m_cancelButton, SIGNAL(clicked()), pm, SLOT(slotCancelAll()));
+}
+
+void StatusBar::polish() {
+ KStatusBar::polish();
+
+ int h = 0;
+ QObjectList* list = queryList("QWidget", 0, false, false);
+ for(QObject* o = list->first(); o; o = list->next()) {
+ int _h = static_cast<QWidget*>(o)->minimumSizeHint().height();
+ if(_h > h) {
+ h = _h;
+ }
+ }
+
+ h -= 4; // hint from amarok, it's too big usually
+
+ for(QObject* o = list->first(); o; o = list->next()) {
+ static_cast<QWidget*>(o)->setFixedHeight(h);
+ }
+
+ delete list;
+}
+
+void StatusBar::clearStatus() {
+ setStatus(i18n("Ready."));
+}
+
+void StatusBar::setStatus(const QString& status_) {
+ // always add a space for asthetics
+ m_mainLabel->setText(status_ + ' ');
+}
+
+void StatusBar::setCount(const QString& count_) {
+ m_countLabel->setText(count_ + ' ');
+}
+
+void StatusBar::slotProgress(uint progress_) {
+ m_progress->setProgress(progress_);
+ if(m_progress->isDone()) {
+ m_progress->hide();
+ m_cancelButton->hide();
+ } else if(m_progress->isHidden()) {
+ m_progress->show();
+ if(ProgressManager::self()->anyCanBeCancelled()) {
+ m_cancelButton->show();
+ }
+ kapp->processEvents(); // needed so the window gets updated ???
+ }
+}
+
+void StatusBar::slotUpdate() {
+/*
+ myDebug() << "StatusBar::slotUpdate() - " << m_progress->isShown() << endl;
+ if(m_progressBox->isEmpty()) {
+ QTimer::singleShot(0, m_progress, SLOT(hide()));
+// m_progressBox->hide();
+ } else {
+ QTimer::singleShot(0, m_progress, SLOT(show()));
+// m_progressBox->show();
+ }
+*/
+}
+
+#include "statusbar.moc"
diff --git a/src/statusbar.h b/src/statusbar.h
new file mode 100644
index 0000000..1ce3c39
--- /dev/null
+++ b/src/statusbar.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+// much of this code is adapted from amarok
+// which is GPL licensed, Copyright (C) 2005 by Max Howell
+
+#ifndef TELLICO_STATUSBAR_H
+#define TELLICO_STATUSBAR_H
+
+#include <kstatusbar.h>
+
+namespace Tellico {
+ namespace GUI {
+ class Progress;
+ }
+ class MainWindow;
+
+/**
+ * @author Robby Stephenson
+ */
+class StatusBar : public KStatusBar {
+Q_OBJECT
+
+public:
+ void clearStatus();
+ void setStatus(const QString& status);
+ void setCount(const QString& count);
+
+ static StatusBar* self() { return s_self; }
+
+protected:
+ virtual void polish();
+
+private slots:
+ void slotProgress(uint progress);
+ void slotUpdate();
+
+private:
+ static StatusBar* s_self;
+
+ friend class MainWindow;
+
+ StatusBar(QWidget* parent);
+
+ KStatusBarLabel* m_mainLabel;
+ KStatusBarLabel* m_countLabel;
+ GUI::Progress* m_progress;
+ QWidget* m_cancelButton;
+};
+
+}
+
+#endif
diff --git a/src/stringset.h b/src/stringset.h
new file mode 100644
index 0000000..47667a0
--- /dev/null
+++ b/src/stringset.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_STRINGSET_H
+#define TELLICO_STRINGSET_H
+
+#include <qdict.h>
+#include <qstringlist.h>
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class StringSet {
+
+public:
+ StringSet(int size = 17) : m_dict(size) {}
+
+ // replace instead of insert, to ensure unique keys
+ void add(const QString& val) { if(!val.isEmpty()) m_dict.replace(val, reinterpret_cast<const int *>(1)); }
+ void add(const QStringList& vals) {
+ for(QStringList::ConstIterator it = vals.begin(), end = vals.end(); it != end; ++it) {
+ add(*it);
+ }
+ }
+ bool remove(const QString& val) { return !val.isEmpty() && m_dict.remove(val); }
+ void clear() { m_dict.clear(); }
+ bool has(const QString& val) const { return !val.isEmpty() && (m_dict.find(val) != 0); }
+ bool isEmpty() const { return m_dict.isEmpty(); }
+ uint count() const { return m_dict.count(); }
+
+ QStringList toList() const {
+ QStringList list;
+ for(QDictIterator<int> it(m_dict); it.current(); ++it) {
+ list << it.currentKey();
+ }
+ return list;
+ }
+
+private:
+ // use a dict for fast random access to keep track of the values
+ QDict<int> m_dict;
+};
+
+}
+
+#endif
diff --git a/src/tellico_debug.h b/src/tellico_debug.h
new file mode 100644
index 0000000..ea65518
--- /dev/null
+++ b/src/tellico_debug.h
@@ -0,0 +1,156 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_DEBUG_H
+#define TELLICO_DEBUG_H
+
+// most of this is borrowed from amarok/src/debug.h
+// which is copyright Max Howell <max.howell@methylblue.com>
+// amarok is licensed under the GPL
+
+#include <kdebug.h>
+// std::clock_t
+#include <ctime>
+
+// linux has __GNUC_PREREQ, NetBSD has __GNUC_PREQ__
+#if defined(__GNUC_PREREQ) && !defined(__GNUC_PREREQ__)
+#define __GNUC_PREREQ__ __GNUC_PREREQ
+#endif
+
+#if !defined(__GNUC_PREREQ__)
+#if defined __GNUC__
+#define __GNUC_PREREQ__(x, y) \
+ ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
+ (__GNUC__ > (x)))
+#else
+#define __GNUC_PREREQ__(x, y) 0
+#endif
+#endif
+
+# if defined __cplusplus ? __GNUC_PREREQ__ (2, 6) : __GNUC_PREREQ__ (2, 4)
+# define MY_FUNCTION __PRETTY_FUNCTION__
+# else
+# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+# define MY_FUNCTION __func__
+# else
+# define MY_FUNCTION __FILE__ ":" __LINE__
+# endif
+# endif
+
+// some logging
+#ifndef NDEBUG
+#define TELLICO_LOG
+#endif
+
+#ifndef NDEBUG
+#define TELLICO_DEBUG
+#endif
+
+namespace Debug {
+ typedef kndbgstream NoDebugStream;
+#ifndef TELLICO_DEBUG
+ typedef kndbgstream DebugStream;
+ static inline DebugStream log() { return DebugStream(); }
+ static inline DebugStream debug() { return DebugStream(); }
+ static inline DebugStream warning() { return DebugStream(); }
+ static inline DebugStream error() { return DebugStream(); }
+ static inline DebugStream fatal() { return DebugStream(); }
+
+#else
+ #ifndef DEBUG_PREFIX
+ #define FUNC_PREFIX ""
+ #else
+ #define FUNC_PREFIX "[" DEBUG_PREFIX "] "
+ #endif
+
+//from kdebug.h
+/*
+ enum DebugLevels {
+ KDEBUG_INFO = 0,
+ KDEBUG_WARN = 1,
+ KDEBUG_ERROR = 2,
+ KDEBUG_FATAL = 3
+ };
+*/
+
+ typedef kdbgstream DebugStream;
+#ifdef TELLICO_LOG
+ static inline DebugStream log() { return kdDebug(); }
+#else
+ static inline kndbgstream log() { return NoDebugStream(); }
+#endif
+ static inline DebugStream debug() { return kdDebug() << FUNC_PREFIX; }
+ static inline DebugStream warning() { return kdWarning() << FUNC_PREFIX << "[WARNING!] "; }
+ static inline DebugStream error() { return kdError() << FUNC_PREFIX << "[ERROR!] "; }
+ static inline DebugStream fatal() { return kdFatal() << FUNC_PREFIX; }
+
+ #undef FUNC_PREFIX
+#endif
+
+class Block {
+
+public:
+ Block(const char* label) : m_start(std::clock()), m_label(label) {
+ Debug::debug() << "BEGIN: " << label << endl;
+ }
+
+ ~Block() {
+ std::clock_t finish = std::clock();
+ const double duration = (double) (finish - m_start) / CLOCKS_PER_SEC;
+ Debug::debug() << " END: " << m_label << " - duration = " << duration << endl;
+ }
+
+private :
+ std::clock_t m_start;
+ const char* m_label;
+};
+
+}
+
+#define myDebug() Debug::debug()
+#define myWarning() Debug::warning()
+#define myLog() Debug::log()
+
+/// Standard function announcer
+#define DEBUG_FUNC_INFO myDebug() << k_funcinfo << endl;
+
+/// Announce a line
+#define DEBUG_LINE_INFO myDebug() << k_funcinfo << "Line: " << __LINE__ << endl;
+
+/// Convenience macro for making a standard Debug::Block
+#define DEBUG_BLOCK Debug::Block uniquelyNamedStackAllocatedStandardBlock( __func__ );
+
+#ifdef TELLICO_LOG
+// see http://www.gnome.org/~federico/news-2006-03.html#timeline-tools
+#define MARK do { \
+ char str[128]; \
+ ::snprintf(str, 128, "MARK: %s: %s (%d)", className(), MY_FUNCTION, __LINE__); \
+ ::access (str, F_OK); \
+ } while(false)
+#define MARK_MSG(s) do { \
+ char str[128]; \
+ ::snprintf(str, 128, "MARK: %s: %s (%d)", className(), s, __LINE__); \
+ ::access (str, F_OK); \
+ } while(false)
+#define MARK_LINE do { \
+ char str[128]; \
+ ::snprintf(str, 128, "MARK: tellico: %s (%d)", __FILE__, __LINE__); \
+ ::access (str, F_OK); \
+ } while(false)
+#else
+#define MARK
+#define MARK_MSG(s)
+#define MARK_LINE
+#endif
+
+#endif
diff --git a/src/tellico_kernel.cpp b/src/tellico_kernel.cpp
new file mode 100644
index 0000000..e0e42b5
--- /dev/null
+++ b/src/tellico_kernel.cpp
@@ -0,0 +1,407 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "tellico_kernel.h"
+#include "mainwindow.h"
+#include "document.h"
+#include "collection.h"
+#include "entryitem.h"
+#include "controller.h"
+#include "filter.h"
+#include "filterdialog.h"
+#include "loandialog.h"
+#include "calendarhandler.h"
+#include "tellico_utils.h"
+#include "tellico_debug.h"
+#include "commands/group.h"
+#include "commands/collectioncommand.h"
+#include "commands/fieldcommand.h"
+#include "commands/filtercommand.h"
+#include "commands/addentries.h"
+#include "commands/modifyentries.h"
+#include "commands/updateentries.h"
+#include "commands/removeentries.h"
+#include "commands/removeloans.h"
+#include "commands/reorderfields.h"
+#include "commands/renamecollection.h"
+#include "collectionfactory.h"
+#include "stringset.h"
+
+#include <kmessagebox.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <kinputdialog.h>
+#include <klocale.h>
+
+using Tellico::Kernel;
+Kernel* Kernel::s_self = 0;
+
+Kernel::Kernel(MainWindow* parent) : m_widget(parent)
+ , m_commandHistory(parent->actionCollection())
+ , m_commandGroup(0) {
+}
+
+const KURL& Kernel::URL() const {
+ return Data::Document::self()->URL();
+}
+
+const QStringList& Kernel::fieldTitles() const {
+ return Data::Document::self()->collection()->fieldTitles();
+}
+
+QString Kernel::fieldNameByTitle(const QString& title_) const {
+ return Data::Document::self()->collection()->fieldNameByTitle(title_);
+}
+
+QString Kernel::fieldTitleByName(const QString& name_) const {
+ return Data::Document::self()->collection()->fieldTitleByName(name_);
+}
+
+QStringList Kernel::valuesByFieldName(const QString& name_) const {
+ return Data::Document::self()->collection()->valuesByFieldName(name_);
+}
+
+int Kernel::collectionType() const {
+ return Data::Document::self()->collection()->type();
+}
+
+QString Kernel::collectionTypeName() const {
+ return Data::Document::self()->collection()->typeName();
+}
+
+void Kernel::sorry(const QString& text_, QWidget* widget_/* =0 */) {
+ if(text_.isEmpty()) {
+ return;
+ }
+ GUI::CursorSaver cs(Qt::arrowCursor);
+ KMessageBox::sorry(widget_ ? widget_ : m_widget, text_);
+}
+
+void Kernel::beginCommandGroup(const QString& name_) {
+ if(m_commandGroup) {
+ myDebug() << "Kernel::beginCommandGroup() - there's an uncommitted group!" << endl;
+ delete m_commandGroup;
+ }
+ m_commandGroup = new Command::Group(name_);
+}
+
+void Kernel::endCommandGroup() {
+ if(!m_commandGroup) {
+ myDebug() << "Kernel::endCommandGroup() - beginCommandGroup() must be called first!" << endl;
+ return;
+ }
+ if(m_commandGroup->isEmpty()) {
+ delete m_commandGroup;
+ } else {
+ m_commandHistory.addCommand(m_commandGroup);
+ Data::Document::self()->slotSetModified(true);
+ }
+ m_commandGroup = 0;
+}
+
+void Kernel::resetHistory() {
+ m_commandHistory.clear();
+ m_commandHistory.documentSaved();
+}
+
+bool Kernel::addField(Data::FieldPtr field_) {
+ if(!field_) {
+ return false;
+ }
+ doCommand(new Command::FieldCommand(Command::FieldCommand::FieldAdd,
+ Data::Document::self()->collection(),
+ field_));
+ return true;
+}
+
+bool Kernel::modifyField(Data::FieldPtr field_) {
+ if(!field_) {
+ return false;
+ }
+ Data::FieldPtr oldField = Data::Document::self()->collection()->fieldByName(field_->name());
+ if(!oldField) {
+ return false;
+ }
+ doCommand(new Command::FieldCommand(Command::FieldCommand::FieldModify,
+ Data::Document::self()->collection(),
+ field_,
+ oldField));
+ return true;
+}
+
+bool Kernel::removeField(Data::FieldPtr field_) {
+ if(!field_) {
+ return false;
+ }
+ doCommand(new Command::FieldCommand(Command::FieldCommand::FieldRemove,
+ Data::Document::self()->collection(),
+ field_));
+ return true;
+}
+
+void Kernel::addEntries(Data::EntryVec entries_, bool checkFields_) {
+ if(entries_.isEmpty()) {
+ return;
+ }
+
+ KCommand* cmd = new Command::AddEntries(Data::Document::self()->collection(), entries_);
+ if(checkFields_) {
+ beginCommandGroup(cmd->name());
+
+ // this is the same as in Command::UpdateEntries::execute()
+ Data::CollPtr c = Data::Document::self()->collection();
+ Data::FieldVec fields = entries_[0]->collection()->fields();
+
+ QPair<Data::FieldVec, Data::FieldVec> p = mergeFields(c, fields, entries_);
+ Data::FieldVec modifiedFields = p.first;
+ Data::FieldVec addedFields = p.second;
+
+ for(Data::FieldVec::Iterator field = modifiedFields.begin(); field != modifiedFields.end(); ++field) {
+ if(c->hasField(field->name())) {
+ doCommand(new Command::FieldCommand(Command::FieldCommand::FieldModify, c,
+ field, c->fieldByName(field->name())));
+ }
+ }
+
+ for(Data::FieldVec::Iterator field = addedFields.begin(); field != addedFields.end(); ++field) {
+ doCommand(new Command::FieldCommand(Command::FieldCommand::FieldAdd, c, field));
+ }
+ }
+ doCommand(cmd);
+ if(checkFields_) {
+ endCommandGroup();
+ }
+}
+
+void Kernel::modifyEntries(Data::EntryVec oldEntries_, Data::EntryVec newEntries_) {
+ if(newEntries_.isEmpty()) {
+ return;
+ }
+
+ doCommand(new Command::ModifyEntries(Data::Document::self()->collection(), oldEntries_, newEntries_));
+}
+
+void Kernel::updateEntry(Data::EntryPtr oldEntry_, Data::EntryPtr newEntry_, bool overWrite_) {
+ if(!newEntry_) {
+ return;
+ }
+
+ doCommand(new Command::UpdateEntries(Data::Document::self()->collection(), oldEntry_, newEntry_, overWrite_));
+}
+
+void Kernel::removeEntries(Data::EntryVec entries_) {
+ if(entries_.isEmpty()) {
+ return;
+ }
+
+ doCommand(new Command::RemoveEntries(Data::Document::self()->collection(), entries_));
+}
+
+bool Kernel::addLoans(Data::EntryVec entries_) {
+ if(entries_.isEmpty()) {
+ return false;
+ }
+
+ LoanDialog dlg(entries_, m_widget);
+ if(dlg.exec() != QDialog::Accepted) {
+ return false;
+ }
+
+ KCommand* cmd = dlg.createCommand();
+ if(!cmd) {
+ return false;
+ }
+ doCommand(cmd);
+ return true;
+}
+
+bool Kernel::modifyLoan(Data::LoanPtr loan_) {
+ if(!loan_) {
+ return false;
+ }
+
+ LoanDialog dlg(loan_, m_widget);
+ if(dlg.exec() != QDialog::Accepted) {
+ return false;
+ }
+
+ KCommand* cmd = dlg.createCommand();
+ if(!cmd) {
+ return false;
+ }
+ doCommand(cmd);
+ return true;
+}
+
+bool Kernel::removeLoans(Data::LoanVec loans_) {
+ if(loans_.isEmpty()) {
+ return true;
+ }
+
+ doCommand(new Command::RemoveLoans(loans_));
+ return true;
+}
+
+void Kernel::addFilter(FilterPtr filter_) {
+ if(!filter_) {
+ return;
+ }
+
+ doCommand(new Command::FilterCommand(Command::FilterCommand::FilterAdd, filter_));
+}
+
+bool Kernel::modifyFilter(FilterPtr filter_) {
+ if(!filter_) {
+ return false;
+ }
+
+ FilterDialog filterDlg(FilterDialog::ModifyFilter, m_widget);
+ // need to create a new filter object
+ FilterPtr newFilter = new Filter(*filter_);
+ filterDlg.setFilter(newFilter);
+ if(filterDlg.exec() != QDialog::Accepted) {
+ return false;
+ }
+
+ doCommand(new Command::FilterCommand(Command::FilterCommand::FilterModify, newFilter, filter_));
+ return true;
+}
+
+bool Kernel::removeFilter(FilterPtr filter_) {
+ if(!filter_) {
+ return false;
+ }
+
+ QString str = i18n("Do you really want to delete this filter?");
+ QString dontAsk = QString::fromLatin1("DeleteFilter");
+ int ret = KMessageBox::questionYesNo(m_widget, str, i18n("Delete Filter?"),
+ KStdGuiItem::yes(), KStdGuiItem::no(), dontAsk);
+ if(ret != KMessageBox::Yes) {
+ return false;
+ }
+
+ doCommand(new Command::FilterCommand(Command::FilterCommand::FilterRemove, filter_));
+ return true;
+}
+
+void Kernel::reorderFields(const Data::FieldVec& fields_) {
+ doCommand(new Command::ReorderFields(Data::Document::self()->collection(),
+ Data::Document::self()->collection()->fields(),
+ fields_));
+}
+
+void Kernel::appendCollection(Data::CollPtr coll_) {
+ doCommand(new Command::CollectionCommand(Command::CollectionCommand::Append,
+ Data::Document::self()->collection(),
+ coll_));
+}
+
+void Kernel::mergeCollection(Data::CollPtr coll_) {
+ doCommand(new Command::CollectionCommand(Command::CollectionCommand::Merge,
+ Data::Document::self()->collection(),
+ coll_));
+}
+
+void Kernel::replaceCollection(Data::CollPtr coll_) {
+ doCommand(new Command::CollectionCommand(Command::CollectionCommand::Replace,
+ Data::Document::self()->collection(),
+ coll_));
+}
+
+void Kernel::renameCollection() {
+ bool ok;
+ QString newTitle = KInputDialog::getText(i18n("Rename Collection"), i18n("New collection name:"),
+ Data::Document::self()->collection()->title(), &ok, m_widget);
+ if(ok) {
+ doCommand(new Command::RenameCollection(Data::Document::self()->collection(), newTitle));
+ }
+}
+
+void Kernel::doCommand(KCommand* command_) {
+ if(m_commandGroup) {
+ m_commandGroup->addCommand(command_);
+ } else {
+ m_commandHistory.addCommand(command_);
+ Data::Document::self()->slotSetModified(true);
+ }
+}
+
+QPair<Tellico::Data::FieldVec, Tellico::Data::FieldVec> Kernel::mergeFields(Data::CollPtr coll_,
+ Data::FieldVec fields_,
+ Data::EntryVec entries_) {
+ Data::FieldVec modified, created;
+ for(Data::FieldVec::Iterator field = fields_.begin(); field != fields_.end(); ++field) {
+ // don't add a field if it's a default field and not in the current collection
+ if(coll_->hasField(field->name()) || CollectionFactory::isDefaultField(coll_->type(), field->name())) {
+ // special case for choice fields, since we might want to add a value
+ if(field->type() == Data::Field::Choice && coll_->hasField(field->name())) {
+ QStringList a1 = field->allowed();
+ QStringList a2 = coll_->fieldByName(field->name())->allowed();
+ if(a1 != a2) {
+ StringSet a;
+ a.add(a1);
+ a.add(a2);
+ Data::FieldPtr f = new Data::Field(*coll_->fieldByName(field->name()));
+ f->setAllowed(a.toList());
+ modified.append(f);
+ }
+ }
+ continue;
+ }
+ // add field if any values are not empty
+ for(Data::EntryVec::Iterator entry = entries_.begin(); entry != entries_.end(); ++entry) {
+ if(!entry->field(field).isEmpty()) {
+ created.append(new Data::Field(*field));
+ break;
+ }
+ }
+ }
+ return qMakePair(modified, created);
+}
+
+int Kernel::askAndMerge(Data::EntryPtr entry1_, Data::EntryPtr entry2_, Data::FieldPtr field_,
+ QString value1_, QString value2_) {
+ QString title1 = entry1_->field(QString::fromLatin1("title"));
+ QString title2 = entry2_->field(QString::fromLatin1("title"));
+ if(title1 == title2) {
+ title1 = i18n("Entry 1");
+ title2 = i18n("Entry 2");
+ }
+ if(value1_.isEmpty()) {
+ value1_ = entry1_->field(field_);
+ }
+ if(value2_.isEmpty()) {
+ value2_ = entry2_->field(field_);
+ }
+ QString text = QString::fromLatin1("<qt>")
+ + i18n("Conflicting values for %1 were found while merging entries.").arg(field_->title())
+ + QString::fromLatin1("<br/><center><table><tr>"
+ "<th>%1</th>"
+ "<th>%2</th></tr>").arg(title1, title2)
+ + QString::fromLatin1("<tr><td><em>%1</em></td>").arg(value1_)
+ + QString::fromLatin1("<td><em>%1</em></td></tr></table></center>").arg(value2_)
+ + i18n("Please choose which value to keep.")
+ + QString::fromLatin1("</qt>");
+
+ int ret = KMessageBox::warningYesNoCancel(Kernel::self()->widget(),
+ text,
+ i18n("Merge Entries"),
+ i18n("Select value from %1").arg(title1),
+ i18n("Select value from %1").arg(title2));
+ switch(ret) {
+ case KMessageBox::Cancel: return 0;
+ case KMessageBox::Yes: return -1; // keep original value
+ case KMessageBox::No: return 1; // use newer value
+ }
+ return 0;
+}
diff --git a/src/tellico_kernel.h b/src/tellico_kernel.h
new file mode 100644
index 0000000..ed801d6
--- /dev/null
+++ b/src/tellico_kernel.h
@@ -0,0 +1,145 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_KERNEL_H
+#define TELLICO_KERNEL_H
+
+#include "datavectors.h"
+#include "borrower.h"
+
+#include <kcommand.h>
+
+class KURL;
+
+class QWidget;
+class QString;
+class QStringList;
+
+namespace Tellico {
+ class MainWindow;
+ class Filter;
+ namespace Command {
+ class Group;
+ }
+ namespace Data {
+ class Collection;
+ }
+
+/**
+ * @author Robby Stephenson
+ */
+class Kernel {
+
+public:
+ static Kernel* self() { return s_self; }
+ /**
+ * Initializes the singleton. Should just be called once, from Tellico::MainWindow
+ */
+ static void init(MainWindow* parent) { if(!s_self) s_self = new Kernel(parent); }
+
+ /**
+ * Returns a pointer to the parent widget. This is mainly used for error dialogs and the like.
+ *
+ * @return The widget pointer
+ */
+ QWidget* widget() { return m_widget; }
+
+ /**
+ * Returns the url of the current document.
+ *
+ * @return The URL
+ */
+ const KURL& URL() const;
+ /**
+ * Returns a list of the field titles, wraps the call to the collection itself.
+ *
+ * @return the field titles
+ */
+ const QStringList& fieldTitles() const;
+ /**
+ * Returns the name of an field, given its title. Wraps the call to the collection itself.
+ *
+ * @param title The field title
+ * @return The field name
+ */
+ QString fieldNameByTitle(const QString& title) const;
+ /**
+ * Returns the title of an field, given its name. Wraps the call to the collection itself.
+ *
+ * @param name The field name
+ * @return The field title
+ */
+ QString fieldTitleByName(const QString& name) const;
+ QStringList valuesByFieldName(const QString& name) const;
+
+ int collectionType() const;
+ QString collectionTypeName() const;
+
+ void sorry(const QString& text, QWidget* widget=0);
+
+ void beginCommandGroup(const QString& name);
+ void endCommandGroup();
+ void resetHistory();
+
+ bool addField(Data::FieldPtr field);
+ bool modifyField(Data::FieldPtr field);
+ bool removeField(Data::FieldPtr field);
+
+ void addEntries(Data::EntryVec entries, bool checkFields);
+ void modifyEntries(Data::EntryVec oldEntries, Data::EntryVec newEntries);
+ void updateEntry(Data::EntryPtr oldEntry, Data::EntryPtr newEntry, bool overWrite);
+ void removeEntries(Data::EntryVec entries);
+
+ bool addLoans(Data::EntryVec entries);
+ bool modifyLoan(Data::LoanPtr loan);
+ bool removeLoans(Data::LoanVec loans);
+
+ void addFilter(FilterPtr filter);
+ bool modifyFilter(FilterPtr filter);
+ bool removeFilter(FilterPtr filter);
+
+ void reorderFields(const Data::FieldVec& fields);
+
+ void appendCollection(Data::CollPtr coll);
+ void mergeCollection(Data::CollPtr coll);
+ void replaceCollection(Data::CollPtr coll);
+
+ // adds new fields into collection if any values in entries are not empty
+ // first object is modified fields, second is new fields
+ QPair<Data::FieldVec, Data::FieldVec> mergeFields(Data::CollPtr coll,
+ Data::FieldVec fields,
+ Data::EntryVec entries);
+
+ void renameCollection();
+ const KCommandHistory* commandHistory() { return &m_commandHistory; }
+
+ int askAndMerge(Data::EntryPtr entry1, Data::EntryPtr entry2, Data::FieldPtr field,
+ QString value1 = QString(), QString value2 = QString());
+
+private:
+ static Kernel* s_self;
+
+ // all constructors are private
+ Kernel(MainWindow* parent);
+ Kernel(const Kernel&);
+ Kernel& operator=(const Kernel&);
+
+ void doCommand(KCommand* command);
+
+ QWidget* m_widget;
+ KCommandHistory m_commandHistory;
+ Command::Group* m_commandGroup;
+};
+
+} // end namespace
+#endif
diff --git a/src/tellico_map.h b/src/tellico_map.h
new file mode 100644
index 0000000..75ceb32
--- /dev/null
+++ b/src/tellico_map.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_MAP_H
+#define TELLICO_MAP_H
+
+#include <qmap.h>
+
+/**
+ * This file contains some template functions for maps
+ *
+ * @author Robby Stephenson
+ */
+namespace Tellico {
+
+/**
+ * Reverse a map's keys and values
+ */
+template<class M>
+QMap<typename M::T, typename M::Key> flipMap(const M& map_) {
+ QMap<typename M::T, typename M::Key> map;
+ typename M::ConstIterator it = map_.begin(), end = map_.end();
+ for( ; it != end; ++it) {
+ map.insert(it.data(), it.key());
+ }
+ return map;
+}
+
+}
+
+#endif
diff --git a/src/tellico_strings.cpp b/src/tellico_strings.cpp
new file mode 100644
index 0000000..e80cbd7
--- /dev/null
+++ b/src/tellico_strings.cpp
@@ -0,0 +1,27 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "tellico_strings.h"
+
+#include <klocale.h>
+
+const char* Tellico::errorLoad = I18N_NOOP("Tellico is unable to load the file - %1.");
+const char* Tellico::errorWrite = I18N_NOOP("Tellico is unable to write the file - %1.");
+const char* Tellico::errorUpload = I18N_NOOP("Tellico is unable to upload the file - %1.");
+const char* Tellico::errorAppendType = I18N_NOOP("Only collections with the same type of entries as "
+ "the current one can be appended. No changes are being "
+ "made to the current collection.");
+const char* Tellico::errorMergeType = I18N_NOOP("Only collections with the same type of entries as "
+ "the current one can be merged. No changes are being "
+ "made to the current collection.");
+const char* Tellico::errorImageLoad = I18N_NOOP("Tellico is unable to load an image from the file - %1.");
diff --git a/src/tellico_strings.h b/src/tellico_strings.h
new file mode 100644
index 0000000..5db5c60
--- /dev/null
+++ b/src/tellico_strings.h
@@ -0,0 +1,26 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_STRINGS_H
+#define TELLICO_STRINGS_H
+
+namespace Tellico {
+ extern const char* errorLoad;
+ extern const char* errorWrite;
+ extern const char* errorUpload;
+ extern const char* errorAppendType;
+ extern const char* errorMergeType;
+ extern const char* errorImageLoad;
+}
+
+#endif
diff --git a/src/tellico_utils.cpp b/src/tellico_utils.cpp
new file mode 100644
index 0000000..6af6706
--- /dev/null
+++ b/src/tellico_utils.cpp
@@ -0,0 +1,218 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "tellico_utils.h"
+#include "tellico_kernel.h"
+#include "latin1literal.h"
+#include "tellico_debug.h"
+
+#include <kapplication.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <klibloader.h>
+#include <kstandarddirs.h>
+#include <kcharsets.h>
+
+#include <qregexp.h>
+#include <qdir.h>
+#include <qcursor.h>
+#include <qscrollview.h>
+
+namespace {
+ static const int STRING_STORE_SIZE = 997; // too big, too small?
+}
+
+QColor Tellico::contrastColor;
+
+QString Tellico::decodeHTML(QString text) {
+ QRegExp rx(QString::fromLatin1("&(.+);"));
+ rx.setMinimal(true);
+ int pos = rx.search(text);
+ while(pos > -1) {
+ QChar c = KCharsets::fromEntity(rx.cap(1));
+ if(!c.isNull()) {
+ text.replace(pos, rx.matchedLength(), c);
+ }
+ pos = rx.search(text, pos+1);
+ }
+ return text;
+}
+
+QString Tellico::uid(int l, bool prefix) {
+ QString uid;
+ if(prefix) {
+ uid = QString::fromLatin1("Tellico");
+ }
+ uid.append(kapp->randomString(QMAX(l - uid.length(), 0)));
+ return uid;
+}
+
+uint Tellico::toUInt(const QString& s, bool* ok) {
+ if(s.isEmpty()) {
+ if(ok) {
+ *ok = false;
+ }
+ return 0;
+ }
+
+ uint idx = 0;
+ while(s[idx].isDigit()) {
+ ++idx;
+ }
+ if(idx == 0) {
+ if(ok) {
+ *ok = false;
+ }
+ return 0;
+ }
+ return s.left(idx).toUInt(ok);
+}
+
+QString Tellico::i18nReplace(QString text) {
+ // Because QDomDocument sticks in random newlines, go ahead and grab them too
+ static QRegExp rx(QString::fromLatin1("(?:\\n+ *)*<i18n>([^<]*)</i18n>(?: *\\n+)*"));
+ int pos = rx.search(text);
+ while(pos > -1) {
+ text.replace(pos, rx.matchedLength(), i18n(rx.cap(1).utf8()));
+ pos = rx.search(text, pos+rx.matchedLength());
+ }
+ return text;
+}
+
+QStringList Tellico::findAllSubDirs(const QString& dir_) {
+ if(dir_.isEmpty()) {
+ return QStringList();
+ }
+
+ // TODO: build in symlink checking, for now, prohibit
+ QDir dir(dir_, QString::null, QDir::Name | QDir::IgnoreCase, QDir::Dirs | QDir::Readable | QDir::NoSymLinks);
+
+ QStringList allSubdirs; // the whole list
+
+ // find immediate sub directories
+ const QStringList subdirs = dir.entryList();
+ for(QStringList::ConstIterator subdir = subdirs.begin(); subdir != subdirs.end(); ++subdir) {
+ if((*subdir).isEmpty() || *subdir == Latin1Literal(".") || *subdir == Latin1Literal("..")) {
+ continue;
+ }
+ QString absSubdir = dir.absFilePath(*subdir);
+ allSubdirs += findAllSubDirs(absSubdir);
+ allSubdirs += absSubdir;
+ }
+ return allSubdirs;
+}
+
+// Based on QGDict's hash functions, Copyright (C) 1992-2000 Trolltech AS
+// and used from Juk, Copyright (C) 2003 - 2004 by Scott Wheeler
+int Tellico::stringHash(const QString& str) {
+ uint h = 0;
+ uint g = 0;
+ for(uint i = 0; i < str.length(); ++i) {
+ h = (h << 4) + str.unicode()[i].cell();
+ if((g = h & 0xf0000000)) {
+ h ^= g >> 24;
+ }
+ h &= ~g;
+ }
+
+ int index = h;
+ return index < 0 ? -index : index;
+}
+
+QString Tellico::shareString(const QString& str) {
+ static QString stringStore[STRING_STORE_SIZE];
+
+ const int hash = stringHash(str) % STRING_STORE_SIZE;
+ if(stringStore[hash] != str) {
+ stringStore[hash] = str;
+ }
+ return stringStore[hash];
+}
+
+void Tellico::updateContrastColor(const QColorGroup& cg_) {
+ // if the value difference between background and highlight is more than ???
+ // use highlight, else go lighter or darker
+ int h1, s1, v1, h2, s2, v2;
+ cg_.background().getHsv(&h1, &s1, &v1);
+
+ QColor hl = cg_.highlight();
+ hl.getHsv(&h2, &s2, &v2);
+ h2 += 120;
+ s2 = 255;
+ hl.setHsv(h2, s2, v2);
+
+ if(KABS(v2-v1) < 48) {
+ if(v1 < 128) {
+ contrastColor = hl.light();
+ } else {
+ contrastColor = hl.dark();
+ }
+ } else {
+ contrastColor = hl;
+ }
+}
+
+KLibrary* Tellico::openLibrary(const QString& libName_) {
+ QString path = KLibLoader::findLibrary(QFile::encodeName(libName_));
+ if(path.isEmpty()) {
+ kdWarning() << "Tellico::openLibrary() - Could not find library '" << libName_ << "'" << endl;
+ kdWarning() << "ERROR: " << KLibLoader::self()->lastErrorMessage() << endl;
+ return 0;
+ }
+
+ KLibrary* library = KLibLoader::self()->library(QFile::encodeName(path));
+ if(!library) {
+ kdWarning() << "Tellico::openLibrary() - Could not load library '" << libName_ << "'" << endl;
+ kdWarning() << " PATH: " << path << endl;
+ kdWarning() << "ERROR: " << KLibLoader::self()->lastErrorMessage() << endl;
+ return 0;
+ }
+
+ return library;
+}
+
+QColor Tellico::blendColors(const QColor& color1, const QColor& color2, int percent) {
+ const double factor2 = percent/100.0;
+ const double factor1 = 1.0 - factor2;
+
+ const int r = static_cast<int>(color1.red() * factor1 + color2.red() * factor2);
+ const int g = static_cast<int>(color1.green() * factor1 + color2.green() * factor2);
+ const int b = static_cast<int>(color1.blue() * factor1 + color2.blue() * factor2);
+
+ return QColor(r, g, b);
+}
+
+QString Tellico::minutes(int seconds) {
+ int min = seconds / 60;
+ seconds = seconds % 60;
+ return QString::number(min) + ':' + QString::number(seconds).rightJustify(2, '0');
+}
+
+QString Tellico::saveLocation(const QString& dir_) {
+ return KGlobal::dirs()->saveLocation("appdata", dir_, true);
+}
+
+Tellico::GUI::CursorSaver::CursorSaver(const QCursor& cursor_) : m_restored(false) {
+ kapp->setOverrideCursor(cursor_);
+}
+
+Tellico::GUI::CursorSaver::~CursorSaver() {
+ if(!m_restored) {
+ kapp->restoreOverrideCursor();
+ }
+}
+
+void Tellico::GUI::CursorSaver::restore() {
+ kapp->restoreOverrideCursor();
+ m_restored = true;
+}
diff --git a/src/tellico_utils.h b/src/tellico_utils.h
new file mode 100644
index 0000000..13250e6
--- /dev/null
+++ b/src/tellico_utils.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_UTILS_H
+#define TELLICO_UTILS_H
+
+#include <qnamespace.h>
+
+class KLibrary;
+
+class QColor;
+class QColorGroup;
+class QCursor;
+class QString;
+class QStringList;
+class QScrollView;
+
+/**
+ * This file contains utility functions.
+ *
+ * @author Robby Stephenson
+ */
+namespace Tellico {
+ /**
+ * Decode HTML entities. Only numeric entities are handled currently.
+ */
+ QString decodeHTML(QString text);
+ /**
+ * Return a random, and almost certainly unique UID.
+ *
+ * @param length The UID starts with "Tellico" and adds enough letters to be @p length long.
+ */
+ QString uid(int length=20, bool prefix=true);
+ uint toUInt(const QString& string, bool* ok);
+ /**
+ * Replace all occurrences of <i18n>text</i18n> with i18n("text")
+ */
+ QString i18nReplace(QString text);
+ /**
+ * Returns a list of the subdirectories in @param dir
+ * Symbolic links are ignored
+ */
+ QStringList findAllSubDirs(const QString& dir);
+ int stringHash(const QString& str);
+ /** take advantage string collisions to reduce memory
+ */
+ QString shareString(const QString& str);
+
+ extern QColor contrastColor;
+ void updateContrastColor(const QColorGroup& cg);
+ QColor blendColors(const QColor& color1, const QColor& color2, int percent);
+ QString minutes(int seconds);
+ QString saveLocation(const QString& dir);
+
+ KLibrary* openLibrary(const QString& libName);
+
+namespace GUI {
+ class CursorSaver {
+ public:
+ CursorSaver(const QCursor& cursor = Qt::waitCursor);
+ ~CursorSaver();
+ void restore();
+ private:
+ bool m_restored : 1;
+ };
+}
+
+}
+
+#endif
diff --git a/src/tellicorc b/src/tellicorc
new file mode 100644
index 0000000..209e5d1
--- /dev/null
+++ b/src/tellicorc
@@ -0,0 +1,3 @@
+[KDE Action Restrictions]
+shell_access=false
+run_desktop_files=false;
diff --git a/src/tellicoui.rc b/src/tellicoui.rc
new file mode 100644
index 0000000..44e9691
--- /dev/null
+++ b/src/tellicoui.rc
@@ -0,0 +1,187 @@
+<?xml version = '1.0'?>
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui version="24" name="tellico">
+ <MenuBar>
+ <Menu name="file">
+ <text>&amp;File</text>
+ <Menu append="new_merge" name="file_new_collection" >
+ <text>&amp;New</text>
+ <Action name="new_book_collection"/>
+ <Action name="new_bibtex_collection"/>
+ <Action name="new_comic_book_collection"/>
+ <Action name="new_video_collection"/>
+ <Action name="new_music_collection"/>
+ <Action name="new_coin_collection"/>
+ <Action name="new_stamp_collection"/>
+ <Action name="new_card_collection"/>
+ <Action name="new_wine_collection"/>
+ <Action name="new_game_collection"/>
+ <Action name="new_boardgame_collection"/>
+ <Action name="new_file_catalog"/>
+ <Action name="new_custom_collection"/>
+ </Menu>
+ <Menu name="file_import">
+ <text>&amp;Import</text>
+ <Action name="file_import_tellico"/>
+ <Action name="file_import_csv"/>
+ <Separator/>
+ <Action name="file_import_alexandria"/>
+ <Action name="file_import_bibtex"/>
+ <Action name="file_import_bibtexml"/>
+ <Action name="file_import_delicious"/>
+ <Action name="file_import_mods"/>
+ <Action name="file_import_pdf"/>
+ <Action name="file_import_referencer"/>
+ <Action name="file_import_ris"/>
+ <Separator/>
+ <Action name="file_import_freedb"/>
+ <Action name="file_import_audiofile"/>
+ <Separator/>
+ <Action name="file_import_amc"/>
+ <Action name="file_import_gcfilms"/>
+ <Action name="file_import_griffith"/>
+ <Separator/>
+ <Action name="file_import_filelisting"/>
+ <Separator/>
+ <Action name="file_import_xslt"/>
+ </Menu>
+ <Menu name="file_export">
+ <text>&amp;Export</text>
+ <Action name="file_export_xml"/>
+ <Action name="file_export_zip"/>
+ <Action name="file_export_html"/>
+ <Action name="file_export_csv"/>
+ <Action name="file_export_pilotdb"/>
+ <Separator/>
+ <Action name="file_export_alexandria"/>
+ <Action name="file_export_bibtex"/>
+ <Action name="file_export_bibtexml"/>
+ <Action name="file_export_onix"/>
+ <Separator/>
+ <Action name="file_export_gcfilms"/>
+ <Separator/>
+ <Action name="file_export_xslt"/>
+ </Menu>
+ </Menu>
+ <Menu name="edit">
+ <Action name="edit_search_internet"/>
+ <Action name="filter_dialog"/>
+ </Menu>
+ <Menu name="collection">
+ <text>&amp;Collection</text>
+ <Action name="coll_new_entry"/>
+ <Action name="coll_edit_entry"/>
+ <Action name="coll_copy_entry"/>
+ <Action name="coll_delete_entry"/>
+ <Action name="coll_merge_entry"/>
+ <Menu name="coll_update_entry">
+ <text>&amp;Update Entry</text>
+ <Action name="update_entry_all"/>
+ <Separator/>
+ <ActionList name="update_entry_actions"/>
+ </Menu>
+ <Separator/>
+ <Action name="coll_checkout"/>
+ <Action name="coll_checkin"/>
+ <Separator/>
+ <Action name="coll_rename_collection"/>
+ <Action name="coll_fields"/>
+ <Action name="coll_reports"/>
+ <Separator/>
+ <Action name="coll_convert_bibliography"/>
+ <Action name="coll_string_macros"/>
+ <Action name="cite_clipboard"/>
+ <Action name="cite_lyxpipe"/>
+ <Action name="cite_openoffice"/>
+ </Menu>
+ <Menu name="settings">
+ <Action append="show_merge" name="toggle_collection_bar"/>
+ <Action append="show_merge" name="toggle_group_widget"/>
+ <Action append="show_merge" name="toggle_edit_widget"/>
+ <Action append="show_merge" name="toggle_entry_view"/>
+ <Action append="show_merge" name="change_entry_grouping"/>
+ </Menu>
+ <Menu name="help">
+ <Action name="tipOfDay"/>
+ </Menu>
+ </MenuBar>
+ <ToolBar noMerge="1" name="mainToolBar">
+ <text>Main Toolbar</text>
+ <Action name="file_new_collection"/>
+ <Action name="file_open"/>
+ <Action name="file_save"/>
+ <Action name="file_print"/>
+ <Separator/>
+ <Action name="edit_search_internet"/>
+ </ToolBar>
+ <ToolBar name="collectionToolBar">
+ <text>Collection Toolbar</text>
+ <Action name="coll_new_entry"/>
+ <Action name="coll_fields"/>
+ <Action name="coll_reports"/>
+ <Action name="change_entry_grouping"/>
+ <Separator lineSeparator="true"/>
+ <Action name="quick_filter_clear"/>
+ <Action name="quick_filter"/>
+ <Action name="filter_dialog"/>
+ </ToolBar>
+
+<State name="collection_reset">
+ <Disable>
+ <Action name="file_export_alexandria"/>
+ <Action name="file_export_onix"/>
+ <Action name="file_export_bibtex"/>
+ <Action name="file_export_bibtexml"/>
+ <Action name="file_export_gcfilms"/>
+ <Action name="file_export_amc"/>
+ <Action name="coll_convert_bibliography"/>
+ <Action name="coll_string_macros"/>
+ <Action name="cite_clipboard"/>
+ <Action name="cite_lyxpipe"/>
+ <Action name="cite_openoffice"/>
+ </Disable>
+</State>
+
+<State name="is_book">
+ <Enable>
+ <Action name="file_export_alexandria"/>
+ <Action name="file_export_onix"/>
+ <Action name="coll_convert_bibliography"/>
+ </Enable>
+</State>
+
+<State name="is_bibliography">
+ <Enable>
+ <Action name="file_export_alexandria"/>
+ <Action name="file_export_onix"/>
+ <Action name="file_export_bibtex"/>
+ <Action name="file_export_bibtexml"/>
+ <Action name="coll_string_macros"/>
+<!-- cite actions taken care in selection code
+ <Action name="cite_clipboard"/>
+ <Action name="cite_lyxpipe"/>
+ <Action name="cite_openoffice"/>
+ -->
+ </Enable>
+</State>
+
+<State name="is_video">
+ <Enable>
+ <Action name="file_export_gcfilms"/>
+ <Action name="file_export_amc"/>
+ </Enable>
+</State>
+
+<State name="empty_selection">
+ <Disable>
+ <Action name="coll_edit_entry"/>
+ <Action name="coll_copy_entry"/>
+ <Action name="coll_delete_entry"/>
+ <Action name="coll_update_entry"/>
+ <Menu name="coll_update_entry"/>
+ <Action name="update_entry_all"/>
+ <Action name="coll_checkout"/>
+ </Disable>
+</State>
+
+</kpartgui>
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
new file mode 100644
index 0000000..75c0313
--- /dev/null
+++ b/src/tests/Makefile.am
@@ -0,0 +1,28 @@
+AM_CPPFLAGS = -I$(srcdir)/.. $(all_includes)
+
+KDE_OPTIONS = noautodist
+
+AM_LDFLAGS = $(QT_LDFLAGS) $(KDE_LDFLAGS) $(X_LDFLAGS)
+
+check_PROGRAMS = isbntest latin1test entitytest
+
+check: isbntest latin1test entitytest
+ ./isbntest
+ ./latin1test
+ ./entitytest
+
+METASOURCES = AUTO
+
+DISTCLEANFILES = *~ *.Po $(CLEANFILES)
+
+isbntest_SOURCES = isbntest.cpp
+isbntest_LDADD = ../isbnvalidator.o $(LIB_QT) $(LIB_KDECORE) $(LIB_KDEUI)
+
+latin1test_SOURCES = latin1test.cpp
+latin1test_LDADD = $(LIB_QT) $(LIB_KDECORE)
+
+entitytest_SOURCES = entitytest.cpp
+entitytest_LDADD = ../tellico_utils.o $(LIB_QT) $(LIB_KDECORE)
+
+#formattest_SOURCES = formattest.cpp
+#formattest_LDADD = ../core/tellico_config.o ../core/tellico_config_addons.o ../field.o ../tellico_utils.o $(LIB_QT) $(LIB_KDECORE)
diff --git a/src/tests/entitytest.cpp b/src/tests/entitytest.cpp
new file mode 100644
index 0000000..215c377
--- /dev/null
+++ b/src/tests/entitytest.cpp
@@ -0,0 +1,19 @@
+#ifdef QT_NO_CAST_ASCII
+#undef QT_NO_CAST_ASCII
+#endif
+
+#include "tellico_utils.h"
+#include <kdebug.h>
+#include <assert.h>
+
+int main(int, char**) {
+ kdDebug() << "\n*****************************************************" << endl;
+
+ assert(Tellico::decodeHTML("robby") == "robby");
+ assert(Tellico::decodeHTML("&fake;") == "&fake;");
+ assert(Tellico::decodeHTML("&#48;") == "0");
+ assert(Tellico::decodeHTML("robby&#48;robby") == "robby0robby");
+
+ kdDebug() << "\ndecodeHTML Test OK !" << endl;
+ kdDebug() << "\n*****************************************************" << endl;
+}
diff --git a/src/tests/isbntest.cpp b/src/tests/isbntest.cpp
new file mode 100644
index 0000000..b4c5fee
--- /dev/null
+++ b/src/tests/isbntest.cpp
@@ -0,0 +1,73 @@
+#ifdef QT_NO_CAST_ASCII
+#undef QT_NO_CAST_ASCII
+#endif
+
+#include "isbnvalidator.h"
+
+#include <kdebug.h>
+
+#include <stdlib.h>
+
+bool check(QString a, QString b) {
+ static const Tellico::ISBNValidator val(0);
+ val.fixup(a);
+ if(a == b) {
+ kdDebug() << "checking '" << a << "' against expected value '" << b << "'... " << "ok" << endl;
+ } else {
+ kdDebug() << "checking '" << a << "' against expected value '" << b << "'... " << "KO!" << endl;
+ exit(1);
+ }
+ return true;
+}
+
+int main(int, char**) {
+ kdDebug() << "\n*****************************************************" << endl;
+
+ // initial checks
+ check("0-446-60098-9", "0-446-60098-9");
+ // check sum value
+ check("0-446-60098", "0-446-60098-9");
+
+ check(Tellico::ISBNValidator::isbn10("978-0-06-087298-4"), "0-06-087298-5");
+ check(Tellico::ISBNValidator::isbn13("0-06-087298-5"), "978-0-06-087298-4");
+
+ // check EAN-13
+ check("9780940016750", "978-0-940016-75-0");
+ check("978-0940016750", "978-0-940016-75-0");
+ check("978-0-940016-75-0", "978-0-940016-75-0");
+ check("978286274486", "978-2-86274-486-5");
+ check("9788186119130", "978-81-86-11913-6");
+ check("9788186119137", "978-81-86-11913-6");
+ check("97881-8611-9-13-0", "978-81-86-11913-6");
+ check("97881-8611-9-13-7", "978-81-86-11913-6");
+
+ // don't add checksum for EAN that start with 978 or 979 and are less than 13 in length
+ check("978059600", "978-059600");
+ check("978-0596000", "978-059600-0");
+
+ // normal english-language hyphenation
+ check("0-596-00053", "0-596-00053-7");
+ check("044660098", "0-446-60098-9");
+ check("0446600989", "0-446-60098-9");
+
+ // check french hyphenation
+ check("2862744867", "2-86274-486-7");
+
+ // check german hyphenation
+ check("3423071516", "3-423-07151-6");
+
+ // check dutch hyphenation
+ check("9065442979", "90-6544-297-9");
+
+ // check keeping middle hyphens
+ check("6-18611913-0", "6-18611913-0");
+ check("6-186119-13-0", "6-186119-13-0");
+ check("6-18611-9-13-0", "6-18611-913-0");
+
+ // check garbage
+ check("My name is robby", "");
+ check("http://www.abclinuxu.cz/clanky/show/63080", "6-3080");
+
+ kdDebug() << "\n ISBN Validator Test OK !" << endl;
+ kdDebug() << "\n*****************************************************" << endl;
+}
diff --git a/src/tests/latin1test.cpp b/src/tests/latin1test.cpp
new file mode 100644
index 0000000..636c33f
--- /dev/null
+++ b/src/tests/latin1test.cpp
@@ -0,0 +1,25 @@
+#ifdef QT_NO_CAST_ASCII
+#undef QT_NO_CAST_ASCII
+#endif
+
+#include "latin1literal.h"
+#include <qstring.h>
+#include <kdebug.h>
+#include <assert.h>
+
+int main(int, char**) {
+ kdDebug() << "\n*****************************************************" << endl;
+
+ assert(QString::null == Latin1Literal(0));
+ assert(QString::null != Latin1Literal(""));
+ assert(QString::fromLatin1("") == Latin1Literal(""));
+ assert(QString::fromLatin1("") != Latin1Literal(0));
+ assert(QString::fromLatin1("x") != Latin1Literal(""));
+ assert(QString::fromLatin1("a") == Latin1Literal("a"));
+ assert(QString::fromLatin1("a") != Latin1Literal("b"));
+ assert(QString::fromLatin1("\xe4") == Latin1Literal("\xe4"));
+ assert(QString::fromUtf8("\xe2\x82\xac") != Latin1Literal("?"));
+
+ kdDebug() << "\nLatin1Literal Test OK !" << endl;
+ kdDebug() << "\n*****************************************************" << endl;
+}
diff --git a/src/translators/Makefile.am b/src/translators/Makefile.am
new file mode 100644
index 0000000..68ee4cc
--- /dev/null
+++ b/src/translators/Makefile.am
@@ -0,0 +1,70 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+noinst_LIBRARIES = libtranslators.a
+
+## AM_CPPFLAGS were found outside kdevelop specific part
+
+libtranslators_a_METASOURCES = AUTO
+
+libtranslators_a_SOURCES = alexandriaexporter.cpp alexandriaimporter.cpp \
+ amcimporter.cpp audiofileimporter.cpp bibtexexporter.cpp bibtexhandler.cpp \
+ bibteximporter.cpp bibtexmlexporter.cpp bibtexmlimporter.cpp csvexporter.cpp \
+ csvimporter.cpp dcimporter.cpp deliciousimporter.cpp exporter.cpp \
+ filelistingimporter.cpp freedb_util.cpp freedbimporter.cpp gcfilmsexporter.cpp \
+ gcfilmsimporter.cpp griffithimporter.cpp grs1importer.cpp htmlexporter.cpp libcsv.c \
+ onixexporter.cpp pdfimporter.cpp pilotdbexporter.cpp referencerimporter.cpp \
+ risimporter.cpp tellico_xml.cpp tellicoimporter.cpp tellicoxmlexporter.cpp \
+ tellicozipexporter.cpp textimporter.cpp xmlimporter.cpp xsltexporter.cpp xslthandler.cpp \
+ xsltimporter.cpp
+
+if !USE_LIBBTPARSE
+ SUBDIR_LIBBTPARSE = btparse
+endif
+
+SUBDIRS = pilotdb $(SUBDIR_LIBBTPARSE)
+
+CLEANFILES = *~
+
+EXTRA_DIST = bibtex-translation.xml \
+bibtexexporter.cpp tellicoxmlexporter.h pilotdbexporter.cpp \
+bibtexexporter.h tellicozipexporter.cpp pilotdbexporter.h \
+bibtexhandler.cpp tellicozipexporter.h \
+bibtexhandler.h csvexporter.cpp textimporter.cpp \
+bibteximporter.cpp csvexporter.h textimporter.h \
+bibteximporter.h csvimporter.cpp xmlimporter.cpp \
+bibtexmlexporter.cpp csvimporter.h xmlimporter.h \
+bibtexmlexporter.h xsltexporter.cpp \
+bibtexmlimporter.cpp dataimporter.h xsltexporter.h \
+bibtexmlimporter.h exporter.h xslthandler.cpp \
+tellicoimporter.cpp htmlexporter.cpp xslthandler.h \
+tellicoimporter.h htmlexporter.h xsltimporter.cpp \
+tellicoxmlexporter.cpp importer.h xsltimporter.h \
+audiofileimporter.h audiofileimporter.cpp alexandriaimporter.h \
+alexandriaimporter.cpp alexandriaexporter.h alexandriaexporter.cpp \
+freedbimporter.h freedbimporter.cpp freedb_util.cpp \
+risimporter.h risimporter.cpp tellico_xml.h \
+tellico_xml.cpp translators.h exporter.cpp \
+onixexporter.h onixexporter.cpp gcfilmsimporter.h \
+gcfilmsimporter.cpp gcfilmsexporter.h gcfilmsexporter.cpp \
+filelistingimporter.h filelistingimporter.cpp grs1importer.h \
+grs1importer.cpp amcimporter.h amcimporter.cpp \
+dcimporter.h dcimporter.cpp griffithimporter.h \
+griffithimporter.cpp griffith2tellico.py pdfimporter.h \
+pdfimporter.cpp referencerimporter.h referencerimporter.cpp \
+libcsv.h libcsv.c \
+deliciousimporter.h deliciousimporter.cpp
+
+####### kdevelop will overwrite this part!!! (end)############
+
+AM_CPPFLAGS = \
+ $(LIBXML_CFLAGS) \
+ $(LIBXSLT_CFLAGS) \
+ $(TAGLIB_CFLAGS) \
+ $(KCDDB_CFLAGS) \
+ $(all_includes) \
+ $(POPPLER_CFLAGS)
+
+KDE_OPTIONS = noautodist
+
+appdir = $(kde_datadir)/tellico
+app_DATA = bibtex-translation.xml
+app_SCRIPTS = griffith2tellico.py
diff --git a/src/translators/alexandriaexporter.cpp b/src/translators/alexandriaexporter.cpp
new file mode 100644
index 0000000..186b866
--- /dev/null
+++ b/src/translators/alexandriaexporter.cpp
@@ -0,0 +1,183 @@
+/***************************************************************************
+ copyright : (C) 2003-2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "alexandriaexporter.h"
+#include "../document.h"
+#include "../collection.h"
+#include "../tellico_kernel.h"
+#include "../imagefactory.h"
+#include "../image.h"
+#include "../tellico_utils.h"
+#include "../tellico_debug.h"
+#include "../progressmanager.h"
+
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kapplication.h>
+
+#include <qdir.h>
+
+namespace {
+ static const int ALEXANDRIA_MAX_SIZE_SMALL = 60;
+ static const int ALEXANDRIA_MAX_SIZE_MEDIUM = 140;
+}
+
+using Tellico::Export::AlexandriaExporter;
+
+QString& AlexandriaExporter::escapeText(QString& str_) {
+ str_.replace('"', QString::fromLatin1("\\\""));
+ return str_;
+}
+
+QString AlexandriaExporter::formatString() const {
+ return i18n("Alexandria");
+}
+
+bool AlexandriaExporter::exec() {
+ Data::CollPtr coll = collection();
+ if(!coll || (coll->type() != Data::Collection::Book && coll->type() != Data::Collection::Bibtex)) {
+ myLog() << "AlexandriaExporter::exec() - bad collection" << endl;
+ return false;
+ }
+
+ const QString alexDirName = QString::fromLatin1(".alexandria");
+
+ // create if necessary
+ QDir libraryDir = QDir::home();
+ if(!libraryDir.cd(alexDirName)) {
+ if(!libraryDir.mkdir(alexDirName) || !libraryDir.cd(alexDirName)) {
+ myLog() << "AlexandriaExporter::exec() - can't locate directory" << endl;
+ return false;
+ }
+ }
+
+ // the collection title is the name of the directory to create
+ if(libraryDir.cd(coll->title())) {
+ int ret = KMessageBox::warningContinueCancel(Kernel::self()->widget(),
+ i18n("<qt>An Alexandria library called <i>%1</i> already exists. "
+ "Any existing books in that library could be overwritten.</qt>")
+ .arg(coll->title()));
+ if(ret == KMessageBox::Cancel) {
+ return false;
+ }
+ } else if(!libraryDir.mkdir(coll->title()) || !libraryDir.cd(coll->title())) {
+ return false; // could not create and cd to the dir
+ }
+
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, QString::null, false);
+ item.setTotalSteps(entries().count());
+ ProgressItem::Done done(this);
+ const uint stepSize = QMIN(1, entries().count()/100);
+ const bool showProgress = options() & ExportProgress;
+
+ GUI::CursorSaver cs;
+ bool success = true;
+ uint j = 0;
+ for(Data::EntryVec::ConstIterator entryIt = entries().begin(); entryIt != entries().end(); ++entryIt, ++j) {
+ success &= writeFile(libraryDir, entryIt.data());
+ if(showProgress && j%stepSize == 0) {
+ item.setProgress(j);
+ kapp->processEvents();
+ }
+ }
+ return success;
+}
+
+// this isn't true YAML export, of course
+// everything is put between quotes except for the rating, just to be sure it's interpreted as a string
+bool AlexandriaExporter::writeFile(const QDir& dir_, Data::ConstEntryPtr entry_) {
+ // the filename is the isbn without dashes, followed by .yaml
+ QString isbn = entry_->field(QString::fromLatin1("isbn"));
+ if(isbn.isEmpty()) {
+ return false; // can't write it since Alexandria uses isbn as name of file
+ }
+ isbn.remove('-'); // remove dashes
+
+ QFile file(dir_.absPath() + QDir::separator() + isbn + QString::fromLatin1(".yaml"));
+ if(!file.open(IO_WriteOnly)) {
+ return false;
+ }
+
+ // do we format?
+ bool format = options() & Export::ExportFormatted;
+
+ QTextStream ts(&file);
+ // alexandria uses utf-8 all the time
+ ts.setEncoding(QTextStream::UnicodeUTF8);
+ ts << "--- !ruby/object:Alexandria::Book\n";
+ ts << "authors:\n";
+ QStringList authors = entry_->fields(QString::fromLatin1("author"), format);
+ for(QStringList::Iterator it = authors.begin(); it != authors.end(); ++it) {
+ ts << " - " << escapeText(*it) << "\n";
+ }
+ // Alexandria crashes when no authors, and uses n/a when none
+ if(authors.count() == 0) {
+ ts << " - n/a\n";
+ }
+
+ QString tmp = entry_->field(QString::fromLatin1("title"), format);
+ ts << "title: \"" << escapeText(tmp) << "\"\n";
+
+ // Alexandria refers to the binding as the edition
+ tmp = entry_->field(QString::fromLatin1("binding"), format);
+ ts << "edition: \"" << escapeText(tmp) << "\"\n";
+
+ // sometimes Alexandria interprets the isbn as a number instead of a string
+ // I have no idea how to debug ruby, so err on safe side and add quotes
+ ts << "isbn: \"" << isbn << "\"\n";
+
+ tmp = entry_->field(QString::fromLatin1("comments"), format);
+ ts << "notes: \"" << escapeText(tmp) << "\"\n";
+
+ tmp = entry_->field(QString::fromLatin1("publisher"), format);
+ // publisher uses n/a when empty
+ ts << "publisher: \"" << (tmp.isEmpty() ? QString::fromLatin1("n/a") : escapeText(tmp)) << "\"\n";
+
+ tmp = entry_->field(QString::fromLatin1("pub_year"), format);
+ if(!tmp.isEmpty()) {
+ ts << "publishing_year: \"" << escapeText(tmp) << "\"\n";
+ }
+
+ tmp = entry_->field(QString::fromLatin1("rating"));
+ bool ok;
+ int rating = Tellico::toUInt(tmp, &ok);
+ if(ok) {
+ ts << "rating: " << rating << "\n";
+ }
+
+ file.close();
+
+ QString cover = entry_->field(QString::fromLatin1("cover"));
+ if(cover.isEmpty() || !(options() & Export::ExportImages)) {
+ return true; // all done
+ }
+
+ QImage img1(ImageFactory::imageById(cover));
+ QImage img2;
+ QString filename = dir_.absPath() + QDir::separator() + isbn;
+ if(img1.height() > ALEXANDRIA_MAX_SIZE_SMALL) {
+ if(img1.height() > ALEXANDRIA_MAX_SIZE_MEDIUM) { // limit maximum size
+ img1 = img1.scale(ALEXANDRIA_MAX_SIZE_MEDIUM, ALEXANDRIA_MAX_SIZE_MEDIUM, QImage::ScaleMin);
+ }
+ img2 = img1.scale(ALEXANDRIA_MAX_SIZE_SMALL, ALEXANDRIA_MAX_SIZE_SMALL, QImage::ScaleMin);
+ } else {
+ img2 = img1.smoothScale(ALEXANDRIA_MAX_SIZE_MEDIUM, ALEXANDRIA_MAX_SIZE_MEDIUM, QImage::ScaleMin); // scale up
+ }
+ if(!img1.save(filename + QString::fromLatin1("_medium.jpg"), "JPEG")
+ || !img2.save(filename + QString::fromLatin1("_small.jpg"), "JPEG")) {
+ return false;
+ }
+ return true;
+}
+
+#include "alexandriaexporter.moc"
diff --git a/src/translators/alexandriaexporter.h b/src/translators/alexandriaexporter.h
new file mode 100644
index 0000000..033bb14
--- /dev/null
+++ b/src/translators/alexandriaexporter.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef ALEXANDRIAEXPORTER_H
+#define ALEXANDRIAEXPORTER_H
+
+class QDir;
+
+#include "exporter.h"
+
+namespace Tellico {
+ namespace Data {
+ class Entry;
+ }
+ namespace Export {
+
+/**
+ * @author Robby Stephenson
+ */
+class AlexandriaExporter : public Exporter {
+Q_OBJECT
+
+public:
+ AlexandriaExporter() : Exporter() {}
+
+ virtual bool exec();
+ virtual QString formatString() const;
+ virtual QString fileFilter() const { return QString::null; } // no need for this
+
+ // no config options
+ virtual QWidget* widget(QWidget*, const char*) { return 0; }
+
+private:
+ static QString& escapeText(QString& str);
+
+ bool writeFile(const QDir& dir, Data::ConstEntryPtr entry);
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/alexandriaimporter.cpp b/src/translators/alexandriaimporter.cpp
new file mode 100644
index 0000000..5e49e86
--- /dev/null
+++ b/src/translators/alexandriaimporter.cpp
@@ -0,0 +1,255 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "alexandriaimporter.h"
+#include "../collections/bookcollection.h"
+#include "../entry.h"
+#include "../field.h"
+#include "../latin1literal.h"
+#include "../isbnvalidator.h"
+#include "../imagefactory.h"
+#include "../progressmanager.h"
+#include "../tellico_debug.h"
+
+#include <kcombobox.h>
+#include <kapplication.h>
+#include <kstringhandler.h>
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qgroupbox.h>
+
+using Tellico::Import::AlexandriaImporter;
+
+bool AlexandriaImporter::canImport(int type) const {
+ return type == Data::Collection::Book;
+}
+
+Tellico::Data::CollPtr AlexandriaImporter::collection() {
+ if(!m_widget || m_library->count() == 0) {
+ return 0;
+ }
+
+ m_coll = new Data::BookCollection(true);
+
+ QDir dataDir = m_libraryDir;
+ dataDir.cd(m_library->currentText());
+ dataDir.setFilter(QDir::Files | QDir::Readable | QDir::NoSymLinks);
+
+ const QString title = QString::fromLatin1("title");
+ const QString author = QString::fromLatin1("author");
+ const QString year = QString::fromLatin1("pub_year");
+ const QString binding = QString::fromLatin1("binding");
+ const QString isbn = QString::fromLatin1("isbn");
+ const QString pub = QString::fromLatin1("publisher");
+ const QString rating = QString::fromLatin1("rating");
+ const QString cover = QString::fromLatin1("cover");
+ const QString comments = QString::fromLatin1("comments");
+
+ // start with yaml files
+ dataDir.setNameFilter(QString::fromLatin1("*.yaml"));
+ const QStringList files = dataDir.entryList();
+ const uint numFiles = files.count();
+ const uint stepSize = QMAX(s_stepSize, numFiles/100);
+ const bool showProgress = options() & ImportProgress;
+
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, progressLabel(), true);
+ item.setTotalSteps(numFiles);
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+ ProgressItem::Done done(this);
+
+ QStringList covers;
+ covers << QString::fromLatin1(".cover")
+ << QString::fromLatin1("_medium.jpg")
+ << QString::fromLatin1("_small.jpg");
+
+ QTextStream ts;
+ ts.setEncoding(QTextStream::UnicodeUTF8); // YAML is always utf8?
+ uint j = 0;
+ for(QStringList::ConstIterator it = files.begin(); !m_cancelled && it != files.end(); ++it, ++j) {
+ QFile file(dataDir.absFilePath(*it));
+ if(!file.open(IO_ReadOnly)) {
+ continue;
+ }
+
+ Data::EntryPtr entry = new Data::Entry(m_coll);
+
+ bool readNextLine = true;
+ ts.unsetDevice();
+ ts.setDevice(&file);
+ QString line;
+ while(!ts.atEnd()) {
+ if(readNextLine) {
+ line = ts.readLine();
+ } else {
+ readNextLine = true;
+ }
+ // skip the line that starts with ---
+ if(line.isEmpty() || line.startsWith(QString::fromLatin1("---"))) {
+ continue;
+ }
+ if(line.endsWith(QChar('\\'))) {
+ line.truncate(line.length()-1); // remove last character
+ line += ts.readLine();
+ }
+
+ cleanLine(line);
+ QString alexField = line.section(':', 0, 0);
+ QString alexValue = line.section(':', 1).stripWhiteSpace();
+ clean(alexValue);
+
+ // Alexandria uses "n/a for empty values, and it is translated
+ // only thing we can do is check for english value and continue
+ if(alexValue == Latin1Literal("n/a")) {
+ continue;
+ }
+
+ if(alexField == Latin1Literal("authors")) {
+ QStringList authors;
+ line = ts.readLine();
+ QRegExp begin(QString::fromLatin1("^\\s*-\\s+"));
+ while(!line.isNull() && line.find(begin) > -1) {
+ line.remove(begin);
+ authors += clean(line);
+ line = ts.readLine();
+ }
+ entry->setField(author, authors.join(QString::fromLatin1("; ")));
+ // the next line has already been read
+ readNextLine = false;
+
+ // Alexandria calls the edition the binding
+ } else if(alexField == Latin1Literal("edition")) {
+ // special case if it's "Hardcover"
+ if(alexValue.lower() == Latin1Literal("hardcover")) {
+ alexValue = i18n("Hardback");
+ }
+ entry->setField(binding, alexValue);
+
+ } else if(alexField == Latin1Literal("publishing_year")) {
+ entry->setField(year, alexValue);
+
+ } else if(alexField == Latin1Literal("isbn")) {
+ const ISBNValidator val(0);
+ val.fixup(alexValue);
+ entry->setField(isbn, alexValue);
+
+ // now find cover image
+ KURL u;
+ alexValue.remove('-');
+ for(QStringList::Iterator ext = covers.begin(); ext != covers.end(); ++ext) {
+ u.setPath(dataDir.absFilePath(alexValue + *ext));
+ if(!QFile::exists(u.path())) {
+ continue;
+ }
+ QString id = ImageFactory::addImage(u, true);
+ if(!id.isEmpty()) {
+ entry->setField(cover, id);
+ break;
+ }
+ }
+ } else if(alexField == Latin1Literal("notes")) {
+ entry->setField(comments, alexValue);
+
+ // now try by name then title
+ } else if(m_coll->fieldByName(alexField)) {
+ entry->setField(alexField, alexValue);
+
+ } else if(m_coll->fieldByTitle(alexField)) {
+ entry->setField(m_coll->fieldByTitle(alexField), alexValue);
+ }
+ }
+ m_coll->addEntries(entry);
+
+ if(showProgress && j%stepSize == 0) {
+ ProgressManager::self()->setProgress(this, j);
+ kapp->processEvents();
+ }
+ }
+
+ return m_coll;
+}
+
+QWidget* AlexandriaImporter::widget(QWidget* parent_, const char* name_/*=0*/) {
+ if(m_widget) {
+ return m_widget;
+ }
+
+ m_libraryDir = QDir::home();
+ m_libraryDir.setFilter(QDir::Dirs | QDir::Readable | QDir::NoSymLinks);
+
+ m_widget = new QWidget(parent_, name_);
+ QVBoxLayout* l = new QVBoxLayout(m_widget);
+
+ QGroupBox* box = new QGroupBox(2, Qt::Horizontal, i18n("Alexandria Options"), m_widget);
+ QLabel* label = new QLabel(i18n("&Library:"), box);
+ m_library = new KComboBox(box);
+ label->setBuddy(m_library);
+
+ // .alexandria might not exist
+ if(m_libraryDir.cd(QString::fromLatin1(".alexandria"))) {
+ QStringList dirs = m_libraryDir.entryList();
+ dirs.remove(QString::fromLatin1(".")); // why can't I tell QDir not to include these? QDir::Hidden doesn't work
+ dirs.remove(QString::fromLatin1(".."));
+ m_library->insertStringList(dirs);
+ }
+
+ l->addWidget(box);
+ l->addStretch(1);
+ return m_widget;
+}
+
+QString& AlexandriaImporter::cleanLine(QString& str_) {
+ static QRegExp escRx(QString::fromLatin1("\\\\x(\\w\\w)"), false);
+ str_.remove(QString::fromLatin1("\\r"));
+ str_.replace(QString::fromLatin1("\\n"), QString::fromLatin1("\n"));
+ str_.replace(QString::fromLatin1("\\t"), QString::fromLatin1("\t"));
+
+ // YAML uses escape sequences like \xC3
+ int pos = escRx.search(str_);
+ int origPos = pos;
+ QCString bytes;
+ while(pos > -1) {
+ bool ok;
+ char c = escRx.cap(1).toInt(&ok, 16);
+ if(ok) {
+ bytes += c;
+ } else {
+ bytes = QCString();
+ break;
+ }
+ pos = escRx.search(str_, pos+1);
+ }
+ if(!bytes.isEmpty()) {
+ str_.replace(origPos, bytes.length()*4, QString::fromUtf8(bytes.data()));
+ }
+ return str_;
+}
+
+QString& AlexandriaImporter::clean(QString& str_) {
+ const QRegExp quote(QString::fromLatin1("\\\\\"")); // equals \"
+ if(str_.startsWith(QChar('\'')) || str_.startsWith(QChar('"'))) {
+ str_.remove(0, 1);
+ }
+ if(str_.endsWith(QChar('\'')) || str_.endsWith(QChar('"'))) {
+ str_.truncate(str_.length()-1);
+ }
+ // we ignore YAML tags, this is not actually a good parser, but will do for now
+ str_.remove(QRegExp(QString::fromLatin1("^![^\\s]*\\s+")));
+ return str_.replace(quote, QChar('"'));
+}
+
+void AlexandriaImporter::slotCancel() {
+ m_cancelled = true;
+}
+
+#include "alexandriaimporter.moc"
diff --git a/src/translators/alexandriaimporter.h b/src/translators/alexandriaimporter.h
new file mode 100644
index 0000000..2c12923
--- /dev/null
+++ b/src/translators/alexandriaimporter.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef ALEXANDRIAIMPORTER_H
+#define ALEXANDRIAIMPORTER_H
+
+class KComboBox;
+
+#include "importer.h"
+#include "../datavectors.h"
+
+#include <qdir.h>
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ * An importer for importing collections used by Alexandria, the Gnome book collection manager.
+ *
+ * The libraries are assumed to be in $HOME/.alexandria. The file format is YAML, but instead
+ * using a real YAML reader, the file is parsed line-by-line, so it's very crude. When Alexandria
+ * adds new fields or types, this will have to be updated.
+ *
+ * @author Robby Stephenson
+ */
+class AlexandriaImporter : public Importer {
+Q_OBJECT
+
+public:
+ /**
+ */
+ AlexandriaImporter() : Importer(), m_coll(0), m_widget(0), m_cancelled(false) {}
+ /**
+ */
+ virtual ~AlexandriaImporter() {}
+
+ /**
+ */
+ virtual Data::CollPtr collection();
+ /**
+ */
+ virtual QWidget* widget(QWidget* parent, const char* name=0);
+ virtual bool canImport(int type) const;
+
+public slots:
+ void slotCancel();
+
+private:
+ static QString& cleanLine(QString& str);
+ static QString& clean(QString& str);
+
+ Data::CollPtr m_coll;
+ QWidget* m_widget;
+ KComboBox* m_library;
+
+ QDir m_libraryDir;
+ bool m_cancelled : 1;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/amcimporter.cpp b/src/translators/amcimporter.cpp
new file mode 100644
index 0000000..8e45cb7
--- /dev/null
+++ b/src/translators/amcimporter.cpp
@@ -0,0 +1,294 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+// The information about the AMC file format was taken from the source code for
+// GCfilms, (GPL) (c) 2005 Tian
+// Monotheka, (GPL) (c) 2004, 2005 Michael Dominic K.
+// 2005 Aurelien Mino
+
+#include "amcimporter.h"
+#include "../collections/videocollection.h"
+#include "../imagefactory.h"
+#include "../latin1literal.h"
+#include "../progressmanager.h"
+#include "../tellico_debug.h"
+
+#include <kapplication.h>
+
+#include <qfile.h>
+#include <qimage.h>
+
+#include <limits.h>
+
+namespace {
+ static const QCString AMC_FILE_ID = " AMC_X.Y Ant Movie Catalog 3.5.x www.buypin.com www.antp.be ";
+}
+
+using Tellico::Import::AMCImporter;
+
+AMCImporter::AMCImporter(const KURL& url_) : DataImporter(url_), m_coll(0), m_cancelled(false) {
+}
+
+AMCImporter::~AMCImporter() {
+}
+
+bool AMCImporter::canImport(int type) const {
+ return type == Data::Collection::Video;
+}
+
+Tellico::Data::CollPtr AMCImporter::collection() {
+ if(m_coll) {
+ return m_coll;
+ }
+
+ if(!fileRef().open()) {
+ return 0;
+ }
+
+ QIODevice* f = fileRef().file();
+ m_ds.setDevice(f);
+ // AMC is always little-endian? can't confirm
+ m_ds.setByteOrder(QDataStream::LittleEndian);
+
+ const uint l = AMC_FILE_ID.length();
+ QMemArray<char> buffer(l+1);
+ m_ds.readRawBytes(buffer.data(), l);
+ QString version = QString::fromLocal8Bit(buffer, l);
+ QRegExp versionRx(QString::fromLatin1(".+AMC_(\\d+)\\.(\\d+).+"));
+ if(version.find(versionRx) == -1) {
+ myDebug() << "AMCImporter::collection() - no file id match" << endl;
+ return 0;
+ }
+
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, progressLabel(), true);
+ item.setTotalSteps(f->size());
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+ ProgressItem::Done done(this);
+
+ m_coll = new Data::VideoCollection(true);
+
+ m_majVersion = versionRx.cap(1).toInt();
+ m_minVersion = versionRx.cap(2).toInt();
+// myDebug() << m_majVersion << "::" << m_minVersion << endl;
+
+ readString(); // name
+ readString(); // email
+ if(m_majVersion <= 3 && m_minVersion < 5) {
+ readString(); // icq
+ }
+ readString(); // webpage
+ readString(); // description
+
+ const bool showProgress = options() & ImportProgress;
+
+ while(!m_cancelled && !f->atEnd()) {
+ readEntry();
+ if(showProgress) {
+ ProgressManager::self()->setProgress(this, f->at());
+ kapp->processEvents();
+ }
+ }
+
+ return m_coll;
+}
+
+bool AMCImporter::readBool() {
+ Q_UINT8 b;
+ m_ds >> b;
+ return b;
+}
+
+Q_UINT32 AMCImporter::readInt() {
+ Q_UINT32 i;
+ m_ds >> i;
+ if(i >= UINT_MAX) {
+ i = 0;
+ }
+ return i;
+}
+
+QString AMCImporter::readString() {
+ // The serialization format is a length specifier first, then l bytes of data
+ uint l = readInt();
+ if(l == 0) {
+ return QString();
+ }
+ QMemArray<char> buffer(l+1);
+ m_ds.readRawBytes(buffer.data(), l);
+ QString s = QString::fromLocal8Bit(buffer, l);
+// myDebug() << "string: " << s << endl;
+ return s;
+}
+
+QString AMCImporter::readImage(const QString& format_) {
+ uint l = readInt();
+ if(l == 0) {
+ return QString();
+ }
+ QMemArray<char> buffer(l+1);
+ m_ds.readRawBytes(buffer.data(), l);
+ QByteArray bytes;
+ bytes.setRawData(buffer.data(), l);
+ QImage img(bytes);
+ bytes.resetRawData(buffer.data(), l);
+ if(img.isNull()) {
+ myDebug() << "AMCImporter::readImage() - null image" << endl;
+ return QString();
+ }
+ QString format = QString::fromLatin1("PNG");
+ if(format_ == Latin1Literal(".jpg")) {
+ format = QString::fromLatin1("JPEG");
+ } else if(format_ == Latin1Literal(".gif")) {
+ format = QString::fromLatin1("GIF");
+ }
+ return ImageFactory::addImage(img, format);
+}
+
+void AMCImporter::readEntry() {
+ Data::EntryPtr e = new Data::Entry(m_coll);
+
+ int id = readInt();
+ if(id > 0) {
+ e->setId(id);
+ }
+ readInt(); // add date
+
+ int rating = readInt();
+ if(m_majVersion >= 3 && m_minVersion >= 5) {
+ rating /= 10;
+ }
+ e->setField(QString::fromLatin1("rating"), QString::number(rating));
+ int year = readInt();
+ if(year > 0) {
+ e->setField(QString::fromLatin1("year"), QString::number(year));
+ }
+ int time = readInt();
+ if(time > 0) {
+ e->setField(QString::fromLatin1("running-time"), QString::number(time));
+ }
+
+ readInt(); // video bitrate
+ readInt(); // audio bitrate
+ readInt(); // number of files
+ readBool(); // checked
+ readString(); // media label
+ e->setField(QString::fromLatin1("medium"), readString());
+ readString(); // source
+ readString(); // borrower
+ QString s = readString(); // title
+ if(!s.isEmpty()) {
+ e->setField(QString::fromLatin1("title"), s);
+ }
+ QString s2 = readString(); // translated title
+ if(s.isEmpty()) {
+ e->setField(QString::fromLatin1("title"), s2);
+ }
+
+ e->setField(QString::fromLatin1("director"), readString());
+ s = readString();
+ QRegExp roleRx(QString::fromLatin1("(.+) \\(([^(]+)\\)"));
+ roleRx.setMinimal(true);
+ if(s.find(roleRx) > -1) {
+ QString role = roleRx.cap(2).lower();
+ if(role == Latin1Literal("story") || role == Latin1Literal("written by")) {
+ e->setField(QString::fromLatin1("writer"), roleRx.cap(1));
+ } else {
+ e->setField(QString::fromLatin1("producer"), s);
+ }
+ } else {
+ e->setField(QString::fromLatin1("producer"), s);
+ }
+ e->setField(QString::fromLatin1("nationality"), readString());
+ e->setField(QString::fromLatin1("genre"), readString().replace(QString::fromLatin1(", "), QString::fromLatin1("; ")));
+
+ e->setField(QString::fromLatin1("cast"), parseCast(readString()).join(QString::fromLatin1("; ")));
+
+ readString(); // url
+ e->setField(QString::fromLatin1("plot"), readString());
+ e->setField(QString::fromLatin1("comments"), readString());
+ s = readString(); // video format
+ QRegExp regionRx(QString::fromLatin1("Region \\d"));
+ if(s.find(regionRx) > -1) {
+ e->setField(QString::fromLatin1("region"), regionRx.cap(0));
+ }
+ e->setField(QString::fromLatin1("audio-track"), readString()); // audio format
+ readString(); // resolution
+ readString(); // frame rate
+ e->setField(QString::fromLatin1("language"), readString()); // audio language
+ e->setField(QString::fromLatin1("subtitle"), readString()); // subtitle
+ readString(); // file size
+ s = readString(); // picture extension
+ s = readImage(s); // picture
+ if(!s.isEmpty()) {
+ e->setField(QString::fromLatin1("cover"), s);
+ }
+
+ m_coll->addEntries(e);
+}
+
+QStringList AMCImporter::parseCast(const QString& text_) {
+ QStringList cast;
+ int nPar = 0;
+ QRegExp castRx(QString::fromLatin1("[,()]"));
+ QString person, role;
+ int oldPos = 0;
+ for(int pos = text_.find(castRx); pos > -1; pos = text_.find(castRx, pos+1)) {
+ if(text_.at(pos) == ',' && nPar%2 == 0) {
+ // we're done with this one
+ person += text_.mid(oldPos, pos-oldPos).stripWhiteSpace();
+ QString all = person;
+ if(!role.isEmpty()) {
+ if(role.startsWith(QString::fromLatin1("as "))) {
+ role = role.mid(3);
+ }
+ all += "::" + role;
+ }
+ cast << all;
+ person.truncate(0);
+ role.truncate(0);
+ oldPos = pos+1; // add one to go past comma
+ } else if(text_.at(pos) == '(') {
+ if(nPar == 0) {
+ person = text_.mid(oldPos, pos-oldPos).stripWhiteSpace();
+ oldPos = pos+1; // add one to go past parenthesis
+ }
+ ++nPar;
+ } else if(text_.at(pos) == ')') {
+ --nPar;
+ if(nPar == 0) {
+ role = text_.mid(oldPos, pos-oldPos).stripWhiteSpace();
+ oldPos = pos+1; // add one to go past parenthesis
+ }
+ }
+ }
+ // grab the last one
+ if(nPar%2 == 0) {
+ int pos = text_.length();
+ person += text_.mid(oldPos, pos-oldPos).stripWhiteSpace();
+ QString all = person;
+ if(!role.isEmpty()) {
+ if(role.startsWith(QString::fromLatin1("as "))) {
+ role = role.mid(3);
+ }
+ all += "::" + role;
+ }
+ cast << all;
+ }
+ return cast;
+}
+
+void AMCImporter::slotCancel() {
+ m_cancelled = true;
+}
+
+#include "amcimporter.moc"
diff --git a/src/translators/amcimporter.h b/src/translators/amcimporter.h
new file mode 100644
index 0000000..d1b9d1a
--- /dev/null
+++ b/src/translators/amcimporter.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_IMPORT_AMCIMPORTER_H
+#define TELLICO_IMPORT_AMCIMPORTER_H
+
+#include "dataimporter.h"
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ @author Robby Stephenson
+ */
+class AMCImporter : public DataImporter {
+Q_OBJECT
+public:
+ AMCImporter(const KURL& url);
+ virtual ~AMCImporter();
+
+ virtual Data::CollPtr collection();
+ bool canImport(int type) const;
+
+public slots:
+ void slotCancel();
+
+private:
+ bool readBool();
+ Q_UINT32 readInt();
+ QString readString();
+ QString readImage(const QString& format);
+ void readEntry();
+ QStringList parseCast(const QString& text);
+
+ Data::CollPtr m_coll;
+ bool m_cancelled : 1;
+ QDataStream m_ds;
+ int m_majVersion;
+ int m_minVersion;
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/translators/audiofileimporter.cpp b/src/translators/audiofileimporter.cpp
new file mode 100644
index 0000000..f825964
--- /dev/null
+++ b/src/translators/audiofileimporter.cpp
@@ -0,0 +1,424 @@
+/***************************************************************************
+ copyright : (C) 2004-2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include <config.h>
+
+#include "audiofileimporter.h"
+#include "../collections/musiccollection.h"
+#include "../entry.h"
+#include "../field.h"
+#include "../latin1literal.h"
+#include "../imagefactory.h"
+#include "../tellico_utils.h"
+#include "../tellico_kernel.h"
+#include "../progressmanager.h"
+#include "../tellico_debug.h"
+
+#ifdef HAVE_TAGLIB
+#include <taglib/fileref.h>
+#include <taglib/tag.h>
+#include <taglib/id3v2tag.h>
+#include <taglib/mpegfile.h>
+#include <taglib/vorbisfile.h>
+#include <taglib/flacfile.h>
+#include <taglib/audioproperties.h>
+#endif
+
+#include <klocale.h>
+#include <kapplication.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qvgroupbox.h>
+#include <qcheckbox.h>
+#include <qdir.h>
+#include <qwhatsthis.h>
+
+using Tellico::Import::AudioFileImporter;
+
+AudioFileImporter::AudioFileImporter(const KURL& url_) : Tellico::Import::Importer(url_)
+ , m_coll(0)
+ , m_widget(0)
+ , m_cancelled(false) {
+}
+
+bool AudioFileImporter::canImport(int type) const {
+ return type == Data::Collection::Album;
+}
+
+Tellico::Data::CollPtr AudioFileImporter::collection() {
+#ifndef HAVE_TAGLIB
+ return 0;
+#else
+
+ if(m_coll) {
+ return m_coll;
+ }
+
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, i18n("Scanning audio files..."), true);
+ item.setTotalSteps(100);
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+ ProgressItem::Done done(this);
+
+ // TODO: allow remote audio file importing
+ QStringList dirs = url().path();
+ if(m_recursive->isChecked()) {
+ dirs += Tellico::findAllSubDirs(dirs[0]);
+ }
+
+ if(m_cancelled) {
+ return 0;
+ }
+
+ const bool showProgress = options() & ImportProgress;
+
+ QStringList files;
+ for(QStringList::ConstIterator it = dirs.begin(); !m_cancelled && it != dirs.end(); ++it) {
+ if((*it).isEmpty()) {
+ continue;
+ }
+
+ QDir dir(*it);
+ dir.setFilter(QDir::Files | QDir::Readable | QDir::Hidden); // hidden since I want directory files
+ const QStringList list = dir.entryList();
+ for(QStringList::ConstIterator it2 = list.begin(); it2 != list.end(); ++it2) {
+ files += dir.absFilePath(*it2);
+ }
+// kapp->processEvents(); not needed ?
+ }
+
+ if(m_cancelled) {
+ return 0;
+ }
+ item.setTotalSteps(files.count());
+
+ const QString title = QString::fromLatin1("title");
+ const QString artist = QString::fromLatin1("artist");
+ const QString year = QString::fromLatin1("year");
+ const QString genre = QString::fromLatin1("genre");
+ const QString track = QString::fromLatin1("track");
+ const QString comments = QString::fromLatin1("comments");
+ const QString file = QString::fromLatin1("file");
+
+ m_coll = new Data::MusicCollection(true);
+
+ const bool addFile = m_addFilePath->isChecked();
+ const bool addBitrate = m_addBitrate->isChecked();
+
+ Data::FieldPtr f;
+ if(addFile) {
+ f = m_coll->fieldByName(file);
+ if(!f) {
+ f = new Data::Field(file, i18n("Files"), Data::Field::Table);
+ m_coll->addField(f);
+ }
+ f->setProperty(QString::fromLatin1("column1"), i18n("Files"));
+ if(addBitrate) {
+ f->setProperty(QString::fromLatin1("columns"), QChar('2'));
+ f->setProperty(QString::fromLatin1("column2"), i18n("Bitrate"));
+ } else {
+ f->setProperty(QString::fromLatin1("columns"), QChar('1'));
+ }
+ }
+
+ QMap<QString, Data::EntryPtr> albumMap;
+
+ QStringList directoryFiles;
+ const uint stepSize = QMAX(static_cast<size_t>(1), files.count() / 100);
+
+ bool changeTrackTitle = true;
+ uint j = 0;
+ for(QStringList::ConstIterator it = files.begin(); !m_cancelled && it != files.end(); ++it, ++j) {
+ TagLib::FileRef f(QFile::encodeName(*it));
+ if(f.isNull() || !f.tag()) {
+ if((*it).endsWith(QString::fromLatin1("/.directory"))) {
+ directoryFiles += *it;
+ }
+ continue;
+ }
+
+ TagLib::Tag* tag = f.tag();
+ QString album = TStringToQString(tag->album()).stripWhiteSpace();
+ if(album.isEmpty()) {
+ // can't do anything since tellico entries are by album
+ kdWarning() << "Skipping: no album listed for " << *it << endl;
+ continue;
+ }
+ int disc = discNumber(f);
+ if(disc > 1 && !m_coll->hasField(QString::fromLatin1("track%1").arg(disc))) {
+ Data::FieldPtr f2 = new Data::Field(QString::fromLatin1("track%1").arg(disc),
+ i18n("Tracks (Disc %1)").arg(disc),
+ Data::Field::Table);
+ f2->setFormatFlag(Data::Field::FormatTitle);
+ f2->setProperty(QString::fromLatin1("columns"), QChar('3'));
+ f2->setProperty(QString::fromLatin1("column1"), i18n("Title"));
+ f2->setProperty(QString::fromLatin1("column2"), i18n("Artist"));
+ f2->setProperty(QString::fromLatin1("column3"), i18n("Length"));
+ m_coll->addField(f2);
+ if(changeTrackTitle) {
+ Data::FieldPtr newTrack = new Data::Field(*m_coll->fieldByName(track));
+ newTrack->setTitle(i18n("Tracks (Disc %1)").arg(1));
+ m_coll->modifyField(newTrack);
+ changeTrackTitle = false;
+ }
+ }
+ bool various = false;
+ bool exists = true;
+ Data::EntryPtr entry = 0;
+ if(!(entry = albumMap[album.lower()])) {
+ entry = new Data::Entry(m_coll);
+ albumMap.insert(album.lower(), entry);
+ exists = false;
+ }
+ // album entries use the album name as the title
+ entry->setField(title, album);
+ QString a = TStringToQString(tag->artist()).stripWhiteSpace();
+ if(!a.isEmpty()) {
+ if(exists && entry->field(artist).lower() != a.lower()) {
+ various = true;
+ entry->setField(artist, i18n("(Various)"));
+ } else {
+ entry->setField(artist, a);
+ }
+ }
+ if(tag->year() > 0) {
+ entry->setField(year, QString::number(tag->year()));
+ }
+ if(!tag->genre().isEmpty()) {
+ entry->setField(genre, TStringToQString(tag->genre()).stripWhiteSpace());
+ }
+
+ if(!tag->title().isEmpty()) {
+ int trackNum = tag->track();
+ if(trackNum <= 0) { // try to figure out track number from file name
+ QFileInfo f(*it);
+ QString fileName = f.baseName();
+ QString numString;
+ int i = 0;
+ const int len = fileName.length();
+ while(fileName[i].isNumber() && i < len) {
+ i++;
+ }
+ if(i == 0) { // does not start with a number
+ i = len - 1;
+ while(i >= 0 && fileName[i].isNumber()) {
+ i--;
+ }
+ // file name ends with a number
+ if(i != len - 1) {
+ numString = fileName.mid(i + 1);
+ }
+ } else {
+ numString = fileName.mid(0, i);
+ }
+ bool ok;
+ int number = numString.toInt(&ok);
+ if(ok) {
+ trackNum = number;
+ }
+ }
+ if(trackNum > 0) {
+ QString t = TStringToQString(tag->title()).stripWhiteSpace();
+ t += "::" + a;
+ const int len = f.audioProperties()->length();
+ if(len > 0) {
+ t += "::" + Tellico::minutes(len);
+ }
+ QString realTrack = disc > 1 ? track + QString::number(disc) : track;
+ entry->setField(realTrack, insertValue(entry->field(realTrack), t, trackNum));
+ if(addFile) {
+ QString fileValue = *it;
+ if(addBitrate) {
+ fileValue += "::" + QString::number(f.audioProperties()->bitrate());
+ }
+ entry->setField(file, insertValue(entry->field(file), fileValue, trackNum));
+ }
+ } else {
+ myDebug() << *it << " contains no track number and track number cannot be determined, so the track is not imported." << endl;
+ }
+ } else {
+ myDebug() << *it << " has an empty title, so the track is not imported." << endl;
+ }
+ if(!tag->comment().stripWhiteSpace().isEmpty()) {
+ QString c = entry->field(comments);
+ if(!c.isEmpty()) {
+ c += QString::fromLatin1("<br/>");
+ }
+ if(!tag->title().isEmpty()) {
+ c += QString::fromLatin1("<em>") + TStringToQString(tag->title()).stripWhiteSpace() + QString::fromLatin1("</em> - ");
+ }
+ c += TStringToQString(tag->comment().stripWhiteSpace()).stripWhiteSpace();
+ entry->setField(comments, c);
+ }
+
+ if(!exists) {
+ m_coll->addEntries(entry);
+ }
+ if(showProgress && j%stepSize == 0) {
+ ProgressManager::self()->setTotalSteps(this, files.count() + directoryFiles.count());
+ ProgressManager::self()->setProgress(this, j);
+ kapp->processEvents();
+ }
+
+/* kdDebug() << "-- TAG --" << endl;
+ kdDebug() << "title - \"" << tag->title().to8Bit() << "\"" << endl;
+ kdDebug() << "artist - \"" << tag->artist().to8Bit() << "\"" << endl;
+ kdDebug() << "album - \"" << tag->album().to8Bit() << "\"" << endl;
+ kdDebug() << "year - \"" << tag->year() << "\"" << endl;
+ kdDebug() << "comment - \"" << tag->comment().to8Bit() << "\"" << endl;
+ kdDebug() << "track - \"" << tag->track() << "\"" << endl;
+ kdDebug() << "genre - \"" << tag->genre().to8Bit() << "\"" << endl;*/
+ }
+
+ if(m_cancelled) {
+ m_coll = 0;
+ return 0;
+ }
+
+ QTextStream ts;
+ QRegExp iconRx(QString::fromLatin1("Icon\\s*=\\s*(.*)"));
+ for(QStringList::ConstIterator it = directoryFiles.begin(); !m_cancelled && it != directoryFiles.end(); ++it, ++j) {
+ QFile file(*it);
+ if(!file.open(IO_ReadOnly)) {
+ continue;
+ }
+ ts.unsetDevice();
+ ts.setDevice(&file);
+ for(QString line = ts.readLine(); !line.isNull(); line = ts.readLine()) {
+ if(!iconRx.exactMatch(line)) {
+ continue;
+ }
+ QDir thisDir(*it);
+ thisDir.cdUp();
+ QFileInfo fi(thisDir, iconRx.cap(1));
+ Data::EntryPtr entry = albumMap[thisDir.dirName()];
+ if(!entry) {
+ continue;
+ }
+ KURL u;
+ u.setPath(fi.absFilePath());
+ QString id = ImageFactory::addImage(u, true);
+ if(!id.isEmpty()) {
+ entry->setField(QString::fromLatin1("cover"), id);
+ }
+ break;
+ }
+
+ if(showProgress && j%stepSize == 0) {
+ ProgressManager::self()->setProgress(this, j);
+ kapp->processEvents();
+ }
+ }
+
+ if(m_cancelled) {
+ m_coll = 0;
+ return 0;
+ }
+
+ return m_coll;
+#endif
+}
+
+QWidget* AudioFileImporter::widget(QWidget* parent_, const char* name_) {
+ if(m_widget) {
+ return m_widget;
+ }
+
+ m_widget = new QWidget(parent_, name_);
+ QVBoxLayout* l = new QVBoxLayout(m_widget);
+
+ QVGroupBox* box = new QVGroupBox(i18n("Audio File Options"), m_widget);
+
+ m_recursive = new QCheckBox(i18n("Recursive &folder search"), box);
+ QWhatsThis::add(m_recursive, i18n("If checked, folders are recursively searched for audio files."));
+ // by default, make it checked
+ m_recursive->setChecked(true);
+
+ m_addFilePath = new QCheckBox(i18n("Include file &location"), box);
+ QWhatsThis::add(m_addFilePath, i18n("If checked, the file names for each track are added to the entries."));
+ m_addFilePath->setChecked(false);
+ connect(m_addFilePath, SIGNAL(toggled(bool)), SLOT(slotAddFileToggled(bool)));
+
+ m_addBitrate = new QCheckBox(i18n("Include &bitrate"), box);
+ QWhatsThis::add(m_addBitrate, i18n("If checked, the bitrate for each track is added to the entries."));
+ m_addBitrate->setChecked(false);
+ m_addBitrate->setEnabled(false);
+
+ l->addWidget(box);
+ l->addStretch(1);
+ return m_widget;
+}
+
+// pos_ is NOT zero-indexed!
+QString AudioFileImporter::insertValue(const QString& str_, const QString& value_, uint pos_) {
+ QStringList list = Data::Field::split(str_, true);
+ for(uint i = list.count(); i < pos_; ++i) {
+ list += QString::null;
+ }
+ if(!list[pos_-1].isNull()) {
+ myDebug() << "AudioFileImporter::insertValue() - overwriting track " << pos_ << endl;
+ myDebug() << "*** Old value: " << list[pos_-1] << endl;
+ myDebug() << "*** New value: " << value_ << endl;
+ }
+ list[pos_-1] = value_;
+ return list.join(QString::fromLatin1("; "));
+}
+
+void AudioFileImporter::slotCancel() {
+ m_cancelled = true;
+}
+
+void AudioFileImporter::slotAddFileToggled(bool on_) {
+ m_addBitrate->setEnabled(on_);
+ if(!on_) {
+ m_addBitrate->setChecked(false);
+ }
+}
+
+int AudioFileImporter::discNumber(const TagLib::FileRef& ref_) const {
+ // default to 1 unless otherwise
+ int num = 1;
+#ifdef HAVE_TAGLIB
+ QString disc;
+ if(TagLib::MPEG::File* file = dynamic_cast<TagLib::MPEG::File*>(ref_.file())) {
+ if(file->ID3v2Tag() && !file->ID3v2Tag()->frameListMap()["TPOS"].isEmpty()) {
+ disc = TStringToQString(file->ID3v2Tag()->frameListMap()["TPOS"].front()->toString()).stripWhiteSpace();
+ }
+ } else if(TagLib::Ogg::Vorbis::File* file = dynamic_cast<TagLib::Ogg::Vorbis::File*>(ref_.file())) {
+ if(file->tag() && !file->tag()->fieldListMap()["DISCNUMBER"].isEmpty()) {
+ disc = TStringToQString(file->tag()->fieldListMap()["DISCNUMBER"].front()).stripWhiteSpace();
+ }
+ } else if(TagLib::FLAC::File* file = dynamic_cast<TagLib::FLAC::File*>(ref_.file())) {
+ if(file->xiphComment() && !file->xiphComment()->fieldListMap()["DISCNUMBER"].isEmpty()) {
+ disc = TStringToQString(file->xiphComment()->fieldListMap()["DISCNUMBER"].front()).stripWhiteSpace();
+ }
+ }
+
+ if(!disc.isEmpty()) {
+ int pos = disc.find('/');
+ int n;
+ bool ok;
+ if(pos == -1) {
+ n = disc.toInt(&ok);
+ } else {
+ n = disc.left(pos).toInt(&ok);
+ }
+ if(ok && n > 0) {
+ num = n;
+ }
+ }
+#endif
+ return num;
+}
+
+#include "audiofileimporter.moc"
diff --git a/src/translators/audiofileimporter.h b/src/translators/audiofileimporter.h
new file mode 100644
index 0000000..d9c0c9a
--- /dev/null
+++ b/src/translators/audiofileimporter.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+ copyright : (C) 2004-2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef AUDIOFILEIMPORTER_H
+#define AUDIOFILEIMPORTER_H
+
+class QCheckBox;
+
+#include "importer.h"
+#include "../datavectors.h"
+
+namespace TagLib {
+ class FileRef;
+}
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ * The AudioFileImporter class takes care of importing audio files.
+ *
+ * @author Robby Stephenson
+ */
+class AudioFileImporter : public Importer {
+Q_OBJECT
+
+public:
+ /**
+ */
+ AudioFileImporter(const KURL& url);
+
+ /**
+ */
+ virtual Data::CollPtr collection();
+ /**
+ */
+ virtual QWidget* widget(QWidget* parent, const char* name=0);
+ virtual bool canImport(int type) const;
+
+public slots:
+ void slotCancel();
+ void slotAddFileToggled(bool on);
+
+private:
+ static QString insertValue(const QString& str, const QString& value, uint pos);
+
+ int discNumber(const TagLib::FileRef& file) const;
+
+ Data::CollPtr m_coll;
+ QWidget* m_widget;
+ QCheckBox* m_recursive;
+ QCheckBox* m_addFilePath;
+ QCheckBox* m_addBitrate;
+ bool m_cancelled : 1;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/bibtex-translation.xml b/src/translators/bibtex-translation.xml
new file mode 100644
index 0000000..0c1bf03
--- /dev/null
+++ b/src/translators/bibtex-translation.xml
@@ -0,0 +1,298 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE keymap>
+<!-- Some bibtex file may incorrectly place the braces. -->
+<!-- The first string element should be the correct representation -->
+<!-- Most of these key mappings were taken, with permission, from the -->
+<!-- CharacterConversion.plist file in the Bibdesk program by Michael McCracken -->
+<keymap version="1.0">
+ <key char="Å">
+ <string>{\AA}</string>
+ </key>
+ <key char="À">
+ <string>{\`A}</string>
+ <string>\`{A}</string>
+ </key>
+ <key char="Â">
+ <string>{\^A}</string>
+ <string>\^{A}</string>
+ </key>
+ <key char="Á">
+ <string>{\'A}</string>
+ <string>\'{A}</string>
+ </key>
+ <key char="Ã">
+ <string>{\~A}</string>
+ <string>\~{A}</string>
+ </key>
+ <key char="Ä">
+ <string>{\"A}</string>
+ <string>\"{A}</string>
+ </key>
+ <key char="Æ">
+ <string>{\AE}</string>
+ </key>
+ <key char="Ø">
+ <string>{\O}</string>
+ </key>
+ <key char="à">
+ <string>{\`a}</string>
+ <string>\`{a}</string>
+ </key>
+ <key char="á">
+ <string>{\'a}</string>
+ <string>\'{a}</string>
+ </key>
+ <key char="â">
+ <string>{\^a}</string>
+ <string>\^{a}</string>
+ </key>
+ <key char="ã">
+ <string>{\~a}</string>
+ <string>\~{a}</string>
+ </key>
+ <key char="ä">
+ <string>{\"a}</string>
+ <string>\"{a}</string>
+ </key>
+ <key char="å">
+ <string>{\aa}</string>
+ </key>
+ <key char="æ">
+ <string>{\ae}</string>
+ </key>
+ <key char="Ç">
+ <string>{\c C}</string>
+ <string>\c{C}</string>
+ </key>
+ <key char="Č">
+ <string>{\u C}</string>
+ <string>\u{C}</string>
+ </key>
+ <key char="Č">
+ <string>{\v C}</string>
+ <string>\v{C}</string>
+ </key>
+ <key char="ç">
+ <string>{\c c}</string>
+ <string>\c{c}</string>
+ </key>
+ <key char="ć">
+ <string>{\'c}</string>
+ <string>\'{c}</string>
+ </key>
+ <key char="č">
+ <string>{\v c}</string>
+ <string>\v{c}</string>
+ </key>
+ <key char="È">
+ <string>{\`E}</string>
+ <string>\`{E}</string>
+ </key>
+ <key char="Ê">
+ <string>{\^E}</string>
+ <string>\^{E}</string>
+ </key>
+ <key char="É">
+ <string>{\'E}</string>
+ <string>\'{E}</string>
+ </key>
+ <key char="Ë">
+ <string>{\"E}</string>
+ <string>\"{E}</string>
+ </key>
+ <key char="è">
+ <string>{\`e}</string>
+ <string>\`{e}</string>
+ </key>
+ <key char="é">
+ <string>{\'e}</string>
+ <string>\'{e}</string>
+ </key>
+ <key char="ê">
+ <string>{\^e}</string>
+ <string>\^{e}</string>
+ </key>
+ <key char="ë">
+ <string>{\"e}</string>
+ <string>\"{e}</string>
+ </key>
+ <key char="Î">
+ <string>{\^I}</string>
+ <string>\^{I}</string>
+ </key>
+ <key char="Í">
+ <string>{\'I}</string>
+ <string>\'{I}</string>
+ </key>
+ <key char="Ï">
+ <string>{\"I}</string>
+ <string>\"{I}</string>
+ </key>
+ <key char="ì">
+ <string>{\`{\i}}</string>
+ <string>\`{\i}</string>
+ </key>
+ <key char="í">
+ <string>{\'{\i}}</string>
+ <string>\'{\i}</string>
+ </key>
+ <key char="î">
+ <string>{\^{\i}}</string>
+ <string>\^{\i}</string>
+ </key>
+ <key char="ï">
+ <string>{\"{\i}}</string>
+ <string>\"{\i}</string>
+ </key>
+ <key char="Ñ">
+ <string>{\~N}</string>
+ <string>\~{N}</string>
+ </key>
+ <key char="ñ">
+ <string>{\~n}</string>
+ <string>\~{n}</string>
+ </key>
+ <key char="Ó">
+ <string>{\'O}</string>
+ <string>\'{O}</string>
+ </key>
+ <key char="Ô">
+ <string>{\^O}</string>
+ <string>\^{O}</string>
+ </key>
+ <key char="Ø">
+ <string>{\O}</string>
+ </key>
+ <key char="Ö">
+ <string>{\"O}</string>
+ <string>\"{O}</string>
+ </key>
+ <key char="Œ">
+ <string>{\OE}</string>
+ </key>
+ <key char="ò">
+ <string>{\`o}</string>
+ <string>\`{o}</string>
+ </key>
+ <key char="ó">
+ <string>{\'o}</string>
+ <string>\'{o}</string>
+ </key>
+ <key char="ô">
+ <string>{\^o}</string>
+ <string>\^{o}</string>
+ </key>
+ <key char="õ">
+ <string>{\~o}</string>
+ <string>\~{o}</string>
+ </key>
+ <key char="ö">
+ <string>{\"o}</string>
+ <string>\"{o}</string>
+ </key>
+ <key char="œ">
+ <string>{\oe}</string>
+ </key>
+ <key char="ø">
+ <string>{\o}</string>
+ </key>
+ <key char="ş">
+ <string>{\c s}</string>
+ <string>\c{s}</string>
+ </key>
+ <key char="š">
+ <string>{\v s}</string>
+ <string>\v{s}</string>
+ </key>
+ <key char="Ţ">
+ <string>{\c T}</string>
+ <string>\c{T}</string>
+ </key>
+ <key char="ţ">
+ <string>{\c t}</string>
+ <string>\c{t}</string>
+ </key>
+ <key char="Ú">
+ <string>{\'U}</string>
+ <string>\'{U}</string>
+ </key>
+ <key char="Û">
+ <string>{\^U}</string>
+ <string>\^{U}</string>
+ </key>
+ <key char="Ü">
+ <string>{\"U}</string>
+ <string>\"{U}</string>
+ </key>
+ <key char="ù">
+ <string>{\`u}</string>
+ <string>\`{u}</string>
+ </key>
+ <key char="ú">
+ <string>{\'u}</string>
+ <string>\'{u}</string>
+ </key>
+ <key char="û">
+ <string>{\^u}</string>
+ <string>\^{u}</string>
+ </key>
+ <key char="ü">
+ <string>{\"u}</string>
+ <string>\"{u}</string>
+ </key>
+ <key char="Ÿ">
+ <string>{\"Y}</string>
+ <string>\"{Y}</string>
+ </key>
+ <key char="ÿ">
+ <string>{\"y}</string>
+ <string>\"{y}</string>
+ </key>
+ <key char="Ž">
+ <string>{\v Z}</string>
+ <string>\v{Z}</string>
+ </key>
+ <key char="ž">
+ <string>{\v z}</string>
+ <string>\v{z}</string>
+ </key>
+ <key char="ß">
+ <string>{\ss}</string>
+ </key>
+ <key char="£">
+ <string>\pounds</string>
+ </key>
+ <key char="±">
+ <string>$\pm$</string>
+ </key>
+ <key char="–">
+ <string>--</string>
+ </key>
+ <key char="—">
+ <string>---</string>
+ </key>
+ <key char="•">
+ <string>*</string>
+ </key>
+ <key char="…">
+ <string>{\ldots}</string>
+ </key>
+ <key char="§">
+ <string>{\S}</string>
+ </key>
+ <key char="©">
+ <string>{\copyright}</string>
+ </key>
+ <key char="®">
+ <string>{\textregistered}</string>
+ </key>
+ <key char="™">
+ <string>{\texttrademark}</string>
+ </key>
+ <key char="°">
+ <string>$^{\circ}$</string>
+ </key>
+ <key char="%">
+ <string>\%</string>
+ </key>
+</keymap>
diff --git a/src/translators/bibtexexporter.cpp b/src/translators/bibtexexporter.cpp
new file mode 100644
index 0000000..2706ac8
--- /dev/null
+++ b/src/translators/bibtexexporter.cpp
@@ -0,0 +1,326 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+
+#include "bibtexexporter.h"
+#include "bibtexhandler.h"
+#include "../document.h"
+#include "../collections/bibtexcollection.h"
+#include "../latin1literal.h"
+#include "../filehandler.h"
+#include "../stringset.h"
+#include "../tellico_debug.h"
+
+#include <config.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kconfig.h>
+#include <kcombobox.h>
+
+#include <qregexp.h>
+#include <qcheckbox.h>
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qwhatsthis.h>
+#include <qlabel.h>
+#include <qhbox.h>
+
+using Tellico::Export::BibtexExporter;
+
+BibtexExporter::BibtexExporter() : Tellico::Export::Exporter(),
+ m_expandMacros(false),
+ m_packageURL(true),
+ m_skipEmptyKeys(false),
+ m_widget(0) {
+}
+
+QString BibtexExporter::formatString() const {
+ return i18n("Bibtex");
+}
+
+QString BibtexExporter::fileFilter() const {
+ return i18n("*.bib|Bibtex Files (*.bib)") + QChar('\n') + i18n("*|All Files");
+}
+
+bool BibtexExporter::exec() {
+ Data::CollPtr c = collection();
+ if(!c || c->type() != Data::Collection::Bibtex) {
+ return false;
+ }
+ const Data::BibtexCollection* coll = static_cast<const Data::BibtexCollection*>(c.data());
+
+// there are some special attributes
+// the entry-type specifies the entry type - book, inproceedings, whatever
+ QString typeField;
+// the key specifies the cite-key
+ QString keyField;
+// the crossref bibtex field can reference another entry
+ QString crossRefField;
+ bool hasCrossRefs = false;
+
+ const QString bibtex = QString::fromLatin1("bibtex");
+// keep a list of all the 'ordinary' fields to iterate through later
+ Data::FieldVec fields;
+ Data::FieldVec vec = coll->fields();
+ for(Data::FieldVec::Iterator it = vec.begin(); it != vec.end(); ++it) {
+ QString bibtexField = it->property(bibtex);
+ if(bibtexField == Latin1Literal("entry-type")) {
+ typeField = it->name();
+ } else if(bibtexField == Latin1Literal("key")) {
+ keyField = it->name();
+ } else if(bibtexField == Latin1Literal("crossref")) {
+ fields.append(it); // still output crossref field
+ crossRefField = it->name();
+ hasCrossRefs = true;
+ } else if(!bibtexField.isEmpty()) {
+ fields.append(it);
+ }
+ }
+
+ if(typeField.isEmpty() || keyField.isEmpty()) {
+ kdWarning() << "BibtexExporter::exec() - the collection must have fields defining "
+ "the entry-type and the key of the entry" << endl;
+ return false;
+ }
+ if(fields.isEmpty()) {
+ kdWarning() << "BibtexExporter::exec() - no bibtex field mapping exists in the collection." << endl;
+ return false;
+ }
+
+ QString text = QString::fromLatin1("@comment{Generated by Tellico ")
+ + QString::fromLatin1(VERSION)
+ + QString::fromLatin1("}\n\n");
+
+ if(!coll->preamble().isEmpty()) {
+ text += QString::fromLatin1("@preamble{") + coll->preamble() + QString::fromLatin1("}\n\n");
+ }
+
+ const QStringList macros = coll->macroList().keys();
+ if(!m_expandMacros) {
+ QMap<QString, QString>::ConstIterator macroIt;
+ for(macroIt = coll->macroList().constBegin(); macroIt != coll->macroList().constEnd(); ++macroIt) {
+ if(!macroIt.data().isEmpty()) {
+ text += QString::fromLatin1("@string{")
+ + macroIt.key()
+ + QString::fromLatin1("=")
+ + BibtexHandler::exportText(macroIt.data(), macros)
+ + QString::fromLatin1("}\n\n");
+ }
+ }
+ }
+
+ // if anything is crossref'd, we have to do an initial scan through the
+ // whole collection first
+ StringSet crossRefKeys;
+ if(hasCrossRefs) {
+ for(Data::EntryVec::ConstIterator entryIt = entries().begin(); entryIt != entries().end(); ++entryIt) {
+ crossRefKeys.add(entryIt->field(crossRefField));
+ }
+ }
+
+
+ StringSet usedKeys;
+ Data::ConstEntryVec crossRefs;
+ QString type, key, newKey, value;
+ for(Data::EntryVec::ConstIterator entryIt = entries().begin(); entryIt != entries().end(); ++entryIt) {
+ type = entryIt->field(typeField);
+ if(type.isEmpty()) {
+ kdWarning() << "BibtexExporter::text() - the entry for '" << entryIt->title()
+ << "' has no entry-type, skipping it!" << endl;
+ continue;
+ }
+
+ key = entryIt->field(keyField);
+ if(key.isEmpty()) {
+ if(m_skipEmptyKeys) {
+ continue;
+ }
+ key = BibtexHandler::bibtexKey(entryIt.data());
+ } else {
+ // check crossrefs, only counts for non-empty keys
+ // if this entry is crossref'd, add it to the list, and skip it
+ if(hasCrossRefs && crossRefKeys.has(key)) {
+ crossRefs.append(entryIt.data());
+ continue;
+ }
+ }
+
+ newKey = key;
+ char c = 'a';
+ while(usedKeys.has(newKey)) {
+ // duplicate found!
+ newKey = key + c;
+ ++c;
+ }
+ key = newKey;
+ usedKeys.add(key);
+
+ writeEntryText(text, fields, *entryIt, type, key);
+ }
+
+ // now write out crossrefs
+ for(Data::ConstEntryVec::Iterator entryIt = crossRefs.begin(); entryIt != crossRefs.end(); ++entryIt) {
+ // no need to check type
+
+ key = entryIt->field(keyField);
+ newKey = key;
+ char c = 'a';
+ while(usedKeys.has(newKey)) {
+ // duplicate found!
+ newKey = key + c;
+ ++c;
+ }
+ key = newKey;
+ usedKeys.add(key);
+
+ writeEntryText(text, fields, *entryIt, entryIt->field(typeField), key);
+ }
+
+ return FileHandler::writeTextURL(url(), text, options() & ExportUTF8, options() & Export::ExportForce);
+}
+
+QWidget* BibtexExporter::widget(QWidget* parent_, const char* name_/*=0*/) {
+ if(m_widget && m_widget->parent() == parent_) {
+ return m_widget;
+ }
+
+ m_widget = new QWidget(parent_, name_);
+ QVBoxLayout* l = new QVBoxLayout(m_widget);
+
+ QGroupBox* box = new QGroupBox(1, Qt::Horizontal, i18n("Bibtex Options"), m_widget);
+ l->addWidget(box);
+
+ m_checkExpandMacros = new QCheckBox(i18n("Expand string macros"), box);
+ m_checkExpandMacros->setChecked(m_expandMacros);
+ QWhatsThis::add(m_checkExpandMacros, i18n("If checked, the string macros will be expanded and no "
+ "@string{} entries will be written."));
+
+ m_checkPackageURL = new QCheckBox(i18n("Use URL package"), box);
+ m_checkPackageURL->setChecked(m_packageURL);
+ QWhatsThis::add(m_checkPackageURL, i18n("If checked, any URL fields will be wrapped in a "
+ "\\url declaration."));
+
+ m_checkSkipEmpty = new QCheckBox(i18n("Skip entries with empty citation keys"), box);
+ m_checkSkipEmpty->setChecked(m_skipEmptyKeys);
+ QWhatsThis::add(m_checkSkipEmpty, i18n("If checked, any entries without a bibtex citation key "
+ "will be skipped."));
+
+ QHBox* hbox = new QHBox(box);
+ QLabel* l1 = new QLabel(i18n("Bibtex quotation style:") + ' ', hbox); // add a space for astheticss
+ m_cbBibtexStyle = new KComboBox(hbox);
+ m_cbBibtexStyle->insertItem(i18n("Braces"));
+ m_cbBibtexStyle->insertItem(i18n("Quotes"));
+ QString whats = i18n("<qt>The quotation style used when exporting bibtex. All field values will "
+ " be escaped with either braces or quotation marks.</qt>");
+ QWhatsThis::add(l1, whats);
+ QWhatsThis::add(m_cbBibtexStyle, whats);
+ if(BibtexHandler::s_quoteStyle == BibtexHandler::BRACES) {
+ m_cbBibtexStyle->setCurrentItem(i18n("Braces"));
+ } else {
+ m_cbBibtexStyle->setCurrentItem(i18n("Quotes"));
+ }
+
+ l->addStretch(1);
+ return m_widget;
+}
+
+void BibtexExporter::readOptions(KConfig* config_) {
+ KConfigGroup group(config_, QString::fromLatin1("ExportOptions - %1").arg(formatString()));
+ m_expandMacros = group.readBoolEntry("Expand Macros", m_expandMacros);
+ m_packageURL = group.readBoolEntry("URL Package", m_packageURL);
+ m_skipEmptyKeys = group.readBoolEntry("Skip Empty Keys", m_skipEmptyKeys);
+
+ if(group.readBoolEntry("Use Braces", true)) {
+ BibtexHandler::s_quoteStyle = BibtexHandler::BRACES;
+ } else {
+ BibtexHandler::s_quoteStyle = BibtexHandler::QUOTES;
+ }
+}
+
+void BibtexExporter::saveOptions(KConfig* config_) {
+ KConfigGroup group(config_, QString::fromLatin1("ExportOptions - %1").arg(formatString()));
+ m_expandMacros = m_checkExpandMacros->isChecked();
+ group.writeEntry("Expand Macros", m_expandMacros);
+ m_packageURL = m_checkPackageURL->isChecked();
+ group.writeEntry("URL Package", m_packageURL);
+ m_skipEmptyKeys = m_checkSkipEmpty->isChecked();
+ group.writeEntry("Skip Empty Keys", m_skipEmptyKeys);
+
+ bool useBraces = m_cbBibtexStyle->currentText() == i18n("Braces");
+ group.writeEntry("Use Braces", useBraces);
+ if(useBraces) {
+ BibtexHandler::s_quoteStyle = BibtexHandler::BRACES;
+ } else {
+ BibtexHandler::s_quoteStyle = BibtexHandler::QUOTES;
+ }
+}
+
+void BibtexExporter::writeEntryText(QString& text_, const Data::FieldVec& fields_, const Data::Entry& entry_,
+ const QString& type_, const QString& key_) {
+ const QStringList macros = static_cast<const Data::BibtexCollection*>(Data::Document::self()->collection().data())->macroList().keys();
+ const QString bibtex = QString::fromLatin1("bibtex");
+ const QString bibtexSep = QString::fromLatin1("bibtex-separator");
+
+ text_ += '@' + type_ + '{' + key_;
+
+ QString value;
+ Data::FieldVec::ConstIterator fIt, end = fields_.constEnd();
+ bool format = options() & Export::ExportFormatted;
+ for(fIt = fields_.constBegin(); fIt != end; ++fIt) {
+ value = entry_.field(fIt->name(), format);
+ if(value.isEmpty()) {
+ continue;
+ }
+
+ // If the entry is formatted as a name and allows multiple values
+ // insert "and" in between them (e.g. author and editor)
+ if(fIt->formatFlag() == Data::Field::FormatName
+ && fIt->flags() & Data::Field::AllowMultiple) {
+ value.replace(Data::Field::delimiter(), QString::fromLatin1(" and "));
+ } else if(fIt->flags() & Data::Field::AllowMultiple) {
+ QString bibsep = fIt->property(bibtexSep);
+ if(!bibsep.isEmpty()) {
+ value.replace(Data::Field::delimiter(), bibsep);
+ }
+ } else if(fIt->type() == Data::Field::Para) {
+ // strip HTML from bibtex export
+ QRegExp stripHTML(QString::fromLatin1("<.*>"), true);
+ stripHTML.setMinimal(true);
+ value.remove(stripHTML);
+ } else if(fIt->property(bibtex) == Latin1Literal("pages")) {
+ QRegExp rx(QString::fromLatin1("(\\d)-(\\d)"));
+ for(int pos = rx.search(value); pos > -1; pos = rx.search(value, pos+2)) {
+ value.replace(pos, 3, rx.cap(1)+"--"+rx.cap(2));
+ }
+ }
+
+ if(m_packageURL && fIt->type() == Data::Field::URL) {
+ bool b = BibtexHandler::s_quoteStyle == BibtexHandler::BRACES;
+ value = (b ? QChar('{') : QChar('"'))
+ + QString::fromLatin1("\\url{") + BibtexHandler::exportText(value, macros) + QChar('}')
+ + (b ? QChar('}') : QChar('"'));
+ } else if(fIt->type() != Data::Field::Number) {
+ // numbers aren't escaped, nor will they have macros
+ // if m_expandMacros is true, then macros is empty, so this is ok even then
+ value = BibtexHandler::exportText(value, macros);
+ }
+ text_ += QString::fromLatin1(",\n ")
+ + fIt->property(bibtex)
+ + QString::fromLatin1(" = ")
+ + value;
+ }
+ text_ += QString::fromLatin1("\n}\n\n");
+}
+
+#include "bibtexexporter.moc"
diff --git a/src/translators/bibtexexporter.h b/src/translators/bibtexexporter.h
new file mode 100644
index 0000000..dccfde8
--- /dev/null
+++ b/src/translators/bibtexexporter.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef BIBTEXEXPORTER_H
+#define BIBTEXEXPORTER_H
+
+class QCheckBox;
+class KComboBox;
+
+#include "exporter.h"
+
+namespace Tellico {
+ namespace Export {
+
+/**
+ * The Bibtex exporter shows a list of possible Bibtex fields next to a combobox of all
+ * the current attributes in the collection. I had thought about the reverse - having a list
+ * of all the attributes, with comboboxes for each Bibtex field, but I think this way is more obvious.
+ *
+ * @author Robby Stephenson
+ */
+class BibtexExporter : public Exporter {
+Q_OBJECT
+
+public:
+ BibtexExporter();
+
+ virtual bool exec();
+ virtual QString formatString() const;
+ virtual QString fileFilter() const;
+
+ virtual QWidget* widget(QWidget* parent, const char* name=0);
+ virtual void readOptions(KConfig*);
+ virtual void saveOptions(KConfig*);
+
+private:
+ void writeEntryText(QString& text, const Data::FieldVec& field, const Data::Entry& entry,
+ const QString& type, const QString& key);
+
+ bool m_expandMacros;
+ bool m_packageURL;
+ bool m_skipEmptyKeys;
+
+ QWidget* m_widget;
+ QCheckBox* m_checkExpandMacros;
+ QCheckBox* m_checkPackageURL;
+ QCheckBox* m_checkSkipEmpty;
+ KComboBox* m_cbBibtexStyle;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/bibtexhandler.cpp b/src/translators/bibtexhandler.cpp
new file mode 100644
index 0000000..8c88e43
--- /dev/null
+++ b/src/translators/bibtexhandler.cpp
@@ -0,0 +1,319 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "bibtexhandler.h"
+#include "../collections/bibtexcollection.h"
+#include "../entry.h"
+#include "../field.h"
+#include "../collection.h"
+#include "../document.h"
+#include "../filehandler.h"
+#include "../latin1literal.h"
+#include "../tellico_debug.h"
+
+#include <kstandarddirs.h>
+#include <kurl.h>
+#include <kstringhandler.h>
+#include <klocale.h>
+
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qregexp.h>
+#include <qdom.h>
+
+// don't add braces around capital letters by default
+#define TELLICO_BIBTEX_BRACES 0
+
+using Tellico::BibtexHandler;
+
+BibtexHandler::StringListMap* BibtexHandler::s_utf8LatexMap = 0;
+BibtexHandler::QuoteStyle BibtexHandler::s_quoteStyle = BibtexHandler::BRACES;
+const QRegExp BibtexHandler::s_badKeyChars(QString::fromLatin1("[^0-9a-zA-Z-]"));
+
+QStringList BibtexHandler::bibtexKeys(const Data::EntryVec& entries_) {
+ QStringList keys;
+ for(Data::EntryVec::ConstIterator it = entries_.begin(); it != entries_.end(); ++it) {
+ QString s = bibtexKey(it.data());
+ if(!s.isEmpty()) {
+ keys << s;
+ }
+ }
+ return keys;
+}
+
+QString BibtexHandler::bibtexKey(Data::ConstEntryPtr entry_) {
+ if(!entry_ || !entry_->collection() || entry_->collection()->type() != Data::Collection::Bibtex) {
+ return QString::null;
+ }
+
+ const Data::BibtexCollection* c = static_cast<const Data::BibtexCollection*>(entry_->collection().data());
+ Data::FieldPtr f = c->fieldByBibtexName(QString::fromLatin1("key"));
+ if(f) {
+ QString key = entry_->field(f->name());
+ if(!key.isEmpty()) {
+ return key;
+ }
+ }
+
+ QString author;
+ Data::FieldPtr authorField = c->fieldByBibtexName(QString::fromLatin1("author"));
+ if(authorField) {
+ if(authorField->flags() & Data::Field::AllowMultiple) {
+ // grab first author only;
+ QString tmp = entry_->field(authorField->name());
+ author = tmp.section(';', 0, 0);
+ } else {
+ author = entry_->field(authorField->name());
+ }
+ }
+
+ Data::FieldPtr titleField = c->fieldByBibtexName(QString::fromLatin1("title"));
+ QString title;
+ if(titleField) {
+ title = entry_->field(titleField->name());
+ }
+
+ Data::FieldPtr yearField = c->fieldByBibtexName(QString::fromLatin1("year"));
+ QString year;
+ if(yearField) {
+ year = entry_->field(yearField->name());
+ }
+ if(year.isEmpty()) {
+ year = entry_->field(QString::fromLatin1("pub_year"));
+ if(year.isEmpty()) {
+ year = entry_->field(QString::fromLatin1("cr_year"));
+ }
+ }
+ year = year.section(';', 0, 0);
+
+ return bibtexKey(author, title, year);
+}
+
+QString BibtexHandler::bibtexKey(const QString& author_, const QString& title_, const QString& year_) {
+ QString key;
+ // if no comma, take the last word
+ if(!author_.isEmpty()) {
+ if(author_.find(',') == -1) {
+ key += author_.section(' ', -1).lower() + '-';
+ } else {
+ // if there is a comma, take the string up to the first comma
+ key += author_.section(',', 0, 0).lower() + '-';
+ }
+ }
+ QStringList words = QStringList::split(' ', title_);
+ for(QStringList::ConstIterator it = words.begin(); it != words.end(); ++it) {
+ key += (*it).left(1).lower();
+ }
+ key += year_;
+ // bibtex key may only contain [0-9a-zA-Z-]
+ return key.replace(s_badKeyChars, QString::null);
+}
+
+void BibtexHandler::loadTranslationMaps() {
+ QString mapfile = locate("appdata", QString::fromLatin1("bibtex-translation.xml"));
+ if(mapfile.isEmpty()) {
+ return;
+ }
+
+ s_utf8LatexMap = new StringListMap();
+
+ KURL u;
+ u.setPath(mapfile);
+ // no namespace processing
+ QDomDocument dom = FileHandler::readXMLFile(u, false);
+
+ QDomNodeList keyList = dom.elementsByTagName(QString::fromLatin1("key"));
+
+ for(unsigned i = 0; i < keyList.count(); ++i) {
+ QDomNodeList strList = keyList.item(i).toElement().elementsByTagName(QString::fromLatin1("string"));
+ // the strList might have more than one node since there are multiple ways
+ // to represent a character in LaTex.
+ QString s = keyList.item(i).toElement().attribute(QString::fromLatin1("char"));
+ for(unsigned j = 0; j < strList.count(); ++j) {
+ (*s_utf8LatexMap)[s].append(strList.item(j).toElement().text());
+// kdDebug() << "BibtexHandler::loadTranslationMaps - "
+// << s << " = " << strList.item(j).toElement().text() << endl;
+ }
+ }
+}
+
+QString BibtexHandler::importText(char* text_) {
+ if(!s_utf8LatexMap) {
+ loadTranslationMaps();
+ }
+
+ QString str = QString::fromUtf8(text_);
+ for(StringListMap::Iterator it = s_utf8LatexMap->begin(); it != s_utf8LatexMap->end(); ++it) {
+ for(QStringList::Iterator sit = it.data().begin(); sit != it.data().end(); ++sit) {
+ str.replace(*sit, it.key());
+ }
+ }
+
+ // now replace capitalized letters, such as {X}
+ // but since we don't want to turn "... X" into "... {X}" later when exporting
+ // we need to lower-case any capitalized text after the first letter that is
+ // NOT contained in braces
+
+ QRegExp rx(QString::fromLatin1("\\{([A-Z]+)\\}"));
+ rx.setMinimal(true);
+ str.replace(rx, QString::fromLatin1("\\1"));
+
+ return str;
+}
+
+QString BibtexHandler::exportText(const QString& text_, const QStringList& macros_) {
+ if(!s_utf8LatexMap) {
+ loadTranslationMaps();
+ }
+
+ QChar lquote, rquote;
+ switch(s_quoteStyle) {
+ case BRACES:
+ lquote = '{';
+ rquote = '}';
+ break;
+ case QUOTES:
+ lquote = '"';
+ rquote = '"';
+ break;
+ }
+
+ QString text = text_;
+
+ for(StringListMap::Iterator it = s_utf8LatexMap->begin(); it != s_utf8LatexMap->end(); ++it) {
+ text.replace(it.key(), it.data()[0]);
+ }
+
+ if(macros_.isEmpty()) {
+ return lquote + addBraces(text) + rquote;
+ }
+
+// Now, split the text by the character '#', and examine each token to see if it is in
+// the macro list. If it is not, then add left-quote and right-quote around it. If it is, don't
+// change it. Then, in case '#' occurs in a non-macro string, replace any occurrences of '}#{' with '#'
+
+// list of new tokens
+ QStringList list;
+
+// first, split the text
+ QStringList tokens = QStringList::split('#', text, true);
+ for(QStringList::Iterator it = tokens.begin(); it != tokens.end(); ++it) {
+ // check to see if token is a macro
+ if(macros_.findIndex((*it).stripWhiteSpace()) == -1) {
+ // the token is NOT a macro, add braces around whole words and also around capitals
+ list << lquote + addBraces(*it) + rquote;
+ } else {
+ list << *it;
+ }
+ }
+
+ const QChar octo = '#';
+ text = list.join(octo);
+ text.replace(QString(rquote)+octo+lquote, octo);
+
+ return text;
+}
+
+bool BibtexHandler::setFieldValue(Data::EntryPtr entry_, const QString& bibtexField_, const QString& value_) {
+ Data::BibtexCollection* c = static_cast<Data::BibtexCollection*>(entry_->collection().data());
+ Data::FieldPtr field = c->fieldByBibtexName(bibtexField_);
+ if(!field) {
+ // it was the case that the default bibliography did not have a bibtex property for keywords
+ // so a "keywords" field would get created in the imported collection
+ // but the existing collection had a field "keyword" so the values would not get imported
+ // here, check to see if the current collection has a field with the same bibtex name and
+ // use it instead of creating a new one
+ Data::BibtexCollection* existingColl = Data::Document::self()->collection()->type() == Data::Collection::Bibtex
+ ? static_cast<Data::BibtexCollection*>(Data::Document::self()->collection().data())
+ : 0;
+ Data::FieldPtr existingField = existingColl ? existingColl->fieldByBibtexName(bibtexField_) : 0;
+ if(existingField) {
+ field = new Data::Field(*existingField);
+ } else if(value_.length() < 100) {
+ // arbitrarily say if the value has more than 100 chars, then it's a paragraph
+ QString vlower = value_.lower();
+ // special case, try to detect URLs
+ // In qt 3.1, QString::startsWith() is always case-sensitive
+ if(bibtexField_ == Latin1Literal("url")
+ || vlower.startsWith(QString::fromLatin1("http")) // may also be https
+ || vlower.startsWith(QString::fromLatin1("ftp:/"))
+ || vlower.startsWith(QString::fromLatin1("file:/"))
+ || vlower.startsWith(QString::fromLatin1("/"))) { // assume this indicates a local path
+ myDebug() << "BibtexHandler::setFieldValue() - creating a URL field for " << bibtexField_ << endl;
+ field = new Data::Field(bibtexField_, KStringHandler::capwords(bibtexField_), Data::Field::URL);
+ } else {
+ field = new Data::Field(bibtexField_, KStringHandler::capwords(bibtexField_), Data::Field::Line);
+ }
+ field->setCategory(i18n("Unknown"));
+ } else {
+ field = new Data::Field(bibtexField_, KStringHandler::capwords(bibtexField_), Data::Field::Para);
+ }
+ field->setProperty(QString::fromLatin1("bibtex"), bibtexField_);
+ c->addField(field);
+ }
+ // special case keywords, replace commas with semi-colons so they get separated
+ QString value = value_;
+ if(field->property(QString::fromLatin1("bibtex")).startsWith(QString::fromLatin1("keyword"))) {
+ value.replace(',', ';');
+ // special case refbase bibtex export, with multiple keywords fields
+ QString oValue = entry_->field(field);
+ if(!oValue.isEmpty()) {
+ value = oValue + "; " + value;
+ }
+ }
+ return entry_->setField(field, value);
+}
+
+QString& BibtexHandler::cleanText(QString& text_) {
+ // FIXME: need to improve this for removing all Latex entities
+// QRegExp rx(QString::fromLatin1("(?=[^\\\\])\\\\.+\\{"));
+ QRegExp rx(QString::fromLatin1("\\\\.+\\{"));
+ rx.setMinimal(true);
+ text_.replace(rx, QString::null);
+ text_.replace(QRegExp(QString::fromLatin1("[{}]")), QString::null);
+ text_.replace('~', ' ');
+ return text_;
+}
+
+// add braces around capital letters
+QString& BibtexHandler::addBraces(QString& text) {
+#if !TELLICO_BIBTEX_BRACES
+ return text;
+#else
+ int inside = 0;
+ uint l = text.length();
+ // start at first letter, but skip if only the first is capitalized
+ for(uint i = 0; i < l; ++i) {
+ const QChar c = text.at(i);
+ if(inside == 0 && c >= 'A' && c <= 'Z') {
+ uint j = i+1;
+ while(text.at(j) >= 'A' && text.at(j) <= 'Z' && j < l) {
+ ++j;
+ }
+ if(i == 0 && j == 1) {
+ continue; // no need to do anything to first letter
+ }
+ text.insert(i, '{');
+ // now j should be incremented
+ text.insert(j+1, '}');
+ i = j+1;
+ l += 2; // the length changed
+ } else if(c == '{') {
+ ++inside;
+ } else if(c == '}') {
+ --inside;
+ }
+ }
+ return text;
+#endif
+}
diff --git a/src/translators/bibtexhandler.h b/src/translators/bibtexhandler.h
new file mode 100644
index 0000000..87d8bf0
--- /dev/null
+++ b/src/translators/bibtexhandler.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef BIBTEXHANDLER_H
+#define BIBTEXHANDLER_H
+
+class QString;
+class QStringList;
+class QRegExp;
+
+#include "../datavectors.h"
+
+#include <qmap.h>
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class BibtexHandler {
+public:
+ enum QuoteStyle { BRACES=0, QUOTES=1 };
+ static QStringList bibtexKeys(const Data::EntryVec& entries);
+ static QString bibtexKey(Data::ConstEntryPtr entry);
+ static QString importText(char* text);
+ static QString exportText(const QString& text, const QStringList& macros);
+ static bool setFieldValue(Data::EntryPtr entry, const QString& bibtexField, const QString& value);
+ /**
+ * Strips the text of all vestiges of LaTeX.
+ *
+ * @param text A reference to the text
+ * @return A reference to the text
+ */
+ static QString& cleanText(QString& text);
+
+ static QuoteStyle s_quoteStyle;
+
+private:
+ typedef QMap<QString, QStringList> StringListMap;
+
+ static QString bibtexKey(const QString& author, const QString& title, const QString& year);
+ static void loadTranslationMaps();
+ static QString& addBraces(QString& string);
+
+ static StringListMap* s_utf8LatexMap;
+ static const QRegExp s_badKeyChars;
+};
+
+} // end namespace
+#endif
diff --git a/src/translators/bibteximporter.cpp b/src/translators/bibteximporter.cpp
new file mode 100644
index 0000000..2e514d3
--- /dev/null
+++ b/src/translators/bibteximporter.cpp
@@ -0,0 +1,312 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "bibteximporter.h"
+#include "bibtexhandler.h"
+#include "../collections/bibtexcollection.h"
+#include "../entry.h"
+#include "../latin1literal.h"
+#include "../progressmanager.h"
+#include "../filehandler.h"
+#include "../tellico_debug.h"
+
+#include <kapplication.h>
+#include <kconfig.h>
+
+#include <qptrlist.h>
+#include <qregexp.h>
+#include <qlayout.h>
+#include <qvbuttongroup.h>
+#include <qradiobutton.h>
+#include <qwhatsthis.h>
+#include <qtextcodec.h>
+
+using Tellico::Import::BibtexImporter;
+
+BibtexImporter::BibtexImporter(const KURL::List& urls_) : Importer(urls_)
+ , m_coll(0), m_widget(0), m_readUTF8(0), m_readLocale(0), m_cancelled(false) {
+ bt_initialize();
+}
+
+BibtexImporter::BibtexImporter(const QString& text_) : Importer(text_)
+ , m_coll(0), m_widget(0), m_readUTF8(0), m_readLocale(0), m_cancelled(false) {
+ bt_initialize();
+}
+
+BibtexImporter::~BibtexImporter() {
+ bt_cleanup();
+ if(m_readUTF8) {
+ KConfigGroup config(kapp->config(), "Import Options");
+ config.writeEntry("Bibtex UTF8", m_readUTF8->isChecked());
+ }
+}
+
+bool BibtexImporter::canImport(int type) const {
+ return type == Data::Collection::Bibtex;
+}
+
+Tellico::Data::CollPtr BibtexImporter::collection() {
+ if(m_coll) {
+ return m_coll;
+ }
+
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, progressLabel(), true);
+ item.setTotalSteps(urls().count() * 100);
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+ ProgressItem::Done done(this);
+
+ bool useUTF8 = m_widget && m_readUTF8->isChecked();
+
+ m_coll = new Data::BibtexCollection(true);
+
+ int count = 0;
+ // might be importing text only
+ if(!text().isEmpty()) {
+ QString text = this->text();
+ Data::CollPtr coll = readCollection(text, count);
+ if(!coll || coll->entryCount() == 0) {
+ setStatusMessage(i18n("No valid bibtex entries were found"));
+ } else {
+ m_coll->addEntries(coll->entries());
+ }
+ }
+
+ KURL::List urls = this->urls();
+ for(KURL::List::ConstIterator it = urls.begin(); it != urls.end(); ++it, ++count) {
+ if(m_cancelled) {
+ return 0;
+ }
+ if(!(*it).isValid()) {
+ continue;
+ }
+ QString text = FileHandler::readTextFile(*it, false, useUTF8);
+ if(text.isEmpty()) {
+ continue;
+ }
+ Data::CollPtr coll = readCollection(text, count);
+ if(!coll || coll->entryCount() == 0) {
+ setStatusMessage(i18n("No valid bibtex entries were found in file - %1").arg(url().fileName()));
+ continue;
+ }
+ m_coll->addEntries(coll->entries());
+ }
+
+ if(m_cancelled) {
+ return 0;
+ }
+
+ return m_coll;
+}
+
+Tellico::Data::CollPtr BibtexImporter::readCollection(const QString& text, int n) {
+ if(text.isEmpty()) {
+ myDebug() << "BibtexImporter::readCollection() - no text" << endl;
+ return 0;
+ }
+ Data::CollPtr ptr = new Data::BibtexCollection(true);
+ Data::BibtexCollection* c = static_cast<Data::BibtexCollection*>(ptr.data());
+
+ parseText(text); // populates m_nodes
+ if(m_cancelled) {
+ return 0;
+ }
+
+ if(m_nodes.isEmpty()) {
+ return 0;
+ }
+
+ QString str;
+ const uint count = m_nodes.count();
+ const uint stepSize = QMAX(s_stepSize, count/100);
+ const bool showProgress = options() & ImportProgress;
+
+ uint j = 0;
+ for(ASTListIterator it(m_nodes); !m_cancelled && it.current(); ++it, ++j) {
+ // if we're parsing a macro string, comment or preamble, skip it for now
+ if(bt_entry_metatype(it.current()) == BTE_PREAMBLE) {
+ char* preamble = bt_get_text(it.current());
+ if(preamble) {
+ c->setPreamble(QString::fromUtf8(preamble));
+ }
+ continue;
+ }
+
+ if(bt_entry_metatype(it.current()) == BTE_MACRODEF) {
+ char* macro;
+ (void) bt_next_field(it.current(), 0, &macro);
+ // FIXME: replace macros within macro definitions!
+ // lookup lowercase macro in map
+ c->addMacro(m_macros[QString::fromUtf8(macro)], QString::fromUtf8(bt_macro_text(macro, 0, 0)));
+ continue;
+ }
+
+ if(bt_entry_metatype(it.current()) == BTE_COMMENT) {
+ continue;
+ }
+
+ // now we're parsing a regular entry
+ Data::EntryPtr entry = new Data::Entry(ptr);
+
+ str = QString::fromUtf8(bt_entry_type(it.current()));
+// kdDebug() << "entry type: " << str << endl;
+ // text is automatically put into lower-case by btparse
+ BibtexHandler::setFieldValue(entry, QString::fromLatin1("entry-type"), str);
+
+ str = QString::fromUtf8(bt_entry_key(it.current()));
+// kdDebug() << "entry key: " << str << endl;
+ BibtexHandler::setFieldValue(entry, QString::fromLatin1("key"), str);
+
+ char* name;
+ AST* field = 0;
+ while((field = bt_next_field(it.current(), field, &name))) {
+// kdDebug() << "\tfound: " << name << endl;
+// str = QString::fromLatin1(bt_get_text(field));
+ str.truncate(0);
+ AST* value = 0;
+ bt_nodetype type;
+ char* svalue;
+ bool end_macro = false;
+ while((value = bt_next_value(field, value, &type, &svalue))) {
+ switch(type) {
+ case BTAST_STRING:
+ case BTAST_NUMBER:
+ str += BibtexHandler::importText(svalue).simplifyWhiteSpace();
+ end_macro = false;
+ break;
+ case BTAST_MACRO:
+ str += QString::fromUtf8(svalue) + '#';
+ end_macro = true;
+ break;
+ default:
+ break;
+ }
+ }
+ if(end_macro) {
+ // remove last character '#'
+ str.truncate(str.length() - 1);
+ }
+ QString fieldName = QString::fromUtf8(name);
+ if(fieldName == Latin1Literal("author") || fieldName == Latin1Literal("editor")) {
+ str.replace(QRegExp(QString::fromLatin1("\\sand\\s")), QString::fromLatin1("; "));
+ }
+ BibtexHandler::setFieldValue(entry, fieldName, str);
+ }
+
+ ptr->addEntries(entry);
+
+ if(showProgress && j%stepSize == 0) {
+ ProgressManager::self()->setProgress(this, n*100 + 100*j/count);
+ kapp->processEvents();
+ }
+ }
+
+ if(m_cancelled) {
+ ptr = 0;
+ }
+
+ // clean-up
+ for(ASTListIterator it(m_nodes); it.current(); ++it) {
+ bt_free_ast(it.current());
+ }
+
+ return ptr;
+}
+
+void BibtexImporter::parseText(const QString& text) {
+ m_nodes.clear();
+ m_macros.clear();
+
+ ushort bt_options = 0; // ushort is defined in btparse.h
+ boolean ok; // boolean is defined in btparse.h as an int
+
+ // for regular nodes (entries), do NOT convert numbers to strings, do NOT expand macros
+ bt_set_stringopts(BTE_REGULAR, 0);
+ bt_set_stringopts(BTE_MACRODEF, 0);
+// bt_set_stringopts(BTE_PREAMBLE, BTO_CONVERT | BTO_EXPAND);
+
+ QString entry;
+ QRegExp rx(QString::fromLatin1("[{}]"));
+ QRegExp macroName(QString::fromLatin1("@string\\s*\\{\\s*(.*)="), false /*case sensitive*/);
+ macroName.setMinimal(true);
+
+ bool needsCleanup = false;
+ int brace = 0;
+ int startpos = 0;
+ int pos = text.find(rx, 0);
+ while(pos > 0 && !m_cancelled) {
+ if(text[pos] == '{') {
+ ++brace;
+ } else if(text[pos] == '}' && brace > 0) {
+ --brace;
+ }
+ if(brace == 0) {
+ entry = text.mid(startpos, pos-startpos+1).stripWhiteSpace();
+ // All the downstream text processing on the AST node will assume utf-8
+ AST* node = bt_parse_entry_s(const_cast<char*>(entry.utf8().data()),
+ const_cast<char*>(url().fileName().local8Bit().data()),
+ 0, bt_options, &ok);
+ if(ok && node) {
+ if(bt_entry_metatype(node) == BTE_MACRODEF && macroName.search(entry) > -1) {
+ char* macro;
+ (void) bt_next_field(node, 0, &macro);
+ m_macros.insert(QString::fromUtf8(macro), macroName.cap(1).stripWhiteSpace());
+ }
+ m_nodes.append(node);
+ needsCleanup = true;
+ }
+ startpos = pos+1;
+ }
+ pos = text.find(rx, pos+1);
+ }
+ if(needsCleanup) {
+ // clean up some structures
+ bt_parse_entry_s(0, 0, 1, 0, 0);
+ }
+}
+
+void BibtexImporter::slotCancel() {
+ m_cancelled = true;
+}
+
+QWidget* BibtexImporter::widget(QWidget* parent_, const char* name_/*=0*/) {
+ if(m_widget) {
+ return m_widget;
+ }
+
+ m_widget = new QWidget(parent_, name_);
+ QVBoxLayout* l = new QVBoxLayout(m_widget);
+
+ QButtonGroup* box = new QVButtonGroup(i18n("Bibtex Options"), m_widget);
+ m_readUTF8 = new QRadioButton(i18n("Use Unicode (UTF-8) encoding"), box);
+ QWhatsThis::add(m_readUTF8, i18n("Read the imported file in Unicode (UTF-8)."));
+ QString localStr = i18n("Use user locale (%1) encoding").arg(
+ QString::fromLatin1(QTextCodec::codecForLocale()->name()));
+ m_readLocale = new QRadioButton(localStr, box);
+ m_readLocale->setChecked(true);
+ QWhatsThis::add(m_readLocale, i18n("Read the imported file in the local encoding."));
+
+ KConfigGroup config(kapp->config(), "Import Options");
+ bool useUTF8 = config.readBoolEntry("Bibtex UTF8", false);
+ if(useUTF8) {
+ m_readUTF8->setChecked(true);
+ } else {
+ m_readLocale->setChecked(true);
+ }
+
+ l->addWidget(box);
+ l->addStretch(1);
+ return m_widget;
+}
+
+
+#include "bibteximporter.moc"
diff --git a/src/translators/bibteximporter.h b/src/translators/bibteximporter.h
new file mode 100644
index 0000000..c17195b
--- /dev/null
+++ b/src/translators/bibteximporter.h
@@ -0,0 +1,90 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef BIBTEXIMPORTER_H
+#define BIBTEXIMPORTER_H
+
+#include <config.h>
+#include "importer.h"
+#include "../datavectors.h"
+
+extern "C" {
+#ifdef HAVE_LIBBTPARSE
+#include <btparse.h>
+#else
+#include "btparse/btparse.h"
+}
+#endif
+
+#include <qptrlist.h>
+#include <qmap.h>
+
+class QRadioButton;
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ * Bibtex files are used for bibliographies within LaTex. The btparse library is used to
+ * parse the text and generate a @ref BibtexCollection.
+ *
+ * @author Robby Stephenson
+ */
+class BibtexImporter : public Importer {
+Q_OBJECT
+
+public:
+ /**
+ * Initializes the btparse library
+ *
+ * @param url The url of the bibtex file
+ */
+ BibtexImporter(const KURL::List& urls);
+ BibtexImporter(const QString& text);
+ /*
+ * Some cleanup is done for the btparse library
+ */
+ virtual ~BibtexImporter();
+
+ /**
+ * Returns a pointer to a @ref BibtexCollection created on the stack. All entries
+ * in the bibtex file are added, including any preamble, all macro strings, and each entry.
+ *
+ * @return A pointer to a @ref BibtexCollection, or 0 if none can be created.
+ */
+ virtual Data::CollPtr collection();
+ virtual QWidget* widget(QWidget* parent, const char* name=0);
+ virtual bool canImport(int type) const;
+
+public slots:
+ void slotCancel();
+
+private:
+ Data::CollPtr readCollection(const QString& text, int n);
+ void parseText(const QString& text);
+
+ typedef QPtrList<AST> ASTList;
+ typedef QPtrListIterator<AST> ASTListIterator;
+ ASTList m_nodes;
+ QMap<QString, QString> m_macros;
+
+ Data::CollPtr m_coll;
+ QWidget* m_widget;
+ QRadioButton* m_readUTF8;
+ QRadioButton* m_readLocale;
+ bool m_cancelled : 1;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/bibtexmlexporter.cpp b/src/translators/bibtexmlexporter.cpp
new file mode 100644
index 0000000..4a0a4d3
--- /dev/null
+++ b/src/translators/bibtexmlexporter.cpp
@@ -0,0 +1,182 @@
+/*************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include <config.h>
+
+#include "bibtexmlexporter.h"
+#include "bibtexhandler.h"
+#include "../document.h"
+#include "../collections/bibtexcollection.h"
+#include "../latin1literal.h"
+#include "../filehandler.h"
+#include "tellico_xml.h"
+#include "../stringset.h"
+
+#include <klocale.h>
+#include <kdebug.h>
+
+#include <qvbox.h>
+#include <qdom.h>
+#include <qregexp.h>
+#include <qtextcodec.h>
+
+using Tellico::Export::BibtexmlExporter;
+
+QString BibtexmlExporter::formatString() const {
+ return i18n("Bibtexml");
+}
+
+QString BibtexmlExporter::fileFilter() const {
+ return i18n("*.xml|Bibtexml Files (*.xml)") + QChar('\n') + i18n("*|All Files");
+}
+
+bool BibtexmlExporter::exec() {
+ Data::CollPtr c = collection();
+ if(!c || c->type() != Data::Collection::Bibtex) {
+ return false;
+ }
+ const Data::BibtexCollection* coll = static_cast<const Data::BibtexCollection*>(c.data());
+
+// there are some special fields
+// the entry-type specifies the entry type - book, inproceedings, whatever
+ QString typeField;
+// the key specifies the cite-key
+ QString keyField;
+
+ const QString bibtex = QString::fromLatin1("bibtex");
+// keep a list of all the 'ordinary' fields to iterate through later
+ Data::FieldVec fields;
+ Data::FieldVec vec = coll->fields();
+ for(Data::FieldVec::Iterator it = vec.begin(); it != vec.end(); ++it) {
+ QString bibtexField = it->property(bibtex);
+ if(bibtexField == Latin1Literal("entry-type")) {
+ typeField = it->name();
+ } else if(bibtexField == Latin1Literal("key")) {
+ keyField = it->name();
+ } else if(!bibtexField.isEmpty()) {
+ fields.append(it);
+ }
+ }
+
+ QDomImplementation impl;
+ QDomDocumentType doctype = impl.createDocumentType(QString::fromLatin1("file"),
+ QString::null,
+ XML::dtdBibtexml);
+ //default namespace
+ const QString& ns = XML::nsBibtexml;
+
+ QDomDocument dom = impl.createDocument(ns, QString::fromLatin1("file"), doctype);
+
+ // root element
+ QDomElement root = dom.documentElement();
+
+ QString encodeStr = QString::fromLatin1("version=\"1.0\" encoding=\"");
+ if(options() & Export::ExportUTF8) {
+ encodeStr += QString::fromLatin1("UTF-8");
+ } else {
+ encodeStr += QString::fromLatin1(QTextCodec::codecForLocale()->mimeName());
+ }
+ encodeStr += '"';
+
+ // createDocument creates a root node, insert the processing instruction before it
+ dom.insertBefore(dom.createProcessingInstruction(QString::fromLatin1("xml"), encodeStr), root);
+ QString comment = QString::fromLatin1("Generated by Tellico ") + QString::fromLatin1(VERSION);
+ dom.insertBefore(dom.createComment(comment), root);
+
+ Data::ConstFieldPtr field;
+ Data::FieldVec::ConstIterator fIt, end = fields.constEnd();
+ bool format = options() & Export::ExportFormatted;
+
+ StringSet usedKeys;
+ QString type, key, newKey, value, elemName, parElemName;
+ QDomElement btElem, entryElem, parentElem, fieldElem;
+ for(Data::EntryVec::ConstIterator entryIt = entries().begin(); entryIt != entries().end(); ++entryIt) {
+ key = entryIt->field(keyField);
+ if(key.isEmpty()) {
+ key = BibtexHandler::bibtexKey(entryIt.data());
+ }
+ QString newKey = key;
+ char c = 'a';
+ while(usedKeys.has(newKey)) {
+ // duplicate found!
+ newKey = key + c;
+ ++c;
+ }
+ key = newKey;
+ usedKeys.add(key);
+
+ btElem = dom.createElement(QString::fromLatin1("entry"));
+ btElem.setAttribute(QString::fromLatin1("id"), key);
+ root.appendChild(btElem);
+
+ type = entryIt->field(typeField);
+ if(type.isEmpty()) {
+ kdWarning() << "BibtexmlExporter::exec() - the entry for '" << entryIt->title()
+ << "' has no entry-type, skipping it!" << endl;
+ continue;
+ }
+
+ entryElem = dom.createElement(type);
+ btElem.appendChild(entryElem);
+
+ // now iterate over attributes
+ for(fIt = fields.constBegin(); fIt != end; ++fIt) {
+ field = fIt.data();
+ value = entryIt->field(field->name(), format);
+ if(value.isEmpty()) {
+ continue;
+ }
+
+/* Bibtexml has special container elements for titles, authors, editors, and keywords
+ I'm going to ignore the titlelist element for right now. All authors are contained in
+ an authorlist element, editors in an editorlist element, and keywords are in a
+ keywords element, and themselves as a keyword. Also, Bibtexml can format names
+ similar to docbook, with first, middle, last, etc elements. I'm going to ignore that
+ for now, too.*/
+ elemName = field->property(bibtex);
+ // split text for author, editor, and keywords
+ if(elemName == Latin1Literal("author") ||
+ elemName == Latin1Literal("editor") ||
+ elemName == Latin1Literal("keywords")) {
+ if(elemName == Latin1Literal("author")) {
+ parElemName = QString::fromLatin1("authorlist");
+ } else if(elemName == Latin1Literal("editor")) {
+ parElemName = QString::fromLatin1("editorlist");
+ } else { // keywords
+ parElemName = QString::fromLatin1("keywords");
+ elemName = QString::fromLatin1("keyword");
+ }
+
+ parentElem = dom.createElement(parElemName);
+ const QStringList values = entryIt->fields(field->name(), false);
+ for(QStringList::ConstIterator it = values.begin(); it != values.end(); ++it) {
+ fieldElem = dom.createElement(elemName);
+ fieldElem.appendChild(dom.createTextNode(*it));
+ parentElem.appendChild(fieldElem);
+ }
+ if(parentElem.hasChildNodes()) {
+ entryElem.appendChild(parentElem);
+ }
+ } else {
+ fieldElem = dom.createElement(elemName);
+ fieldElem.appendChild(dom.createTextNode(value));
+ entryElem.appendChild(fieldElem);
+ }
+ }
+ }
+
+ return FileHandler::writeTextURL(url(), dom.toString(),
+ options() & ExportUTF8, options() & Export::ExportForce);
+}
+
+#include "bibtexmlexporter.moc"
diff --git a/src/translators/bibtexmlexporter.h b/src/translators/bibtexmlexporter.h
new file mode 100644
index 0000000..8f63a55
--- /dev/null
+++ b/src/translators/bibtexmlexporter.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef BIBTEXMLEXPORTER_H
+#define BIBTEXMLEXPORTER_H
+
+#include "exporter.h"
+
+namespace Tellico {
+ namespace Export {
+
+/**
+ * @author Robby Stephenson
+ */
+class BibtexmlExporter : public Exporter {
+Q_OBJECT
+
+public:
+ BibtexmlExporter() : Exporter() {}
+
+ virtual bool exec();
+ virtual QString formatString() const;
+ virtual QString fileFilter() const;
+
+ // no options
+ virtual QWidget* widget(QWidget*, const char*) { return 0; }
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/bibtexmlimporter.cpp b/src/translators/bibtexmlimporter.cpp
new file mode 100644
index 0000000..2feb2f2
--- /dev/null
+++ b/src/translators/bibtexmlimporter.cpp
@@ -0,0 +1,163 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "bibtexmlimporter.h"
+#include "tellico_xml.h"
+#include "bibtexhandler.h"
+#include "../collections/bibtexcollection.h"
+#include "../field.h"
+#include "../entry.h"
+#include "../latin1literal.h"
+#include "../tellico_strings.h"
+#include "../progressmanager.h"
+#include "../tellico_debug.h"
+
+#include <kapplication.h>
+
+using Tellico::Import::BibtexmlImporter;
+
+bool BibtexmlImporter::canImport(int type) const {
+ return type == Data::Collection::Bibtex;
+}
+
+Tellico::Data::CollPtr BibtexmlImporter::collection() {
+ if(!m_coll) {
+ loadDomDocument();
+ }
+ return m_coll;
+}
+
+void BibtexmlImporter::loadDomDocument() {
+ QDomElement root = domDocument().documentElement();
+ if(root.isNull() || root.localName() != Latin1Literal("file")) {
+ setStatusMessage(i18n(errorLoad).arg(url().fileName()));
+ return;
+ }
+
+ const QString& ns = XML::nsBibtexml;
+ m_coll = new Data::BibtexCollection(true);
+
+ QDomNodeList entryelems = root.elementsByTagNameNS(ns, QString::fromLatin1("entry"));
+// kdDebug() << "BibtexmlImporter::loadDomDocument - found " << entryelems.count() << " entries" << endl;
+
+ const uint count = entryelems.count();
+ const uint stepSize = QMAX(s_stepSize, count/100);
+ const bool showProgress = options() & ImportProgress;
+
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, progressLabel(), true);
+ item.setTotalSteps(count);
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+ ProgressItem::Done done(this);
+
+ for(uint j = 0; !m_cancelled && j < entryelems.count(); ++j) {
+ readEntry(entryelems.item(j));
+
+ if(showProgress && j%stepSize == 0) {
+ ProgressManager::self()->setProgress(this, j);
+ kapp->processEvents();
+ }
+ } // end entry loop
+}
+
+void BibtexmlImporter::readEntry(const QDomNode& entryNode_) {
+ QDomNode node = const_cast<QDomNode&>(entryNode_);
+
+ Data::EntryPtr entry = new Data::Entry(m_coll);
+
+/* The Bibtexml format looks like
+ <entry id="...">
+ <book>
+ <authorlist>
+ <author>...</author>
+ </authorlist>
+ <publisher>...</publisher> */
+
+ QString type = node.firstChild().toElement().tagName();
+ entry->setField(QString::fromLatin1("entry-type"), type);
+ QString id = node.toElement().attribute(QString::fromLatin1("id"));
+ entry->setField(QString::fromLatin1("bibtex-key"), id);
+
+ QString name, value;
+ // field values are first child of first child of entry node
+ for(QDomNode n = node.firstChild().firstChild(); !n.isNull(); n = n.nextSibling()) {
+ // n could be something like authorlist, with multiple authors, or just
+ // a plain element with a single text child...
+ // second case first
+ if(n.firstChild().isText()) {
+ name = n.toElement().tagName();
+ value = n.toElement().text();
+ } else {
+ // is either titlelist, authorlist, editorlist, or keywords
+ QString parName = n.toElement().tagName();
+ if(parName == Latin1Literal("titlelist")) {
+ for(QDomNode n2 = node.firstChild(); !n2.isNull(); n2 = n2.nextSibling()) {
+ name = n2.toElement().tagName();
+ value = n2.toElement().text();
+ if(!name.isEmpty() && !value.isEmpty()) {
+ BibtexHandler::setFieldValue(entry, name, value.simplifyWhiteSpace());
+ }
+ }
+ name.truncate(0);
+ value.truncate(0);
+ } else {
+ name = n.firstChild().toElement().tagName();
+ if(name == Latin1Literal("keyword")) {
+ name = QString::fromLatin1("keywords");
+ }
+ value.truncate(0);
+ for(QDomNode n2 = n.firstChild(); !n2.isNull(); n2 = n2.nextSibling()) {
+ // n2 could have first, middle, lastname elements...
+ if(name == Latin1Literal("person")) {
+ QStringList names;
+ names << QString::fromLatin1("initials") << QString::fromLatin1("first")
+ << QString::fromLatin1("middle") << QString::fromLatin1("prelast")
+ << QString::fromLatin1("last") << QString::fromLatin1("lineage");
+ for(QStringList::ConstIterator it = names.begin(); it != names.end(); ++it) {
+ QDomNodeList list = n2.toElement().elementsByTagName(*it);
+ if(list.count() > 1) {
+ value += list.item(0).toElement().text();
+ }
+ if(*it != names.last()) {
+ value += QString::fromLatin1(" ");
+ }
+ }
+ }
+ for(QDomNode n3 = n2.firstChild(); !n3.isNull(); n3 = n3.nextSibling()) {
+ if(n3.isElement()) {
+ value += n3.toElement().text();
+ } else if(n3.isText()) {
+ value += n3.toText().data();
+ }
+ if(n3 != n2.lastChild()) {
+ value += QString::fromLatin1(" ");
+ }
+ }
+ if(n2 != n.lastChild()) {
+ value += QString::fromLatin1("; ");
+ }
+ }
+ }
+ }
+ if(!name.isEmpty() && !value.isEmpty()) {
+ BibtexHandler::setFieldValue(entry, name, value.simplifyWhiteSpace());
+ }
+ }
+
+ m_coll->addEntries(entry);
+}
+
+void BibtexmlImporter::slotCancel() {
+ m_cancelled = true;
+}
+
+#include "bibtexmlimporter.moc"
diff --git a/src/translators/bibtexmlimporter.h b/src/translators/bibtexmlimporter.h
new file mode 100644
index 0000000..826ea30
--- /dev/null
+++ b/src/translators/bibtexmlimporter.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef BIBTEXMLIMPORTER_H
+#define BIBTEXMLIMPORTER_H
+
+#include "xmlimporter.h"
+#include "../datavectors.h"
+
+class QDomNode;
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ *@author Robby Stephenson
+ */
+class BibtexmlImporter : public XMLImporter {
+Q_OBJECT
+
+public:
+ /**
+ */
+ BibtexmlImporter(const KURL& url) : Import::XMLImporter(url), m_coll(0), m_cancelled(false) {}
+
+ /**
+ */
+ virtual Data::CollPtr collection();
+ virtual bool canImport(int type) const;
+
+public slots:
+ void slotCancel();
+
+private:
+ void loadDomDocument();
+ void readEntry(const QDomNode& entryNode);
+
+ Data::CollPtr m_coll;
+ bool m_cancelled : 1;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/btparse/Makefile.am b/src/translators/btparse/Makefile.am
new file mode 100644
index 0000000..84af63b
--- /dev/null
+++ b/src/translators/btparse/Makefile.am
@@ -0,0 +1,18 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+if !USE_LIBBTPARSE
+
+noinst_LIBRARIES = libbtparse.a
+
+AM_CPPFLAGS = $(all_includes)
+
+libbtparse_a_METASOURCES = AUTO
+
+libbtparse_a_SOURCES = bibtex_ast.c bibtex.c err.c ast.c scan.c util.c lex_auxiliary.c parse_auxiliary.c format_name.c string_util.c tex_tree.c names.c modify.c traversal.c sym.c macros.c error.c postprocess.c input.c init.c
+
+endif
+
+EXTRA_DIST = btparse.h init.c stdpccts.h attrib.h lex_auxiliary.h error.h parse_auxiliary.h prototypes.h tokens.h mode.h input.c postprocess.c error.c macros.c sym.h sym.c bt_debug.h traversal.c modify.c names.c my_alloca.h tex_tree.c string_util.c format_name.c antlr.h ast.h btconfig.h dlgdef.h parse_auxiliary.c lex_auxiliary.c util.c scan.c dlgauto.h ast.c err.h err.c bibtex.c bibtex_ast.c
+
+####### kdevelop will overwrite this part!!! (end)############
+
+KDE_OPTIONS = noautodist
diff --git a/src/translators/btparse/antlr.h b/src/translators/btparse/antlr.h
new file mode 100644
index 0000000..f52aba6
--- /dev/null
+++ b/src/translators/btparse/antlr.h
@@ -0,0 +1,561 @@
+/* antlr.h
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+#ifndef ANTLR_H
+#define ANTLR_H
+
+#include "btconfig.h"
+
+/*
+ * Define all of the stack setup and manipulation of $i, #i variables.
+ *
+ * Notes:
+ * The type 'Attrib' must be defined before entry into this .h file.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+typedef int ANTLRTokenType;
+typedef unsigned char SetWordType;
+
+typedef char ANTLRChar;
+
+ /* G u e s s S t u f f */
+
+#ifdef ZZCAN_GUESS
+#ifndef ZZINF_LOOK
+#define ZZINF_LOOK
+#endif
+#endif
+
+#ifdef ZZCAN_GUESS
+typedef struct _zzjmp_buf {
+ jmp_buf state;
+ } zzjmp_buf;
+#endif
+
+
+/* can make this a power of 2 for more efficient lookup */
+#ifndef ZZLEXBUFSIZE
+#define ZZLEXBUFSIZE 2000
+#endif
+
+#define zzOvfChk \
+ if ( zzasp <= 0 ) \
+ { \
+ fprintf(stderr, zzStackOvfMsg, __FILE__, __LINE__); \
+ exit(PCCTS_EXIT_FAILURE); \
+ }
+
+#ifndef ZZA_STACKSIZE
+#define ZZA_STACKSIZE 400
+#endif
+#ifndef ZZAST_STACKSIZE
+#define ZZAST_STACKSIZE 400
+#endif
+
+#ifndef zzfailed_pred
+#define zzfailed_pred(_p) \
+ fprintf(stderr, "semantic error; failed predicate: '%s'\n",_p)
+#endif
+
+#ifdef LL_K
+#define LOOKAHEAD \
+ int zztokenLA[LL_K]; \
+ char zztextLA[LL_K][ZZLEXBUFSIZE]; \
+ int zzlap = 0, zzlabase=0; /* labase only used for DEMAND_LOOK */
+#else
+#define LOOKAHEAD \
+ int zztoken;
+#endif
+
+#ifndef zzcr_ast
+#define zzcr_ast(ast,attr,tok,text)
+#endif
+
+#ifdef DEMAND_LOOK
+#define DemandLookData int zzdirty=1;
+#else
+#define DemandLookData
+#endif
+
+ /* S t a t e S t u f f */
+
+#ifdef ZZCAN_GUESS
+#define zzGUESS_BLOCK zzantlr_state zzst; int zzrv;
+#define zzGUESS zzsave_antlr_state(&zzst); \
+ zzguessing = 1; \
+ zzrv = setjmp(zzguess_start.state);
+#define zzGUESS_FAIL longjmp(zzguess_start.state, 1)
+#define zzGUESS_DONE zzrestore_antlr_state(&zzst);
+#define zzNON_GUESS_MODE if ( !zzguessing )
+#define zzGuessData \
+ zzjmp_buf zzguess_start; \
+ int zzguessing;
+#else
+#define zzGUESS_BLOCK
+#define zzGUESS
+#define zzGUESS_FAIL
+#define zzGUESS_DONE
+#define zzNON_GUESS_MODE
+#define zzGuessData
+#endif
+
+typedef struct _zzantlr_state {
+#ifdef ZZCAN_GUESS
+ zzjmp_buf guess_start;
+ int guessing;
+#endif
+ int asp;
+ int ast_sp;
+#ifdef ZZINF_LOOK
+ int inf_lap; /* not sure we need to save this one */
+ int inf_labase;
+ int inf_last;
+#endif
+#ifdef DEMAND_LOOK
+ int dirty;
+#endif
+
+#ifdef LL_K
+ int tokenLA[LL_K];
+ char textLA[LL_K][ZZLEXBUFSIZE];
+ int lap;
+ int labase;
+#else
+ int token;
+ char text[ZZLEXBUFSIZE];
+#endif
+ } zzantlr_state;
+
+
+ /* I n f i n i t e L o o k a h e a d */
+
+
+#ifdef ZZINF_LOOK
+#define InfLookData \
+ int *zzinf_tokens; \
+ char **zzinf_text; \
+ char *zzinf_text_buffer; \
+ int *zzinf_line; \
+ int zzinf_labase; \
+ int zzinf_last;
+#else
+#define InfLookData
+#endif
+
+#ifdef ZZINF_LOOK
+
+#ifndef ZZINF_DEF_TEXT_BUFFER_SIZE
+#define ZZINF_DEF_TEXT_BUFFER_SIZE 20000
+#endif
+#ifndef ZZINF_DEF_TOKEN_BUFFER_SIZE
+#define ZZINF_DEF_TOKEN_BUFFER_SIZE 2000
+#endif
+/* WARNING!!!!!!
+ * ZZINF_BUFFER_TEXT_CHUNK_SIZE must be > sizeof(text) largest possible token.
+ */
+#ifndef ZZINF_BUFFER_TEXT_CHUNK_SIZE
+#define ZZINF_BUFFER_TEXT_CHUNK_SIZE 5000
+#endif
+#ifndef ZZINF_BUFFER_TOKEN_CHUNK_SIZE
+#define ZZINF_BUFFER_TOKEN_CHUNK_SIZE 1000
+#endif
+
+#if ZZLEXBUFSIZE > ZZINF_BUFFER_TEXT_CHUNK_SIZE
+#define ZZINF_BUFFER_TEXT_CHUNK_SIZE ZZLEXBUFSIZE+5
+#endif
+
+/* make inf_look user-access macros */
+#ifdef LL_K
+#define ZZINF_LA_VALID(i) (((zzinf_labase+i-1)-LL_K+1) <= zzinf_last)
+#define ZZINF_LA(i) zzinf_tokens[(zzinf_labase+i-1)-LL_K+1]
+#define ZZINF_LATEXT(i) zzinf_text[(zzinf_labase+i-1)-LL_K+1]
+/* #define ZZINF_LINE(i) zzinf_line[(zzinf_labase+i-1)-LL_K+1]*/
+#else
+#define ZZINF_LA_VALID(i) (((zzinf_labase+i-1)) <= zzinf_last)
+#define ZZINF_LA(i) zzinf_tokens[(zzinf_labase+i-1)]
+#define ZZINF_LATEXT(i) zzinf_text[(zzinf_labase+i-1)]
+#endif
+
+#define inf_zzgettok _inf_zzgettok()
+extern void _inf_zzgettok();
+
+#endif /* ZZINF_LOOK */
+
+
+#ifdef LL_K
+
+#define ANTLR_INFO \
+ Attrib zzempty_attr(void) {static Attrib a; return a;} \
+ Attrib zzconstr_attr(int _tok, char *_text)\
+ {Attrib a; zzcr_attr((&a),_tok,_text); return a;} \
+ int zzasp=ZZA_STACKSIZE; \
+ char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \
+ Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \
+ InfLookData \
+ zzGuessData
+
+#else
+
+#define ANTLR_INFO \
+ Attrib zzempty_attr(void) {static Attrib a; return a;} \
+ Attrib zzconstr_attr(int _tok, char *_text)\
+ {Attrib a; zzcr_attr((&a),_tok,_text); return a;} \
+ int zzasp=ZZA_STACKSIZE; \
+ char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \
+ Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \
+ InfLookData \
+ zzGuessData
+
+#endif /* LL_k */
+
+
+#ifdef ZZINF_LOOK
+
+#ifdef LL_K
+#ifdef DEMAND_LOOK
+#define zzPrimeLookAhead {zzdirty=LL_K; zzlap = zzlabase = 0;}
+#else
+#define zzPrimeLookAhead {zzlap = zzlabase = 0; zzfill_inf_look();\
+ {int _i; for(_i=1;_i<=LL_K; _i++) \
+ {zzCONSUME;} zzlap = zzlabase = 0;}}
+#endif
+
+#else /* LL_K */
+
+#ifdef DEMAND_LOOK
+#define zzPrimeLookAhead zzfill_inf_look(); zzdirty=1
+#else
+#define zzPrimeLookAhead zzfill_inf_look(); inf_zzgettok
+
+#endif
+#endif /* LL_K */
+
+#else /* ZZINF_LOOK */
+
+#ifdef LL_K
+#ifdef DEMAND_LOOK
+#define zzPrimeLookAhead {zzdirty=LL_K; zzlap = zzlabase = 0;}
+#else
+#define zzPrimeLookAhead {int _i; zzlap = 0; for(_i=1;_i<=LL_K; _i++) \
+ {zzCONSUME;} zzlap = 0;}
+#endif
+
+#else
+
+#ifdef DEMAND_LOOK
+#define zzPrimeLookAhead zzdirty=1
+#else
+#define zzPrimeLookAhead zzgettok()
+#endif
+#endif /* LL_K */
+
+#endif /* ZZINF_LOOK */
+
+
+#ifdef LL_K
+#define zzenterANTLRs(s) \
+ zzlextext = &(zztextLA[0][0]); zzrdstr( s ); zzPrimeLookAhead;
+#define zzenterANTLRf(f) \
+ zzlextext = &(zztextLA[0][0]); zzrdfunc( f ); zzPrimeLookAhead;
+#define zzenterANTLR(f) \
+ zzlextext = &(zztextLA[0][0]); zzrdstream( f ); zzPrimeLookAhead;
+#ifdef ZZINF_LOOK
+#define zzleaveANTLR(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
+#define zzleaveANTLRf(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
+#define zzleaveANTLRs(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
+#else
+#define zzleaveANTLR(f)
+#define zzleaveANTLRf(f)
+#define zzleaveANTLRs(f)
+#endif
+
+#else
+
+#define zzenterANTLRs(s) \
+ {static char zztoktext[ZZLEXBUFSIZE]; \
+ zzlextext = zztoktext; zzrdstr( s ); zzPrimeLookAhead;}
+#define zzenterANTLRf(f) \
+ {static char zztoktext[ZZLEXBUFSIZE]; \
+ zzlextext = zztoktext; zzrdfunc( f ); zzPrimeLookAhead;}
+#define zzenterANTLR(f) \
+ {static char zztoktext[ZZLEXBUFSIZE]; \
+ zzlextext = zztoktext; zzrdstream( f ); zzPrimeLookAhead;}
+#ifdef ZZINF_LOOK
+#define zzleaveANTLR(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
+#define zzleaveANTLRf(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
+#define zzleaveANTLRs(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line);
+#else
+#define zzleaveANTLR(f)
+#define zzleaveANTLRf(f)
+#define zzleaveANTLRs(f)
+#endif
+
+#endif
+
+#define ANTLR(st, f) zzbufsize = ZZLEXBUFSIZE; \
+ zzenterANTLR(f); \
+ st; ++zzasp; \
+ zzleaveANTLR(f);
+
+#define ANTLRm(st, f, _m) zzbufsize = ZZLEXBUFSIZE; \
+ zzmode(_m); \
+ zzenterANTLR(f); \
+ st; ++zzasp; \
+ zzleaveANTLR(f);
+
+#define ANTLRf(st, f) zzbufsize = ZZLEXBUFSIZE; \
+ zzenterANTLRf(f); \
+ st; ++zzasp; \
+ zzleaveANTLRf(f);
+
+#define ANTLRs(st, s) zzbufsize = ZZLEXBUFSIZE; \
+ zzenterANTLRs(s); \
+ st; ++zzasp; \
+ zzleaveANTLRs(s);
+
+#ifdef LL_K
+#define zztext (&(zztextLA[zzlap][0]))
+#else
+#define zztext zzlextext
+#endif
+
+
+ /* A r g u m e n t A c c e s s */
+
+#define zzaCur (zzaStack[zzasp])
+#define zzaRet (*zzaRetPtr)
+#define zzaArg(v,n) zzaStack[v-n]
+#define zzMakeAttr { zzNON_GUESS_MODE {zzOvfChk; --zzasp; zzcr_attr(&(zzaStack[zzasp]),LA(1),LATEXT(1));}}
+#ifdef zzdef0
+#define zzMake0 { zzOvfChk; --zzasp; zzdef0(&(zzaStack[zzasp]));}
+#else
+#define zzMake0 { zzOvfChk; --zzasp;}
+#endif
+#define zzaPush(_v) { zzOvfChk; zzaStack[--zzasp] = _v;}
+#ifndef zzd_attr
+#define zzREL(t) zzasp=(t); /* Restore state of stack */
+#else
+#define zzREL(t) for (; zzasp<(t); zzasp++) \
+ { zzd_attr(&(zzaStack[zzasp])); }
+#endif
+
+#define zzsetmatch(_es) \
+ if ( !_zzsetmatch(_es, &zzBadText, &zzMissText, &zzMissTok, &zzBadTok, &zzMissSet) ) goto fail;
+#define zzsetmatch_wsig(_es, handler) \
+ if ( !_zzsetmatch_wsig(_es) ) {_signal=MismatchedToken; goto handler;}
+
+extern int _zzsetmatch(SetWordType *, char **, char **, int *, int *, SetWordType **);
+extern int _zzsetmatch_wsig(SetWordType *);
+
+#define zzmatch(_t) \
+ if ( !_zzmatch(_t, &zzBadText, &zzMissText, &zzMissTok, &zzBadTok, &zzMissSet) ) goto fail;
+#define zzmatch_wsig(_t,handler) \
+ if ( !_zzmatch_wsig(_t) ) {_signal=MismatchedToken; goto handler;}
+
+extern int _zzmatch(int, const char **, const char **, int *, int *, SetWordType **);
+extern int _zzmatch_wsig(int);
+
+#define zzmatch_wdfltsig(_t,_f) \
+ if ( !_zzmatch_wdfltsig(_t,_f) ) _signal=MismatchedToken;
+#define zzsetmatch_wdfltsig(tw,tt,wf) \
+ if ( !_zzsetmatch_wdfltsig(tw,tt,wf) ) _signal=MismatchedToken;
+
+extern int _zzmatch_wdfltsig(int, SetWordType *);
+extern int _zzsetmatch_wdfltsig(SetWordType *tokensWanted,
+ int tokenTypeOfSet,
+ SetWordType *whatFollows);
+
+#ifdef GENAST
+#define zzRULE Attrib *zzaRetPtr = &(zzaStack[zzasp-1]); \
+ SetWordType *zzMissSet=NULL; int zzMissTok=0; \
+ int zzBadTok=0; const char *zzBadText=""; \
+ int zzErrk=1; \
+ const char *zzMissText=""; zzASTVars
+#else
+#define zzRULE Attrib *zzaRetPtr = &(zzaStack[zzasp-1]); \
+ int zzBadTok=0; const char *zzBadText=""; \
+ int zzErrk=1; \
+ SetWordType *zzMissSet=NULL; int zzMissTok=0; const char *zzMissText=""
+#endif
+
+#ifdef GENAST
+#define zzBLOCK(i) int i = zzasp - 1; int zztsp = zzast_sp
+#define zzEXIT(i) zzREL(i); zzastREL; zzNON_GUESS_MODE { zzastPush(*_root); }
+#define zzLOOP(i) zzREL(i); zzastREL
+#else
+#define zzBLOCK(i) int i = zzasp - 1
+#define zzEXIT(i) zzREL(i)
+#define zzLOOP(i) zzREL(i)
+#endif
+
+#ifdef LL_K
+
+#ifdef DEMAND_LOOK
+#define LOOK(_k) {int i,stop=_k-(LL_K-zzdirty); for (i=1; i<=stop; i++) \
+ zzCONSUME;}
+#define zzCONSUME {zzgettok(); zzdirty--; \
+ zzlap = (zzlap+1)&(LL_K-1); \
+ zzlextext = &(zztextLA[zzlap][0]);}
+#else
+#ifdef ZZINF_LOOK
+#define zzCONSUME {inf_zzgettok; \
+ zzlap = (zzlap+1)&(LL_K-1); \
+ zzlextext = &(zztextLA[zzlap][0]); \
+ }
+#else
+#define zzCONSUME {zzgettok(); \
+ zzlap = (zzlap+1)&(LL_K-1); \
+ zzlextext = &(zztextLA[zzlap][0]);}
+#endif /* ZZINF_LOOK */
+#endif /* DEMAND_LOOK */
+
+#else /* LL_K */
+
+#ifdef DEMAND_LOOK
+#define LOOK(_k) if ( zzdirty) zzCONSUME;
+#ifdef ZZINF_LOOK
+#define zzCONSUME inf_zzgettok; zzdirty=0;
+#else
+#define zzCONSUME zzgettok(); zzdirty=0;
+#endif /* ZZINF_LOOK */
+
+#else /* DEMAND_LOOK */
+
+#ifdef ZZINF_LOOK
+#define zzCONSUME inf_zzgettok
+#else
+#define zzCONSUME zzgettok();
+#endif
+
+#endif /* DEMAND_LOOK */
+
+#endif /* LL_K */
+
+#ifdef LL_K
+#define NLA zztokenLA[zzlap&(LL_K-1)] /* --> next LA */
+#define NLATEXT zztextLA[zzlap&(LL_K-1)] /* --> next text of LA */
+#ifdef DEMAND_LOOK
+#define LA(i) zztokenLA[(zzlabase+(i)-1)&(LL_K-1)]
+#define LATEXT(i) (&(zztextLA[(zzlabase+(i)-1)&(LL_K-1)][0]))
+#else
+#define LA(i) zztokenLA[(zzlap+(i)-1)&(LL_K-1)]
+#define LATEXT(i) (&(zztextLA[(zzlap+(i)-1)&(LL_K-1)][0]))
+#endif
+#else
+#define NLA zztoken
+#define NLATEXT zztext
+#define LA(i) zztoken
+#define LATEXT(i) zztext
+#endif
+
+
+ /* S t a n d a r d S i g n a l s */
+
+#define NoSignal 0
+#define MismatchedToken 1
+#define NoViableAlt 2
+#define NoSemViableAlt 3
+
+
+ /* F u n c t i o n T r a c i n g */
+
+#ifndef zzTRACEIN
+#define zzTRACEIN(r) fprintf(stderr, "enter rule \"%s\"\n", r);
+#endif
+#ifndef zzTRACEOUT
+#define zzTRACEOUT(r) fprintf(stderr, "exit rule \"%s\"\n", r);
+#endif
+
+#ifdef ZZWCHAR_T
+#define zzchar_t unsigned wchar_t
+#else
+#define zzchar_t unsigned char
+#endif
+
+ /* E x t e r n D e f s */
+
+extern Attrib zzempty_attr(void);
+extern Attrib zzconstr_attr(int, char *);
+extern void zzsyn(const char *, int, char *, SetWordType *, int, int, const char *);
+extern int zzset_el(unsigned, SetWordType *);
+extern int zzset_deg(SetWordType *);
+extern void zzedecode(SetWordType *);
+extern void zzFAIL(int k, ...);
+extern void zzresynch(SetWordType *, SetWordType);
+extern void zzsave_antlr_state(zzantlr_state *);
+extern void zzrestore_antlr_state(zzantlr_state *);
+extern void zzfill_inf_look(void);
+#ifdef EXCEPTION_HANDLING
+extern void zzdflthandlers(int, int *);
+#endif
+
+ /* G l o b a l V a r i a b l e s */
+
+/* Define a parser; user should do a "#parser myname" in their grammar file */
+/*extern struct pccts_parser zzparser;*/
+
+extern const char *zztokens[];
+#ifdef LL_K
+extern int zztokenLA[];
+extern char zztextLA[][ZZLEXBUFSIZE];
+extern int zzlap;
+extern int zzlabase;
+#else
+extern int zztoken;
+#endif
+
+extern char zzStackOvfMsg[];
+extern int zzasp;
+extern Attrib zzaStack[];
+#ifdef ZZINF_LOOK
+extern int *zzinf_tokens;
+extern char **zzinf_text;
+extern char *zzinf_text_buffer;
+extern int *zzinf_line;
+extern int zzinf_labase;
+extern int zzinf_last;
+#endif
+#ifdef DEMAND_LOOK
+extern int zzdirty;
+#endif
+#ifdef ZZCAN_GUESS
+extern int zzguessing;
+extern zzjmp_buf zzguess_start;
+#endif
+
+/* Define global veriables that refer to values exported by the scanner.
+ * These declarations duplicate those in dlgdef.h, but are needed
+ * if ANTLR is not to generate a .dlg file (-gx); PS, this is a hack.
+ */
+extern zzchar_t *zzlextext; /* text of most recently matched token */
+extern int zzbufsize; /* how long zzlextext is */
+
+#endif
diff --git a/src/translators/btparse/ast.c b/src/translators/btparse/ast.c
new file mode 100644
index 0000000..d433f79
--- /dev/null
+++ b/src/translators/btparse/ast.c
@@ -0,0 +1,227 @@
+/* Abstract syntax tree manipulation functions
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "ast.h"
+#include "attrib.h"
+#include "antlr.h"
+
+/* ensure that tree manipulation variables are current after a rule
+ * reference
+ */
+void
+zzlink(AST **_root, AST **_sibling, AST **_tail)
+{
+ if ( *_sibling == NULL ) return;
+ if ( *_root == NULL ) *_root = *_sibling;
+ else if ( *_root != *_sibling ) (*_root)->down = *_sibling;
+ if ( *_tail==NULL ) *_tail = *_sibling;
+ while ( (*_tail)->right != NULL ) *_tail = (*_tail)->right;
+}
+
+AST *
+zzastnew(void)
+{
+ AST *p = (AST *) calloc(1, sizeof(AST));
+ if ( p == NULL ) fprintf(stderr,"%s(%d): cannot allocate AST node\n",__FILE__,__LINE__);
+ return p;
+}
+
+/* add a child node to the current sibling list */
+void
+zzsubchild(AST **_root, AST **_sibling, AST **_tail)
+{
+ AST *n;
+ zzNON_GUESS_MODE {
+ n = zzastnew();
+#ifdef DEMAND_LOOK
+ zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0));
+#else
+ zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1));
+#endif
+ zzastPush( n );
+ if ( *_tail != NULL ) (*_tail)->right = n;
+ else {
+ *_sibling = n;
+ if ( *_root != NULL ) (*_root)->down = *_sibling;
+ }
+ *_tail = n;
+ if ( *_root == NULL ) *_root = *_sibling;
+ }
+}
+
+/* make a new AST node. Make the newly-created
+ * node the root for the current sibling list. If a root node already
+ * exists, make the newly-created node the root of the current root.
+ */
+void
+zzsubroot(AST **_root, AST **_sibling, AST **_tail)
+{
+ AST *n;
+ zzNON_GUESS_MODE {
+ n = zzastnew();
+#ifdef DEMAND_LOOK
+ zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0));
+#else
+ zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1));
+#endif
+ zzastPush( n );
+ if ( *_root != NULL )
+ if ( (*_root)->down == *_sibling ) *_sibling = *_tail = *_root;
+ *_root = n;
+ (*_root)->down = *_sibling;
+ }
+}
+
+/* Apply function to root then each sibling
+ * example: print tree in child-sibling LISP-format (AST has token field)
+ *
+ * void show(tree)
+ * AST *tree;
+ * {
+ * if ( tree == NULL ) return;
+ * printf(" %s", zztokens[tree->token]);
+ * }
+ *
+ * void before() { printf(" ("); }
+ * void after() { printf(" )"); }
+ *
+ * LISPdump() { zzpre_ast(tree, show, before, after); }
+ *
+ */
+void
+zzpre_ast(
+ AST *tree,
+ void (*func)(AST *), /* apply this to each tree node */
+ void (*before)(AST *), /* apply this to root of subtree before preordering it */
+ void (*after)(AST *)) /* apply this to root of subtree after preordering it */
+{
+ while ( tree!= NULL )
+ {
+ if ( tree->down != NULL ) (*before)(tree);
+ (*func)(tree);
+ zzpre_ast(tree->down, func, before, after);
+ if ( tree->down != NULL ) (*after)(tree);
+ tree = tree->right;
+ }
+}
+
+/* free all AST nodes in tree; apply func to each before freeing */
+void
+zzfree_ast(AST *tree)
+{
+ if ( tree == NULL ) return;
+ zzfree_ast( tree->down );
+ zzfree_ast( tree->right );
+ zztfree( tree );
+}
+
+/* build a tree (root child1 child2 ... NULL)
+ * If root is NULL, simply make the children siblings and return ptr
+ * to 1st sibling (child1). If root is not single node, return NULL.
+ *
+ * Siblings that are actually siblins lists themselves are handled
+ * correctly. For example #( NULL, #( NULL, A, B, C), D) results
+ * in the tree ( NULL A B C D ).
+ *
+ * Requires at least two parameters with the last one being NULL. If
+ * both are NULL, return NULL.
+ */
+AST *zztmake(AST *rt, ...)
+{
+ va_list ap;
+ register AST *child, *sibling=NULL, *tail, *w;
+ AST *root;
+
+ va_start(ap, rt);
+ root = rt;
+
+ if ( root != NULL )
+ if ( root->down != NULL ) return NULL;
+ child = va_arg(ap, AST *);
+ while ( child != NULL )
+ {
+ for (w=child; w->right!=NULL; w=w->right) {;} /* find end of child */
+ if ( sibling == NULL ) {sibling = child; tail = w;}
+ else {tail->right = child; tail = w;}
+ child = va_arg(ap, AST *);
+ }
+ if ( root==NULL ) root = sibling;
+ else root->down = sibling;
+ va_end(ap);
+ return root;
+}
+
+/* tree duplicate */
+AST *
+zzdup_ast(AST *t)
+{
+ AST *u;
+
+ if ( t == NULL ) return NULL;
+ u = zzastnew();
+ *u = *t;
+#ifdef zzAST_DOUBLE
+ u->up = NULL; /* set by calling invocation */
+ u->left = NULL;
+#endif
+ u->right = zzdup_ast(t->right);
+ u->down = zzdup_ast(t->down);
+#ifdef zzAST_DOUBLE
+ if ( u->right!=NULL ) u->right->left = u;
+ if ( u->down!=NULL ) u->down->up = u;
+#endif
+ return u;
+}
+
+void
+zztfree(AST *t)
+{
+#ifdef zzd_ast
+ zzd_ast( t );
+#endif
+ free( t );
+}
+
+#ifdef zzAST_DOUBLE
+/*
+ * Set the 'up', and 'left' pointers of all nodes in 't'.
+ * Initial call is double_link(your_tree, NULL, NULL).
+ */
+void
+zzdouble_link(AST *t, AST *left, AST *up)
+{
+ if ( t==NULL ) return;
+ t->left = left;
+ t->up = up;
+ zzdouble_link(t->down, NULL, t);
+ zzdouble_link(t->right, t, up);
+}
+#endif
diff --git a/src/translators/btparse/ast.h b/src/translators/btparse/ast.h
new file mode 100644
index 0000000..59622ec
--- /dev/null
+++ b/src/translators/btparse/ast.h
@@ -0,0 +1,99 @@
+/* Abstract syntax tree
+ *
+ * Macros, definitions
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+
+#ifndef ZZAST_H
+#define ZZAST_H
+
+#define zzastOvfChk \
+ if ( zzast_sp <= 0 ) \
+ { \
+ fprintf(stderr, zzStackOvfMsg, __FILE__, __LINE__); \
+ exit(PCCTS_EXIT_FAILURE); \
+ }
+
+#ifndef USER_DEFINED_AST
+#ifndef AST_FIELDS
+#define AST_FIELDS
+#endif
+
+typedef struct _ast {
+ struct _ast *right, *down;
+#ifdef zzAST_DOUBLE
+ struct _ast *left, *up;
+#endif
+ AST_FIELDS
+} AST;
+
+#else
+
+#ifdef zzAST_DOUBLE
+#define AST_REQUIRED_FIELDS struct _ast *right, *down, *left, *up;
+#else
+#define AST_REQUIRED_FIELDS struct _ast *right, *down;
+#endif
+
+#endif
+
+
+/* N o d e a c c e s s m a c r o s */
+#define zzchild(t) (((t)==NULL)?NULL:(t->down))
+#define zzsibling(t) (((t)==NULL)?NULL:(t->right))
+
+
+/* define global variables needed by #i stack */
+#define zzASTgvars \
+ AST *zzastStack[ZZAST_STACKSIZE]; \
+ int zzast_sp = ZZAST_STACKSIZE;
+
+#define zzASTVars AST *_ast = NULL, *_sibling = NULL, *_tail = NULL
+#define zzSTR ( (_tail==NULL)?(&_sibling):(&(_tail->right)) )
+#define zzastCur (zzastStack[zzast_sp])
+#define zzastArg(i) (zzastStack[zztsp-i])
+#define zzastPush(p) zzastOvfChk; zzastStack[--zzast_sp] = p;
+#define zzastDPush --zzast_sp
+#define zzastMARK zztsp=zzast_sp; /* Save state of stack */
+#define zzastREL zzast_sp=zztsp; /* Return state of stack */
+#define zzrm_ast {zzfree_ast(*_root); _tail = _sibling = (*_root)=NULL;}
+
+extern int zzast_sp;
+extern AST *zzastStack[];
+
+void zzlink(AST **, AST **, AST **);
+void zzsubchild(AST **, AST **, AST **);
+void zzsubroot(AST **, AST **, AST **);
+void zzpre_ast(AST *, void (*)(), void (*)(), void (*)());
+void zzfree_ast(AST *);
+AST *zztmake(AST *, ...);
+AST *zzdup_ast(AST *);
+void zztfree(AST *);
+void zzdouble_link(AST *, AST *, AST *);
+AST *zzastnew(void);
+#endif
diff --git a/src/translators/btparse/attrib.h b/src/translators/btparse/attrib.h
new file mode 100644
index 0000000..6a3cecf
--- /dev/null
+++ b/src/translators/btparse/attrib.h
@@ -0,0 +1,35 @@
+/* ------------------------------------------------------------------------
+@NAME : attrib.h
+@DESCRIPTION: Definition of the Attrib type needed by the PCCTS-
+ generated parser.
+@CREATED : Summer 1996, Greg Ward
+@MODIFIED :
+@VERSION : $Id: attrib.h,v 1.3 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+
+#ifndef ATTRIB_H
+#define ATTRIB_H
+
+/*
+ * Defining Attrib this way (as opposed to making it a pointer to a struct)
+ * avoid the expense of allocating/deallocating a structure for each token;
+ * this way, PCCTS statically allocates the whole stack once and that's
+ * it. (Of course, the stack is four times bigger than it would have been
+ * otherwise.)
+ */
+
+typedef struct {
+ int line;
+ int offset;
+ int token;
+ char *text;
+} Attrib;
+
+#endif /* ATTRIB_H */
diff --git a/src/translators/btparse/bibtex.c b/src/translators/btparse/bibtex.c
new file mode 100644
index 0000000..c922803
--- /dev/null
+++ b/src/translators/btparse/bibtex.c
@@ -0,0 +1,312 @@
+/*
+ * A n t l r T r a n s l a t i o n H e a d e r
+ *
+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994
+ * Purdue University Electrical Engineering
+ * With AHPCRC, University of Minnesota
+ * ANTLR Version 1.33
+ */
+#include <stdio.h>
+#define ANTLR_VERSION 133
+
+#define ZZCOL
+#define USER_ZZSYN
+
+#include "btconfig.h"
+#include "btparse.h"
+#include "attrib.h"
+#include "lex_auxiliary.h"
+#include "error.h"
+#include "parse_auxiliary.h"
+/*#include "my_dmalloc.h"*/
+
+extern char * InputFilename; /* for zzcr_ast call in pccts/ast.c */
+#define GENAST
+
+#include "ast.h"
+
+#define zzSET_SIZE 4
+#include "antlr.h"
+#include "tokens.h"
+#include "dlgdef.h"
+#include "mode.h"
+#ifndef PURIFY
+#define PURIFY(r,s)
+#endif
+#include "ast.c"
+zzASTgvars
+
+ANTLR_INFO
+
+void
+bibfile(AST**_root)
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ AST *last; (*_root) = NULL;
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (LA(1)==AT) ) {
+ _ast = NULL; entry(&_ast);
+ /* a little creative forestry... */
+ if ((*_root) == NULL)
+ (*_root) = zzastArg(1);
+ else
+ last->right = zzastArg(1);
+ last = zzastArg(1);
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd1, 0x1);
+ }
+}
+
+void
+entry(AST**_root)
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ bt_metatype metatype;
+ zzmatch(AT); zzCONSUME;
+ zzmatch(NAME); zzsubroot(_root, &_sibling, &_tail);
+
+ metatype = entry_metatype();
+ zzastArg(1)->nodetype = BTAST_ENTRY;
+ zzastArg(1)->metatype = metatype;
+ zzCONSUME;
+
+ body(zzSTR, metatype ); zzlink(_root, &_sibling, &_tail);
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd1, 0x2);
+ }
+}
+
+void
+body(AST**_root, bt_metatype metatype )
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ if ( (LA(1)==STRING) ) {
+ if (!(metatype == BTE_COMMENT )) {zzfailed_pred(" metatype == BTE_COMMENT ");}
+ zzmatch(STRING); zzsubchild(_root, &_sibling, &_tail);
+ zzastArg(1)->nodetype = BTAST_STRING;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==ENTRY_OPEN) ) {
+ zzmatch(ENTRY_OPEN); zzCONSUME;
+ contents(zzSTR, metatype ); zzlink(_root, &_sibling, &_tail);
+ zzmatch(ENTRY_CLOSE); zzCONSUME;
+ }
+ else {zzFAIL(1,zzerr1,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd1, 0x4);
+ }
+}
+
+void
+contents(AST**_root, bt_metatype metatype )
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ if ( (setwd1[LA(1)]&0x8)&&(metatype == BTE_REGULAR /* || metatype == BTE_MODIFY */ ) ) {
+ if (!(metatype == BTE_REGULAR /* || metatype == BTE_MODIFY */ )) {zzfailed_pred(" metatype == BTE_REGULAR /* || metatype == BTE_MODIFY */ ");}
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==NAME) ) {
+ zzmatch(NAME); zzsubchild(_root, &_sibling, &_tail); zzCONSUME;
+ }
+ else {
+ if ( (LA(1)==NUMBER) ) {
+ zzmatch(NUMBER); zzsubchild(_root, &_sibling, &_tail); zzCONSUME;
+ }
+ else {zzFAIL(1,zzerr2,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzastArg(1)->nodetype = BTAST_KEY;
+ zzmatch(COMMA); zzCONSUME;
+ fields(zzSTR); zzlink(_root, &_sibling, &_tail);
+ }
+ else {
+ if ( (setwd1[LA(1)]&0x10)&&(metatype == BTE_MACRODEF ) ) {
+ if (!(metatype == BTE_MACRODEF )) {zzfailed_pred(" metatype == BTE_MACRODEF ");}
+ fields(zzSTR); zzlink(_root, &_sibling, &_tail);
+ }
+ else {
+ if ( (setwd1[LA(1)]&0x20)&&(metatype == BTE_PREAMBLE ) ) {
+ if (!(metatype == BTE_PREAMBLE )) {zzfailed_pred(" metatype == BTE_PREAMBLE ");}
+ value(zzSTR); zzlink(_root, &_sibling, &_tail);
+ }
+ else {zzFAIL(1,zzerr3,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd1, 0x40);
+ }
+}
+
+void
+fields(AST**_root)
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ if ( (LA(1)==NAME) ) {
+ field(zzSTR); zzlink(_root, &_sibling, &_tail);
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ if ( (LA(1)==COMMA) ) {
+ zzmatch(COMMA); zzCONSUME;
+ fields(zzSTR); zzlink(_root, &_sibling, &_tail);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ }
+ else {
+ if ( (LA(1)==ENTRY_CLOSE) ) {
+ }
+ else {zzFAIL(1,zzerr4,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd1, 0x80);
+ }
+}
+
+void
+field(AST**_root)
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ zzmatch(NAME); zzsubroot(_root, &_sibling, &_tail);
+ zzastArg(1)->nodetype = BTAST_FIELD; check_field_name (zzastArg(1));
+ zzCONSUME;
+
+ zzmatch(EQUALS); zzCONSUME;
+ value(zzSTR); zzlink(_root, &_sibling, &_tail);
+
+#if DEBUG > 1
+ printf ("field: fieldname = %p (%s)\n"
+ " first val = %p (%s)\n",
+ zzastArg(1)->text, zzastArg(1)->text, zzastArg(2)->text, zzastArg(2)->text);
+#endif
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd2, 0x1);
+ }
+}
+
+void
+value(AST**_root)
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ simple_value(zzSTR); zzlink(_root, &_sibling, &_tail);
+ {
+ zzBLOCK(zztasp2);
+ zzMake0;
+ {
+ while ( (LA(1)==HASH) ) {
+ zzmatch(HASH); zzCONSUME;
+ simple_value(zzSTR); zzlink(_root, &_sibling, &_tail);
+ zzLOOP(zztasp2);
+ }
+ zzEXIT(zztasp2);
+ }
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd2, 0x2);
+ }
+}
+
+void
+simple_value(AST**_root)
+{
+ zzRULE;
+ zzBLOCK(zztasp1);
+ zzMake0;
+ {
+ if ( (LA(1)==STRING) ) {
+ zzmatch(STRING); zzsubchild(_root, &_sibling, &_tail);
+ zzastArg(1)->nodetype = BTAST_STRING;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==NUMBER) ) {
+ zzmatch(NUMBER); zzsubchild(_root, &_sibling, &_tail);
+ zzastArg(1)->nodetype = BTAST_NUMBER;
+ zzCONSUME;
+
+ }
+ else {
+ if ( (LA(1)==NAME) ) {
+ zzmatch(NAME); zzsubchild(_root, &_sibling, &_tail);
+ zzastArg(1)->nodetype = BTAST_MACRO;
+ zzCONSUME;
+
+ }
+ else {zzFAIL(1,zzerr5,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}
+ }
+ }
+ zzEXIT(zztasp1);
+ return;
+fail:
+ zzEXIT(zztasp1);
+ zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText);
+ zzresynch(setwd2, 0x4);
+ }
+}
diff --git a/src/translators/btparse/bibtex_ast.c b/src/translators/btparse/bibtex_ast.c
new file mode 100644
index 0000000..354cefb
--- /dev/null
+++ b/src/translators/btparse/bibtex_ast.c
@@ -0,0 +1,63 @@
+/* ------------------------------------------------------------------------
+@NAME : bibtex_ast.c
+@DESCRIPTION: Data and functions for internal display/manipulation of AST
+ nodes. (Stuff for external consumption, and for processing
+ whole trees, is to be found in traversal.c.)
+@GLOBALS :
+@CREATED : 1997/08/12, Greg Ward
+@MODIFIED :
+@VERSION : $Id: bibtex_ast.c,v 1.6 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+
+/*#include "bt_config.h"*/
+#include "btparse.h"
+#include "prototypes.h"
+/*#include "my_dmalloc.h"*/
+
+
+const char *nodetype_names[] =
+{
+ "bogus", "entry", "key", "field", "string", "number", "macro"
+};
+
+
+static void dump (AST *root, int depth)
+{
+ AST *cur;
+
+ if (root == NULL)
+ {
+ printf ("[empty]\n");
+ return;
+ }
+
+ cur = root;
+ while (cur != NULL)
+ {
+ printf ("%*s[%s]: ", 2*depth, "", nodetype_names[cur->nodetype]);
+ if (cur->text != NULL)
+ printf ("(%s)\n", cur->text);
+ else
+ printf ("(null)\n");
+
+ if (cur->down != NULL)
+ dump (cur->down, depth+1);
+ cur = cur->right;
+ }
+}
+
+
+void dump_ast (char *msg, AST *root)
+{
+ if (msg != NULL)
+ printf (msg);
+ dump (root, 0);
+ printf ("\n");
+}
diff --git a/src/translators/btparse/bt_debug.h b/src/translators/btparse/bt_debug.h
new file mode 100644
index 0000000..913ae1a
--- /dev/null
+++ b/src/translators/btparse/bt_debug.h
@@ -0,0 +1,38 @@
+/* ------------------------------------------------------------------------
+@NAME : bt_debug.h
+@DESCRIPTION: Defines various macros needed for compile-time selection
+ of debugging code.
+@GLOBALS :
+@CREATED :
+@MODIFIED :
+@VERSION : $Id: bt_debug.h,v 1.2 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+
+#ifndef BT_DEBUG_H
+#define BT_DEBUG_H
+
+/*
+ * DEBUG is the debug level -- an integer, defaults to 0
+ * DBG_ACTION is a macro to conditionally execute a bit of code --
+ * must have compiled with DEBUG true, and the debug level
+ * must be >= `level' (the macro argument)
+ */
+
+#ifndef DEBUG
+# define DEBUG 0
+#endif
+
+#if DEBUG
+# define DBG_ACTION(level,action) if (DEBUG >= level) { action; }
+#else
+# define DBG_ACTION(level,action)
+#endif
+
+#endif /* BT_DEBUG_H */
diff --git a/src/translators/btparse/btconfig.h b/src/translators/btparse/btconfig.h
new file mode 100644
index 0000000..7405825
--- /dev/null
+++ b/src/translators/btparse/btconfig.h
@@ -0,0 +1,220 @@
+#ifndef BTPARSE_CONFIG_H
+#define BTPARSE_CONFIG_H
+/*
+ * config.h (for ANTLR, DLG, and SORCERER)
+ *
+ * This is a simple configuration file that doesn't have config stuff
+ * in it, but it's a start.
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * Used by PCCTS 1.33 (SORCERER 1.00B11 and up)
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+
+/* This file knows about the following ``environments''
+ UNIX (default)
+ DOS (use #define PC)
+ MAC (use #define MPW; has a few things for THINK C, Metrowerks)
+ */
+
+/*
+* Define PC32 if in a 32-bit PC environment (e.g. extended DOS or Win32).
+* The macros tested here are defined by Watcom, Microsoft, Borland,
+* and djgpp, respectively, when they are used as 32-bit compilers.
+* Users of these compilers *must* be sure to define PC in their
+* makefiles for this to work correctly.
+*/
+#ifdef PC
+# if (defined(__WATCOM__) || defined(_WIN32) || defined(__WIN32__) || \
+ defined(__GNUC__) || defined(__GNUG__))
+# ifndef PC32
+# define PC32
+# endif
+# endif
+#endif
+
+#ifdef PC
+#define ATOKEN_H "AToken.h"
+#define ATOKPTR_H "ATokPtr.h"
+#define ATOKPTR_C "ATokPtr.cpp"
+#define ATOKENBUFFER_H "ATokBuf.h"
+#define ATOKENBUFFER_C "ATokBuf.cpp"
+#define ATOKENSTREAM_H "ATokStr.h"
+#define APARSER_H "AParser.h"
+#define APARSER_C "AParser.cpp"
+#define ASTBASE_H "ASTBase.h"
+#define ASTBASE_C "ASTBase.cpp"
+#define PCCTSAST_C "PCCTSAST.cpp"
+#define LIST_C "List.cpp"
+#define DLEXERBASE_H "DLexBase.h"
+#define DLEXERBASE_C "DLexBase.cpp"
+#define DLEXER_C "DLexer.cpp"
+#define STREESUPPORT_C "STreeSup.C"
+#else
+#define ATOKEN_H "AToken.h"
+#define ATOKPTR_H "ATokPtr.h"
+#define ATOKPTR_C "ATokPtr.cpp"
+#define ATOKENBUFFER_H "ATokenBuffer.h"
+#define ATOKENBUFFER_C "ATokenBuffer.cpp"
+#define ATOKENSTREAM_H "ATokenStream.h"
+#define APARSER_H "AParser.h"
+#define APARSER_C "AParser.cpp"
+#define ASTBASE_H "ASTBase.h"
+#define ASTBASE_C "ASTBase.cpp"
+#define PCCTSAST_C "PCCTSAST.cpp"
+#define LIST_C "List.cpp"
+#define DLEXERBASE_H "DLexerBase.h"
+#define DLEXERBASE_C "DLexerBase.cpp"
+#define DLEXER_C "DLexer.cpp"
+#define STREESUPPORT_C "STreeSupport.cpp"
+#endif
+
+/* SORCERER Stuff */
+#ifdef PC
+#define STPARSER_H "STreePar.h"
+#define STPARSER_C "STreePar.C"
+#else
+#define STPARSER_H "STreeParser.h"
+#define STPARSER_C "STreeParser.cpp"
+#endif
+
+#ifdef MPW
+#define CPP_FILE_SUFFIX ".cp"
+#define CPP_FILE_SUFFIX_NO_DOT "cp"
+#define OBJ_FILE_SUFFIX ".o"
+#else
+#ifdef PC
+#define CPP_FILE_SUFFIX ".cpp"
+#define CPP_FILE_SUFFIX_NO_DOT "cpp"
+#define OBJ_FILE_SUFFIX ".obj"
+#else
+#define CPP_FILE_SUFFIX ".cpp"
+#define CPP_FILE_SUFFIX_NO_DOT "cpp"
+#define OBJ_FILE_SUFFIX ".o"
+#endif
+#endif
+
+/* User may redefine how line information looks */
+#define LineInfoFormatStr "# %d \"%s\"\n"
+
+#ifdef MPW /* Macintosh Programmer's Workshop */
+#define ErrHdr "File \"%s\"; Line %d #"
+#else
+#define ErrHdr "%s, line %d:"
+#endif
+
+
+/* must assume old K&R cpp here, can't use #if defined(..)... */
+
+#ifdef MPW
+#define TopDirectory ":"
+#define DirectorySymbol ":"
+#define OutputDirectoryOption "Directory where all output files should go (default=\":\")"
+#else
+#ifdef PC
+#define TopDirectory "."
+#define DirectorySymbol "\\"
+#define OutputDirectoryOption "Directory where all output files should go (default=\".\")"
+#else
+#define TopDirectory "."
+#define DirectorySymbol "/"
+#define OutputDirectoryOption "Directory where all output files should go (default=\".\")"
+#endif
+#endif
+
+#ifdef MPW
+
+/* Make sure we have prototypes for all functions under MPW */
+
+#include <string.h>
+#include <stdlib.h>
+#include <CursorCtl.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void fsetfileinfo (char *filename, unsigned long newcreator, unsigned long newtype);
+#ifdef __cplusplus
+}
+#endif
+
+/* File creators for various popular development environments */
+
+#define MAC_FILE_CREATOR 'MPS ' /* MPW Text files */
+#if 0
+#define MAC_FILE_CREATOR 'KAHL' /* THINK C/Symantec C++ Text files */
+#endif
+#if 0
+#define MAC_FILE_CREATOR 'MMCC' /* Metrowerks C/C++ Text files */
+#endif
+
+#endif
+
+#ifdef MPW
+#define DAWDLE SpinCursor(1)
+#else
+#define DAWDLE
+#endif
+
+
+/*
+ * useless definitions of special_inits() and special_fopen_actions()
+ * deleted -- GPW 1997/09/06
+ */
+
+/* Define usable bits for set.c stuff */
+#define BytesPerWord sizeof(unsigned)
+#define WORDSIZE (sizeof(unsigned)*8)
+#define LogWordSize (WORDSIZE==16?4:5)
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifdef VAXC
+#define PCCTS_EXIT_SUCCESS 1
+#define PCCTS_EXIT_FAILURE 0
+#define zzDIE return 0;
+#define zzDONE return 1;
+
+#else /* !VAXC */
+
+#define PCCTS_EXIT_SUCCESS 0
+#define PCCTS_EXIT_FAILURE 1
+#define zzDIE return 1;
+#define zzDONE return 0;
+
+#endif
+
+#ifdef USER_ZZMODE_STACK
+# ifndef ZZSTACK_MAX_MODE
+# define ZZSTACK_MAX_MODE 32
+# endif
+# define ZZMAXSTK (ZZSTACK_MAX_MODE * 2)
+#endif
+
+#endif
diff --git a/src/translators/btparse/btparse.h b/src/translators/btparse/btparse.h
new file mode 100644
index 0000000..841d3ee
--- /dev/null
+++ b/src/translators/btparse/btparse.h
@@ -0,0 +1,378 @@
+/* ------------------------------------------------------------------------
+@NAME : btparse.h
+@DESCRIPTION: Declarations and types for users of the btparse library.
+
+ (Actually, btparse.h is generated from btparse.h.in by
+ the `configure' script, in order to automatically determine
+ the appropriate values of HAVE_USHORT and HAVE_BOOLEAN.)
+@GLOBALS :
+@CALLS :
+@CREATED : 1997/01/19, Greg Ward
+@MODIFIED :
+@VERSION : $Id: btparse.h.in,v 1.35 1999/12/28 18:23:17 greg Exp $
+@COPYRIGHT : Copyright (c) 1996-97 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+#ifndef BTPARSE_H
+#define BTPARSE_H
+
+#include <sys/types.h> /* probably supplies 'ushort' */
+#include <stdio.h>
+
+#include "config.h" /* not btparse's config.h but Tellico's */
+
+/*
+ * Here we attempt to define HAVE_USHORT if a typdef for `ushort' appears
+ * in <sys/types.h>. The detective work is actually done by the
+ * `configure' script, so if compilation fails because of duplicate
+ * definitions of `ushort', that's a bug in `configure' -- please tell me
+ * about it!
+ */
+
+#ifndef HAVE_USHORT
+# define HAVE_USHORT 0
+#endif
+
+#if ! HAVE_USHORT /* needed for various bitmaps */
+typedef unsigned short ushort;
+#endif
+
+
+/* Likewise for boolean. */
+
+#ifndef HAVE_BOOLEAN
+# define HAVE_BOOLEAN 0
+#endif
+
+#if ! HAVE_BOOLEAN
+typedef int boolean;
+#endif
+
+#ifndef TRUE
+# define TRUE 1
+# define FALSE 0
+#endif
+
+#ifndef HAVE_STRLWR
+# define HAVE_STRLWR 0
+#endif
+
+#ifndef HAVE_STRUPR
+# define HAVE_STRUPR 0
+#endif
+
+
+/* Parsing (and post-processing) options */
+
+#define BTO_CONVERT 1 /* convert numbers to strings? */
+#define BTO_EXPAND 2 /* expand macros? */
+#define BTO_PASTE 4 /* paste substrings together? */
+#define BTO_COLLAPSE 8 /* collapse whitespace? */
+
+#define BTO_NOSTORE 16
+
+#define BTO_FULL (BTO_CONVERT | BTO_EXPAND | BTO_PASTE | BTO_COLLAPSE)
+#define BTO_MACRO (BTO_CONVERT | BTO_EXPAND | BTO_PASTE)
+#define BTO_MINIMAL 0
+
+#define BTO_STRINGMASK (BTO_CONVERT | BTO_EXPAND | BTO_PASTE | BTO_COLLAPSE)
+
+#define BT_VALID_NAMEPARTS "fvlj"
+#define BT_MAX_NAMEPARTS 4
+
+typedef enum
+{
+ BTE_UNKNOWN,
+ BTE_REGULAR,
+ BTE_COMMENT,
+ BTE_PREAMBLE,
+ BTE_MACRODEF
+/*
+ BTE_ALIAS,
+ BTE_MODIFY
+*/
+} bt_metatype;
+
+#define NUM_METATYPES ((int) BTE_MACRODEF + 1)
+
+typedef enum
+{
+ BTAST_BOGUS, /* to detect uninitialized nodes */
+ BTAST_ENTRY,
+ BTAST_KEY,
+ BTAST_FIELD,
+ BTAST_STRING,
+ BTAST_NUMBER,
+ BTAST_MACRO
+} bt_nodetype;
+
+typedef enum
+{
+ BTN_FIRST, BTN_VON, BTN_LAST, BTN_JR, BTN_NONE
+} bt_namepart;
+
+typedef enum
+{
+ BTJ_MAYTIE, /* "discretionary" tie between words */
+ BTJ_SPACE, /* force a space between words */
+ BTJ_FORCETIE, /* force a tie (~ in TeX) */
+ BTJ_NOTHING /* nothing between words */
+} bt_joinmethod;
+
+
+#define USER_DEFINED_AST 1
+
+#define zzcr_ast(ast,attr,tok,txt) \
+{ \
+ (ast)->filename = InputFilename; \
+ (ast)->line = (attr)->line; \
+ (ast)->offset = (attr)->offset; \
+ (ast)->text = strdup ((attr)->text); \
+}
+
+#define zzd_ast(ast) \
+/* printf ("zzd_ast: free'ing ast node with string %p (%s)\n", \
+ (ast)->text, (ast)->text); */ \
+ if ((ast)->text != NULL) free ((ast)->text);
+
+
+#ifdef USER_DEFINED_AST
+typedef struct _ast
+{
+ struct _ast *right, *down;
+ char * filename;
+ int line;
+ int offset;
+ bt_nodetype nodetype;
+ bt_metatype metatype;
+ char * text;
+} AST;
+#endif /* USER_DEFINED_AST */
+
+
+typedef struct
+{
+ /*
+ * `string' is the string that has been split; items[0] ...
+ * items[num_items-1] are pointers into `string', or NULL for empty
+ * substrings. Note that `string' is actually a copy of the string
+ * passed in to bt_split_list() with NULs inserted between substrings.
+ */
+
+ char * string;
+ int num_items;
+ char ** items;
+} bt_stringlist;
+
+
+typedef struct
+{
+ bt_stringlist * tokens; /* flat list of all tokens in name */
+ char ** parts[BT_MAX_NAMEPARTS]; /* each elt. is list of pointers */
+ /* into `tokens->string' */
+ int part_len[BT_MAX_NAMEPARTS]; /* length in tokens */
+} bt_name;
+
+
+typedef struct tex_tree_s
+{
+ char * start;
+ int len;
+ struct tex_tree_s
+ * child,
+ * next;
+} bt_tex_tree;
+
+
+typedef struct
+{
+ /* These determine the order (and presence) of parts in the name. */
+ int num_parts;
+ bt_namepart parts[BT_MAX_NAMEPARTS];
+
+ /*
+ * These lists are always in the order of the bt_namepart enum -- *not*
+ * dependent on the particular order of parts the user specified! (This
+ * will make it a bit harder if I ever allow more than one occurrence of
+ * a part in a format; since I don't allow that, I'm not [yet] worried
+ * about it!)
+ */
+ const char * pre_part[BT_MAX_NAMEPARTS];
+ char * post_part[BT_MAX_NAMEPARTS];
+ char * pre_token[BT_MAX_NAMEPARTS];
+ const char * post_token[BT_MAX_NAMEPARTS];
+ boolean abbrev[BT_MAX_NAMEPARTS];
+ bt_joinmethod join_tokens[BT_MAX_NAMEPARTS];
+ bt_joinmethod join_part[BT_MAX_NAMEPARTS];
+} bt_name_format;
+
+
+typedef enum
+{
+ BTERR_NOTIFY, /* notification about next action */
+ BTERR_CONTENT, /* warning about the content of a record */
+ BTERR_LEXWARN, /* warning in lexical analysis */
+ BTERR_USAGEWARN, /* warning about library usage */
+ BTERR_LEXERR, /* error in lexical analysis */
+ BTERR_SYNTAX, /* error in parser */
+ BTERR_USAGEERR, /* fatal error in library usage */
+ BTERR_INTERNAL /* my fault */
+} bt_errclass;
+
+typedef enum
+{
+ BTACT_NONE, /* do nothing on error */
+ BTACT_CRASH, /* call exit(1) */
+ BTACT_ABORT /* call abort() */
+} bt_erraction;
+
+typedef struct
+{
+ bt_errclass errclass;
+ char * filename;
+ int line;
+ const char * item_desc;
+ int item;
+ char * message;
+} bt_error;
+
+typedef void (*bt_err_handler) (bt_error *);
+
+
+#if defined(__cplusplus__) || defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* Function prototypes */
+
+/*
+ * First, we might need a prototype for strdup() (because the zzcr_ast
+ * macro uses it, and that macro is used in pccts/ast.c -- which I don't
+ * want to modify if I can help it, because it's someone else's code).
+ * This is to accomodate AIX, where including <string.h> apparently doesn't
+ * declare strdup() (reported by Reiner Schlotte
+ * <schlotte@geo.palmod.uni-bremen.de>), and compiling bibtex.c (which
+ * includes pccts/ast.c) crashes because of this (yes, yes, I know it
+ * should just be a warning -- I don't know what's going on there!).
+ *
+ * Unfortunately, this duplicates code in bt_config.h -- I can't include
+ * bt_config.h here, because this header must be freestanding; I don't want
+ * to include bt_config.h in pccts/ast.c, because I don't want to touch the
+ * PCCTS code if I can help it; but I don't want every source file that
+ * uses strdup() to have to include btparse.h. Hence the duplication.
+ * Yuck.
+ */
+#ifndef HAVE_STRDUP_DECL
+# define HAVE_STRDUP_DECL 0
+#endif
+#if !HAVE_STRDUP_DECL
+extern char *strdup (const char *s);
+#endif
+
+
+/* init.c */
+void bt_initialize (void);
+void bt_free_ast (AST *ast);
+void bt_cleanup (void);
+
+/* input.c */
+void bt_set_stringopts (bt_metatype metatype, ushort options);
+AST * bt_parse_entry_s (char * entry_text,
+ char * filename,
+ int line,
+ ushort options,
+ boolean * status);
+AST * bt_parse_entry (FILE * infile,
+ char * filename,
+ ushort options,
+ boolean * status);
+AST * bt_parse_file (char * filename,
+ ushort options,
+ boolean * overall_status);
+
+/* postprocess.c */
+void bt_postprocess_string (char * s, ushort options);
+char * bt_postprocess_value (AST * value, ushort options, boolean replace);
+char * bt_postprocess_field (AST * field, ushort options, boolean replace);
+void bt_postprocess_entry (AST * entry, ushort options);
+
+/* error.c */
+void bt_reset_error_counts (void);
+int bt_get_error_count (bt_errclass errclass);
+int * bt_get_error_counts (int *counts);
+ushort bt_error_status (int *saved_counts);
+
+/* macros.c */
+void bt_add_macro_value (AST *assignment, ushort options);
+void bt_add_macro_text (char * macro, char * text, char * filename, int line);
+void bt_delete_macro (char * macro);
+void bt_delete_all_macros (void);
+int bt_macro_length (char *macro);
+char * bt_macro_text (char * macro, char * filename, int line);
+
+/* traversal.c */
+AST *bt_next_entry (AST *entry_list, AST *prev_entry);
+bt_metatype bt_entry_metatype (AST *entry);
+char *bt_entry_type (AST *entry);
+char *bt_entry_key (AST *entry);
+AST *bt_next_field (AST *entry, AST *prev, char **name);
+AST *bt_next_macro (AST *entry, AST *prev, char **name);
+AST *bt_next_value (AST *head,
+ AST *prev,
+ bt_nodetype *nodetype,
+ char **text);
+char *bt_get_text (AST *node);
+
+/* modify.c */
+void bt_set_text (AST * node, char * new_text);
+void bt_entry_set_key (AST * entry, char * new_key);
+
+/* names.c */
+bt_stringlist * bt_split_list (char * string,
+ char * delim,
+ char * filename,
+ int line,
+ char * description);
+void bt_free_list (bt_stringlist *list);
+bt_name * bt_split_name (char * name,
+ char * filename,
+ int line,
+ int name_num);
+void bt_free_name (bt_name * name);
+
+/* tex_tree.c */
+bt_tex_tree * bt_build_tex_tree (char * string);
+void bt_free_tex_tree (bt_tex_tree **top);
+void bt_dump_tex_tree (bt_tex_tree *node, int depth, FILE *stream);
+char * bt_flatten_tex_tree (bt_tex_tree *top);
+
+/* string_util.c */
+void bt_purify_string (char * string, ushort options);
+void bt_change_case (char transform, char * string, ushort options);
+
+/* format_name.c */
+bt_name_format * bt_create_name_format (char * parts, boolean abbrev_first);
+void bt_free_name_format (bt_name_format * format);
+void bt_set_format_text (bt_name_format * format,
+ bt_namepart part,
+ char * pre_part,
+ char * post_part,
+ char * pre_token,
+ char * post_token);
+void bt_set_format_options (bt_name_format * format,
+ bt_namepart part,
+ boolean abbrev,
+ bt_joinmethod join_tokens,
+ bt_joinmethod join_part);
+char * bt_format_name (bt_name * name, bt_name_format * format);
+
+#if defined(__cplusplus__) || defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* BTPARSE_H */
diff --git a/src/translators/btparse/dlgauto.h b/src/translators/btparse/dlgauto.h
new file mode 100644
index 0000000..efcc3b2
--- /dev/null
+++ b/src/translators/btparse/dlgauto.h
@@ -0,0 +1,408 @@
+/* dlgauto.h automaton
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Will Cohen and Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+
+#ifndef ZZDEFAUTO_H
+#define ZZDEFAUTO_H
+
+zzchar_t *zzlextext; /* text of most recently matched token */
+zzchar_t *zzbegexpr; /* beginning of last reg expr recogn. */
+zzchar_t *zzendexpr; /* beginning of last reg expr recogn. */
+int zzbufsize; /* number of characters in zzlextext */
+int zzbegcol = 0; /* column that first character of token is in*/
+int zzendcol = 0; /* column that last character of token is in */
+int zzline = 1; /* line current token is on */
+int zzreal_line=1; /* line of 1st portion of token that is not skipped */
+int zzchar; /* character to determine next state */
+int zzbufovf; /* indicates that buffer too small for text */
+int zzcharfull = 0;
+static zzchar_t *zznextpos;/* points to next available position in zzlextext*/
+static int zzclass;
+
+void zzerrstd(const char *);
+void (*zzerr)(const char *)=zzerrstd;/* pointer to error reporting function */
+extern int zzerr_in(void);
+
+static FILE *zzstream_in=0;
+static int (*zzfunc_in)() = zzerr_in;
+static zzchar_t *zzstr_in=0;
+
+#ifdef USER_ZZMODE_STACK
+int zzauto = 0;
+#else
+static int zzauto = 0;
+#endif
+static int zzadd_erase;
+static char zzebuf[70];
+
+#ifdef ZZCOL
+#define ZZINC (++zzendcol)
+#else
+#define ZZINC
+#endif
+
+
+#define ZZGETC_STREAM {zzchar = getc(zzstream_in); zzclass = ZZSHIFT(zzchar);}
+#define ZZGETC_FUNC {zzchar = (*zzfunc_in)(); zzclass = ZZSHIFT(zzchar);}
+#define ZZGETC_STR { \
+ if (*zzstr_in){ \
+ zzchar = *zzstr_in; \
+ ++zzstr_in; \
+ }else{ \
+ zzchar = EOF; \
+ } \
+ zzclass = ZZSHIFT(zzchar); \
+}
+
+#define ZZNEWSTATE (newstate = dfa[state][zzclass])
+
+#ifndef ZZCOPY
+#define ZZCOPY \
+ /* Truncate matching buffer to size (not an error) */ \
+ if (zznextpos < lastpos){ \
+ *(zznextpos++) = zzchar; \
+ }else{ \
+ zzbufovf = 1; \
+ }
+#endif
+
+void
+zzrdstream( FILE *f )
+{
+ /* make sure that it is really set to something, otherwise just
+ leave it be.
+ */
+ if (f){
+ /* make sure that there is always someplace to get input
+ before closing zzstream_in
+ */
+ zzline = 1;
+ zzstream_in = f;
+ zzfunc_in = NULL;
+ zzstr_in = 0;
+ zzcharfull = 0;
+ }
+}
+
+void
+zzrdfunc( int (*f)() )
+{
+ /* make sure that it is really set to something, otherwise just
+ leave it be.
+ */
+ if (f){
+ /* make sure that there is always someplace to get input
+ before closing zzstream_in
+ */
+ zzline = 1;
+ zzstream_in = NULL;
+ zzfunc_in = f;
+ zzstr_in = 0;
+ zzcharfull = 0;
+ }
+}
+
+
+void
+zzrdstr( zzchar_t *s )
+{
+ /* make sure that it is really set to something, otherwise just
+ leave it be.
+ */
+ if (s){
+ /* make sure that there is always someplace to get input
+ before closing zzstream_in
+ */
+ zzline = 1;
+ zzstream_in = NULL;
+ zzfunc_in = 0;
+ zzstr_in = s;
+ zzcharfull = 0;
+ }
+}
+
+
+void
+zzclose_stream()
+{
+}
+
+/* saves dlg state, but not what feeds dlg (such as file position) */
+void
+zzsave_dlg_state(struct zzdlg_state *state)
+{
+ state->stream = zzstream_in;
+ state->func_ptr = zzfunc_in;
+ state->str = zzstr_in;
+ state->auto_num = zzauto;
+ state->add_erase = zzadd_erase;
+ state->lookc = zzchar;
+ state->char_full = zzcharfull;
+ state->begcol = zzbegcol;
+ state->endcol = zzendcol;
+ state->line = zzline;
+ state->lextext = zzlextext;
+ state->begexpr = zzbegexpr;
+ state->endexpr = zzendexpr;
+ state->bufsize = zzbufsize;
+ state->bufovf = zzbufovf;
+ state->nextpos = zznextpos;
+ state->class_num = zzclass;
+}
+
+void
+zzrestore_dlg_state(struct zzdlg_state *state)
+{
+ zzstream_in = state->stream;
+ zzfunc_in = state->func_ptr;
+ zzstr_in = state->str;
+ zzauto = state->auto_num;
+ zzadd_erase = state->add_erase;
+ zzchar = state->lookc;
+ zzcharfull = state->char_full;
+ zzbegcol = state->begcol;
+ zzendcol = state->endcol;
+ zzline = state->line;
+ zzlextext = state->lextext;
+ zzbegexpr = state->begexpr;
+ zzendexpr = state->endexpr;
+ zzbufsize = state->bufsize;
+ zzbufovf = state->bufovf;
+ zznextpos = state->nextpos;
+ zzclass = state->class_num;
+}
+
+void
+zzmode( int m )
+{
+ /* points to base of dfa table */
+ if (m<MAX_MODE){
+ zzauto = m;
+ /* have to redo class since using different compression */
+ zzclass = ZZSHIFT(zzchar);
+ }else{
+ sprintf(zzebuf,"Invalid automaton mode = %d ",m);
+ zzerr(zzebuf);
+ }
+}
+
+/* erase what is currently in the buffer, and get a new reg. expr */
+void
+zzskip()
+{
+ zzadd_erase = 1;
+}
+
+/* don't erase what is in the zzlextext buffer, add on to it */
+void
+zzmore()
+{
+ zzadd_erase = 2;
+}
+
+/* substitute c for the reg. expr last matched and is in the buffer */
+void
+zzreplchar(zzchar_t c)
+{
+ /* can't allow overwriting null at end of string */
+ if (zzbegexpr < &zzlextext[zzbufsize-1]){
+ *zzbegexpr = c;
+ *(zzbegexpr+1) = '\0';
+ }
+ zzendexpr = zzbegexpr;
+ zznextpos = zzbegexpr + 1;
+}
+
+/* replace the string s for the reg. expr last matched and in the buffer */
+void
+zzreplstr(register zzchar_t *s)
+{
+ register zzchar_t *l= &zzlextext[zzbufsize -1];
+
+ zznextpos = zzbegexpr;
+ if (s){
+ while ((zznextpos <= l) && (*(zznextpos++) = *(s++))!=0){
+ /* empty */
+ }
+ /* correct for NULL at end of string */
+ zznextpos--;
+ }
+ if ((zznextpos <= l) && (*(--s) == 0)){
+ zzbufovf = 0;
+ }else{
+ zzbufovf = 1;
+ }
+ *(zznextpos) = '\0';
+ zzendexpr = zznextpos - 1;
+}
+
+void
+zzgettok()
+{
+ register int state, newstate;
+ /* last space reserved for the null char */
+ zzchar_t *lastpos; /* GPW 1997/09/05 (removed 'register' */
+
+skip:
+ zzreal_line = zzline;
+ zzbufovf = 0;
+ lastpos = &zzlextext[zzbufsize-1];
+ zznextpos = zzlextext;
+ zzbegcol = zzendcol+1;
+more:
+ zzbegexpr = zznextpos;
+#ifdef ZZINTERACTIVE
+ /* interactive version of automaton */
+ /* if there is something in zzchar, process it */
+ state = newstate = dfa_base[zzauto];
+ if (zzcharfull){
+ ZZINC;
+ ZZCOPY;
+ ZZNEWSTATE;
+ }
+ if (zzstr_in)
+ while (zzalternatives[newstate]){
+ state = newstate;
+ ZZGETC_STR;
+ ZZINC;
+ ZZCOPY;
+ ZZNEWSTATE;
+ }
+ else if (zzstream_in)
+ while (zzalternatives[newstate]){
+ state = newstate;
+ ZZGETC_STREAM;
+ ZZINC;
+ ZZCOPY;
+ ZZNEWSTATE;
+ }
+ else if (zzfunc_in)
+ while (zzalternatives[newstate]){
+ state = newstate;
+ ZZGETC_FUNC;
+ ZZINC;
+ ZZCOPY;
+ ZZNEWSTATE;
+ }
+ /* figure out if last character really part of token */
+ if ((state != dfa_base[zzauto]) && (newstate == DfaStates)){
+ zzcharfull = 1;
+ --zznextpos;
+ }else{
+ zzcharfull = 0;
+ state = newstate;
+ }
+ *(zznextpos) = '\0';
+ /* Able to transition out of start state to some non err state?*/
+ if ( state == dfa_base[zzauto] ){
+ /* make sure doesn't get stuck */
+ zzadvance();
+ }
+#else
+ /* non-interactive version of automaton */
+ if (!zzcharfull)
+ zzadvance();
+ else
+ ZZINC;
+ state = dfa_base[zzauto];
+ if (zzstr_in)
+ while (ZZNEWSTATE != DfaStates){
+ state = newstate;
+ ZZCOPY;
+ ZZGETC_STR;
+ ZZINC;
+ }
+ else if (zzstream_in)
+ while (ZZNEWSTATE != DfaStates){
+ state = newstate;
+ ZZCOPY;
+ ZZGETC_STREAM;
+ ZZINC;
+ }
+ else if (zzfunc_in)
+ while (ZZNEWSTATE != DfaStates){
+ state = newstate;
+ ZZCOPY;
+ ZZGETC_FUNC;
+ ZZINC;
+ }
+ zzcharfull = 1;
+ if ( state == dfa_base[zzauto] ){
+ if (zznextpos < lastpos){
+ *(zznextpos++) = zzchar;
+ }else{
+ zzbufovf = 1;
+ }
+ *zznextpos = '\0';
+ /* make sure doesn't get stuck */
+ zzadvance();
+ }else{
+ *zznextpos = '\0';
+ }
+#endif
+#ifdef ZZCOL
+ zzendcol -= zzcharfull;
+#endif
+ zzendexpr = zznextpos -1;
+ zzadd_erase = 0;
+ (*actions[accepts[state]])();
+ switch (zzadd_erase) {
+ case 1: goto skip;
+ case 2: goto more;
+ }
+}
+
+void
+zzadvance()
+{
+ if (zzstream_in) { ZZGETC_STREAM; zzcharfull = 1; ZZINC;}
+ if (zzfunc_in) { ZZGETC_FUNC; zzcharfull = 1; ZZINC;}
+ if (zzstr_in) { ZZGETC_STR; zzcharfull = 1; ZZINC;}
+ if (!(zzstream_in || zzfunc_in || zzstr_in)){
+ zzerr_in();
+ }
+}
+
+void
+zzerrstd(const char *s)
+{
+ fprintf(stderr,
+ "%s near line %d (text was '%s')\n",
+ ((s == NULL) ? "Lexical error" : s),
+ zzline,zzlextext);
+}
+
+int
+zzerr_in()
+{
+ fprintf(stderr,"No input stream, function, or string\n");
+ /* return eof to get out gracefully */
+ return EOF;
+}
+
+#endif
diff --git a/src/translators/btparse/dlgdef.h b/src/translators/btparse/dlgdef.h
new file mode 100644
index 0000000..ded2c31
--- /dev/null
+++ b/src/translators/btparse/dlgdef.h
@@ -0,0 +1,97 @@
+/* dlgdef.h
+ * Things in scanner produced by dlg that should be visible to the outside
+ * world
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+
+#ifndef ZZDLGDEF_H
+#define ZZDLGDEF_H
+
+#include "btconfig.h"
+
+#ifndef zzchar_t
+#ifdef ZZWCHAR_T
+#define zzchar_t unsigned wchar_t
+#else
+#define zzchar_t unsigned char
+#endif
+#endif
+
+struct zzdlg_state {
+ FILE *stream;
+ int (*func_ptr)();
+ zzchar_t *str;
+ int auto_num;
+ int add_erase;
+ int lookc;
+ int char_full;
+ int begcol, endcol;
+ int line;
+ zzchar_t *lextext, *begexpr, *endexpr;
+ int bufsize;
+ int bufovf;
+ zzchar_t *nextpos;
+ int class_num;
+};
+
+extern zzchar_t *zzlextext; /* text of most recently matched token */
+extern zzchar_t *zzbegexpr; /* beginning of last reg expr recogn. */
+extern zzchar_t *zzendexpr; /* beginning of last reg expr recogn. */
+extern int zzbufsize; /* how long zzlextext is */
+extern int zzbegcol; /* column that first character of token is in*/
+extern int zzendcol; /* column that last character of token is in */
+extern int zzline; /* line current token is on */
+extern int zzreal_line; /* line of 1st portion of token that is not skipped */
+extern int zzchar; /* character to determine next state */
+extern int zzbufovf; /* indicates that buffer too small for text */
+extern void (*zzerr)(const char *);/* pointer to error reporting function */
+
+#ifdef USER_ZZMODE_STACK
+extern int zzauto;
+#endif
+
+extern void zzadvance(void);
+extern void zzskip(void); /* erase zzlextext, look for antoher token */
+extern void zzmore(void); /* keep zzlextext, look for another token */
+extern void zzmode(int k); /* switch to automaton 'k' */
+extern void zzrdstream(FILE *);/* what stream to read from */
+extern void zzclose_stream(void);/* close the current input stream */
+extern void zzrdfunc(int (*)());/* what function to get char from */
+extern void zzrdstr( zzchar_t * );
+extern void zzgettok(void); /* get next token */
+extern void zzreplchar(zzchar_t c);/* replace last recognized reg. expr. with
+ a character */
+extern void zzreplstr(zzchar_t *s);/* replace last recognized reg. expr. with
+ a string */
+extern void zzsave_dlg_state(struct zzdlg_state *);
+extern void zzrestore_dlg_state(struct zzdlg_state *);
+extern int zzerr_in(void);
+extern void zzerrstd(const char *);
+extern void zzerraction();
+
+#endif
diff --git a/src/translators/btparse/err.c b/src/translators/btparse/err.c
new file mode 100644
index 0000000..f143048
--- /dev/null
+++ b/src/translators/btparse/err.c
@@ -0,0 +1,75 @@
+/*
+ * A n t l r S e t s / E r r o r F i l e H e a d e r
+ *
+ * Generated from: bibtex.g
+ *
+ * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-1995
+ * Parr Research Corporation
+ * with Purdue University Electrical Engineering
+ * With AHPCRC, University of Minnesota
+ * ANTLR Version 1.33
+ */
+
+#include <stdio.h>
+#define ANTLR_VERSION 133
+
+#define ZZCOL
+#define USER_ZZSYN
+
+#include "btconfig.h"
+#include "btparse.h"
+#include "attrib.h"
+#include "lex_auxiliary.h"
+#include "error.h"
+/*#include "my_dmalloc.h"*/
+
+extern char * InputFilename; /* for zzcr_ast call in pccts/ast.c */
+#define zzSET_SIZE 4
+#include "antlr.h"
+#include "ast.h"
+#include "tokens.h"
+#include "dlgdef.h"
+#include "err.h"
+
+const ANTLRChar *zztokens[27]={
+ /* 00 */ "Invalid",
+ /* 01 */ "@",
+ /* 02 */ "AT",
+ /* 03 */ "\\n",
+ /* 04 */ "COMMENT",
+ /* 05 */ "[\\ \\r\\t]+",
+ /* 06 */ "~[\\@\\n\\ \\r\\t]+",
+ /* 07 */ "\\n",
+ /* 08 */ "[\\ \\r\\t]+",
+ /* 09 */ "NUMBER",
+ /* 10 */ "NAME",
+ /* 11 */ "LBRACE",
+ /* 12 */ "RBRACE",
+ /* 13 */ "ENTRY_OPEN",
+ /* 14 */ "ENTRY_CLOSE",
+ /* 15 */ "EQUALS",
+ /* 16 */ "HASH",
+ /* 17 */ "COMMA",
+ /* 18 */ "\"",
+ /* 19 */ "\\n~[\\n\\{\\}\\(\\)\"\\]*",
+ /* 20 */ "[\\r\\t]",
+ /* 21 */ "\\{",
+ /* 22 */ "\\}",
+ /* 23 */ "\\(",
+ /* 24 */ "\\)",
+ /* 25 */ "STRING",
+ /* 26 */ "~[\\n\\{\\}\\(\\)\"]+"
+};
+SetWordType zzerr1[4] = {0x0,0x20,0x0,0x2};
+SetWordType zzerr2[4] = {0x0,0x6,0x0,0x0};
+SetWordType zzerr3[4] = {0x0,0x46,0x0,0x2};
+SetWordType zzerr4[4] = {0x0,0x44,0x0,0x0};
+SetWordType setwd1[27] = {0x0,0x7,0x6,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x28,0x38,0x0,0x0,0x0,0xd0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x20,0x0};
+SetWordType zzerr5[4] = {0x0,0x6,0x0,0x2};
+SetWordType setwd2[27] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,
+ 0x0,0x4,0x7,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0x0,0x0,0x0};
diff --git a/src/translators/btparse/err.h b/src/translators/btparse/err.h
new file mode 100644
index 0000000..d16615d
--- /dev/null
+++ b/src/translators/btparse/err.h
@@ -0,0 +1,700 @@
+/*
+ * err.h
+ *
+ * Standard error handling mechanism
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * Has grown to hold all kinds of stuff (err.h is increasingly misnamed)
+ *
+ * ANTLR 1.33
+ * Terence Parr
+ * Parr Research Corporation
+ * with Purdue University and AHPCRC, University of Minnesota
+ * 1989-1995
+ */
+
+#ifndef ERR_H
+#define ERR_H
+
+#include "btconfig.h"
+
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef DUM
+/* Define usable bits per unsigned int word (used for set stuff) */
+#ifdef PC
+#define BSETWORDSIZE 16
+#define BSETLOGWORDSIZE 4
+#else
+#define BSETWORDSIZE 32
+#define BSETLOGWORDSIZE 5
+#endif
+#endif
+
+#define BSETWORDSIZE 8
+#define BSETLOGWORDSIZE 3 /* SetWordType is 8bits */
+
+#define BSETMODWORD(x) ((x) & (BSETWORDSIZE-1)) /* x % BSETWORDSIZE */
+#define BSETDIVWORD(x) ((x) >> BSETLOGWORDSIZE) /* x / BSETWORDSIZE */
+
+/* This is not put into the global pccts_parser structure because it is
+ * hidden and does not need to be saved during a "save state" operation
+ */
+/* maximum of 32 bits/unsigned int and must be 8 bits/byte */
+static SetWordType bitmask[] = {
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008,
+ 0x00000010, 0x00000020, 0x00000040, 0x00000080
+};
+
+void
+zzresynch(SetWordType *wd,SetWordType mask)
+{
+ static int consumed = 1;
+
+ /* if you enter here without having consumed a token from last resynch
+ * force a token consumption.
+ */
+ if ( !consumed ) {zzCONSUME; return;}
+
+ /* if current token is in resynch set, we've got what we wanted */
+ if ( wd[LA(1)]&mask || LA(1) == zzEOF_TOKEN ) {consumed=0; return;}
+
+ /* scan until we find something in the resynch set */
+ while ( !(wd[LA(1)]&mask) && LA(1) != zzEOF_TOKEN ) {zzCONSUME;}
+ consumed=1;
+}
+
+void
+zzconsumeUntil(SetWordType *st)
+{
+ while ( !zzset_el(LA(1), st) ) { zzCONSUME; }
+}
+
+void
+zzconsumeUntilToken(int t)
+{
+ while ( LA(1)!=t ) { zzCONSUME; }
+}
+
+/* input looks like:
+ * zzFAIL(k, e1, e2, ...,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText)
+ * where the zzMiss stuff is set here to the token that did not match
+ * (and which set wasn't it a member of).
+ */
+void
+zzFAIL(int k, ...)
+{
+#ifdef LL_K
+ static char text[LL_K*ZZLEXBUFSIZE+1];
+ SetWordType *f[LL_K];
+#else
+ static char text[ZZLEXBUFSIZE+1];
+ SetWordType *f[1];
+#endif
+ SetWordType **miss_set;
+ char **miss_text;
+ int *bad_tok;
+ char **bad_text;
+ int *err_k;
+ int i;
+ va_list ap;
+/* Removed because it shadows a parameter. gcc 3.4 complains.
+ I think removing it preserves the behavior of gcc 3.3 and previous.
+ int k;
+*/
+ va_start(ap, k);
+ text[0] = '\0';
+ for (i=1; i<=k; i++) /* collect all lookahead sets */
+ {
+ f[i-1] = va_arg(ap, SetWordType *);
+ }
+ for (i=1; i<=k; i++) /* look for offending token */
+ {
+ if ( i>1 ) strcat(text, " ");
+ strcat(text, LATEXT(i));
+ if ( !zzset_el((unsigned)LA(i), f[i-1]) ) break;
+ }
+ miss_set = va_arg(ap, SetWordType **);
+ miss_text = va_arg(ap, char **);
+ bad_tok = va_arg(ap, int *);
+ bad_text = va_arg(ap, char **);
+ err_k = va_arg(ap, int *);
+ if ( i>k )
+ {
+ /* bad; lookahead is permutation that cannot be matched,
+ * but, the ith token of lookahead is valid at the ith position
+ * (The old LL sub 1 (k) versus LL(k) parsing technique)
+ */
+ *miss_set = NULL;
+ *miss_text = zzlextext;
+ *bad_tok = LA(1);
+ *bad_text = LATEXT(1);
+ *err_k = k;
+ return;
+ }
+/* fprintf(stderr, "%s not in %dth set\n", zztokens[LA(i)], i);*/
+ *miss_set = f[i-1];
+ *miss_text = text;
+ *bad_tok = LA(i);
+ *bad_text = LATEXT(i);
+ if ( i==1 ) *err_k = 1;
+ else *err_k = k;
+}
+
+void
+zzsave_antlr_state(zzantlr_state *buf)
+{
+#ifdef LL_K
+ int i;
+#endif
+
+#ifdef ZZCAN_GUESS
+ buf->guess_start = zzguess_start;
+ buf->guessing = zzguessing;
+#endif
+ buf->asp = zzasp;
+#ifdef GENAST
+ buf->ast_sp = zzast_sp;
+#endif
+#ifdef ZZINF_LOOK
+ buf->inf_labase = zzinf_labase;
+ buf->inf_last = zzinf_last;
+#endif
+#ifdef DEMAND_LOOK
+ buf->dirty = zzdirty;
+#endif
+#ifdef LL_K
+ for (i=0; i<LL_K; i++) buf->tokenLA[i] = zztokenLA[i];
+ for (i=0; i<LL_K; i++) strcpy(buf->textLA[i], zztextLA[i]);
+ buf->lap = zzlap;
+ buf->labase = zzlabase;
+#else
+ buf->token = zztoken;
+ strcpy(buf->text, zzlextext);
+#endif
+}
+
+void
+zzrestore_antlr_state(zzantlr_state *buf)
+{
+#ifdef LL_K
+ int i;
+#endif
+
+#ifdef ZZCAN_GUESS
+ zzguess_start = buf->guess_start;
+ zzguessing = buf->guessing;
+#endif
+ zzasp = buf->asp;
+#ifdef GENAST
+ zzast_sp = buf->ast_sp;
+#endif
+#ifdef ZZINF_LOOK
+ zzinf_labase = buf->inf_labase;
+ zzinf_last = buf->inf_last;
+#endif
+#ifdef DEMAND_LOOK
+ zzdirty = buf->dirty;
+#endif
+#ifdef LL_K
+ for (i=0; i<LL_K; i++) zztokenLA[i] = buf->tokenLA[i];
+ for (i=0; i<LL_K; i++) strcpy(zztextLA[i], buf->textLA[i]);
+ zzlap = buf->lap;
+ zzlabase = buf->labase;
+#else
+ zztoken = buf->token;
+ strcpy(zzlextext, buf->text);
+#endif
+}
+
+void
+zzedecode(SetWordType *a)
+{
+ register SetWordType *p = a;
+ register SetWordType *endp = &(p[zzSET_SIZE]);
+ register unsigned e = 0;
+
+ if ( zzset_deg(a)>1 ) fprintf(stderr, " {");
+ do {
+ register SetWordType t = *p;
+ register SetWordType *b = &(bitmask[0]);
+ do {
+ if ( t & *b ) fprintf(stderr, " %s", zztokens[e]);
+ e++;
+ } while (++b < &(bitmask[sizeof(SetWordType)*8]));
+ } while (++p < endp);
+ if ( zzset_deg(a)>1 ) fprintf(stderr, " }");
+}
+
+#ifndef USER_ZZSYN
+/* standard error reporting function */
+void
+zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, int k, char *bad_text)
+{
+
+ fprintf(stderr, "line %d: syntax error at \"%s\"", zzline, (tok==zzEOF_TOKEN)?"EOF":bad_text);
+ if ( !etok && !eset ) {fprintf(stderr, "\n"); return;}
+ if ( k==1 ) fprintf(stderr, " missing");
+ else
+ {
+ fprintf(stderr, "; \"%s\" not", bad_text);
+ if ( zzset_deg(eset)>1 ) fprintf(stderr, " in");
+ }
+ if ( zzset_deg(eset)>0 ) zzedecode(eset);
+ else fprintf(stderr, " %s", zztokens[etok]);
+ if ( strlen(egroup) > 0 ) fprintf(stderr, " in %s", egroup);
+ fprintf(stderr, "\n");
+}
+#endif
+
+/* is b an element of set p? */
+int
+zzset_el(unsigned b, SetWordType *p)
+{
+ return( p[BSETDIVWORD(b)] & bitmask[BSETMODWORD(b)] );
+}
+
+int
+zzset_deg(SetWordType *a)
+{
+ /* Fast compute degree of a set... the number
+ of elements present in the set. Assumes
+ that all word bits are used in the set
+ */
+ register SetWordType *p = a;
+ register SetWordType *endp = &(a[zzSET_SIZE]);
+ register int degree = 0;
+
+ if ( a == NULL ) return 0;
+ while ( p < endp )
+ {
+ register SetWordType t = *p;
+ register SetWordType *b = &(bitmask[0]);
+ do {
+ if (t & *b) ++degree;
+ } while (++b < &(bitmask[sizeof(SetWordType)*8]));
+ p++;
+ }
+
+ return(degree);
+}
+
+#ifdef DEMAND_LOOK
+
+#ifdef LL_K
+int
+_zzmatch(int _t, char **zzBadText, char **zzMissText,
+ int *zzMissTok, int *zzBadTok,
+ SetWordType **zzMissSet)
+{
+ if ( zzdirty==LL_K ) {
+ zzCONSUME;
+ }
+ if ( LA(1)!=_t ) {
+ *zzBadText = *zzMissText=LATEXT(1);
+ *zzMissTok= _t; *zzBadTok=LA(1);
+ *zzMissSet=NULL;
+ return 0;
+ }
+ zzMakeAttr
+ zzdirty++;
+ zzlabase++;
+ return 1;
+}
+
+int
+_zzmatch_wsig(int _t)
+{
+ if ( zzdirty==LL_K ) {
+ zzCONSUME;
+ }
+ if ( LA(1)!=_t ) {
+ return 0;
+ }
+ zzMakeAttr
+ zzdirty++;
+ zzlabase++;
+ return 1;
+}
+
+#else
+
+int
+_zzmatch(int _t, char **zzBadText, char **zzMissText,
+ int *zzMissTok, int *zzBadTok, SetWordType **zzMissSet)
+{
+ if ( zzdirty ) {zzCONSUME;}
+ if ( LA(1)!=_t ) {
+ *zzBadText = *zzMissText=LATEXT(1);
+ *zzMissTok= _t; *zzBadTok=LA(1);
+ *zzMissSet=NULL;
+ return 0;
+ }
+ zzdirty = 1;
+ zzMakeAttr
+ return 1;
+}
+
+int
+_zzmatch_wsig(int _t)
+{
+ if ( zzdirty ) {zzCONSUME;}
+ if ( LA(1)!=_t ) {
+ return 0;
+ }
+ zzdirty = 1;
+ zzMakeAttr
+ return 1;
+}
+
+#endif /*LL_K*/
+
+#else
+
+int
+_zzmatch(int _t, const char **zzBadText, const char **zzMissText,
+ int *zzMissTok, int *zzBadTok,
+ SetWordType **zzMissSet)
+{
+ if ( LA(1)!=_t ) {
+ *zzBadText = *zzMissText=LATEXT(1);
+ *zzMissTok= _t; *zzBadTok=LA(1);
+ *zzMissSet=NULL;
+ return 0;
+ }
+ zzMakeAttr
+ return 1;
+}
+
+int
+_zzmatch_wsig(int _t)
+{
+ if ( LA(1)!=_t ) return 0;
+ zzMakeAttr
+ return 1;
+}
+
+#endif /*DEMAND_LOOK*/
+
+#ifdef ZZINF_LOOK
+void
+_inf_zzgettok(void)
+{
+ if ( zzinf_labase >= zzinf_last )
+ {NLA = zzEOF_TOKEN; strcpy(NLATEXT, "");}
+ else {
+ NLA = zzinf_tokens[zzinf_labase];
+ zzline = zzinf_line[zzinf_labase]; /* wrong in 1.21 */
+ strcpy(NLATEXT, zzinf_text[zzinf_labase]);
+ zzinf_labase++;
+ }
+}
+#endif
+
+#ifdef ZZINF_LOOK
+/* allocate default size text,token and line arrays;
+ * then, read all of the input reallocing the arrays as needed.
+ * Once the number of total tokens is known, the LATEXT(i) array (zzinf_text)
+ * is allocated and it's pointers are set to the tokens in zzinf_text_buffer.
+ */
+void
+zzfill_inf_look(void)
+{
+ int tok, line;
+ int zzinf_token_buffer_size = ZZINF_DEF_TOKEN_BUFFER_SIZE;
+ int zzinf_text_buffer_size = ZZINF_DEF_TEXT_BUFFER_SIZE;
+ int zzinf_text_buffer_index = 0;
+ int zzinf_lap = 0;
+
+ /* allocate text/token buffers */
+ zzinf_text_buffer = (char *) malloc(zzinf_text_buffer_size);
+ if ( zzinf_text_buffer == NULL )
+ {
+ fprintf(stderr, "cannot allocate lookahead text buffer (%d bytes)\n",
+ zzinf_text_buffer_size);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+ zzinf_tokens = (int *) calloc(zzinf_token_buffer_size,sizeof(int));
+ if ( zzinf_tokens == NULL )
+ {
+ fprintf(stderr, "cannot allocate token buffer (%d tokens)\n",
+ zzinf_token_buffer_size);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+ zzinf_line = (int *) calloc(zzinf_token_buffer_size,sizeof(int));
+ if ( zzinf_line == NULL )
+ {
+ fprintf(stderr, "cannot allocate line buffer (%d ints)\n",
+ zzinf_token_buffer_size);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+
+ /* get tokens, copying text to text buffer */
+ zzinf_text_buffer_index = 0;
+ do {
+ zzgettok();
+ line = zzreal_line;
+ while ( zzinf_lap>=zzinf_token_buffer_size )
+ {
+ zzinf_token_buffer_size += ZZINF_BUFFER_TOKEN_CHUNK_SIZE;
+ zzinf_tokens = (int *) realloc(zzinf_tokens,
+ zzinf_token_buffer_size*sizeof(int));
+ if ( zzinf_tokens == NULL )
+ {
+ fprintf(stderr, "cannot allocate lookahead token buffer (%d tokens)\n",
+ zzinf_token_buffer_size);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+ zzinf_line = (int *) realloc(zzinf_line,
+ zzinf_token_buffer_size*sizeof(int));
+ if ( zzinf_line == NULL )
+ {
+ fprintf(stderr, "cannot allocate lookahead line buffer (%d ints)\n",
+ zzinf_token_buffer_size);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+
+ }
+ while ( (zzinf_text_buffer_index+strlen(NLATEXT)+1) >= zzinf_text_buffer_size )
+ {
+ zzinf_text_buffer_size += ZZINF_BUFFER_TEXT_CHUNK_SIZE;
+ zzinf_text_buffer = (char *) realloc(zzinf_text_buffer,
+ zzinf_text_buffer_size);
+ if ( zzinf_text_buffer == NULL )
+ {
+ fprintf(stderr, "cannot allocate lookahead text buffer (%d bytes)\n",
+ zzinf_text_buffer_size);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+ }
+ /* record token and text and line of input symbol */
+ tok = zzinf_tokens[zzinf_lap] = NLA;
+ strcpy(&zzinf_text_buffer[zzinf_text_buffer_index], NLATEXT);
+ zzinf_text_buffer_index += strlen(NLATEXT)+1;
+ zzinf_line[zzinf_lap] = line;
+ zzinf_lap++;
+ } while (tok!=zzEOF_TOKEN);
+ zzinf_labase = 0;
+ zzinf_last = zzinf_lap-1;
+
+ /* allocate ptrs to text of ith token */
+ zzinf_text = (char **) calloc(zzinf_last+1,sizeof(char *));
+ if ( zzinf_text == NULL )
+ {
+ fprintf(stderr, "cannot allocate lookahead text buffer (%d)\n",
+ zzinf_text_buffer_size);
+ exit(PCCTS_EXIT_FAILURE);
+ }
+ zzinf_text_buffer_index = 0;
+ zzinf_lap = 0;
+ /* set ptrs so that zzinf_text[i] is the text of the ith token found on input */
+ while (zzinf_lap<=zzinf_last)
+ {
+ zzinf_text[zzinf_lap++] = &zzinf_text_buffer[zzinf_text_buffer_index];
+ zzinf_text_buffer_index += strlen(&zzinf_text_buffer[zzinf_text_buffer_index])+1;
+ }
+}
+#endif
+
+int
+_zzsetmatch(SetWordType *e, char **zzBadText, char **zzMissText,
+ int *zzMissTok, int *zzBadTok,
+ SetWordType **zzMissSet)
+{
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ if ( zzdirty==LL_K ) {zzCONSUME;}
+#else
+ if ( zzdirty ) {zzCONSUME;}
+#endif
+#endif
+ if ( !zzset_el((unsigned)LA(1), e) ) {
+ *zzBadText = LATEXT(1); *zzMissText=NULL;
+ *zzMissTok= 0; *zzBadTok=LA(1);
+ *zzMissSet=e;
+ return 0;
+ }
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ zzdirty++;
+#else
+ zzdirty = 1;
+#endif
+#endif
+ zzMakeAttr
+ return 1;
+}
+
+int
+_zzmatch_wdfltsig(int tokenWanted, SetWordType *whatFollows)
+{
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ if ( zzdirty==LL_K ) {
+ zzCONSUME;
+ }
+#else
+ if ( zzdirty ) {zzCONSUME;}
+#endif
+#endif
+
+ if ( LA(1)!=tokenWanted )
+ {
+ fprintf(stderr,
+ "line %d: syntax error at \"%s\" missing %s\n",
+ zzline,
+ (LA(1)==zzEOF_TOKEN)?"<eof>":(char*)LATEXT(1),
+ zztokens[tokenWanted]);
+ zzconsumeUntil( whatFollows );
+ return 0;
+ }
+ else {
+ zzMakeAttr
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ zzdirty++;
+ zzlabase++;
+#else
+ zzdirty = 1;
+#endif
+#else
+/* zzCONSUME; consume if not demand lookahead */
+#endif
+ return 1;
+ }
+}
+
+int
+_zzsetmatch_wdfltsig(SetWordType *tokensWanted,
+ int tokenTypeOfSet,
+ SetWordType *whatFollows)
+{
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ if ( zzdirty==LL_K ) {zzCONSUME;}
+#else
+ if ( zzdirty ) {zzCONSUME;}
+#endif
+#endif
+ if ( !zzset_el((unsigned)LA(1), tokensWanted) )
+ {
+ fprintf(stderr,
+ "line %d: syntax error at \"%s\" missing %s\n",
+ zzline,
+ (LA(1)==zzEOF_TOKEN)?"<eof>":(char*)LATEXT(1),
+ zztokens[tokenTypeOfSet]);
+ zzconsumeUntil( whatFollows );
+ return 0;
+ }
+ else {
+ zzMakeAttr
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ zzdirty++;
+ zzlabase++;
+#else
+ zzdirty = 1;
+#endif
+#else
+/* zzCONSUME; consume if not demand lookahead */
+#endif
+ return 1;
+ }
+}
+
+int
+_zzsetmatch_wsig(SetWordType *e)
+{
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ if ( zzdirty==LL_K ) {zzCONSUME;}
+#else
+ if ( zzdirty ) {zzCONSUME;}
+#endif
+#endif
+ if ( !zzset_el((unsigned)LA(1), e) ) return 0;
+#ifdef DEMAND_LOOK
+#ifdef LL_K
+ zzdirty++;
+#else
+ zzdirty = 1;
+#endif
+#endif
+ zzMakeAttr
+ return 1;
+}
+
+#ifdef USER_ZZMODE_STACK
+static int zzmstk[ZZMAXSTK] = { -1 };
+static int zzmdep = 0;
+static char zzmbuf[70];
+
+void
+zzmpush( int m )
+{
+ if(zzmdep == ZZMAXSTK - 1) {
+ sprintf(zzmbuf, "Mode stack overflow ");
+ zzerr(zzmbuf);
+ } else {
+ zzmstk[zzmdep++] = zzauto;
+ zzmode(m);
+ }
+}
+
+void
+zzmpop( void )
+{
+ if(zzmdep == 0)
+ { sprintf(zzmbuf, "Mode stack underflow ");
+ zzerr(zzmbuf);
+ }
+ else
+ { zzmdep--;
+ zzmode(zzmstk[zzmdep]);
+ }
+}
+
+void
+zzsave_mode_stack( int modeStack[], int *modeLevel )
+{
+ int i;
+ memcpy(modeStack, zzmstk, sizeof(zzmstk));
+ *modeLevel = zzmdep;
+ zzmdep = 0;
+
+ return;
+}
+
+void
+zzrestore_mode_stack( int modeStack[], int *modeLevel )
+{
+ int i;
+
+ memcpy(zzmstk, modeStack, sizeof(zzmstk));
+ zzmdep = *modeLevel;
+
+ return;
+}
+#endif /* USER_ZZMODE_STACK */
+
+#endif /* ERR_H */
diff --git a/src/translators/btparse/error.c b/src/translators/btparse/error.c
new file mode 100644
index 0000000..26f2fb2
--- /dev/null
+++ b/src/translators/btparse/error.c
@@ -0,0 +1,348 @@
+/* ------------------------------------------------------------------------
+@NAME : error.c
+@DESCRIPTION: Anything relating to reporting or recording errors and
+ warnings.
+@GLOBALS : errclass_names
+ err_actions
+ err_handlers
+ errclass_counts
+ error_buf
+@CALLS :
+@CREATED : 1996/08/28, Greg Ward
+@MODIFIED :
+@VERSION : $Id: error.c,v 2.5 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+
+/*#include "bt_config.h"*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include "btparse.h"
+#include "error.h"
+/*#include "my_dmalloc.h"*/
+
+
+#define NUM_ERRCLASSES ((int) BTERR_INTERNAL + 1)
+
+
+static const char *errclass_names[NUM_ERRCLASSES] =
+{
+ NULL, /* BTERR_NOTIFY */
+ "warning", /* BTERR_CONTENT */
+ "warning", /* BTERR_LEXWARN */
+ "warning", /* BTERR_USAGEWARN */
+ "error", /* BTERR_LEXERR */
+ "syntax error", /* BTERR_SYNTAX */
+ "fatal error", /* BTERR_USAGEERR */
+ "internal error" /* BTERR_INTERNAL */
+};
+
+static const bt_erraction err_actions[NUM_ERRCLASSES] =
+{
+ BTACT_NONE, /* BTERR_NOTIFY */
+ BTACT_NONE, /* BTERR_CONTENT */
+ BTACT_NONE, /* BTERR_LEXWARN */
+ BTACT_NONE, /* BTERR_USAGEWARN */
+ BTACT_NONE, /* BTERR_LEXERR */
+ BTACT_NONE, /* BTERR_SYNTAX */
+ BTACT_CRASH, /* BTERR_USAGEERR */
+ BTACT_ABORT /* BTERR_INTERNAL */
+};
+
+void print_error (bt_error *err);
+
+static bt_err_handler err_handlers[NUM_ERRCLASSES] =
+{
+ print_error,
+ print_error,
+ print_error,
+ print_error,
+ print_error,
+ print_error,
+ print_error,
+ print_error
+};
+
+static int errclass_counts[NUM_ERRCLASSES] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+static char error_buf[MAX_ERROR+1];
+
+
+/* ----------------------------------------------------------------------
+ * Error-handling functions.
+ */
+
+void print_error (bt_error *err)
+{
+ const char * name;
+ boolean something_printed;
+
+ something_printed = FALSE;
+
+ if (err->filename)
+ {
+ fprintf (stderr, err->filename);
+ something_printed = TRUE;
+ }
+ if (err->line > 0) /* going to print a line number? */
+ {
+ if (something_printed)
+ fprintf (stderr, ", ");
+ fprintf (stderr, "line %d", err->line);
+ something_printed = TRUE;
+ }
+ if (err->item_desc && err->item > 0) /* going to print an item number? */
+ {
+ if (something_printed)
+ fprintf (stderr, ", ");
+ fprintf (stderr, "%s %d", err->item_desc, err->item);
+ something_printed = TRUE;
+ }
+
+ name = errclass_names[(int) err->errclass];
+ if (name)
+ {
+ if (something_printed)
+ fprintf (stderr, ", ");
+ fprintf (stderr, name);
+ something_printed = TRUE;
+ }
+
+ if (something_printed)
+ fprintf (stderr, ": ");
+
+ fprintf (stderr, "%s\n", err->message);
+
+} /* print_error() */
+
+
+
+/* ----------------------------------------------------------------------
+ * Error-reporting functions: these are called anywhere in the library
+ * when we encounter an error.
+ */
+
+void
+report_error (bt_errclass errclass,
+ char * filename,
+ int line,
+ const char * item_desc,
+ int item,
+ const char * fmt,
+ va_list arglist)
+{
+ bt_error err;
+#if !HAVE_VSNPRINTF
+ int msg_len;
+#endif
+
+ err.errclass = errclass;
+ err.filename = filename;
+ err.line = line;
+ err.item_desc = item_desc;
+ err.item = item;
+
+ errclass_counts[(int) errclass]++;
+
+
+ /*
+ * Blech -- we're writing to a static buffer because there's no easy
+ * way to know how long the error message is going to be. (Short of
+ * reimplementing printf(), or maybe printf()'ing to a dummy file
+ * and using the return value -- ugh!) The GNU C library conveniently
+ * supplies vsnprintf(), which neatly solves this problem by truncating
+ * the output string if it gets too long. (I could check for this
+ * truncation if I wanted to, but I don't think it's necessary given the
+ * ample size of the message buffer.) For non-GNU systems, though,
+ * we're stuck with using vsprintf()'s return value. This can't be
+ * trusted on all systems -- thus there's a check for it in configure.
+ * Also, this won't necessarily trigger the internal_error() if we
+ * do overflow; it's conceivable that vsprintf() itself would crash.
+ * At least doing it this way we avoid the possibility of vsprintf()
+ * silently corrupting some memory, and crashing unpredictably at some
+ * later point.
+ */
+
+#if HAVE_VSNPRINTF
+ vsnprintf (error_buf, MAX_ERROR, fmt, arglist);
+#else
+ msg_len = vsprintf (error_buf, fmt, arglist);
+ if (msg_len > MAX_ERROR)
+ internal_error ("static error message buffer overflowed");
+#endif
+
+ err.message = error_buf;
+ if (err_handlers[errclass])
+ (*err_handlers[errclass]) (&err);
+
+ switch (err_actions[errclass])
+ {
+ case BTACT_NONE: return;
+ case BTACT_CRASH: exit (1);
+ case BTACT_ABORT: abort ();
+ default: internal_error ("invalid error action %d for class %d (%s)",
+ (int) err_actions[errclass],
+ (int) errclass, errclass_names[errclass]);
+ }
+
+} /* report_error() */
+
+
+GEN_ERRFUNC (general_error,
+ (bt_errclass errclass,
+ char * filename,
+ int line,
+ const char * item_desc,
+ int item,
+ char * fmt,
+ ...),
+ errclass, filename, line, item_desc, item, fmt)
+
+GEN_ERRFUNC (error,
+ (bt_errclass errclass,
+ char * filename,
+ int line,
+ char * fmt,
+ ...),
+ errclass, filename, line, NULL, -1, fmt)
+
+GEN_ERRFUNC (ast_error,
+ (bt_errclass errclass,
+ AST * ast,
+ char * fmt,
+ ...),
+ errclass, ast->filename, ast->line, NULL, -1, fmt)
+
+GEN_ERRFUNC (notify,
+ (const char * fmt, ...),
+ BTERR_NOTIFY, NULL, -1, NULL, -1, fmt)
+
+GEN_ERRFUNC (usage_warning,
+ (const char * fmt, ...),
+ BTERR_USAGEWARN, NULL, -1, NULL, -1, fmt)
+
+GEN_ERRFUNC (usage_error,
+ (const char * fmt, ...),
+ BTERR_USAGEERR, NULL, -1, NULL, -1, fmt)
+
+GEN_ERRFUNC (internal_error,
+ (const char * fmt, ...),
+ BTERR_INTERNAL, NULL, -1, NULL, -1, fmt)
+
+
+/* ======================================================================
+ * Functions to be used outside of the library
+ */
+
+/* ------------------------------------------------------------------------
+@NAME : bt_reset_error_counts()
+@INPUT :
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Resets all the error counters to zero.
+@GLOBALS :
+@CALLS :
+@CREATED : 1997/01/08, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void bt_reset_error_counts (void)
+{
+ int i;
+
+ for (i = 0; i < NUM_ERRCLASSES; i++)
+ errclass_counts[i] = 0;
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_get_error_count()
+@INPUT : errclass
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Returns number of errors seen in the specified class.
+@GLOBALS : errclass_counts
+@CALLS :
+@CREATED :
+@MODIFIED :
+-------------------------------------------------------------------------- */
+int bt_get_error_count (bt_errclass errclass)
+{
+ return errclass_counts[errclass];
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_get_error_counts()
+@INPUT : counts - pointer to an array big enough to hold all the counts
+ if NULL, the array will be allocated for you (and you
+ must free() it when done with it)
+@OUTPUT :
+@RETURNS : counts - either the passed-in pointer, or the newly-
+ allocated array if you pass in NULL
+@DESCRIPTION: Returns a newly-allocated array with the number of errors
+ in each error class, indexed by the members of the
+ eclass_t enum.
+@GLOBALS : errclass_counts
+@CALLS :
+@CREATED : 1997/01/06, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+int *bt_get_error_counts (int *counts)
+{
+ int i;
+
+ if (counts == NULL)
+ counts = (int *) malloc (sizeof (int) * NUM_ERRCLASSES);
+ for (i = 0; i < NUM_ERRCLASSES; i++)
+ counts[i] = errclass_counts[i];
+
+ return counts;
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_error_status
+@INPUT : saved_counts - an array of error counts as returned by
+ bt_get_error_counts, or NULL not to compare
+ to a previous checkpoint
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Computes a bitmap where a bit is set for each error class
+ that has more errors now than it used to have (or, if
+ saved_counts is NULL, the bit is set of there are have been
+ any errors in the corresponding error class).
+
+ Eg. "x & (1<<E_SYNTAX)" (where x is returned by bt_error_status)
+ is true if there have been any syntax errors.
+@GLOBALS :
+@CALLS :
+@CREATED :
+@MODIFIED :
+-------------------------------------------------------------------------- */
+ushort bt_error_status (int *saved_counts)
+{
+ int i;
+ ushort status;
+
+ status = 0;
+
+ if (saved_counts)
+ {
+ for (i = 0; i < NUM_ERRCLASSES; i++)
+ status |= ( (errclass_counts[i] > saved_counts[i]) << i);
+ }
+ else
+ {
+ for (i = 0; i < NUM_ERRCLASSES; i++)
+ status |= ( (errclass_counts[i] > 0) << i);
+ }
+
+ return status;
+} /* bt_error_status () */
diff --git a/src/translators/btparse/error.h b/src/translators/btparse/error.h
new file mode 100644
index 0000000..aede151
--- /dev/null
+++ b/src/translators/btparse/error.h
@@ -0,0 +1,65 @@
+/* ------------------------------------------------------------------------
+@NAME : error.c
+@DESCRIPTION: Prototypes for the error-generating functions (i.e. functions
+ defined in error.c, and meant only for use elswhere in the
+ library).
+@CREATED : Summer 1996, Greg Ward
+@MODIFIED :
+@VERSION : $Id: error.h,v 1.11 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+
+#ifndef ERROR_H
+#define ERROR_H
+
+#include <stdarg.h>
+#include "btparse.h" /* for AST typedef */
+
+#define MAX_ERROR 1024
+
+#define ERRFUNC_BODY(class,filename,line,item_desc,item,format) \
+{ \
+ va_list arglist; \
+ \
+ va_start (arglist, format); \
+ report_error (class, filename, line, item_desc, item, format, arglist); \
+ va_end (arglist); \
+}
+
+#define GEN_ERRFUNC(name,params,class,filename,line,item_desc,item,format) \
+void name params \
+ERRFUNC_BODY (class, filename, line, item_desc, item, format)
+
+#define GEN_PRIVATE_ERRFUNC(name,params, \
+ class,filename,line,item_desc,item,format) \
+static GEN_ERRFUNC(name,params,class,filename,line,item_desc,item,format)
+
+/*
+ * Prototypes for functions exported by error.c but only used within
+ * the library -- functions that can be called by outsiders are declared
+ * in btparse.h.
+ */
+
+void print_error (bt_error *err);
+void report_error (bt_errclass class,
+ char * filename, int line, const char * item_desc, int item,
+ const char * format, va_list arglist);
+
+void general_error (bt_errclass class,
+ char * filename, int line, const char * item_desc, int item,
+ char * format, ...);
+void error (bt_errclass class, char * filename, int line, char * format, ...);
+void ast_error (bt_errclass class, AST * ast, char * format, ...);
+
+void notify (const char *format,...);
+void usage_warning (const char * format, ...);
+void usage_error (const char * format, ...);
+void internal_error (const char * format, ...);
+
+#endif
diff --git a/src/translators/btparse/format_name.c b/src/translators/btparse/format_name.c
new file mode 100644
index 0000000..d6c99ae
--- /dev/null
+++ b/src/translators/btparse/format_name.c
@@ -0,0 +1,841 @@
+/* ------------------------------------------------------------------------
+@NAME : format_name.c
+@DESCRIPTION: bt_format_name() and support functions: everything needed
+ to turn a bt_name structure (as returned by bt_split_name())
+ back into a string according to a highly customizable format.
+@GLOBALS :
+@CREATED :
+@MODIFIED :
+@VERSION : $Id: format_name.c,v 1.12 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+
+/*#include "bt_config.h"*/
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "btparse.h"
+#include "error.h"
+/*#include "my_dmalloc.h"*/
+#include "bt_debug.h"
+
+
+static char EmptyString[] = "";
+
+
+#if DEBUG
+/* prototypes to shut "gcc -Wmissing-prototypes" up */
+void print_tokens (char *partname, char **tokens, int num_tokens);
+void dump_name (bt_name * name);
+void dump_format (bt_name_format * format);
+#endif
+
+
+/* ----------------------------------------------------------------------
+ * Interface to create/customize bt_name_format structures
+ */
+
+/* ------------------------------------------------------------------------
+@NAME : bt_create_name_format
+@INPUT : parts - a string of letters (maximum four, from the set
+ f, v, l, j, with no repetition) denoting the order
+ and presence of name parts. Also used to determine
+ certain pre-part text strings.
+ abbrev_first - flag: should first names be abbreviated?
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Creates a bt_name_format structure, slightly customized
+ according to the caller's choice of token order and
+ whether to abbreviate the first name. Use
+ bt_free_name_format() to free the structure (and any sub-
+ structures that may be allocated here). Use
+ bt_set_format_text() and bt_set_format_options() for
+ further customization of the format structure; do not
+ fiddle its fields directly.
+
+ Fills in the structures `parts' field according to `parts'
+ string: 'f' -> BTN_FIRST, and so on.
+
+ Sets token join methods: inter-token join (within each part)
+ is set to BTJ_MAYTIE (a "discretionary tie") for all parts;
+ inter-part join is set to BTJ_SPACE, except for a 'von'
+ token immediately preceding a 'last' token; there, we have
+ a discretionary tie.
+
+ Sets abbreviation flags: FALSE for everything except `first',
+ which follows `abbrev_first' argument.
+
+ Sets surrounding text (pre- and post-part, pre- and post-
+ token): empty string for everything, except:
+ - post-token for 'first' is "." if abbrev_first true
+ - if 'jr' immediately preceded by 'last':
+ pre-part for 'jr' is ", ", join for 'last' is nothing
+ - if 'first' immediately preceded by 'last'
+ pre-part for 'first' is ", " , join for 'last' is nothing
+ - if 'first' immediately preceded by 'jr' and 'jr' immediately
+ preceded by 'last':
+ pre-part for 'first' and 'jr' is ", " ,
+ join for 'last' and 'jr' is nothing
+@CREATED : 1997/11/02, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+bt_name_format *
+bt_create_name_format (char * parts, boolean abbrev_first)
+{
+ int num_parts;
+ int num_valid_parts;
+ bt_name_format *
+ format;
+ int part_pos[BT_MAX_NAMEPARTS];
+ int i;
+
+ /*
+ * Check that the part list (a string with one letter -- f, v, l, or j
+ * -- for each part is valid: no longer than four characters, and no
+ * invalid characters.
+ */
+
+ num_parts = strlen (parts);
+ num_valid_parts = strspn (parts, BT_VALID_NAMEPARTS);
+ if (num_parts > BT_MAX_NAMEPARTS)
+ {
+ usage_error ("bt_create_name_format: part list must have no more than "
+ "%d letters", BT_MAX_NAMEPARTS);
+ }
+ if (num_valid_parts != num_parts)
+ {
+ usage_error ("bt_create_name_format: bad part abbreviation \"%c\" "
+ "(must be one of \"%s\")",
+ parts[num_valid_parts], BT_VALID_NAMEPARTS);
+ }
+
+
+ /* User input is OK -- let's create the structure */
+
+ format = (bt_name_format *) malloc (sizeof (bt_name_format));
+ format->num_parts = num_parts;
+ for (i = 0; i < num_parts; i++)
+ {
+ switch (parts[i])
+ {
+ case 'f': format->parts[i] = BTN_FIRST; break;
+ case 'v': format->parts[i] = BTN_VON; break;
+ case 'l': format->parts[i] = BTN_LAST; break;
+ case 'j': format->parts[i] = BTN_JR; break;
+ default: internal_error ("bad part abbreviation \"%c\"", parts[i]);
+ }
+ part_pos[format->parts[i]] = i;
+ }
+ for (; i < BT_MAX_NAMEPARTS; i++)
+ {
+ format->parts[i] = BTN_NONE;
+ }
+
+
+ /*
+ * Set the token join methods: between tokens for all parts is a
+ * discretionary tie, and the join between parts is a space (except for
+ * 'von': if followed by 'last', we will have a discretionary tie).
+ */
+ for (i = 0; i < num_parts; i++)
+ {
+ format->join_tokens[i] = BTJ_MAYTIE;
+ format->join_part[i] = BTJ_SPACE;
+ }
+ if (part_pos[BTN_VON] + 1 == part_pos[BTN_LAST])
+ format->join_part[BTN_VON] = BTJ_MAYTIE;
+
+
+ /*
+ * Now the abbreviation flags: follow 'abbrev_first' flag for 'first',
+ * and FALSE for everything else.
+ */
+ format->abbrev[BTN_FIRST] = abbrev_first;
+ format->abbrev[BTN_VON] = FALSE;
+ format->abbrev[BTN_LAST] = FALSE;
+ format->abbrev[BTN_JR] = FALSE;
+
+
+
+ /*
+ * Now fill in the "surrounding text" fields (pre- and post-part, pre-
+ * and post-token) -- start out with everything NULL (empty string),
+ * and then tweak it to handle abbreviated first names, 'jr' following
+ * 'last', and 'first' following 'last' or 'last' and 'jr'. In the
+ * last three cases, we put in some pre-part text (", "), and also
+ * set the join method for the *previous* part (jr or last) to
+ * BTJ_NOTHING, so we don't get extraneous space before the ", ".
+ */
+ for (i = 0; i < BT_MAX_NAMEPARTS; i++)
+ {
+ format->pre_part[i] = EmptyString;
+ format->post_part[i] = EmptyString;
+ format->pre_token[i] = EmptyString;
+ format->post_token[i] = EmptyString;
+ }
+
+ /* abbreviated first name:
+ * "Blow J" -> "Blow J.", or "J Blow" -> "J. Blow"
+ */
+ if (abbrev_first)
+ {
+ format->post_token[BTN_FIRST] = ".";
+ }
+ /* 'jr' after 'last': "Joe Blow Jr." -> "Joe Blow, Jr." */
+ if (part_pos[BTN_JR] == part_pos[BTN_LAST]+1)
+ {
+ format->pre_part[BTN_JR] = ", ";
+ format->join_part[BTN_LAST] = BTJ_NOTHING;
+ /* 'first' after 'last' and 'jr': "Blow, Jr. Joe"->"Blow, Jr., Joe" */
+ if (part_pos[BTN_FIRST] == part_pos[BTN_JR]+1)
+ {
+ format->pre_part[BTN_FIRST] = ", ";
+ format->join_part[BTN_JR] = BTJ_NOTHING;
+ }
+ }
+ /* first after last: "Blow Joe" -> "Blow, Joe" */
+ if (part_pos[BTN_FIRST] == part_pos[BTN_LAST]+1)
+ {
+ format->pre_part[BTN_FIRST] = ", ";
+ format->join_part[BTN_LAST] = BTJ_NOTHING;
+ }
+
+ DBG_ACTION
+ (1, printf ("bt_create_name_format(): returning structure %p\n", format))
+
+ return format;
+
+} /* bt_create_name_format() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_free_name_format()
+@INPUT : format - free()'d, so this is an invalid pointer after the call
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Frees a bt_name_format structure created by
+ bt_create_name_format().
+@CREATED : 1997/11/02, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void
+bt_free_name_format (bt_name_format * format)
+{
+ free (format);
+}
+
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_set_format_text
+@INPUT : format - the format structure to update
+ part - which name-part to change the surrounding text for
+ pre_part - "pre-part" text, or NULL to leave alone
+ post_part - "post-part" text, or NULL to leave alone
+ pre_token - "pre-token" text, or NULL to leave alone
+ post_token - "post-token" text, or NULL to leave alone
+@OUTPUT : format - pre_part, post_part, pre_token, post_token
+ arrays updated (only those with corresponding
+ non-NULL parameters are touched)
+@RETURNS :
+@DESCRIPTION: Sets the "surrounding text" for a particular name part in
+ a name format structure.
+@CREATED : 1997/11/02, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void
+bt_set_format_text (bt_name_format * format,
+ bt_namepart part,
+ char * pre_part,
+ char * post_part,
+ char * pre_token,
+ char * post_token)
+{
+ if (pre_part) format->pre_part[part] = pre_part;
+ if (post_part) format->post_part[part] = post_part;
+ if (pre_token) format->pre_token[part] = pre_token;
+ if (post_token) format->post_token[part] = post_token;
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_set_format_options()
+@INPUT : format
+ part
+ abbrev
+ join_tokens
+ join_part
+@OUTPUT : format - abbrev, join_tokens, join_part arrays all updated
+@RETURNS :
+@DESCRIPTION: Sets various formatting options for a particular name part in
+ a name format structure.
+@CREATED : 1997/11/02, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void
+bt_set_format_options (bt_name_format * format,
+ bt_namepart part,
+ boolean abbrev,
+ bt_joinmethod join_tokens,
+ bt_joinmethod join_part)
+{
+ format->abbrev[part] = abbrev;
+ format->join_tokens[part] = join_tokens;
+ format->join_part[part] = join_part;
+}
+
+
+
+/* ----------------------------------------------------------------------
+ * Functions for actually formatting a name (given a name and a name
+ * format structure).
+ */
+
+/* ------------------------------------------------------------------------
+@NAME : count_virtual_char()
+@INPUT : string
+ offset
+@OUTPUT : vchar_count
+@INOUT : depth
+ in_special
+@RETURNS :
+@DESCRIPTION: Munches a single physical character from a string, updating
+ the virtual character count, the depth, and an "in special
+ character" flag.
+
+ The virtual character count is incremented by any character
+ not part of a special character, and also by the right-brace
+ that closes a special character. The depth is incremented by
+ a left brace, and decremented by a right brace. in_special
+ is set to TRUE when we encounter a left brace at depth zero
+ that is immediately followed by a backslash; it is set to
+ false when we encounter the end of the special character,
+ i.e. when in_special is TRUE and we hit a right brace that
+ brings us back to depth zero.
+
+ *vchar_count and *depth should both be set to zero the first
+ time you call count_virtual_char() on a particular string,
+ and in_special should be set to FALSE.
+@CALLS :
+@CALLERS : string_length()
+ string_prefix()
+@CREATED : 1997/11/03, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static void
+count_virtual_char (char * string,
+ int offset,
+ int * vchar_count,
+ int * depth,
+ boolean * in_special)
+{
+ switch (string[offset])
+ {
+ case '{':
+ {
+ /* start of a special char? */
+ if (*depth == 0 && string[offset+1] == '\\')
+ *in_special = TRUE;
+ (*depth)++;
+ break;
+ }
+ case '}':
+ {
+ /* end of a special char? */
+ if (*depth == 1 && *in_special)
+ {
+ *in_special = FALSE;
+ (*vchar_count)++;
+ }
+ (*depth)--;
+ break;
+ }
+ default:
+ {
+ /* anything else? (possibly inside a special char) */
+ if (! *in_special) (*vchar_count)++;
+ }
+ }
+} /* count_virtual_char () */
+
+
+/* this should probably be publicly available, documented, etc. */
+/* ------------------------------------------------------------------------
+@NAME : string_length()
+@INPUT : string
+@OUTPUT :
+@RETURNS : "virtual length" of `string'
+@DESCRIPTION: Counts the number of "virtual characters" in a string. A
+ virtual character is either an entire BibTeX special character,
+ or any character outside of a special character.
+
+ Thus, "Hello" has virtual length 5, and so does
+ "H{\\'e}ll{\\\"o}". "{\\noop Hello there how are you?}" has
+ virtual length one.
+@CALLS : count_virtual_char()
+@CALLERS : format_name()
+@CREATED : 1997/11/03, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static int
+string_length (char * string)
+{
+ int length;
+ int depth;
+ boolean in_special;
+ int i;
+
+ length = 0;
+ depth = 0;
+ in_special = FALSE;
+
+ for (i = 0; string[i] != 0; i++)
+ {
+ count_virtual_char (string, i, &length, &depth, &in_special);
+ }
+
+ return length;
+} /* string_length() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : string_prefix()
+@INPUT : string
+ prefix_len
+@OUTPUT :
+@RETURNS : physical length of the prefix of `string' with a virtual length
+ of `prefix_len'
+@DESCRIPTION: Counts the number of physical characters from the beginning
+ of `string' needed to extract a sub-string with virtual
+ length `prefix_len'.
+@CALLS : count_virtual_char()
+@CALLERS : format_name()
+@CREATED : 1997/11/03, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static int
+string_prefix (char * string, int prefix_len)
+{
+ int i;
+ int vchars_seen;
+ int depth;
+ boolean in_special;
+
+ vchars_seen = 0;
+ depth = 0;
+ in_special = FALSE;
+
+ for (i = 0; string[i] != 0; i++)
+ {
+ count_virtual_char (string, i, &vchars_seen, &depth, &in_special);
+ if (vchars_seen == prefix_len)
+ return i+1;
+ }
+
+ return i;
+
+} /* string_prefix() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : append_text()
+@INOUT : string
+@INPUT : offset
+ text
+ start
+ len
+@OUTPUT :
+@RETURNS : number of characters copied from text+start to string+offset
+@DESCRIPTION: Copies at most `len' characters from text+start to
+ string+offset. (I don't use strcpy() or strncpy() for this
+ because I need to get the number of characters actually
+ copied.)
+@CALLS :
+@CALLERS : format_name()
+@CREATED : 1997/11/03, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static int
+append_text (char * string,
+ int offset,
+ const char * text,
+ int start,
+ int len)
+{
+ int i;
+
+ if (text == NULL) return 0; /* no text -- none appended! */
+
+ for (i = 0; text[start+i] != 0; i++)
+ {
+ if (len > 0 && i == len)
+ break; /* exit loop without i++, right?!? */
+ string[offset+i] = text[start+i];
+ } /* for i */
+
+ return i; /* number of characters copied */
+
+} /* append_text () */
+
+
+/* ------------------------------------------------------------------------
+@NAME : append_join
+@INOUT : string
+@INPUT : offset
+ method
+ should_tie
+@OUTPUT :
+@RETURNS : number of charactersa appended to string+offset (either 0 or 1)
+@DESCRIPTION: Copies a "join character" ('~' or ' ') or nothing to
+ string+offset, according to the join method specified by
+ `method' and the `should_tie' flag.
+
+ Specifically: if `method' is BTJ_SPACE, a space is appended
+ and 1 is returned; if `method' is BTJ_FORCETIE, a TeX "tie"
+ character ('~') is appended and 1 is returned. If `method'
+ is BTJ_NOTHING, `string' is unchanged and 0 is returned. If
+ `method' is BTJ_MAYTIE then either a tie (if should_tie is
+ true) or a space (otherwise) is appended, and 1 is returned.
+@CALLS :
+@CALLERS : format_name()
+@CREATED : 1997/11/03, GPW
+@MODIFIED :
+@COMMENTS : This should allow "tie" strings other than TeX's '~' -- I
+ think this could be done by putting a "tie string" field in
+ the name format structure, and using it here.
+-------------------------------------------------------------------------- */
+static int
+append_join (char * string,
+ int offset,
+ bt_joinmethod method,
+ boolean should_tie)
+{
+ switch (method)
+ {
+ case BTJ_MAYTIE: /* a "discretionary tie" -- pay */
+ { /* attention to should_tie */
+ if (should_tie)
+ string[offset] = '~';
+ else
+ string[offset] = ' ';
+ return 1;
+ }
+ case BTJ_SPACE:
+ {
+ string[offset] = ' ';
+ return 1;
+ }
+ case BTJ_FORCETIE:
+ {
+ string[offset] = '~';
+ return 1;
+ }
+ case BTJ_NOTHING:
+ {
+ return 0;
+ }
+ default:
+ internal_error ("bad token join method %d", (int) method);
+ }
+
+ return 0; /* can't happen -- just here to */
+ /* keep gcc -Wall happy */
+} /* append_join () */
+
+
+#define STRLEN(s) (s == NULL) ? 0 : strlen (s)
+
+/* ------------------------------------------------------------------------
+@NAME : format_firstpass()
+@INPUT : name
+ format
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Makes the first pass over a name for formatting, in order to
+ establish an upper bound on the length of the formatted name.
+@CALLS :
+@CALLERS : bt_format_name()
+@CREATED : 1997/11/03, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static unsigned
+format_firstpass (bt_name * name,
+ bt_name_format * format)
+{
+ int i; /* loop over parts */
+ int j; /* loop over tokens */
+ unsigned max_length;
+ bt_namepart part;
+ char ** tok;
+ int num_tok;
+
+ max_length = 0;
+
+ for (i = 0; i < format->num_parts; i++)
+ {
+ part = format->parts[i]; /* 'cause I'm a lazy typist */
+ tok = name->parts[part];
+ num_tok = name->part_len[part];
+
+ assert ((tok != NULL) == (num_tok > 0));
+ if (tok)
+ {
+ max_length += STRLEN (format->pre_part[part]);
+ max_length += STRLEN (format->post_part[part]);
+ max_length += STRLEN (format->pre_token[part]) * num_tok;
+ max_length += STRLEN (format->post_token[part]) * num_tok;
+ max_length += num_tok + 1; /* one join char per token, plus */
+ /* join char to next part */
+
+ /*
+ * We ignore abbreviation here -- just overestimates the maximum
+ * length, so no big deal. Also saves us the bother of computing
+ * the physical length of the prefix of virtual length 1.
+ */
+ for (j = 0; j < num_tok; j++)
+ max_length += strlen (tok[j]);
+ }
+
+ } /* for i (loop over parts) */
+
+ return max_length;
+
+} /* format_firstpass() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : format_name()
+@INPUT : format
+ tokens - token list (eg. from format_firstpass())
+ num_tokens - token count list (eg. from format_firstpass())
+@OUTPUT : fname - filled in, must be preallocated by caller
+@RETURNS :
+@DESCRIPTION: Performs the second pass over a name and format, to actually
+ put the name into a single string according to `format'.
+@CALLS :
+@CALLERS : bt_format_name()
+@CREATED : 1997/11/03, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static void
+format_name (bt_name_format * format,
+ char *** tokens,
+ int * num_tokens,
+ char * fname)
+{
+ bt_namepart parts[BT_MAX_NAMEPARTS]; /* culled list from format */
+ int num_parts;
+
+ int offset; /* into fname */
+ int i; /* loop over parts */
+ int j; /* loop over tokens */
+ bt_namepart part;
+ int prefix_len;
+ int token_len; /* "physical" length (characters) */
+ int token_vlen; /* "virtual" length (special char */
+ /* counts as one character) */
+ boolean should_tie;
+
+ /*
+ * Cull format->parts down by keeping only those parts that are actually
+ * present in the current name (keeps the main loop simpler: makes it
+ * easy to know if the "next part" is present or not, so we know whether
+ * to append a join character.
+ */
+ num_parts = 0;
+ for (i = 0; i < format->num_parts; i++)
+ {
+ part = format->parts[i];
+ if (tokens[part]) /* name actually has this part */
+ parts[num_parts++] = part;
+ }
+
+ offset = 0;
+ token_vlen = -1; /* sanity check, and keeps */
+ /* "gcc -O -Wall" happy */
+
+ for (i = 0; i < num_parts; i++)
+ {
+ part = parts[i];
+
+ offset += append_text (fname, offset,
+ format->pre_part[part], 0, -1);
+
+ for (j = 0; j < num_tokens[part]; j++)
+ {
+ offset += append_text (fname, offset,
+ format->pre_token[part], 0, -1);
+ if (format->abbrev[part])
+ {
+ prefix_len = string_prefix (tokens[part][j], 1);
+ token_len = append_text (fname, offset,
+ tokens[part][j], 0, prefix_len);
+ token_vlen = 1;
+ }
+ else
+ {
+ token_len = append_text (fname, offset,
+ tokens[part][j], 0, -1);
+ token_vlen = string_length (tokens[part][j]);
+ }
+ offset += token_len;
+ offset += append_text (fname, offset,
+ format->post_token[part], 0, -1);
+
+ /* join to next token, but only if there is a next token! */
+ if (j < num_tokens[part]-1)
+ {
+ should_tie = (num_tokens[part] > 1)
+ && (((j == 0) && (token_vlen < 3))
+ || (j == num_tokens[part]-2));
+ offset += append_join (fname, offset,
+ format->join_tokens[part], should_tie);
+ }
+
+ } /* for j */
+
+ offset += append_text (fname, offset,
+ format->post_part[part], 0, -1);
+ /* join to the next part, but again only if there is a next part */
+ if (i < num_parts-1)
+ {
+ if (token_vlen == -1)
+ {
+ internal_error ("token_vlen uninitialized -- no tokens in a part "
+ "that I checked existed");
+ }
+ should_tie = (num_tokens[part] == 1 && token_vlen < 3);
+ offset += append_join (fname, offset,
+ format->join_part[part], should_tie);
+ }
+
+ } /* for i (loop over parts) */
+
+ fname[offset] = 0;
+
+} /* format_name () */
+
+
+#if DEBUG
+
+#define STATIC /* so BibTeX.xs can call 'em too */
+
+/* borrowed print_tokens() and dump_name() from t/name_test.c */
+STATIC void
+print_tokens (char *partname, char **tokens, int num_tokens)
+{
+ int i;
+
+ if (tokens)
+ {
+ printf ("%s = (", partname);
+ for (i = 0; i < num_tokens; i++)
+ {
+ printf ("%s%c", tokens[i], i == num_tokens-1 ? ')' : '|');
+ }
+ putchar ('\n');
+ }
+}
+
+
+STATIC void
+dump_name (bt_name * name)
+{
+ if (name == NULL)
+ {
+ printf (" name: null\n");
+ return;
+ }
+
+ if (name->tokens == NULL)
+ {
+ printf (" name: null token list\n");
+ return;
+ }
+
+ printf (" name (%p):\n", name);
+ printf (" total number of tokens = %d\n", name->tokens->num_items);
+ print_tokens (" first", name->parts[BTN_FIRST], name->part_len[BTN_FIRST]);
+ print_tokens (" von", name->parts[BTN_VON], name->part_len[BTN_VON]);
+ print_tokens (" last", name->parts[BTN_LAST], name->part_len[BTN_LAST]);
+ print_tokens (" jr", name->parts[BTN_JR], name->part_len[BTN_JR]);
+}
+
+
+STATIC void
+dump_format (bt_name_format * format)
+{
+ int i;
+ static char * nameparts[] = { "first", "von", "last", "jr" };
+ static char * joinmethods[] = {"may tie", "space", "force tie", "nothing"};
+
+ printf (" name format (%p):\n", format);
+ printf (" order:");
+ for (i = 0; i < format->num_parts; i++)
+ printf (" %s", nameparts[format->parts[i]]);
+ printf ("\n");
+
+ for (i = 0; i < BT_MAX_NAMEPARTS; i++)
+ {
+ printf (" %-5s: pre-part=%p (%s), post-part=%p (%s)\n",
+ nameparts[i],
+ format->pre_part[i], format->pre_part[i],
+ format->post_part[i], format->post_part[i]);
+ printf (" %-5s pre-token=%p (%s), post-token=%p (%s)\n",
+ "",
+ format->pre_token[i], format->pre_token[i],
+ format->post_token[i],format->post_token[i]);
+ printf (" %-5s abbrev=%s, join_tokens=%s, join_parts=%s\n",
+ "",
+ format->abbrev[i] ? "yes" : "no",
+ joinmethods[format->join_tokens[i]],
+ joinmethods[format->join_part[i]]);
+ }
+}
+#endif
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_format_name()
+@INPUT : name
+ format
+@OUTPUT :
+@RETURNS : formatted name (allocated with malloc(); caller must free() it)
+@DESCRIPTION: Formats an already-split name according to a pre-constructed
+ format structure.
+@GLOBALS :
+@CALLS : format_firstpass(), format_name()
+@CALLERS :
+@CREATED : 1997/11/03, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+char *
+bt_format_name (bt_name * name,
+ bt_name_format * format)
+{
+ unsigned max_length;
+ char * fname;
+
+#if DEBUG >= 2
+ printf ("bt_format_name():\n");
+ dump_name (name);
+ dump_format (format);
+#endif
+
+ max_length = format_firstpass (name, format);
+ fname = (char *) malloc ((max_length+1) * sizeof (char));
+#if 0
+ memset (fname, '_', max_length);
+ fname[max_length] = 0;
+#endif
+ format_name (format, name->parts, name->part_len, fname);
+ assert (strlen (fname) <= max_length);
+ return fname;
+
+} /* bt_format_name() */
diff --git a/src/translators/btparse/init.c b/src/translators/btparse/init.c
new file mode 100644
index 0000000..4a1ec06
--- /dev/null
+++ b/src/translators/btparse/init.c
@@ -0,0 +1,42 @@
+/* ------------------------------------------------------------------------
+@NAME : init.c
+@DESCRIPTION: Initialization and cleanup functions for the btparse library.
+@GLOBALS :
+@CALLS :
+@CREATED : 1997/01/19, Greg Ward
+@MODIFIED :
+@VERSION : $Id: init.c,v 1.8 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+
+/*#include "bt_config.h"*/
+#include "stdpccts.h" /* for zzfree_ast() prototype */
+#include "parse_auxiliary.h" /* for fix_token_names() proto */
+#include "prototypes.h" /* for other prototypes */
+/*#include "my_dmalloc.h"*/
+
+void bt_initialize (void)
+{
+ /* Initialize data structures */
+
+ fix_token_names ();
+ init_macros ();
+}
+
+
+void bt_free_ast (AST *ast)
+{
+ zzfree_ast (ast);
+}
+
+
+void bt_cleanup (void)
+{
+ done_macros ();
+}
diff --git a/src/translators/btparse/input.c b/src/translators/btparse/input.c
new file mode 100644
index 0000000..dbb7b44
--- /dev/null
+++ b/src/translators/btparse/input.c
@@ -0,0 +1,499 @@
+/* ------------------------------------------------------------------------
+@NAME : input.c
+@DESCRIPTION: Routines for input of BibTeX data.
+@GLOBALS : InputFilename
+ StringOptions
+@CALLS :
+@CREATED : 1997/10/14, Greg Ward (from code in bibparse.c)
+@MODIFIED :
+@VERSION : $Id: input.c,v 1.18 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+/*#include "bt_config.h"*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <assert.h>
+#include "stdpccts.h"
+#include "lex_auxiliary.h"
+#include "prototypes.h"
+#include "error.h"
+/*#include "my_dmalloc.h"*/
+
+
+char * InputFilename;
+ushort StringOptions[NUM_METATYPES] =
+{
+ 0, /* BTE_UNKNOWN */
+ BTO_FULL, /* BTE_REGULAR */
+ BTO_MINIMAL, /* BTE_COMMENT */
+ BTO_MINIMAL, /* BTE_PREAMBLE */
+ BTO_MACRO /* BTE_MACRODEF */
+};
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_set_filename
+@INPUT : filename
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Sets the current input filename -- used for generating
+ error and warning messages.
+@GLOBALS : InputFilename
+@CALLS :
+@CREATED : Feb 1997, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+#if 0
+void bt_set_filename (char *filename)
+{
+ InputFilename = filename;
+}
+#endif
+
+/* ------------------------------------------------------------------------
+@NAME : bt_set_stringopts
+@INPUT : metatype
+ options
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Sets the string-processing options for a particular
+ entry metatype. Used later on by bt_parse_* to determine
+ just how to post-process each particular entry.
+@GLOBALS : StringOptions
+@CREATED : 1997/08/24, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void bt_set_stringopts (bt_metatype metatype, ushort options)
+{
+ if (metatype < BTE_REGULAR || metatype > BTE_MACRODEF)
+ usage_error ("bt_set_stringopts: illegal metatype");
+ if (options & ~BTO_STRINGMASK)
+ usage_error ("bt_set_stringopts: illegal options "
+ "(must only set string option bits");
+
+ StringOptions[metatype] = options;
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : start_parse
+@INPUT : infile input stream we'll read from (or NULL if reading
+ from string)
+ instring input string we'll read from (or NULL if reading
+ from stream)
+ line line number of the start of the string (just
+ use 1 if the string is standalone and independent;
+ if it comes from a file, you should supply the
+ line number where it starts for better error
+ messages) (ignored if infile != NULL)
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Prepares things for parsing, in particular initializes the
+ lexical state and lexical buffer, prepares DLG for
+ reading (either from a stream or a string), and reads
+ the first token.
+@GLOBALS :
+@CALLS : initialize_lexer_state()
+ alloc_lex_buffer()
+ zzrdstream() or zzrdstr()
+ zzgettok()
+@CALLERS :
+@CREATED : 1997/06/21, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static void
+start_parse (FILE *infile, char *instring, int line)
+{
+ if ( (infile == NULL) == (instring == NULL) )
+ {
+ internal_error ("start_parse(): exactly one of infile and "
+ "instring may be non-NULL");
+ }
+ initialize_lexer_state ();
+ alloc_lex_buffer (ZZLEXBUFSIZE);
+ if (infile)
+ {
+ zzrdstream (infile);
+ }
+ else
+ {
+ zzrdstr (instring);
+ zzline = line;
+ }
+
+ zzendcol = zzbegcol = 0;
+ zzgettok ();
+}
+
+
+
+/* ------------------------------------------------------------------------
+@NAME : finish_parse()
+@INPUT : err_counts - pointer to error count list (which is local to
+ the parsing functions, hence has to be passed in)
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Frees up what was needed to parse a whole file or a sequence
+ of strings: the lexical buffer and the error count list.
+@GLOBALS :
+@CALLS : free_lex_buffer()
+@CALLERS :
+@CREATED : 1997/06/21, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static void
+finish_parse (int **err_counts)
+{
+ free_lex_buffer ();
+ free (*err_counts);
+ *err_counts = NULL;
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : parse_status()
+@INPUT : saved_counts
+@OUTPUT :
+@RETURNS : false if there were serious errors in the recently-parsed input
+ true otherwise (no errors or just warnings)
+@DESCRIPTION: Gets the "error status" bitmap relative to a saved set of
+ error counts and masks of non-serious errors.
+@GLOBALS :
+@CALLS :
+@CALLERS :
+@CREATED : 1997/06/21, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static boolean
+parse_status (int *saved_counts)
+{
+ ushort ignore_emask;
+
+ /*
+ * This bit-twiddling fetches the error status (which has a bit
+ * for each error class), masks off the bits for trivial errors
+ * to get "true" if there were any serious errors, and then
+ * returns the opposite of that.
+ */
+ ignore_emask =
+ (1<<BTERR_NOTIFY) | (1<<BTERR_CONTENT) | (1<<BTERR_LEXWARN);
+ return !(bt_error_status (saved_counts) & ~ignore_emask);
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_parse_entry_s()
+@INPUT : entry_text - string containing the entire entry to parse,
+ or NULL meaning we're done, please cleanup
+ options - standard btparse options bitmap
+ line - current line number (if that makes any sense)
+ -- passed to the parser to set zzline, so that
+ lexical and syntax errors are properly localized
+@OUTPUT : *top - newly-allocated AST for the entry
+ (or NULL if entry_text was NULL, ie. at EOF)
+@RETURNS : 1 with *top set to AST for entry on successful read/parse
+ 1 with *top==NULL if entry_text was NULL, ie. at EOF
+ 0 if any serious errors seen in input (*top is still
+ set to the AST, but only for as much of the input as we
+ were able to parse)
+ (A "serious" error is a lexical or syntax error; "trivial"
+ errors such as warnings and notifications count as "success"
+ for the purposes of this function's return value.)
+@DESCRIPTION: Parses a BibTeX entry contained in a string.
+@GLOBALS :
+@CALLS : ANTLR
+@CREATED : 1997/01/18, GPW (from code in bt_parse_entry())
+@MODIFIED :
+-------------------------------------------------------------------------- */
+AST * bt_parse_entry_s (char * entry_text,
+ char * filename,
+ int line,
+ ushort options,
+ boolean * status)
+{
+ AST * entry_ast = NULL;
+ static int * err_counts = NULL;
+
+ if (options & BTO_STRINGMASK) /* any string options set? */
+ {
+ usage_error ("bt_parse_entry_s: illegal options "
+ "(string options not allowed");
+ }
+
+ InputFilename = filename;
+ err_counts = bt_get_error_counts (err_counts);
+
+ if (entry_text == NULL) /* signal to clean up */
+ {
+ finish_parse (&err_counts);
+ if (status) *status = TRUE;
+ return NULL;
+ }
+
+ zzast_sp = ZZAST_STACKSIZE; /* workaround apparent pccts bug */
+ start_parse (NULL, entry_text, line);
+
+ entry (&entry_ast); /* enter the parser */
+ ++zzasp; /* why is this done? */
+
+ if (entry_ast == NULL) /* can happen with very bad input */
+ {
+ if (status) *status = FALSE;
+ return entry_ast;
+ }
+
+#if DEBUG
+ dump_ast ("bt_parse_entry_s: single entry, after parsing:\n",
+ entry_ast);
+#endif
+ bt_postprocess_entry (entry_ast,
+ StringOptions[entry_ast->metatype] | options);
+#if DEBUG
+ dump_ast ("bt_parse_entry_s: single entry, after post-processing:\n",
+ entry_ast);
+#endif
+
+ if (status) *status = parse_status (err_counts);
+ return entry_ast;
+
+} /* bt_parse_entry_s () */
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_parse_entry()
+@INPUT : infile - file to read next entry from
+ options - standard btparse options bitmap
+@OUTPUT : *top - AST for the entry, or NULL if no entries left in file
+@RETURNS : same as bt_parse_entry_s()
+@DESCRIPTION: Starts (or continues) parsing from a file.
+@GLOBALS :
+@CALLS :
+@CREATED : Jan 1997, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+AST * bt_parse_entry (FILE * infile,
+ char * filename,
+ ushort options,
+ boolean * status)
+{
+ AST * entry_ast = NULL;
+ static int * err_counts = NULL;
+ static FILE * prev_file = NULL;
+
+ if (prev_file != NULL && infile != prev_file)
+ {
+ usage_error ("bt_parse_entry: you can't interleave calls "
+ "across different files");
+ }
+
+ if (options & BTO_STRINGMASK) /* any string options set? */
+ {
+ usage_error ("bt_parse_entry: illegal options "
+ "(string options not allowed)");
+ }
+
+ InputFilename = filename;
+ err_counts = bt_get_error_counts (err_counts);
+
+ if (feof (infile))
+ {
+ if (prev_file != NULL) /* haven't already done the cleanup */
+ {
+ prev_file = NULL;
+ finish_parse (&err_counts);
+ }
+ else
+ {
+ usage_warning ("bt_parse_entry: second attempt to read past eof");
+ }
+
+ if (status) *status = TRUE;
+ return NULL;
+ }
+
+ /*
+ * Here we do some nasty poking about the innards of PCCTS in order to
+ * enter the parser multiple times on the same input stream. This code
+ * comes from expanding the macro invokation:
+ *
+ * ANTLR (entry (top), infile);
+ *
+ * When LL_K, ZZINF_LOOK, and DEMAND_LOOK are all undefined, this
+ * ultimately expands to
+ *
+ * zzbufsize = ZZLEXBUFSIZE;
+ * {
+ * static char zztoktext[ZZLEXBUFSIZE];
+ * zzlextext = zztoktext;
+ * zzrdstream (f);
+ * zzgettok();
+ * }
+ * entry (top);
+ * ++zzasp;
+ *
+ * (I'm expanding hte zzenterANTLR, zzleaveANTLR, and zzPrimateLookAhead
+ * macros, but leaving ZZLEXBUFSIZE -- a simple constant -- alone.)
+ *
+ * There are two problems with this: 1) zztoktext is a statically
+ * allocated buffer, and when it overflows we just ignore further
+ * characters that should belong to that lexeme; and 2) zzrdstream() and
+ * zzgettok() are called every time we enter the parser, which means the
+ * token left over from the previous entry will be discarded when we
+ * parse entries 2 .. N.
+ *
+ * I handle the static buffer problem with alloc_lex_buffer() and
+ * realloc_lex_buffer() (in lex_auxiliary.c), and by rewriting the ZZCOPY
+ * macro to call realloc_lex_buffer() when overflow is detected.
+ *
+ * I handle the extra token-read by hanging on to a static file
+ * pointer, prev_file, between calls to bt_parse_entry() -- when
+ * the program starts it is NULL, and we reset it to NULL on
+ * finishing a file. Thus, any call that is the first on a given
+ * file will allocate the lexical buffer and read the first token;
+ * thereafter, we skip those steps, and free the buffer on reaching
+ * end-of-file. Currently, this method precludes interleaving
+ * calls to bt_parse_entry() on different files -- perhaps I could
+ * fix this with the zz{save,restore}_{antlr,dlg}_state()
+ * functions?
+ */
+
+ zzast_sp = ZZAST_STACKSIZE; /* workaround apparent pccts bug */
+
+#if defined(LL_K) || defined(ZZINF_LOOK) || defined(DEMAND_LOOK)
+# error One of LL_K, ZZINF_LOOK, or DEMAND_LOOK was defined
+#endif
+ if (prev_file == NULL) /* only read from input stream if */
+ { /* starting afresh with a file */
+ start_parse (infile, NULL, 0);
+ prev_file = infile;
+ }
+ assert (prev_file == infile);
+
+ entry (&entry_ast); /* enter the parser */
+ ++zzasp; /* why is this done? */
+
+ if (entry_ast == NULL) /* can happen with very bad input */
+ {
+ if (status) *status = FALSE;
+ return entry_ast;
+ }
+
+#if DEBUG
+ dump_ast ("bt_parse_entry(): single entry, after parsing:\n",
+ entry_ast);
+#endif
+ bt_postprocess_entry (entry_ast,
+ StringOptions[entry_ast->metatype] | options);
+#if DEBUG
+ dump_ast ("bt_parse_entry(): single entry, after post-processing:\n",
+ entry_ast);
+#endif
+
+ if (status) *status = parse_status (err_counts);
+ return entry_ast;
+
+} /* bt_parse_entry() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_parse_file ()
+@INPUT : filename - name of file to open. If NULL or "-", we read
+ from stdin rather than opening a new file.
+ options
+@OUTPUT : top
+@RETURNS : 0 if any entries in the file had serious errors
+ 1 if all entries were OK
+@DESCRIPTION: Parses an entire BibTeX file, and returns a linked list
+ of ASTs (or, if you like, a forest) for the entries in it.
+ (Any entries with serious errors are omitted from the list.)
+@GLOBALS :
+@CALLS : bt_parse_entry()
+@CREATED : 1997/01/18, from process_file() in bibparse.c
+@MODIFIED :
+@COMMENTS : This function bears a *striking* resemblance to bibparse.c's
+ process_file(). Eventually, I plan to replace this with
+ a generalized process_file() that takes a function pointer
+ to call for each entry. Until I decide on the right interface
+ for that, though, I'm sticking with this simpler (but possibly
+ memory-intensive) approach.
+-------------------------------------------------------------------------- */
+AST * bt_parse_file (char * filename,
+ ushort options,
+ boolean * status)
+{
+ FILE * infile;
+ AST * entries,
+ * cur_entry,
+ * last;
+ boolean entry_status,
+ overall_status;
+
+ if (options & BTO_STRINGMASK) /* any string options set? */
+ {
+ usage_error ("bt_parse_file: illegal options "
+ "(string options not allowed");
+ }
+
+ /*
+ * If a string was given, and it's *not* "-", then open that filename.
+ * Otherwise just use stdin.
+ */
+
+ if (filename != NULL && strcmp (filename, "-") != 0)
+ {
+ InputFilename = filename;
+ infile = fopen (filename, "r");
+ if (infile == NULL)
+ {
+ perror (filename);
+ return 0;
+ }
+ }
+ else
+ {
+ InputFilename = "(stdin)";
+ infile = stdin;
+ }
+
+ entries = NULL;
+ last = NULL;
+
+#if 1
+ /* explicit loop over entries, with junk cleaned out by read_entry () */
+
+ overall_status = TRUE; /* assume success */
+ while ((cur_entry = bt_parse_entry
+ (infile, InputFilename, options, &entry_status)))
+ {
+ overall_status &= entry_status;
+ if (!entry_status) continue; /* bad entry -- try next one */
+ if (!cur_entry) break; /* at eof -- we're done */
+ if (last == NULL) /* this is the first entry */
+ entries = cur_entry;
+ else /* have already seen one */
+ last->right = cur_entry;
+
+ last = cur_entry;
+ }
+
+#else
+ /* let the PCCTS lexer/parser handle everything */
+
+ initialize_lexer_state ();
+ ANTLR (bibfile (top), infile);
+
+#endif
+
+ fclose (infile);
+ InputFilename = NULL;
+ if (status) *status = overall_status;
+ return entries;
+
+} /* bt_parse_file() */
diff --git a/src/translators/btparse/lex_auxiliary.c b/src/translators/btparse/lex_auxiliary.c
new file mode 100644
index 0000000..8fac463
--- /dev/null
+++ b/src/translators/btparse/lex_auxiliary.c
@@ -0,0 +1,939 @@
+/* ------------------------------------------------------------------------
+@NAME : lex_auxiliary.c
+@INPUT :
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: The code and global variables here have three main purposes:
+ - maintain the lexical buffer (zztoktext, which
+ traditionally with PCCTS is a static array; I have
+ changed things so that it's dynamically allocated and
+ resized on overflow)
+ - keep track of lexical state that's not handled by PCCTS
+ code (like "where are we in terms of BibTeX entries?" or
+ "what are the delimiters for the current entry/string?")
+ - everything called from lexical actions is here, to keep
+ the grammar file itself neat and clean
+@GLOBALS :
+@CALLS :
+@CALLERS :
+@CREATED : Greg Ward, 1996/07/25-28
+@MODIFIED : Jan 1997
+ Jun 1997
+@VERSION : $Id: lex_auxiliary.c,v 1.31 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+
+/*#include "bt_config.h"*/
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <assert.h>
+#include "lex_auxiliary.h"
+#include "stdpccts.h"
+#include "error.h"
+#include "prototypes.h"
+/*#include "my_dmalloc.h"*/
+
+#define DUPE_TEXT 0
+
+extern char * InputFilename; /* from input.c */
+
+GEN_PRIVATE_ERRFUNC (lexical_warning, (const char * fmt, ...),
+ BTERR_LEXWARN, InputFilename, zzline, NULL, -1, fmt)
+GEN_PRIVATE_ERRFUNC (lexical_error, (const char * fmt, ...),
+ BTERR_LEXERR, InputFilename, zzline, NULL, -1, fmt)
+
+
+
+/* ----------------------------------------------------------------------
+ * Global variables
+ */
+
+/* First, the lexical buffer. This is used elsewhere, so can't be static */
+char * zztoktext = NULL;
+
+/*
+ * Now, the lexical state -- first, stuff that arises from scanning
+ * at top-level and the beginnings of entries;
+ * EntryState:
+ * toplevel when we start scanning a file, or when we are in in_entry
+ * mode and see '}' or ')'
+ * after_at when we are in toplevel mode and see an '@'
+ * after_type when we are in after_at mode and see a name (!= 'comment')
+ * in_comment when we are in after_at mode and see a name (== 'comment')
+ * in_entry when we are in after_type mode and see '{' or '('
+ * EntryOpener:
+ * the character ('(' or '{') which opened the entry currently being
+ * scanned (we use this to make sure that the entry opener and closer
+ * match; if not, we issue a warning)
+ * EntryMetatype: (NB. typedef for bt_metatype is in btparse.h)
+ * classifies entries according to the syntax we will use to parse them;
+ * also winds up (after being changed to a bt_nodetype value) in the
+ * node that roots the entry AST:
+ * comment - anything between () or {}
+ * preamble - a single compound value
+ * string - a list of "name = compound_value" assignments; no key
+ * alias - a single "name = compound_value" assignment (where
+ * the compound value in this case is presumably a
+ * name, rather than a string -- this is not syntactically
+ * checked though)
+ * modify,
+ * entry - a key followed by a list of "name = compound_value"
+ * assignments
+ * JunkCount:
+ * the number of non-whitespace, non-'@' characters seen at toplevel
+ * between two entries (used to print out a warning when we hit
+ * the beginning of entry, to help people catch "old style" implicit
+ * comments
+ */
+static enum { toplevel, after_at, after_type, in_comment, in_entry }
+ EntryState;
+static char EntryOpener; /* '(' or '{' */
+static bt_metatype
+ EntryMetatype;
+static int JunkCount; /* non-whitespace chars at toplevel */
+
+/*
+ * String state -- these are maintained and used by the functions called
+ * from actions in the string lexer.
+ * BraceDepth:
+ * brace depth within a string; we can only end the current string
+ * when this is zero
+ * ParenDepth:
+ * parenthesis depth within a string; needed for @comment entries
+ * that are paren-delimited (because the comment in that case is
+ * a paren-delimited string)
+ * StringOpener:
+ * similar to EntryOpener, but stronger than merely warning of token
+ * mismatch -- this determines which character ('"' or '}') can
+ * actually end the string
+ * StringStart:
+ * line on which current string started; if we detect an apparent
+ * runaway, this is used to report where the runaway started
+ * ApparentRunaway:
+ * flags if we have already detected (and warned) that the current
+ * string appears to be a runaway, so that we don't warn again
+ * (and again and again and again)
+ * QuoteWarned:
+ * flags if we have already warned about seeing a '"' in a string,
+ * because they tend to come in pairs and one warning per string
+ * is enough
+ *
+ * (See bibtex.g for an explanation of my runaway string detection heuristic.)
+ */
+static char StringOpener = '\0'; /* '{' or '"' */
+static int BraceDepth; /* depth of brace-nesting */
+static int ParenDepth; /* depth of parenthesis-nesting */
+static int StringStart = -1; /* start line of current string */
+static int ApparentRunaway; /* current string looks like runaway */
+static int QuoteWarned; /* already warned about " in string? */
+
+
+
+/* ----------------------------------------------------------------------
+ * Miscellaneous functions:
+ * lex_info() (handy for debugging)
+ * zzcr_attr() (called from PCCTS-generated code)
+ */
+
+void lex_info (void)
+{
+ printf ("LA(1) = \"%s\" token %d, %s\n", LATEXT(1), LA(1), zztokens[LA(1)]);
+#ifdef LL_K
+ printf ("LA(2) = \"%s\" token %d, %s\n", LATEXT(2), LA(2), zztokens[LA(2)]);
+#endif
+}
+
+
+void zzcr_attr (Attrib *a, int tok, char *txt)
+{
+ if (tok == STRING)
+ {
+ int len = strlen (txt);
+
+ assert ((txt[0] == '{' && txt[len-1] == '}')
+ || (txt[0] == '"' && txt[len-1] == '"'));
+ txt[len-1] = (char) 0; /* remove closing quote from string */
+ txt++; /* so we'll skip the opening quote */
+ }
+
+#if DUPE_TEXT
+ a->text = strdup (txt);
+#else
+ a->text = txt;
+#endif
+ a->token = tok;
+ a->line = zzline;
+ a->offset = zzbegcol;
+#if DEBUG > 1
+ dprintf ("zzcr_attr: input txt = %p (%s)\n", txt, txt);
+ dprintf (" dupe txt = %p (%s)\n", a->text, a->text);
+#endif
+}
+
+
+#if DUPE_TEXT
+void zzd_attr (Attrib *attr)
+{
+ free (attr->text);
+}
+#endif
+
+
+/* ----------------------------------------------------------------------
+ * Lexical buffer functions:
+ * alloc_lex_buffer()
+ * realloc_lex_buffer()
+ * free_lex_buffer()
+ * lexer_overflow()
+ * zzcopy() (only if ZZCOPY_FUNCTION is defined and true)
+ */
+
+
+/*
+ * alloc_lex_buffer()
+ *
+ * allocates the lexical buffer with `size' characters. Clears the buffer,
+ * points zzlextext at it, and sets zzbufsize to `size'.
+ *
+ * Does nothing if the buffer is already allocated.
+ *
+ * globals: zztoktext, zzlextext, zzbufsize
+ * callers: bt_parse_entry() (in input.c)
+ */
+void alloc_lex_buffer (int size)
+{
+ if (zztoktext == NULL)
+ {
+ zztoktext = (char *) malloc (size * sizeof (char));
+ memset (zztoktext, 0, size);
+ zzlextext = zztoktext;
+ zzbufsize = size;
+ }
+} /* alloc_lex_buffer() */
+
+
+/*
+ * realloc_lex_buffer()
+ *
+ * Reallocates the lexical buffer -- size is increased by `size_increment'
+ * characters (which could be negative). Updates all globals that point
+ * to or into the buffer (zzlextext, zzbegexpr, zzendexpr), as well as
+ * zztoktext (the buffer itself) zzbufsize (the buffer size).
+ *
+ * This is only meant to be called (ultimately) from zzgettok(), part of
+ * the DLG code. (In fact, zzgettok() invokes the ZZCOPY() macro, which
+ * calls lexer_overflow() on buffer overflow, which calls
+ * realloc_lex_buffer(). Whatever.) The `lastpos' and `nextpos' arguments
+ * correspond, respectively, to a local variable in zzgettok() and a static
+ * global in dlgauto.h (hence really in scan.c). They both point into
+ * the lexical buffer, so have to be passed by reference here so that
+ * we can update them to point into the newly-reallocated buffer.
+ *
+ * globals: zztottext, zzbufsize, zzlextext, zzbegexpr, zzendexpr
+ * callers: lexer_overflow()
+ */
+static void
+realloc_lex_buffer (int size_increment,
+ unsigned char ** lastpos,
+ unsigned char ** nextpos)
+{
+ int beg, end, next;
+
+ if (zztoktext == NULL)
+ internal_error ("attempt to reallocate unallocated lexical buffer");
+
+ zztoktext = (char *) realloc (zztoktext, zzbufsize+size_increment);
+ memset (zztoktext+zzbufsize, 0, size_increment);
+ zzbufsize += size_increment;
+
+ beg = zzbegexpr - zzlextext;
+ end = zzendexpr - zzlextext;
+ next = *nextpos - zzlextext;
+ zzlextext = zztoktext;
+
+ if (lastpos != NULL)
+ *lastpos = zzlextext+zzbufsize-1;
+ zzbegexpr = zzlextext + beg;
+ zzendexpr = zzlextext + end;
+ *nextpos = zzlextext + next;
+
+} /* realloc_lex_buffer() */
+
+
+/*
+ * free_lex_buffer()
+ *
+ * Frees the lexical buffer allocated by alloc_lex_buffer().
+ */
+void free_lex_buffer (void)
+{
+ if (zztoktext == NULL)
+ internal_error ("attempt to free unallocated (or already freed) "
+ "lexical buffer");
+
+ free (zztoktext);
+ zztoktext = NULL;
+} /* free_lex_buffer() */
+
+
+/*
+ * lexer_overflow()
+ *
+ * Prints a warning and calls realloc_lex_buffer() to increase the size
+ * of the lexical buffer by ZZLEXBUFSIZE (a constant -- hence the buffer
+ * size increases linearly, not exponentially).
+ *
+ * Also prints a couple of lines of useful debugging stuff if DEBUG is true.
+ */
+void lexer_overflow (unsigned char **lastpos, unsigned char **nextpos)
+{
+#if DEBUG
+ char head[16], tail[16];
+
+ printf ("zzcopy: overflow detected\n");
+ printf (" zzbegcol=%d, zzendcol=%d, zzline=%d\n",
+ zzbegcol, zzendcol, zzline);
+ strncpy (head, zzlextext, 15); head[15] = 0;
+ strncpy (tail, zzlextext+ZZLEXBUFSIZE-15, 15); tail[15] = 0;
+ printf (" zzlextext=>%s...%s< (last char=%d (%c))\n",
+ head, tail,
+ zzlextext[ZZLEXBUFSIZE-1], zzlextext[ZZLEXBUFSIZE-1]);
+ printf (" zzchar = %d (%c), zzbegexpr=zzlextext+%d\n",
+ zzchar, zzchar, zzbegexpr-zzlextext);
+#endif
+
+ notify ("lexical buffer overflowed (reallocating to %d bytes)",
+ zzbufsize+ZZLEXBUFSIZE);
+ realloc_lex_buffer (ZZLEXBUFSIZE, lastpos, nextpos);
+
+} /* lexer_overflow () */
+
+
+#if ZZCOPY_FUNCTION
+/*
+ * zzcopy()
+ *
+ * Does the same as the ZZCOPY macro (in lex_auxiliary.h), but as a
+ * function for easier debugging.
+ */
+void zzcopy (char **nextpos, char **lastpos, int *ovf_flag)
+{
+ if (*nextpos >= *lastpos)
+ {
+ lexer_overflow (lastpos, nextpos);
+ }
+
+ **nextpos = zzchar;
+ (*nextpos)++;
+}
+#endif
+
+
+
+/* ----------------------------------------------------------------------
+ * Report/maintain lexical state
+ * report_state() (only meaningful if DEBUG)
+ * initialize_lexer_state()
+ *
+ * Note that the lexical action functions, below, also fiddle with
+ * the lexical state variables an awful lot.
+ */
+
+#if DEBUG
+char *state_names[] =
+ { "toplevel", "after_at", "after_type", "in_comment", "in_entry" };
+char *metatype_names[] =
+ { "unknown", "comment", "preamble", "string", "alias", "modify", "entry" };
+
+static void
+report_state (char *where)
+{
+ printf ("%s: lextext=%s (line %d, offset %d), token=%d, "
+ "EntryState=%s\n",
+ where, zzlextext, zzline, zzbegcol, NLA,
+ state_names[EntryState]);
+}
+#else
+# define report_state(where)
+/*
+static void
+report_state (char *where) { }
+*/
+#endif
+
+void initialize_lexer_state (void)
+{
+ zzmode (START);
+ EntryState = toplevel;
+ EntryOpener = (char) 0;
+ EntryMetatype = BTE_UNKNOWN;
+ JunkCount = 0;
+}
+
+
+bt_metatype entry_metatype (void)
+{
+ return EntryMetatype;
+}
+
+
+
+/* ----------------------------------------------------------------------
+ * Lexical actions (START and LEX_ENTRY modes)
+ */
+
+/*
+ * newline ()
+ *
+ * Does everything needed to handle newline outside of a quoted string:
+ * increments line counter and skips the newline.
+ */
+void newline (void)
+{
+ zzline++;
+ zzskip();
+}
+
+
+void comment (void)
+{
+ zzline++;
+ zzskip();
+}
+
+
+void at_sign (void)
+{
+ if (EntryState == toplevel)
+ {
+ EntryState = after_at;
+ zzmode (LEX_ENTRY);
+ if (JunkCount > 0)
+ {
+ lexical_warning ("%d characters of junk seen at toplevel", JunkCount);
+ JunkCount = 0;
+ }
+ }
+ else
+ {
+ /* internal_error ("lexer recognized \"@\" at other than top-level"); */
+ lexical_warning ("\"@\" in strange place -- should get syntax error");
+ }
+ report_state ("at_sign");
+}
+
+
+void toplevel_junk (void)
+{
+ JunkCount += strlen (zzlextext);
+ zzskip ();
+}
+
+
+void name (void)
+{
+ report_state ("name (pre)");
+
+ switch (EntryState)
+ {
+ case toplevel:
+ {
+ internal_error ("junk at toplevel (\"%s\")", zzlextext);
+ break;
+ }
+ case after_at:
+ {
+ char * etype = zzlextext;
+ EntryState = after_type;
+
+ if (strcasecmp (etype, "comment") == 0)
+ {
+ EntryMetatype = BTE_COMMENT;
+ EntryState = in_comment;
+ }
+
+ else if (strcasecmp (etype, "preamble") == 0)
+ EntryMetatype = BTE_PREAMBLE;
+
+ else if (strcasecmp (etype, "string") == 0)
+ EntryMetatype = BTE_MACRODEF;
+/*
+ else if (strcasecmp (etype, "alias") == 0)
+ EntryMetatype = BTE_ALIAS;
+
+ else if (strcasecmp (etype, "modify") == 0)
+ EntryMetatype = BTE_MODIFY;
+*/
+ else
+ EntryMetatype = BTE_REGULAR;
+
+ break;
+ }
+ case after_type:
+ case in_comment:
+ case in_entry:
+ break; /* do nothing */
+ }
+
+ report_state ("name (post)");
+
+}
+
+
+void lbrace (void)
+{
+ /*
+ * Currently takes a restrictive view of "when an lbrace is an entry
+ * opener" -- ie. *only* after '@name' (as determined by EntryState),
+ * where name is not 'comment'. This means that lbrace usually
+ * determines a string (in particular, when it's seen at toplevel --
+ * which will happen under certain error situations), which in turn
+ * means that some unexpected things can become strings (like whole
+ * entries).
+ */
+
+ if (EntryState == in_entry || EntryState == in_comment)
+ {
+ start_string ('{');
+ }
+ else if (EntryState == after_type)
+ {
+ EntryState = in_entry;
+ EntryOpener = '{';
+ NLA = ENTRY_OPEN;
+ }
+ else
+ {
+ lexical_warning ("\"{\" in strange place -- should get a syntax error");
+ }
+
+ report_state ("lbrace");
+}
+
+
+void rbrace (void)
+{
+ if (EntryState == in_entry)
+ {
+ if (EntryOpener == '(')
+ lexical_warning ("entry started with \"(\", but ends with \"}\"");
+ NLA = ENTRY_CLOSE;
+ initialize_lexer_state ();
+ }
+ else
+ {
+ lexical_warning ("\"}\" in strange place -- should get a syntax error");
+ }
+ report_state ("rbrace");
+}
+
+
+void lparen (void)
+{
+ if (EntryState == in_comment)
+ {
+ start_string ('(');
+ }
+ else if (EntryState == after_type)
+ {
+ EntryState = in_entry;
+ EntryOpener = '(';
+ }
+ else
+ {
+ lexical_warning ("\"(\" in strange place -- should get a syntax error");
+ }
+ report_state ("lparen");
+}
+
+
+void rparen (void)
+{
+ if (EntryState == in_entry)
+ {
+ if (EntryOpener == '{')
+ lexical_warning ("entry started with \"{\", but ends with \")\"");
+ initialize_lexer_state ();
+ }
+ else
+ {
+ lexical_warning ("\")\" in strange place -- should get a syntax error");
+ }
+ report_state ("rparen");
+}
+
+
+/* ----------------------------------------------------------------------
+ * Stuff for processing strings.
+ */
+
+
+/*
+ * start_string ()
+ *
+ * Called when we see a '{' or '"' in the field data. Records which quote
+ * character was used, and calls open_brace() to increment the depth
+ * counter if it was a '{'. Switches to LEX_STRING mode, and tells the
+ * lexer to continue slurping characters into the same buffer.
+ */
+void start_string (char start_char)
+{
+ StringOpener = start_char;
+ BraceDepth = 0;
+ ParenDepth = 0;
+ StringStart = zzline;
+ ApparentRunaway = 0;
+ QuoteWarned = 0;
+ if (start_char == '{')
+ open_brace ();
+ if (start_char == '(')
+ ParenDepth++;
+ if (start_char == '"' && EntryState == in_comment)
+ {
+ lexical_error ("comment entries must be delimited by either braces or parentheses");
+ EntryState = toplevel;
+ zzmode (START);
+ return;
+ }
+
+#ifdef USER_ZZMODE_STACK
+ if (zzauto != LEX_ENTRY || EntryState != in_entry)
+#else
+ if (EntryState != in_entry && EntryState != in_comment)
+#endif
+ {
+ lexical_warning ("start of string seen at weird place");
+ }
+
+ zzmore ();
+ zzmode (LEX_STRING);
+}
+
+
+/*
+ * end_string ()
+ *
+ * Called when we see either a '"' (at depth 0) or '}' (if it brings us
+ * down to depth 0) in a quoted string. Just makes sure that braces are
+ * balanced, and then goes back to the LEX_FIELD mode.
+ */
+void end_string (char end_char)
+{
+ char match;
+
+#ifndef ALLOW_WARNINGS
+ match = (char) 0; /* silence "might be used" */
+ /* uninitialized" warning */
+#endif
+
+ switch (end_char)
+ {
+ case '}': match = '{'; break;
+ case ')': match = '('; break;
+ case '"': match = '"'; break;
+ default:
+ internal_error ("end_string(): invalid end_char \"%c\"", end_char);
+ }
+
+ assert (StringOpener == match);
+
+ /*
+ * If we're at non-zero BraceDepth, that probably means mismatched braces
+ * somewhere -- complain about it and reset BraceDepth to minimize future
+ * confusion.
+ */
+
+ if (BraceDepth > 0)
+ {
+ lexical_error ("unbalanced braces: too many {'s");
+ BraceDepth = 0;
+ }
+
+ StringOpener = (char) 0;
+ StringStart = -1;
+ NLA = STRING;
+
+ if (EntryState == in_comment)
+ {
+ int len = strlen (zzlextext);
+
+ /*
+ * ARG! no, this is wrong -- what if unbalanced braces in the string
+ * and we try to output put it later?
+ *
+ * ARG! again, this is no more wrong than when we strip quotes in
+ * post_parse.c, and blithely assume that we can put them back on
+ * later for output in BibTeX syntax. Hmmm.
+ *
+ * Actually, it looks like this isn't a problem after all: you
+ * can't have unbalanced braces in a BibTeX string (at least
+ * not as parsed by btparse).
+ */
+
+ if (zzlextext[0] == '(') /* convert to standard quote delims */
+ {
+ zzlextext[ 0] = '{';
+ zzlextext[len-1] = '}';
+ }
+
+ EntryState = toplevel;
+ zzmode (START);
+ }
+ else
+ {
+ zzmode (LEX_ENTRY);
+ }
+
+ report_state ("string");
+}
+
+
+/*
+ * open_brace ()
+ *
+ * Called when we see a '{', either to start a string (in which case
+ * it's called from start_string()) or inside a string (called directly
+ * from the lexer).
+ */
+void open_brace (void)
+{
+ BraceDepth++;
+ zzmore ();
+ report_state ("open_brace");
+}
+
+
+/*
+ * close_brace ()
+ *
+ * Called when we see a '}' inside a string. Decrements the depth counter
+ * and checks to see if we are down to depth 0, in which case the string is
+ * ended and the current lookahead token is set to STRING. Otherwise,
+ * just tells the lexer to keep slurping characters into the buffer.
+ */
+void close_brace (void)
+{
+ BraceDepth--;
+ if (StringOpener == '{' && BraceDepth == 0)
+ {
+ end_string ('}');
+ }
+
+ /*
+ * This could happen if some bonehead puts an unmatched right-brace
+ * in a quote-delimited string (eg. "Hello}"). To attempt to recover,
+ * we reset the depth to zero and continue slurping into the string.
+ */
+ else if (BraceDepth < 0)
+ {
+ lexical_error ("unbalanced braces: too many }'s");
+ BraceDepth = 0;
+ zzmore ();
+ }
+
+ /* Otherwise, it's just any old right brace in a string -- keep eating */
+ else
+ {
+ zzmore ();
+ }
+ report_state ("close_brace");
+}
+
+
+void lparen_in_string (void)
+{
+ ParenDepth++;
+ zzmore ();
+}
+
+
+void rparen_in_string (void)
+{
+ ParenDepth--;
+ if (StringOpener == '(' && ParenDepth == 0)
+ {
+ end_string (')');
+ }
+ else
+ {
+ zzmore ();
+ }
+}
+
+
+/*
+ * quote_in_string ()
+ *
+ * Called when we see '"' in a string. Ends the string if the quote is at
+ * depth 0 and the string was started with a quote, otherwise instructs the
+ * lexer to continue munching happily along. (Also prints a warning,
+ * assuming that input is destined for processing by TeX and you really
+ * want either `` or '' rather than ".)
+ */
+void quote_in_string (void)
+{
+ if (StringOpener == '"' && BraceDepth == 0)
+ {
+ end_string ('"');
+ }
+ else
+ {
+ boolean at_top = FALSE;;
+
+ /*
+ * Note -- this warning assumes that strings are destined
+ * to be processed by TeX, so it should be optional. Hmmm.
+ */
+
+ if (StringOpener == '"' || StringOpener == '(')
+ at_top = (BraceDepth == 0);
+ else if (StringOpener == '{')
+ at_top = (BraceDepth == 1);
+ else
+ internal_error ("Illegal string opener \"%c\"", StringOpener);
+
+ if (!QuoteWarned && at_top)
+ {
+ lexical_warning ("found \" at brace-depth zero in string "
+ "(TeX accents in BibTeX should be inside braces)");
+ QuoteWarned = 1;
+ }
+ zzmore ();
+ }
+}
+
+
+/*
+ * check_runaway_string ()
+ *
+ * Called from the lexer whenever we see a newline in a string. See
+ * bibtex.g for a detailed explanation; basically, this function
+ * looks for an entry start ("@name{") or new field ("name=") immediately
+ * after a newline (with possible whitespace). This is a heuristic
+ * check for runaway strings, under the assumption that text that looks
+ * like a new entry or new field won't actually occur inside a string
+ * very often.
+ */
+void check_runaway_string (void)
+{
+ int len;
+ int i;
+
+ /*
+ * could these be made significantly more efficient by a 256-element
+ * lookup table instead of calling strchr()?
+ */
+ static const char *alpha_chars = "abcdefghijklmnopqrstuvwxyz";
+ static const char *name_chars = "abcdefghijklmnopqrstuvwxyz0123456789:+/'.-";
+
+ /*
+ * on entry: zzlextext contains the whole string, starting with {
+ * and with newlines/tabs converted to space; zzbegexpr points to
+ * a chunk of the string starting with newline (newlines and
+ * tabs have not yet been converted)
+ */
+
+#if DEBUG > 1
+ printf ("check_runaway_string(): zzline=%d\n", zzline);
+ printf ("zzlextext=>%s<\nzzbegexpr=>%s<\n",
+ zzlextext, zzbegexpr);
+#endif
+
+
+ /*
+ * increment zzline to take the leading newline into account -- but
+ * first a sanity check to be sure that newline is there!
+ */
+
+ if (zzbegexpr[0] != '\n')
+ {
+ lexical_warning ("huh? something's wrong (buffer overflow?) near "
+ "offset %d (line %d)", zzendcol, zzline);
+ /* internal_error ("zzbegexpr (line %d, offset %d-%d, "
+ "text >%s<, expr >%s<)"
+ "should start with a newline",
+ zzline, zzbegcol, zzendcol, zzlextext, zzbegexpr);
+ */
+ }
+ else
+ {
+ zzline++;
+ }
+
+ /* standardize whitespace (convert all to space) */
+
+ len = strlen (zzbegexpr);
+ for (i = 0; i < len; i++)
+ {
+ if (isspace (zzbegexpr[i]))
+ zzbegexpr[i] = ' ';
+ }
+
+
+ if (!ApparentRunaway) /* haven't already warned about it */
+ {
+ enum { none, entry, field, giveup } guess;
+
+ i = 1;
+ guess = none;
+ while (i < len && zzbegexpr[i] == ' ') i++;
+
+ if (zzbegexpr[i] == '@')
+ {
+ i++;
+ while (i < len && zzbegexpr[i] == ' ') i++;
+ guess = entry;
+ }
+
+ if (strchr (alpha_chars, tolower (zzbegexpr[i])) != NULL)
+ {
+ while (i < len && strchr (name_chars, tolower (zzbegexpr[i])) != NULL)
+ i++;
+ while (i < len && zzbegexpr[i] == ' ') i++;
+ if (i == len)
+ {
+ guess = giveup;
+ }
+ else
+ {
+ if (guess == entry)
+ {
+ if (zzbegexpr[i] != '{' && zzbegexpr[i] != '(')
+ guess = giveup;
+ }
+ else /* assume it's a field */
+ {
+ if (zzbegexpr[i] == '=')
+ guess = field;
+ else
+ guess = giveup;
+ }
+ }
+ }
+ else /* no name seen after WS or @ */
+ {
+ guess = giveup;
+ }
+
+ if (guess == none)
+ internal_error ("gee, I should have made a guess by now");
+
+ if (guess != giveup)
+ {
+ lexical_warning ("possible runaway string started at line %d",
+ StringStart);
+ ApparentRunaway = 1;
+ }
+ }
+
+ zzmore();
+}
+
diff --git a/src/translators/btparse/lex_auxiliary.h b/src/translators/btparse/lex_auxiliary.h
new file mode 100644
index 0000000..ebbf053
--- /dev/null
+++ b/src/translators/btparse/lex_auxiliary.h
@@ -0,0 +1,71 @@
+/* ------------------------------------------------------------------------
+@NAME : lex_auxiliary.h
+@DESCRIPTION: Macros and function prototypes needed by the lexical scanner.
+ Some of these are called from internal PCCTS code, and some
+ are explicitly called from the lexer actions in bibtex.g.
+@CREATED : Summer 1996, Greg Ward
+@MODIFIED :
+@VERSION : $Id: lex_auxiliary.h,v 1.15 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+#ifndef LEX_AUXILIARY_H
+#define LEX_AUXILIARY_H
+
+#include "btparse.h"
+#include "attrib.h"
+
+#define ZZCOPY_FUNCTION 0
+
+#if ZZCOPY_FUNCTION
+#define ZZCOPY zzcopy (&zznextpos, &lastpos, &zzbufovf)
+#else
+#define ZZCOPY \
+ if (zznextpos >= lastpos) \
+ { \
+ lexer_overflow (&lastpos, &zznextpos); \
+ } \
+ *(zznextpos++) = zzchar;
+#endif
+
+
+/* Function prototypes: */
+
+void lex_info (void);
+void zzcr_attr (Attrib *a, int tok, char *txt);
+
+void alloc_lex_buffer (int size);
+void free_lex_buffer (void);
+void lexer_overflow (unsigned char **lastpos, unsigned char **nextpos);
+#if ZZCOPY_FUNCTION
+void zzcopy (char **nextpos, char **lastpos, int *ovf_flag);
+#endif
+
+void initialize_lexer_state (void);
+bt_metatype entry_metatype (void);
+
+void newline (void);
+void comment (void);
+void at_sign (void);
+void toplevel_junk (void);
+void name (void);
+void lbrace (void);
+void rbrace (void);
+void lparen (void);
+void rparen (void);
+
+void start_string (char start_char);
+void end_string (char end_char);
+void open_brace (void);
+void close_brace (void);
+void lparen_in_string (void);
+void rparen_in_string (void);
+void quote_in_string (void);
+void check_runaway_string (void);
+
+#endif /* ! defined LEX_AUXILIARY_H */
diff --git a/src/translators/btparse/macros.c b/src/translators/btparse/macros.c
new file mode 100644
index 0000000..06db983
--- /dev/null
+++ b/src/translators/btparse/macros.c
@@ -0,0 +1,367 @@
+/* ------------------------------------------------------------------------
+@NAME : macros.c
+@DESCRIPTION: Front-end to the standard PCCTS symbol table code (sym.c)
+ to abstract my "macro table".
+@GLOBALS :
+@CALLS :
+@CREATED : 1997/01/12, Greg Ward
+@MODIFIED :
+@VERSION : $Id: macros.c,v 1.19 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+/*#include "bt_config.h"*/
+#include <stdlib.h>
+#include <string.h>
+#include "sym.h"
+#include "prototypes.h"
+#include "error.h"
+/*#include "my_dmalloc.h"*/
+#include "bt_debug.h"
+
+
+/*
+ * NUM_MACROS and STRING_SIZE define the size of the static data
+ * structure that holds the macro table. The defaults are to allocate
+ * 4096 bytes of string space that will be divided up amongst 547
+ * macros. This should be fine for most applications, but if you have a
+ * big macro table you might need to change these and recompile (don't
+ * forget to rebuild and reinstall Text::BibTeX if you're using it!).
+ * You can set these as high as you like; just remember that a block of
+ * STRING_SIZE bytes will be allocated and not freed as long as you're
+ * using btparse. Also, NUM_MACROS defines the size of a hashtable, so
+ * it should probably be a prime a bit greater than a power of 2 -- or
+ * something like that. I'm not sure of the exact Knuthian
+ * specification.
+ */
+#define NUM_MACROS 547
+#define STRING_SIZE 4096
+
+Sym *AllMacros = NULL; /* `scope' so we can get back list */
+ /* of all macros when done */
+
+
+GEN_PRIVATE_ERRFUNC (macro_warning,
+ (char * filename, int line, const char * fmt, ...),
+ BTERR_CONTENT, filename, line, NULL, -1, fmt)
+
+
+/* ------------------------------------------------------------------------
+@NAME : init_macros()
+@INPUT :
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Initializes the symbol table used to store macro values.
+@GLOBALS : AllMacros
+@CALLS : zzs_init(), zzs_scope() (sym.c)
+@CALLERS : bt_initialize() (init.c)
+@CREATED : Jan 1997, GPW
+-------------------------------------------------------------------------- */
+void
+init_macros (void)
+{
+ zzs_init (NUM_MACROS, STRING_SIZE);
+ zzs_scope (&AllMacros);
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : done_macros()
+@INPUT :
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Frees up all the macro values in the symbol table, and
+ then frees up the symbol table itself.
+@GLOBALS : AllMacros
+@CALLS : zzs_rmscope(), zzs_done()
+@CALLERS : bt_cleanup() (init.c)
+@CREATED : Jan 1997, GPW
+-------------------------------------------------------------------------- */
+void
+done_macros (void)
+{
+ bt_delete_all_macros ();
+ zzs_done ();
+}
+
+
+static void
+delete_macro_entry (Sym * sym)
+{
+ Sym * cur;
+ Sym * prev;
+
+ /*
+ * Yechh! All this mucking about with the scope list really
+ * ought to be handled by the symbol table code. Must write
+ * my own someday.
+ */
+
+ /* Find this entry in the list of all macro table entries */
+ cur = AllMacros;
+ prev = NULL;
+ while (cur != NULL && cur != sym)
+ {
+ prev = cur;
+ cur = cur->scope;
+ }
+
+ if (cur == NULL) /* uh-oh -- wasn't found! */
+ {
+ internal_error ("macro table entry for \"%s\" not found in scope list",
+ sym->symbol);
+ }
+
+ /* Now unlink from the "scope" list */
+ if (prev == NULL) /* it's the head of the list */
+ AllMacros = cur->scope;
+ else
+ prev->scope = cur->scope;
+
+ /* Remove it from the macro hash table */
+ zzs_del (sym);
+
+ /* And finally, free up the entry's text and the entry itself */
+ if (sym->text) free (sym->text);
+ free (sym);
+} /* delete_macro_entry() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_add_macro_value()
+@INPUT : assignment - AST node representing "macro = value"
+ options - string-processing options that were used to
+ process this string after parsing
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Adds a value to the symbol table used for macros.
+
+ If the value was not already post-processed as a macro value
+ (expand macros, paste substrings, but don't collapse
+ whitespace), then this post-processing is done before adding
+ the macro text to the table.
+
+ If the macro is already defined, a warning is printed and
+ the old text is overridden.
+@GLOBALS :
+@CALLS : bt_add_macro_text()
+ bt_postprocess_field()
+@CALLERS : bt_postprocess_entry() (post_parse.c)
+@CREATED : Jan 1997, GPW
+-------------------------------------------------------------------------- */
+void
+bt_add_macro_value (AST *assignment, ushort options)
+{
+ AST * value;
+ char * macro;
+ char * text;
+ boolean free_text;
+
+ if (assignment == NULL || assignment->down == NULL) return;
+ value = assignment->down;
+
+ /*
+ * If the options that were used to process the macro's expansion text
+ * are anything other than BTO_MACRO, then we'll have to do it ourselves.
+ */
+
+ if ((options & BTO_STRINGMASK) != BTO_MACRO)
+ {
+ text = bt_postprocess_field (assignment, BTO_MACRO, FALSE);
+ free_text = TRUE; /* because it's alloc'd by */
+ /* bt_postprocess_field() */
+ }
+ else
+ {
+ /*
+ * First a sanity check to make sure that the presumed post-processing
+ * had the desired effect.
+ */
+
+ if (value->nodetype != BTAST_STRING || value->right != NULL)
+ {
+ internal_error ("add_macro: macro value was not "
+ "correctly preprocessed");
+ }
+
+ text = assignment->down->text;
+ free_text = FALSE;
+ }
+
+ macro = assignment->text;
+ bt_add_macro_text (macro, text, assignment->filename, assignment->line);
+ if (free_text && text != NULL)
+ free (text);
+
+} /* bt_add_macro_value() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_add_macro_text()
+@INPUT : macro - the name of the macro to define
+ text - the macro text
+ filename, line - where the macro is defined; pass NULL
+ for filename if no file, 0 for line if no line number
+ (just used to generate warning message)
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Sets the text value for a macro. If the macro is already
+ defined, a warning is printed and the old value is overridden.
+@GLOBALS :
+@CALLS : zzs_get(), zzs_newadd()
+@CALLERS : bt_add_macro_value()
+ (exported from library)
+@CREATED : 1997/11/13, GPW (from code in bt_add_macro_value())
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void
+bt_add_macro_text (char * macro, char * text, char * filename, int line)
+{
+ Sym * sym;
+ Sym * new_rec;
+
+#if DEBUG == 1
+ printf ("adding macro \"%s\" = \"%s\"\n", macro, text);
+#elif DEBUG >= 2
+ printf ("add_macro: macro = %p (%s)\n"
+ " text = %p (%s)\n",
+ macro, macro, text, text);
+#endif
+
+ if ((sym = zzs_get (macro)))
+ {
+ macro_warning (filename, line,
+ "overriding existing definition of macro \"%s\"",
+ macro);
+ delete_macro_entry (sym);
+ }
+
+ new_rec = zzs_newadd (macro);
+ new_rec->text = (text != NULL) ? strdup (text) : NULL;
+ DBG_ACTION
+ (2, printf (" saved = %p (%s)\n",
+ new_rec->text, new_rec->text);)
+
+} /* bt_add_macro_text() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_delete_macro()
+@INPUT : macro - name of macro to delete
+@DESCRIPTION: Deletes a macro from the macro table.
+@CALLS : zzs_get()
+@CALLERS :
+@CREATED : 1998/03/01, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void
+bt_delete_macro (char * macro)
+{
+ Sym * sym;
+
+ sym = zzs_get (macro);
+ if (! sym) return;
+ delete_macro_entry (sym);
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_delete_all_macros()
+@DESCRIPTION: Deletes all macros from the macro table.
+@CALLS : zzs_rmscore()
+@CALLERS :
+@CREATED : 1998/03/01, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void
+bt_delete_all_macros (void)
+{
+ Sym *cur, *next;
+
+ DBG_ACTION (2, printf ("bt_delete_all_macros():\n");)
+
+ /*
+ * Use the current `scope' (same one for all macros) to get access to
+ * a linked list of all macros. Then traverse the list, free()'ing
+ * both the text (which was strdup()'d in add_macro(), below) and
+ * the records themselves (which are calloc()'d by zzs_new()).
+ */
+
+ cur = zzs_rmscope (&AllMacros);
+ while (cur != NULL)
+ {
+ DBG_ACTION
+ (2, printf (" freeing macro \"%s\" (%p=\"%s\") at %p\n",
+ cur->symbol, cur->text, cur->text, cur);)
+
+ next = cur->scope;
+ if (cur->text != NULL) free (cur->text);
+ free (cur);
+ cur = next;
+ }
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_macro_length()
+@INPUT : macro - the macro name
+@OUTPUT :
+@RETURNS : length of the macro's text, or zero if the macro is undefined
+@DESCRIPTION: Returns length of a macro's text.
+@GLOBALS :
+@CALLS : zzs_get()
+@CALLERS : bt_postprocess_value()
+ (exported from library)
+@CREATED : Jan 1997, GPW
+-------------------------------------------------------------------------- */
+int
+bt_macro_length (char *macro)
+{
+ Sym *sym;
+
+ DBG_ACTION
+ (2, printf ("bt_macro_length: looking up \"%s\"\n", macro);)
+
+ sym = zzs_get (macro);
+ if (sym)
+ return strlen (sym->text);
+ else
+ return 0;
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_macro_text()
+@INPUT : macro - the macro name
+ filename, line - where the macro was invoked; NULL for
+ `filename' and zero for `line' if not applicable
+@OUTPUT :
+@RETURNS : The text of the macro, or NULL if it's undefined.
+@DESCRIPTION: Fetches a macros text; prints warning and returns NULL if
+ macro is undefined.
+@CALLS : zzs_get()
+@CALLERS : bt_postprocess_value()
+@CREATED : Jan 1997, GPW
+-------------------------------------------------------------------------- */
+char *
+bt_macro_text (char * macro, char * filename, int line)
+{
+ Sym * sym;
+
+ DBG_ACTION
+ (2, printf ("bt_macro_text: looking up \"%s\"\n", macro);)
+
+ sym = zzs_get (macro);
+ if (!sym)
+ {
+ macro_warning (filename, line, "undefined macro \"%s\"", macro);
+ return NULL;
+ }
+
+ return sym->text;
+}
diff --git a/src/translators/btparse/mode.h b/src/translators/btparse/mode.h
new file mode 100644
index 0000000..25b36ce
--- /dev/null
+++ b/src/translators/btparse/mode.h
@@ -0,0 +1,3 @@
+#define START 0
+#define LEX_ENTRY 1
+#define LEX_STRING 2
diff --git a/src/translators/btparse/modify.c b/src/translators/btparse/modify.c
new file mode 100644
index 0000000..2d8d9c1
--- /dev/null
+++ b/src/translators/btparse/modify.c
@@ -0,0 +1,75 @@
+/* ------------------------------------------------------------------------
+@NAME : modify.c
+@DESCRIPTION: Routines for modifying the AST for a single entry.
+@GLOBALS :
+@CALLS :
+@CREATED : 1999/11/25, Greg Ward (based on code supplied by
+ Stphane Genaud <genaud@icps.u-strasbg.fr>)
+@MODIFIED :
+@VERSION : $Id: modify.c,v 1.2 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+/*#include "bt_config.h"*/
+#include <stdlib.h>
+#include <string.h>
+#include "btparse.h"
+#include "error.h"
+/*#include "my_dmalloc.h"*/
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_set_text ()
+@INPUT : node
+ new_text
+@OUTPUT : node->text
+@RETURNS :
+@DESCRIPTION: Replace the text member of an AST node with a new string.
+ The passed in string, 'new_text', is duplicated, so the
+ caller may free it without worry.
+@GLOBALS :
+@CALLS :
+@CALLERS :
+@CREATED : 1999/11/25, GPW (from Stphane Genaud)
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void bt_set_text (AST * node, char * new_text)
+{
+ free(node->text);
+ node->text = strdup (new_text);
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_entry_set_key ()
+@INPUT : entry
+ new_key
+@OUTPUT : entry->down->text
+@RETURNS :
+@DESCRIPTION: Changes the key of a regular entry to 'new_key'. If 'entry'
+ is not a regular entry, or if it doesn't already have a child
+ node holding an entry key, bombs via 'usage_error()'.
+ Otherwise a duplicate of 'new_key' is copied into the entry
+ AST (so the caller can free that string without worry).
+@CALLS : bt_set_text ()
+@CREATED : 1999/11/25, GPW (from Stphane Genaud)
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void bt_entry_set_key (AST * entry, char * new_key)
+{
+ if (entry->metatype == BTE_REGULAR &&
+ entry->down && entry->down->nodetype == BTAST_KEY)
+ {
+ bt_set_text (entry->down, new_key);
+ }
+ else
+ {
+ usage_error ("can't set entry key -- not a regular entry, "
+ "or doesn't have a key already");
+ }
+}
diff --git a/src/translators/btparse/my_alloca.h b/src/translators/btparse/my_alloca.h
new file mode 100644
index 0000000..0466157
--- /dev/null
+++ b/src/translators/btparse/my_alloca.h
@@ -0,0 +1,35 @@
+/* ------------------------------------------------------------------------
+@NAME : my_alloca.h
+@DESCRIPTION: All-out assault at making alloca() available on any Unix
+ platform. Stolen from the GNU Autoconf manual.
+@CREATED : 1997/10/30, Greg Ward
+@VERSION : $Id: my_alloca.h,v 1.1 1997/10/31 03:56:17 greg Rel $
+@COPYRIGHT : This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+
+#ifndef MY_ALLOCA_H
+#define MY_ALLOCA_H
+
+#ifdef __GNUC__
+# ifndef alloca
+# define alloca __builtin_alloca
+# endif
+#else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+# pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+#endif
+
+#endif /* MY_ALLOCA_H */
diff --git a/src/translators/btparse/names.c b/src/translators/btparse/names.c
new file mode 100644
index 0000000..11c4bfd
--- /dev/null
+++ b/src/translators/btparse/names.c
@@ -0,0 +1,915 @@
+/* ------------------------------------------------------------------------
+@NAME : names.c
+@DESCRIPTION: Functions for dealing with BibTeX names and lists of names:
+ bt_split_list
+ bt_split_name
+@GLOBALS :
+@CALLS :
+@CREATED : 1997/05/05, Greg Ward (as string_util.c)
+@MODIFIED : 1997/05/14-05/16, GW: added all the code to split individual
+ names, renamed file to names.c
+@VERSION : $Id: names.c,v 1.23 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+
+/*#include "bt_config.h"*/
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "btparse.h"
+#include "prototypes.h"
+#include "error.h"
+#include "my_alloca.h"
+/*#include "my_dmalloc.h"*/
+#include "bt_debug.h"
+
+
+#define MAX_COMMAS 2
+
+#define update_depth(s,offs,depth) \
+switch (s[offs]) \
+{ \
+ case '{': depth++; break; \
+ case '}': depth--; break; \
+}
+
+/*
+ * `name_loc' specifies where a name is found -- used for generating
+ * useful warning messages. `line' and `name_num' are both 1-based.
+ */
+typedef struct
+{
+ char * filename;
+ int line;
+ int name_num;
+} name_loc;
+
+
+GEN_PRIVATE_ERRFUNC (name_warning,
+ (name_loc * loc, const char * fmt, ...),
+ BTERR_CONTENT, loc->filename, loc->line,
+ "name", loc->name_num, fmt)
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_split_list()
+@INPUT : string - string to split up; whitespace must be collapsed
+ eg. by bt_postprocess_string()
+ delim - delimiter to use; must be lowercase and should be
+ free of whitespace (code requires that delimiters
+ in string be surrounded by whitespace)
+ filename - source of string (for warning messages)
+ line - 1-based line number into file (for warning messages)
+ description - what substrings are (eg. "name") (for warning
+ messages); if NULL will use "substring"
+@OUTPUT : substrings (*substrings is allocated by bt_split_list() for you)
+@RETURNS : number of substrings found
+@DESCRIPTION: Splits a string using a fixed delimiter, in the BibTeX way:
+ * delimiters at beginning or end of string are ignored
+ * delimiters in string must be surrounded by whitespace
+ * case insensitive
+ * delimiters at non-zero brace depth are ignored
+
+ The list of substrings is returned as *substrings, which
+ is an array of pointers into a duplicate of string. This
+ duplicate copy has been scribbled on such that there is
+ a nul byte at the end of every substring. You should
+ call bt_free_list() to free both the duplicate copy
+ of string and *substrings itself. Do *not* walk over
+ the array free()'ing the substrings yourself, as this is
+ invalid -- they were not malloc()'d!
+@GLOBALS :
+@CALLS :
+@CALLERS : anyone (exported by library)
+@CREATED : 1997/05/05, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+bt_stringlist *
+bt_split_list (char * string,
+ char * delim,
+ char * filename,
+ int line,
+ char * description)
+{
+ int depth; /* brace depth */
+ int i, j; /* offset into string and delim */
+ int inword; /* flag telling if prev. char == ws */
+ int string_len;
+ int delim_len;
+ int maxdiv; /* upper limit on no. of divisions */
+ int maxoffs; /* max offset of delim in string */
+ int numdiv; /* number of divisions */
+ int * start; /* start of each division */
+ int * stop; /* stop of each division */
+ bt_stringlist *
+ list; /* structure to return */
+
+ if (string == NULL)
+ return NULL;
+ if (description == NULL)
+ description = "substring";
+
+ string_len = strlen (string);
+ delim_len = strlen (delim);
+ maxdiv = (string_len / delim_len) + 1;
+ maxoffs = string_len - delim_len + 1;
+
+ /*
+ * This is a bit of a band-aid solution to the "split empty string"
+ * bug (formerly hit the internal_error() at the end of hte function).
+ * Still need a general "detect and fix unpreprocessed string" --
+ * admittedly a different bug/misfeature.
+ */
+ if (string_len == 0)
+ return NULL;
+
+ start = (int *) alloca (maxdiv * sizeof (int));
+ stop = (int *) alloca (maxdiv * sizeof (int));
+
+ list = (bt_stringlist *) malloc (sizeof (bt_stringlist));
+
+ depth = 0;
+ i = j = 0;
+ inword = 1; /* so leading delim ignored */
+ numdiv = 0;
+ start[0] = 0; /* first substring @ start of string */
+
+ while (i < maxoffs)
+ {
+ /* does current char. in string match current char. in delim? */
+ if (depth == 0 && !inword && tolower (string[i]) == delim[j])
+ {
+ j++; i++;
+
+ /* have we found an entire delim, followed by a space? */
+ if (j == delim_len && string[i] == ' ')
+ {
+
+ stop[numdiv] = i - delim_len - 1;
+ start[++numdiv] = ++i;
+ j = 0;
+
+#if DEBUG
+ printf ("found complete delim; i == %d, numdiv == %d: "
+ "stop[%d] == %d, start[%d] == %d\n",
+ i, numdiv,
+ numdiv-1, stop[numdiv-1],
+ numdiv, start[numdiv]);
+#endif
+ }
+ }
+
+ /* no match between string and delim, at non-zero depth, or in a word */
+ else
+ {
+ update_depth (string, i, depth);
+ inword = (i < string_len) && (string[i] != ' ');
+ i++;
+ j = 0;
+ }
+ }
+
+ stop[numdiv] = string_len; /* last substring ends just past eos */
+ list->num_items = numdiv+1;
+
+
+ /*
+ * OK, now we know how many divisions there are and where they are --
+ * so let's split that string up for real!
+ *
+ * list->items will be an array of pointers into a duplicate of
+ * `string'; we duplicate `string' so we can safely scribble on it and
+ * free() it later (in bt_free_list()).
+ */
+
+ list->items = (char **) malloc (list->num_items * sizeof (char *));
+ list->string = strdup (string);
+
+ for (i = 0; i < list->num_items; i++)
+ {
+ /*
+ * Possible cases:
+ * - stop < start is for empty elements, e.g. "and and" seen in
+ * input. (`start' for empty element will be the 'a' of the
+ * second 'and', and its stop will be the ' ' *before* the
+ * second 'and'.)
+ * - stop > start is for anything else between two and's (the usual)
+ * - stop == start should never happen if the loop above is correct
+ */
+
+ if (stop[i] > start[i]) /* the usual case */
+ {
+ list->string[stop[i]] = 0;
+ list->items[i] = list->string+start[i];
+ }
+ else if (stop[i] < start[i]) /* empty element */
+ {
+ list->items[i] = NULL;
+ general_error (BTERR_CONTENT, filename, line,
+ description, i+1, "empty %s", description);
+ }
+ else /* should not happen! */
+ {
+ internal_error ("stop == start for substring %d", i);
+ }
+ }
+
+ return list;
+/* return num_substrings; */
+
+} /* bt_split_list () */
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_free_list()
+@INPUT : list
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Frees the list of strings created by bt_split_list().
+@GLOBALS :
+@CALLS :
+@CALLERS : anyone (exported by library)
+@CREATED : 1997/05/06, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void bt_free_list (bt_stringlist *list)
+{
+ if (list && list->string) free (list->string);
+ if (list && list->items) free (list->items);
+ if (list) free (list);
+}
+
+
+
+/* ----------------------------------------------------------------------
+ * Stuff for splitting up a single name
+ */
+
+
+/* ------------------------------------------------------------------------
+@NAME : find_commas
+@INPUT : name - string to search for commas
+ max_commas - maximum number of commas to allow (if more than
+ this number are seen, a warning is printed and
+ the excess commas are removed)
+@OUTPUT :
+@RETURNS : number of commas found
+@DESCRIPTION: Counts and records positions of commas at brace-depth 0.
+ Modifies string in-place to remove whitespace around commas,
+ excess commas, and any trailing commas; warns on excess or
+ trailing commas. Excess commas are removed by replacing them
+ with space and calling bt_postprocess_string() to collapse
+ whitespace a second time; trailing commas are simply replaced
+ with (char) 0 to truncate the string.
+
+ Assumes whitespace has been collapsed (ie. no space at
+ beginning or end of string, and all internal strings of
+ whitespace reduced to exactly one space).
+@GLOBALS :
+@CALLS : name_warning() (if too many commas, or commas at end)
+@CALLERS : bt_split_name()
+@CREATED : 1997/05/14, Greg Ward
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static int
+find_commas (name_loc * loc, char *name, int max_commas)
+{
+ int i, j;
+ int depth;
+ int num_commas;
+ int len;
+ boolean at_comma;
+ boolean warned;
+
+ i = j = 0;
+ depth = 0;
+ num_commas = 0;
+ len = strlen (name);
+ warned = 0;
+
+ /* First pass to check for and blank out excess commas */
+
+ for (i = 0; i < len; i++)
+ {
+ if (depth == 0 && name[i] == ',')
+ {
+ num_commas++;
+ if (num_commas > max_commas)
+ {
+ if (! warned)
+ {
+ name_warning (loc, "too many commas in name (removing extras)");
+ warned = TRUE;
+ }
+ name[i] = ' ';
+ }
+ }
+ }
+
+ /*
+ * If we blanked out a comma, better re-collapse whitespace. (This is
+ * a bit of a cop-out -- I could probably adjust i and j appropriately
+ * in the above loop to do the collapsing for me, but my brain
+ * hurt when I tried to think it through. Some other time, perhaps.
+ */
+
+ if (warned)
+ bt_postprocess_string (name, BTO_COLLAPSE);
+
+ /* Now the real comma-finding loop (only if necessary) */
+
+ if (num_commas == 0)
+ return 0;
+
+ num_commas = 0;
+ i = 0;
+ while (i < len)
+ {
+ at_comma = (depth == 0 && name[i] == ',');
+ if (at_comma)
+ {
+ while (j > 0 && name[j-1] == ' ') j--;
+ num_commas++;
+ }
+
+ update_depth (name, i, depth);
+ if (i != j)
+ name[j] = name[i];
+
+ i++; j++;
+ if (at_comma)
+ {
+ while (i < len && name[i] == ' ') i++;
+ }
+ } /* while i */
+
+ if (i != j) name[j] = (char) 0;
+ j--;
+
+ if (name[j] == ',')
+ {
+ name_warning (loc, "comma(s) at end of name (removing)");
+ while (name[j] == ',')
+ {
+ name[j--] = (char) 0;
+ num_commas--;
+ }
+ }
+
+ return num_commas;
+
+} /* find_commas() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : find_tokens
+@INPUT : name - string to tokenize (should be a private copy
+ that we're free to clobber and mangle)
+@OUTPUT : comma_token- number of token immediately preceding each comma
+ (caller must allocate with at least one element
+ per comma in `name')
+@RETURNS : newly-allocated bt_stringlist structure
+@DESCRIPTION: Finds tokens in a string; delimiter is space or comma at
+ brace-depth zero. Assumes whitespace has been collapsed
+ and find_commas has been run on the string to remove
+ whitespace around commas and any trailing commas.
+
+ The bt_stringlist structure returned can (and should) be
+ freed with bt_free_list().
+@GLOBALS :
+@CALLS :
+@CALLERS : bt_split_name()
+@CREATED : 1997/05/14, Greg Ward
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static bt_stringlist *
+find_tokens (char * name,
+ int * comma_token)
+{
+ int i; /* index into name */
+ int num_tok;
+ int in_boundary; /* previous char was ' ' or ',' */
+ int cur_comma; /* index into comma_token */
+ int len;
+ int depth;
+ bt_stringlist *
+ tokens;
+
+ i = 0;
+ in_boundary = 1; /* so first char will start a token */
+ cur_comma = 0;
+ len = strlen (name);
+ depth = 0;
+
+ tokens = (bt_stringlist *) malloc (sizeof (bt_stringlist));
+ /* tokens->string = name ? strdup (name) : NULL; */
+ tokens->string = name;
+ num_tok = 0;
+ tokens->items = NULL;
+
+ if (len == 0) /* empty string? */
+ return tokens; /* return empty token list */
+
+ tokens->items = (char **) malloc (sizeof (char *) * len);
+
+ while (i < len)
+ {
+ if (depth == 0 && in_boundary) /* at start of a new token */
+ {
+ tokens->items[num_tok++] = name+i;
+ }
+
+ if (depth == 0 && (name[i] == ' ' || name[i] == ','))
+ {
+ /* if we're at a comma, record the token preceding the comma */
+
+ if (name[i] == ',')
+ {
+ comma_token[cur_comma++] = num_tok-1;
+ }
+
+ /*
+ * if already in a boundary zone, we have an empty token
+ * (caused by multiple consecutive commas)
+ */
+ if (in_boundary)
+ {
+ tokens->items[num_tok-1] = NULL;
+ }
+ num_tok--;
+
+ /* in any case, mark the end of one token and prepare for the
+ * start of the next
+ */
+ name[i] = (char) 0;
+ in_boundary = 1;
+ }
+ else
+ {
+ in_boundary = 0; /* inside a token */
+ }
+
+ update_depth (name, i, depth);
+ i++;
+
+ } /* while i */
+
+ tokens->num_items = num_tok;
+ return tokens;
+
+} /* find_tokens() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : find_lc_tokens()
+@INPUT : tokens
+@OUTPUT : first_lc
+ last_lc
+@RETURNS :
+@DESCRIPTION: Finds the first contiguous string of lowercase tokens in
+ `name'. The string must already be tokenized by
+ find_tokens(), and the input args num_tok, tok_start, and
+ tok_stop are the return value and the two same-named output
+ arguments from find_tokens().
+@GLOBALS :
+@CALLS :
+@CALLERS : bt_split_name()
+@CREATED : 1997/05/14, Greg Ward
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static void
+find_lc_tokens (bt_stringlist * tokens,
+ int * first_lc,
+ int * last_lc)
+{
+ int i; /* iterate over token list this time */
+ int in_lc_sequence; /* in contig. sequence of lc tokens? */
+
+ *first_lc = *last_lc = -1; /* haven't found either yet */
+ in_lc_sequence = 0;
+
+ i = 0;
+ while (i < tokens->num_items)
+ {
+ if (*first_lc == -1 && islower (tokens->items[i][0]))
+ {
+ *first_lc = i;
+
+ i++;
+ while (i < tokens->num_items && islower (tokens->items[i][0]))
+ i++;
+
+ *last_lc = i-1;
+ }
+ else
+ {
+ i++;
+ }
+ }
+} /* find_lc_tokens() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : resolve_token_range()
+@INPUT : tokens - structure containing the token list
+ tok_range - two-element array with start and stop token number
+@OUTPUT : *part - set to point to first token in range, or NULL
+ if empty range
+ *num_tok - number of tokens in the range
+@RETURNS :
+@DESCRIPTION: Given a list of tokens and a range of token numbers (as a
+ two-element array, tok_range), computes the number of tokens
+ in the range. If this is >= 0, sets *part to point
+ to the first token in the range; otherwise, sets *part
+ to NULL.
+@CALLERS :
+@CREATED : May 1997, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static void
+resolve_token_range (bt_stringlist *tokens,
+ int * tok_range,
+ char *** part,
+ int * num_tok)
+{
+ *num_tok = (tok_range[1] - tok_range[0]) + 1;
+ if (*num_tok <= 0)
+ {
+ *num_tok = 0;
+ *part = NULL;
+ }
+ else
+ {
+ *part = tokens->items + tok_range[0];
+ }
+} /* resolve_token_range() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : split_simple_name()
+@INPUT : name
+ first_lc
+ last_lc
+@OUTPUT : name
+@RETURNS :
+@DESCRIPTION: Splits up a name (represented as a string divided into
+ non-overlapping, whitespace-separated tokens) according
+ to the BibTeX rules for names without commas. Specifically:
+ * tokens up to (but not including) the first lowercase
+ token, or the last token of the string if there
+ are no lowercase tokens, become the `first' part
+ * the earliest contiguous sequence of lowercase tokens,
+ up to (but not including) the last token of the string,
+ becomes the `von' part
+ * the tokens following the `von' part, or the last
+ single token if there is no `von' part, become
+ the `last' part
+ * there is no `jr' part
+@GLOBALS :
+@CALLS : name_warning() (if last lc token taken as lastname)
+ resolve_token_range()
+@CALLERS : bt_split_name()
+@CREATED : 1997/05/15, Greg Ward
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static void
+split_simple_name (name_loc * loc,
+ bt_name * name,
+ int first_lc,
+ int last_lc)
+{
+ int first_t[2], von_t[2], last_t[2];
+ int end;
+
+ end = name->tokens->num_items-1; /* token number of last token */
+
+ if (first_lc > -1) /* any lowercase tokens at all? */
+ {
+ first_t[0] = 0; /* first name goes from beginning */
+ first_t[1] = first_lc-1; /* to just before first lc token */
+
+ if (last_lc == end) /* sequence of lowercase tokens */
+ { /* goes all the way to end of string */
+ last_lc--; /* -- roll it back by one so we */
+ /* still have a lastname */
+#ifdef WARN_LC_LASTNAME
+ /*
+ * disable this warning for now because "others" is used fairly
+ * often as a name in BibTeX databases -- oops!
+ */
+ name_warning (loc,
+ "no capitalized token at end of name; "
+ "using \"%s\" as lastname",
+ name->tokens->items[end]);
+#else
+# ifndef ALLOW_WARNINGS
+ loc = NULL; /* avoid "unused parameter" warning */
+# endif
+#endif
+ }
+
+ von_t[0] = first_lc; /* `von' part covers sequence of */
+ von_t[1] = last_lc; /* lowercase tokens */
+ last_t[0] = last_lc+1; /* lastname from after `von' to end */
+ last_t[1] = end; /* of string */
+ }
+ else /* no lowercase tokens */
+ {
+ von_t[0] = 0; /* empty `von' part */
+ von_t[1] = -1;
+ first_t[0] = 0; /* `first' goes from first to second */
+ first_t[1] = end-1; /* last token */
+ last_t[0] = last_t[1] = end; /* and `last' is just the last token */
+ }
+
+ resolve_token_range (name->tokens, first_t,
+ name->parts+BTN_FIRST, name->part_len+BTN_FIRST);
+ resolve_token_range (name->tokens, von_t,
+ name->parts+BTN_VON, name->part_len+BTN_VON);
+ resolve_token_range (name->tokens, last_t,
+ name->parts+BTN_LAST, name->part_len+BTN_LAST);
+ name->parts[BTN_JR] = NULL; /* no jr part possible */
+ name->part_len[BTN_JR] = 0;
+
+} /* split_simple_name() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : split_general_name()
+@INPUT : name
+ num_commas
+ comma_token
+ first_lc
+ last_lc
+@OUTPUT : name
+@RETURNS :
+@DESCRIPTION: Splits a name according to the BibTeX rules for names
+ with 1 or 2 commas (> 2 commas is handled elsewhere,
+ namely by bt_split_name() calling find_commas() with
+ max_commas == 2). Specifically:
+ * an initial string of lowercase tokens, up to (but not
+ including) the token before the first comma, becomes
+ the `von' part
+ * tokens from immediately after the `von' part,
+ or from the beginning of the string if no `von',
+ up to the first comma become the `last' part
+
+ if one comma:
+ * all tokens following the sole comma become the
+ `first' part
+
+ if two commas:
+ * tokens between the two commas become the `jr' part
+ * all tokens following the second comma become the
+ `first' part
+@GLOBALS :
+@CALLS : name_warning() (if last lc token taken as lastname)
+ resolve_token_range()
+@CALLERS : bt_split_name()
+@CREATED : 1997/05/15, Greg Ward
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static void
+split_general_name (name_loc * loc,
+ bt_name * name,
+ int num_commas,
+ int * comma_token,
+ int first_lc,
+ int last_lc)
+{
+ int first_t[2], von_t[2], last_t[2], jr_t[2];
+ int end;
+
+ end = name->tokens->num_items-1; /* last token number */
+
+ if (first_lc == 0) /* we have an initial string of */
+ { /* lowercase tokens */
+ if (last_lc == comma_token[0]) /* lc string ends at first comma */
+ {
+ name_warning (loc, "no capitalized tokens before first comma");
+ last_lc--;
+ }
+
+ von_t[0] = first_lc; /* `von' covers the sequence of */
+ von_t[1] = last_lc; /* lowercase tokens */
+ }
+ else /* no lowercase tokens at start */
+ {
+ von_t[0] = 0; /* empty `von' part */
+ von_t[1] = -1;
+ }
+
+ last_t[0] = von_t[1] + 1; /* start right after end of `von' */
+ last_t[1] = comma_token[0]; /* and end at first comma */
+
+ if (num_commas == 1)
+ {
+ first_t[0] = comma_token[0]+1; /* start right after comma */
+ first_t[1] = end; /* stop at end of string */
+ jr_t[0] = 0; /* empty `jr' part */
+ jr_t[1] = -1;
+ }
+ else /* more than 1 comma */
+ {
+ jr_t[0] = comma_token[0]+1; /* start after first comma */
+ jr_t[1] = comma_token[1]; /* stop at second comma */
+ first_t[0] = comma_token[1]+1; /* start after second comma */
+ first_t[1] = end; /* and go to end */
+ }
+
+ resolve_token_range (name->tokens, first_t,
+ name->parts+BTN_FIRST, name->part_len+BTN_FIRST);
+ resolve_token_range (name->tokens, von_t,
+ name->parts+BTN_VON, name->part_len+BTN_VON);
+ resolve_token_range (name->tokens, last_t,
+ name->parts+BTN_LAST, name->part_len+BTN_LAST);
+ resolve_token_range (name->tokens, jr_t,
+ name->parts+BTN_JR, name->part_len+BTN_JR);
+
+} /* split_general_name() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_split_name()
+@INPUT : name
+ filename
+ line
+ name_num
+@OUTPUT :
+@RETURNS : newly-allocated bt_name structure containing the four
+ parts as token-lists
+@DESCRIPTION: Splits a name according to the BibTeX rules. There are
+ actually two sets of rules: one for names with no commas,
+ and one for names with 1 or 2 commas. (If a name has
+ more than 2 commas, the extras are removed and it's treated
+ as though it had just the first 2.)
+
+ See split_simple_name() for the no-comma rules, and
+ split_general_name() for the 1-or-2-commas rules.
+
+ The bt_name structure returned can (and should) be freed
+ with bt_free_name() when you no longer need it.
+@GLOBALS :
+@CALLS :
+@CALLERS : anyone (exported by library)
+@CREATED : 1997/05/14, Greg Ward
+@MODIFIED :
+@COMMENTS : The name-splitting code all implicitly assumes that the
+ string being split has been post-processed to collapse
+ whitespace in the BibTeX way. This means that it tends to
+ dump core on such things as leading whitespace, or more than
+ one space in a row inside the string. This could probably be
+ alleviated with a call to bt_postprocess_string(), possibly
+ preceded by a check for any of those occurences. Before
+ doing that, though, I want to examine the code carefully to
+ determine just what assumptions it makes -- so I can
+ check/correct for all of them.
+-------------------------------------------------------------------------- */
+bt_name *
+bt_split_name (char * name,
+ char * filename,
+ int line,
+ int name_num)
+{
+ name_loc loc;
+ bt_stringlist *
+ tokens;
+ int comma_token[MAX_COMMAS];
+ int len;
+ int num_commas;
+ int first_lc, last_lc;
+ bt_name * split_name;
+ int i;
+
+ DBG_ACTION (1, printf ("bt_split_name(): name=%p (%s)\n", name, name))
+
+ split_name = (bt_name *) malloc (sizeof (bt_name));
+ if (name == NULL)
+ {
+ len = 0;
+ }
+ else
+ {
+ name = strdup (name); /* private copy that we may clobber */
+ len = strlen (name);
+ }
+
+ DBG_ACTION (1, printf ("bt_split_name(): split_name=%p\n", split_name))
+
+ if (len == 0) /* non-existent or empty string? */
+ {
+ split_name->tokens = NULL;
+ for (i = 0; i < BT_MAX_NAMEPARTS; i++)
+ {
+ split_name->parts[i] = NULL;
+ split_name->part_len[i] = 0;
+ }
+ return split_name;
+ }
+
+ loc.filename = filename; /* so called functions can generate */
+ loc.line = line; /* decent warning messages */
+ loc.name_num = name_num;
+
+ num_commas = find_commas (&loc, name, MAX_COMMAS);
+ assert (num_commas <= MAX_COMMAS);
+
+ DBG_ACTION (1, printf ("found %d commas: ", num_commas))
+
+ tokens = find_tokens (name, comma_token);
+
+#if DEBUG
+ printf ("found %d tokens:\n", tokens->num_items);
+ for (i = 0; i < tokens->num_items; i++)
+ {
+ printf (" %d: ", i);
+
+ if (tokens->items[i]) /* non-empty token? */
+ {
+ printf (">%s<\n", tokens->items[i]);
+ }
+ else
+ {
+ printf ("(empty)\n");
+ }
+ }
+#endif
+
+#if DEBUG
+ printf ("comma tokens: ");
+ for (i = 0; i < num_commas; i++)
+ printf ("%d ", comma_token[i]);
+ printf ("\n");
+#endif
+
+ find_lc_tokens (tokens, &first_lc, &last_lc);
+#if DEBUG
+ printf ("(first,last) lc tokens = (%d,%d)\n", first_lc, last_lc);
+#endif
+
+ if (strlen (name) == 0) /* name now empty? */
+ {
+ split_name->tokens = NULL;
+ for (i = 0; i < BT_MAX_NAMEPARTS; i++)
+ {
+ split_name->parts[i] = NULL;
+ split_name->part_len[i] = 0;
+ }
+ }
+ else
+ {
+ split_name->tokens = tokens;
+ if (num_commas == 0) /* no commas -- "simple" format */
+ {
+ split_simple_name (&loc, split_name,
+ first_lc, last_lc);
+ }
+ else
+ {
+ split_general_name (&loc, split_name,
+ num_commas, comma_token,
+ first_lc, last_lc);
+ }
+ }
+
+#if DEBUG
+ printf ("bt_split_name(): returning structure %p\n", split_name);
+#endif
+ return split_name;
+} /* bt_split_name() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_free_name()
+@INPUT : name
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Frees up any memory allocated for a bt_name structure
+ (namely, the `tokens' field [a bt_stringlist structure,
+ this freed with bt_free_list()] and the structure itself.)
+@CALLS : bt_free_list()
+@CALLERS : anyone (exported)
+@CREATED : 1997/11/14, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void
+bt_free_name (bt_name * name)
+{
+ DBG_ACTION (2, printf ("bt_free_name(): freeing name %p "
+ "(%d tokens, string=%p (%s), last[0]=%s)\n",
+ name,
+ name->tokens->num_items,
+ name->tokens->string,
+ name->tokens->string,
+ name->parts[BTN_LAST][0]));
+ bt_free_list (name->tokens);
+ free (name);
+ DBG_ACTION (2, printf ("bt_free_name(): done, everything freed\n"));
+}
diff --git a/src/translators/btparse/parse_auxiliary.c b/src/translators/btparse/parse_auxiliary.c
new file mode 100644
index 0000000..f509741
--- /dev/null
+++ b/src/translators/btparse/parse_auxiliary.c
@@ -0,0 +1,336 @@
+/* ------------------------------------------------------------------------
+@NAME : parse_auxiliary.c
+@INPUT :
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Anything needed by the parser that's too hairy to go in the
+ grammar itself. Currently, just stuff needed for generating
+ syntax errors. (See error.c for how they're actually
+ printed.)
+@GLOBALS :
+@CALLS :
+@CALLERS :
+@CREATED : 1996/08/07, Greg Ward
+@MODIFIED :
+@VERSION : $Id: parse_auxiliary.c,v 1.20 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+
+/*#include "bt_config.h"*/
+#include "stdpccts.h"
+#include "error.h"
+#include "lex_auxiliary.h"
+#include "parse_auxiliary.h"
+/*#include "my_dmalloc.h"*/
+
+extern char * InputFilename; /* from input.c */
+
+GEN_PRIVATE_ERRFUNC (syntax_error, (char * fmt, ...),
+ BTERR_SYNTAX, InputFilename, zzline, NULL, -1, fmt)
+
+
+/* this is stolen from PCCTS' err.h */
+static SetWordType bitmask[] =
+{
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008,
+ 0x00000010, 0x00000020, 0x00000040, 0x00000080
+};
+
+static struct
+{
+ int token;
+ const char *new_name;
+} new_tokens[] =
+{
+ { AT, "\"@\"" },
+ { NAME, "name (entry type, key, field, or macro name)" },
+ { LBRACE, "left brace (\"{\")" },
+ { RBRACE, "right brace (\"}\")" },
+ { ENTRY_OPEN, "start of entry (\"{\" or \"(\")" },
+ { ENTRY_CLOSE,"end of entry (\"}\" or \")\")" },
+ { EQUALS, "\"=\"" },
+ { HASH, "\"#\"" },
+ { COMMA, "\",\"" },
+ { NUMBER, "number" },
+ { STRING, "quoted string ({...} or \"...\")" }
+};
+
+
+#ifdef CLEVER_TOKEN_STUFF
+char **token_names;
+#endif
+
+
+void
+fix_token_names (void)
+{
+ int i;
+ int num_replace;
+
+#ifdef CLEVER_TOKEN_STUFF /* clever, but it doesn't work... */
+ /* arg! this doesn't work because I don't know how to find out the
+ * number of tokens
+ */
+
+ int num_tok;
+
+ num_tok = (sizeof(zztokens) / sizeof(*zztokens));
+ sizeof (zztokens);
+ sizeof (*zztokens);
+ token_names = (char **) malloc (sizeof (char *) * num_tok);
+
+ for (i = 0; i < num_tok; i++)
+ {
+ token_names[i] = zztokens[i];
+ }
+#endif
+
+ num_replace = (sizeof(new_tokens) / sizeof(*new_tokens));
+ for (i = 0; i < num_replace; i++)
+ {
+ const char *new = new_tokens[i].new_name;
+ const char **old = zztokens + new_tokens[i].token;
+
+ *old = new;
+ }
+}
+
+
+#ifdef USER_ZZSYN
+
+static void
+append_token_set (char *msg, SetWordType *a)
+{
+ SetWordType *p = a;
+ SetWordType *endp = &(p[zzSET_SIZE]);
+ unsigned e = 0;
+ int tokens_printed = 0;
+
+ do
+ {
+ SetWordType t = *p;
+ SetWordType *b = &(bitmask[0]);
+ do
+ {
+ if (t & *b)
+ {
+ strcat (msg, zztokens[e]);
+ tokens_printed++;
+ if (tokens_printed < zzset_deg (a) - 1)
+ strcat (msg, ", ");
+ else if (tokens_printed == zzset_deg (a) - 1)
+ strcat (msg, " or ");
+ }
+ e++;
+ } while (++b < &(bitmask[sizeof(SetWordType)*8]));
+ } while (++p < endp);
+}
+
+
+void
+zzsyn(const char * text,
+ int tok,
+ char * egroup,
+ SetWordType * eset,
+ int etok,
+ int k,
+ const char * bad_text)
+{
+ static char msg [MAX_ERROR];
+ int len;
+
+#ifndef ALLOW_WARNINGS
+ text = NULL; /* avoid "unused parameter" warning */
+#endif
+
+ /* Initial message: give location of error */
+
+ msg[0] = (char) 0; /* make sure string is empty to start! */
+ if (tok == zzEOF_TOKEN)
+ strcat (msg, "at end of input");
+ else
+ sprintf (msg, "found \"%s\"", bad_text);
+
+ len = strlen (msg);
+
+
+ /* Caller supplied neither a single token nor set of tokens expected... */
+
+ if (!etok && !eset)
+ {
+ syntax_error (msg);
+ return;
+ }
+ else
+ {
+ strcat (msg, ", ");
+ len += 2;
+ }
+
+
+ /* I'm not quite sure what this is all about, or where k would be != 1... */
+
+ if (k != 1)
+ {
+ sprintf (msg+len, "; \"%s\" not", bad_text);
+ if (zzset_deg (eset) > 1) strcat (msg, " in");
+ len = strlen (msg);
+ }
+
+
+ /* This is the code that usually gets run */
+
+ if (zzset_deg (eset) > 0)
+ {
+ if (zzset_deg (eset) == 1)
+ strcat (msg, "expected ");
+ else
+ strcat (msg, "expected one of: ");
+
+ append_token_set (msg, eset);
+ }
+ else
+ {
+ sprintf (msg+len, "expected %s", zztokens[etok]);
+ if (etok == ENTRY_CLOSE)
+ {
+ strcat (msg, " (skipping to next \"@\")");
+ initialize_lexer_state ();
+ }
+ }
+
+ len = strlen (msg);
+ if (egroup && strlen (egroup) > 0)
+ sprintf (msg+len, " in %s", egroup);
+
+ syntax_error (msg);
+
+}
+#endif /* USER_ZZSYN */
+
+
+void
+check_field_name (AST * field)
+{
+ char * name;
+
+ if (! field || field->nodetype != BTAST_FIELD)
+ return;
+
+ name = field->text;
+ if (strchr ("0123456789", name[0]))
+ syntax_error ("invalid field name \"%s\": cannot start with digit",
+ name);
+}
+
+
+#ifdef STACK_DUMP_CODE
+
+static void
+show_ast_stack_elem (int num)
+{
+ extern const char *nodetype_names[]; /* nicked from bibtex_ast.c */
+ /* bt_nodetype nodetype;
+ bt_metatype metatype; */
+ AST *elem;
+
+ elem = zzastStack[num];
+ printf ("zzastStack[%3d] = ", num);
+ if (elem)
+ {
+ /* get_node_type (elem, &nodetype, &metatype); */
+ if (elem->nodetype <= BTAST_MACRO)
+ {
+ printf ("{ %s: \"%s\" (line %d, char %d) }\n",
+ nodetype_names[elem->nodetype],
+ elem->text, elem->line, elem->offset);
+ }
+ else
+ {
+ printf ("bogus node (uninitialized?)\n");
+ }
+ }
+ else
+ {
+ printf ("NULL\n");
+ }
+}
+
+
+static void
+show_ast_stack_top (char *label)
+{
+ if (label)
+ printf ("%s: ast stack top: ", label);
+ else
+ printf ("ast stack top: ");
+ show_ast_stack_elem (zzast_sp);
+}
+
+
+static void
+dump_ast_stack (char *label)
+{
+ int i;
+
+ if (label)
+ printf ("%s: complete ast stack:\n", label);
+ else
+ printf ("complete ast stack:\n");
+
+ for (i = zzast_sp; i < ZZAST_STACKSIZE; i++)
+ {
+ printf (" ");
+ show_ast_stack_elem (i);
+ }
+}
+
+
+static void
+show_attrib_stack_elem (int num)
+{
+ Attrib elem;
+
+ elem = zzaStack[num];
+ printf ("zzaStack[%3d] = ", num);
+ printf ("{ \"%s\" (token %d (%s), line %d, char %d) }\n",
+ elem.text, elem.token, zztokens[elem.token],
+ elem.line, elem.offset);
+}
+
+
+static void
+show_attrib_stack_top (char *label)
+{
+ if (label)
+ printf ("%s: attrib stack top: ", label);
+ else
+ printf ("attrib stack top: ");
+ show_attrib_stack_elem (zzasp);
+}
+
+
+static void
+dump_attrib_stack (char *label)
+{
+ int i;
+
+ if (label)
+ printf ("%s: complete attrib stack:\n", label);
+ else
+ printf ("complete attrib stack:\n");
+
+ for (i = zzasp; i < ZZA_STACKSIZE; i++)
+ {
+ printf (" ");
+ show_attrib_stack_elem (i);
+ }
+}
+
+#endif /* STACK_DUMP_CODE */
diff --git a/src/translators/btparse/parse_auxiliary.h b/src/translators/btparse/parse_auxiliary.h
new file mode 100644
index 0000000..5500513
--- /dev/null
+++ b/src/translators/btparse/parse_auxiliary.h
@@ -0,0 +1,32 @@
+/* ------------------------------------------------------------------------
+@NAME : parse_auxiliary.h
+@INPUT :
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Prototype declarations for functions in parse_auxiliary.c
+@GLOBALS :
+@CALLS :
+@CREATED : 1997/01/08, Greg Ward
+@MODIFIED :
+@VERSION : $Id: parse_auxiliary.h,v 1.5 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+
+#ifndef PARSE_AUXILIARY_H
+#define PARSE_AUXILIARY_H
+
+#include "stdpccts.h" /* for SetWordType typedef */
+
+void fix_token_names (void);
+void zzsyn (const char *text, int tok,
+ char *egroup, SetWordType *eset, int etok,
+ int k, const char *bad_text);
+void check_field_name (AST * field);
+
+#endif /* PARSE_AUXILIARY_H */
diff --git a/src/translators/btparse/postprocess.c b/src/translators/btparse/postprocess.c
new file mode 100644
index 0000000..7f7bfd4
--- /dev/null
+++ b/src/translators/btparse/postprocess.c
@@ -0,0 +1,498 @@
+/* ------------------------------------------------------------------------
+@NAME : postprocess.c
+@DESCRIPTION: Operations applied to the AST (or strings in it) after
+ parsing is complete.
+@GLOBALS :
+@CALLS :
+@CREATED : 1997/01/12, Greg Ward (from code in bibparse.c, lex_auxiliary.c)
+@MODIFIED :
+@VERSION : $Id: postprocess.c,v 1.25 2000/05/02 23:06:31 greg Exp $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+/*#include "bt_config.h"*/
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "btparse.h"
+#include "error.h"
+#include "parse_auxiliary.h"
+#include "prototypes.h"
+/*#include "my_dmalloc.h"*/
+
+#define DEBUG 1
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_postprocess_string ()
+@INPUT : s
+ options
+@OUTPUT : s (modified in place according to the flags)
+@RETURNS : (void)
+@DESCRIPTION: Make a pass over string s (which is modified in-place) to
+ optionally collapse whitespace according to BibTeX rules
+ (if the BTO_COLLAPSE bit in options is true).
+
+ Rules for collapsing whitespace are:
+ * whitespace at beginning/end of string is deleted
+ * within the string, each whitespace sequence is replaced by
+ a single space
+
+ Note that part of the work is done by the lexer proper,
+ namely conversion of tabs and newlines to spaces.
+@GLOBALS :
+@CALLS :
+@CREATED : originally in lex_auxiliary.c; moved here 1997/01/12
+@MODIFIED :
+@COMMENTS : this only collapses whitespace now -- rename it???
+-------------------------------------------------------------------------- */
+void
+bt_postprocess_string (char * s, ushort options)
+{
+ boolean collapse_whitespace;
+ char *i, *j;
+ int len;
+
+ if (s == NULL) return; /* quit if no string supplied */
+
+#if DEBUG > 1
+ printf ("bt_postprocess_string: looking at >%s<\n", s);
+#endif
+
+ /* Extract any relevant options (just one currently) to local flags. */
+ collapse_whitespace = options & BTO_COLLAPSE;
+
+ /*
+ * N.B. i and j will both point into s; j is always >= i, and
+ * we copy characters from j to i. Whitespace is collapsed/deleted
+ * by advancing j without advancing i.
+ */
+ i = j = s; /* start both at beginning of string */
+
+ /*
+ * If we're supposed to collapse whitespace, then advance j to the
+ * first non-space character.
+ */
+ if (collapse_whitespace)
+ {
+ while (*j == ' ' && *j != (char) 0)
+ j++;
+ }
+
+ while (*j != (char) 0)
+ {
+ /*
+ * If we're in a string of spaces (ie. current and previous char.
+ * are both space), and we're supposed to be collapsing whitespace,
+ * then skip until we hit a non-space character (or end of string).
+ */
+ if (collapse_whitespace && *j == ' ' && *(j-1) == ' ')
+ {
+ while (*j == ' ') j++; /* skip spaces */
+ if (*j == (char) 0) /* reached end of string? */
+ break;
+ }
+
+ /* Copy the current character from j down to i */
+ *(i++) = *(j++);
+ }
+ *i = (char) 0; /* ensure string is terminated */
+
+
+ /*
+ * And mop up whitespace (if any) at end of string -- note that if there
+ * was any whitespace there, it has already been collapsed to exactly
+ * one space.
+ */
+ len = strlen (s);
+ if (len > 0 && collapse_whitespace && s[len-1] == ' ')
+ {
+ s[--len] = (char) 0;
+ }
+
+#if DEBUG > 1
+ printf (" transformed to >%s<\n", s);
+#endif
+
+} /* bt_postprocess_string */
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_postprocess_value()
+@INPUT :
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Post-processes a series of strings (compound value),
+ frequently found as the value of a "field = value" or "macro
+ = value" assignment. The actions taken here are governed by
+ the bits in 'options', but there are two distinct modes of
+ operation: pasting or not.
+
+ We paste strings if and only if the BTO_PASTE bit in options
+ is set and there are two or more simple values in the
+ compound value. In this case, the BTO_EXPAND bit must be set
+ (it would be very silly to paste together strings with
+ unexpanded macro names!), and we make two passes over the
+ data: one to postprocess individual strings and accumulate
+ the one big string, and a second to postprocess the big
+ string. In the first pass, the caller-supplied 'options'
+ variable is largely ignored; we will never collapse
+ whitespace in the individual strings. The caller's wishes
+ are fully respected when we make the final post-processing
+ pass over the concatenation of the individual strings,
+ though.
+
+ If we're not pasting strings, then the character of the
+ individual simple values will be preserved; macros might not
+ be expanded (depending on the BTO_EXPAND bit), numbers will
+ stay numbers, and strings will be post-processed
+ independently according to the 'options' variable. (Beware
+ -- this means you might collapse whitespace in individual
+ sub-strings, which would be bad if you intend to concatenate
+ them later in the BibTeX sense.)
+
+ The 'replace' parameter is used to govern whether the
+ existing strings in the AST should be replaced with their
+ post-processed versions. This can extend as far as
+ collapsing a series of simple values into a single BTAST_STRING
+ node, if we paste sub-strings together. If replace is FALSE,
+ the returned string is allocated here, and you must free() it
+ later.
+@GLOBALS :
+@CALLS :
+@CREATED : 1997/01/10, GPW
+@MODIFIED : 1997/08/25, GPW: renamed from bt_postprocess_field(), and changed
+ to take the head of a list of simple values,
+ rather than the parent of that list
+-------------------------------------------------------------------------- */
+char *
+bt_postprocess_value (AST * value, ushort options, boolean replace)
+{
+ AST * simple_value; /* current simple value */
+ boolean pasting;
+ ushort string_opts; /* what to do to individual strings */
+ int tot_len; /* total length of pasted string */
+ char * new_string; /* in case of string pasting */
+ char * tmp_string;
+ boolean free_tmp; /* should we free() tmp_string? */
+
+ if (value == NULL) return NULL;
+ if (value->nodetype != BTAST_STRING &&
+ value->nodetype != BTAST_NUMBER &&
+ value->nodetype != BTAST_MACRO)
+ {
+ usage_error ("bt_postprocess_value: invalid AST node (not a value)");
+ }
+
+
+ /*
+ * We will paste strings iff the user wants us to, and there are at least
+ * two simple values in the list headed by 'value'.
+ */
+
+ pasting = (options & BTO_PASTE) && (value->right);
+
+ /*
+ * If we're to concatenate (paste) sub-strings, we need to know the
+ * total length of them. So make a pass over all the sub-strings
+ * (simple values), adding up their lengths.
+ */
+
+ tot_len = 0; /* these are out here to keep */
+ new_string = NULL; /* gcc -Wall happy */
+ tmp_string = NULL;
+
+ if (pasting)
+ {
+ simple_value = value;
+ while (simple_value)
+ {
+ switch (simple_value->nodetype)
+ {
+ case BTAST_MACRO:
+ tot_len += bt_macro_length (simple_value->text);
+ break;
+ case BTAST_STRING:
+ tot_len += (simple_value->text)
+ ? (strlen (simple_value->text)) : 0;
+ break;
+ case BTAST_NUMBER:
+ tot_len += (simple_value->text)
+ ? (strlen (simple_value->text)) : 0;
+ break;
+ default:
+ internal_error ("simple value has bad nodetype (%d)",
+ (int) simple_value->nodetype);
+ }
+ simple_value = simple_value->right;
+ }
+
+ /* Now allocate the buffer in which we'll accumulate the whole string */
+
+ new_string = (char *) calloc (tot_len+1, sizeof (char));
+ }
+
+
+ /*
+ * Before entering the main loop, figure out just what
+ * bt_postprocess_string() is supposed to do -- eg. if pasting strings,
+ * we should not (yet) collapse whitespace. (That'll be done on the
+ * final, concatenated string -- assuming the caller put BTO_COLLAPSE in
+ * the options bitmap.)
+ */
+
+ if (pasting)
+ {
+ string_opts = options & ~BTO_COLLAPSE; /* turn off collapsing */
+ }
+ else
+ {
+ string_opts = options; /* leave it alone */
+ }
+
+ /*
+ * Sanity check: if we continue blindly on, we might stupidly
+ * concatenate a macro name and a literal string. So check for that.
+ * Converting numbers is superficial, but requiring that it be done
+ * keeps people honest.
+ */
+
+ if (pasting && ! (options & (BTO_CONVERT|BTO_EXPAND)))
+ {
+ usage_error ("bt_postprocess_value(): "
+ "must convert numbers and expand macros "
+ "when pasting substrings");
+ }
+
+ /*
+ * Now the main loop to process each string, and possibly tack it onto
+ * new_string.
+ */
+
+ simple_value = value;
+ while (simple_value)
+ {
+ tmp_string = NULL;
+ free_tmp = FALSE;
+
+ /*
+ * If this simple value is a macro and we're supposed to expand
+ * macros, then do so. We also have to post-process the string
+ * returned from the macro table, because they're stored there
+ * without whitespace collapsed; if we're supposed to be doing that
+ * to the current value (and we're not pasting), this is where it
+ * will get done.
+ */
+ if (simple_value->nodetype == BTAST_MACRO && (options & BTO_EXPAND))
+ {
+ tmp_string = bt_macro_text (simple_value->text,
+ simple_value->filename,
+ simple_value->line);
+ if (tmp_string != NULL)
+ {
+ tmp_string = strdup (tmp_string);
+ free_tmp = TRUE;
+ bt_postprocess_string (tmp_string, string_opts);
+ }
+
+ if (replace)
+ {
+ simple_value->nodetype = BTAST_STRING;
+ if (simple_value->text)
+ free (simple_value->text);
+ simple_value->text = tmp_string;
+ free_tmp = FALSE; /* mustn't free, it's now in the AST */
+ }
+ }
+
+ /*
+ * If the current simple value is a literal string, then just
+ * post-process it. This will be done in-place if 'replace' is
+ * true, otherwise a copy of the string will be post-processed.
+ */
+ else if (simple_value->nodetype == BTAST_STRING && simple_value->text)
+ {
+ if (replace)
+ {
+ tmp_string = simple_value->text;
+ }
+ else
+ {
+ tmp_string = strdup (simple_value->text);
+ free_tmp = TRUE;
+ }
+
+ bt_postprocess_string (tmp_string, string_opts);
+ }
+
+ /*
+ * Finally, if the current simple value is a number, change it to a
+ * string (depending on options) and get its value. We generally
+ * treat strings as numbers as equivalent, except of course numbers
+ * aren't post-processed -- there can't be any whitespace in them!
+ * The BTO_CONVERT option is mainly a sop to my strong-typing
+ * tendencies.
+ */
+ if (simple_value->nodetype == BTAST_NUMBER)
+ {
+ if (replace && (options & BTO_CONVERT))
+ simple_value->nodetype = BTAST_STRING;
+
+ if (simple_value->text)
+ {
+ if (replace)
+ tmp_string = simple_value->text;
+ else
+ {
+ tmp_string = strdup (simple_value->text);
+ free_tmp = TRUE;
+ }
+ }
+ }
+
+ if (pasting)
+ {
+ if (tmp_string)
+ strcat (new_string, tmp_string);
+ if (free_tmp)
+ free (tmp_string);
+ }
+ else
+ {
+ /*
+ * N.B. if tmp_string is NULL (eg. from a single undefined macro)
+ * we make a strdup() of the empty string -- this is so we can
+ * safely free() the string returned from this function
+ * at some future point.
+ *
+ * This strdup() seems to cause a 1-byte memory leak in some
+ * circumstances. I s'pose I should look into that some rainy
+ * afternoon...
+ */
+
+ new_string = (tmp_string != NULL) ? tmp_string : strdup ("");
+ }
+
+ simple_value = simple_value->right;
+ }
+
+ if (pasting)
+ {
+ int len;
+
+ len = strlen (new_string);
+ assert (len <= tot_len); /* hope we alloc'd enough! */
+
+ bt_postprocess_string (new_string, options);
+
+ /*
+ * If replacing data in the AST, delete all but first child of
+ * `field', and replace text for first child with new_string.
+ */
+
+ if (replace)
+ {
+ assert (value->right != NULL); /* there has to be > 1 simple value! */
+ zzfree_ast (value->right); /* free from second simple value on */
+ value->right = NULL; /* remind ourselves they're gone */
+ if (value->text) /* free text of first simple value */
+ free (value->text);
+ value->text = new_string; /* and replace it with concatenation */
+ }
+ }
+
+ return new_string;
+
+} /* bt_postprocess_value() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_postprocess_field()
+@INPUT :
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Postprocesses all the strings in a single "field = value"
+ assignment subtree. Just checks that 'field' does indeed
+ point to an BTAST_FIELD node (presumably the parent of a list
+ of simple values), downcases the field name, and calls
+ bt_postprocess_value() on the value.
+@GLOBALS :
+@CALLS :
+@CALLERS :
+@CREATED : 1997/08/25, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+char *
+bt_postprocess_field (AST * field, ushort options, boolean replace)
+{
+ if (field == NULL) return NULL;
+ if (field->nodetype != BTAST_FIELD)
+ usage_error ("bt_postprocess_field: invalid AST node (not a field)");
+
+ strlwr (field->text); /* downcase field name */
+ return bt_postprocess_value (field->down, options, replace);
+
+} /* bt_postprocess_field() */
+
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_postprocess_entry()
+@INPUT :
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Postprocesses all the strings in an entry: collapse whitespace,
+ concatenate substrings, expands macros, and whatnot.
+@GLOBALS :
+@CALLS :
+@CREATED : 1997/01/10, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void
+bt_postprocess_entry (AST * top, ushort options)
+{
+ AST *cur;
+
+ if (top == NULL) return; /* not even an entry at all! */
+ if (top->nodetype != BTAST_ENTRY)
+ usage_error ("bt_postprocess_entry: "
+ "invalid node type (not entry root)");
+ strlwr (top->text); /* downcase entry type */
+
+ if (top->down == NULL) return; /* no children at all */
+
+ cur = top->down;
+ if (cur->nodetype == BTAST_KEY)
+ cur = cur->right;
+
+ switch (top->metatype)
+ {
+ case BTE_REGULAR:
+ case BTE_MACRODEF:
+ {
+ while (cur)
+ {
+ bt_postprocess_field (cur, options, TRUE);
+ if (top->metatype == BTE_MACRODEF && ! (options & BTO_NOSTORE))
+ bt_add_macro_value (cur, options);
+
+ cur = cur->right;
+ }
+ break;
+ }
+
+ case BTE_COMMENT:
+ case BTE_PREAMBLE:
+ bt_postprocess_value (cur, options, TRUE);
+ break;
+ default:
+ internal_error ("bt_postprocess_entry: unknown entry metatype (%d)",
+ (int) top->metatype);
+ }
+
+} /* bt_postprocess_entry() */
diff --git a/src/translators/btparse/prototypes.h b/src/translators/btparse/prototypes.h
new file mode 100644
index 0000000..88beada
--- /dev/null
+++ b/src/translators/btparse/prototypes.h
@@ -0,0 +1,47 @@
+/* ------------------------------------------------------------------------
+@NAME : prototypes.h
+@INPUT :
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Prototype declarations for functions from various places.
+ Only functions that are private to the library (but shared
+ between files within the library) are declared here.
+ Functions that are "exported from" the library (ie. usable
+ by and expected to be used by library user) are declared in
+ btparse.h.
+@GLOBALS :
+@CALLS :
+@CREATED : 1997/01/12, Greg Ward
+@MODIFIED :
+@VERSION : $Id: prototypes.h,v 1.14 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+
+#ifndef PROTOTYPES_H
+#define PROTOTYPES_H
+
+#include <stdio.h>
+#include "btparse.h" /* for types */
+
+/* util.c */
+#if !HAVE_STRLWR
+char *strlwr (char *s);
+#endif
+#if !HAVE_STRUPR
+char *strupr (char *s);
+#endif
+
+/* macros.c */
+void init_macros (void);
+void done_macros (void);
+
+/* bibtex_ast.c */
+void dump_ast (char *msg, AST *root);
+
+#endif /* PROTOTYPES_H */
diff --git a/src/translators/btparse/scan.c b/src/translators/btparse/scan.c
new file mode 100644
index 0000000..b9899e4
--- /dev/null
+++ b/src/translators/btparse/scan.c
@@ -0,0 +1,615 @@
+
+/* parser.dlg -- DLG Description of scanner
+ *
+ * Generated from: bibtex.g
+ *
+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994
+ * Purdue University Electrical Engineering
+ * With AHPCRC, University of Minnesota
+ * ANTLR Version 1.33
+ */
+
+#include <stdio.h>
+#define ANTLR_VERSION 133
+
+#define ZZCOL
+#define USER_ZZSYN
+
+#include "btconfig.h"
+#include "btparse.h"
+#include "attrib.h"
+#include "lex_auxiliary.h"
+#include "error.h"
+/*#include "my_dmalloc.h"*/
+
+extern char * InputFilename; /* for zzcr_ast call in pccts/ast.c */
+#include "antlr.h"
+#include "ast.h"
+#include "tokens.h"
+#include "dlgdef.h"
+LOOKAHEAD
+void zzerraction()
+{
+ (*zzerr)("invalid token");
+ zzadvance();
+ zzskip();
+}
+/*
+ * D L G tables
+ *
+ * Generated from: parser.dlg
+ *
+ * 1989-1994 by Will Cohen, Terence Parr, and Hank Dietz
+ * Purdue University Electrical Engineering
+ * DLG Version 1.33
+ */
+
+#include "mode.h"
+
+
+
+static void act1()
+{
+ NLA = 1;
+ }
+
+
+static void act2()
+{
+ NLA = AT;
+ at_sign ();
+ }
+
+
+static void act3()
+{
+ NLA = 3;
+ newline ();
+ }
+
+
+static void act4()
+{
+ NLA = COMMENT;
+ comment ();
+ }
+
+
+static void act5()
+{
+ NLA = 5;
+ zzskip ();
+ }
+
+
+static void act6()
+{
+ NLA = 6;
+ toplevel_junk ();
+ }
+
+static unsigned char shift0[257] = {
+ 0, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 4, 2, 5, 5, 4, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 4, 5, 5, 5, 5, 3, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 1, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5
+};
+
+
+static void act7()
+{
+ NLA = 1;
+ }
+
+
+static void act8()
+{
+ NLA = 7;
+ newline ();
+ }
+
+
+static void act9()
+{
+ NLA = COMMENT;
+ comment ();
+ }
+
+
+static void act10()
+{
+ NLA = 8;
+ zzskip ();
+ }
+
+
+static void act11()
+{
+ NLA = NUMBER;
+ }
+
+
+static void act12()
+{
+ NLA = NAME;
+ name ();
+ }
+
+
+static void act13()
+{
+ NLA = LBRACE;
+ lbrace ();
+ }
+
+
+static void act14()
+{
+ NLA = RBRACE;
+ rbrace ();
+ }
+
+
+static void act15()
+{
+ NLA = ENTRY_OPEN;
+ lparen ();
+ }
+
+
+static void act16()
+{
+ NLA = ENTRY_CLOSE;
+ rparen ();
+ }
+
+
+static void act17()
+{
+ NLA = EQUALS;
+ }
+
+
+static void act18()
+{
+ NLA = HASH;
+ }
+
+
+static void act19()
+{
+ NLA = COMMA;
+ }
+
+
+static void act20()
+{
+ NLA = 18;
+ start_string ('"');
+ }
+
+static unsigned char shift1[257] = {
+ 0, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 3, 1, 14, 14, 3, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 3, 5, 13, 11, 5, 2, 5,
+ 14, 8, 9, 5, 5, 12, 5, 5, 5, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
+ 5, 5, 10, 5, 5, 14, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 14, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 6, 5, 7, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14
+};
+
+
+static void act21()
+{
+ NLA = 1;
+ }
+
+
+static void act22()
+{
+ NLA = 19;
+ check_runaway_string ();
+ }
+
+
+static void act23()
+{
+ NLA = 20;
+ zzreplchar (' '); zzmore ();
+ }
+
+
+static void act24()
+{
+ NLA = 21;
+ open_brace ();
+ }
+
+
+static void act25()
+{
+ NLA = 22;
+ close_brace ();
+ }
+
+
+static void act26()
+{
+ NLA = 23;
+ lparen_in_string ();
+ }
+
+
+static void act27()
+{
+ NLA = 24;
+ rparen_in_string ();
+ }
+
+
+static void act28()
+{
+ NLA = STRING;
+ quote_in_string ();
+ }
+
+
+static void act29()
+{
+ NLA = 26;
+ zzmore ();
+ }
+
+static unsigned char shift2[257] = {
+ 0, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 2, 1, 3, 3, 2, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 8, 3, 3, 3, 3,
+ 3, 6, 7, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 9, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 4, 3, 5, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3
+};
+
+#define DfaStates 38
+typedef unsigned char DfaState;
+
+static DfaState st0[7] = {
+ 1, 2, 3, 4, 5, 6, 38
+};
+
+static DfaState st1[7] = {
+ 38, 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st2[7] = {
+ 38, 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st3[7] = {
+ 38, 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st4[7] = {
+ 38, 7, 8, 9, 7, 9, 38
+};
+
+static DfaState st5[7] = {
+ 38, 38, 38, 38, 5, 38, 38
+};
+
+static DfaState st6[7] = {
+ 38, 38, 38, 6, 38, 6, 38
+};
+
+static DfaState st7[7] = {
+ 38, 7, 8, 7, 7, 7, 38
+};
+
+static DfaState st8[7] = {
+ 38, 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st9[7] = {
+ 38, 7, 8, 9, 7, 9, 38
+};
+
+static DfaState st10[16] = {
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 38, 38
+};
+
+static DfaState st11[16] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st12[16] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st13[16] = {
+ 38, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 38
+};
+
+static DfaState st14[16] = {
+ 38, 38, 38, 14, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st15[16] = {
+ 38, 38, 38, 38, 15, 16, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st16[16] = {
+ 38, 38, 38, 38, 16, 16, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st17[16] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st18[16] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st19[16] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st20[16] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st21[16] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st22[16] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st23[16] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st24[16] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st25[16] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38
+};
+
+static DfaState st26[16] = {
+ 38, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 38
+};
+
+static DfaState st27[11] = {
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 31,
+ 38
+};
+
+static DfaState st28[11] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38
+};
+
+static DfaState st29[11] = {
+ 38, 38, 37, 37, 38, 38, 38, 38, 38, 38,
+ 38
+};
+
+static DfaState st30[11] = {
+ 38, 38, 31, 31, 38, 38, 38, 38, 38, 31,
+ 38
+};
+
+static DfaState st31[11] = {
+ 38, 38, 31, 31, 38, 38, 38, 38, 38, 31,
+ 38
+};
+
+static DfaState st32[11] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38
+};
+
+static DfaState st33[11] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38
+};
+
+static DfaState st34[11] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38
+};
+
+static DfaState st35[11] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38
+};
+
+static DfaState st36[11] = {
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38
+};
+
+static DfaState st37[11] = {
+ 38, 38, 37, 37, 38, 38, 38, 38, 38, 38,
+ 38
+};
+
+
+DfaState *dfa[38] = {
+ st0,
+ st1,
+ st2,
+ st3,
+ st4,
+ st5,
+ st6,
+ st7,
+ st8,
+ st9,
+ st10,
+ st11,
+ st12,
+ st13,
+ st14,
+ st15,
+ st16,
+ st17,
+ st18,
+ st19,
+ st20,
+ st21,
+ st22,
+ st23,
+ st24,
+ st25,
+ st26,
+ st27,
+ st28,
+ st29,
+ st30,
+ st31,
+ st32,
+ st33,
+ st34,
+ st35,
+ st36,
+ st37
+};
+
+
+DfaState accepts[39] = {
+ 0, 1, 2, 3, 6, 5, 6, 0, 4, 6,
+ 0, 7, 8, 0, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 9, 0, 0, 21, 22,
+ 23, 29, 24, 25, 26, 27, 28, 22, 0
+};
+
+void (*actions[30])() = {
+ zzerraction,
+ act1,
+ act2,
+ act3,
+ act4,
+ act5,
+ act6,
+ act7,
+ act8,
+ act9,
+ act10,
+ act11,
+ act12,
+ act13,
+ act14,
+ act15,
+ act16,
+ act17,
+ act18,
+ act19,
+ act20,
+ act21,
+ act22,
+ act23,
+ act24,
+ act25,
+ act26,
+ act27,
+ act28,
+ act29
+};
+
+static DfaState dfa_base[] = {
+ 0,
+ 10,
+ 27
+};
+
+static unsigned char *b_class_no[] = {
+ shift0,
+ shift1,
+ shift2
+};
+
+
+
+#define ZZSHIFT(c) (b_class_no[zzauto][1+c])
+#define MAX_MODE 3
+#include "dlgauto.h"
diff --git a/src/translators/btparse/stdpccts.h b/src/translators/btparse/stdpccts.h
new file mode 100644
index 0000000..e232634
--- /dev/null
+++ b/src/translators/btparse/stdpccts.h
@@ -0,0 +1,31 @@
+#ifndef STDPCCTS_H
+#define STDPCCTS_H
+/*
+ * stdpccts.h -- P C C T S I n c l u d e
+ *
+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994
+ * Purdue University Electrical Engineering
+ * With AHPCRC, University of Minnesota
+ * ANTLR Version 1.33
+ */
+#include <stdio.h>
+#define ANTLR_VERSION 133
+
+#define ZZCOL
+#define USER_ZZSYN
+
+#include "btparse.h"
+#include "attrib.h"
+#include "lex_auxiliary.h"
+#include "error.h"
+/*#include "my_dmalloc.h"*/
+
+extern char * InputFilename; /* for zzcr_ast call in pccts/ast.c */
+#define GENAST
+#define zzSET_SIZE 4
+#include "antlr.h"
+#include "ast.h"
+#include "tokens.h"
+#include "dlgdef.h"
+#include "mode.h"
+#endif
diff --git a/src/translators/btparse/string_util.c b/src/translators/btparse/string_util.c
new file mode 100644
index 0000000..3713608
--- /dev/null
+++ b/src/translators/btparse/string_util.c
@@ -0,0 +1,695 @@
+/* ------------------------------------------------------------------------
+@NAME : string_util.c
+@DESCRIPTION: Various string-processing utility functions:
+ bt_purify_string()
+ bt_change_case()
+
+ and their helpers:
+ foreign_letter()
+ purify_special_char()
+@GLOBALS :
+@CALLS :
+@CALLERS :
+@CREATED : 1997/10/19, Greg Ward
+@MODIFIED : 1997/11/25, GPW: renamed to from purify.c to string_util.c
+ added bt_change_case() and friends
+@VERSION : $Id: string_util.c,v 1.10 1999/10/28 22:50:28 greg Rel $
+-------------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include "error.h"
+#include "btparse.h"
+#include "bt_debug.h"
+
+
+/*
+ * These definitions should be fixed to be consistent with HTML
+ * entities, just for fun. And perhaps I should add entries for
+ * accented letters (at least those supported by TeX and HTML).
+ */
+typedef enum
+{
+ L_OTHER, /* not a "foreign" letter */
+ L_OSLASH_L, /* Eastern European {\o} */
+ L_OSLASH_U,
+ L_LSLASH_L, /* {\l} */
+ L_LSLASH_U,
+ L_OELIG_L, /* Latin {\oe} ligature */
+ L_OELIG_U,
+ L_AELIG_L, /* {\ae} ligature */
+ L_AELIG_U,
+ L_SSHARP_L, /* German "sharp s" {\ss} */
+ L_SSHARP_U,
+ L_ACIRCLE_L, /* Nordic {\aa} */
+ L_ACIRCLE_U,
+ L_INODOT_L, /* undotted i: {\i} */
+ L_JNODOT_L /* {\j} */
+} bt_letter;
+
+
+static const char * uc_version[] =
+{
+ NULL, /* L_OTHER */
+ "\\O", /* L_OSLASH_L */
+ "\\O", /* L_OSLASH_U */
+ "\\L", /* L_LSLASH_L */
+ "\\L", /* L_LSLASH_U */
+ "\\OE", /* L_OELIG_L */
+ "\\OE", /* L_OELIG_U */
+ "\\AE", /* L_AELIG_L */
+ "\\AE", /* L_AELIG_U */
+ "SS", /* L_SSHARP_L -- for LaTeX 2.09 */
+ "\\SS", /* L_SSHARP_U */
+ "\\AA", /* L_ACIRCLE_L */
+ "\\AA", /* L_ACIRCLE_U */
+ "I", /* L_INODOT_L */
+ "J" /* L_JNODOT_L */
+};
+
+static const char * lc_version[] =
+{
+ NULL, /* L_OTHER */
+ "\\o", /* L_OSLASH_L */
+ "\\o", /* L_OSLASH_U */
+ "\\l", /* L_LSLASH_L */
+ "\\l", /* L_LSLASH_U */
+ "\\oe", /* L_OELIG_L */
+ "\\oe", /* L_OELIG_U */
+ "\\ae", /* L_AELIG_L */
+ "\\ae", /* L_AELIG_U */
+ "\\ss", /* L_SSHARP_L */
+ "\\ss", /* L_SSHARP_U */
+ "\\aa", /* L_ACIRCLE_L */
+ "\\aa", /* L_ACIRCLE_U */
+ "\\i", /* L_INODOT_L */
+ "\\j" /* L_JNODOT_L */
+};
+
+
+
+/* ------------------------------------------------------------------------
+@NAME : foreign_letter()
+@INPUT : str
+ start
+ stop
+@OUTPUT : letter
+@RETURNS : TRUE if the string delimited by start and stop is a foreign
+ letter control sequence
+@DESCRIPTION: Determines if a character sequence is one of (La)TeX's
+ "foreign letter" control sequences (l, o, ae, oe, aa, ss, plus
+ uppercase versions). If `letter' is non-NULL, returns which
+ letter was found in it (as a bt_letter value).
+@CALLS :
+@CALLERS : purify_special_char()
+@CREATED : 1997/10/19, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static boolean
+foreign_letter (char *str, int start, int stop, bt_letter * letter)
+{
+ char c1, c2;
+ bt_letter dummy;
+
+
+ /*
+ * This is written for speed, not flexibility -- adding new foreign
+ * letters would be trying and vexatious.
+ *
+ * N.B. my gold standard list of foreign letters is Kopka and Daly's
+ * *A Guide to LaTeX 2e*, section 2.5.6.
+ */
+
+ if (letter == NULL) /* so we can assign to *letter */
+ letter = &dummy; /* without compunctions */
+ *letter = L_OTHER; /* assume not a "foreign" letter */
+
+ c1 = str[start+0]; /* only two characters that we're */
+ c2 = str[start+1]; /* interested in */
+
+ switch (stop - start)
+ {
+ case 1: /* one-character control sequences */
+ switch (c1) /* (\o and \l) */
+ {
+ case 'o':
+ *letter = L_OSLASH_L; return TRUE;
+ case 'O':
+ *letter = L_OSLASH_U; return TRUE;
+ case 'l':
+ *letter = L_LSLASH_L; return TRUE;
+ case 'L':
+ *letter = L_LSLASH_L; return TRUE;
+ case 'i':
+ *letter = L_INODOT_L; return TRUE;
+ case 'j':
+ *letter = L_JNODOT_L; return TRUE;
+ default:
+ return FALSE;
+ }
+ break;
+ case 2: /* two character control sequences */
+ switch (c1) /* (\oe, \ae, \aa, and \ss) */
+ {
+ case 'o':
+ if (c2 == 'e') { *letter = L_OELIG_L; return TRUE; }
+ case 'O':
+ if (c2 == 'E') { *letter = L_OELIG_U; return TRUE; }
+
+ /* BibTeX 0.99 does not handle \aa and \AA -- but I do!*/
+ case 'a':
+ if (c2 == 'e')
+ { *letter = L_AELIG_L; return TRUE; }
+ else if (c2 == 'a')
+ { *letter = L_ACIRCLE_L; return TRUE; }
+ else
+ return FALSE;
+ case 'A':
+ if (c2 == 'E')
+ { *letter = L_AELIG_U; return TRUE; }
+ else if (c2 == 'A')
+ { *letter = L_ACIRCLE_U; return TRUE; }
+ else
+ return FALSE;
+
+ /* uppercase sharp-s -- new with LaTeX 2e (so far all I do
+ * is recognize it as a "foreign" letter)
+ */
+ case 's':
+ if (c2 == 's')
+ { *letter = L_SSHARP_L; return TRUE; }
+ else
+ return FALSE;
+ case 'S':
+ if (c2 == 'S')
+ { *letter = L_SSHARP_U; return TRUE; }
+ else
+ return FALSE;
+ }
+ break;
+ default:
+ return FALSE;
+ } /* switch on length of control sequence */
+
+ internal_error ("foreign_letter(): should never reach end of function");
+ return FALSE; /* to keep gcc -Wall happy */
+
+} /* foreign_letter */
+
+
+/* ------------------------------------------------------------------------
+@NAME : purify_special_char()
+@INPUT : *src, *dst - pointers into the input and output strings
+@OUTPUT : *src - updated to point to the closing brace of the
+ special char
+ *dst - updated to point to the next available spot
+ for copying text to
+@RETURNS :
+@DESCRIPTION: "Purifies" a BibTeX special character. On input, *src should
+ point to the opening brace of a special character (ie. the
+ brace must be at depth 0 of the whole string, and the
+ character immediately following it must be a backslash).
+ *dst should point to the next spot to copy into the output
+ (purified) string. purify_special_char() will skip over the
+ opening brace and backslash; if the control sequence is one
+ of LaTeX's foreign letter sequences (as determined by
+ foreign_letter()), then it is simply copied to *dst.
+ Otherwise the control sequence is skipped. In either case,
+ text after the control sequence is either copied (alphabetic
+ characters) or skipped (anything else, including hyphens,
+ ties, and digits).
+@CALLS : foreign_letter()
+@CALLERS : bt_purify_string()
+@CREATED : 1997/10/19, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static void
+purify_special_char (char *str, int * src, int * dst)
+{
+ int depth;
+ int peek;
+
+ assert (str[*src] == '{' && str[*src + 1] == '\\');
+ depth = 1;
+
+ *src += 2; /* jump to start of control sequence */
+ peek = *src; /* scan to end of control sequence */
+ while (isalpha (str[peek]))
+ peek++;
+ if (peek == *src) /* in case of single-char, non-alpha */
+ peek++; /* control sequence (eg. {\'e}) */
+
+ if (foreign_letter (str, *src, peek, NULL))
+ {
+ assert (peek - *src == 1 || peek - *src == 2);
+ str[(*dst)++] = str[(*src)++]; /* copy first char */
+ if (*src < peek) /* copy second char, downcasing */
+ str[(*dst)++] = tolower (str[(*src)++]);
+ }
+ else /* not a foreign letter -- skip */
+ { /* the control sequence entirely */
+ *src = peek;
+ }
+
+ while (str[*src])
+ {
+ switch (str[*src])
+ {
+ case '{':
+ depth++;
+ (*src)++;
+ break;
+ case '}':
+ depth--;
+ if (depth == 0) return; /* done with special char */
+ (*src)++;
+ break;
+ default:
+ if (isalpha (str[*src])) /* copy alphabetic chars */
+ str[(*dst)++] = str[(*src)++];
+ else /* skip everything else */
+ (*src)++;
+ }
+ }
+
+ /*
+ * If we get here, we have unbalanced braces -- the '}' case should
+ * always hit a depth == 0 point if braces are balanced. No warning,
+ * though, because a) BibTeX doesn't warn about purifying unbalanced
+ * strings, and b) we (should have) already warned about it in the
+ * lexer.
+ */
+
+} /* purify_special_char() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_purify_string()
+@INOUT : instr
+@INPUT : options
+@OUTPUT :
+@RETURNS : instr - same as input string, but modified in place
+@DESCRIPTION: "Purifies" a BibTeX string. This consists of copying
+ alphanumeric characters, converting hyphens and ties to
+ space, copying spaces, and skipping everything else. (Well,
+ almost -- special characters are handled specially, of
+ course. Basically, accented letters have the control
+ sequence skipped, while foreign letters have the control
+ sequence preserved in a reasonable manner. See
+ purify_special_char() for details.)
+@CALLS : purify_special_char()
+@CALLERS :
+@CREATED : 1997/10/19, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void
+bt_purify_string (char * string, ushort options)
+{
+ int src, /* both indeces into string */
+ dst;
+ int depth; /* brace depth in string */
+ unsigned orig_len;
+
+ /*
+ * Since purification always copies or deletes chars, outstr will
+ * be no longer than string -- so nothing fancy is required to put
+ * an upper bound on its eventual size.
+ */
+
+ depth = 0;
+ src = 0;
+ dst = 0;
+ orig_len = strlen (string);
+
+ DBG_ACTION (1, printf ("bt_purify_string(): input = %p (%s)\n",
+ string, string));
+
+ while (string[src] != (char) 0)
+ {
+ DBG_ACTION (2, printf (" next: >%c<: ", string[src]));
+ switch (string[src])
+ {
+ case '~': /* "separator" characters -- */
+ case '-': /* replaced with space */
+ case ' ': /* and copy an actual space */
+ string[dst++] = ' ';
+ src++;
+ DBG_ACTION (2, printf ("replacing with space"));
+ break;
+ case '{':
+ if (depth == 0 && string[src+1] == '\\')
+ {
+ DBG_ACTION (2, printf ("special char found"));
+ purify_special_char (string, &src, &dst);
+ }
+ else
+ {
+ DBG_ACTION (2, printf ("ordinary open brace"));
+ src++;
+ }
+ depth++;
+ break;
+ case '}':
+ DBG_ACTION (2, printf ("close brace"));
+ depth--;
+ src++;
+ break;
+ default:
+ if (isalnum (string[src])) /* any alphanumeric char -- */
+ {
+ DBG_ACTION (2, printf ("alphanumeric -- copying"));
+ string[dst++] = string[src++]; /* copy it */
+ }
+ else /* anything else -- skip it */
+ {
+ DBG_ACTION (2, printf ("non-separator, non-brace, non-alpha"));
+ src++;
+ }
+ } /* switch string[src] */
+
+ DBG_ACTION (2, printf ("\n"));
+
+ } /* while string[src] */
+
+ DBG_ACTION (1, printf ("bt_purify_string(): depth on exit: %d\n", depth));
+
+ string[dst] = (char) 0;
+ assert (strlen (string) <= orig_len);
+} /* bt_purify_string() */
+
+
+/* ======================================================================
+ * Case-transformation stuff
+ */
+
+
+/* ------------------------------------------------------------------------
+@NAME : convert_special_char()
+@INPUT : transform
+@INOUT : string
+ src
+ dst
+ start_sentence
+ after_colon
+@RETURNS :
+@DESCRIPTION: Does case conversion on a special character.
+@GLOBALS :
+@CALLS :
+@CALLERS :
+@CREATED : 1997/11/25, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static void
+convert_special_char (char transform,
+ char * string,
+ int * src,
+ int * dst,
+ boolean * start_sentence,
+ boolean * after_colon)
+{
+ int depth;
+ boolean done_special;
+ int cs_end;
+ int cs_len; /* counting the backslash */
+ bt_letter letter;
+ const char * repl;
+ int repl_len;
+
+#ifndef ALLOW_WARNINGS
+ repl = NULL; /* silence "might be used" */
+ /* uninitialized" warning */
+#endif
+
+ /* First, copy just the opening brace */
+ string[(*dst)++] = string[(*src)++];
+
+ /*
+ * Now loop over characters inside the braces -- stop when we reach
+ * the matching close brace, or when the string ends.
+ */
+ depth = 1; /* because we're in a special char */
+ done_special = FALSE;
+
+ while (string[*src] != 0 && !done_special)
+ {
+ switch (string[*src])
+ {
+ case '\\': /* a control sequence */
+ {
+ cs_end = *src+1; /* scan over chars of c.s. */
+ while (isalpha (string[cs_end]))
+ cs_end++;
+
+ /*
+ * OK, now *src points to the backslash (so src+*1 points to
+ * first char. of control sequence), and cs_end points to
+ * character immediately following end of control sequence.
+ * Thus we analyze [*src+1..cs_end] to determine if the control
+ * sequence is a foreign letter, and use (cs_end - (*src+1) + 1)
+ * = (cs_end - *src) as the length of the control sequence.
+ */
+
+ cs_len = cs_end - *src; /* length of cs, counting backslash */
+
+ if (foreign_letter (string, *src+1, cs_end, &letter))
+ {
+ if (letter == L_OTHER)
+ internal_error ("impossible foreign letter");
+
+ switch (transform)
+ {
+ case 'u':
+ repl = uc_version[(int) letter];
+ break;
+ case 'l':
+ repl = lc_version[(int) letter];
+ break;
+ case 't':
+ if (*start_sentence || *after_colon)
+ {
+ repl = uc_version[(int) letter];
+ *start_sentence = *after_colon = FALSE;
+ }
+ else
+ {
+ repl = lc_version[(int) letter];
+ }
+ break;
+ default:
+ internal_error ("impossible case transform \"%c\"",
+ transform);
+ }
+
+ repl_len = strlen (repl);
+ if (repl_len > cs_len)
+ internal_error
+ ("replacement text longer than original cs");
+
+ strncpy (string + *dst, repl, repl_len);
+ *src = cs_end;
+ *dst += repl_len;
+ } /* control sequence is a foreign letter */
+ else
+ {
+ /* not a foreign letter -- just copy the control seq. as is */
+
+
+ strncpy (string + *dst, string + *src, cs_end - *src);
+ *src += cs_len;
+ assert (*src == cs_end);
+ *dst += cs_len;
+ } /* control sequence not a foreign letter */
+
+ break;
+ } /* case: '\\' */
+
+ case '{':
+ {
+ string[(*dst)++] = string[(*src)++];
+ depth++;
+ break;
+ }
+
+ case '}':
+ {
+ string[(*dst)++] = string[(*src)++];
+ depth--;
+ if (depth == 0)
+ done_special = TRUE;
+ break;
+ }
+
+ default: /* any other character */
+ {
+ switch (transform)
+ {
+ /*
+ * Inside special chars, lowercase and title caps are same.
+ * (At least, that's bibtex's convention. I might change this
+ * at some point to be a bit smarter.)
+ */
+ case 'l':
+ case 't':
+ string[(*dst)++] = tolower (string[(*src)++]);
+ break;
+ case 'u':
+ string[(*dst)++] = toupper (string[(*src)++]);
+ break;
+ default:
+ internal_error ("impossible case transform \"%c\"",
+ transform);
+ }
+ } /* default char */
+
+ } /* switch: current char */
+
+ } /* while: string or special char not done */
+
+} /* convert_special_char() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_change_case()
+@INPUT :
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Converts a string (in-place) to either uppercase, lowercase,
+ or "title capitalization">
+@GLOBALS :
+@CALLS :
+@CALLERS :
+@CREATED : 1997/11/25, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void
+bt_change_case (char transform,
+ char * string,
+ ushort options)
+{
+ int len;
+ int depth;
+ int src, dst; /* indeces into string */
+ boolean start_sentence;
+ boolean after_colon;
+
+ src = dst = 0;
+ len = strlen (string);
+ depth = 0;
+
+ start_sentence = TRUE;
+ after_colon = FALSE;
+
+ while (string[src] != 0)
+ {
+ switch (string[src])
+ {
+ case '{':
+
+ /*
+ * At start of special character? The entire special char.
+ * will be handled here, as follows:
+ * - text at any brace-depth within the s.c. is case-mangled;
+ * punctuation (sentence endings, colons) are ignored
+ * - control sequences are left alone, unless they are
+ * one of the "foreign letter" control sequences, in
+ * which case they're converted to the appropriate string
+ * according to the uc_version or lc_version tables.
+ */
+ if (depth == 0 && string[src+1] == '\\')
+ {
+ convert_special_char (transform, string, &src, &dst,
+ &start_sentence, &after_colon);
+ }
+
+ /*
+ * Otherwise, it's just something in braces. This is probably
+ * a proper noun or something encased in braces to protect it
+ * from case-mangling, so we do not case-mangle it. However,
+ * we *do* switch out of start_sentence or after_colon mode if
+ * we happen to be there (otherwise we'll do the wrong thing
+ * once we're out of the braces).
+ */
+ else
+ {
+ string[dst++] = string[src++];
+ start_sentence = after_colon = FALSE;
+ depth++;
+ }
+ break;
+
+ case '}':
+ string[dst++] = string[src++];
+ depth--;
+ break;
+
+ /*
+ * Sentence-ending punctuation and colons are handled separately
+ * to allow for exact mimicing of BibTeX's behaviour. I happen
+ * to think that this behaviour (capitalize first word of sentences
+ * in a title) is better than BibTeX's, but I want to keep my
+ * options open for a future goal of perfect compatability.
+ */
+ case '.':
+ case '?':
+ case '!':
+ start_sentence = TRUE;
+ string[dst++] = string[src++];
+ break;
+
+ case ':':
+ after_colon = TRUE;
+ string[dst++] = string[src++];
+ break;
+
+ default:
+ if (isspace (string[src]))
+ {
+ string[dst++] = string[src++];
+ }
+ else
+ {
+ if (depth == 0)
+ {
+ switch (transform)
+ {
+ case 'u':
+ string[dst++] = toupper (string[src++]);
+ break;
+ case 'l':
+ string[dst++] = tolower (string[src++]);
+ break;
+ case 't':
+ if (start_sentence || after_colon)
+ {
+ /*
+ * XXX BibTeX only preserves case of character
+ * immediately after a colon; I do two things
+ * differently: first, I pay attention to sentence
+ * punctuation, and second I force uppercase
+ * at start of sentence or after a colon.
+ */
+ string[dst++] = toupper (string[src++]);
+ start_sentence = after_colon = FALSE;
+ }
+ else
+ {
+ string[dst++] = tolower (string[src++]);
+ }
+ break;
+ default:
+ internal_error ("impossible case transform \"%c\"",
+ transform);
+ }
+ } /* depth == 0 */
+ else
+ {
+ string[dst++] = string[src++];
+ }
+ } /* not blank */
+ } /* switch on current character */
+
+ } /* while not at end of string */
+
+} /* bt_change_case */
diff --git a/src/translators/btparse/sym.c b/src/translators/btparse/sym.c
new file mode 100644
index 0000000..2426dea
--- /dev/null
+++ b/src/translators/btparse/sym.c
@@ -0,0 +1,372 @@
+/*
+ * Simple symbol table manager using coalesced chaining to resolve collisions
+ *
+ * Doubly-linked lists are used for fast removal of entries.
+ *
+ * 'sym.h' must have a definition for typedef "Sym". Sym must include at
+ * minimum the following fields:
+ *
+ * ...
+ * char *symbol;
+ * struct ... *next, *prev, **head, *scope;
+ * unsigned int hash;
+ * ...
+ *
+ * 'template.h' can be used as a template to create a 'sym.h'.
+ *
+ * 'head' is &(table[hash(itself)]).
+ * The hash table is not resizable at run-time.
+ * The scope field is used to link all symbols of a current scope together.
+ * Scope() sets the current scope (linked list) to add symbols to.
+ * Any number of scopes can be handled. The user passes the address of
+ * a pointer to a symbol table
+ * entry (INITIALIZED TO NULL first time).
+ *
+ * Available Functions:
+ *
+ * zzs_init(s1,s2) -- Create hash table with size s1, string table size s2.
+ * zzs_done() -- Free hash and string table created with zzs_init().
+ * zzs_add(key,rec)-- Add 'rec' with key 'key' to the symbol table.
+ * zzs_newadd(key) -- create entry; add using 'key' to the symbol table.
+ * zzs_get(key) -- Return pointer to last record entered under 'key'
+ * Else return NULL
+ * zzs_del(p) -- Unlink the entry associated with p. This does
+ * NOT free 'p' and DOES NOT remove it from a scope
+ * list. If it was a part of your intermediate code
+ * tree or another structure. It will still be there.
+ * It is only removed from further consideration
+ * by the symbol table.
+ * zzs_keydel(s) -- Unlink the entry associated with key s.
+ * Calls zzs_del(p) to unlink.
+ * zzs_scope(sc) -- Specifies that everything added to the symbol
+ * table with zzs_add() is added to the list (scope)
+ * 'sc'. 'sc' is of 'Sym **sc' type and must be
+ * initialized to NULL before trying to add anything
+ * to it (passing it to zzs_scope()). Scopes can be
+ * switched at any time and merely links a set of
+ * symbol table entries. If a NULL pointer is
+ * passed, the current scope is returned.
+ * zzs_rmscope(sc) -- Remove (zzs_del()) all elements of scope 'sc'
+ * from the symbol table. The entries are NOT
+ * free()'d. A pointer to the first
+ * element in the "scope" is returned. The user
+ * can then manipulate the list as he/she chooses
+ * (such as freeing them all). NOTE that this
+ * function sets your scope pointer to NULL,
+ * but returns a pointer to the list for you to use.
+ * zzs_stat() -- Print out the symbol table and some relevant stats.
+ * zzs_new(key) -- Create a new record with calloc() of type Sym.
+ * Add 'key' to the string table and make the new
+ * records 'symbol' pointer point to it.
+ * zzs_strdup(s) -- Add s to the string table and return a pointer
+ * to it. Very fast allocation routine
+ * and does not require strlen() nor calloc().
+ *
+ * Example:
+ *
+ * #include <stdio.h>
+ * #include "sym.h"
+ *
+ * main()
+ * {
+ * Sym *scope1=NULL, *scope2=NULL, *a, *p;
+ *
+ * zzs_init(101, 100);
+ *
+ * a = zzs_new("Apple"); zzs_add(a->symbol, a); -- No scope
+ * zzs_scope( &scope1 ); -- enter scope 1
+ * a = zzs_new("Plum"); zzs_add(a->symbol, a);
+ * zzs_scope( &scope2 ); -- enter scope 2
+ * a = zzs_new("Truck"); zzs_add(a->symbol, a);
+ *
+ * p = zzs_get("Plum");
+ * if ( p == NULL ) fprintf(stderr, "Hmmm...Can't find 'Plum'\n");
+ *
+ * p = zzs_rmscope(&scope1)
+ * for (; p!=NULL; p=p->scope) {printf("Scope1: %s\n", p->symbol);}
+ * p = zzs_rmscope(&scope2)
+ * for (; p!=NULL; p=p->scope) {printf("Scope2: %s\n", p->symbol);}
+ * }
+ *
+ * Terence Parr
+ * Purdue University
+ * February 1990
+ *
+ * CHANGES
+ *
+ * Terence Parr
+ * May 1991
+ * Renamed functions to be consistent with ANTLR
+ * Made HASH macro
+ * Added zzs_keydel()
+ * Added zzs_newadd()
+ * Fixed up zzs_stat()
+ *
+ * July 1991
+ * Made symbol table entry save its hash code for fast comparison
+ * during searching etc...
+ */
+
+/*#include "bt_config.h"*/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef MEMCHK
+#include "trax.h"
+#endif
+#include "sym.h"
+/*#include "my_dmalloc.h"*/
+
+#define StrSame 0
+
+static Sym **CurScope = NULL;
+static unsigned size = 0;
+static Sym **table=NULL;
+static char *strings;
+static char *strp;
+static int strsize = 0;
+
+void
+zzs_init(int sz, int strs)
+{
+ if ( sz <= 0 || strs <= 0 ) return;
+ table = (Sym **) calloc(sz, sizeof(Sym *));
+ if ( table == NULL )
+ {
+ fprintf(stderr, "Cannot allocate table of size %d\n", sz);
+ exit(1);
+ }
+ strings = (char *) calloc(strs, sizeof(char));
+ if ( strings == NULL )
+ {
+ fprintf(stderr, "Cannot allocate string table of size %d\n", strs);
+ exit(1);
+ }
+ size = sz;
+ strsize = strs;
+ strp = strings;
+}
+
+
+void
+zzs_free(void)
+{
+ unsigned i;
+ Sym *cur, *next;
+
+ for (i = 0; i < size; i++)
+ {
+ cur = table[i];
+ while (cur != NULL)
+ {
+ next = cur->next;
+ free (cur);
+ cur = next;
+ }
+ }
+}
+
+
+void
+zzs_done(void)
+{
+ if ( table != NULL ) free( table );
+ if ( strings != NULL ) free( strings );
+}
+
+void
+zzs_add(char *key, register Sym *rec)
+{
+ register unsigned int h=0;
+ register char *p=key;
+
+ HASH_FUN(p, h);
+ rec->hash = h; /* save hash code for fast comp later */
+ h %= size;
+
+ if ( CurScope != NULL ) {rec->scope = *CurScope; *CurScope = rec;}
+ rec->next = table[h]; /* Add to doubly-linked list */
+ rec->prev = NULL;
+ if ( rec->next != NULL ) (rec->next)->prev = rec;
+ table[h] = rec;
+ rec->head = &(table[h]);
+}
+
+Sym *
+zzs_get(char *key)
+{
+ register unsigned int h=0;
+ register char *p=key;
+ register Sym *q;
+
+ HASH_FUN(p, h);
+
+ for (q = table[h%size]; q != NULL; q = q->next)
+ {
+ if ( q->hash == h ) /* do we even have a chance of matching? */
+ if ( strcasecmp(key, q->symbol) == StrSame ) return( q );
+ }
+ return( NULL );
+}
+
+/*
+ * Unlink p from the symbol table. Hopefully, it's actually in the
+ * symbol table.
+ *
+ * If p is not part of a bucket chain of the symbol table, bad things
+ * will happen.
+ *
+ * Will do nothing if all list pointers are NULL
+ */
+void
+zzs_del(register Sym *p)
+{
+ if ( p == NULL ) {fprintf(stderr, "zzs_del(NULL)\n"); exit(1);}
+ if ( p->prev == NULL ) /* Head of list */
+ {
+ register Sym **t = p->head;
+
+ if ( t == NULL ) return; /* not part of symbol table */
+ (*t) = p->next;
+ if ( (*t) != NULL ) (*t)->prev = NULL;
+ }
+ else
+ {
+ (p->prev)->next = p->next;
+ if ( p->next != NULL ) (p->next)->prev = p->prev;
+ }
+ p->next = p->prev = NULL; /* not part of symbol table anymore */
+ p->head = NULL;
+}
+
+void
+zzs_keydel(char *key)
+{
+ Sym *p = zzs_get(key);
+
+ if ( p != NULL ) zzs_del( p );
+}
+
+/* S c o p e S t u f f */
+
+/* Set current scope to 'scope'; return current scope if 'scope' == NULL */
+Sym **
+zzs_scope(Sym **scope)
+{
+ if ( scope == NULL ) return( CurScope );
+ CurScope = scope;
+ return( scope );
+}
+
+/* Remove a scope described by 'scope'. Return pointer to 1st element in scope */
+Sym *
+zzs_rmscope(register Sym **scope)
+{
+ register Sym *p;
+ Sym *start;
+
+ if ( scope == NULL ) return(NULL);
+ start = p = *scope;
+ for (; p != NULL; p=p->scope) { zzs_del( p ); }
+ *scope = NULL;
+ return( start );
+}
+
+void
+zzs_stat(void)
+{
+ static unsigned short count[20];
+ unsigned int i,n=0,low=0, hi=0;
+ register Sym **p;
+ float avg=0.0;
+
+ for (i=0; i<20; i++) count[i] = 0;
+ for (p=table; p<&(table[size]); p++)
+ {
+ register Sym *q = *p;
+ unsigned int len;
+
+ if ( q != NULL && low==0 ) low = p-table;
+ len = 0;
+ if ( q != NULL ) printf("[%d]", p-table);
+ while ( q != NULL )
+ {
+ len++;
+ n++;
+ printf(" %s", q->symbol);
+ q = q->next;
+ if ( q == NULL ) printf("\n");
+ }
+ if ( len>=20 ) printf("zzs_stat: count table too small\n");
+ else count[len]++;
+ if ( *p != NULL ) hi = p-table;
+ }
+
+ printf("Storing %d recs used %d hash positions out of %d\n",
+ n, size-count[0], size);
+ printf("%f %% utilization\n",
+ ((float)(size-count[0]))/((float)size));
+ for (i=0; i<20; i++)
+ {
+ if ( count[i] != 0 )
+ {
+ avg += (((float)(i*count[i]))/((float)n)) * i;
+ printf("Buckets of len %d == %d (%f %% of recs)\n",
+ i, count[i], 100.0*((float)(i*count[i]))/((float)n));
+ }
+ }
+ printf("Avg bucket length %f\n", avg);
+ printf("Range of hash function: %d..%d\n", low, hi);
+}
+
+/*
+ * Given a string, this function allocates and returns a pointer to a
+ * symbol table record whose "symbol" pointer is reset to a position
+ * in the string table.
+ */
+Sym *
+zzs_new(char *text)
+{
+ Sym *p;
+ char *zzs_strdup(register char *s);
+
+ if ( (p = (Sym *) calloc(1,sizeof(Sym))) == 0 )
+ {
+ fprintf(stderr,"Out of memory\n");
+ exit(1);
+ }
+ p->symbol = zzs_strdup(text);
+
+ return p;
+}
+
+/* create a new symbol table entry and add it to the symbol table */
+Sym *
+zzs_newadd(char *text)
+{
+ Sym *p = zzs_new(text);
+ if ( p != NULL ) zzs_add(text, p);
+ return p;
+}
+
+/* Add a string to the string table and return a pointer to it.
+ * Bump the pointer into the string table to next avail position.
+ */
+char *
+zzs_strdup(register char *s)
+{
+ register char *start=strp;
+
+ while ( *s != '\0' )
+ {
+ if ( strp >= &(strings[strsize-2]) )
+ {
+ fprintf(stderr, "sym: string table overflow (%d chars)\n", strsize);
+ exit(-1);
+ }
+ *strp++ = *s++;
+ }
+ *strp++ = '\0';
+
+ return( start );
+}
diff --git a/src/translators/btparse/sym.h b/src/translators/btparse/sym.h
new file mode 100644
index 0000000..78983d1
--- /dev/null
+++ b/src/translators/btparse/sym.h
@@ -0,0 +1,33 @@
+#include <ctype.h>
+
+/*
+ * Declarations for symbol table in sym.c
+ */
+
+/* define some hash function */
+#ifndef HASH_FUN
+#define HASH_FUN(p, h) while ( *p != '\0' ) h = (h<<1) + tolower (*p++);
+#endif
+
+/* minimum symbol table record */
+typedef struct _sym
+{
+ char *symbol; /* the macro name */
+ char *text; /* its expansion */
+ struct _sym *next, *prev, **head, *scope;
+ unsigned int hash;
+} Sym, *SymPtr;
+
+void zzs_init(int, int);
+void zzs_free(void);
+void zzs_done(void);
+void zzs_add(char *, Sym *);
+Sym *zzs_get(char *);
+void zzs_del(Sym *);
+void zzs_keydel(char *);
+Sym **zzs_scope(Sym **);
+Sym *zzs_rmscope(Sym **);
+void zzs_stat(void);
+Sym *zzs_new(char *);
+Sym *zzs_newadd(char *);
+char *zzs_strdup(char *);
diff --git a/src/translators/btparse/tex_tree.c b/src/translators/btparse/tex_tree.c
new file mode 100644
index 0000000..0d7d33d
--- /dev/null
+++ b/src/translators/btparse/tex_tree.c
@@ -0,0 +1,414 @@
+/* ------------------------------------------------------------------------
+@NAME : tex_tree.c
+@DESCRIPTION: Functions for dealing with strings of TeX code: converting
+ them to tree representation, traversing the trees to glean
+ useful information, and converting back to string form.
+@GLOBALS :
+@CALLS :
+@CALLERS :
+@CREATED : 1997/05/29, Greg Ward
+@MODIFIED :
+@VERSION : $Id: tex_tree.c,v 1.4 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+
+/*#include "bt_config.h"*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "error.h"
+#include "btparse.h"
+/*#include "my_dmalloc.h"*/
+
+/* blech! temp hack until I make error.c perfect and magical */
+#define string_warning(w) fprintf (stderr, w);
+
+typedef struct treestack_s
+{
+ bt_tex_tree * node;
+ struct treestack_s
+ * prev,
+ * next;
+} treestack;
+
+
+/* ----------------------------------------------------------------------
+ * Stack manipulation functions
+ */
+
+/* ------------------------------------------------------------------------
+@NAME : push_treestack()
+@INPUT : *stack
+ node
+@OUTPUT : *stack
+@RETURNS :
+@DESCRIPTION: Creates and initializes new node in a stack, and pushes it
+ onto the stack.
+@GLOBALS :
+@CALLS :
+@CALLERS :
+@CREATED : 1997/05/29, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static void
+push_treestack (treestack **stack, bt_tex_tree *node)
+{
+ treestack *newtop;
+
+ newtop = (treestack *) malloc (sizeof (treestack));
+ newtop->node = node;
+ newtop->next = NULL;
+ newtop->prev = *stack;
+
+ if (*stack != NULL) /* stack already has some entries */
+ {
+ (*stack)->next = newtop;
+ *stack = newtop;
+ }
+
+ *stack = newtop;
+
+} /* push_treestack() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : pop_treestack
+@INPUT : *stack
+@OUTPUT : *stack
+@RETURNS :
+@DESCRIPTION: Pops an entry off of a stack of tex_tree nodes, frees up
+ the wrapper treestack node, and returns the popped tree node.
+@GLOBALS :
+@CALLS :
+@CALLERS :
+@CREATED : 1997/05/29, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static bt_tex_tree *
+pop_treestack (treestack **stack)
+{
+ treestack * oldtop;
+ bt_tex_tree * node;
+
+ if (*stack == NULL)
+ internal_error ("attempt to pop off empty stack");
+ oldtop = (*stack)->prev;
+ node = (*stack)->node;
+ free (*stack);
+ if (oldtop != NULL)
+ oldtop->next = NULL;
+ *stack = oldtop;
+ return node;
+
+} /* pop_treestack() */
+
+
+/* ----------------------------------------------------------------------
+ * Tree creation/destruction functions
+ */
+
+/* ------------------------------------------------------------------------
+@NAME : new_tex_tree
+@INPUT : start
+@OUTPUT :
+@RETURNS : pointer to newly-allocated node
+@DESCRIPTION: Allocates and initializes a bt_tex_tree node.
+@GLOBALS :
+@CALLS :
+@CALLERS :
+@CREATED : 1997/05/29, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static bt_tex_tree *
+new_tex_tree (char *start)
+{
+ bt_tex_tree * node;
+
+ node = (bt_tex_tree *) malloc (sizeof (bt_tex_tree));
+ node->start = start;
+ node->len = 0;
+ node->child = node->next = NULL;
+ return node;
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_build_tex_tree
+@INPUT : string
+@OUTPUT :
+@RETURNS : pointer to a complete tree; call bt_free_tex_tree() to free
+ the entire tree
+@DESCRIPTION: Traverses a string looking for TeX groups ({...}), and builds
+ a tree containing pointers into the string and describing
+ its brace-structure.
+@GLOBALS :
+@CALLS :
+@CALLERS :
+@CREATED : 1997/05/29, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+bt_tex_tree *
+bt_build_tex_tree (char * string)
+{
+ int i;
+ int depth;
+ int len;
+ bt_tex_tree
+ * top,
+ * cur,
+ * new;
+ treestack
+ * stack;
+
+ i = 0;
+ depth = 0;
+ len = strlen (string);
+ top = new_tex_tree (string);
+ stack = NULL;
+
+ cur = top;
+
+ while (i < len)
+ {
+ switch (string[i])
+ {
+ case '{': /* go one level deeper */
+ {
+ if (i == len-1) /* open brace in last character? */
+ {
+ string_warning ("unbalanced braces: { at end of string");
+ goto error;
+ }
+
+ new = new_tex_tree (string+i+1);
+ cur->child = new;
+ push_treestack (&stack, cur);
+ cur = new;
+ depth++;
+ break;
+ }
+ case '}': /* pop level(s) off */
+ {
+ while (i < len && string[i] == '}')
+ {
+ if (stack == NULL)
+ {
+ string_warning ("unbalanced braces: extra }");
+ goto error;
+ }
+ cur = pop_treestack (&stack);
+ depth--;
+ i++;
+ }
+ i--;
+
+ if (i == len-1) /* reached end of string? */
+ {
+ if (depth > 0) /* but not at depth 0 */
+ {
+ string_warning ("unbalanced braces: not enough }'s");
+ goto error;
+ }
+
+ /*
+ * if we get here, do nothing -- we've reached the end of
+ * the string and are at depth 0, so will just fall out
+ * of the while loop at the end of this iteration
+ */
+ }
+ else /* still have characters left */
+ { /* to worry about */
+ new = new_tex_tree (string+i+1);
+ cur->next = new;
+ cur = new;
+ }
+
+ break;
+ }
+ default:
+ {
+ cur->len++;
+ }
+
+ } /* switch */
+
+ i++;
+
+ } /* while i */
+
+ if (depth > 0)
+ {
+ string_warning ("unbalanced braces (not enough }'s)");
+ goto error;
+ }
+
+ return top;
+
+error:
+ bt_free_tex_tree (&top);
+ return NULL;
+
+} /* bt_build_tex_tree() */
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_free_tex_tree
+@INPUT : *top
+@OUTPUT : *top (set to NULL after it's free()'d)
+@RETURNS :
+@DESCRIPTION: Frees up an entire tree created by bt_build_tex_tree().
+@GLOBALS :
+@CALLS : itself, free()
+@CALLERS :
+@CREATED : 1997/05/29, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void
+bt_free_tex_tree (bt_tex_tree **top)
+{
+ if ((*top)->child) bt_free_tex_tree (&(*top)->child);
+ if ((*top)->next) bt_free_tex_tree (&(*top)->next);
+ free (*top);
+ *top = NULL;
+}
+
+
+
+/* ----------------------------------------------------------------------
+ * Tree traversal functions
+ */
+
+/* ------------------------------------------------------------------------
+@NAME : bt_dump_tex_tree
+@INPUT : node
+ depth
+ stream
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Dumps a TeX tree: one node per line, depth indented according
+ to depth.
+@GLOBALS :
+@CALLS : itself
+@CALLERS :
+@CREATED : 1997/05/29, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+void
+bt_dump_tex_tree (bt_tex_tree *node, int depth, FILE *stream)
+{
+ char buf[256];
+
+ if (node == NULL)
+ return;
+
+ if (node->len > 255)
+ internal_error ("augughgh! buf too small");
+ strncpy (buf, node->start, node->len);
+ buf[node->len] = (char) 0;
+
+ fprintf (stream, "%*s[%s]\n", depth*2, "", buf);
+
+ bt_dump_tex_tree (node->child, depth+1, stream);
+ bt_dump_tex_tree (node->next, depth, stream);
+
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : count_length
+@INPUT : node
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Counts the total number of characters that will be needed
+ to print a string reconstructed from a TeX tree. (Length
+ of string in each node, plus two [{ and }] for each down
+ edge.)
+@GLOBALS :
+@CALLS : itself
+@CALLERS : bt_flatten_tex_tree
+@CREATED : 1997/05/29, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static int
+count_length (bt_tex_tree *node)
+{
+ if (node == NULL) return 0;
+ return
+ node->len +
+ (node->child ? 2 : 0) +
+ count_length (node->child) +
+ count_length (node->next);
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : flatten_tree
+@INPUT : node
+ *offset
+@OUTPUT : *buf
+ *offset
+@RETURNS :
+@DESCRIPTION: Dumps a reconstructed string ("flat" representation of the
+ tree) into a pre-allocated buffer, starting at a specified
+ offset.
+@GLOBALS :
+@CALLS : itself
+@CALLERS : bt_flatten_tex_tree
+@CREATED : 1997/05/29, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+static void
+flatten_tree (bt_tex_tree *node, char *buf, int *offset)
+{
+ strncpy (buf + *offset, node->start, node->len);
+ *offset += node->len;
+
+ if (node->child)
+ {
+ buf[(*offset)++] = '{';
+ flatten_tree (node->child, buf, offset);
+ buf[(*offset)++] = '}';
+ }
+
+ if (node->next)
+ {
+ flatten_tree (node->next, buf, offset);
+ }
+}
+
+
+/* ------------------------------------------------------------------------
+@NAME : bt_flatten_tex_tree
+@INPUT : top
+@OUTPUT :
+@RETURNS : flattened string representation of the tree (as a string
+ allocated with malloc(), so you should free() it when
+ you're done with it)
+@DESCRIPTION: Counts the number of characters needed for a "flat"
+ string representation of a tree, allocates a string of
+ that size, and generates the string.
+@GLOBALS :
+@CALLS : count_length, flatten_tree
+@CALLERS :
+@CREATED : 1997/05/29, GPW
+@MODIFIED :
+-------------------------------------------------------------------------- */
+char *
+bt_flatten_tex_tree (bt_tex_tree *top)
+{
+ int len;
+ int offset;
+ char * buf;
+
+ len = count_length (top);
+ buf = (char *) malloc (sizeof (char) * (len+1));
+ offset = 0;
+ flatten_tree (top, buf, &offset);
+ return buf;
+}
diff --git a/src/translators/btparse/tokens.h b/src/translators/btparse/tokens.h
new file mode 100644
index 0000000..6f9405a
--- /dev/null
+++ b/src/translators/btparse/tokens.h
@@ -0,0 +1,41 @@
+#ifndef tokens_h
+#define tokens_h
+/* tokens.h -- List of labelled tokens and stuff
+ *
+ * Generated from: bibtex.g
+ *
+ * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994
+ * Purdue University Electrical Engineering
+ * ANTLR Version 1.33
+ */
+#define zzEOF_TOKEN 1
+#define AT 2
+#define COMMENT 4
+#define NUMBER 9
+#define NAME 10
+#define LBRACE 11
+#define RBRACE 12
+#define ENTRY_OPEN 13
+#define ENTRY_CLOSE 14
+#define EQUALS 15
+#define HASH 16
+#define COMMA 17
+#define STRING 25
+
+void bibfile(AST**_root);
+void entry(AST**_root);
+void body(AST**_root, bt_metatype metatype );
+void contents(AST**_root, bt_metatype metatype );
+void fields(AST**_root);
+void field(AST**_root);
+void value(AST**_root);
+void simple_value(AST**_root);
+
+#endif
+extern SetWordType zzerr1[];
+extern SetWordType zzerr2[];
+extern SetWordType zzerr3[];
+extern SetWordType zzerr4[];
+extern SetWordType setwd1[];
+extern SetWordType zzerr5[];
+extern SetWordType setwd2[];
diff --git a/src/translators/btparse/traversal.c b/src/translators/btparse/traversal.c
new file mode 100644
index 0000000..c7e10a2
--- /dev/null
+++ b/src/translators/btparse/traversal.c
@@ -0,0 +1,187 @@
+/* ------------------------------------------------------------------------
+@NAME : traversal.c
+@DESCRIPTION: Routines for traversing the AST for a single entry.
+@GLOBALS :
+@CALLS :
+@CREATED : 1997/01/21, Greg Ward
+@MODIFIED :
+@VERSION : $Id: traversal.c,v 1.17 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+/*#include "bt_config.h"*/
+#include <stdlib.h>
+#include "btparse.h"
+#include "parse_auxiliary.h"
+#include "prototypes.h"
+/*#include "my_dmalloc.h"*/
+
+
+AST *bt_next_entry (AST *entry_list, AST *prev_entry)
+{
+ if (entry_list == NULL || entry_list->nodetype != BTAST_ENTRY)
+ return NULL;
+
+ if (prev_entry)
+ {
+ if (prev_entry->nodetype != BTAST_ENTRY)
+ return NULL;
+ else
+ return prev_entry->right;
+ }
+ else
+ return entry_list;
+}
+
+
+bt_metatype bt_entry_metatype (AST *entry)
+{
+ if (!entry) return BTE_UNKNOWN;
+ if (entry->nodetype != BTAST_ENTRY)
+ return BTE_UNKNOWN;
+ else
+ return entry->metatype;
+}
+
+
+char *bt_entry_type (AST *entry)
+{
+ if (!entry) return NULL;
+ if (entry->nodetype != BTAST_ENTRY)
+ return NULL;
+ else
+ return entry->text;
+}
+
+
+char *bt_entry_key (AST *entry)
+{
+ if (entry->metatype == BTE_REGULAR &&
+ entry->down && entry->down->nodetype == BTAST_KEY)
+ {
+ return entry->down->text;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+
+AST *bt_next_field (AST *entry, AST *prev, char **name)
+{
+ AST *field;
+ bt_metatype metatype;
+
+ *name = NULL;
+ if (!entry || !entry->down) return NULL; /* protect against empty entry */
+
+ metatype = entry->metatype;
+ if (metatype != BTE_MACRODEF && metatype != BTE_REGULAR)
+ return NULL;
+
+ if (prev == NULL) /* no previous field -- they must */
+ { /* want the first one */
+ field = entry->down;
+ if (metatype == BTE_REGULAR && field->nodetype == BTAST_KEY)
+ field = field->right; /* skip over citation key if present */
+ }
+ else /* they really do want the next one */
+ {
+ field = prev->right;
+ }
+
+ if (!field) return NULL; /* protect against field-less entry */
+ if (name) *name = field->text;
+ return field;
+} /* bt_next_field() */
+
+
+AST *bt_next_macro (AST *entry, AST *prev, char **name)
+{
+ return bt_next_field (entry, prev, name);
+}
+
+
+AST *bt_next_value (AST *top, AST *prev, bt_nodetype *nodetype, char **text)
+{
+ bt_nodetype nt; /* type of `top' node (to check) */
+ bt_metatype mt;
+ AST * value;
+
+ if (nodetype) *nodetype = BTAST_BOGUS;
+ if (text) *text = NULL;
+
+ if (!top) return NULL;
+ /* get_node_type (top, &nt, &mt); */
+ nt = top->nodetype;
+ mt = top->metatype;
+
+ if ((nt == BTAST_FIELD) ||
+ (nt == BTAST_ENTRY && (mt == BTE_COMMENT || mt == BTE_PREAMBLE)))
+ {
+ if (prev == NULL) /* no previous value -- give 'em */
+ { /* the first one */
+ value = top->down;
+ if (!value) return NULL;
+ if (nodetype) *nodetype = value->nodetype;
+ }
+ else
+ {
+ value = prev->right;
+ if (!value) return NULL;
+ if (nodetype) *nodetype = value->nodetype;
+ }
+
+ if (nt == BTAST_ENTRY && value->nodetype != BTAST_STRING)
+ internal_error ("found comment or preamble with non-string value");
+ }
+ else
+ {
+ value = NULL;
+ }
+
+ if (text && value) *text = value->text;
+
+ return value;
+} /* bt_next_value() */
+
+
+char *bt_get_text (AST *node)
+{
+ ushort pp_options = BTO_FULL; /* options for full processing: */
+ /* expand macros, paste strings, */
+ /* collapse whitespace */
+ bt_nodetype nt;
+ bt_metatype mt;
+
+ nt = node->nodetype;
+ mt = node->metatype;
+
+ if (nt == BTAST_FIELD)
+ {
+#if DEBUG
+ char *value;
+
+ dump_ast ("bt_get_text (pre): node =\n", node);
+ value = bt_postprocess_field (node, pp_options, FALSE);
+ dump_ast ("bt_get_text (post): node =\n", node);
+ return value;
+#else
+ return bt_postprocess_field (node, pp_options, FALSE);
+#endif
+ }
+ else if (nt == BTAST_ENTRY && (mt == BTE_COMMENT || mt == BTE_PREAMBLE))
+ {
+ return bt_postprocess_value (node->down, pp_options, FALSE);
+ }
+ else
+ {
+ return NULL;
+ }
+}
diff --git a/src/translators/btparse/util.c b/src/translators/btparse/util.c
new file mode 100644
index 0000000..1330176
--- /dev/null
+++ b/src/translators/btparse/util.c
@@ -0,0 +1,79 @@
+/* ------------------------------------------------------------------------
+@NAME : util.c
+@INPUT :
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Miscellaneous utility functions. So far, just:
+ strlwr
+ strupr
+@CREATED : Summer 1996, Greg Ward
+@MODIFIED :
+@VERSION : $Id: util.c,v 1.6 1999/11/29 01:13:10 greg Rel $
+@COPYRIGHT : Copyright (c) 1996-99 by Gregory P. Ward. All rights reserved.
+
+ This file is part of the btparse library. This library is
+ free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+-------------------------------------------------------------------------- */
+
+/*#include "bt_config.h"*/
+#include <string.h>
+#include <ctype.h>
+#include "prototypes.h"
+/*#include "my_dmalloc.h"*/
+
+/* ------------------------------------------------------------------------
+@NAME : strlwr()
+@INPUT :
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Converts a string to lowercase in place.
+@GLOBALS :
+@CALLS :
+@CREATED : 1996/01/06, GPW
+@MODIFIED :
+@COMMENTS : This should work the same as strlwr() in DOS compilers --
+ why this isn't mandated by ANSI is a mystery to me...
+-------------------------------------------------------------------------- */
+#if !HAVE_STRLWR
+char *strlwr (char *s)
+{
+ int len, i;
+
+ len = strlen (s);
+ for (i = 0; i < len; i++)
+ s[i] = tolower (s[i]);
+
+ return s;
+}
+#endif
+
+
+
+/* ------------------------------------------------------------------------
+@NAME : strupr()
+@INPUT :
+@OUTPUT :
+@RETURNS :
+@DESCRIPTION: Converts a string to uppercase in place.
+@GLOBALS :
+@CALLS :
+@CREATED : 1996/01/06, GPW
+@MODIFIED :
+@COMMENTS : This should work the same as strupr() in DOS compilers --
+ why this isn't mandated by ANSI is a mystery to me...
+-------------------------------------------------------------------------- */
+#if !HAVE_STRUPR
+char *strupr (char *s)
+{
+ int len, i;
+
+ len = strlen (s);
+ for (i = 0; i < len; i++)
+ s[i] = toupper (s[i]);
+
+ return s;
+}
+#endif
diff --git a/src/translators/csvexporter.cpp b/src/translators/csvexporter.cpp
new file mode 100644
index 0000000..bb206e1
--- /dev/null
+++ b/src/translators/csvexporter.cpp
@@ -0,0 +1,190 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "csvexporter.h"
+#include "../document.h"
+#include "../collection.h"
+#include "../filehandler.h"
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <klineedit.h>
+#include <kconfig.h>
+
+#include <qgroupbox.h>
+#include <qcheckbox.h>
+#include <qlayout.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qwhatsthis.h>
+
+using Tellico::Export::CSVExporter;
+
+CSVExporter::CSVExporter() : Tellico::Export::Exporter(),
+ m_includeTitles(true),
+ m_delimiter(QChar(',')),
+ m_widget(0) {
+}
+
+QString CSVExporter::formatString() const {
+ return i18n("CSV");
+}
+
+QString CSVExporter::fileFilter() const {
+ return i18n("*.csv|CSV Files (*.csv)") + QChar('\n') + i18n("*|All Files");
+}
+
+QString& CSVExporter::escapeText(QString& text_) {
+ bool quotes = false;
+ if(text_.find('"') != -1) {
+ quotes = true;
+ // quotation marks will be escaped by using a double pair
+ text_.replace('"', QString::fromLatin1("\"\""));
+ }
+ // if the text contains quotes or the delimiter, it needs to be surrounded by quotes
+ if(quotes || text_.find(m_delimiter) != -1) {
+ text_.prepend('"');
+ text_.append('"');
+ }
+ return text_;
+}
+
+bool CSVExporter::exec() {
+ if(!collection()) {
+ return false;
+ }
+
+ QString text;
+
+ Data::FieldVec fields = collection()->fields();
+ Data::FieldVec::Iterator fIt;
+
+ if(m_includeTitles) {
+ for(fIt = fields.begin(); fIt != fields.end(); ++fIt) {
+ QString title = fIt->title();
+ text += escapeText(title);
+ if(!fIt.nextEnd()) {
+ text += m_delimiter;
+ }
+ }
+ text += '\n';
+ }
+
+ bool format = options() & Export::ExportFormatted;
+
+ QString tmp;
+ for(Data::EntryVec::ConstIterator entryIt = entries().begin(); entryIt != entries().end(); ++entryIt) {
+ for(fIt = fields.begin(); fIt != fields.end(); ++fIt) {
+ tmp = entryIt->field(fIt->name(), format);
+ text += escapeText(tmp);
+ if(!fIt.nextEnd()) {
+ text += m_delimiter;
+ }
+ }
+ fIt = fields.begin();
+ text += '\n';
+ }
+
+ return FileHandler::writeTextURL(url(), text, options() & ExportUTF8, options() & Export::ExportForce);
+}
+
+QWidget* CSVExporter::widget(QWidget* parent_, const char* name_/*=0*/) {
+ if(m_widget && m_widget->parent() == parent_) {
+ return m_widget;
+ }
+
+ m_widget = new QWidget(parent_, name_);
+ QVBoxLayout* l = new QVBoxLayout(m_widget);
+
+ QGroupBox* box = new QGroupBox(1, Qt::Horizontal, i18n("CSV Options"), m_widget);
+ l->addWidget(box);
+
+ m_checkIncludeTitles = new QCheckBox(i18n("Include field titles as column headers"), box);
+ m_checkIncludeTitles->setChecked(m_includeTitles);
+ QWhatsThis::add(m_checkIncludeTitles, i18n("If checked, a header row will be added with the "
+ "field titles."));
+
+ QButtonGroup* delimiterGroup = new QButtonGroup(0, Qt::Vertical, i18n("Delimiter"), box);
+ QGridLayout* m_delimiterGroupLayout = new QGridLayout(delimiterGroup->layout());
+ m_delimiterGroupLayout->setAlignment(Qt::AlignTop);
+ QWhatsThis::add(delimiterGroup, i18n("In addition to a comma, other characters may be used as "
+ "a delimiter, separating each value in the file."));
+
+ m_radioComma = new QRadioButton(delimiterGroup);
+ m_radioComma->setText(i18n("Comma"));
+ m_radioComma->setChecked(true);
+ QWhatsThis::add(m_radioComma, i18n("Use a comma as the delimiter."));
+ m_delimiterGroupLayout->addWidget(m_radioComma, 0, 0);
+
+ m_radioSemicolon = new QRadioButton( delimiterGroup);
+ m_radioSemicolon->setText(i18n("Semicolon"));
+ QWhatsThis::add(m_radioSemicolon, i18n("Use a semi-colon as the delimiter."));
+ m_delimiterGroupLayout->addWidget(m_radioSemicolon, 0, 1);
+
+ m_radioTab = new QRadioButton(delimiterGroup);
+ m_radioTab->setText(i18n("Tab"));
+ QWhatsThis::add(m_radioTab, i18n("Use a tab as the delimiter."));
+ m_delimiterGroupLayout->addWidget(m_radioTab, 1, 0);
+
+ m_radioOther = new QRadioButton(delimiterGroup);
+ m_radioOther->setText(i18n("Other"));
+ QWhatsThis::add(m_radioOther, i18n("Use a custom string as the delimiter."));
+ m_delimiterGroupLayout->addWidget(m_radioOther, 1, 1);
+
+ m_editOther = new KLineEdit(delimiterGroup);
+ m_editOther->setEnabled(m_radioOther->isChecked());
+ QWhatsThis::add(m_editOther, i18n("A custom string, such as a colon, may be used as a delimiter."));
+ m_delimiterGroupLayout->addWidget(m_editOther, 1, 2);
+ QObject::connect(m_radioOther, SIGNAL(toggled(bool)),
+ m_editOther, SLOT(setEnabled(bool)));
+
+ if(m_delimiter == QChar(',')) {
+ m_radioComma->setChecked(true);
+ } else if(m_delimiter == QChar(';')) {
+ m_radioSemicolon->setChecked(true);
+ } else if(m_delimiter == QChar('\t')) {
+ m_radioTab->setChecked(true);
+ } else if(!m_delimiter.isEmpty()) {
+ m_radioOther->setChecked(true);
+ m_editOther->setEnabled(true);
+ m_editOther->setText(m_delimiter);
+ }
+
+ l->addStretch(1);
+ return m_widget;
+}
+
+void CSVExporter::readOptions(KConfig* config_) {
+ KConfigGroup group(config_, QString::fromLatin1("ExportOptions - %1").arg(formatString()));
+ m_includeTitles = group.readBoolEntry("Include Titles", m_includeTitles);
+ m_delimiter = group.readEntry("Delimiter", m_delimiter);
+}
+
+void CSVExporter::saveOptions(KConfig* config_) {
+ m_includeTitles = m_checkIncludeTitles->isChecked();
+ if(m_radioComma->isChecked()) {
+ m_delimiter = QChar(',');
+ } else if(m_radioSemicolon->isChecked()) {
+ m_delimiter = QChar(';');
+ } else if(m_radioTab->isChecked()) {
+ m_delimiter = QChar('\t');
+ } else {
+ m_delimiter = m_editOther->text();
+ }
+
+ KConfigGroup group(config_, QString::fromLatin1("ExportOptions - %1").arg(formatString()));
+ group.writeEntry("Include Titles", m_includeTitles);
+ group.writeEntry("Delimiter", m_delimiter);
+}
+
+#include "csvexporter.moc"
diff --git a/src/translators/csvexporter.h b/src/translators/csvexporter.h
new file mode 100644
index 0000000..23624e3
--- /dev/null
+++ b/src/translators/csvexporter.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef CSVEXPORTER_H
+#define CSVEXPORTER_H
+
+class KLineEdit;
+class KConfig;
+
+class QWidget;
+class QCheckBox;
+class QRadioButton;
+
+#include "exporter.h"
+
+namespace Tellico {
+ namespace Export {
+
+/**
+ * @author Robby Stephenson
+ */
+class CSVExporter : public Exporter {
+Q_OBJECT
+
+public:
+ CSVExporter();
+
+ virtual bool exec();
+ virtual QString formatString() const;
+ virtual QString fileFilter() const;
+
+ virtual QWidget* widget(QWidget* parent, const char* name=0);
+ virtual void readOptions(KConfig* config);
+ virtual void saveOptions(KConfig* config);
+
+private:
+ QString& escapeText(QString& text);
+
+ bool m_includeTitles;
+ QString m_delimiter;
+
+ QWidget* m_widget;
+ QCheckBox* m_checkIncludeTitles;
+ QRadioButton* m_radioComma;
+ QRadioButton* m_radioSemicolon;
+ QRadioButton* m_radioTab;
+ QRadioButton* m_radioOther;
+ KLineEdit* m_editOther;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/csvimporter.cpp b/src/translators/csvimporter.cpp
new file mode 100644
index 0000000..f0c0900
--- /dev/null
+++ b/src/translators/csvimporter.cpp
@@ -0,0 +1,552 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "csvimporter.h"
+#include "translators.h" // needed for ImportAction
+#include "../collectionfieldsdialog.h"
+#include "../document.h"
+#include "../collection.h"
+#include "../progressmanager.h"
+#include "../tellico_debug.h"
+#include "../collectionfactory.h"
+#include "../gui/collectiontypecombo.h"
+#include "../latin1literal.h"
+#include "../stringset.h"
+
+extern "C" {
+#include "libcsv.h"
+}
+
+#include <klineedit.h>
+#include <kcombobox.h>
+#include <knuminput.h>
+#include <kpushbutton.h>
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <kconfig.h>
+#include <kmessagebox.h>
+
+#include <qgroupbox.h>
+#include <qlayout.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qwhatsthis.h>
+#include <qtable.h>
+#include <qvaluevector.h>
+#include <qregexp.h>
+
+using Tellico::Import::CSVImporter;
+
+static void writeToken(char* buffer, size_t len, void* data);
+static void writeRow(char buffer, void* data);
+
+class CSVImporter::Parser {
+public:
+ Parser(const QString& str) : stream(new QTextIStream(&str)) { csv_init(&parser, 0); }
+ ~Parser() { csv_free(parser); delete stream; stream = 0; }
+
+ void setDelimiter(const QString& s) { Q_ASSERT(s.length() == 1); csv_set_delim(parser, s[0].latin1()); }
+ void reset(const QString& str) { delete stream; stream = new QTextIStream(&str); };
+ bool hasNext() { return !stream->atEnd(); }
+ void skipLine() { stream->readLine(); }
+
+ void addToken(const QString& t) { tokens += t; }
+ void setRowDone(bool b) { done = b; }
+
+ QStringList nextTokens() {
+ tokens.clear();
+ done = false;
+ while(hasNext() && !done) {
+ QCString line = stream->readLine().utf8() + '\n'; // need the eol char
+ csv_parse(parser, line, line.length(), &writeToken, &writeRow, this);
+ }
+ csv_fini(parser, &writeToken, &writeRow, this);
+ return tokens;
+ }
+
+private:
+ struct csv_parser* parser;
+ QTextIStream* stream;
+ QStringList tokens;
+ bool done;
+};
+
+static void writeToken(char* buffer, size_t len, void* data) {
+ CSVImporter::Parser* p = static_cast<CSVImporter::Parser*>(data);
+ p->addToken(QString::fromUtf8(buffer, len));
+}
+
+static void writeRow(char c, void* data) {
+ Q_UNUSED(c);
+ CSVImporter::Parser* p = static_cast<CSVImporter::Parser*>(data);
+ p->setRowDone(true);
+}
+
+CSVImporter::CSVImporter(const KURL& url_) : Tellico::Import::TextImporter(url_),
+ m_coll(0),
+ m_existingCollection(0),
+ m_firstRowHeader(false),
+ m_delimiter(QString::fromLatin1(",")),
+ m_cancelled(false),
+ m_widget(0),
+ m_table(0),
+ m_hasAssignedFields(false),
+ m_parser(new Parser(text())) {
+ m_parser->setDelimiter(m_delimiter);
+}
+
+CSVImporter::~CSVImporter() {
+ delete m_parser;
+ m_parser = 0;
+}
+
+Tellico::Data::CollPtr CSVImporter::collection() {
+ // don't just check if m_coll is non-null since the collection can be created elsewhere
+ if(m_coll && m_coll->entryCount() > 0) {
+ return m_coll;
+ }
+
+ if(!m_coll) {
+ m_coll = CollectionFactory::collection(m_comboColl->currentType(), true);
+ }
+
+ const QStringList existingNames = m_coll->fieldNames();
+
+ QValueVector<int> cols;
+ QStringList names;
+ for(int col = 0; col < m_table->numCols(); ++col) {
+ QString t = m_table->horizontalHeader()->label(col);
+ if(m_existingCollection && m_existingCollection->fieldByTitle(t)) {
+ // the collection might have the right field, but a different title, say for translations
+ Data::FieldPtr f = m_existingCollection->fieldByTitle(t);
+ if(m_coll->hasField(f->name())) {
+ // might have different values settings
+ m_coll->removeField(f->name(), true /* force */);
+ }
+ m_coll->addField(new Data::Field(*f));
+ cols.push_back(col);
+ names << f->name();
+ } else if(m_coll->fieldByTitle(t)) {
+ cols.push_back(col);
+ names << m_coll->fieldNameByTitle(t);
+ }
+ }
+
+ if(names.isEmpty()) {
+ myDebug() << "CSVImporter::collection() - no fields assigned" << endl;
+ return 0;
+ }
+
+ m_parser->reset(text());
+
+ // if the first row are headers, skip it
+ if(m_firstRowHeader) {
+ m_parser->skipLine();
+ }
+
+ const uint numLines = text().contains('\n');
+ const uint stepSize = QMAX(s_stepSize, numLines/100);
+ const bool showProgress = options() & ImportProgress;
+
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, progressLabel(), true);
+ item.setTotalSteps(numLines);
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+ ProgressItem::Done done(this);
+
+ uint j = 0;
+ while(!m_cancelled && m_parser->hasNext()) {
+ bool empty = true;
+ Data::EntryPtr entry = new Data::Entry(m_coll);
+ QStringList values = m_parser->nextTokens();
+ for(uint i = 0; i < names.size(); ++i) {
+// QString value = values[cols[i]].simplifyWhiteSpace();
+ QString value = values[cols[i]].stripWhiteSpace();
+ bool success = entry->setField(names[i], value);
+ // we might need to add a new allowed value
+ // assume that if the user is importing the value, it should be allowed
+ if(!success && m_coll->fieldByName(names[i])->type() == Data::Field::Choice) {
+ Data::FieldPtr f = m_coll->fieldByName(names[i]);
+ StringSet allow;
+ allow.add(f->allowed());
+ allow.add(value);
+ f->setAllowed(allow.toList());
+ m_coll->modifyField(f);
+ success = entry->setField(names[i], value);
+ }
+ if(empty && success) {
+ empty = false;
+ }
+ }
+ if(!empty) {
+ m_coll->addEntries(entry);
+ }
+
+ if(showProgress && j%stepSize == 0) {
+ ProgressManager::self()->setProgress(this, j);
+ kapp->processEvents();
+ }
+ ++j;
+ }
+
+ {
+ KConfigGroup config(KGlobal::config(), QString::fromLatin1("ImportOptions - CSV"));
+ config.writeEntry("Delimiter", m_delimiter);
+ config.writeEntry("First Row Titles", m_firstRowHeader);
+ }
+
+ return m_coll;
+}
+
+QWidget* CSVImporter::widget(QWidget* parent_, const char* name_) {
+ if(m_widget && m_widget->parent() == parent_) {
+ return m_widget;
+ }
+
+ m_widget = new QWidget(parent_, name_);
+ QVBoxLayout* l = new QVBoxLayout(m_widget);
+
+ QGroupBox* group = new QGroupBox(1, Qt::Horizontal, i18n("CSV Options"), m_widget);
+ l->addWidget(group);
+
+ QHBox* box = new QHBox(group);
+ box->setSpacing(5);
+ QLabel* lab = new QLabel(i18n("Collection &type:"), box);
+ m_comboColl = new GUI::CollectionTypeCombo(box);
+ lab->setBuddy(m_comboColl);
+ QWhatsThis::add(m_comboColl, i18n("Select the type of collection being imported."));
+ connect(m_comboColl, SIGNAL(activated(int)), SLOT(slotTypeChanged()));
+ // need a spacer
+ QWidget* w = new QWidget(box);
+ box->setStretchFactor(w, 1);
+
+ m_checkFirstRowHeader = new QCheckBox(i18n("&First row contains field titles"), group);
+ QWhatsThis::add(m_checkFirstRowHeader, i18n("If checked, the first row is used as field titles."));
+ connect(m_checkFirstRowHeader, SIGNAL(toggled(bool)), SLOT(slotFirstRowHeader(bool)));
+
+ QHBox* hbox2 = new QHBox(group);
+ m_delimiterGroup = new QButtonGroup(0, Qt::Vertical, i18n("Delimiter"), hbox2);
+ QGridLayout* m_delimiterGroupLayout = new QGridLayout(m_delimiterGroup->layout(), 3, 3);
+ m_delimiterGroupLayout->setAlignment(Qt::AlignTop);
+ QWhatsThis::add(m_delimiterGroup, i18n("In addition to a comma, other characters may be used as "
+ "a delimiter, separating each value in the file."));
+ connect(m_delimiterGroup, SIGNAL(clicked(int)), SLOT(slotDelimiter()));
+
+ m_radioComma = new QRadioButton(m_delimiterGroup);
+ m_radioComma->setText(i18n("&Comma"));
+ m_radioComma->setChecked(true);
+ QWhatsThis::add(m_radioComma, i18n("Use a comma as the delimiter."));
+ m_delimiterGroupLayout->addWidget(m_radioComma, 1, 0);
+
+ m_radioSemicolon = new QRadioButton( m_delimiterGroup);
+ m_radioSemicolon->setText(i18n("&Semicolon"));
+ QWhatsThis::add(m_radioSemicolon, i18n("Use a semi-colon as the delimiter."));
+ m_delimiterGroupLayout->addWidget(m_radioSemicolon, 1, 1);
+
+ m_radioTab = new QRadioButton(m_delimiterGroup);
+ m_radioTab->setText(i18n("Ta&b"));
+ QWhatsThis::add(m_radioTab, i18n("Use a tab as the delimiter."));
+ m_delimiterGroupLayout->addWidget(m_radioTab, 2, 0);
+
+ m_radioOther = new QRadioButton(m_delimiterGroup);
+ m_radioOther->setText(i18n("Ot&her:"));
+ QWhatsThis::add(m_radioOther, i18n("Use a custom string as the delimiter."));
+ m_delimiterGroupLayout->addWidget(m_radioOther, 2, 1);
+
+ m_editOther = new KLineEdit(m_delimiterGroup);
+ m_editOther->setEnabled(false);
+ m_editOther->setFixedWidth(m_widget->fontMetrics().width('X') * 4);
+ m_editOther->setMaxLength(1);
+ QWhatsThis::add(m_editOther, i18n("A custom string, such as a colon, may be used as a delimiter."));
+ m_delimiterGroupLayout->addWidget(m_editOther, 2, 2);
+ connect(m_radioOther, SIGNAL(toggled(bool)),
+ m_editOther, SLOT(setEnabled(bool)));
+ connect(m_editOther, SIGNAL(textChanged(const QString&)), SLOT(slotDelimiter()));
+
+ w = new QWidget(hbox2);
+ hbox2->setStretchFactor(w, 1);
+
+ m_table = new QTable(5, 0, group);
+ m_table->setSelectionMode(QTable::Single);
+ m_table->setFocusStyle(QTable::FollowStyle);
+ m_table->setLeftMargin(0);
+ m_table->verticalHeader()->hide();
+ m_table->horizontalHeader()->setClickEnabled(true);
+ m_table->setReadOnly(true);
+ m_table->setMinimumHeight(m_widget->fontMetrics().lineSpacing() * 8);
+ QWhatsThis::add(m_table, i18n("The table shows up to the first five lines of the CSV file."));
+ connect(m_table, SIGNAL(currentChanged(int, int)), SLOT(slotCurrentChanged(int, int)));
+ connect(m_table->horizontalHeader(), SIGNAL(clicked(int)), SLOT(slotHeaderClicked(int)));
+
+ QWidget* hbox = new QWidget(group);
+ QHBoxLayout* hlay = new QHBoxLayout(hbox, 5);
+ hlay->addStretch(10);
+ QWhatsThis::add(hbox, i18n("<qt>Set each column to correspond to a field in the collection by choosing "
+ "a column, selecting the field, then clicking the <i>Assign Field</i> button.</qt>"));
+ lab = new QLabel(i18n("Co&lumn:"), hbox);
+ hlay->addWidget(lab);
+ m_colSpinBox = new KIntSpinBox(hbox);
+ hlay->addWidget(m_colSpinBox);
+ m_colSpinBox->setMinValue(1);
+ connect(m_colSpinBox, SIGNAL(valueChanged(int)), SLOT(slotSelectColumn(int)));
+ lab->setBuddy(m_colSpinBox);
+ hlay->addSpacing(10);
+
+ lab = new QLabel(i18n("&Data field in this column:"), hbox);
+ hlay->addWidget(lab);
+ m_comboField = new KComboBox(hbox);
+ hlay->addWidget(m_comboField);
+ connect(m_comboField, SIGNAL(activated(int)), SLOT(slotFieldChanged(int)));
+ lab->setBuddy(m_comboField);
+ hlay->addSpacing(10);
+
+ m_setColumnBtn = new KPushButton(i18n("&Assign Field"), hbox);
+ hlay->addWidget(m_setColumnBtn);
+ m_setColumnBtn->setIconSet(SmallIconSet(QString::fromLatin1("apply")));
+ connect(m_setColumnBtn, SIGNAL(clicked()), SLOT(slotSetColumnTitle()));
+ hlay->addStretch(10);
+
+ l->addStretch(1);
+
+ KConfigGroup config(KGlobal::config(), QString::fromLatin1("ImportOptions - CSV"));
+ m_delimiter = config.readEntry("Delimiter", m_delimiter);
+ m_firstRowHeader = config.readBoolEntry("First Row Titles", m_firstRowHeader);
+
+ m_checkFirstRowHeader->setChecked(m_firstRowHeader);
+ if(m_delimiter == Latin1Literal(",")) {
+ m_radioComma->setChecked(true);
+ slotDelimiter(); // since the comma box was already checked, the slot won't fire
+ } else if(m_delimiter == Latin1Literal(";")) {
+ m_radioSemicolon->setChecked(true);
+ } else if(m_delimiter == Latin1Literal("\t")) {
+ m_radioTab->setChecked(true);
+ } else if(!m_delimiter.isEmpty()) {
+ m_radioOther->setChecked(true);
+ m_editOther->setEnabled(true);
+ m_editOther->setText(m_delimiter);
+ }
+
+ return m_widget;
+}
+
+bool CSVImporter::validImport() const {
+ // at least one column has to be defined
+ if(!m_hasAssignedFields) {
+ KMessageBox::sorry(m_widget, i18n("At least one column must be assigned to a field. "
+ "Only assigned columns will be imported."));
+ }
+ return m_hasAssignedFields;
+}
+
+void CSVImporter::fillTable() {
+ if(!m_table) {
+ return;
+ }
+
+ m_parser->reset(text());
+ // not skipping first row since the updateHeader() call depends on it
+
+ int maxCols = 0;
+ int row = 0;
+ for( ; m_parser->hasNext() && row < m_table->numRows(); ++row) {
+ QStringList values = m_parser->nextTokens();
+ if(static_cast<int>(values.count()) > m_table->numCols()) {
+ m_table->setNumCols(values.count());
+ m_colSpinBox->setMaxValue(values.count());
+ }
+ int col = 0;
+ for(QStringList::ConstIterator it = values.begin(); it != values.end(); ++it) {
+ m_table->setText(row, col, *it);
+ m_table->adjustColumn(col);
+ ++col;
+ }
+ if(col > maxCols) {
+ maxCols = col;
+ }
+ }
+ for( ; row < m_table->numRows(); ++row) {
+ for(int col = 0; col < m_table->numCols(); ++col) {
+ m_table->clearCell(row, col);
+ }
+ }
+
+ m_table->setNumCols(maxCols);
+}
+
+void CSVImporter::slotTypeChanged() {
+ // iterate over the collection names until it matches the text of the combo box
+ Data::Collection::Type type = static_cast<Data::Collection::Type>(m_comboColl->currentType());
+ m_coll = CollectionFactory::collection(type, true);
+
+ updateHeader(true);
+ m_comboField->clear();
+ m_comboField->insertStringList(m_existingCollection ? m_existingCollection->fieldTitles() : m_coll->fieldTitles());
+ m_comboField->insertItem('<' + i18n("New Field") + '>');
+
+ // hack to force a resize
+ m_comboField->setFont(m_comboField->font());
+ m_comboField->updateGeometry();
+}
+
+void CSVImporter::slotFirstRowHeader(bool b_) {
+ m_firstRowHeader = b_;
+ updateHeader(false);
+ fillTable();
+}
+
+void CSVImporter::slotDelimiter() {
+ if(m_radioComma->isChecked()) {
+ m_delimiter = ',';
+ } else if(m_radioSemicolon->isChecked()) {
+ m_delimiter = ';';
+ } else if(m_radioTab->isChecked()) {
+ m_delimiter = '\t';
+ } else {
+ m_editOther->setFocus();
+ m_delimiter = m_editOther->text();
+ }
+ if(!m_delimiter.isEmpty()) {
+ m_parser->setDelimiter(m_delimiter);
+ fillTable();
+ updateHeader(false);
+ }
+}
+
+void CSVImporter::slotCurrentChanged(int, int col_) {
+ int pos = col_+1;
+ m_colSpinBox->setValue(pos); //slotSelectColumn() gets called because of the signal
+}
+
+void CSVImporter::slotHeaderClicked(int col_) {
+ int pos = col_+1;
+ m_colSpinBox->setValue(pos); //slotSelectColumn() gets called because of the signal
+}
+
+void CSVImporter::slotSelectColumn(int pos_) {
+ // pos is really the number of the position of the column
+ int col = pos_ - 1;
+ m_table->ensureCellVisible(0, col);
+ m_comboField->setCurrentItem(m_table->horizontalHeader()->label(col));
+}
+
+void CSVImporter::slotSetColumnTitle() {
+ int col = m_colSpinBox->value()-1;
+ const QString title = m_comboField->currentText();
+ m_table->horizontalHeader()->setLabel(col, title);
+ m_hasAssignedFields = true;
+ // make sure none of the other columns have this title
+ bool found = false;
+ for(int i = 0; i < col; ++i) {
+ if(m_table->horizontalHeader()->label(i) == title) {
+ m_table->horizontalHeader()->setLabel(i, QString::number(i+1));
+ found = true;
+ break;
+ }
+ }
+ // if found, then we're done
+ if(found) {
+ return;
+ }
+ for(int i = col+1; i < m_table->numCols(); ++i) {
+ if(m_table->horizontalHeader()->label(i) == title) {
+ m_table->horizontalHeader()->setLabel(i, QString::number(i+1));
+ break;
+ }
+ }
+}
+
+void CSVImporter::updateHeader(bool force_) {
+ if(!m_table) {
+ return;
+ }
+ if(!m_firstRowHeader && !force_) {
+ return;
+ }
+
+ Data::CollPtr c = m_existingCollection ? m_existingCollection : m_coll;
+ for(int col = 0; col < m_table->numCols(); ++col) {
+ QString s = m_table->text(0, col);
+ Data::FieldPtr f;
+ if(c) {
+ c->fieldByTitle(s);
+ if(!f) {
+ f = c->fieldByName(s);
+ }
+ }
+ if(m_firstRowHeader && !s.isEmpty() && c && f) {
+ m_table->horizontalHeader()->setLabel(col, f->title());
+ m_hasAssignedFields = true;
+ } else {
+ m_table->horizontalHeader()->setLabel(col, QString::number(col+1));
+ }
+ }
+}
+
+void CSVImporter::slotFieldChanged(int idx_) {
+ // only care if it's the last item -> add new field
+ if(idx_ < m_comboField->count()-1) {
+ return;
+ }
+
+ Data::CollPtr c = m_existingCollection ? m_existingCollection : m_coll;
+ uint count = c->fieldTitles().count();
+ CollectionFieldsDialog dlg(c, m_widget);
+// dlg.setModal(true);
+ if(dlg.exec() == QDialog::Accepted) {
+ m_comboField->clear();
+ m_comboField->insertStringList(c->fieldTitles());
+ m_comboField->insertItem('<' + i18n("New Field") + '>');
+ if(count != c->fieldTitles().count()) {
+ fillTable();
+ }
+ m_comboField->setCurrentItem(0);
+ }
+}
+
+void CSVImporter::slotActionChanged(int action_) {
+ Data::CollPtr currColl = Data::Document::self()->collection();
+ if(!currColl) {
+ m_existingCollection = 0;
+ return;
+ }
+
+ switch(action_) {
+ case Import::Replace:
+ {
+ int currType = m_comboColl->currentType();
+ m_comboColl->reset();
+ m_comboColl->setCurrentType(currType);
+ m_existingCollection = 0;
+ }
+ break;
+
+ case Import::Append:
+ case Import::Merge:
+ {
+ m_comboColl->clear();
+ QString name = CollectionFactory::nameMap()[currColl->type()];
+ m_comboColl->insertItem(name, currColl->type());
+ m_existingCollection = currColl;
+ }
+ break;
+ }
+ slotTypeChanged();
+}
+
+void CSVImporter::slotCancel() {
+ m_cancelled = true;
+}
+
+#include "csvimporter.moc"
diff --git a/src/translators/csvimporter.h b/src/translators/csvimporter.h
new file mode 100644
index 0000000..6561584
--- /dev/null
+++ b/src/translators/csvimporter.h
@@ -0,0 +1,107 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef CSVIMPORTER_H
+#define CSVIMPORTER_H
+
+class CSVImporterWidget;
+
+class KLineEdit;
+class KComboBox;
+class KIntSpinBox;
+class KPushButton;
+
+class QButtonGroup;
+class QCheckBox;
+class QRadioButton;
+class QTable;
+
+#include "textimporter.h"
+#include "../datavectors.h"
+
+namespace Tellico {
+ namespace GUI {
+ class CollectionTypeCombo;
+ }
+ namespace Import {
+
+/**
+ * @author Robby Stephenson
+ */
+class CSVImporter : public TextImporter {
+Q_OBJECT
+
+public:
+ class Parser;
+
+ /**
+ */
+ CSVImporter(const KURL& url);
+ ~CSVImporter();
+
+ /**
+ * @return A pointer to a @ref Data::Collection, or 0 if none can be created.
+ */
+ virtual Data::CollPtr collection();
+ /**
+ */
+ virtual QWidget* widget(QWidget* parent, const char* name=0);
+
+ virtual bool validImport() const;
+
+public slots:
+ void slotActionChanged(int action);
+ void slotCancel();
+
+private slots:
+ void slotTypeChanged();
+ void slotFieldChanged(int idx);
+ void slotFirstRowHeader(bool b);
+ void slotDelimiter();
+ void slotCurrentChanged(int row, int col);
+ void slotHeaderClicked(int col);
+ void slotSelectColumn(int col);
+ void slotSetColumnTitle();
+
+private:
+ void fillTable();
+ void updateHeader(bool force);
+
+ Data::CollPtr m_coll;
+ Data::CollPtr m_existingCollection; // used to grab fields from current collection in window
+ bool m_firstRowHeader;
+ QString m_delimiter;
+ bool m_cancelled;
+
+ QWidget* m_widget;
+ GUI::CollectionTypeCombo* m_comboColl;
+ QCheckBox* m_checkFirstRowHeader;
+ QButtonGroup* m_delimiterGroup;
+ QRadioButton* m_radioComma;
+ QRadioButton* m_radioSemicolon;
+ QRadioButton* m_radioTab;
+ QRadioButton* m_radioOther;
+ KLineEdit* m_editOther;
+ QTable* m_table;
+ KIntSpinBox* m_colSpinBox;
+ KComboBox* m_comboField;
+ KPushButton* m_setColumnBtn;
+ bool m_hasAssignedFields;
+
+ friend class Parser;
+ Parser* m_parser;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/dataimporter.h b/src/translators/dataimporter.h
new file mode 100644
index 0000000..4d21a53
--- /dev/null
+++ b/src/translators/dataimporter.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef DATAIMPORTER_H
+#define DATAIMPORTER_H
+
+#include "importer.h"
+#include "../filehandler.h"
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ * @author Robby Stephenson
+ */
+class DataImporter : public Importer {
+Q_OBJECT
+
+public:
+ enum Source { URL, Text };
+
+ /**
+ * @param url The URL of the file to import
+ */
+// DataImporter(const KURL& url) : Importer(url), m_data(FileHandler::readDataFile(url)), m_source(URL) {}
+ DataImporter(const KURL& url) : Importer(url), m_source(URL) { m_fileRef = FileHandler::fileRef(url); }
+ /**
+ * Since the conversion to a QCString appends a \0 character at the end, remove it.
+ *
+ * @param text The text. It MUST be in UTF-8.
+ */
+ DataImporter(const QString& text) : Importer(text), m_data(text.utf8()), m_source(Text), m_fileRef(0)
+ { m_data.truncate(m_data.size()-1); }
+ /**
+ */
+ virtual ~DataImporter() { delete m_fileRef; m_fileRef = 0; }
+
+ Source source() const { return m_source; }
+
+ virtual void setText(const QString& text) {
+ Importer::setText(text); m_data = text.utf8(); m_data.truncate(m_data.size()-1); m_source = Text;
+ }
+
+protected:
+ /**
+ * Return the data in the imported file
+ *
+ * @return the file data
+ */
+ const QByteArray& data() const { return m_data; }
+ FileHandler::FileRef& fileRef() const { return *m_fileRef; }
+
+private:
+ QByteArray m_data;
+ Source m_source;
+ FileHandler::FileRef* m_fileRef;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/dcimporter.cpp b/src/translators/dcimporter.cpp
new file mode 100644
index 0000000..c8bb59f
--- /dev/null
+++ b/src/translators/dcimporter.cpp
@@ -0,0 +1,128 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "dcimporter.h"
+#include "../collections/bookcollection.h"
+#include "tellico_xml.h"
+#include "../tellico_debug.h"
+
+using Tellico::Import::DCImporter;
+
+DCImporter::DCImporter(const KURL& url_) : XMLImporter(url_) {
+}
+
+DCImporter::DCImporter(const QString& text_) : XMLImporter(text_) {
+}
+
+DCImporter::DCImporter(const QDomDocument& dom_) : XMLImporter(dom_) {
+}
+
+Tellico::Data::CollPtr DCImporter::collection() {
+ const QString& dc = XML::nsDublinCore;
+ const QString& zing = XML::nsZing;
+
+ Data::CollPtr c = new Data::BookCollection(true);
+
+ QDomDocument doc = domDocument();
+
+ QRegExp authorDateRX(QString::fromLatin1(",?(\\s+\\d{4}-?(?:\\d{4})?\\.?)(.*)$"));
+ QRegExp dateRX(QString::fromLatin1("\\d{4}"));
+
+ QDomNodeList recordList = doc.elementsByTagNameNS(zing, QString::fromLatin1("recordData"));
+ myDebug() << "DCImporter::collection() - number of records: " << recordList.count() << endl;
+
+ enum { UnknownNS, UseNS, NoNS } useNS = UnknownNS;
+
+#define GETELEMENTS(s) (useNS == NoNS) \
+ ? elem.elementsByTagName(QString::fromLatin1(s)) \
+ : elem.elementsByTagNameNS(dc, QString::fromLatin1(s))
+
+ for(uint i = 0; i < recordList.count(); ++i) {
+ Data::EntryPtr e = new Data::Entry(c);
+
+ QDomElement elem = recordList.item(i).toElement();
+
+ QDomNodeList nodeList = GETELEMENTS("title");
+ if(nodeList.count() == 0) { // no title, skip
+ if(useNS == UnknownNS) {
+ nodeList = elem.elementsByTagName(QString::fromLatin1("title"));
+ if(nodeList.count() > 0) {
+ useNS = NoNS;
+ } else {
+ myDebug() << "DCImporter::collection() - no title, skipping" << endl;
+ continue;
+ }
+ } else {
+ myDebug() << "DCImporter::collection() - no title, skipping" << endl;
+ continue;
+ }
+ } else if(useNS == UnknownNS) {
+ useNS = UseNS;
+ }
+ QString s = nodeList.item(0).toElement().text();
+ s.replace('\n', ' ');
+ s = s.simplifyWhiteSpace();
+ e->setField(QString::fromLatin1("title"), s);
+
+ nodeList = GETELEMENTS("creator");
+ QStringList creators;
+ for(uint j = 0; j < nodeList.count(); ++j) {
+ QString s = nodeList.item(j).toElement().text();
+ if(authorDateRX.search(s) > -1) {
+ // check if anything after date like [publisher]
+ if(authorDateRX.cap(2).stripWhiteSpace().isEmpty()) {
+ s.remove(authorDateRX);
+ s = s.simplifyWhiteSpace();
+ creators << s;
+ } else {
+ myDebug() << "DCImporter::collection() - weird creator, skipping: " << s << endl;
+ }
+ } else {
+ creators << s;
+ }
+ }
+ e->setField(QString::fromLatin1("author"), creators.join(QString::fromLatin1("; ")));
+
+ nodeList = GETELEMENTS("publisher");
+ QStringList publishers;
+ for(uint j = 0; j < nodeList.count(); ++j) {
+ publishers << nodeList.item(j).toElement().text();
+ }
+ e->setField(QString::fromLatin1("publisher"), publishers.join(QString::fromLatin1("; ")));
+
+ nodeList = GETELEMENTS("subject");
+ QStringList keywords;
+ for(uint j = 0; j < nodeList.count(); ++j) {
+ keywords << nodeList.item(j).toElement().text();
+ }
+ e->setField(QString::fromLatin1("keyword"), keywords.join(QString::fromLatin1("; ")));
+
+ nodeList = GETELEMENTS("date");
+ if(nodeList.count() > 0) {
+ QString s = nodeList.item(0).toElement().text();
+ if(dateRX.search(s) > -1) {
+ e->setField(QString::fromLatin1("pub_year"), dateRX.cap());
+ }
+ }
+
+ nodeList = GETELEMENTS("description");
+ if(nodeList.count() > 0) { // no title, skip
+ e->setField(QString::fromLatin1("comments"), nodeList.item(0).toElement().text());
+ }
+
+ c->addEntries(e);
+ }
+#undef GETELEMENTS
+
+ return c;
+}
diff --git a/src/translators/dcimporter.h b/src/translators/dcimporter.h
new file mode 100644
index 0000000..03eaedf
--- /dev/null
+++ b/src/translators/dcimporter.h
@@ -0,0 +1,34 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_IMPORT_DCIMPORTER_H
+#define TELLICO_IMPORT_DCIMPORTER_H
+
+#include "xmlimporter.h"
+
+namespace Tellico {
+ namespace Import {
+
+class DCImporter : public XMLImporter {
+public:
+ DCImporter(const KURL& url);
+ DCImporter(const QString& text);
+ DCImporter(const QDomDocument& dom);
+ ~DCImporter() {}
+
+ virtual Data::CollPtr collection();
+};
+
+ }
+}
+#endif
diff --git a/src/translators/deliciousimporter.cpp b/src/translators/deliciousimporter.cpp
new file mode 100644
index 0000000..5c434cd
--- /dev/null
+++ b/src/translators/deliciousimporter.cpp
@@ -0,0 +1,87 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "deliciousimporter.h"
+#include "../collection.h"
+#include "../rtf2html/rtf2html.h"
+#include "../imagefactory.h"
+#include "../tellico_debug.h"
+
+#include <kstandarddirs.h>
+
+#include <qfile.h>
+
+using Tellico::Import::DeliciousImporter;
+
+DeliciousImporter::DeliciousImporter(const KURL& url_) : XSLTImporter(url_) {
+ QString xsltFile = locate("appdata", QString::fromLatin1("delicious2tellico.xsl"));
+ if(!xsltFile.isEmpty()) {
+ KURL u;
+ u.setPath(xsltFile);
+ XSLTImporter::setXSLTURL(u);
+ } else {
+ kdWarning() << "DeliciousImporter() - unable to find delicious2tellico.xml!" << endl;
+ }
+}
+
+bool DeliciousImporter::canImport(int type) const {
+ return type == Data::Collection::Book;
+}
+
+Tellico::Data::CollPtr DeliciousImporter::collection() {
+ Data::CollPtr coll = XSLTImporter::collection();
+ if(!coll) {
+ return 0;
+ }
+
+ KURL libraryDir = url();
+ libraryDir.setPath(url().directory() + "Images/");
+ const QStringList imageDirs = QStringList()
+ << QString::fromLatin1("Large Covers/")
+ << QString::fromLatin1("Medium Covers/")
+ << QString::fromLatin1("Small Covers/")
+ << QString::fromLatin1("Plain Covers/");
+ const QString commField = QString::fromLatin1("comments");
+ const QString uuidField = QString::fromLatin1("uuid");
+ const QString coverField = QString::fromLatin1("cover");
+ const bool isLocal = url().isLocalFile();
+
+ Data::EntryVec entries = coll->entries();
+ for(Data::EntryVecIt entry = entries.begin(); entry != entries.end(); ++entry) {
+ QString comments = entry->field(commField);
+ if(!comments.isEmpty()) {
+ RTF2HTML rtf2html(comments);
+ entry->setField(commField, rtf2html.toHTML());
+ }
+
+ //try to add images
+ QString uuid = entry->field(uuidField);
+ if(!uuid.isEmpty() && isLocal) {
+ for(QStringList::ConstIterator it = imageDirs.begin(); it != imageDirs.end(); ++it) {
+ QString imgPath = libraryDir.path() + *it + uuid;
+ if(!QFile::exists(imgPath)) {
+ continue;
+ }
+ QString imgID = ImageFactory::addImage(imgPath, true);
+ if(!imgID.isEmpty()) {
+ entry->setField(coverField, imgID);
+ }
+ break;
+ }
+ }
+ }
+ coll->removeField(uuidField);
+ return coll;
+}
+
+#include "deliciousimporter.moc"
diff --git a/src/translators/deliciousimporter.h b/src/translators/deliciousimporter.h
new file mode 100644
index 0000000..657160e
--- /dev/null
+++ b/src/translators/deliciousimporter.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_IMPORT_DELICIOUSIMPORTER_H
+#define TELLICO_IMPORT_DELICIOUSIMPORTER_H
+
+#include "xsltimporter.h"
+#include "../datavectors.h"
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ * @author Robby Stephenson
+*/
+class DeliciousImporter : public XSLTImporter {
+Q_OBJECT
+
+public:
+ /**
+ */
+ DeliciousImporter(const KURL& url);
+
+ /**
+ */
+ virtual Data::CollPtr collection();
+ /**
+ */
+ virtual QWidget* widget(QWidget*, const char*) { return 0; }
+ virtual bool canImport(int type) const;
+
+private:
+ // private so it can't be changed accidently
+ void setXSLTURL(const KURL& url);
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/exporter.cpp b/src/translators/exporter.cpp
new file mode 100644
index 0000000..2fe78b7
--- /dev/null
+++ b/src/translators/exporter.cpp
@@ -0,0 +1,36 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "exporter.h"
+#include "../document.h"
+#include "../collection.h"
+
+using Tellico::Export::Exporter;
+
+Exporter::Exporter() : QObject(), m_options(Export::ExportUTF8 | Export::ExportComplete), m_coll(0) {
+}
+
+Exporter::Exporter(Data::CollPtr coll) : QObject(), m_options(Export::ExportUTF8), m_coll(coll) {
+}
+
+Exporter::~Exporter() {
+}
+
+Tellico::Data::CollPtr Exporter::collection() const {
+ if(m_coll) {
+ return m_coll;
+ }
+ return Data::Document::self()->collection();
+}
+
+#include "exporter.moc"
diff --git a/src/translators/exporter.h b/src/translators/exporter.h
new file mode 100644
index 0000000..2ffc13b
--- /dev/null
+++ b/src/translators/exporter.h
@@ -0,0 +1,89 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_EXPORTER_H
+#define TELLICO_EXPORTER_H
+
+class KConfig;
+
+class QWidget;
+class QString;
+
+#include "../entry.h"
+#include "../datavectors.h"
+
+#include <kurl.h>
+
+#include <qobject.h>
+
+namespace Tellico {
+ namespace Export {
+ enum Options {
+ ExportFormatted = 1 << 0, // format entries when exported
+ ExportUTF8 = 1 << 1, // valid for some text files, export as utf-8
+ ExportImages = 1 << 2, // should the images be included?
+ ExportForce = 1 << 3, // force the export, no confirmation of overwriting
+ ExportComplete = 1 << 4, // export complete document, including loans, etc.
+ ExportProgress = 1 << 5, // show progress bar
+ ExportClean = 1 << 6, // specifically for bibliographies, remove latex commands
+ ExportVerifyImages= 1 << 7, // don't put in an image link that's not in the cache
+ ExportImageSize = 1 << 8 // include image size in the generated XML
+ };
+
+/**
+ * @author Robby Stephenson
+ */
+class Exporter : public QObject {
+Q_OBJECT
+
+public:
+ Exporter();
+ Exporter(Data::CollPtr coll);
+ virtual ~Exporter();
+
+ Data::CollPtr collection() const;
+
+ void setURL(const KURL& url_) { m_url = url_; }
+ void setEntries(const Data::EntryVec& entries) { m_entries = entries; }
+ void setOptions(long options) { m_options = options; reset(); }
+
+ virtual QString formatString() const = 0;
+ virtual QString fileFilter() const = 0;
+ const KURL& url() const { return m_url; }
+ const Data::EntryVec& entries() const { return m_entries; }
+ long options() const { return m_options; }
+
+ /**
+ * Do the export
+ */
+ virtual bool exec() = 0;
+ /**
+ * If changing options in the exporter should cause member variables to reset, implement
+ * that here
+ */
+ virtual void reset() {}
+
+ virtual QWidget* widget(QWidget* parent, const char* name=0) = 0;
+ virtual void readOptions(KConfig*) {}
+ virtual void saveOptions(KConfig*) {}
+
+private:
+ long m_options;
+ Data::CollPtr m_coll;
+ Data::EntryVec m_entries;
+ KURL m_url;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/filelistingimporter.cpp b/src/translators/filelistingimporter.cpp
new file mode 100644
index 0000000..bef9288
--- /dev/null
+++ b/src/translators/filelistingimporter.cpp
@@ -0,0 +1,274 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "filelistingimporter.h"
+#include "../collections/filecatalog.h"
+#include "../entry.h"
+#include "../field.h"
+#include "../latin1literal.h"
+#include "../imagefactory.h"
+#include "../tellico_utils.h"
+#include "../tellico_kernel.h"
+#include "../progressmanager.h"
+#include "../core/netaccess.h"
+#include "../tellico_debug.h"
+
+#include <kapplication.h>
+#include <kmountpoint.h>
+#include <kio/job.h>
+#include <kio/netaccess.h>
+
+#include <qcheckbox.h>
+#include <qvgroupbox.h>
+#include <qlayout.h>
+#include <qwhatsthis.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+
+#include <stdio.h>
+
+namespace {
+ static const int FILE_PREVIEW_SIZE = 128;
+ // volume name starts at 16*2048+40 bytes into the header
+ static const int VOLUME_NAME_POS = 32808;
+ static const int VOLUME_NAME_SIZE = 32;
+}
+
+using Tellico::Import::FileListingImporter;
+
+FileListingImporter::FileListingImporter(const KURL& url_) : Importer(url_), m_coll(0), m_widget(0),
+ m_job(0), m_cancelled(false) {
+ m_files.setAutoDelete(true);
+}
+
+bool FileListingImporter::canImport(int type) const {
+ return type == Data::Collection::File;
+}
+
+Tellico::Data::CollPtr FileListingImporter::collection() {
+ if(m_coll) {
+ return m_coll;
+ }
+
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, i18n("Scanning files..."), true);
+ item.setTotalSteps(100);
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+ ProgressItem::Done done(this);
+
+ // going to assume only one volume will ever be imported
+ QString volume = volumeName();
+
+ m_job = m_recursive->isChecked()
+ ? KIO::listRecursive(url(), true, false)
+ : KIO::listDir(url(), true, false);
+ connect(m_job, SIGNAL(entries(KIO::Job*, const KIO::UDSEntryList&)),
+ SLOT(slotEntries(KIO::Job*, const KIO::UDSEntryList&)));
+
+ if(!KIO::NetAccess::synchronousRun(m_job, Kernel::self()->widget()) || m_cancelled) {
+ return 0;
+ }
+
+ const bool usePreview = m_filePreview->isChecked();
+
+ const QString title = QString::fromLatin1("title");
+ const QString url = QString::fromLatin1("url");
+ const QString desc = QString::fromLatin1("description");
+ const QString vol = QString::fromLatin1("volume");
+ const QString folder = QString::fromLatin1("folder");
+ const QString type = QString::fromLatin1("mimetype");
+ const QString size = QString::fromLatin1("size");
+ const QString perm = QString::fromLatin1("permissions");
+ const QString owner = QString::fromLatin1("owner");
+ const QString group = QString::fromLatin1("group");
+ const QString created = QString::fromLatin1("created");
+ const QString modified = QString::fromLatin1("modified");
+ const QString metainfo = QString::fromLatin1("metainfo");
+ const QString icon = QString::fromLatin1("icon");
+
+ m_coll = new Data::FileCatalog(true);
+ QString tmp;
+ const uint stepSize = QMAX(1, m_files.count()/100);
+ const bool showProgress = options() & ImportProgress;
+
+ item.setTotalSteps(m_files.count());
+ uint j = 0;
+ for(KFileItemListIterator it(m_files); !m_cancelled && it.current(); ++it, ++j) {
+ Data::EntryPtr entry = new Data::Entry(m_coll);
+
+ const KURL u = it.current()->url();
+ entry->setField(title, u.fileName());
+ entry->setField(url, u.url());
+ entry->setField(desc, it.current()->mimeComment());
+ entry->setField(vol, volume);
+ tmp = KURL::relativePath(this->url().path(), u.directory());
+ // remove "./" from the string
+ entry->setField(folder, tmp.right(tmp.length()-2));
+ entry->setField(type, it.current()->mimetype());
+ entry->setField(size, KIO::convertSize(it.current()->size()));
+ entry->setField(perm, it.current()->permissionsString());
+ entry->setField(owner, it.current()->user());
+ entry->setField(group, it.current()->group());
+
+ time_t t = it.current()->time(KIO::UDS_CREATION_TIME);
+ if(t > 0) {
+ QDateTime dt;
+ dt.setTime_t(t);
+ entry->setField(created, dt.toString(Qt::ISODate));
+ }
+ t = it.current()->time(KIO::UDS_MODIFICATION_TIME);
+ if(t > 0) {
+ QDateTime dt;
+ dt.setTime_t(t);
+ entry->setField(modified, dt.toString(Qt::ISODate));
+ }
+ const KFileMetaInfo& meta = it.current()->metaInfo();
+ if(meta.isValid() && !meta.isEmpty()) {
+ const QStringList keys = meta.supportedKeys();
+ QStringList strings;
+ for(QStringList::ConstIterator it2 = keys.begin(); it2 != keys.end(); ++it2) {
+ KFileMetaInfoItem item = meta.item(*it2);
+ if(item.isValid()) {
+ QString s = item.string();
+ if(!s.isEmpty()) {
+ strings << item.key() + "::" + s;
+ }
+ }
+ }
+ entry->setField(metainfo, strings.join(QString::fromLatin1("; ")));
+ }
+
+ if(!m_cancelled && usePreview) {
+ m_pixmap = NetAccess::filePreview(it.current(), FILE_PREVIEW_SIZE);
+ if(m_pixmap.isNull()) {
+ m_pixmap = it.current()->pixmap(0);
+ }
+ } else {
+ m_pixmap = it.current()->pixmap(0);
+ }
+
+ if(!m_pixmap.isNull()) {
+ // is png best option?
+ QString id = ImageFactory::addImage(m_pixmap, QString::fromLatin1("PNG"));
+ if(!id.isEmpty()) {
+ entry->setField(icon, id);
+ }
+ }
+
+ m_coll->addEntries(entry);
+
+ if(showProgress && j%stepSize == 0) {
+ ProgressManager::self()->setProgress(this, j);
+ kapp->processEvents();
+ }
+ }
+
+ if(m_cancelled) {
+ m_coll = 0;
+ return 0;
+ }
+
+ return m_coll;
+}
+
+QWidget* FileListingImporter::widget(QWidget* parent_, const char* name_) {
+ if(m_widget) {
+ return m_widget;
+ }
+
+ m_widget = new QWidget(parent_, name_);
+ QVBoxLayout* l = new QVBoxLayout(m_widget);
+
+ QVGroupBox* box = new QVGroupBox(i18n("File Listing Options"), m_widget);
+
+ m_recursive = new QCheckBox(i18n("Recursive folder search"), box);
+ QWhatsThis::add(m_recursive, i18n("If checked, folders are recursively searched for all files."));
+ // by default, make it checked
+ m_recursive->setChecked(true);
+
+ m_filePreview = new QCheckBox(i18n("Generate file previews"), box);
+ QWhatsThis::add(m_filePreview, i18n("If checked, previews of the file contents are generated, which can slow down "
+ "the folder listing."));
+ // by default, make it no previews
+ m_filePreview->setChecked(false);
+
+ l->addWidget(box);
+ l->addStretch(1);
+ return m_widget;
+}
+
+void FileListingImporter::slotEntries(KIO::Job* job_, const KIO::UDSEntryList& list_) {
+ if(m_cancelled) {
+ job_->kill();
+ m_job = 0;
+ return;
+ }
+
+ for(KIO::UDSEntryList::ConstIterator it = list_.begin(); it != list_.end(); ++it) {
+ KFileItem* item = new KFileItem(*it, url(), false, true);
+ if(item->isFile()) {
+ m_files.append(item);
+ } else {
+ delete item;
+ }
+ }
+}
+
+QString FileListingImporter::volumeName() const {
+ // this functions turns /media/cdrom into /dev/hdc, then reads 32 bytes after the 16 x 2048 header
+ QString volume;
+ const KMountPoint::List mountPoints = KMountPoint::currentMountPoints(KMountPoint::NeedRealDeviceName);
+ for(KMountPoint::List::ConstIterator it = mountPoints.begin(), end = mountPoints.end(); it != end; ++it) {
+ // path() could be /media/cdrom
+ // which could be the mount point of the device
+ // I know it works for iso9660 (cdrom) and udf (dvd)
+ if(url().path() == (*it)->mountPoint()
+ && ((*it)->mountType() == Latin1Literal("iso9660")
+ || (*it)->mountType() == Latin1Literal("udf"))) {
+ volume = (*it)->mountPoint();
+ if(!(*it)->realDeviceName().isEmpty()) {
+ QString devName = (*it)->realDeviceName();
+ if(devName.endsWith(QChar('/'))) {
+ devName.truncate(devName.length()-1);
+ }
+ // QFile can't do a sequential seek, and I don't want to do a 32808x loop on getch()
+ FILE* dev = 0;
+ if((dev = fopen(devName.latin1(), "rb")) != 0) {
+ // returns 0 on success
+ if(fseek(dev, VOLUME_NAME_POS, SEEK_SET) == 0) {
+ char buf[VOLUME_NAME_SIZE];
+ int ret = fread(buf, 1, VOLUME_NAME_SIZE, dev);
+ if(ret == VOLUME_NAME_SIZE) {
+ volume = QString::fromLatin1(buf, VOLUME_NAME_SIZE).stripWhiteSpace();
+ }
+ } else {
+ myDebug() << "FileListingImporter::volumeName() - can't seek " << devName << endl;
+ }
+ fclose(dev);
+ } else {
+ myDebug() << "FileListingImporter::volumeName() - can't read " << devName << endl;
+ }
+ }
+ break;
+ }
+ }
+ return volume;
+}
+
+void FileListingImporter::slotCancel() {
+ m_cancelled = true;
+ if(m_job) {
+ m_job->kill();
+ }
+}
+
+#include "filelistingimporter.moc"
diff --git a/src/translators/filelistingimporter.h b/src/translators/filelistingimporter.h
new file mode 100644
index 0000000..aca4602
--- /dev/null
+++ b/src/translators/filelistingimporter.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_IMPORT_FILELISTINGIMPORTER_H
+#define TELLICO_IMPORT_FILELISTINGIMPORTER_H
+
+#include "importer.h"
+#include "../datavectors.h"
+
+#include <kio/global.h>
+#include <kfileitem.h>
+
+#include <qguardedptr.h>
+
+class QCheckBox;
+namespace KIO {
+ class Job;
+}
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ * @author Robby Stephenson
+ */
+class FileListingImporter : public Importer {
+Q_OBJECT
+
+public:
+ FileListingImporter(const KURL& url);
+
+ /**
+ * @return A pointer to a @ref Data::Collection, or 0 if none can be created.
+ */
+ virtual Data::CollPtr collection();
+ /**
+ */
+ virtual QWidget* widget(QWidget*, const char*);
+ virtual bool canImport(int type) const;
+
+public slots:
+ void slotCancel();
+
+private slots:
+ void slotEntries(KIO::Job* job, const KIO::UDSEntryList& list);
+
+private:
+ QString volumeName() const;
+
+ Data::CollPtr m_coll;
+ QWidget* m_widget;
+ QCheckBox* m_recursive;
+ QCheckBox* m_filePreview;
+ QGuardedPtr<KIO::Job> m_job;
+ KFileItemList m_files;
+ QPixmap m_pixmap;
+ bool m_cancelled : 1;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/freedb_util.cpp b/src/translators/freedb_util.cpp
new file mode 100644
index 0000000..6640ef6
--- /dev/null
+++ b/src/translators/freedb_util.cpp
@@ -0,0 +1,376 @@
+/***************************************************************************
+ * *
+ * Modified from cd-discid.c, found at http://lly.org/~rcw/cd-discid/ *
+ * *
+ * Copyright (c) 1999-2003 Robert Woodcock <rcw@debian.org> *
+ * *
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "freedbimporter.h"
+#include "../tellico_debug.h"
+
+using Tellico::Import::FreeDBImporter;
+
+extern "C" {
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+/* Porting credits:
+ * Solaris: David Champion <dgc@uchicago.edu>
+ * FreeBSD: Niels Bakker <niels@bakker.net>
+ * OpenBSD: Marcus Daniel <danielm@uni-muenster.de>
+ * NetBSD: Chris Gilbert <chris@NetBSD.org>
+ * MacOSX: Evan Jones <ejones@uwaterloo.ca> http://www.eng.uwaterloo.ca/~ejones/
+ */
+
+#if defined(__linux__)
+
+// see http://bugs.kde.org/show_bug.cgi?id=86188
+#ifdef __STRICT_ANSI__
+#undef __STRICT_ANSI__
+#define _ANSI_WAS_HERE_
+#endif
+#include <linux/types.h>
+#include <linux/cdrom.h>
+#ifdef _ANSI_WAS_HERE_
+#define __STRICT_ANSI__
+#undef _ANSI_WAS_HERE_
+#endif
+#define cdte_track_address cdte_addr.lba
+
+#elif defined(sun) && defined(unix) && defined(__SVR4)
+
+#include <sys/cdio.h>
+#define CD_MSF_OFFSET 150
+#define CD_FRAMES 75
+/* According to David Schweikert <dws@ee.ethz.ch>, cd-discid needs this
+ * to compile on Solaris */
+#define cdte_track_address cdte_addr.lba
+
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+
+#include <netinet/in.h>
+#include <sys/cdio.h>
+#define CDROM_LBA CD_LBA_FORMAT /* first frame is 0 */
+#define CD_MSF_OFFSET 150 /* MSF offset of first frame */
+#define CD_FRAMES 75 /* per second */
+#define CDROM_LEADOUT 0xAA /* leadout track */
+#define CDROMREADTOCHDR CDIOREADTOCHEADER
+#define CDROMREADTOCENTRY CDIOREADTOCENTRY
+#define cdrom_tochdr ioc_toc_header
+#define cdth_trk0 starting_track
+#define cdth_trk1 ending_track
+#define cdrom_tocentry ioc_read_toc_single_entry
+#define cdte_track track
+#define cdte_format address_format
+#define cdte_track_address entry.addr.lba
+
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
+
+#include <netinet/in.h>
+#include <sys/cdio.h>
+#define CDROM_LBA CD_LBA_FORMAT /* first frame is 0 */
+#define CD_MSF_OFFSET 150 /* MSF offset of first frame */
+#define CD_FRAMES 75 /* per second */
+#define CDROM_LEADOUT 0xAA /* leadout track */
+#define CDROMREADTOCHDR CDIOREADTOCHEADER
+#define cdrom_tochdr ioc_toc_header
+#define cdth_trk0 starting_track
+#define cdth_trk1 ending_track
+#define cdrom_tocentry cd_toc_entry
+#define cdte_track track
+#define cdte_track_address addr.lba
+
+#elif defined(__APPLE__)
+
+#include <sys/types.h>
+#include <IOKit/storage/IOCDTypes.h>
+#include <IOKit/storage/IOCDMediaBSDClient.h>
+#define CD_FRAMES 75 /* per second */
+#define CD_MSF_OFFSET 150 /* MSF offset of first frame */
+#define cdrom_tochdr CDDiscInfo
+#define cdth_trk0 numberOfFirstTrack
+/* NOTE: Judging by the name here, we might have to do this:
+ * hdr.lastTrackNumberInLastSessionMSB << 8 *
+ * sizeof(hdr.lastTrackNumberInLastSessionLSB)
+ * | hdr.lastTrackNumberInLastSessionLSB; */
+#define cdth_trk1 lastTrackNumberInLastSessionLSB
+#define cdrom_tocentry CDTrackInfo
+#define cdte_track_address trackStartAddress
+
+#else
+# warning "Your OS isn't supported yet for CDDB lookup."
+#endif /* os selection */
+
+}
+
+#include <config.h>
+
+namespace {
+ class CloseDrive {
+ public:
+ CloseDrive(int d) : drive(d) {}
+ ~CloseDrive() { ::close(drive); }
+ private:
+ int drive;
+ };
+}
+
+QValueList<uint> FreeDBImporter::offsetList(const QCString& drive_, QValueList<uint>& trackLengths_) {
+ QValueList<uint> list;
+
+ int drive = ::open(drive_.data(), O_RDONLY | O_NONBLOCK);
+ CloseDrive closer(drive);
+ if(drive < 0) {
+ return list;
+ }
+
+ cdrom_tochdr hdr;
+#if defined(__APPLE__)
+ dk_cd_read_disc_info_t discInfoParams;
+ ::memset(&discInfoParams, 0, sizeof(discInfoParams));
+ discInfoParams.buffer = &hdr;
+ discInfoParams.bufferLength = sizeof(hdr);
+ if(ioctl(drive, DKIOCCDREADDISCINFO, &discInfoParams) < 0
+ || discInfoParams.bufferLength != sizeof(hdr)) {
+ return list;
+ }
+#else
+ if(ioctl(drive, CDROMREADTOCHDR, &hdr) < 0) {
+ return list;
+ }
+#endif
+
+// uchar first = hdr.cdth_trk0;
+ uchar last = hdr.cdth_trk1;
+
+ cdrom_tocentry* TocEntry = new cdrom_tocentry[last+1];
+#if defined(__OpenBSD__)
+ ioc_read_toc_entry t;
+ t.starting_track = 0;
+#elif defined(__NetBSD__)
+ ioc_read_toc_entry t;
+ t.starting_track = 1;
+#endif
+#if defined(__OpenBSD__) || defined(__NetBSD__)
+ t.address_format = CDROM_LBA;
+ t.data_len = (last + 1) * sizeof(cdrom_tocentry);
+ t.data = TocEntry;
+
+ if (::ioctl(drive, CDIOREADTOCENTRYS, (char *) &t) < 0)
+ return list;
+
+#elif defined(__APPLE__)
+ dk_cd_read_track_info_t trackInfoParams;
+ ::memset(&trackInfoParams, 0, sizeof(trackInfoParams));
+ trackInfoParams.addressType = kCDTrackInfoAddressTypeTrackNumber;
+ trackInfoParams.bufferLength = sizeof(*TocEntry);
+
+ for(int i = 0; i < last; ++i) {
+ trackInfoParams.address = i + 1;
+ trackInfoParams.buffer = &TocEntry[i];
+ ::ioctl(drive, DKIOCCDREADTRACKINFO, &trackInfoParams);
+ }
+
+ /* MacOS X on G5-based systems does not report valid info for
+ * TocEntry[last-1].lastRecordedAddress + 1, so we compute the start
+ * of leadout from the start+length of the last track instead
+ */
+ TocEntry[last].cdte_track_address = TocEntry[last-1].trackSize + TocEntry[last-1].trackStartAddress;
+#else /* FreeBSD, Linux, Solaris */
+ for(uint i = 0; i < last; ++i) {
+ /* tracks start with 1, but I must start with 0 on OpenBSD */
+ TocEntry[i].cdte_track = i + 1;
+ TocEntry[i].cdte_format = CDROM_LBA;
+ ::ioctl(drive, CDROMREADTOCENTRY, &TocEntry[i]);
+ }
+
+ TocEntry[last].cdte_track = CDROM_LEADOUT;
+ TocEntry[last].cdte_format = CDROM_LBA;
+ ::ioctl(drive, CDROMREADTOCENTRY, &TocEntry[last]);
+#endif
+
+#if defined(__FreeBSD__)
+ TocEntry[last].cdte_track_address = ntohl(TocEntry[last].cdte_track_address);
+#endif
+
+ for(uint i = 0; i < last; ++i) {
+#if defined(__FreeBSD__)
+ TocEntry[i].cdte_track_address = ntohl(TocEntry[i].cdte_track_address);
+#endif
+ list.append(TocEntry[i].cdte_track_address + CD_MSF_OFFSET);
+ }
+
+ list.append(TocEntry[0].cdte_track_address + CD_MSF_OFFSET);
+ list.append(TocEntry[last].cdte_track_address + CD_MSF_OFFSET);
+
+ // hey, these are track lengths! :P
+ trackLengths_.clear();
+ for(uint i = 0; i < last; ++i) {
+ trackLengths_.append((TocEntry[i+1].cdte_track_address - TocEntry[i].cdte_track_address) / CD_FRAMES);
+ }
+
+ delete[] TocEntry;
+ return list;
+}
+
+inline
+ushort from2Byte(uchar* d) {
+ return (d[0] << 8 & 0xFF00) | (d[1] & 0xFF);
+}
+
+#define SIZE 61
+// mostly taken from kover and k3b
+// licensed under GPL
+FreeDBImporter::CDText FreeDBImporter::getCDText(const QCString& drive_) {
+ CDText cdtext;
+#ifdef USE_CDTEXT
+// only works for linux ATM
+#if defined(__linux__)
+ int drive = ::open(drive_.data(), O_RDONLY | O_NONBLOCK);
+ CloseDrive closer(drive);
+ if(drive < 0) {
+ return cdtext;
+ }
+
+ cdrom_generic_command m_cmd;
+ ::memset(&m_cmd, 0, sizeof(cdrom_generic_command));
+
+ int dataLen;
+
+ int format = 5;
+ uint track = 0;
+ uchar buffer[2048];
+
+ m_cmd.cmd[0] = 0x43;
+ m_cmd.cmd[1] = 0x0;
+ m_cmd.cmd[2] = format & 0x0F;
+ m_cmd.cmd[6] = track;
+ m_cmd.cmd[8] = 2; // we only read the length first
+
+ m_cmd.buffer = buffer;
+ m_cmd.buflen = 2;
+ m_cmd.data_direction = CGC_DATA_READ;
+
+ if(ioctl(drive, CDROM_SEND_PACKET, &m_cmd) != 0) {
+ myDebug() << "FreeDBImporter::getCDText() - access error" << endl;
+ return cdtext;
+ }
+
+ dataLen = from2Byte(buffer) + 2;
+ m_cmd.cmd[7] = 2048 >> 8;
+ m_cmd.cmd[8] = 2048 & 0xFF;
+ m_cmd.buflen = 2048;
+ ::ioctl(drive, CDROM_SEND_PACKET, &m_cmd);
+ dataLen = from2Byte(buffer) + 2;
+
+ ::memset(buffer, 0, dataLen);
+
+ m_cmd.cmd[7] = dataLen >> 8;
+ m_cmd.cmd[8] = dataLen;
+ m_cmd.buffer = buffer;
+ m_cmd.buflen = dataLen;
+ ::ioctl(drive, CDROM_SEND_PACKET, &m_cmd);
+
+ bool rc = false;
+ int buffer_size = (buffer[0] << 8) | buffer[1];
+ buffer_size -= 2;
+
+ char data[SIZE];
+ short pos_data = 0;
+ char old_block_no = 0xff;
+ for(uchar* bufptr = buffer + 4; buffer_size >= 18; bufptr += 18, buffer_size -= 18) {
+ char code = *bufptr;
+
+ if((code & 0x80) != 0x80) {
+ continue;
+ }
+
+ char block_no = *(bufptr + 3);
+ if(block_no & 0x80) {
+ myDebug() << "FreeDBImporter::readCDText() - double byte code not supported" << endl;
+ continue;
+ }
+ block_no &= 0x70;
+
+ if(block_no != old_block_no) {
+ if(rc) {
+ break;
+ }
+ pos_data = 0;
+ old_block_no = block_no;
+ }
+
+ track = *(bufptr + 1);
+ if(track & 0x80) {
+ continue;
+ }
+
+ uchar* txtstr = bufptr + 4;
+
+ int length = 11;
+ while(length >= 0 && *(txtstr + length) == '\0') {
+ --length;
+ }
+
+ ++length;
+ if(length < 12) {
+ ++length;
+ }
+
+ for(int j = 0; j < length; ++j) {
+ char c = *(txtstr + j);
+ if(c == '\0') {
+ data[pos_data] = c;
+ if(track == 0) {
+ if(code == (char)0xFFFFFF80) {
+ cdtext.title = QString::fromUtf8(data);
+ } else if(code == (char)0xFFFFFF81) {
+ cdtext.artist = QString::fromUtf8(data);
+ } else if (code == (char)0xFFFFFF85) {
+ cdtext.message = QString::fromUtf8(data);
+ }
+ } else {
+ if(code == (char)0xFFFFFF80) {
+ if(cdtext.trackTitles.size() < track) {
+ cdtext.trackTitles.resize(track);
+ }
+ cdtext.trackTitles[track-1] = QString::fromUtf8(data);
+ } else if(code == (char)0xFFFFFF81) {
+ if(cdtext.trackArtists.size() < track) {
+ cdtext.trackArtists.resize(track);
+ }
+ cdtext.trackArtists[track-1] = QString::fromUtf8(data);
+ }
+ }
+ rc = true;
+ pos_data = 0;
+ ++track;
+ } else if(pos_data < (SIZE - 1)) {
+ data[pos_data++] = c;
+ }
+ }
+ }
+ if(cdtext.trackTitles.size() != cdtext.trackArtists.size()) {
+ int size = QMAX(cdtext.trackTitles.size(), cdtext.trackArtists.size());
+ cdtext.trackTitles.resize(size);
+ cdtext.trackArtists.resize(size);
+ }
+#endif
+#endif
+ return cdtext;
+}
+#undef SIZE
diff --git a/src/translators/freedbimporter.cpp b/src/translators/freedbimporter.cpp
new file mode 100644
index 0000000..14d92d8
--- /dev/null
+++ b/src/translators/freedbimporter.cpp
@@ -0,0 +1,556 @@
+/***************************************************************************
+ copyright : (C) 2004-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "freedbimporter.h"
+#include "../collections/musiccollection.h"
+#include "../entry.h"
+#include "../field.h"
+#include "../latin1literal.h"
+#include "../tellico_utils.h"
+#include "../tellico_debug.h"
+#include "../tellico_kernel.h"
+#include "../progressmanager.h"
+
+#include <config.h>
+
+#ifdef HAVE_KCDDB
+#ifdef QT_NO_CAST_ASCII
+#define HAD_QT_NO_CAST_ASCII
+#undef QT_NO_CAST_ASCII
+#endif
+#include <libkcddb/client.h>
+#ifdef HAD_QT_NO_CAST_ASCII
+#define QT_NO_CAST_ASCII
+#undef HAD_QT_NO_CAST_ASCII
+#endif
+#endif
+
+#include <kcombobox.h>
+#include <kconfig.h>
+#include <kapplication.h>
+#include <kinputdialog.h>
+
+#include <qfile.h>
+#include <qdir.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qwhatsthis.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include <qhbox.h>
+#include <qcheckbox.h>
+
+using Tellico::Import::FreeDBImporter;
+
+FreeDBImporter::FreeDBImporter() : Tellico::Import::Importer(), m_coll(0), m_widget(0), m_cancelled(false) {
+}
+
+bool FreeDBImporter::canImport(int type) const {
+ return type == Data::Collection::Album;
+}
+
+Tellico::Data::CollPtr FreeDBImporter::collection() {
+ if(m_coll) {
+ return m_coll;
+ }
+
+ m_cancelled = false;
+ if(m_radioCDROM->isChecked()) {
+ readCDROM();
+ } else {
+ readCache();
+ }
+ if(m_cancelled) {
+ m_coll = 0;
+ }
+ return m_coll;
+}
+
+void FreeDBImporter::readCDROM() {
+#ifdef HAVE_KCDDB
+ QString drivePath = m_driveCombo->currentText();
+ if(drivePath.isEmpty()) {
+ setStatusMessage(i18n("<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>").arg(drivePath));
+ myDebug() << "FreeDBImporter::readCDROM() - no drive!" << endl;
+ return;
+ }
+
+ // now it's ok to add device to saved list
+ m_driveCombo->insertItem(drivePath);
+ QStringList drives;
+ for(int i = 0; i < m_driveCombo->count(); ++i) {
+ if(drives.findIndex(m_driveCombo->text(i)) == -1) {
+ drives += m_driveCombo->text(i);
+ }
+ }
+
+ {
+ KConfigGroup config(KGlobal::config(), QString::fromLatin1("ImportOptions - FreeDB"));
+ config.writeEntry("CD-ROM Devices", drives);
+ config.writeEntry("Last Device", drivePath);
+ config.writeEntry("Cache Files Only", false);
+ }
+
+ QCString drive = QFile::encodeName(drivePath);
+ QValueList<uint> lengths;
+ KCDDB::TrackOffsetList list;
+#if 0
+ // a1107d0a - Kruder & Dorfmeister - The K&D Sessions - Disc One.
+/* list
+ << 150 // First track start.
+ << 29462
+ << 66983
+ << 96785
+ << 135628
+ << 168676
+ << 194147
+ << 222158
+ << 247076
+ << 278203 // Last track start.
+ << 10 // Disc start.
+ << 316732; // Disc end.
+*/
+ list
+ << 150 // First track start.
+ << 3296
+ << 14437
+ << 41279
+ << 51362
+ << 56253
+ << 59755
+ << 61324
+ << 66059
+ << 69073
+ << 77790
+ << 83214
+ << 89726
+ << 92078
+ << 106325
+ << 113117
+ << 116040
+ << 119877
+ << 124377
+ << 145466
+ << 157583
+ << 167208
+ << 173486
+ << 180120
+ << 185279
+ << 193270
+ << 206451
+ << 217303 // Last track start.
+ << 10 // Disc start.
+ << 224925; // Disc end.
+/*
+ list
+ << 150
+ << 106965
+ << 127220
+ << 151925
+ << 176085
+ << 5
+ << 234500;
+*/
+#else
+ list = offsetList(drive, lengths);
+#endif
+
+ if(list.isEmpty()) {
+ setStatusMessage(i18n("<qt>Tellico was unable to access the CD-ROM device - <i>%1</i>.</qt>").arg(drivePath));
+ return;
+ }
+// myDebug() << KCDDB::CDDB::trackOffsetListToId(list) << endl;
+// for(KCDDB::TrackOffsetList::iterator it = list.begin(); it != list.end(); ++it) {
+// myDebug() << *it << endl;
+// }
+
+ // the result info, could be multiple ones
+ KCDDB::CDInfo info;
+ KCDDB::Client client;
+ client.setBlockingMode(true);
+ KCDDB::CDDB::Result r = client.lookup(list);
+ // KCDDB doesn't return MultipleRecordFound properly, so check outselves
+ if(r == KCDDB::CDDB::MultipleRecordFound || client.lookupResponse().count() > 1) {
+ QStringList list;
+ KCDDB::CDInfoList infoList = client.lookupResponse();
+ for(KCDDB::CDInfoList::iterator it = infoList.begin(); it != infoList.end(); ++it) {
+ list.append(QString::fromLatin1("%1, %2, %3").arg((*it).artist)
+ .arg((*it).title)
+ .arg((*it).genre));
+ }
+
+ // switch back to pointer cursor
+ GUI::CursorSaver cs(Qt::arrowCursor);
+ bool ok;
+ QString res = KInputDialog::getItem(i18n("Select CDDB Entry"),
+ i18n("Select a CDDB entry:"),
+ list, 0, false, &ok,
+ Kernel::self()->widget());
+ if(ok) {
+ uint i = 0;
+ for(QStringList::ConstIterator it = list.begin(); it != list.end(); ++it, ++i) {
+ if(*it == res) {
+ break;
+ }
+ }
+ if(i < infoList.size()) {
+ info = infoList[i];
+ }
+ } else { // cancelled dialog
+ m_cancelled = true;
+ }
+ } else if(r == KCDDB::CDDB::Success) {
+ info = client.bestLookupResponse();
+ } else {
+// myDebug() << "FreeDBImporter::readCDROM() - no success! Return value = " << r << endl;
+ QString s;
+ switch(r) {
+ case KCDDB::CDDB::NoRecordFound:
+ s = i18n("<qt>No records were found to match the CD.</qt>");
+ break;
+ case KCDDB::CDDB::ServerError:
+ myDebug() << "Server Error" << endl;
+ break;
+ case KCDDB::CDDB::HostNotFound:
+ myDebug() << "Host Not Found" << endl;
+ break;
+ case KCDDB::CDDB::NoResponse:
+ myDebug() << "No Response" << endl;
+ break;
+ case KCDDB::CDDB::UnknownError:
+ myDebug() << "Unknown Error" << endl;
+ break;
+ default:
+ break;
+ }
+ if(s.isEmpty()) {
+ s = i18n("<qt>Tellico was unable to complete the CD lookup.</qt>");
+ }
+ setStatusMessage(s);
+ return;
+ }
+
+ if(!info.isValid()) {
+ // go ahead and try to read cd-text if we weren't cancelled
+ // could be the case we don't have net access
+ if(!m_cancelled) {
+ readCDText(drive);
+ }
+ return;
+ }
+
+ m_coll = new Data::MusicCollection(true);
+
+ Data::EntryPtr entry = new Data::Entry(m_coll);
+ // obviously a CD
+ entry->setField(QString::fromLatin1("medium"), i18n("Compact Disc"));
+ entry->setField(QString::fromLatin1("title"), info.title);
+ entry->setField(QString::fromLatin1("artist"), info.artist);
+ entry->setField(QString::fromLatin1("genre"), info.genre);
+ if(info.year > 0) {
+ entry->setField(QString::fromLatin1("year"), QString::number(info.year));
+ }
+ entry->setField(QString::fromLatin1("keyword"), info.category);
+ QString extd = info.extd;
+ extd.replace('\n', QString::fromLatin1("<br/>"));
+ entry->setField(QString::fromLatin1("comments"), extd);
+
+ QStringList trackList;
+ KCDDB::TrackInfoList t = info.trackInfoList;
+ for(uint i = 0; i < t.count(); ++i) {
+#if KDE_IS_VERSION(3,4,90)
+ QString s = t[i].get(QString::fromLatin1("title")).toString() + "::" + info.artist;
+#else
+ QString s = t[i].title + "::" + info.artist;
+#endif
+ if(i < lengths.count()) {
+ s += "::" + Tellico::minutes(lengths[i]);
+ }
+ trackList << s;
+ // TODO: KDE4 will probably have track length too
+ }
+ entry->setField(QString::fromLatin1("track"), trackList.join(QString::fromLatin1("; ")));
+
+ m_coll->addEntries(entry);
+ readCDText(drive);
+#endif
+}
+
+void FreeDBImporter::readCache() {
+#ifdef HAVE_KCDDB
+ {
+ // remember the import options
+ KConfigGroup config(KGlobal::config(), QString::fromLatin1("ImportOptions - FreeDB"));
+ config.writeEntry("Cache Files Only", true);
+ }
+
+ KCDDB::Config cfg;
+ cfg.readConfig();
+
+ QStringList dirs = cfg.cacheLocations();
+ for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) {
+ dirs += Tellico::findAllSubDirs(*it);
+ }
+
+ // using a QMap is a lazy man's way of getting unique keys
+ // the cddb info may be in multiple files, all with the same filename, the cddb id
+ QMap<QString, QString> files;
+ for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) {
+ if((*it).isEmpty()) {
+ continue;
+ }
+
+ QDir dir(*it);
+ dir.setFilter(QDir::Files | QDir::Readable | QDir::Hidden); // hidden since I want directory files
+ const QStringList list = dir.entryList();
+ for(QStringList::ConstIterator it2 = list.begin(); it2 != list.end(); ++it2) {
+ files.insert(*it2, dir.absFilePath(*it2), false);
+ }
+// kapp->processEvents(); // really needed ?
+ }
+
+ const QString title = QString::fromLatin1("title");
+ const QString artist = QString::fromLatin1("artist");
+ const QString year = QString::fromLatin1("year");
+ const QString genre = QString::fromLatin1("genre");
+ const QString track = QString::fromLatin1("track");
+ const QString comments = QString::fromLatin1("comments");
+ uint numFiles = files.count();
+
+ if(numFiles == 0) {
+ myDebug() << "FreeDBImporter::readCache() - no files found" << endl;
+ return;
+ }
+
+ m_coll = new Data::MusicCollection(true);
+
+ const uint stepSize = QMAX(1, numFiles / 100);
+ const bool showProgress = options() & ImportProgress;
+
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, progressLabel(), true);
+ item.setTotalSteps(numFiles);
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+ ProgressItem::Done done(this);
+
+ uint step = 1;
+
+ KCDDB::CDInfo info;
+ for(QMap<QString, QString>::Iterator it = files.begin(); !m_cancelled && it != files.end(); ++it, ++step) {
+ // open file and read content
+ QFileInfo fileinfo(it.data()); // skip files larger than 10 kB
+ if(!fileinfo.exists() || !fileinfo.isReadable() || fileinfo.size() > 10*1024) {
+ myDebug() << "FreeDBImporter::readCache() - skipping " << it.data() << endl;
+ continue;
+ }
+ QFile file(it.data());
+ if(!file.open(IO_ReadOnly)) {
+ continue;
+ }
+ QTextStream ts(&file);
+ // libkcddb always writes the cache files in utf-8
+ ts.setEncoding(QTextStream::UnicodeUTF8);
+ QString cddbData = ts.read();
+ file.close();
+
+ if(cddbData.isEmpty() || !info.load(cddbData) || !info.isValid()) {
+ myDebug() << "FreeDBImporter::readCache() - Error - CDDB record is not valid" << endl;
+ myDebug() << "FreeDBImporter::readCache() - File = " << it.data() << endl;
+ continue;
+ }
+
+ // create a new entry and set fields
+ Data::EntryPtr entry = new Data::Entry(m_coll);
+ // obviously a CD
+ entry->setField(QString::fromLatin1("medium"), i18n("Compact Disc"));
+ entry->setField(title, info.title);
+ entry->setField(artist, info.artist);
+ entry->setField(genre, info.genre);
+ if(info.year > 0) {
+ entry->setField(QString::fromLatin1("year"), QString::number(info.year));
+ }
+ entry->setField(QString::fromLatin1("keyword"), info.category);
+ QString extd = info.extd;
+ extd.replace('\n', QString::fromLatin1("<br/>"));
+ entry->setField(QString::fromLatin1("comments"), extd);
+
+ // step through trackList
+ QStringList trackList;
+ KCDDB::TrackInfoList t = info.trackInfoList;
+ for(uint i = 0; i < t.count(); ++i) {
+#if KDE_IS_VERSION(3,4,90)
+ trackList << t[i].get(QString::fromLatin1("title")).toString();
+#else
+ trackList << t[i].title;
+#endif
+ }
+ entry->setField(track, trackList.join(QString::fromLatin1("; ")));
+
+#if 0
+ // add CDDB info
+ const QString br = QString::fromLatin1("<br/>");
+ QString comment;
+ if(!info.extd.isEmpty()) {
+ comment.append(info.extd + br);
+ }
+ if(!info.id.isEmpty()) {
+ comment.append(QString::fromLatin1("CDDB-ID: ") + info.id + br);
+ }
+ if(info.length > 0) {
+ comment.append("Length: " + QString::number(info.length) + br);
+ }
+ if(info.revision > 0) {
+ comment.append("Revision: " + QString::number(info.revision) + br);
+ }
+ entry->setField(comments, comment);
+#endif
+
+ // add this entry to the music collection
+ m_coll->addEntries(entry);
+
+ if(showProgress && step%stepSize == 0) {
+ ProgressManager::self()->setProgress(this, step);
+ kapp->processEvents();
+ }
+ }
+#endif
+}
+
+#define SETFIELD(name,value) \
+ if(entry->field(QString::fromLatin1(name)).isEmpty()) { \
+ entry->setField(QString::fromLatin1(name), value); \
+ }
+
+void FreeDBImporter::readCDText(const QCString& drive_) {
+#ifdef USE_CDTEXT
+ Data::EntryPtr entry;
+ if(m_coll) {
+ if(m_coll->entryCount() > 0) {
+ entry = m_coll->entries().front();
+ }
+ } else {
+ m_coll = new Data::MusicCollection(true);
+ }
+ if(!entry) {
+ entry = new Data::Entry(m_coll);
+ entry->setField(QString::fromLatin1("medium"), i18n("Compact Disc"));
+ m_coll->addEntries(entry);
+ }
+
+ CDText cdtext = getCDText(drive_);
+/*
+ myDebug() << "CDText - title: " << cdtext.title << endl;
+ myDebug() << "CDText - title: " << cdtext.artist << endl;
+ for(int i = 0; i < cdtext.trackTitles.size(); ++i) {
+ myDebug() << i << "::" << cdtext.trackTitles[i] << " - " << cdtext.trackArtists[i] << endl;
+ }
+*/
+
+ QString artist = cdtext.artist;
+ SETFIELD("title", cdtext.title);
+ SETFIELD("artist", artist);
+ SETFIELD("comments", cdtext.message);
+ QStringList tracks;
+ for(uint i = 0; i < cdtext.trackTitles.size(); ++i) {
+ tracks << cdtext.trackTitles[i] + "::" + cdtext.trackArtists[i];
+ if(artist.isEmpty()) {
+ artist = cdtext.trackArtists[i];
+ }
+ if(!artist.isEmpty() && artist.lower() != cdtext.trackArtists[i].lower()) {
+ artist = i18n("Various");
+ }
+ }
+ SETFIELD("track", tracks.join(QString::fromLatin1("; ")));
+
+ // something special for compilations and such
+ SETFIELD("title", i18n(Data::Collection::s_emptyGroupTitle));
+ SETFIELD("artist", artist);
+#endif
+}
+#undef SETFIELD
+
+QWidget* FreeDBImporter::widget(QWidget* parent_, const char* name_/*=0*/) {
+ if(m_widget) {
+ return m_widget;
+ }
+ m_widget = new QWidget(parent_, name_);
+ QVBoxLayout* l = new QVBoxLayout(m_widget);
+
+ QGroupBox* bigbox = new QGroupBox(1, Qt::Horizontal, i18n("Audio CD Options"), m_widget);
+
+ // cdrom stuff
+ QHBox* box = new QHBox(bigbox);
+ m_radioCDROM = new QRadioButton(i18n("Read data from CD-ROM device"), box);
+ m_driveCombo = new KComboBox(true, box);
+ m_driveCombo->setDuplicatesEnabled(false);
+ QString w = i18n("Select or input the CD-ROM device location.");
+ QWhatsThis::add(m_radioCDROM, w);
+ QWhatsThis::add(m_driveCombo, w);
+
+ /********************************************************************************/
+
+ m_radioCache = new QRadioButton(i18n("Read all CDDB cache files only"), bigbox);
+ QWhatsThis::add(m_radioCache, i18n("Read data recursively from all the CDDB cache files "
+ "contained in the default cache folders."));
+
+ // cddb cache stuff
+ m_buttonGroup = new QButtonGroup(m_widget);
+ m_buttonGroup->hide(); // only use as button parent
+ m_buttonGroup->setExclusive(true);
+ m_buttonGroup->insert(m_radioCDROM);
+ m_buttonGroup->insert(m_radioCache);
+ connect(m_buttonGroup, SIGNAL(clicked(int)), SLOT(slotClicked(int)));
+
+ l->addWidget(bigbox);
+ l->addStretch(1);
+
+ // now read config options
+ KConfigGroup config(KGlobal::config(), QString::fromLatin1("ImportOptions - FreeDB"));
+ QStringList devices = config.readListEntry("CD-ROM Devices");
+ if(devices.isEmpty()) {
+#if defined(__OpenBSD__)
+ devices += QString::fromLatin1("/dev/rcd0c");
+#endif
+ devices += QString::fromLatin1("/dev/cdrom");
+ devices += QString::fromLatin1("/dev/dvd");
+ }
+ m_driveCombo->insertStringList(devices);
+ QString device = config.readEntry("Last Device");
+ if(!device.isEmpty()) {
+ m_driveCombo->setCurrentText(device);
+ }
+ if(config.readBoolEntry("Cache Files Only", false)) {
+ m_radioCache->setChecked(true);
+ } else {
+ m_radioCDROM->setChecked(true);
+ }
+ // set enabled widgets
+ slotClicked(m_buttonGroup->selectedId());
+
+ return m_widget;
+}
+
+void FreeDBImporter::slotClicked(int id_) {
+ QButton* button = m_buttonGroup->find(id_);
+ if(!button) {
+ return;
+ }
+
+ m_driveCombo->setEnabled(button == m_radioCDROM);
+}
+
+void FreeDBImporter::slotCancel() {
+ m_cancelled = true;
+}
+
+#include "freedbimporter.moc"
diff --git a/src/translators/freedbimporter.h b/src/translators/freedbimporter.h
new file mode 100644
index 0000000..263f89d
--- /dev/null
+++ b/src/translators/freedbimporter.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+ copyright : (C) 2004-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef FREEDBIMPORTER_H
+#define FREEDBIMPORTER_H
+
+#include "importer.h"
+#include "../datavectors.h"
+
+#include <qvaluevector.h>
+
+class QButtonGroup;
+class QRadioButton;
+class KComboBox;
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ * The FreeDBImporter class takes care of importing audio files.
+ *
+ * @author Robby Stephenson
+ */
+class FreeDBImporter : public Importer {
+Q_OBJECT
+
+public:
+ /**
+ */
+ FreeDBImporter();
+
+ /**
+ */
+ virtual Data::CollPtr collection();
+ /**
+ */
+ virtual QWidget* widget(QWidget* parent, const char* name=0);
+ virtual bool canImport(int type) const;
+
+public slots:
+ void slotCancel();
+
+private slots:
+ void slotClicked(int id);
+
+private:
+ typedef QValueVector<QString> StringVector;
+ struct CDText {
+ friend class FreeDBImporter;
+ QString title;
+ QString artist;
+ QString message;
+ StringVector trackTitles;
+ StringVector trackArtists;
+ };
+
+ static QValueList<uint> offsetList(const QCString& drive, QValueList<uint>& trackLengths);
+ static CDText getCDText(const QCString& drive);
+
+ void readCDROM();
+ void readCache();
+ void readCDText(const QCString& drive);
+
+ Data::CollPtr m_coll;
+ QWidget* m_widget;
+ QButtonGroup* m_buttonGroup;
+ QRadioButton* m_radioCDROM;
+ QRadioButton* m_radioCache;
+ KComboBox* m_driveCombo;
+ bool m_cancelled : 1;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/gcfilmsexporter.cpp b/src/translators/gcfilmsexporter.cpp
new file mode 100644
index 0000000..b172996
--- /dev/null
+++ b/src/translators/gcfilmsexporter.cpp
@@ -0,0 +1,235 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "gcfilmsexporter.h"
+#include "../collection.h"
+#include "../document.h"
+#include "../filehandler.h"
+#include "../latin1literal.h"
+#include "../tellico_utils.h"
+#include "../stringset.h"
+#include "../tellico_kernel.h"
+#include "../imagefactory.h"
+
+#include <klocale.h>
+#include <kio/netaccess.h>
+
+namespace {
+ char GCFILMS_DELIMITER = '|';
+}
+
+using Tellico::Export::GCfilmsExporter;
+
+GCfilmsExporter::GCfilmsExporter() : Tellico::Export::Exporter() {
+}
+
+QString GCfilmsExporter::formatString() const {
+ return i18n("GCfilms");
+}
+
+QString GCfilmsExporter::fileFilter() const {
+ return i18n("*.gcf|GCfilms Data Files (*.gcf)") + QChar('\n') + i18n("*|All Files");
+#if 0
+ i18n("*.gcs|GCstar Data Files (*.gcs)")
+#endif
+}
+
+bool GCfilmsExporter::exec() {
+ Data::CollPtr coll = collection();
+ if(!coll) {
+ return false;
+ }
+
+ QString text;
+ QTextOStream ts(&text);
+
+ ts << "GCfilms|" << coll->entryCount() << "|";
+ if(options() & Export::ExportUTF8) {
+ ts << "UTF8" << endl;
+ }
+
+ char d = GCFILMS_DELIMITER;
+ bool format = options() & Export::ExportFormatted;
+ // when importing GCfilms, a url field is added
+ bool hasURL = coll->hasField(QString::fromLatin1("url"))
+ && coll->fieldByName(QString::fromLatin1("url"))->type() == Data::Field::URL;
+
+ uint minRating = 1;
+ uint maxRating = 5;
+ Data::FieldPtr f = coll->fieldByName(QString::fromLatin1("rating"));
+ if(f) {
+ bool ok;
+ uint n = Tellico::toUInt(f->property(QString::fromLatin1("minimum")), &ok);
+ if(ok) {
+ minRating = n;
+ }
+ n = Tellico::toUInt(f->property(QString::fromLatin1("maximum")), &ok);
+ if(ok) {
+ maxRating = n;
+ }
+ }
+
+ // only going to export images if it's a local path
+ KURL imageDir;
+ if(url().isLocalFile()) {
+ imageDir = url();
+ imageDir.cd(QString::fromLatin1(".."));
+ imageDir.addPath(url().fileName().section('.', 0, 0) + QString::fromLatin1("_images/"));
+ if(!KIO::NetAccess::exists(imageDir, false, 0)) {
+ bool success = KIO::NetAccess::mkdir(imageDir, Kernel::self()->widget());
+ if(!success) {
+ imageDir = KURL(); // means don't write images
+ }
+ }
+ }
+
+ QStringList images;
+ for(Data::EntryVec::ConstIterator entry = entries().begin(); entry != entries().end(); ++entry) {
+ ts << entry->id() << d;
+ push(ts, "title", entry, format);
+ push(ts, "year", entry, format);
+ push(ts, "running-time", entry, format);
+ push(ts, "director", entry, format);
+ push(ts, "nationality", entry, format);
+ push(ts, "genre", entry, format);
+ // do image
+ QString tmp = entry->field(QString::fromLatin1("cover"));
+ if(!tmp.isEmpty() && !imageDir.isEmpty()) {
+ images << tmp;
+ ts << imageDir.path() << tmp;
+ }
+ ts << d;
+
+ // do not format cast since the commas could get mixed up
+ const QStringList cast = entry->fields(QString::fromLatin1("cast"), false);
+ for(QStringList::ConstIterator it = cast.begin(); it != cast.end(); ++it) {
+ ts << (*it).section(QString::fromLatin1("::"), 0, 0);
+ if(it != cast.fromLast()) {
+ ts << ", ";
+ }
+ }
+ ts << d;
+
+ // values[9] is the original title
+ ts << d;
+
+ push(ts, "plot", entry, format);
+
+ if(hasURL) {
+ push(ts, "url", entry, format);
+ } else {
+ ts << d;
+ }
+
+ // values[12] is whether the film has been viewed or not
+ ts << d;
+
+ push(ts, "medium", entry, format);
+ // values[14] is number of DVDS?
+ ts << d;
+ // values[15] is place?
+ ts << d;
+
+ // gcfilms's ratings go 0-10, just multiply by two
+ bool ok;
+ int rat = Tellico::toUInt(entry->field(QString::fromLatin1("rating"), format), &ok);
+ if(ok) {
+ ts << rat * 10/(maxRating-minRating);
+ }
+ ts << d;
+
+ push(ts, "comments", entry, format);
+ push(ts, "language", entry, format); // ignoring audio-tracks
+
+ push(ts, "subtitle", entry, format);
+
+ // values[20] is borrower name, values[21] is loan date
+ if(entry->field(QString::fromLatin1("loaned")).isEmpty()) {
+ ts << d << d;
+ } else {
+ // find loan
+ bool found = false;
+ const Data::BorrowerVec& borrowers = Data::Document::self()->collection()->borrowers();
+ for(Data::BorrowerVec::ConstIterator b = borrowers.begin(); b != borrowers.end() && !found; ++b) {
+ const Data::LoanVec& loans = b->loans();
+ for(Data::LoanVec::ConstIterator loan = loans.begin(); loan != loans.end(); ++loan) {
+ if(entry.data() == loan->entry()) {
+ ts << b->name() << d;
+ ts << loan->loanDate().day() << '/'
+ << loan->loanDate().month() << '/'
+ << loan->loanDate().year() << d;
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+
+ // values[22] is history ?
+ ts << d;
+
+ // for certification, only thing we can do is assume default american ratings
+ tmp = entry->field(QString::fromLatin1("certification"), format);
+ int age = 0;
+ if(tmp == Latin1Literal("U (USA)")) {
+ age = 1;
+ } else if(tmp == Latin1Literal("G (USA)")) {
+ age = 2;
+ } else if(tmp == Latin1Literal("PG (USA)")) {
+ age = 5;
+ } else if(tmp == Latin1Literal("PG-13 (USA)")) {
+ age = 13;
+ } else if(tmp == Latin1Literal("R (USA)")) {
+ age = 17;
+ }
+ if(age > 0) {
+ ts << age << d;
+ }
+ ts << d;
+
+ // all done
+ ts << endl;
+ }
+
+ StringSet imageSet;
+ for(QStringList::ConstIterator it = images.begin(); it != images.end(); ++it) {
+ if(imageSet.has(*it)) {
+ continue;
+ }
+ if(ImageFactory::writeImage(*it, imageDir)) {
+ imageSet.add(*it);
+ } else {
+ kdWarning() << "GCfilmsExporter::exec() - unable to write image file: "
+ << imageDir << *it << endl;
+ }
+ }
+
+ return FileHandler::writeTextURL(url(), text, options() & Export::ExportUTF8, options() & Export::ExportForce);
+}
+
+void GCfilmsExporter::push(QTextOStream& ts_, QCString fieldName_, Data::EntryVec::ConstIterator entry_, bool format_) {
+ Data::FieldPtr f = collection()->fieldByName(QString::fromLatin1(fieldName_));
+ // don't format multiple names cause commas will cause problems
+ if(f->formatFlag() == Data::Field::FormatName && (f->flags() & Data::Field::AllowMultiple)) {
+ format_ = false;
+ }
+ QString s = entry_->field(QString::fromLatin1(fieldName_), format_);
+ if(f->flags() & Data::Field::AllowMultiple) {
+ ts_ << s.replace(QString::fromLatin1("; "), QChar(','));
+ } else {
+ ts_ << s;
+ }
+ ts_ << GCFILMS_DELIMITER;
+}
+
+#include "gcfilmsexporter.moc"
diff --git a/src/translators/gcfilmsexporter.h b/src/translators/gcfilmsexporter.h
new file mode 100644
index 0000000..50ee31c
--- /dev/null
+++ b/src/translators/gcfilmsexporter.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_EXPORT_GCFILMSEXPORTER_H
+#define TELLICO_EXPORT_GCFILMSEXPORTER_H
+
+class QTextOStream;
+
+#include "exporter.h"
+
+namespace Tellico {
+ namespace Export {
+
+/**
+ * @author Robby Stephenson
+ */
+class GCfilmsExporter : public Exporter {
+Q_OBJECT
+
+public:
+ GCfilmsExporter();
+
+ virtual bool exec();
+ virtual QString formatString() const;
+ virtual QString fileFilter() const;
+
+ // no options
+ virtual QWidget* widget(QWidget*, const char*) { return 0; }
+
+private:
+ void push(QTextOStream& ts, QCString fieldName, Data::EntryVec::ConstIterator entry, bool format);
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/gcfilmsimporter.cpp b/src/translators/gcfilmsimporter.cpp
new file mode 100644
index 0000000..e2ff9ca
--- /dev/null
+++ b/src/translators/gcfilmsimporter.cpp
@@ -0,0 +1,273 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "gcfilmsimporter.h"
+#include "../collections/videocollection.h"
+#include "../latin1literal.h"
+#include "../tellico_utils.h"
+#include "../imagefactory.h"
+#include "../borrower.h"
+#include "../progressmanager.h"
+#include "xslthandler.h"
+#include "tellicoimporter.h"
+
+#include <kapplication.h>
+#include <kstandarddirs.h>
+
+#include <qtextcodec.h>
+
+#define CHECKLIMITS(n) if(values.count() <= n) continue
+
+using Tellico::Import::GCfilmsImporter;
+
+GCfilmsImporter::GCfilmsImporter(const KURL& url_) : TextImporter(url_), m_coll(0), m_cancelled(false) {
+}
+
+bool GCfilmsImporter::canImport(int type) const {
+ return type == Data::Collection::Video
+ || type == Data::Collection::Book
+ || type == Data::Collection::Album
+ || type == Data::Collection::Game
+ || type == Data::Collection::Wine
+ || type == Data::Collection::Coin;
+}
+
+Tellico::Data::CollPtr GCfilmsImporter::collection() {
+ if(m_coll) {
+ return m_coll;
+ }
+
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, progressLabel(), true);
+ item.setTotalSteps(100);
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+ ProgressItem::Done done(this);
+
+ QString str = text();
+ QTextIStream t(&str);
+ QString line = t.readLine();
+ if(line.startsWith(QString::fromLatin1("GCfilms"))) {
+ readGCfilms(str);
+ } else {
+ // need to reparse the string if it's in utf-8
+ if(line.lower().find(QString::fromLatin1("utf-8")) > 0) {
+ str = QString::fromUtf8(str.local8Bit());
+ }
+ readGCstar(str);
+ }
+ return m_coll;
+}
+
+void GCfilmsImporter::readGCfilms(const QString& text_) {
+ m_coll = new Data::VideoCollection(true);
+ bool hasURL = false;
+ if(m_coll->hasField(QString::fromLatin1("url"))) {
+ hasURL = m_coll->fieldByName(QString::fromLatin1("url"))->type() == Data::Field::URL;
+ } else {
+ Data::FieldPtr field = new Data::Field(QString::fromLatin1("url"), i18n("URL"), Data::Field::URL);
+ field->setCategory(i18n("General"));
+ m_coll->addField(field);
+ hasURL = true;
+ }
+
+ bool convertUTF8 = false;
+ QMap<QString, Data::BorrowerPtr> borrowers;
+ const QRegExp rx(QString::fromLatin1("\\s*,\\s*"));
+ QRegExp year(QString::fromLatin1("\\d{4}"));
+ QRegExp runTimeHr(QString::fromLatin1("(\\d+)\\s?hr?"));
+ QRegExp runTimeMin(QString::fromLatin1("(\\d+)\\s?mi?n?"));
+
+ bool gotFirstLine = false;
+ uint total = 0;
+
+ QTextIStream t(&text_);
+
+ const uint length = text_.length();
+ const uint stepSize = QMAX(s_stepSize, length/100);
+ const bool showProgress = options() & ImportProgress;
+
+ ProgressManager::self()->setTotalSteps(this, length);
+ uint j = 0;
+ for(QString line = t.readLine(); !m_cancelled && !line.isNull(); line = t.readLine(), j += line.length()) {
+ // string was wrongly converted
+ QStringList values = QStringList::split('|', (convertUTF8 ? QString::fromUtf8(line.local8Bit()) : line), true);
+ if(values.empty()) {
+ continue;
+ }
+
+ if(!gotFirstLine) {
+ if(values[0] != Latin1Literal("GCfilms")) {
+ setStatusMessage(i18n("<qt>The file is not a valid GCstar data file.</qt>"));
+ m_coll = 0;
+ return;
+ }
+ total = Tellico::toUInt(values[1], 0)+1; // number of lines really
+ if(values.size() > 2 && values[2] == Latin1Literal("UTF8")) {
+ // if locale encoding isn't utf8, need to do a reconversion
+ QTextCodec* codec = QTextCodec::codecForLocale();
+ if(QCString(codec->name()).find("utf-8", 0, false) == -1) {
+ convertUTF8 = true;
+ }
+ }
+ gotFirstLine = true;
+ continue;
+ }
+
+ bool ok;
+
+ Data::EntryPtr entry = new Data::Entry(m_coll);
+ entry->setId(Tellico::toUInt(values[0], &ok));
+ entry->setField(QString::fromLatin1("title"), values[1]);
+ if(year.search(values[2]) > -1) {
+ entry->setField(QString::fromLatin1("year"), year.cap());
+ }
+
+ uint time = 0;
+ if(runTimeHr.search(values[3]) > -1) {
+ time = Tellico::toUInt(runTimeHr.cap(1), &ok) * 60;
+ }
+ if(runTimeMin.search(values[3]) > -1) {
+ time += Tellico::toUInt(runTimeMin.cap(1), &ok);
+ }
+ if(time > 0) {
+ entry->setField(QString::fromLatin1("running-time"), QString::number(time));
+ }
+
+ entry->setField(QString::fromLatin1("director"), splitJoin(rx, values[4]));
+ entry->setField(QString::fromLatin1("nationality"), splitJoin(rx, values[5]));
+ entry->setField(QString::fromLatin1("genre"), splitJoin(rx, values[6]));
+ KURL u = KURL::fromPathOrURL(values[7]);
+ if(!u.isEmpty()) {
+ QString id = ImageFactory::addImage(u, true /* quiet */);
+ if(!id.isEmpty()) {
+ entry->setField(QString::fromLatin1("cover"), id);
+ }
+ }
+ entry->setField(QString::fromLatin1("cast"), splitJoin(rx, values[8]));
+ // values[9] is the original title
+ entry->setField(QString::fromLatin1("plot"), values[10]);
+ if(hasURL) {
+ entry->setField(QString::fromLatin1("url"), values[11]);
+ }
+
+ CHECKLIMITS(12);
+
+ // values[12] is whether the film has been viewed or not
+ entry->setField(QString::fromLatin1("medium"), values[13]);
+ // values[14] is number of DVDS?
+ // values[15] is place?
+ // gcfilms's ratings go 0-10, just divide by two
+ entry->setField(QString::fromLatin1("rating"), QString::number(int(Tellico::toUInt(values[16], &ok)/2)));
+ entry->setField(QString::fromLatin1("comments"), values[17]);
+
+ CHECKLIMITS(18);
+
+ QStringList s = QStringList::split(',', values[18]);
+ QStringList tracks, langs;
+ for(QStringList::ConstIterator it = s.begin(); it != s.end(); ++it) {
+ langs << (*it).section(';', 0, 0);
+ tracks << (*it).section(';', 1, 1);
+ }
+ entry->setField(QString::fromLatin1("language"), langs.join(QString::fromLatin1("; ")));
+ entry->setField(QString::fromLatin1("audio-track"), tracks.join(QString::fromLatin1("; ")));
+
+ entry->setField(QString::fromLatin1("subtitle"), splitJoin(rx, values[19]));
+
+ CHECKLIMITS(20);
+
+ // values[20] is borrower name
+ if(!values[20].isEmpty()) {
+ QString tmp = values[20];
+ Data::BorrowerPtr b = borrowers[tmp];
+ if(!b) {
+ b = new Data::Borrower(tmp, QString());
+ borrowers.insert(tmp, b);
+ }
+ // values[21] is loan date
+ if(!values[21].isEmpty()) {
+ tmp = values[21]; // assume date is dd/mm/yyyy
+ int d = Tellico::toUInt(tmp.section('/', 0, 0), &ok);
+ int m = Tellico::toUInt(tmp.section('/', 1, 1), &ok);
+ int y = Tellico::toUInt(tmp.section('/', 2, 2), &ok);
+ b->addLoan(new Data::Loan(entry, QDate(y, m, d), QDate(), QString()));
+ entry->setField(QString::fromLatin1("loaned"), QString::fromLatin1("true"));
+ }
+ }
+ // values[22] is history ?
+ // for certification, only thing we can do is assume default american ratings
+ // they're not translated one for one
+ CHECKLIMITS(23);
+
+ int age = Tellico::toUInt(values[23], &ok);
+ if(age < 2) {
+ entry->setField(QString::fromLatin1("certification"), QString::fromLatin1("U (USA)"));
+ } else if(age < 3) {
+ entry->setField(QString::fromLatin1("certification"), QString::fromLatin1("G (USA)"));
+ } else if(age < 6) {
+ entry->setField(QString::fromLatin1("certification"), QString::fromLatin1("PG (USA)"));
+ } else if(age < 14) {
+ entry->setField(QString::fromLatin1("certification"), QString::fromLatin1("PG-13 (USA)"));
+ } else {
+ entry->setField(QString::fromLatin1("certification"), QString::fromLatin1("R (USA)"));
+ }
+
+ m_coll->addEntries(entry);
+
+ if(showProgress && j%stepSize == 0) {
+ ProgressManager::self()->setProgress(this, j);
+ kapp->processEvents();
+ }
+ }
+
+ if(m_cancelled) {
+ m_coll = 0;
+ return;
+ }
+
+ for(QMap<QString, Data::BorrowerPtr>::Iterator it = borrowers.begin(); it != borrowers.end(); ++it) {
+ if(!it.data()->isEmpty()) {
+ m_coll->addBorrower(it.data());
+ }
+ }
+}
+
+void GCfilmsImporter::readGCstar(const QString& text_) {
+ QString xsltFile = locate("appdata", QString::fromLatin1("gcstar2tellico.xsl"));
+ XSLTHandler handler(xsltFile);
+ if(!handler.isValid()) {
+ setStatusMessage(i18n("Tellico encountered an error in XSLT processing."));
+ return;
+ }
+
+ QString str = handler.applyStylesheet(text_);
+
+ if(str.isEmpty()) {
+ setStatusMessage(i18n("<qt>The file is not a valid GCstar data file.</qt>"));
+ return;
+ }
+
+ Import::TellicoImporter imp(str);
+ m_coll = imp.collection();
+ setStatusMessage(imp.statusMessage());
+}
+
+inline
+QString GCfilmsImporter::splitJoin(const QRegExp& rx, const QString& s) {
+ return QStringList::split(rx, s, false).join(QString::fromLatin1("; "));
+}
+
+void GCfilmsImporter::slotCancel() {
+ m_cancelled = true;
+}
+
+#undef CHECKLIMITS
+#include "gcfilmsimporter.moc"
diff --git a/src/translators/gcfilmsimporter.h b/src/translators/gcfilmsimporter.h
new file mode 100644
index 0000000..8fa9a0d
--- /dev/null
+++ b/src/translators/gcfilmsimporter.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_IMPORT_GCFILMSIMPORTER_H
+#define TELLICO_IMPORT_GCFILMSIMPORTER_H
+
+#include "textimporter.h"
+#include "../datavectors.h"
+
+class QRegExp;
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ * @author Robby Stephenson
+*/
+class GCfilmsImporter : public TextImporter {
+Q_OBJECT
+
+public:
+ /**
+ */
+ GCfilmsImporter(const KURL& url);
+
+ /**
+ *
+ */
+ virtual Data::CollPtr collection();
+ /**
+ */
+ virtual QWidget* widget(QWidget*, const char*) { return 0; }
+ virtual bool canImport(int type) const;
+
+public slots:
+ void slotCancel();
+
+private:
+ static QString splitJoin(const QRegExp& rx, const QString& s);
+
+ void readGCfilms(const QString& text);
+ void readGCstar(const QString& text);
+
+ Data::CollPtr m_coll;
+ bool m_cancelled;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/griffith2tellico.py b/src/translators/griffith2tellico.py
new file mode 100755
index 0000000..24bfb41
--- /dev/null
+++ b/src/translators/griffith2tellico.py
@@ -0,0 +1,319 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-1 -*-
+
+# ***************************************************************************
+# copyright : (C) 2007 by Robby Stephenson
+# email : robby@periapsis.org
+# based on : fr.allocine.py by Mathias Monnerville
+# ***************************************************************************
+#
+# ***************************************************************************
+# * *
+# * This program is free software; you can redistribute it and/or modify *
+# * it under the terms of version 2 of the GNU General Public License as *
+# * published by the Free Software Foundation; *
+# * *
+# ***************************************************************************
+
+import os, sys
+import base64
+import xml.dom.minidom
+try:
+ import sqlite3
+except:
+ print sys.stderr, "The Python sqlite3 module is required to import Griffith databases."
+ exit(1)
+
+DB_PATH = os.environ['HOME'] + '/.griffith/griffith.db'
+POSTERS_PATH = os.environ['HOME'] + '/.griffith/posters/'
+
+XML_HEADER = """<?xml version="1.0" encoding="UTF-8"?>"""
+DOCTYPE = """<!DOCTYPE tellico PUBLIC "-//Robby Stephenson/DTD Tellico V9.0//EN" "http://periapsis.org/tellico/dtd/v9/tellico.dtd">"""
+
+class BasicTellicoDOM:
+ def __init__(self):
+ self.__doc = xml.dom.minidom.Document()
+ self.__root = self.__doc.createElement('tellico')
+ self.__root.setAttribute('xmlns', 'http://periapsis.org/tellico/')
+ self.__root.setAttribute('syntaxVersion', '9')
+
+ self.__collection = self.__doc.createElement('collection')
+ self.__collection.setAttribute('title', 'Griffith Import')
+ self.__collection.setAttribute('type', '3')
+
+ self.__fields = self.__doc.createElement('fields')
+ # Add all default (standard) fields
+ self.__dfltField = self.__doc.createElement('field')
+ self.__dfltField.setAttribute('name', '_default')
+
+ # change the rating to have a maximum of 10
+ self.__ratingField = self.__doc.createElement('field')
+ self.__ratingField.setAttribute('name', 'rating')
+ self.__ratingField.setAttribute('title', 'Personal Rating')
+ self.__ratingField.setAttribute('flags', '2')
+ self.__ratingField.setAttribute('category', 'Personal')
+ self.__ratingField.setAttribute('format', '4')
+ self.__ratingField.setAttribute('type', '14')
+ self.__ratingField.setAttribute('i18n', 'yes')
+ propNode = self.__doc.createElement('prop')
+ propNode.setAttribute('name', 'maximum')
+ propNode.appendChild(self.__doc.createTextNode('10'))
+ self.__ratingField.appendChild(propNode);
+ propNode = self.__doc.createElement('prop')
+ propNode.setAttribute('name', 'minimum')
+ propNode.appendChild(self.__doc.createTextNode('1'))
+ self.__ratingField.appendChild(propNode);
+
+ # Add a custom 'Original Title' field
+ self.__titleField = self.__doc.createElement('field')
+ self.__titleField.setAttribute('name', 'orig-title')
+ self.__titleField.setAttribute('title', 'Original Title')
+ self.__titleField.setAttribute('flags', '8')
+ self.__titleField.setAttribute('category', 'General')
+ self.__titleField.setAttribute('format', '1')
+ self.__titleField.setAttribute('type', '1')
+ self.__titleField.setAttribute('i18n', 'yes')
+
+ self.__keywordField = self.__doc.createElement('field')
+ self.__keywordField.setAttribute('name', 'keyword')
+ self.__keywordField.setAttribute('title', 'Keywords')
+ self.__keywordField.setAttribute('flags', '7')
+ self.__keywordField.setAttribute('category', 'Personal')
+ self.__keywordField.setAttribute('format', '4')
+ self.__keywordField.setAttribute('type', '1')
+ self.__keywordField.setAttribute('i18n', 'yes')
+
+ self.__urlField = self.__doc.createElement('field')
+ self.__urlField.setAttribute('name', 'url')
+ self.__urlField.setAttribute('title', 'URL')
+ self.__urlField.setAttribute('flags', '0')
+ self.__urlField.setAttribute('category', 'General')
+ self.__urlField.setAttribute('format', '4')
+ self.__urlField.setAttribute('type', '7')
+ self.__urlField.setAttribute('i18n', 'yes')
+
+ self.__fields.appendChild(self.__dfltField)
+ self.__fields.appendChild(self.__ratingField)
+ self.__fields.appendChild(self.__titleField)
+ self.__fields.appendChild(self.__keywordField)
+ self.__fields.appendChild(self.__urlField)
+ self.__collection.appendChild(self.__fields)
+
+ self.__images = self.__doc.createElement('images')
+
+ self.__root.appendChild(self.__collection)
+ self.__doc.appendChild(self.__root)
+ self.__fieldsMap = dict(country='nationality',
+ classification='certification',
+ runtime='running-time',
+ o_title='orig-title',
+ notes='comments',
+ image='cover',
+ tag='keyword',
+ site='url')
+
+
+ def addMedia(self, media):
+ if len(media) == 0: return
+ # add default Tellico values
+ orig_media = 'DVD;VHS;VCD;DivX;Blu-ray;HD DVD'.split(';')
+ orig_media.extend(media)
+ # make sure unique
+ set = {}
+ media = [set.setdefault(e,e) for e in orig_media if e not in set]
+
+ mediaField = self.__doc.createElement('field')
+ mediaField.setAttribute('name', 'medium')
+ mediaField.setAttribute('title', 'Medium')
+ mediaField.setAttribute('flags', '2')
+ mediaField.setAttribute('category', 'General')
+ mediaField.setAttribute('format', '4')
+ mediaField.setAttribute('type', '3')
+ mediaField.setAttribute('i18n', 'yes')
+ mediaField.setAttribute('allowed', ';'.join(media))
+ self.__fields.appendChild(mediaField)
+
+ def addEntry(self, movieData):
+ """
+ Add a movie entry
+ """
+ entryNode = self.__doc.createElement('entry')
+ entryNode.setAttribute('id', movieData['id'])
+
+ for key, values in movieData.iteritems():
+ if key == 'id':
+ continue
+
+ if self.__fieldsMap.has_key(key):
+ field = self.__fieldsMap[key]
+ else:
+ field = key
+
+ parentNode = self.__doc.createElement(field + 's')
+
+ for value in values:
+ if len(value) == 0: continue
+ node = self.__doc.createElement(field)
+ if field == 'certification': value += " (USA)"
+ elif field == 'region': value = "Region " + value
+ elif field == 'cover':
+ imageNode = self.__doc.createElement('image')
+ imageNode.setAttribute('format', 'JPEG')
+ imageNode.setAttribute('id', value[0])
+ imageNode.appendChild(self.__doc.createTextNode(value[1]))
+ self.__images.appendChild(imageNode)
+ value = value[0] # value was (id, md5)
+
+ if field == 'cast':
+ for v in value:
+ columnNode = self.__doc.createElement('column')
+ columnNode.appendChild(self.__doc.createTextNode(v.strip()))
+ node.appendChild(columnNode)
+
+ else:
+ node.appendChild(self.__doc.createTextNode(value.strip()))
+
+ if node.hasChildNodes(): parentNode.appendChild(node)
+
+ if parentNode.hasChildNodes(): entryNode.appendChild(parentNode)
+
+ self.__collection.appendChild(entryNode)
+
+ def printXML(self):
+ """
+ Outputs XML content to stdout
+ """
+ self.__collection.appendChild(self.__images)
+ print XML_HEADER; print DOCTYPE
+ print self.__root.toxml()
+
+
+class GriffithParser:
+ def __init__(self):
+ self.__dbPath = DB_PATH
+ self.__domTree = BasicTellicoDOM()
+
+ def run(self):
+ """
+ Runs the parser: fetch movie ids, then fills and prints the DOM tree
+ to stdout (in tellico format) so that tellico can use it.
+ """
+ self.__conn = sqlite3.connect(self.__dbPath)
+ self.__loadDatabase()
+ # Print results to stdout
+ self.__domTree.printXML()
+
+ def __addMediaValues(self):
+ c = self.__conn.cursor()
+ c.execute("SELECT name FROM media")
+
+ media = list([row[0].encode('utf-8') for row in c.fetchall()])
+ self.__domTree.addMedia(media)
+
+
+ def __fetchMovieIds(self):
+ """
+ Retrieve all movie ids
+ """
+ c = self.__conn.cursor()
+ c.execute("SELECT movie_id FROM movies")
+ data = c.fetchall()
+ dataList = [row[0] for row in data]
+ return dataList
+
+ def __fetchMovieInfo(self, id):
+ """
+ Fetches movie information
+ """
+ #cast is a reserved word
+ columns = ('title','director','rating','year','region',
+ 'country','genre','classification','plot',
+ 'runtime','o_title','studio','notes','image',
+ '[cast]','loaned','color','site')
+
+ c = self.__conn.cursor()
+ c.execute("SELECT %s FROM movies WHERE movie_id=%s" % (','.join(columns),id))
+ row = c.fetchone()
+
+ data = {}
+ data['id'] = str(id)
+
+ for i in range(len(columns)):
+ if row[i] == None : continue
+
+ try:
+ value = row[i].encode('utf-8')
+ except:
+ value = str(row[i])
+
+ col = columns[i].replace('[','').replace(']','')
+
+ if col == 'genre' or col == 'studio':
+ values = value.split('/')
+ elif col == 'plot' or col == 'notes':
+ value = value.replace('\n', '\n<br/>')
+ values = (value,)
+ elif col == 'cast':
+ values = []
+ lines = value.split('\n')
+ for line in lines:
+ cast = line.split('as')
+ values.append(cast)
+ elif col == 'image':
+ imgfile = POSTERS_PATH + value + '.jpg'
+ img = file(imgfile,'rb').read()
+ values = ((value + '.jpg', base64.encodestring(img)),)
+ elif col == 'loaned':
+ if value == '0': value = ''
+ values = (value,)
+ elif col == 'color':
+ if value == '1': value = 'Color'
+ elif value == '2': value = 'Black & White'
+ values = (value,)
+ else:
+ values = (value,)
+ col = col.replace('"','')
+ data[col] = values
+
+ # get medium
+ c.execute("SELECT name FROM media WHERE medium_id IN (SELECT medium_id FROM movies WHERE movie_id=%s)" % id)
+
+ media = list([row[0].encode('utf-8') for row in c.fetchall()])
+ if len(media) > 0: data['medium'] = media
+
+ # get all tags
+ c.execute("SELECT name FROM tags WHERE tag_id IN (SELECT tag_id FROM movie_tag WHERE movie_id=%s)" % id)
+
+ tags = list([row[0].encode('utf-8') for row in c.fetchall()])
+ if len(tags) > 0: data['tag'] = tags
+
+ # get all languages
+ c.execute("SELECT name FROM languages WHERE lang_id IN (SELECT lang_id FROM movie_lang WHERE movie_id=%s)" % id)
+
+ langs = list([row[0].encode('utf-8') for row in c.fetchall()])
+ if len(langs) > 0: data['language'] = langs
+
+ return data
+
+
+ def __loadDatabase(self):
+ # Get all ids
+ self.__addMediaValues();
+ ids = self.__fetchMovieIds()
+
+ # Now retrieve data
+ if ids:
+ for entry in ids:
+ data = self.__fetchMovieInfo(entry)
+ self.__domTree.addEntry(data)
+ else:
+ return None
+
+
+
+def main():
+ parser = GriffithParser()
+ parser.run()
+
+if __name__ == '__main__':
+ main()
diff --git a/src/translators/griffithimporter.cpp b/src/translators/griffithimporter.cpp
new file mode 100644
index 0000000..8b0394f
--- /dev/null
+++ b/src/translators/griffithimporter.cpp
@@ -0,0 +1,107 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "griffithimporter.h"
+#include "../collections/videocollection.h"
+#include "tellicoimporter.h"
+#include "../tellico_debug.h"
+
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <kprocess.h>
+
+#include <qdir.h>
+#include <qfile.h>
+
+using Tellico::Import::GriffithImporter;
+
+GriffithImporter::~GriffithImporter() {
+ if(m_process) {
+ m_process->kill();
+ delete m_process;
+ m_process = 0;
+ }
+}
+
+Tellico::Data::CollPtr GriffithImporter::collection() {
+ QString filename = QDir::homeDirPath() + QString::fromLatin1("/.griffith/griffith.db");
+ if(!QFile::exists(filename)) {
+ myWarning() << "GriffithImporter::collection() - database not found: " << filename << endl;
+ return 0;
+ }
+
+ QString python = KStandardDirs::findExe(QString::fromLatin1("python"));
+ if(python.isEmpty()) {
+ myWarning() << "GriffithImporter::collection() - python not found!" << endl;
+ return 0;
+ }
+
+ QString griffith = KGlobal::dirs()->findResource("appdata", QString::fromLatin1("griffith2tellico.py"));
+ if(griffith.isEmpty()) {
+ myWarning() << "GriffithImporter::collection() - griffith2tellico.py not found!" << endl;
+ return 0;
+ }
+
+ m_process = new KProcess();
+ connect(m_process, SIGNAL(receivedStdout(KProcess*, char*, int)), SLOT(slotData(KProcess*, char*, int)));
+ connect(m_process, SIGNAL(receivedStderr(KProcess*, char*, int)), SLOT(slotError(KProcess*, char*, int)));
+ connect(m_process, SIGNAL(processExited(KProcess*)), SLOT(slotProcessExited(KProcess*)));
+ *m_process << python << griffith;
+ if(!m_process->start(KProcess::Block, KProcess::AllOutput)) {
+ myDebug() << "ExecExternalFetcher::startSearch() - process failed to start" << endl;
+ return 0;
+ }
+
+ return m_coll;
+}
+
+void GriffithImporter::slotData(KProcess*, char* buffer_, int len_) {
+ QDataStream stream(m_data, IO_WriteOnly | IO_Append);
+ stream.writeRawBytes(buffer_, len_);
+}
+
+void GriffithImporter::slotError(KProcess*, char* buffer_, int len_) {
+ QString msg = QString::fromLocal8Bit(buffer_, len_);
+ myDebug() << "GriffithImporter::slotError() - " << msg << endl;
+ setStatusMessage(msg);
+}
+
+
+void GriffithImporter::slotProcessExited(KProcess*) {
+// myDebug() << "GriffithImporter::slotProcessExited()" << endl;
+ if(!m_process->normalExit() || m_process->exitStatus()) {
+ myDebug() << "GriffithImporter::slotProcessExited() - process did not exit successfully" << endl;
+ return;
+ }
+
+ if(m_data.isEmpty()) {
+ myDebug() << "GriffithImporter::slotProcessExited() - no data" << endl;
+ return;
+ }
+
+ QString text = QString::fromUtf8(m_data, m_data.size());
+ TellicoImporter imp(text);
+
+ m_coll = imp.collection();
+ if(!m_coll) {
+ myDebug() << "GriffithImporter::slotProcessExited() - no collection pointer" << endl;
+ } else {
+ myLog() << "GriffithImporter::slotProcessExited() - results found: " << m_coll->entryCount() << endl;
+ }
+}
+
+bool GriffithImporter::canImport(int type) const {
+ return type == Data::Collection::Video;
+}
+
+#include "griffithimporter.moc"
diff --git a/src/translators/griffithimporter.h b/src/translators/griffithimporter.h
new file mode 100644
index 0000000..60bae07
--- /dev/null
+++ b/src/translators/griffithimporter.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef GRIFFITHIMPORTER_H
+#define GRIFFITHIMPORTER_H
+
+#include "importer.h"
+#include "../datavectors.h"
+
+class KProcess;
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ * An importer for importing collections used by Griffith, a movie colleciton manager.
+ *
+ * The database is assumed to be $HOME/.griffith/griffith.db. The file format is sqlite3,
+ * and a python script, depending on pysqlite, i sused to import the database
+ *
+ * @author Robby Stephenson
+ */
+class GriffithImporter : public Importer {
+Q_OBJECT
+
+public:
+ /**
+ */
+ GriffithImporter() : Importer(), m_coll(0), m_process(0) {}
+ /**
+ */
+ virtual ~GriffithImporter();
+
+ /**
+ */
+ virtual Data::CollPtr collection();
+ virtual bool canImport(int type) const;
+
+private slots:
+ void slotData(KProcess* proc, char* buffer, int len);
+ void slotError(KProcess* proc, char* buffer, int len);
+ void slotProcessExited(KProcess* proc);
+
+private:
+ Data::CollPtr m_coll;
+
+ KProcess* m_process;
+ QByteArray m_data;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/grs1importer.cpp b/src/translators/grs1importer.cpp
new file mode 100644
index 0000000..7eca9e3
--- /dev/null
+++ b/src/translators/grs1importer.cpp
@@ -0,0 +1,130 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "grs1importer.h"
+#include "../collections/bibtexcollection.h"
+#include "../entry.h"
+#include "../field.h"
+#include "../latin1literal.h"
+#include "../tellico_debug.h"
+
+using Tellico::Import::GRS1Importer;
+GRS1Importer::TagMap* GRS1Importer::s_tagMap = 0;
+
+// static
+void GRS1Importer::initTagMap() {
+ if(!s_tagMap) {
+ s_tagMap = new TagMap();
+ // BT is special and is handled separately
+ s_tagMap->insert(TagPair(2, 1), QString::fromLatin1("title"));
+ s_tagMap->insert(TagPair(2, 2), QString::fromLatin1("author"));
+ s_tagMap->insert(TagPair(2, 4), QString::fromLatin1("year"));
+ s_tagMap->insert(TagPair(2, 7), QString::fromLatin1("publisher"));
+ s_tagMap->insert(TagPair(2, 31), QString::fromLatin1("publisher"));
+ s_tagMap->insert(TagPair(2, 20), QString::fromLatin1("language"));
+ s_tagMap->insert(TagPair(2, 21), QString::fromLatin1("keyword"));
+ s_tagMap->insert(TagPair(3, QString::fromLatin1("isbn/issn")), QString::fromLatin1("isbn"));
+ s_tagMap->insert(TagPair(3, QString::fromLatin1("isbn")), QString::fromLatin1("isbn"));
+ s_tagMap->insert(TagPair(3, QString::fromLatin1("notes")), QString::fromLatin1("note"));
+ s_tagMap->insert(TagPair(3, QString::fromLatin1("note")), QString::fromLatin1("note"));
+ s_tagMap->insert(TagPair(3, QString::fromLatin1("series")), QString::fromLatin1("series"));
+ s_tagMap->insert(TagPair(3, QString::fromLatin1("physical description")), QString::fromLatin1("note"));
+ s_tagMap->insert(TagPair(3, QString::fromLatin1("subtitle")), QString::fromLatin1("subtitle"));
+ }
+}
+
+GRS1Importer::GRS1Importer(const QString& text_) : TextImporter(text_) {
+ initTagMap();
+}
+
+bool GRS1Importer::canImport(int type) const {
+ return type == Data::Collection::Bibtex;
+}
+
+Tellico::Data::CollPtr GRS1Importer::collection() {
+ Data::CollPtr coll = new Data::BibtexCollection(true);
+
+ Data::FieldPtr f = new Data::Field(QString::fromLatin1("isbn"), i18n("ISBN#"));
+ f->setCategory(i18n("Publishing"));
+ f->setDescription(i18n("International Standard Book Number"));
+ coll->addField(f);
+
+ f = new Data::Field(QString::fromLatin1("language"), i18n("Language"));
+ f->setCategory(i18n("Publishing"));
+ f->setFlags(Data::Field::AllowCompletion | Data::Field::AllowGrouped | Data::Field::AllowMultiple);
+ coll->addField(f);
+
+ Data::EntryPtr e = new Data::Entry(coll);
+ bool empty = true;
+
+ // in format "(tag, tag) value"
+ QRegExp rx(QString::fromLatin1("\\s*\\((\\d+),\\s*(.+)\\s*\\)\\s*(.+)\\s*"));
+// rx.setMinimal(true);
+ QRegExp dateRx(QString::fromLatin1(",[^,]*\\d{3,4}[^,]*")); // remove dates from authors
+ QRegExp pubRx(QString::fromLatin1("([^:]+):([^,]+),?")); // split location and publisher
+
+ bool ok;
+ int n;
+ QVariant v;
+ QString tmp, field, val, str = text();
+ if(str.isEmpty()) {
+ return 0;
+ }
+ QTextStream t(&str, IO_ReadOnly);
+ for(QString line = t.readLine(); !line.isNull(); line = t.readLine()) {
+// myDebug() << line << endl;
+ if(!rx.exactMatch(line)) {
+ continue;
+ }
+ n = rx.cap(1).toInt();
+ v = rx.cap(2).toInt(&ok);
+ if(!ok) {
+ v = rx.cap(2).lower();
+ }
+ field = (*s_tagMap)[TagPair(n, v)];
+ if(field.isEmpty()) {
+ continue;
+ }
+// myDebug() << "field is " << field << endl;
+ // assume if multiple values, it's allowed
+ val = rx.cap(3).stripWhiteSpace();
+ if(val.isEmpty()) {
+ continue;
+ }
+ empty = false;
+ if(field == Latin1Literal("title")) {
+ val = val.section('/', 0, 0).stripWhiteSpace(); // only take portion of title before slash
+ } else if(field == Latin1Literal("author")) {
+ val.replace(dateRx, QString::null);
+ } else if(field == Latin1Literal("publisher")) {
+ int pos = val.find(pubRx);
+ if(pos > -1) {
+ e->setField(QString::fromLatin1("address"), pubRx.cap(1));
+ val = pubRx.cap(2);
+ }
+ }
+
+ tmp = e->field(field);
+ if(!tmp.isEmpty()) {
+ tmp += QString::fromLatin1("; ");
+ }
+ e->setField(field, tmp + val);
+ }
+
+ if(!empty) {
+ coll->addEntries(e);
+ }
+ return coll;
+}
+
+#include "grs1importer.moc"
diff --git a/src/translators/grs1importer.h b/src/translators/grs1importer.h
new file mode 100644
index 0000000..a4929a4
--- /dev/null
+++ b/src/translators/grs1importer.h
@@ -0,0 +1,65 @@
+/***************************************************************************
+ copyright : (C) 2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_IMPORT_GRS1IMPORTER_H
+#define TELLICO_IMPORT_GRS1IMPORTER_H
+
+#include "textimporter.h"
+#include "../datavectors.h"
+
+#include <qvariant.h>
+#include <qmap.h>
+#include <qpair.h>
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ * @author Robby Stephenson
+ */
+class GRS1Importer : public TextImporter {
+Q_OBJECT
+
+public:
+ GRS1Importer(const QString& text);
+ virtual ~GRS1Importer() {}
+
+ /**
+ * @return A pointer to a @ref Data::Collection, or 0 if none can be created.
+ */
+ virtual Data::CollPtr collection();
+ /**
+ */
+ virtual QWidget* widget(QWidget*, const char*) { return 0; }
+ virtual bool canImport(int type) const;
+
+private:
+ static void initTagMap();
+
+ class TagPair : public QPair<int, QVariant> {
+ public:
+ TagPair() : QPair<int, QVariant>(-1, QVariant()) {}
+ TagPair(int n, const QVariant& v) : QPair<int, QVariant>(n, v) {}
+ QString toString() const { return QString::number(first) + second.toString(); }
+ bool operator< (const TagPair& p) const {
+ return toString() < p.toString();
+ }
+ };
+
+ typedef QMap<TagPair, QString> TagMap;
+ static TagMap* s_tagMap;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/htmlexporter.cpp b/src/translators/htmlexporter.cpp
new file mode 100644
index 0000000..e947793
--- /dev/null
+++ b/src/translators/htmlexporter.cpp
@@ -0,0 +1,815 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "htmlexporter.h"
+#include "xslthandler.h"
+#include "tellicoxmlexporter.h"
+#include "../document.h"
+#include "../collection.h"
+#include "../filehandler.h"
+#include "../imagefactory.h"
+#include "../latin1literal.h"
+#include "../tellico_kernel.h"
+#include "../tellico_utils.h"
+#include "../progressmanager.h"
+#include "../core/tellico_config.h"
+#include "../tellico_debug.h"
+
+#include <kstandarddirs.h>
+#include <kconfig.h>
+#include <kglobal.h>
+#include <kio/netaccess.h>
+#include <kapplication.h>
+#include <klocale.h>
+
+#include <qdom.h>
+#include <qgroupbox.h>
+#include <qlayout.h>
+#include <qcheckbox.h>
+#include <qwhatsthis.h>
+#include <qfile.h>
+#include <qhbox.h>
+#include <qlabel.h>
+
+extern "C" {
+#include <libxml/HTMLparser.h>
+#include <libxml/HTMLtree.h>
+}
+
+using Tellico::Export::HTMLExporter;
+
+HTMLExporter::HTMLExporter() : Tellico::Export::Exporter(),
+ m_handler(0),
+ m_printHeaders(true),
+ m_printGrouped(false),
+ m_exportEntryFiles(false),
+ m_cancelled(false),
+ m_parseDOM(true),
+ m_checkCreateDir(true),
+ m_imageWidth(0),
+ m_imageHeight(0),
+ m_widget(0),
+ m_xsltFile(QString::fromLatin1("tellico2html.xsl")) {
+}
+
+HTMLExporter::HTMLExporter(Data::CollPtr coll_) : Tellico::Export::Exporter(coll_),
+ m_handler(0),
+ m_printHeaders(true),
+ m_printGrouped(false),
+ m_exportEntryFiles(false),
+ m_cancelled(false),
+ m_parseDOM(true),
+ m_checkCreateDir(true),
+ m_imageWidth(0),
+ m_imageHeight(0),
+ m_widget(0),
+ m_xsltFile(QString::fromLatin1("tellico2html.xsl")) {
+}
+
+HTMLExporter::~HTMLExporter() {
+ delete m_handler;
+ m_handler = 0;
+}
+
+QString HTMLExporter::formatString() const {
+ return i18n("HTML");
+}
+
+QString HTMLExporter::fileFilter() const {
+ return i18n("*.html|HTML Files (*.html)") + QChar('\n') + i18n("*|All Files");
+}
+
+void HTMLExporter::reset() {
+ // since the ExportUTF8 option may have changed, need to delete handler
+ delete m_handler;
+ m_handler = 0;
+ m_files.clear();
+ m_links.clear();
+ m_copiedFiles.clear();
+}
+
+bool HTMLExporter::exec() {
+ if(url().isEmpty() || !url().isValid()) {
+ kdWarning() << "HTMLExporter::exec() - trying to export to invalid URL" << endl;
+ return false;
+ }
+
+ // check file exists first
+ // if we're not forcing, ask use
+ bool force = (options() & Export::ExportForce) || FileHandler::queryExists(url());
+ if(!force) {
+ return false;
+ }
+
+ if(!m_parseDOM) {
+ return FileHandler::writeTextURL(url(), text(), options() & Export::ExportUTF8, force);
+ }
+
+ m_cancelled = false;
+ // TODO: maybe need label?
+ if(options() & ExportProgress) {
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, QString::null, true);
+ item.setTotalSteps(100);
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+ }
+ // ok if not ExportProgress, no worries
+ ProgressItem::Done done(this);
+
+ htmlDocPtr htmlDoc = htmlParseDoc(reinterpret_cast<xmlChar*>(text().utf8().data()), NULL);
+ xmlNodePtr root = xmlDocGetRootElement(htmlDoc);
+ if(root == 0) {
+ myDebug() << "HTMLExporter::exec() - no root" << endl;
+ return false;
+ }
+ parseDOM(root);
+
+ if(m_cancelled) {
+ return true; // intentionally cancelled
+ }
+ ProgressManager::self()->setProgress(this, 15);
+
+ xmlChar* c;
+ int bytes;
+ htmlDocDumpMemory(htmlDoc, &c, &bytes);
+ QString allText;
+ if(bytes > 0) {
+ allText = QString::fromUtf8(reinterpret_cast<const char*>(c), bytes);
+ xmlFree(c);
+ }
+
+ if(m_cancelled) {
+ return true; // intentionally cancelled
+ }
+ ProgressManager::self()->setProgress(this, 20);
+
+ bool success = FileHandler::writeTextURL(url(), allText, options() & Export::ExportUTF8, force);
+ success &= copyFiles() && (!m_exportEntryFiles || writeEntryFiles());
+ return success;
+}
+
+bool HTMLExporter::loadXSLTFile() {
+ QString xsltfile = locate("appdata", m_xsltFile);
+ if(xsltfile.isNull()) {
+ myDebug() << "HTMLExporter::loadXSLTFile() - no xslt file for " << m_xsltFile << endl;
+ return false;
+ }
+
+ KURL u;
+ u.setPath(xsltfile);
+ // do NOT do namespace processing, it messes up the XSL declaration since
+ // QDom thinks there are no elements in the Tellico namespace and as a result
+ // removes the namespace declaration
+ QDomDocument dom = FileHandler::readXMLFile(u, false);
+ if(dom.isNull()) {
+ myDebug() << "HTMLExporter::loadXSLTFile() - error loading xslt file: " << xsltfile << endl;
+ return false;
+ }
+
+ // notes about utf-8 encoding:
+ // all params should be passed to XSLTHandler in utf8
+ // input string to XSLTHandler should be in utf-8, EVEN IF DOM STRING SAYS OTHERWISE
+
+ // the stylesheet prints utf-8 by default, if using locale encoding, need
+ // to change the encoding attribute on the xsl:output element
+ if(!(options() & Export::ExportUTF8)) {
+ XSLTHandler::setLocaleEncoding(dom);
+ }
+
+ delete m_handler;
+ m_handler = new XSLTHandler(dom, QFile::encodeName(xsltfile), true /*translate*/);
+ if(!m_handler->isValid()) {
+ delete m_handler;
+ m_handler = 0;
+ return false;
+ }
+
+ if(m_exportEntryFiles) {
+ // export entries to same place as all the other date files
+ m_handler->addStringParam("entrydir", QFile::encodeName(fileDir().fileName())+ '/');
+ // be sure to link all the entries
+ m_handler->addParam("link-entries", "true()");
+ }
+
+ if(!m_collectionURL.isEmpty()) {
+ QString s = QString::fromLatin1("../") + m_collectionURL.fileName();
+ m_handler->addStringParam("collection-file", s.utf8());
+ }
+
+ // look for a file that gets installed to know the installation directory
+ // if parseDOM, that means we want the locations to be the actual location
+ // otherwise, we assume it'll be relative
+ if(m_parseDOM && m_dataDir.isEmpty()) {
+ m_dataDir = KGlobal::dirs()->findResourceDir("appdata", QString::fromLatin1("pics/tellico.png"));
+ } else if(!m_parseDOM) {
+ m_dataDir.truncate(0);
+ }
+ if(!m_dataDir.isEmpty()) {
+ m_handler->addStringParam("datadir", QFile::encodeName(m_dataDir));
+ }
+
+ setFormattingOptions(collection());
+
+ return m_handler->isValid();
+}
+
+QString HTMLExporter::text() {
+ if((!m_handler || !m_handler->isValid()) && !loadXSLTFile()) {
+ kdWarning() << "HTMLExporter::text() - error loading xslt file: " << m_xsltFile << endl;
+ return QString::null;
+ }
+
+ Data::CollPtr coll = collection();
+ if(!coll) {
+ myDebug() << "HTMLExporter::text() - no collection pointer!" << endl;
+ return QString::null;
+ }
+
+ if(m_groupBy.isEmpty()) {
+ m_printGrouped = false; // can't group if no groups exist
+ }
+
+ GUI::CursorSaver cs;
+ writeImages(coll);
+
+ // now grab the XML
+ TellicoXMLExporter exporter(coll);
+ exporter.setURL(url());
+ exporter.setEntries(entries());
+ exporter.setIncludeGroups(m_printGrouped);
+// yes, this should be in utf8, always
+ exporter.setOptions(options() | Export::ExportUTF8 | Export::ExportImages);
+ QDomDocument output = exporter.exportXML();
+#if 0
+ QFile f(QString::fromLatin1("/tmp/test.xml"));
+ if(f.open(IO_WriteOnly)) {
+ QTextStream t(&f);
+ t << output.toString();
+ }
+ f.close();
+#endif
+
+ QString text = m_handler->applyStylesheet(output.toString());
+#if 0
+ QFile f2(QString::fromLatin1("/tmp/test.html"));
+ if(f2.open(IO_WriteOnly)) {
+ QTextStream t(&f2);
+ t << text;
+// t << "\n\n-------------------------------------------------------\n\n";
+// t << Tellico::i18nReplace(text);
+ }
+ f2.close();
+#endif
+ // the XSLT file gets translated instead
+// return Tellico::i18nReplace(text);
+ return text;
+}
+
+void HTMLExporter::setFormattingOptions(Data::CollPtr coll) {
+ QString file = Kernel::self()->URL().fileName();
+ if(file != i18n("Untitled")) {
+ m_handler->addStringParam("filename", QFile::encodeName(file));
+ }
+ m_handler->addStringParam("cdate", KGlobal::locale()->formatDate(QDate::currentDate()).utf8());
+ m_handler->addParam("show-headers", m_printHeaders ? "true()" : "false()");
+ m_handler->addParam("group-entries", m_printGrouped ? "true()" : "false()");
+
+ QStringList sortTitles;
+ if(!m_sort1.isEmpty()) {
+ sortTitles << m_sort1;
+ }
+ if(!m_sort2.isEmpty()) {
+ sortTitles << m_sort2;
+ }
+
+ // the third sort column may be same as first
+ if(!m_sort3.isEmpty() && sortTitles.findIndex(m_sort3) == -1) {
+ sortTitles << m_sort3;
+ }
+
+ if(sortTitles.count() > 0) {
+ m_handler->addStringParam("sort-name1", coll->fieldNameByTitle(sortTitles[0]).utf8());
+ if(sortTitles.count() > 1) {
+ m_handler->addStringParam("sort-name2", coll->fieldNameByTitle(sortTitles[1]).utf8());
+ if(sortTitles.count() > 2) {
+ m_handler->addStringParam("sort-name3", coll->fieldNameByTitle(sortTitles[2]).utf8());
+ }
+ }
+ }
+
+ // no longer showing "sorted by..." since the column headers are clickable
+ // but still use "grouped by"
+ QString sortString;
+ if(m_printGrouped) {
+ QString s;
+ // if more than one, then it's the People pseudo-group
+ if(m_groupBy.count() > 1) {
+ s = i18n("People");
+ } else {
+ s = coll->fieldTitleByName(m_groupBy[0]);
+ }
+ sortString = i18n("(grouped by %1)").arg(s);
+
+ QString groupFields;
+ for(QStringList::ConstIterator it = m_groupBy.begin(); it != m_groupBy.end(); ++it) {
+ Data::FieldPtr f = coll->fieldByName(*it);
+ if(!f) {
+ continue;
+ }
+ if(f->flags() & Data::Field::AllowMultiple) {
+ groupFields += QString::fromLatin1("tc:") + *it + QString::fromLatin1("s/tc:") + *it;
+ } else {
+ groupFields += QString::fromLatin1("tc:") + *it;
+ }
+ int ncols = 0;
+ if(f->type() == Data::Field::Table) {
+ bool ok;
+ ncols = Tellico::toUInt(f->property(QString::fromLatin1("columns")), &ok);
+ if(!ok) {
+ ncols = 1;
+ }
+ }
+ if(ncols > 1) {
+ groupFields += QString::fromLatin1("/tc:column[1]");
+ }
+ if(*it != m_groupBy.last()) {
+ groupFields += '|';
+ }
+ }
+// myDebug() << groupFields << endl;
+ m_handler->addStringParam("group-fields", groupFields.utf8());
+ m_handler->addStringParam("sort-title", sortString.utf8());
+ }
+
+ QString pageTitle = coll->title();
+ pageTitle += QChar(' ') + sortString;
+ m_handler->addStringParam("page-title", pageTitle.utf8());
+
+ QStringList showFields;
+ for(QStringList::ConstIterator it = m_columns.begin(); it != m_columns.end(); ++it) {
+ showFields << coll->fieldNameByTitle(*it);
+ }
+ m_handler->addStringParam("column-names", showFields.join(QChar(' ')).utf8());
+
+ if(m_imageWidth > 0 && m_imageHeight > 0) {
+ m_handler->addParam("image-width", QCString().setNum(m_imageWidth));
+ m_handler->addParam("image-height", QCString().setNum(m_imageHeight));
+ }
+
+ // add system colors to stylesheet
+ const int type = coll->type();
+ m_handler->addStringParam("font", Config::templateFont(type).family().latin1());
+ m_handler->addStringParam("fontsize", QCString().setNum(Config::templateFont(type).pointSize()));
+ m_handler->addStringParam("bgcolor", Config::templateBaseColor(type).name().latin1());
+ m_handler->addStringParam("fgcolor", Config::templateTextColor(type).name().latin1());
+ m_handler->addStringParam("color1", Config::templateHighlightedTextColor(type).name().latin1());
+ m_handler->addStringParam("color2", Config::templateHighlightedBaseColor(type).name().latin1());
+
+ // add locale code to stylesheet (for sorting)
+ m_handler->addStringParam("lang", KGlobal::locale()->languagesTwoAlpha().first().utf8());
+}
+
+void HTMLExporter::writeImages(Data::CollPtr coll_) {
+ // keep track of which image fields to write, this is for field names
+ StringSet imageFields;
+ for(QStringList::ConstIterator it = m_columns.begin(); it != m_columns.end(); ++it) {
+ if(coll_->fieldByTitle(*it)->type() == Data::Field::Image) {
+ imageFields.add(*it);
+ }
+ }
+
+ // all the images potentially used in the HTML export need to be written to disk
+ // if we're exporting entry files, then we'll certainly want all the image fields written
+ // if we're not exporting to a file, then we might be exporting an entry template file
+ // and so we need to write all of them too.
+ if(m_exportEntryFiles || url().isEmpty()) {
+ // add all image fields to string list
+ Data::FieldVec fields = coll_->imageFields();
+ for(Data::FieldVec::Iterator fieldIt = fields.begin(); fieldIt != fields.end(); ++fieldIt) {
+ imageFields.add(fieldIt->name());
+ }
+ }
+
+ // all of them are going to get written to tmp file
+ bool useTemp = url().isEmpty();
+ KURL imgDir;
+ QString imgDirRelative;
+ // really some convoluted logic here
+ // basically, four cases. 1) we're writing to a tmp file, for printing probably
+ // so then write all the images to the tmp directory, 2) we're exporting to HTML, and
+ // this is the main collection file, in which case m_parseDOM is always true;
+ // 3) we're exporting HTML, and this is the first entry file, for which parseDOM is true
+ // and exportEntryFiles is false. Then the image file will get copied in copyFiles() and is
+ // probably an image in the entry template. 4) we're exporting HTML, and this is not the
+ // first entry file, in which case, we want to refer directly to the target dir
+ if(useTemp) { // everything goes in the tmp dir
+ imgDir.setPath(ImageFactory::tempDir());
+ imgDirRelative = imgDir.path();
+ } else if(m_parseDOM) {
+ imgDir = fileDir(); // copy to fileDir
+ imgDirRelative = Data::Document::self()->allImagesOnDisk() ? ImageFactory::dataDir() : ImageFactory::tempDir();
+ createDir();
+ } else {
+ imgDir = fileDir();
+ imgDirRelative = KURL::relativeURL(url(), imgDir);
+ createDir();
+ }
+ m_handler->addStringParam("imgdir", QFile::encodeName(imgDirRelative));
+
+ int count = 0;
+ const int processCount = 100; // process after every 100 events
+
+ QStringList fieldsList = imageFields.toList();
+ StringSet imageSet; // track which images are written
+ for(QStringList::ConstIterator fieldName = fieldsList.begin(); fieldName != fieldsList.end(); ++fieldName) {
+ for(Data::EntryVec::ConstIterator entryIt = entries().begin(); entryIt != entries().end(); ++entryIt) {
+ QString id = entryIt->field(*fieldName);
+ // if no id or is already writen, continue
+ if(id.isEmpty() || imageSet.has(id)) {
+ continue;
+ }
+ imageSet.add(id);
+ // try writing
+ bool success = useTemp ? ImageFactory::writeCachedImage(id, ImageFactory::TempDir)
+ : ImageFactory::writeImage(id, imgDir, true);
+ if(!success) {
+ kdWarning() << "HTMLExporter::writeImages() - unable to write image file: "
+ << imgDir.path() << id << endl;
+ }
+
+ if(++count == processCount) {
+ kapp->processEvents();
+ count = 0;
+ }
+ }
+ }
+}
+
+QWidget* HTMLExporter::widget(QWidget* parent_, const char* name_/*=0*/) {
+ if(m_widget && m_widget->parent() == parent_) {
+ return m_widget;
+ }
+
+ m_widget = new QWidget(parent_, name_);
+ QVBoxLayout* l = new QVBoxLayout(m_widget);
+
+ QGroupBox* box = new QGroupBox(1, Qt::Horizontal, i18n("HTML Options"), m_widget);
+ l->addWidget(box);
+
+ m_checkPrintHeaders = new QCheckBox(i18n("Print field headers"), box);
+ QWhatsThis::add(m_checkPrintHeaders, i18n("If checked, the field names will be "
+ "printed as table headers."));
+ m_checkPrintHeaders->setChecked(m_printHeaders);
+
+ m_checkPrintGrouped = new QCheckBox(i18n("Group the entries"), box);
+ QWhatsThis::add(m_checkPrintGrouped, i18n("If checked, the entries will be grouped by "
+ "the selected field."));
+ m_checkPrintGrouped->setChecked(m_printGrouped);
+
+ m_checkExportEntryFiles = new QCheckBox(i18n("Export individual entry files"), box);
+ QWhatsThis::add(m_checkExportEntryFiles, i18n("If checked, individual files will be created for each entry."));
+ m_checkExportEntryFiles->setChecked(m_exportEntryFiles);
+
+ l->addStretch(1);
+ return m_widget;
+}
+
+void HTMLExporter::readOptions(KConfig* config_) {
+ KConfigGroup exportConfig(config_, QString::fromLatin1("ExportOptions - %1").arg(formatString()));
+ m_printHeaders = exportConfig.readBoolEntry("Print Field Headers", m_printHeaders);
+ m_printGrouped = exportConfig.readBoolEntry("Print Grouped", m_printGrouped);
+ m_exportEntryFiles = exportConfig.readBoolEntry("Export Entry Files", m_exportEntryFiles);
+
+ // read current entry export template
+ m_entryXSLTFile = Config::templateName(collection()->type());
+ m_entryXSLTFile = locate("appdata", QString::fromLatin1("entry-templates/")
+ + m_entryXSLTFile + QString::fromLatin1(".xsl"));
+}
+
+void HTMLExporter::saveOptions(KConfig* config_) {
+ KConfigGroup cfg(config_, QString::fromLatin1("ExportOptions - %1").arg(formatString()));
+ m_printHeaders = m_checkPrintHeaders->isChecked();
+ cfg.writeEntry("Print Field Headers", m_printHeaders);
+ m_printGrouped = m_checkPrintGrouped->isChecked();
+ cfg.writeEntry("Print Grouped", m_printGrouped);
+ m_exportEntryFiles = m_checkExportEntryFiles->isChecked();
+ cfg.writeEntry("Export Entry Files", m_exportEntryFiles);
+}
+
+void HTMLExporter::setXSLTFile(const QString& filename_) {
+ if(m_xsltFile == filename_) {
+ return;
+ }
+
+ m_xsltFile = filename_;
+ m_xsltFilePath = QString::null;
+ reset();
+}
+
+KURL HTMLExporter::fileDir() const {
+ if(url().isEmpty()) {
+ return KURL();
+ }
+ KURL fileDir = url();
+ // cd to directory of target URL
+ fileDir.cd(QString::fromLatin1(".."));
+ fileDir.addPath(fileDirName());
+ return fileDir;
+}
+
+QString HTMLExporter::fileDirName() const {
+ if(!m_collectionURL.isEmpty()) {
+ return QString::fromLatin1("/");
+ }
+ return url().fileName().section('.', 0, 0) + QString::fromLatin1("_files/");
+}
+
+// how ugly is this?
+const xmlChar* HTMLExporter::handleLink(const xmlChar* link_) {
+ return reinterpret_cast<xmlChar*>(qstrdup(handleLink(QString::fromUtf8(reinterpret_cast<const char*>(link_))).utf8()));
+}
+
+QString HTMLExporter::handleLink(const QString& link_) {
+ if(m_links.contains(link_)) {
+ return m_links[link_];
+ }
+ // assume that if the link_ is not relative, then we don't need to copy it
+ if(!KURL::isRelativeURL(link_)) {
+ return link_;
+ }
+
+ if(m_xsltFilePath.isEmpty()) {
+ m_xsltFilePath = locate("appdata", m_xsltFile);
+ if(m_xsltFilePath.isNull()) {
+ kdWarning() << "HTMLExporter::handleLink() - no xslt file for " << m_xsltFile << endl;
+ }
+ }
+
+ KURL u;
+ u.setPath(m_xsltFilePath);
+ u = KURL(u, link_);
+
+ // one of the "quirks" of the html export is that img src urls are set to point to
+ // the tmpDir() when exporting entry files from a collection, but those images
+ // don't actually exist, and they get copied in writeImages() instead.
+ // so we only need to keep track of the url if it exists
+ const bool exists = KIO::NetAccess::exists(u, false, 0);
+ if(exists) {
+ m_files.append(u);
+ }
+
+ // if we're exporting entry files, we want pics/ to
+ // go in pics/
+ const bool isPic = link_.startsWith(m_dataDir + QString::fromLatin1("pics/"));
+ QString midDir;
+ if(m_exportEntryFiles && isPic) {
+ midDir = QString::fromLatin1("pics/");
+ }
+ // pictures are special since they might not exist when the HTML is exported, since they might get copied later
+ // on the other hand, don't change the file location if it doesn't exist
+ if(isPic || exists) {
+ m_links.insert(link_, fileDirName() + midDir + u.fileName());
+ } else {
+ m_links.insert(link_, link_);
+ }
+ return m_links[link_];
+}
+
+const xmlChar* HTMLExporter::analyzeInternalCSS(const xmlChar* str_) {
+ return reinterpret_cast<xmlChar*>(qstrdup(analyzeInternalCSS(QString::fromUtf8(reinterpret_cast<const char*>(str_))).utf8()));
+}
+
+QString HTMLExporter::analyzeInternalCSS(const QString& str_) {
+ QString str = str_;
+ int start = 0;
+ int end = 0;
+ const QString url = QString::fromLatin1("url(");
+ for(int pos = str.find(url); pos >= 0; pos = str.find(url, pos+1)) {
+ pos += 4; // url(
+ if(str[pos] == '"' || str[pos] == '\'') {
+ ++pos;
+ }
+
+ start = pos;
+ pos = str.find(')', start);
+ end = pos;
+ if(str[pos-1] == '"' || str[pos-1] == '\'') {
+ --end;
+ }
+
+ str.replace(start, end-start, handleLink(str.mid(start, end-start)));
+ }
+ return str;
+}
+
+void HTMLExporter::createDir() {
+ if(!m_checkCreateDir) {
+ return;
+ }
+ KURL dir = fileDir();
+ if(dir.isEmpty()) {
+ myDebug() << "HTMLExporter::createDir() - called on empty URL!" << endl;
+ return;
+ }
+ if(KIO::NetAccess::exists(dir, false, 0)) {
+ m_checkCreateDir = false;
+ } else {
+ m_checkCreateDir = !KIO::NetAccess::mkdir(dir, m_widget);
+ }
+}
+
+bool HTMLExporter::copyFiles() {
+ if(m_files.isEmpty()) {
+ return true;
+ }
+ const uint start = 20;
+ const uint maxProgress = m_exportEntryFiles ? 40 : 80;
+ const uint stepSize = QMAX(1, m_files.count()/maxProgress);
+ uint j = 0;
+
+ createDir();
+ KURL target;
+ for(KURL::List::ConstIterator it = m_files.begin(); it != m_files.end() && !m_cancelled; ++it, ++j) {
+ if(m_copiedFiles.has((*it).url())) {
+ continue;
+ }
+
+ if(target.isEmpty()) {
+ target = fileDir();
+ }
+ target.setFileName((*it).fileName());
+ bool success = KIO::NetAccess::file_copy(*it, target, -1, true /* overwrite */, false /* resume */, m_widget);
+ if(success) {
+ m_copiedFiles.add((*it).url());
+ } else {
+ kdWarning() << "HTMLExporter::copyFiles() - can't copy " << target << endl;
+ kdWarning() << KIO::NetAccess::lastErrorString() << endl;
+ }
+ if(j%stepSize == 0) {
+ if(options() & ExportProgress) {
+ ProgressManager::self()->setProgress(this, QMIN(start+j/stepSize, 99));
+ }
+ kapp->processEvents();
+ }
+ }
+ return true;
+}
+
+bool HTMLExporter::writeEntryFiles() {
+ if(m_entryXSLTFile.isEmpty()) {
+ kdWarning() << "HTMLExporter::writeEntryFiles() - no entry XSLT file" << endl;
+ return false;
+ }
+
+ const uint start = 60;
+ const uint stepSize = QMAX(1, entries().count()/40);
+ uint j = 0;
+
+ // now worry about actually exporting entry files
+ // I can't reliable encode a string as a URI, so I'm punting, and I'll just replace everything but
+ // a-zA-Z0-9 with an underscore. This MUST match the filename template in tellico2html.xsl
+ // the id is used so uniqueness is guaranteed
+ const QRegExp badChars(QString::fromLatin1("[^-a-zA-Z0-9]"));
+ bool formatted = options() & Export::ExportFormatted;
+
+ KURL outputFile = fileDir();
+
+ GUI::CursorSaver cs(Qt::waitCursor);
+
+ HTMLExporter exporter(collection());
+ long opt = options() | Export::ExportForce;
+ opt &= ~ExportProgress;
+ exporter.setOptions(opt);
+ exporter.setXSLTFile(m_entryXSLTFile);
+ exporter.setCollectionURL(url());
+ bool parseDOM = true;
+
+ const QString title = QString::fromLatin1("title");
+ const QString html = QString::fromLatin1(".html");
+ bool multipleTitles = collection()->fieldByName(title)->flags() & Data::Field::AllowMultiple;
+ Data::EntryVec entries = this->entries(); // not const since the pointer has to be copied
+ for(Data::EntryVecIt entryIt = entries.begin(); entryIt != entries.end() && !m_cancelled; ++entryIt, ++j) {
+ QString file = entryIt->field(title, formatted);
+
+ // but only use the first title if it has multiple
+ if(multipleTitles) {
+ file = file.section(';', 0, 0);
+ }
+ file.replace(badChars, QChar('_'));
+ file += QChar('-') + QString::number(entryIt->id()) + html;
+ outputFile.setFileName(file);
+
+ exporter.setEntries(Data::EntryVec(entryIt));
+ exporter.setURL(outputFile);
+ exporter.exec();
+
+ // no longer need to parse DOM
+ if(parseDOM) {
+ parseDOM = false;
+ exporter.setParseDOM(false);
+ // this is rather stupid, but I'm too lazy to figure out the better way
+ // since we parsed the DOM for the first entry file to grab any
+ // images used in the template, need to resave it so the image links
+ // get written correctly
+ exporter.exec();
+ }
+
+ if(j%stepSize == 0) {
+ if(options() & ExportProgress) {
+ ProgressManager::self()->setProgress(this, QMIN(start+j/stepSize, 99));
+ }
+ kapp->processEvents();
+ }
+ }
+ // the images in "pics/" are special data images, copy them always
+ // since the entry files may refer to them, but we don't know that
+ QStringList dataImages;
+ dataImages << QString::fromLatin1("checkmark.png");
+ for(uint i = 1; i <= 10; ++i) {
+ dataImages << QString::fromLatin1("stars%1.png").arg(i);
+ }
+ KURL dataDir;
+ dataDir.setPath(KGlobal::dirs()->findResourceDir("appdata", QString::fromLatin1("pics/tellico.png")) + "pics/");
+ KURL target = fileDir();
+ target.addPath(QString::fromLatin1("pics/"));
+ KIO::NetAccess::mkdir(target, m_widget);
+ for(QStringList::ConstIterator it = dataImages.begin(); it != dataImages.end(); ++it) {
+ dataDir.setFileName(*it);
+ target.setFileName(*it);
+ KIO::NetAccess::copy(dataDir, target, m_widget);
+ }
+
+ return true;
+}
+
+void HTMLExporter::slotCancel() {
+ m_cancelled = true;
+}
+
+void HTMLExporter::parseDOM(xmlNode* node_) {
+ if(node_ == 0) {
+ myDebug() << "HTMLExporter::parseDOM() - no node" << endl;
+ return;
+ }
+
+ bool parseChildren = true;
+
+ if(node_->type == XML_ELEMENT_NODE) {
+ const QCString nodeName = QCString(reinterpret_cast<const char*>(node_->name)).upper();
+ xmlElement* elem = reinterpret_cast<xmlElement*>(node_);
+ // to speed up things, check now for nodename
+ if(nodeName == "IMG" || nodeName == "SCRIPT" || nodeName == "LINK") {
+ for(xmlAttribute* attr = elem->attributes; attr; attr = reinterpret_cast<xmlAttribute*>(attr->next)) {
+ QCString attrName = QCString(reinterpret_cast<const char*>(attr->name)).upper();
+
+ if( (attrName == "SRC" && (nodeName == "IMG" || nodeName == "SCRIPT")) ||
+ (attrName == "HREF" && nodeName == "LINK")) {
+/* (attrName == "BACKGROUND" && (nodeName == "BODY" ||
+ nodeName == "TABLE" ||
+ nodeName == "TH" ||
+ nodeName == "TD"))) */
+ xmlChar* value = xmlGetProp(node_, attr->name);
+ if(value) {
+ xmlSetProp(node_, attr->name, handleLink(value));
+ xmlFree(value);
+ }
+ // each node only has one significant attribute, so break now
+ break;
+ }
+ }
+ } else if(nodeName == "STYLE") {
+ // if the first child is a CDATA, use it, otherwise replace complete node
+ xmlNode* nodeToReplace = node_;
+ xmlNode* child = node_->children;
+ if(child && child->type == XML_CDATA_SECTION_NODE) {
+ nodeToReplace = child;
+ }
+ xmlChar* value = xmlNodeGetContent(nodeToReplace);
+ if(value) {
+ xmlNodeSetContent(nodeToReplace, analyzeInternalCSS(value));
+ xmlFree(value);
+ }
+ // no longer need to parse child text nodes
+ parseChildren = false;
+ }
+ }
+
+ if(parseChildren) {
+ xmlNode* child = node_->children;
+ while(child) {
+ parseDOM(child);
+ child = child->next;
+ }
+ }
+}
+
+#include "htmlexporter.moc"
diff --git a/src/translators/htmlexporter.h b/src/translators/htmlexporter.h
new file mode 100644
index 0000000..be89bbf
--- /dev/null
+++ b/src/translators/htmlexporter.h
@@ -0,0 +1,124 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef HTMLEXPORTER_H
+#define HTMLEXPORTER_H
+
+class QCheckBox;
+
+#include "exporter.h"
+#include "../stringset.h"
+
+#include <qstringlist.h>
+
+#include <libxml/xmlstring.h>
+
+extern "C" {
+ struct _xmlNode;
+}
+
+namespace Tellico {
+ namespace Data {
+ class Collection;
+ }
+ class XSLTHandler;
+
+ namespace Export {
+
+/**
+ * @author Robby Stephenson
+ */
+class HTMLExporter : public Exporter {
+Q_OBJECT
+
+public:
+ HTMLExporter();
+ HTMLExporter(Data::CollPtr coll);
+ ~HTMLExporter();
+
+ virtual bool exec();
+ virtual void reset();
+ virtual QString formatString() const;
+ virtual QString fileFilter() const;
+
+ virtual QWidget* widget(QWidget* parent, const char* name=0);
+ virtual void readOptions(KConfig*);
+ virtual void saveOptions(KConfig*);
+
+ void setCollectionURL(const KURL& url) { m_collectionURL = url; m_links.clear(); }
+ void setXSLTFile(const QString& filename);
+ void setPrintHeaders(bool printHeaders) { m_printHeaders = printHeaders; }
+ void setPrintGrouped(bool printGrouped) { m_printGrouped = printGrouped; }
+ void setMaxImageSize(int w, int h) { m_imageWidth = w; m_imageHeight = h; }
+ void setGroupBy(const QStringList& groupBy) { m_groupBy = groupBy; }
+ void setSortTitles(const QStringList& l)
+ { m_sort1 = l[0]; m_sort2 = l[1]; m_sort3 = l[2]; }
+ void setColumns(const QStringList& columns) { m_columns = columns; }
+ void setParseDOM(bool parseDOM) { m_parseDOM = parseDOM; reset(); }
+
+ QString text();
+
+public slots:
+ void slotCancel();
+
+private:
+ void setFormattingOptions(Data::CollPtr coll);
+ void writeImages(Data::CollPtr coll);
+ bool writeEntryFiles();
+ KURL fileDir() const;
+ QString fileDirName() const;
+
+ void parseDOM(_xmlNode* node);
+ QString handleLink(const QString& link);
+ const xmlChar* handleLink(const xmlChar* link);
+ QString analyzeInternalCSS(const QString& string);
+ const xmlChar* analyzeInternalCSS(const xmlChar* string);
+ bool copyFiles();
+ bool loadXSLTFile();
+ void createDir();
+
+ XSLTHandler* m_handler;
+ bool m_printHeaders : 1;
+ bool m_printGrouped : 1;
+ bool m_exportEntryFiles : 1;
+ bool m_cancelled : 1;
+ bool m_parseDOM : 1;
+ bool m_checkCreateDir : 1;
+ int m_imageWidth;
+ int m_imageHeight;
+
+ QWidget* m_widget;
+ QCheckBox* m_checkPrintHeaders;
+ QCheckBox* m_checkPrintGrouped;
+ QCheckBox* m_checkExportEntryFiles;
+ QCheckBox* m_checkExportImages;
+
+ KURL m_collectionURL;
+ QString m_xsltFile;
+ QString m_xsltFilePath;
+ QString m_dataDir;
+ QStringList m_groupBy;
+ QString m_sort1;
+ QString m_sort2;
+ QString m_sort3;
+ QStringList m_columns;
+ QString m_entryXSLTFile;
+
+ KURL::List m_files;
+ QMap<QString, QString> m_links;
+ StringSet m_copiedFiles;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/importer.h b/src/translators/importer.h
new file mode 100644
index 0000000..4df5ccb
--- /dev/null
+++ b/src/translators/importer.h
@@ -0,0 +1,137 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef IMPORTER_H
+#define IMPORTER_H
+
+class QWidget;
+
+#include "../datavectors.h"
+
+#include <klocale.h>
+#include <kurl.h>
+
+#include <qobject.h>
+#include <qstring.h>
+
+namespace Tellico {
+ namespace Import {
+ enum Options {
+ ImportProgress = 1 << 5 // show progress bar
+ };
+
+/**
+ * The top-level abstract class for importing other document formats into Tellico.
+ *
+ * The Importer classes import a file, and return a pointer to a newly created
+ * @ref Data::Collection. Any errors or warnings are added to a status message queue.
+ * The calling function owns the collection pointer.
+ *
+ * @author Robby Stephenson
+ */
+class Importer : public QObject {
+Q_OBJECT
+
+public:
+ Importer() : QObject(), m_options(ImportProgress) {}
+ /**
+ * The constructor should immediately load the contents of the file to be imported.
+ * Any warnings or errors should be added the the status message queue.
+ *
+ * @param url The URL of the file to import
+ */
+ Importer(const KURL& url) : QObject(), m_options(ImportProgress), m_urls(url) {}
+ Importer(const KURL::List& urls) : QObject(), m_options(ImportProgress), m_urls(urls) {}
+ Importer(const QString& text) : QObject(), m_options(ImportProgress), m_text(text) {}
+ /**
+ */
+ virtual ~Importer() {}
+
+ /**
+ * Returns a pointer to a @ref Data::Collection containing the contents of the imported file.
+ * This function should probably only be called once, but the subclasses may cache the
+ * collection. The collection should not be created until this function is called.
+ *
+ * @return A pointer to a @ref Collection created on the stack, or 0 if none could be created.
+ */
+ virtual Data::CollPtr collection() = 0;
+ /**
+ * Returns a string containing all the messages added to the queue in the course of loading
+ * and importing the file.
+ *
+ * @return The status message
+ */
+ const QString& statusMessage() const { return m_statusMsg; }
+ /**
+ * Returns a widget with the setting specific to this importer, or 0 if no
+ * options are needed.
+ *
+ * @return A pointer to the setting widget
+ */
+ virtual QWidget* widget(QWidget*, const char*) { return 0; }
+ /**
+ * Checks to see if the importer can return a collection of this type
+ *
+ * @param type The collection type to check
+ * @return Whether the importer could return a collection of that type
+ */
+ virtual bool canImport(int) const { return true; }
+ /**
+ * Validate the import settings
+ */
+ virtual bool validImport() const { return true; }
+ virtual void setText(const QString& text) { m_text = text; }
+ long options() const { return m_options; }
+ void setOptions(long options) { m_options = options; }
+ /**
+ * Returns a string useful for the ProgressManager
+ */
+ QString progressLabel() const {
+ if(url().isEmpty()) return i18n("Loading data..."); else return i18n("Loading %1...").arg(url().fileName());
+ }
+
+public slots:
+ /**
+ * The import action was changed in the import dialog
+ */
+ virtual void slotActionChanged(int) {}
+
+protected:
+ /**
+ * Return the URL of the imported file.
+ *
+ * @return the file URL
+ */
+ KURL url() const { return m_urls.isEmpty() ? KURL() : m_urls[0]; }
+ KURL::List urls() const { return m_urls; }
+ QString text() const { return m_text; }
+ /**
+ * Adds a message to the status queue.
+ *
+ * @param msg A string containing a warning or error.
+ */
+ void setStatusMessage(const QString& msg) { if(!msg.isEmpty()) m_statusMsg += msg + QChar(' '); }
+
+ static const uint s_stepSize;
+
+private:
+ long m_options;
+ KURL::List m_urls;
+ QString m_text;
+ QString m_statusMsg;
+};
+
+ } // end namespace
+} // end namespace
+
+#endif
diff --git a/src/translators/libcsv.c b/src/translators/libcsv.c
new file mode 100644
index 0000000..4e53f63
--- /dev/null
+++ b/src/translators/libcsv.c
@@ -0,0 +1,490 @@
+/*
+libcsv - parse and write csv data
+Copyright (C) 2007 Robert Gamble
+
+ available at http://libcsv.sf.net
+
+ Original available under the terms of the GNU LGPL2, and according
+ to those terms, relicensed under the GNU GPL2 for inclusion in Tellico */
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#if ___STDC_VERSION__ >= 199901L
+# include <stdint.h>
+#else
+# define SIZE_MAX ((size_t)-1) /* C89 doesn't have stdint.h or SIZE_MAX */
+#endif
+
+#include "libcsv.h"
+
+#define VERSION "2.0.0"
+
+#define ROW_NOT_BEGUN 0
+#define FIELD_NOT_BEGUN 1
+#define FIELD_BEGUN 2
+#define FIELD_MIGHT_HAVE_ENDED 3
+
+/*
+ Explanation of states
+ ROW_NOT_BEGUN There have not been any fields encountered for this row
+ FIELD_NOT_BEGUN There have been fields but we are currently not in one
+ FIELD_BEGUN We are in a field
+ FIELD_MIGHT_HAVE_ENDED
+ We encountered a double quote inside a quoted field, the
+ field is either ended or the quote is literal
+*/
+
+#define MEM_BLK_SIZE 128
+
+#define SUBMIT_FIELD(p) \
+ do { \
+ if (!quoted) \
+ entry_pos -= spaces; \
+ if (cb1) \
+ cb1(p->entry_buf, entry_pos, data); \
+ pstate = FIELD_NOT_BEGUN; \
+ entry_pos = quoted = spaces = 0; \
+ } while (0)
+
+#define SUBMIT_ROW(p, c) \
+ do { \
+ if (cb2) \
+ cb2(c, data); \
+ pstate = ROW_NOT_BEGUN; \
+ entry_pos = quoted = spaces = 0; \
+ } while (0)
+
+#define SUBMIT_CHAR(p, c) ((p)->entry_buf[entry_pos++] = (c))
+
+static char *csv_errors[] = {"success",
+ "error parsing data while strict checking enabled",
+ "memory exhausted while increasing buffer size",
+ "data size too large",
+ "invalid status code"};
+
+int
+csv_error(struct csv_parser *p)
+{
+ return p->status;
+}
+
+char *
+csv_strerror(int status)
+{
+ if (status >= CSV_EINVALID || status < 0)
+ return csv_errors[CSV_EINVALID];
+ else
+ return csv_errors[status];
+}
+
+int
+csv_opts(struct csv_parser *p, unsigned char options)
+{
+ if (p == NULL)
+ return -1;
+
+ p->options = options;
+ return 0;
+}
+
+int
+csv_init(struct csv_parser **p, unsigned char options)
+{
+ /* Initialize a csv_parser object returns 0 on success, -1 on error */
+ if (p == NULL)
+ return -1;
+
+ if ((*p = malloc(sizeof(struct csv_parser))) == NULL)
+ return -1;
+
+ if ( ((*p)->entry_buf = malloc(MEM_BLK_SIZE)) == NULL ) {
+ free(*p);
+ return -1;
+ }
+ (*p)->pstate = ROW_NOT_BEGUN;
+ (*p)->quoted = 0;
+ (*p)->spaces = 0;
+ (*p)->entry_pos = 0;
+ (*p)->entry_size = MEM_BLK_SIZE;
+ (*p)->status = 0;
+ (*p)->options = options;
+ (*p)->quote_char = CSV_QUOTE;
+ (*p)->delim_char = CSV_COMMA;
+ (*p)->is_space = NULL;
+ (*p)->is_term = NULL;
+
+ return 0;
+}
+
+void
+csv_free(struct csv_parser *p)
+{
+ /* Free the entry_buffer and the csv_parser object */
+ if (p == NULL)
+ return;
+
+ if (p->entry_buf)
+ free(p->entry_buf);
+
+ free(p);
+ return;
+}
+
+int
+csv_fini(struct csv_parser *p, void (*cb1)(char *, size_t, void *), void (*cb2)(char c, void *), void *data)
+{
+ /* Finalize parsing. Needed, for example, when file does not end in a newline */
+ int quoted = p->quoted;
+ int pstate = p->pstate;
+ size_t spaces = p->spaces;
+ size_t entry_pos = p->entry_pos;
+
+ if (p == NULL)
+ return -1;
+
+
+ if (p->pstate == FIELD_BEGUN && p->quoted && p->options & CSV_STRICT && p->options & CSV_STRICT_FINI) {
+ p->status = CSV_EPARSE;
+ return -1;
+ }
+
+ switch (p->pstate) {
+ case FIELD_MIGHT_HAVE_ENDED:
+ p->entry_pos -= p->spaces + 1; /* get rid of spaces and original quote */
+ case FIELD_NOT_BEGUN:
+ case FIELD_BEGUN:
+ quoted = p->quoted, pstate = p->pstate;
+ spaces = p->spaces, entry_pos = p->entry_pos;
+ SUBMIT_FIELD(p);
+ SUBMIT_ROW(p, 0);
+ case ROW_NOT_BEGUN: /* Already ended properly */
+ ;
+ }
+
+ p->spaces = p->quoted = p->entry_pos = p->status = 0;
+ p->pstate = ROW_NOT_BEGUN;
+
+ return 0;
+}
+
+void
+csv_set_delim(struct csv_parser *p, char c)
+{
+ if (p) p->delim_char = c;
+}
+
+void
+csv_set_quote(struct csv_parser *p, char c)
+{
+ if (p) p->quote_char = c;
+}
+
+char
+csv_get_delim(struct csv_parser *p)
+{
+ return p->delim_char;
+}
+
+char
+csv_get_quote(struct csv_parser *p)
+{
+ return p->quote_char;
+}
+
+void
+csv_set_space_func(struct csv_parser *p, int (*f)(char))
+{
+ if (p) p->is_space = f;
+}
+
+void
+csv_set_term_func(struct csv_parser *p, int (*f)(char))
+{
+ if (p) p->is_term = f;
+}
+
+static int
+csv_increase_buffer(struct csv_parser *p)
+{
+ size_t to_add = MEM_BLK_SIZE;
+ void *vp;
+ while ( p->entry_size >= SIZE_MAX - to_add )
+ to_add /= 2;
+ if (!to_add) {
+ p->status = CSV_ETOOBIG;
+ return -1;
+ }
+ while ((vp = realloc(p->entry_buf, p->entry_size + to_add)) == NULL) {
+ to_add /= 2;
+ if (!to_add) {
+ p->status = CSV_ENOMEM;
+ return -1;
+ }
+ }
+ p->entry_buf = vp;
+ p->entry_size += to_add;
+ return 0;
+}
+
+size_t
+csv_parse(struct csv_parser *p, const char *s, size_t len, void (*cb1)(char *, size_t, void *), void (*cb2)(char c, void *), void *data)
+{
+ char c; /* The character we are currently processing */
+ size_t pos = 0; /* The number of characters we have processed in this call */
+ char delim = p->delim_char;
+ char quote = p->quote_char;
+ int (*is_space)(char) = p->is_space;
+ int (*is_term)(char) = p->is_term;
+ int quoted = p->quoted;
+ int pstate = p->pstate;
+ size_t spaces = p->spaces;
+ size_t entry_pos = p->entry_pos;
+
+ while (pos < len) {
+ /* Check memory usage */
+ if (entry_pos == p->entry_size)
+ if (csv_increase_buffer(p) != 0) {
+ p->quoted = quoted, p->pstate = pstate, p->spaces = spaces, p->entry_pos = entry_pos;
+ return pos;
+ }
+
+ c = s[pos++];
+ switch (pstate) {
+ case ROW_NOT_BEGUN:
+ case FIELD_NOT_BEGUN:
+ if (is_space ? is_space(c) : c == CSV_SPACE || c == CSV_TAB) { /* Space or Tab */
+ continue;
+ } else if (is_term ? is_term(c) : c == CSV_CR || c == CSV_LF) { /* Carriage Return or Line Feed */
+ if (pstate == FIELD_NOT_BEGUN) {
+ SUBMIT_FIELD(p);
+ SUBMIT_ROW(p, c);
+ } else { /* ROW_NOT_BEGUN */
+ /* Don't submit empty rows by default */
+ if (p->options & CSV_REPALL_NL) {
+ SUBMIT_ROW(p, c);
+ }
+ }
+ continue;
+ } else if (c == delim) { /* Comma */
+ SUBMIT_FIELD(p);
+ break;
+ } else if (c == quote) { /* Quote */
+ pstate = FIELD_BEGUN;
+ quoted = 1;
+ } else { /* Anything else */
+ pstate = FIELD_BEGUN;
+ quoted = 0;
+ SUBMIT_CHAR(p, c);
+ }
+ break;
+ case FIELD_BEGUN:
+ if (c == quote) { /* Quote */
+ if (quoted) {
+ SUBMIT_CHAR(p, c);
+ pstate = FIELD_MIGHT_HAVE_ENDED;
+ } else {
+ /* STRICT ERROR - double quote inside non-quoted field */
+ if (p->options & CSV_STRICT) {
+ p->status = CSV_EPARSE;
+ p->quoted = quoted, p->pstate = pstate, p->spaces = spaces, p->entry_pos = entry_pos;
+ return pos-1;
+ }
+ SUBMIT_CHAR(p, c);
+ spaces = 0;
+ }
+ } else if (c == delim) { /* Comma */
+ if (quoted) {
+ SUBMIT_CHAR(p, c);
+ } else {
+ SUBMIT_FIELD(p);
+ }
+ } else if (is_term ? is_term(c) : c == CSV_CR || c == CSV_LF) { /* Carriage Return or Line Feed */
+ if (!quoted) {
+ SUBMIT_FIELD(p);
+ SUBMIT_ROW(p, c);
+ } else {
+ SUBMIT_CHAR(p, c);
+ }
+ } else if (!quoted && (is_space? is_space(c) : c == CSV_SPACE || c == CSV_TAB)) { /* Tab or space for non-quoted field */
+ SUBMIT_CHAR(p, c);
+ spaces++;
+ } else { /* Anything else */
+ SUBMIT_CHAR(p, c);
+ spaces = 0;
+ }
+ break;
+ case FIELD_MIGHT_HAVE_ENDED:
+ /* This only happens when a quote character is encountered in a quoted field */
+ if (c == delim) { /* Comma */
+ entry_pos -= spaces + 1; /* get rid of spaces and original quote */
+ SUBMIT_FIELD(p);
+ } else if (is_term ? is_term(c) : c == CSV_CR || c == CSV_LF) { /* Carriage Return or Line Feed */
+ entry_pos -= spaces + 1; /* get rid of spaces and original quote */
+ SUBMIT_FIELD(p);
+ SUBMIT_ROW(p, c);
+ } else if (is_space ? is_space(c) : c == CSV_SPACE || c == CSV_TAB) { /* Space or Tab */
+ SUBMIT_CHAR(p, c);
+ spaces++;
+ } else if (c == quote) { /* Quote */
+ if (spaces) {
+ /* STRICT ERROR - unescaped double quote */
+ if (p->options & CSV_STRICT) {
+ p->status = CSV_EPARSE;
+ p->quoted = quoted, p->pstate = pstate, p->spaces = spaces, p->entry_pos = entry_pos;
+ return pos-1;
+ }
+ spaces = 0;
+ SUBMIT_CHAR(p, c);
+ } else {
+ /* Two quotes in a row */
+ pstate = FIELD_BEGUN;
+ }
+ } else { /* Anything else */
+ /* STRICT ERROR - unescaped double quote */
+ if (p->options & CSV_STRICT) {
+ p->status = CSV_EPARSE;
+ p->quoted = quoted, p->pstate = pstate, p->spaces = spaces, p->entry_pos = entry_pos;
+ return pos-1;
+ }
+ pstate = FIELD_BEGUN;
+ spaces = 0;
+ SUBMIT_CHAR(p, c);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ p->quoted = quoted, p->pstate = pstate, p->spaces = spaces, p->entry_pos = entry_pos;
+ return pos;
+}
+
+size_t
+csv_write (char *dest, size_t dest_size, const char *src, size_t src_size)
+{
+ size_t chars = 0;
+
+ if (src == NULL)
+ return 0;
+
+ if (dest == NULL)
+ dest_size = 0;
+
+ if (dest_size > 0)
+ *dest++ = '"';
+ chars++;
+
+ while (src_size) {
+ if (*src == '"') {
+ if (dest_size > chars)
+ *dest++ = '"';
+ if (chars < SIZE_MAX) chars++;
+ }
+ if (dest_size > chars)
+ *dest++ = *src;
+ if (chars < SIZE_MAX) chars++;
+ src_size--;
+ src++;
+ }
+
+ if (dest_size > chars)
+ *dest = '"';
+ if (chars < SIZE_MAX) chars++;
+
+ return chars;
+}
+
+int
+csv_fwrite (FILE *fp, const char *src, size_t src_size)
+{
+ if (fp == NULL || src == NULL)
+ return 0;
+
+ if (fputc('"', fp) == EOF)
+ return EOF;
+
+ while (src_size) {
+ if (*src == '"') {
+ if (fputc('"', fp) == EOF)
+ return EOF;
+ }
+ if (fputc(*src, fp) == EOF)
+ return EOF;
+ src_size--;
+ src++;
+ }
+
+ if (fputc('"', fp) == EOF) {
+ return EOF;
+ }
+
+ return 0;
+}
+
+size_t
+csv_write2 (char *dest, size_t dest_size, const char *src, size_t src_size, char quote)
+{
+ size_t chars = 0;
+
+ if (src == NULL)
+ return 0;
+
+ if (dest == NULL)
+ dest_size = 0;
+
+ if (dest_size > 0)
+ *dest++ = quote;
+ chars++;
+
+ while (src_size) {
+ if (*src == quote) {
+ if (dest_size > chars)
+ *dest++ = quote;
+ if (chars < SIZE_MAX) chars++;
+ }
+ if (dest_size > chars)
+ *dest++ = *src;
+ if (chars < SIZE_MAX) chars++;
+ src_size--;
+ src++;
+ }
+
+ if (dest_size > chars)
+ *dest = quote;
+ if (chars < SIZE_MAX) chars++;
+
+ return chars;
+}
+
+int
+csv_fwrite2 (FILE *fp, const char *src, size_t src_size, char quote)
+{
+ if (fp == NULL || src == NULL)
+ return 0;
+
+ if (fputc(quote, fp) == EOF)
+ return EOF;
+
+ while (src_size) {
+ if (*src == quote) {
+ if (fputc(quote, fp) == EOF)
+ return EOF;
+ }
+ if (fputc(*src, fp) == EOF)
+ return EOF;
+ src_size--;
+ src++;
+ }
+
+ if (fputc(quote, fp) == EOF) {
+ return EOF;
+ }
+
+ return 0;
+}
diff --git a/src/translators/libcsv.h b/src/translators/libcsv.h
new file mode 100644
index 0000000..9058192
--- /dev/null
+++ b/src/translators/libcsv.h
@@ -0,0 +1,84 @@
+/*
+libcsv - parse and write csv data
+Copyright (C) 2007 Robert Gamble
+
+ available at http://libcsv.sf.net
+
+ Original available under the terms of the GNU LGPL2, and according
+ to those terms, relicensed under the GNU GPL2 for inclusion in Tellico */
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+
+#ifndef LIBCSV_H__
+#define LIBCSV_H__
+#include <stdlib.h>
+#include <stdio.h>
+
+#define CSV_MAJOR 2
+#define CSV_MINOR 0
+#define CSV_RELEASE 1
+
+/* Error Codes */
+#define CSV_SUCCESS 0
+#define CSV_EPARSE 1 /* Parse error in strict mode */
+#define CSV_ENOMEM 2 /* Out of memory while increasing buffer size */
+#define CSV_ETOOBIG 3 /* Buffer larger than SIZE_MAX needed */
+#define CSV_EINVALID 4 /* Invalid code,should never be received from csv_error*/
+
+
+/* parser options */
+#define CSV_STRICT 1 /* enable strict mode */
+#define CSV_REPALL_NL 2 /* report all unquoted carriage returns and linefeeds */
+#define CSV_STRICT_FINI 4 /* causes csv_fini to return CSV_EPARSE if last
+ field is quoted and doesn't containg ending
+ quote */
+
+/* Character values */
+#define CSV_TAB 0x09
+#define CSV_SPACE 0x20
+#define CSV_CR 0x0d
+#define CSV_LF 0x0a
+#define CSV_COMMA 0x2c
+#define CSV_QUOTE 0x22
+
+struct csv_parser {
+ int pstate; /* Parser state */
+ int quoted; /* Is the current field a quoted field? */
+ size_t spaces; /* Number of continious spaces after quote or in a non-quoted field */
+ char * entry_buf; /* Entry buffer */
+ size_t entry_pos; /* Current position in entry_buf (and current size of entry) */
+ size_t entry_size; /* Size of buffer */
+ int status; /* Operation status */
+ unsigned char options;
+ char quote_char;
+ char delim_char;
+ int (*is_space)(char);
+ int (*is_term)(char);
+};
+
+int csv_init(struct csv_parser **p, unsigned char options);
+int csv_fini(struct csv_parser *p, void (*cb1)(char *, size_t, void *), void (*cb2)(char, void *), void *data);
+void csv_free(struct csv_parser *p);
+int csv_error(struct csv_parser *p);
+char * csv_strerror(int error);
+size_t csv_parse(struct csv_parser *p, const char *s, size_t len, void (*cb1)(char *, size_t, void *), void (*cb2)(char, void *), void *data);
+size_t csv_write(char *dest, size_t dest_size, const char *src, size_t src_size);
+int csv_fwrite(FILE *fp, const char *src, size_t src_size);
+size_t csv_write2(char *dest, size_t dest_size, const char *src, size_t src_size, char quote);
+int csv_fwrite2(FILE *fp, const char *src, size_t src_size, char quote);
+int csv_opts(struct csv_parser *p, unsigned char options);
+void csv_set_delim(struct csv_parser *p, char c);
+void csv_set_quote(struct csv_parser *p, char c);
+char csv_get_delim(struct csv_parser *p);
+char csv_get_quote(struct csv_parser *p);
+void csv_set_space_func(struct csv_parser *p, int (*f)(char));
+void csv_set_term_func(struct csv_parser *p, int (*f)(char));
+
+#endif
diff --git a/src/translators/onixexporter.cpp b/src/translators/onixexporter.cpp
new file mode 100644
index 0000000..4479b2f
--- /dev/null
+++ b/src/translators/onixexporter.cpp
@@ -0,0 +1,199 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "onixexporter.h"
+#include "xslthandler.h"
+#include "tellicoxmlexporter.h"
+#include "../collection.h"
+#include "../filehandler.h"
+#include "../tellico_utils.h"
+#include "../imagefactory.h"
+#include "../image.h"
+#include "../tellico_debug.h"
+
+#include <config.h>
+
+#include <kstandarddirs.h>
+#include <kapplication.h>
+#include <kzip.h>
+#include <kconfig.h>
+#include <klocale.h>
+
+#include <qdom.h>
+#include <qfile.h>
+#include <qdatetime.h>
+#include <qbuffer.h>
+#include <qlayout.h>
+#include <qwhatsthis.h>
+#include <qcheckbox.h>
+#include <qgroupbox.h>
+
+using Tellico::Export::ONIXExporter;
+
+ONIXExporter::ONIXExporter() : Tellico::Export::Exporter(),
+ m_handler(0),
+ m_xsltFile(QString::fromLatin1("tellico2onix.xsl")),
+ m_includeImages(true),
+ m_widget(0) {
+}
+
+ONIXExporter::ONIXExporter(Data::CollPtr coll_) : Tellico::Export::Exporter(coll_),
+ m_handler(0),
+ m_xsltFile(QString::fromLatin1("tellico2onix.xsl")),
+ m_includeImages(true),
+ m_widget(0) {
+}
+
+ONIXExporter::~ONIXExporter() {
+ delete m_handler;
+ m_handler = 0;
+}
+
+QString ONIXExporter::formatString() const {
+ return i18n("ONIX Archive");
+}
+
+QString ONIXExporter::fileFilter() const {
+ return i18n("*.zip|Zip Files (*.zip)") + QChar('\n') + i18n("*|All Files");
+}
+
+bool ONIXExporter::exec() {
+ Data::CollPtr coll = collection();
+ if(!coll) {
+ return false;
+ }
+
+ QCString xml = text().utf8(); // encoded in utf-8
+
+ QByteArray data;
+ QBuffer buf(data);
+
+ KZip zip(&buf);
+ zip.open(IO_WriteOnly);
+ zip.writeFile(QString::fromLatin1("onix.xml"), QString::null, QString::null, xml.length(), xml);
+
+ // use a dict for fast random access to keep track of which images were written to the file
+ if(m_includeImages) { // for now, we're ignoring (options() & Export::ExportImages)
+ const QString cover = QString::fromLatin1("cover");
+ StringSet imageSet;
+ for(Data::EntryVec::ConstIterator it = entries().begin(); it != entries().end(); ++it) {
+ const Data::Image& img = ImageFactory::imageById(it->field(cover));
+ if(!img.isNull() && !imageSet.has(img.id())
+ && (img.format() == "JPEG" || img.format() == "JPG" || img.format() == "GIF")) { /// onix only understands jpeg and gif
+ QByteArray ba = img.byteArray();
+ zip.writeFile(QString::fromLatin1("images/") + it->field(cover),
+ QString::null, QString::null, ba.size(), ba);
+ imageSet.add(img.id());
+ }
+ }
+ }
+
+ zip.close();
+ return FileHandler::writeDataURL(url(), data, options() & Export::ExportForce);
+// return FileHandler::writeTextURL(url(), text(), options() & Export::ExportUTF8, options() & Export::ExportForce);
+}
+
+QString ONIXExporter::text() {
+ QString xsltfile = locate("appdata", m_xsltFile);
+ if(xsltfile.isNull()) {
+ myDebug() << "ONIXExporter::text() - no xslt file for " << m_xsltFile << endl;
+ return QString::null;
+ }
+
+ Data::CollPtr coll = collection();
+ if(!coll) {
+ myDebug() << "ONIXExporter::text() - no collection pointer!" << endl;
+ return QString::null;
+ }
+
+ // notes about utf-8 encoding:
+ // all params should be passed to XSLTHandler in utf8
+ // input string to XSLTHandler should be in utf-8, EVEN IF DOM STRING SAYS OTHERWISE
+
+ KURL u;
+ u.setPath(xsltfile);
+ // do NOT do namespace processing, it messes up the XSL declaration since
+ // QDom thinks there are no elements in the Tellico namespace and as a result
+ // removes the namespace declaration
+ QDomDocument dom = FileHandler::readXMLFile(u, false);
+ if(dom.isNull()) {
+ myDebug() << "ONIXExporter::text() - error loading xslt file: " << xsltfile << endl;
+ return QString::null;
+ }
+
+ // the stylesheet prints utf-8 by default, if using locale encoding, need
+ // to change the encoding attribute on the xsl:output element
+ if(!(options() & Export::ExportUTF8)) {
+ XSLTHandler::setLocaleEncoding(dom);
+ }
+
+ delete m_handler;
+ m_handler = new XSLTHandler(dom, QFile::encodeName(xsltfile));
+
+ QDateTime now = QDateTime::currentDateTime();
+ m_handler->addStringParam("sentDate", now.toString(QString::fromLatin1("yyyyMMddhhmm")).utf8());
+
+ m_handler->addStringParam("version", VERSION);
+
+ GUI::CursorSaver cs(Qt::waitCursor);
+
+ // now grab the XML
+ TellicoXMLExporter exporter(coll);
+ exporter.setEntries(entries());
+ exporter.setIncludeImages(false); // do not include images in XML
+// yes, this should be in utf8, always
+ exporter.setOptions(options() | Export::ExportUTF8);
+ QDomDocument output = exporter.exportXML();
+#if 0
+ QFile f(QString::fromLatin1("/tmp/test.xml"));
+ if(f.open(IO_WriteOnly)) {
+ QTextStream t(&f);
+ t << output.toString();
+ }
+ f.close();
+#endif
+ return m_handler->applyStylesheet(output.toString());
+}
+
+QWidget* ONIXExporter::widget(QWidget* parent_, const char* name_/*=0*/) {
+ if(m_widget && m_widget->parent() == parent_) {
+ return m_widget;
+ }
+
+ m_widget = new QWidget(parent_, name_);
+ QVBoxLayout* l = new QVBoxLayout(m_widget);
+
+ QGroupBox* box = new QGroupBox(1, Qt::Horizontal, i18n("ONIX Archive Options"), m_widget);
+ l->addWidget(box);
+
+ m_checkIncludeImages = new QCheckBox(i18n("Include images in archive"), box);
+ m_checkIncludeImages->setChecked(m_includeImages);
+ QWhatsThis::add(m_checkIncludeImages, i18n("If checked, the images in the document will be included "
+ "in the zipped ONIX archive."));
+
+ return m_widget;
+}
+
+void ONIXExporter::readOptions(KConfig* config_) {
+ KConfigGroup group(config_, QString::fromLatin1("ExportOptions - %1").arg(formatString()));
+ m_includeImages = group.readBoolEntry("Include Images", m_includeImages);
+}
+
+void ONIXExporter::saveOptions(KConfig* config_) {
+ m_includeImages = m_checkIncludeImages->isChecked();
+
+ KConfigGroup group(config_, QString::fromLatin1("ExportOptions - %1").arg(formatString()));
+ group.writeEntry("Include Images", m_includeImages);
+}
+
+#include "onixexporter.moc"
diff --git a/src/translators/onixexporter.h b/src/translators/onixexporter.h
new file mode 100644
index 0000000..19d52dd
--- /dev/null
+++ b/src/translators/onixexporter.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef ONIXEXPORTER_H
+#define ONIXEXPORTER_H
+
+class QCheckBox;
+
+#include "exporter.h"
+
+namespace Tellico {
+ namespace Data {
+ class Collection;
+ }
+ class XSLTHandler;
+ namespace Export {
+
+/**
+ * @author Robby Stephenson
+ */
+class ONIXExporter : public Exporter {
+Q_OBJECT
+
+public:
+ ONIXExporter();
+ ONIXExporter(Data::CollPtr coll);
+ ~ONIXExporter();
+
+ virtual bool exec();
+ virtual QString formatString() const;
+ virtual QString fileFilter() const;
+
+ virtual QWidget* widget(QWidget*, const char* name=0);
+ virtual void readOptions(KConfig*);
+ virtual void saveOptions(KConfig*);
+
+ QString text();
+
+private:
+ XSLTHandler* m_handler;
+ QString m_xsltFile;
+ bool m_includeImages;
+
+ QWidget* m_widget;
+ QCheckBox* m_checkIncludeImages;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/pdfimporter.cpp b/src/translators/pdfimporter.cpp
new file mode 100644
index 0000000..2d59b33
--- /dev/null
+++ b/src/translators/pdfimporter.cpp
@@ -0,0 +1,281 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "pdfimporter.h"
+#include "tellicoimporter.h"
+#include "xslthandler.h"
+#include "../collections/bibtexcollection.h"
+#include "../xmphandler.h"
+#include "../filehandler.h"
+#include "../imagefactory.h"
+#include "../tellico_kernel.h"
+#include "../fetch/fetchmanager.h"
+#include "../fetch/crossreffetcher.h"
+#include "../tellico_utils.h"
+#include "../progressmanager.h"
+#include "../core/netaccess.h"
+#include "../tellico_debug.h"
+
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+
+#include <config.h>
+#ifdef HAVE_POPPLER
+#include <poppler-qt.h>
+#endif
+
+namespace {
+ static const int PDF_FILE_PREVIEW_SIZE = 196;
+}
+
+using Tellico::Import::PDFImporter;
+
+PDFImporter::PDFImporter(const KURL::List& urls_) : Importer(urls_), m_cancelled(false) {
+}
+
+bool PDFImporter::canImport(int type_) const {
+ return type_ == Data::Collection::Bibtex;
+}
+
+Tellico::Data::CollPtr PDFImporter::collection() {
+ QString xsltfile = ::locate("appdata", QString::fromLatin1("xmp2tellico.xsl"));
+ if(xsltfile.isEmpty()) {
+ kdWarning() << "DropHandler::handleURL() - can not locate xmp2tellico.xsl" << endl;
+ return 0;
+ }
+
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, progressLabel(), true);
+ item.setTotalSteps(urls().count());
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+ ProgressItem::Done done(this);
+ const bool showProgress = options() & ImportProgress;
+
+ KURL u;
+ u.setPath(xsltfile);
+
+ XSLTHandler xsltHandler(u);
+ if(!xsltHandler.isValid()) {
+ kdWarning() << "DropHandler::handleURL() - invalid xslt in xmp2tellico.xsl" << endl;
+ return 0;
+ }
+
+ bool hasDOI = false;
+ bool hasArxiv = false;
+
+ uint j = 0;
+
+ Data::CollPtr coll;
+ XMPHandler xmpHandler;
+ KURL::List list = urls();
+ for(KURL::List::Iterator it = list.begin(); it != list.end() && !m_cancelled; ++it, ++j) {
+ FileHandler::FileRef* ref = FileHandler::fileRef(*it);
+ if(!ref) {
+ continue;
+ }
+
+ Data::CollPtr newColl;
+ Data::EntryPtr entry;
+
+ QString xmp = xmpHandler.extractXMP(ref->fileName());
+ // myDebug() << xmp << endl;
+ if(xmp.isEmpty()) {
+ setStatusMessage(i18n("Tellico was unable to read any metadata from the PDF file."));
+ } else {
+ setStatusMessage(QString());
+
+ Import::TellicoImporter importer(xsltHandler.applyStylesheet(xmp));
+ newColl = importer.collection();
+ if(!newColl || newColl->entryCount() == 0) {
+ kdWarning() << "DropHandler::handleURL() - no collection found" << endl;
+ setStatusMessage(i18n("Tellico was unable to read any metadata from the PDF file."));
+ } else {
+ entry = newColl->entries().front();
+ hasDOI |= !entry->field(QString::fromLatin1("doi")).isEmpty();
+ }
+ }
+
+ if(!newColl) {
+ newColl = new Data::BibtexCollection(true);
+ }
+ if(!entry) {
+ entry = new Data::Entry(newColl);
+ newColl->addEntries(entry);
+ }
+
+#ifdef HAVE_POPPLER
+
+ // now load from poppler
+ Poppler::Document* doc = Poppler::Document::load(ref->fileName());
+ if(doc && !doc->isLocked()) {
+ // now the question is, do we overwrite XMP data with Poppler data?
+ // for now, let's say yes conditionally
+ QString s = doc->getInfo(QString::fromLatin1("Title")).simplifyWhiteSpace();
+ if(!s.isEmpty()) {
+ entry->setField(QString::fromLatin1("title"), s);
+ }
+ // author could be separated by commas, "and" or whatever
+ // we're not going to overwrite it
+ if(entry->field(QString::fromLatin1("author")).isEmpty()) {
+ QRegExp rx(QString::fromLatin1("\\s*(and|,|;)\\s*"));
+ QStringList authors = QStringList::split(rx, doc->getInfo(QString::fromLatin1("Author")).simplifyWhiteSpace());
+ entry->setField(QString::fromLatin1("author"), authors.join(QString::fromLatin1("; ")));
+ }
+ s = doc->getInfo(QString::fromLatin1("Keywords")).simplifyWhiteSpace();
+ if(!s.isEmpty()) {
+ // keywords are also separated by semi-colons in poppler
+ entry->setField(QString::fromLatin1("keyword"), s);
+ }
+
+ // now parse the first page text and try to guess
+ Poppler::Page* page = doc->getPage(0);
+ if(page) {
+ // a null rectangle means get all text on page
+ QString text = page->getText(Poppler::Rectangle());
+ // borrowed from Referencer
+ QRegExp rx(QString::fromLatin1("(?:"
+ "(?:[Dd][Oo][Ii]:? *)"
+ "|"
+ "(?:[Dd]igital *[Oo]bject *[Ii]dentifier:? *)"
+ ")"
+ "("
+ "[^\\.\\s]+"
+ "\\."
+ "[^\\/\\s]+"
+ "\\/"
+ "[^\\s]+"
+ ")"));
+ if(rx.search(text) > -1) {
+ QString doi = rx.cap(1);
+ myDebug() << "PDFImporter::collection() - in PDF file, found DOI: " << doi << endl;
+ entry->setField(QString::fromLatin1("doi"), doi);
+ hasDOI = true;
+ }
+ rx = QRegExp(QString::fromLatin1("arXiv:"
+ "("
+ "[^\\/\\s]+"
+ "[\\/\\.]"
+ "[^\\s]+"
+ ")"));
+ if(rx.search(text) > -1) {
+ QString arxiv = rx.cap(1);
+ myDebug() << "PDFImporter::collection() - in PDF file, found arxiv: " << arxiv << endl;
+ if(entry->collection()->fieldByName(QString::fromLatin1("arxiv")) == 0) {
+ Data::FieldPtr field = new Data::Field(QString::fromLatin1("arxiv"), i18n("arXiv ID"));
+ field->setCategory(i18n("Publishing"));
+ entry->collection()->addField(field);
+ }
+ entry->setField(QString::fromLatin1("arxiv"), arxiv);
+ hasArxiv = true;
+ }
+
+ delete page;
+ }
+ } else {
+ myDebug() << "PDFImporter::collection() - unable to read PDF info (poppler)" << endl;
+ }
+ delete doc;
+#endif
+
+ entry->setField(QString::fromLatin1("url"), (*it).url());
+ // always an article?
+ entry->setField(QString::fromLatin1("entry-type"), QString::fromLatin1("article"));
+
+ QPixmap pix = NetAccess::filePreview(ref->fileName(), PDF_FILE_PREVIEW_SIZE);
+ delete ref; // removes temp file
+
+ if(!pix.isNull()) {
+ // is png best option?
+ QString id = ImageFactory::addImage(pix, QString::fromLatin1("PNG"));
+ if(!id.isEmpty()) {
+ Data::FieldPtr field = newColl->fieldByName(QString::fromLatin1("cover"));
+ if(!field && !newColl->imageFields().isEmpty()) {
+ field = newColl->imageFields().front();
+ } else if(!field) {
+ field = new Data::Field(QString::fromLatin1("cover"), i18n("Front Cover"), Data::Field::Image);
+ newColl->addField(field);
+ }
+ entry->setField(field, id);
+ }
+ }
+ if(coll) {
+ coll->addEntries(newColl->entries());
+ } else {
+ coll = newColl;
+ }
+
+ if(showProgress) {
+ ProgressManager::self()->setProgress(this, j);
+ kapp->processEvents();
+ }
+ }
+
+ if(m_cancelled) {
+ return 0;
+ }
+
+ if(hasDOI) {
+ myDebug() << "looking for DOI" << endl;
+ Fetch::FetcherVec vec = Fetch::Manager::self()->createUpdateFetchers(coll->type(), Fetch::DOI);
+ if(vec.isEmpty()) {
+ GUI::CursorSaver cs(Qt::arrowCursor);
+ KMessageBox::information(Kernel::self()->widget(),
+ i18n("Tellico is able to download information about entries with a DOI from "
+ "CrossRef.org. However, you must create an CrossRef account and add a new "
+ "data source with your account information."),
+ QString::null,
+ QString::fromLatin1("CrossRefSourceNeeded"));
+ } else {
+ Data::EntryVec entries = coll->entries();
+ for(Fetch::FetcherVec::Iterator fetcher = vec.begin(); fetcher != vec.end(); ++fetcher) {
+ for(Data::EntryVecIt entry = entries.begin(); entry != entries.end(); ++entry) {
+ fetcher->updateEntrySynchronous(entry);
+ }
+ }
+ }
+ }
+
+ if(m_cancelled) {
+ return 0;
+ }
+
+ if(hasArxiv) {
+ Data::EntryVec entries = coll->entries();
+ Fetch::FetcherVec vec = Fetch::Manager::self()->createUpdateFetchers(coll->type(), Fetch::ArxivID);
+ for(Fetch::FetcherVec::Iterator fetcher = vec.begin(); fetcher != vec.end(); ++fetcher) {
+ for(Data::EntryVecIt entry = entries.begin(); entry != entries.end(); ++entry) {
+ fetcher->updateEntrySynchronous(entry);
+ }
+ }
+ }
+
+// finally
+ Data::EntryVec entries = coll->entries();
+ for(Data::EntryVecIt entry = entries.begin(); entry != entries.end(); ++entry) {
+ if(entry->title().isEmpty()) {
+ // use file name
+ KURL u = entry->field(QString::fromLatin1("url"));
+ entry->setField(QString::fromLatin1("title"), u.fileName());
+ }
+ }
+
+ if(m_cancelled) {
+ return 0;
+ }
+ return coll;
+}
+
+void PDFImporter::slotCancel() {
+ m_cancelled = true;
+}
+
+#include "pdfimporter.moc"
diff --git a/src/translators/pdfimporter.h b/src/translators/pdfimporter.h
new file mode 100644
index 0000000..87da58e
--- /dev/null
+++ b/src/translators/pdfimporter.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_IMPORT_PDFIMPORTER_H
+#define TELLICO_IMPORT_PDFIMPORTER_H
+
+#include "importer.h"
+
+namespace Tellico {
+ namespace Import {
+
+class PDFImporter : public Importer {
+Q_OBJECT
+
+public:
+ PDFImporter(const KURL::List& urls);
+
+ virtual bool canImport(int type) const;
+
+ virtual Data::CollPtr collection();
+
+public slots:
+ void slotCancel();
+
+private:
+ bool m_cancelled;
+};
+
+ }
+}
+#endif
diff --git a/src/translators/pilotdb/Makefile.am b/src/translators/pilotdb/Makefile.am
new file mode 100644
index 0000000..cf21d12
--- /dev/null
+++ b/src/translators/pilotdb/Makefile.am
@@ -0,0 +1,16 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+noinst_LIBRARIES = libpilotdb.a
+
+AM_CPPFLAGS = $(all_includes)
+
+libpilotdb_a_METASOURCES = AUTO
+
+libpilotdb_a_SOURCES = pilotdb.cpp strop.cpp
+
+SUBDIRS = libflatfile libpalm
+
+EXTRA_DIST = strop.cpp strop.h portability.h pilotdb.h pilotdb.cpp
+
+####### kdevelop will overwrite this part!!! (end)############
+
+KDE_OPTIONS = noautodist
diff --git a/src/translators/pilotdb/libflatfile/DB.cpp b/src/translators/pilotdb/libflatfile/DB.cpp
new file mode 100644
index 0000000..40e639a
--- /dev/null
+++ b/src/translators/pilotdb/libflatfile/DB.cpp
@@ -0,0 +1,1437 @@
+/*
+ * palm-db-tools: Read/write DB-format databases
+ * Copyright (C) 1999-2001 by Tom Dyas (tdyas@users.sourceforge.net)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifh Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <iostream>
+#include <vector>
+#include <string>
+#include <stdexcept>
+#include <sstream>
+#include <time.h>
+
+#include <cstring>
+
+#include <kdebug.h>
+
+#include "../strop.h"
+
+#include "DB.h"
+
+#include <kdebug.h>
+
+#define charSeperator '/'
+#define VIEWFLAG_USE_IN_EDITVIEW 0x01
+
+#define INVALID_DEFAULT 0
+#define NOW_DEFAULT 1
+#define CONSTANT_DEFAULT 2
+
+using namespace PalmLib::FlatFile;
+using namespace PalmLib;
+
+namespace {
+ static const pi_uint16_t CHUNK_FIELD_NAMES = 0;
+ static const pi_uint16_t CHUNK_FIELD_TYPES = 1;
+ static const pi_uint16_t CHUNK_FIELD_DATA = 2;
+ static const pi_uint16_t CHUNK_LISTVIEW_DEFINITION = 64;
+ static const pi_uint16_t CHUNK_LISTVIEW_OPTIONS = 65;
+ static const pi_uint16_t CHUNK_LFIND_OPTIONS = 128;
+ static const pi_uint16_t CHUNK_ABOUT = 254;
+}
+
+template <class Map, class Key>
+static inline bool has_key(const Map& map, const Key& key)
+{
+ return map.find(key) != map.end();
+}
+
+bool PalmLib::FlatFile::DB::classify(PalmLib::Database& pdb)
+{
+ return (! pdb.isResourceDB())
+ && (pdb.creator() == PalmLib::mktag('D','B','O','S'))
+ && (pdb.type() == PalmLib::mktag('D','B','0','0'));
+}
+
+bool PalmLib::FlatFile::DB::match_name(const std::string& name)
+{
+ return (name == "DB") || (name == "db");
+}
+
+void PalmLib::FlatFile::DB::extract_chunks(const PalmLib::Block& appinfo)
+{
+ size_t i;
+ pi_uint16_t chunk_type;
+ pi_uint16_t chunk_size;
+
+ if (appinfo.size() > 4) {
+ // Loop through each chunk in the block while data remains.
+ i = 4;
+ while (i < appinfo.size()) {
+ /* Stop the loop if there is not enough room for even one
+ * chunk header.
+ */
+ if (i + 4 >= appinfo.size()) {
+// throw PalmLib::error("header is corrupt");
+ kdDebug() << "header is corrupt" << endl;
+ }
+ // Copy the chunk type and size into the local buffer.
+ chunk_type = get_short(appinfo.data() + i);
+ chunk_size = get_short(appinfo.data() + i + 2);
+ i += 4;
+
+ // Copy the chunk into seperate storage.
+ Chunk chunk(appinfo.data() + i, chunk_size);
+ chunk.chunk_type = chunk_type;
+ m_chunks[chunk.chunk_type].push_back(chunk);
+
+ /* Advance the index by the size of the chunk. */
+ i += chunk.size();
+ }
+
+ // If everything was correct, then we should be exactly at the
+ // end of the block.
+ if (i != appinfo.size()) {
+// throw PalmLib::error("header is corrupt");
+ kdDebug() << "header is corrupt" << endl;
+ }
+ } else {
+// throw PalmLib::error("header is corrupt");
+ kdDebug() << "header is corrupt" << endl;
+ }
+}
+
+void PalmLib::FlatFile::DB::extract_schema(unsigned numFields)
+{
+ unsigned i;
+
+ if (!has_key(m_chunks, CHUNK_FIELD_NAMES)
+ || !has_key(m_chunks, CHUNK_FIELD_TYPES)) {
+// throw PalmLib::error("database is missing its schema");
+ kdDebug() << "database is missing its schema" << endl;
+ return;
+ }
+
+ Chunk names_chunk = m_chunks[CHUNK_FIELD_NAMES][0];
+ Chunk types_chunk = m_chunks[CHUNK_FIELD_TYPES][0];
+ pi_char_t* p = names_chunk.data();
+ pi_char_t* q = types_chunk.data();
+
+ // Ensure that the types chunk has the expected size.
+ if (types_chunk.size() != numFields * sizeof(pi_uint16_t)) {
+// throw PalmLib::error("types chunk is corrupt");
+ kdDebug() << "types chunk is corrupt" << endl;
+ }
+ // Loop for each field and extract the name and type.
+ for (i = 0; i < numFields; ++i) {
+ PalmLib::FlatFile::Field::FieldType type;
+ int len;
+
+ // Determine the length of the name string. Ensure that the
+ // string does not go beyond the end of the chunk.
+ pi_char_t* null_p = reinterpret_cast<pi_char_t*>
+ (memchr(p, 0, names_chunk.size() - (p - names_chunk.data())));
+ if (!null_p) {
+// throw PalmLib::error("names chunk is corrupt");
+ kdDebug() << "names chunk is corrupt" << endl;
+ }
+ len = null_p - p;
+
+ switch (PalmLib::get_short(q)) {
+ case 0:
+ type = PalmLib::FlatFile::Field::STRING;
+ break;
+
+ case 1:
+ type = PalmLib::FlatFile::Field::BOOLEAN;
+ break;
+
+ case 2:
+ type = PalmLib::FlatFile::Field::INTEGER;
+ break;
+
+ case 3:
+ type = PalmLib::FlatFile::Field::DATE;
+ break;
+
+ case 4:
+ type = PalmLib::FlatFile::Field::TIME;
+ break;
+
+ case 5:
+ type = PalmLib::FlatFile::Field::NOTE;
+ break;
+
+ case 6:
+ type = PalmLib::FlatFile::Field::LIST;
+ break;
+
+ case 7:
+ type = PalmLib::FlatFile::Field::LINK;
+ break;
+
+ case 8:
+ type = PalmLib::FlatFile::Field::FLOAT;
+ break;
+
+ case 9:
+ type = PalmLib::FlatFile::Field::CALCULATED;
+ break;
+
+ case 10:
+ type = PalmLib::FlatFile::Field::LINKED;
+ break;
+
+ default:
+// throw PalmLib::error("unknown field type");
+ kdDebug() << "PalmLib::FlatFile::DB::extract_schema() - unknown field type" << endl;
+ type = PalmLib::FlatFile::Field::STRING;
+ break;
+ }
+
+ // Inform the superclass about this field.
+ appendField(std::string((char *) p, len), type, extract_fieldsdata(i, type));
+
+ // Advance to the information on the next field.
+ p += len + 1;
+ q += 2;
+ }
+}
+
+void PalmLib::FlatFile::DB::extract_listviews()
+{
+ if (!has_key(m_chunks, CHUNK_LISTVIEW_DEFINITION))
+ return;
+
+/* throw PalmLib::error("no list views in database");*/
+
+ const std::vector<Chunk>& chunks = m_chunks[CHUNK_LISTVIEW_DEFINITION];
+
+ for (std::vector<Chunk>::const_iterator iter = chunks.begin();
+ iter != chunks.end(); ++iter) {
+ const Chunk& chunk = (*iter);
+ PalmLib::FlatFile::ListView lv;
+
+ if (chunk.size() < (2 + 2 + 32)) {
+// throw PalmLib::error("list view is corrupt");
+ kdDebug() << "list view is corrupt" << endl;
+ }
+ pi_uint16_t flags = PalmLib::get_short(chunk.data());
+ pi_uint16_t num_cols = PalmLib::get_short(chunk.data() + 2);
+
+ lv.editoruse = false;
+ if (flags & VIEWFLAG_USE_IN_EDITVIEW)
+ lv.editoruse = true;
+
+ if (chunk.size() != static_cast<unsigned> (2 + 2 + 32 + num_cols * 4)) {
+// throw PalmLib::error("list view is corrupt");
+ kdDebug() << "list view is corrupt" << endl;
+ }
+ // Determine the length of the name string.
+ pi_char_t* null_ptr = reinterpret_cast<pi_char_t*>
+ (memchr(chunk.data() + 4, 0, 32));
+ if (null_ptr)
+ lv.name = std::string((char *) (chunk.data() + 4),
+ null_ptr - (chunk.data() + 4));
+ else
+ lv.name = "Unknown";
+
+ const pi_char_t* p = chunk.data() + 2 + 2 + 32;
+ for (int i = 0; i < num_cols; ++i) {
+ pi_uint16_t field = PalmLib::get_short(p);
+ pi_uint16_t width = PalmLib::get_short(p + 2);
+ p += 2 * sizeof(pi_uint16_t);
+
+ if (field >= getNumOfFields()) {
+// throw PalmLib::error("list view is corrupt");
+ kdDebug() << "list view is corrupt" << endl;
+ }
+ PalmLib::FlatFile::ListViewColumn col(field, width);
+ lv.push_back(col);
+ }
+
+ appendListView(lv);
+ }
+}
+
+std::string PalmLib::FlatFile::DB::extract_fieldsdata(pi_uint16_t field_search, PalmLib::FlatFile::Field::FieldType type)
+{
+ std::ostringstream theReturn;
+
+ if (!has_key(m_chunks, CHUNK_FIELD_DATA))
+ return std::string(theReturn.str());
+
+ std::vector<Chunk>& chunks = m_chunks[CHUNK_FIELD_DATA];
+
+ pi_uint16_t field_num = 0;
+ bool find = false;
+ std::vector<Chunk>::const_iterator iter = chunks.begin();
+ for ( ; iter != chunks.end(); ++iter) {
+ const Chunk& chunk = (*iter);
+
+ field_num = PalmLib::get_short(chunk.data());
+
+ if (field_num == field_search) {
+ find = true;
+ break;
+ }
+ }
+
+ if (find) {
+ const Chunk& chunk = (*iter);
+
+ switch (type) {
+
+ case PalmLib::FlatFile::Field::STRING:
+ theReturn << std::string((const char *)chunk.data()+2, chunk.size() - 2);
+ break;
+
+ case PalmLib::FlatFile::Field::BOOLEAN:
+ break;
+
+ case PalmLib::FlatFile::Field::INTEGER:
+ theReturn << PalmLib::get_long(chunk.data() + sizeof(pi_uint16_t));
+ theReturn << charSeperator;
+ theReturn << PalmLib::get_short(chunk.data() + sizeof(pi_uint16_t) + sizeof(pi_uint32_t));
+ break;
+
+ case PalmLib::FlatFile::Field::FLOAT: {
+ pi_double_t value;
+ value.words.hi = PalmLib::get_long(chunk.data() + 2);
+ value.words.lo = PalmLib::get_long(chunk.data() + 6);
+
+ theReturn << value.number;
+ }
+ break;
+
+ case PalmLib::FlatFile::Field::DATE:
+ if (*(chunk.data() + sizeof(pi_uint16_t)) == NOW_DEFAULT)
+ theReturn << "now";
+ else if (*(chunk.data() + sizeof(pi_uint16_t)) == CONSTANT_DEFAULT) {
+ const pi_char_t * ptr = chunk.data() + sizeof(pi_uint16_t) + 1;
+ struct tm date;
+ date.tm_year = PalmLib::get_short(ptr) - 1900;
+ date.tm_mon = (static_cast<int> (*(ptr + 2))) - 1;
+ date.tm_mday = static_cast<int> (*(ptr + 3));
+
+ (void) mktime(&date);
+
+ char buf[1024];
+
+ // Clear out the output buffer.
+ memset(buf, 0, sizeof(buf));
+
+ // Convert and output the date using the format.
+ strftime(buf, sizeof(buf), "%Y/%m/%d", &date);
+
+ theReturn << buf;
+ }
+ break;
+
+ case PalmLib::FlatFile::Field::TIME:
+ if (*(chunk.data() + sizeof(pi_uint16_t)) == NOW_DEFAULT)
+ theReturn << "now";
+ else if (*(chunk.data() + sizeof(pi_uint16_t)) == CONSTANT_DEFAULT) {
+ const pi_char_t * ptr = chunk.data() + sizeof(pi_uint16_t) + 1;
+ struct tm t;
+ const struct tm * tm_ptr;
+ time_t now;
+
+ time(&now);
+ tm_ptr = localtime(&now);
+ memcpy(&t, tm_ptr, sizeof(tm));
+
+ t.tm_hour = static_cast<int> (*(ptr));
+ t.tm_min = static_cast<int> (*(ptr + 1));
+ t.tm_sec = 0;
+
+ char buf[1024];
+
+ // Clear out the output buffer.
+ memset(buf, 0, sizeof(buf));
+
+ // Convert and output the date using the format.
+ strftime(buf, sizeof(buf), "%H:%M", &t);
+
+ theReturn << buf;
+ }
+ break;
+
+ case PalmLib::FlatFile::Field::NOTE:
+ break;
+
+ case PalmLib::FlatFile::Field::LIST: {
+ unsigned short numItems = PalmLib::get_short(chunk.data() + sizeof(pi_uint16_t));
+ int prevLength = 0;
+ std::string item;
+
+ if (numItems > 0) {
+ for (unsigned short i = 0; i < numItems - 1; i++) {
+ item = std::string((const char *)chunk.data() + 3 * sizeof(pi_uint16_t) + prevLength);
+ theReturn << item << charSeperator;
+ prevLength += item.length() + 1;
+ }
+ item = std::string((const char *)chunk.data() + 3 * sizeof(pi_uint16_t) + prevLength);
+ theReturn << item;
+ }
+ }
+ break;
+
+ case PalmLib::FlatFile::Field::LINK:
+ theReturn << std::string((const char *)chunk.data()+sizeof(pi_uint16_t));
+// theReturn << std::string((const char *)chunk.data()+sizeof(pi_uint16_t), chunk.size() - 2);
+ theReturn << charSeperator;
+ theReturn << PalmLib::get_short(chunk.data() + sizeof(pi_uint16_t) + 32 * sizeof(pi_char_t));
+ break;
+
+ case PalmLib::FlatFile::Field::LINKED:
+ theReturn << PalmLib::get_short(chunk.data() + sizeof(pi_uint16_t));
+ theReturn << charSeperator;
+ theReturn << PalmLib::get_short(chunk.data() + 2 * sizeof(pi_uint16_t));
+ break;
+
+ case PalmLib::FlatFile::Field::CALCULATED:
+ break;
+
+ default:
+ kdDebug() << "unknown field type" << endl;
+ break;
+ }
+ }
+ return std::string(theReturn.str());
+}
+
+void PalmLib::FlatFile::DB::extract_aboutinfo()
+{
+ if (!has_key(m_chunks, CHUNK_ABOUT))
+ return;
+
+ Chunk chunk = m_chunks[CHUNK_ABOUT][0];
+ pi_char_t* header = chunk.data();
+ pi_char_t* q = chunk.data() + PalmLib::get_short(header);
+
+ setAboutInformation( (char*)q);
+}
+
+void PalmLib::FlatFile::DB::parse_record(PalmLib::Record& record,
+ std::vector<pi_char_t *>& ptrs,
+ std::vector<size_t>& sizes)
+{
+ unsigned i;
+
+ // Ensure that enough space for the offset table exists.
+ if (record.size() < getNumOfFields() * sizeof(pi_uint16_t)) {
+// throw PalmLib::error("record is corrupt");
+ kdDebug() << "record is corrupt" << endl;
+ }
+ // Extract the offsets from the record. Determine field pointers.
+ std::vector<pi_uint16_t> offsets(getNumOfFields());
+ for (i = 0; i < getNumOfFields(); ++i) {
+ offsets[i] = get_short(record.data() + i * sizeof(pi_uint16_t));
+ if (offsets[i] >= record.size()) {
+// throw PalmLib::error("record is corrupt");
+ kdDebug() << "record is corrupt" << endl;
+ }
+ ptrs.push_back(record.data() + offsets[i]);
+ }
+
+ // Determine the field sizes.
+ for (i = 0; i < getNumOfFields() - 1; ++i) {
+ sizes.push_back(offsets[i + 1] - offsets[i]);
+ }
+ sizes.push_back(record.size() - offsets[getNumOfFields() - 1]);
+}
+
+PalmLib::FlatFile::DB::DB(PalmLib::Database& pdb)
+ : Database("db", pdb), m_flags(0)
+{
+ // Split the application information block into its component chunks.
+ extract_chunks(pdb.getAppInfoBlock());
+
+ // Pull the header fields and schema out of the databasse.
+ m_flags = get_short(pdb.getAppInfoBlock().data());
+ unsigned numFields = get_short(pdb.getAppInfoBlock().data() + 2);
+ extract_schema(numFields);
+
+ // Extract all of the list views.
+ extract_listviews();
+
+ extract_aboutinfo();
+
+ for (unsigned i = 0; i < pdb.getNumRecords(); ++i) {
+ PalmLib::Record record = pdb.getRecord(i);
+ Record rec;
+
+ std::vector<pi_char_t *> ptrs;
+ std::vector<size_t> sizes;
+ parse_record(record, ptrs, sizes);
+ for (unsigned j = 0; j < getNumOfFields(); ++j) {
+ PalmLib::FlatFile::Field f;
+ f.type = field_type(j);
+
+ switch (field_type(j)) {
+ case PalmLib::FlatFile::Field::STRING:
+ f.type = PalmLib::FlatFile::Field::STRING;
+ f.v_string = std::string((char *) ptrs[j], sizes[j] - 1);
+ break;
+
+ case PalmLib::FlatFile::Field::BOOLEAN:
+ f.type = PalmLib::FlatFile::Field::BOOLEAN;
+ if (*(ptrs[j]))
+ f.v_boolean = true;
+ else
+ f.v_boolean = false;
+ break;
+
+ case PalmLib::FlatFile::Field::INTEGER:
+ f.type = PalmLib::FlatFile::Field::INTEGER;
+ f.v_integer = PalmLib::get_long(ptrs[j]);
+ break;
+
+ case PalmLib::FlatFile::Field::FLOAT: {
+ // Place data from database in a union for conversion.
+ pi_double_t value;
+ value.words.hi = PalmLib::get_long(ptrs[j]);
+ value.words.lo = PalmLib::get_long(ptrs[j] + 4);
+
+ // Fill out the information for this field.
+ f.type = PalmLib::FlatFile::Field::FLOAT;
+ f.v_float = value.number;
+ }
+ break;
+
+ case PalmLib::FlatFile::Field::DATE:
+ f.type = PalmLib::FlatFile::Field::DATE;
+ f.v_date.year = PalmLib::get_short(ptrs[j]);
+ f.v_date.month = static_cast<int> (*(ptrs[j] + 2));
+ f.v_date.day = static_cast<int> (*(ptrs[j] + 3));
+ break;
+
+ case PalmLib::FlatFile::Field::TIME:
+ f.type = PalmLib::FlatFile::Field::TIME;
+ f.v_time.hour = static_cast<int> (*(ptrs[j]));
+ f.v_time.minute = static_cast<int> (*(ptrs[j] + 1));
+ break;
+
+ case PalmLib::FlatFile::Field::NOTE:
+ f.type = PalmLib::FlatFile::Field::NOTE;
+ f.v_string = std::string((char *) ptrs[j], sizes[j] - 3);
+ f.v_note = std::string((char *) (record.data() + get_short(ptrs[j] + strlen(f.v_string.c_str()) + 1)));
+ break;
+
+ case PalmLib::FlatFile::Field::LIST:
+ f.type = PalmLib::FlatFile::Field::LIST;
+ if (!field(j).argument().empty()) {
+ std::string data = field(j).argument();
+ unsigned int k;
+ std::string::size_type pos = 0;
+ pi_uint16_t itemID = *ptrs[j]; // TR: a list value is stored on 1 byte
+
+ for (k = 0; k < itemID; k++) {
+ if ((pos = data.find(charSeperator, pos)) == std::string::npos) {
+ break;
+ }
+ pos++;
+ }
+ if (pos == std::string::npos) {
+ f.v_string = "N/A";
+ } else {
+ if (data.find(charSeperator, pos) == std::string::npos) {
+ f.v_string = data.substr( pos, std::string::npos);
+ } else {
+ f.v_string = data.substr( pos, data.find(charSeperator, pos) - pos);
+ }
+ }
+ }
+ break;
+
+ case PalmLib::FlatFile::Field::LINK:
+ f.type = PalmLib::FlatFile::Field::LINK;
+ f.v_integer = PalmLib::get_long(ptrs[j]);
+ f.v_string = std::string((char *) (ptrs[j] + 4), sizes[j] - 5);
+ break;
+
+ case PalmLib::FlatFile::Field::LINKED:
+ f.type = PalmLib::FlatFile::Field::LINKED;
+ f.v_string = std::string((char *) ptrs[j], sizes[j] - 1);
+ break;
+
+ case PalmLib::FlatFile::Field::CALCULATED: {
+ std::ostringstream value;
+ f.type = PalmLib::FlatFile::Field::CALCULATED;
+ switch (ptrs[j][0]) {
+ case 1: //string
+ value << std::string((char *) ptrs[j] + 1, sizes[j] - 2);
+ break;
+ case 2: //integer
+ value << PalmLib::get_long(ptrs[j] + 1);
+ break;
+ case 9: //float
+ {
+ pi_double_t fvalue;
+ fvalue.words.hi = PalmLib::get_long(ptrs[j] + 1);
+ fvalue.words.lo = PalmLib::get_long(ptrs[j] + 5);
+
+ value << fvalue.number;
+ }
+ default:
+ value << "N/A";
+ }
+ f.v_string = value.str();
+ } break;
+
+ default:
+ kdDebug() << "unknown field type" << endl;
+ break;
+ }
+
+ // Append this field to the record.
+ rec.appendField(f);
+ }
+ rec.unique_id(record.unique_id());
+ // Append this record to the database.
+ appendRecord(rec);
+ }
+}
+
+void PalmLib::FlatFile::DB::make_record(PalmLib::Record& pdb_record,
+ const Record& record) const
+{
+ unsigned int i;
+
+ // Determine the packed size of this record.
+ size_t size = getNumOfFields() * sizeof(pi_uint16_t);
+ for (i = 0; i < getNumOfFields(); i++) {
+#ifdef HAVE_VECTOR_AT
+ const Field field = record.fields().at(i);
+#else
+ const Field field = record.fields()[i];
+#endif
+ switch (field.type) {
+ case PalmLib::FlatFile::Field::STRING:
+ size += field.v_string.length() + 1;
+ break;
+
+ case PalmLib::FlatFile::Field::NOTE:
+ size += field.v_string.length() + 3;
+ size += field.v_note.length() + 1;
+ break;
+
+ case PalmLib::FlatFile::Field::BOOLEAN:
+ size += 1;
+ break;
+
+ case PalmLib::FlatFile::Field::INTEGER:
+ size += 4;
+ break;
+
+ case PalmLib::FlatFile::Field::FLOAT:
+ size += 8;
+ break;
+
+ case PalmLib::FlatFile::Field::DATE:
+ size += sizeof(pi_uint16_t) + 2 * sizeof(pi_char_t);
+ break;
+
+ case PalmLib::FlatFile::Field::TIME:
+ size += 2 * sizeof(pi_char_t);
+ break;
+
+ case PalmLib::FlatFile::Field::LIST:
+ size += sizeof(pi_char_t);
+ break;
+
+ case PalmLib::FlatFile::Field::LINK:
+ size += sizeof(pi_int32_t);
+ size += field.v_string.length() + 1;
+ break;
+
+ case PalmLib::FlatFile::Field::LINKED:
+ size += field.v_string.length() + 1;
+ break;
+
+ case PalmLib::FlatFile::Field::CALCULATED:
+ size += 1;
+ break;
+
+ default:
+ kdDebug() << "unsupported field type" << endl;
+ break;
+ }
+ }
+
+ // Allocate a block for the packed record and setup the pointers.
+ pi_char_t* buf = new pi_char_t[size];
+ pi_char_t* p = buf + getNumOfFields() * sizeof(pi_uint16_t);
+ pi_char_t* offsets = buf;
+
+ // Pack the fields into the buffer.
+ for (i = 0; i < getNumOfFields(); i++) {
+ pi_char_t* noteOffsetOffset = 0;
+ bool setNote = false;
+#ifdef HAVE_VECTOR_AT
+ const Field fieldData = record.fields().at(i);
+#else
+ const Field fieldData = record.fields()[i];
+#endif
+
+ // Mark the offset to the start of this field in the offests table.
+ PalmLib::set_short(offsets, static_cast<pi_uint16_t> (p - buf));
+ offsets += sizeof(pi_uint16_t);
+
+ // Pack the field.
+ switch (fieldData.type) {
+ case PalmLib::FlatFile::Field::STRING:
+ memcpy(p, fieldData.v_string.c_str(), fieldData.v_string.length() + 1);
+ p += fieldData.v_string.length() + 1;
+ break;
+
+ case PalmLib::FlatFile::Field::NOTE:
+ if (setNote)
+ kdDebug() << "unsupported field type";
+ memcpy(p, fieldData.v_string.c_str(), fieldData.v_string.length() + 1);
+ p += fieldData.v_string.length() + 1;
+ noteOffsetOffset = p;
+ p += 2;
+ setNote = true;
+ break;
+
+ case PalmLib::FlatFile::Field::BOOLEAN:
+ *p++ = ((fieldData.v_boolean) ? 1 : 0);
+ break;
+
+ case PalmLib::FlatFile::Field::INTEGER:
+ PalmLib::set_long(p, fieldData.v_integer);
+ p += sizeof(pi_int32_t);
+ break;
+
+ case PalmLib::FlatFile::Field::FLOAT: {
+ // Place data the data in a union for easy conversion.
+ pi_double_t value;
+ value.number = fieldData.v_float;
+ PalmLib::set_long(p, value.words.hi);
+ p += sizeof(pi_uint32_t);
+ PalmLib::set_long(p, value.words.lo);
+ p += sizeof(pi_uint32_t);
+ break;
+ }
+
+ case PalmLib::FlatFile::Field::DATE:
+ PalmLib::set_short(p, fieldData.v_date.year);
+ p += sizeof(pi_uint16_t);
+ *p++ = static_cast<pi_char_t> (fieldData.v_date.month & 0xFF);
+ *p++ = static_cast<pi_char_t> (fieldData.v_date.day & 0xFF);
+ break;
+
+ case PalmLib::FlatFile::Field::TIME:
+ *p++ = static_cast<pi_char_t> (fieldData.v_time.hour & 0xFF);
+ *p++ = static_cast<pi_char_t> (fieldData.v_time.minute & 0xFF);
+ break;
+
+ case PalmLib::FlatFile::Field::LIST:
+ if (!field(i).argument().empty()) {
+ std::string data = field(i).argument();
+ std::string::size_type pos = 0, next;
+ unsigned int j = 0;
+ pi_int16_t itemID = -1;
+
+ while ( (next = data.find(charSeperator, pos)) != std::string::npos) {
+ if (fieldData.v_string == data.substr( pos, next - pos)) {
+ itemID = j;
+ break;
+ }
+ j++;
+ pos = next + 1;
+ }
+ // TR: the following test handles the case where the field value
+ // equals the last item in list (bugfix)
+ if (itemID == -1 && fieldData.v_string == data.substr( pos, std::string::npos)) {
+ itemID = j;
+ }
+ p[0] = itemID; // TR: a list value is stored on 1 byte
+ p += sizeof(pi_char_t);
+ }
+ break;
+
+ case PalmLib::FlatFile::Field::LINK:
+ PalmLib::set_long(p, fieldData.v_integer);
+ p += sizeof(pi_int32_t);
+ memcpy(p, fieldData.v_string.c_str(), fieldData.v_string.length() + 1);
+ p += fieldData.v_string.length() + 1;
+ break;
+
+ case PalmLib::FlatFile::Field::LINKED:
+ memcpy(p, fieldData.v_string.c_str(), fieldData.v_string.length() + 1);
+ p += fieldData.v_string.length() + 1;
+ break;
+
+ case PalmLib::FlatFile::Field::CALCULATED:
+ *p = 13;
+ p++;
+ break;
+
+ default:
+ kdDebug() << "unsupported field type";
+ break;
+ }
+ if (setNote) {
+ if (fieldData.v_note.length()) {
+ memcpy(p, fieldData.v_note.c_str(), fieldData.v_note.length() + 1);
+ PalmLib::set_short(noteOffsetOffset, (pi_uint16_t)(p - buf));
+ p += fieldData.v_note.length() + 1;
+ } else {
+ PalmLib::set_short(noteOffsetOffset, 0);
+ }
+ }
+ }
+
+ // Place the packed data into the PalmOS record.
+ pdb_record.set_raw(buf, size);
+ delete [] buf;
+}
+
+void PalmLib::FlatFile::DB::build_fieldsdata_chunks(std::vector<DB::Chunk>& chunks) const
+{
+ pi_char_t * buf = 0, * p;
+ unsigned int size, i;
+
+ for (i = 0; i < getNumOfFields(); ++i) {
+ size = 0;
+ switch (field_type(i)) {
+ case PalmLib::FlatFile::Field::STRING:
+ if (!field(i).argument().empty()) {
+ size = (field(i).argument().length() + 1) + 2;
+ buf = new pi_char_t[size];
+ PalmLib::set_short(buf, i);
+ strcpy((char *) (buf + 2), field(i).argument().c_str());
+ }
+ break;
+
+ case PalmLib::FlatFile::Field::BOOLEAN:
+ break;
+
+ case PalmLib::FlatFile::Field::INTEGER:
+ if (!field(i).argument().empty()) {
+ std::string data = field(i).argument();
+ std::pair< PalmLib::pi_int32_t, PalmLib::pi_int16_t> values(0, 0);
+
+ if ( data.find(charSeperator) != std::string::npos) {
+ StrOps::convert_string(data.substr( 0, data.find(charSeperator)), values.first);
+ StrOps::convert_string(data.substr( data.find(charSeperator) + 1, std::string::npos), values.second);
+ } else
+ StrOps::convert_string(data, values.first);
+
+ size = 2 + sizeof(pi_uint32_t) + sizeof(pi_uint16_t);
+ buf = new pi_char_t[size];
+ p = buf;
+ PalmLib::set_short(p, i);
+ p += sizeof(pi_uint16_t);
+ PalmLib::set_long(p, values.first);
+ p += sizeof(pi_uint32_t);
+ PalmLib::set_short(p, values.second);
+ p += sizeof(pi_uint16_t);
+ }
+ break;
+
+ case PalmLib::FlatFile::Field::FLOAT:
+ if (!field(i).argument().empty()) {
+ std::string data = field(i).argument();
+ pi_double_t value;
+
+ StrOps::convert_string(data, value.number);
+
+ size = 2 + 2 * sizeof(pi_uint32_t);
+ buf = new pi_char_t[size];
+ p = buf;
+ PalmLib::set_short(p, i);
+ p += sizeof(pi_uint16_t);
+ PalmLib::set_long(p, value.words.hi);
+ p += sizeof(pi_uint32_t);
+ PalmLib::set_long(p, value.words.lo);
+ p += sizeof(pi_uint32_t);
+ }
+ break;
+
+ case PalmLib::FlatFile::Field::DATE:
+ if (!field(i).argument().empty()) {
+ std::string data = field(i).argument();
+ struct tm date;
+ pi_char_t type;
+
+ if (data.substr(0, 3) == "now") {
+ type = NOW_DEFAULT;
+ const struct tm * tm_ptr;
+ time_t now;
+
+ time(&now);
+ tm_ptr = localtime(&now);
+ memcpy(&date, tm_ptr, sizeof(tm));
+ } else
+#ifdef strptime
+ if (strptime(data.c_str(), "%Y/%m/%d", &date))
+#else
+ if (StrOps::strptime(data.c_str(), "%Y/%m/%d", &date))
+#endif
+ type = CONSTANT_DEFAULT;
+ else
+ type = INVALID_DEFAULT;
+
+ if (type != INVALID_DEFAULT) {
+ size = sizeof(pi_uint16_t) + 1 + sizeof(pi_uint16_t) + 2;
+ buf = new pi_char_t[size];
+ p = buf;
+ PalmLib::set_short(p, i);
+ p += sizeof(pi_uint16_t);
+ *p++ = static_cast<pi_char_t> (type & 0xFF);
+ PalmLib::set_short(p, date.tm_year + 1900);
+ p += sizeof(pi_uint16_t);
+ *p++ = static_cast<pi_char_t> ((date.tm_mon + 1) & 0xFF);
+ *p++ = static_cast<pi_char_t> (date.tm_mday & 0xFF);
+ }
+
+ }
+ break;
+
+ case PalmLib::FlatFile::Field::TIME:
+ if (!field(i).argument().empty()) {
+ std::string data = field(i).argument();
+ struct tm t;
+ pi_char_t type;
+
+ if (data == "now") {
+ type = NOW_DEFAULT;
+ const struct tm * tm_ptr;
+ time_t now;
+
+ time(&now);
+ tm_ptr = localtime(&now);
+ memcpy(&t, tm_ptr, sizeof(tm));
+ } else
+#ifdef strptime
+ if (!strptime(data.c_str(), "%H/%M", &t))
+#else
+ if (!StrOps::strptime(data.c_str(), "%H/%M", &t))
+#endif
+ type = CONSTANT_DEFAULT;
+ else
+ type = INVALID_DEFAULT;
+
+ if (type != INVALID_DEFAULT) {
+ size = sizeof(pi_uint16_t) + 1 + sizeof(pi_uint16_t) + 2;
+ buf = new pi_char_t[size];
+ p = buf;
+ PalmLib::set_short(p, i);
+ p += sizeof(pi_uint16_t);
+ *p++ = static_cast<pi_char_t> (type & 0xFF);
+ *p++ = static_cast<pi_char_t> (t.tm_hour & 0xFF);
+ *p++ = static_cast<pi_char_t> (t.tm_min & 0xFF);
+ }
+
+ }
+ break;
+
+ case PalmLib::FlatFile::Field::NOTE:
+ break;
+
+ case PalmLib::FlatFile::Field::LIST:
+ if (!field(i).argument().empty()) {
+ std::string data = field(i).argument();
+ std::vector<std::string> items;
+ std::string::size_type pos = 0, next;
+ std::vector<std::string>::iterator iter;
+ size = 2 + 2 * sizeof(pi_uint16_t);
+ while ( (next = data.find(charSeperator, pos)) != std::string::npos) {
+ std::string item = data.substr( pos, next - pos);
+ items.push_back(item);
+ size += item.length() + 1;
+ pos = next + 1;
+ }
+ if (pos != std::string::npos) {
+ std::string item = data.substr( pos, std::string::npos);
+ items.push_back(item);
+ size += item.length() + 1;
+ }
+
+ buf = new pi_char_t[size];
+ p = buf;
+ PalmLib::set_short(p, i);
+ p += sizeof(pi_uint16_t);
+ PalmLib::set_short(p, items.size());
+ p += sizeof(pi_uint16_t);
+ p += sizeof(pi_uint16_t);
+ for (iter = items.begin(); iter != items.end(); ++iter) {
+ std::string& item = (*iter);
+ strcpy((char *) p, item.c_str());
+ p[item.length()] = 0;
+ p += item.length() + 1;
+ }
+
+ }
+ break;
+
+ case PalmLib::FlatFile::Field::LINK:
+ if (!field(i).argument().empty()) {
+ std::string data = field(i).argument();
+ std::string databasename;
+ pi_uint16_t fieldnum;
+
+ if ( data.find(charSeperator) != std::string::npos) {
+ databasename = data.substr( 0, data.find(charSeperator));
+ StrOps::convert_string(data.substr( data.find(charSeperator) + 1, std::string::npos), fieldnum);
+ } else {
+ databasename = data;
+ fieldnum = 0;
+ }
+
+ size = 2 + 32 * sizeof(pi_char_t) + sizeof(pi_uint16_t);
+ buf = new pi_char_t[size];
+ p = buf;
+ PalmLib::set_short(p, i);
+ p += sizeof(pi_uint16_t);
+ strcpy((char *) p, databasename.c_str());
+ p += 32 * sizeof(pi_char_t);
+ PalmLib::set_short(p, fieldnum);
+ p += sizeof(pi_uint16_t);
+ }
+ break;
+
+ case PalmLib::FlatFile::Field::LINKED:
+ if (!field(i).argument().empty()) {
+ std::string data = field(i).argument();
+ pi_uint16_t linknum;
+ pi_uint16_t fieldnum;
+
+ if ( data.find(charSeperator) != std::string::npos) {
+ StrOps::convert_string(data.substr( 0, data.find(charSeperator)), linknum);
+ StrOps::convert_string(data.substr( data.find(charSeperator) + 1, std::string::npos), fieldnum);
+ if (field_type(linknum) != PalmLib::FlatFile::Field::LINK) {
+ unsigned int j = 0;
+ while (field_type(j) != PalmLib::FlatFile::Field::LINK && j < i) j++;
+ linknum = j;
+ }
+ } else {
+ unsigned int j = 0;
+ while (field_type(j) != PalmLib::FlatFile::Field::LINK && j < i) j++;
+ linknum = j;
+ fieldnum = 0;
+ }
+
+ size = 2 + 2 * sizeof(pi_uint16_t);
+ buf = new pi_char_t[size];
+ p = buf;
+ PalmLib::set_short(p, i);
+ p += sizeof(pi_uint16_t);
+ PalmLib::set_short(p, linknum);
+ p += sizeof(pi_uint16_t);
+ PalmLib::set_short(p, fieldnum);
+ p += sizeof(pi_uint16_t);
+ }
+ break;
+
+ case PalmLib::FlatFile::Field::CALCULATED:
+ break;
+
+ default:
+ kdDebug() << "unknown field type" << endl;
+ break;
+ }
+
+ if (size) {
+ Chunk data_chunk(buf, size);
+ data_chunk.chunk_type = CHUNK_FIELD_DATA;
+ delete [] buf;
+ chunks.push_back(data_chunk);
+ }
+ }
+}
+
+void PalmLib::FlatFile::DB::build_about_chunk(std::vector<DB::Chunk>& chunks) const
+{
+ pi_char_t* buf;
+ pi_char_t* p;
+ int headersize = 2*sizeof(pi_uint16_t);
+ std::string information = getAboutInformation();
+
+ if (!information.length())
+ return;
+ // Build the names chunk.
+ buf = new pi_char_t[headersize + information.length() + 1];
+ p = buf;
+
+ PalmLib::set_short(p, headersize);
+ p += 2;
+ PalmLib::set_short(p, 1); //about type version
+ p += 2;
+ memcpy(p, information.c_str(), information.length() + 1);
+ p += information.length() + 1;
+ Chunk chunk(buf, headersize + information.length() + 1);
+ chunk.chunk_type = CHUNK_ABOUT;
+ delete [] buf;
+ chunks.push_back(chunk);
+
+}
+
+void PalmLib::FlatFile::DB::build_standard_chunks(std::vector<DB::Chunk>& chunks) const
+{
+ pi_char_t* buf;
+ pi_char_t* p;
+ unsigned i;
+
+ // Determine the size needed for the names chunk.
+ size_t names_chunk_size = 0;
+ for (i = 0; i < getNumOfFields(); ++i) {
+ names_chunk_size += field_name(i).length() + 1;
+ }
+
+ // Build the names chunk.
+ buf = new pi_char_t[names_chunk_size];
+ p = buf;
+ for (i = 0; i < getNumOfFields(); ++i) {
+ const std::string name = field_name(i);
+ memcpy(p, name.c_str(), name.length() + 1);
+ p += name.length() + 1;
+ }
+ Chunk names_chunk(buf, names_chunk_size);
+ names_chunk.chunk_type = CHUNK_FIELD_NAMES;
+ delete [] buf;
+
+ // Build the types chunk.
+ buf = new pi_char_t[getNumOfFields() * sizeof(pi_uint16_t)];
+ p = buf;
+ for (i = 0; i < getNumOfFields(); ++i) {
+ // Pack the type of the current field.
+ switch (field_type(i)) {
+ case PalmLib::FlatFile::Field::STRING:
+ PalmLib::set_short(p, 0);
+ break;
+
+ case PalmLib::FlatFile::Field::BOOLEAN:
+ PalmLib::set_short(p, 1);
+ break;
+
+ case PalmLib::FlatFile::Field::INTEGER:
+ PalmLib::set_short(p, 2);
+ break;
+
+ case PalmLib::FlatFile::Field::DATE:
+ PalmLib::set_short(p, 3);
+ break;
+
+ case PalmLib::FlatFile::Field::TIME:
+ PalmLib::set_short(p, 4);
+ break;
+
+ case PalmLib::FlatFile::Field::NOTE:
+ PalmLib::set_short(p, 5);
+ break;
+
+ case PalmLib::FlatFile::Field::LIST:
+ PalmLib::set_short(p, 6);
+ break;
+
+ case PalmLib::FlatFile::Field::LINK:
+ PalmLib::set_short(p, 7);
+ break;
+
+ case PalmLib::FlatFile::Field::FLOAT:
+ PalmLib::set_short(p, 8);
+ break;
+
+ case PalmLib::FlatFile::Field::CALCULATED:
+ PalmLib::set_short(p, 9);
+ break;
+
+ case PalmLib::FlatFile::Field::LINKED:
+ PalmLib::set_short(p, 10);
+ break;
+
+ default:
+ kdDebug() << "unsupported field type" << endl;
+ break;
+ }
+
+ // Advance to the next position.
+ p += sizeof(pi_uint16_t);
+ }
+ Chunk types_chunk(buf, getNumOfFields() * sizeof(pi_uint16_t));
+ types_chunk.chunk_type = CHUNK_FIELD_TYPES;
+ delete [] buf;
+
+ // Build the list view options chunk.
+ buf = new pi_char_t[2 * sizeof(pi_uint16_t)];
+ PalmLib::set_short(buf, 0);
+ PalmLib::set_short(buf + sizeof(pi_uint16_t), 0);
+ Chunk listview_options_chunk(buf, 2 * sizeof(pi_uint16_t));
+ listview_options_chunk.chunk_type = CHUNK_LISTVIEW_OPTIONS;
+ delete [] buf;
+
+ // Build the local find options chunk.
+ buf = new pi_char_t[sizeof(pi_uint16_t)];
+ PalmLib::set_short(buf, 0);
+ Chunk lfind_options_chunk(buf, 1 * sizeof(pi_uint16_t));
+ lfind_options_chunk.chunk_type = CHUNK_LFIND_OPTIONS;
+ delete [] buf;
+
+ // Add all the chunks to the chunk list.
+ chunks.push_back(names_chunk);
+ chunks.push_back(types_chunk);
+ chunks.push_back(listview_options_chunk);
+ chunks.push_back(lfind_options_chunk);
+}
+
+void PalmLib::FlatFile::DB::build_listview_chunk(std::vector<DB::Chunk>& chunks,
+ const ListView& lv) const
+{
+ // Calculate size and allocate space for the temporary buffer.
+ size_t size = 2 * sizeof(pi_uint16_t) + 32
+ + lv.size() * (2 * sizeof(pi_uint16_t));
+ pi_char_t* buf = new pi_char_t[size];
+
+ // Fill in the header details.
+ pi_uint16_t flags = 0;
+ if (lv.editoruse) {
+ std::cout << "editoruse\n";
+ flags |= VIEWFLAG_USE_IN_EDITVIEW;
+ }
+ PalmLib::set_short(buf, flags);
+ PalmLib::set_short(buf + sizeof(pi_uint16_t), lv.size());
+ memset((char *) (buf + 4), 0, 32);
+ strncpy((char *) (buf + 4), lv.name.c_str(), 32);
+
+ // Fill in the column details.
+ pi_char_t* p = buf + 4 + 32;
+ for (ListView::const_iterator i = lv.begin(); i != lv.end(); ++i) {
+ const ListViewColumn& col = (*i);
+ PalmLib::set_short(p, col.field);
+ PalmLib::set_short(p + sizeof(pi_uint16_t), col.width);
+ p += 2 * sizeof(pi_uint16_t);
+ }
+
+ // Create the chunk and place it in the chunks list.
+ Chunk chunk(buf, size);
+ chunk.chunk_type = CHUNK_LISTVIEW_DEFINITION;
+ delete [] buf;
+ chunks.push_back(chunk);
+}
+
+void PalmLib::FlatFile::DB::build_appinfo_block(const std::vector<DB::Chunk>& chunks, PalmLib::Block& appinfo) const
+{
+ std::vector<Chunk>::const_iterator iter;
+
+ // Determine the size of the final app info block.
+ size_t size = 2 * sizeof(pi_uint16_t);
+ for (iter = chunks.begin(); iter != chunks.end(); ++iter) {
+ const Chunk& chunk = (*iter);
+ size += 2 * sizeof(pi_uint16_t) + chunk.size();
+ }
+
+ // Allocate the temporary buffer. Fill in the header.
+ pi_char_t* buf = new pi_char_t[size];
+ PalmLib::set_short(buf, m_flags);
+ PalmLib::set_short(buf + sizeof(pi_uint16_t), getNumOfFields());
+
+ // Pack the chunks into the buffer.
+ size_t i = 4;
+ for (iter = chunks.begin(); iter != chunks.end(); ++iter) {
+ const Chunk& chunk = (*iter);
+ // Set the chunk type and size.
+ PalmLib::set_short(buf + i, chunk.chunk_type);
+ PalmLib::set_short(buf + i + 2, chunk.size());
+ i += 4;
+
+ // Copy the chunk data into the buffer.
+ memcpy(buf + i, chunk.data(), chunk.size());
+ i += chunk.size();
+ }
+
+ // Finally, move the buffer into the provided appinfo block.
+ appinfo.set_raw(buf, size);
+ delete [] buf;
+}
+
+void PalmLib::FlatFile::DB::outputPDB(PalmLib::Database& pdb) const
+{
+ unsigned i;
+
+ // Let the superclass have a chance.
+ SUPERCLASS(PalmLib::FlatFile, Database, outputPDB, (pdb));
+
+ // Set the database's type and creator.
+ pdb.type(PalmLib::mktag('D','B','0','0'));
+ pdb.creator(PalmLib::mktag('D','B','O','S'));
+
+ // Create the app info block.
+ std::vector<Chunk> chunks;
+ build_standard_chunks(chunks);
+ for (i = 0; i < getNumOfListViews(); ++i) {
+ build_listview_chunk(chunks, getListView(i));
+ }
+ build_fieldsdata_chunks(chunks);
+ build_about_chunk(chunks);
+
+ PalmLib::Block appinfo;
+ build_appinfo_block(chunks, appinfo);
+ pdb.setAppInfoBlock(appinfo);
+
+ // Output each record to the PalmOS database.
+ for (i = 0; i < getNumRecords(); ++i) {
+ Record record = getRecord(i);
+ PalmLib::Record pdb_record;
+
+ make_record(pdb_record, record);
+ pdb.appendRecord(pdb_record);
+ }
+}
+
+unsigned PalmLib::FlatFile::DB::getMaxNumOfFields() const
+{
+ return 0;
+}
+
+bool
+PalmLib::FlatFile::DB::supportsFieldType(const Field::FieldType& type) const
+{
+ switch (type) {
+ case PalmLib::FlatFile::Field::STRING:
+ case PalmLib::FlatFile::Field::BOOLEAN:
+ case PalmLib::FlatFile::Field::INTEGER:
+ case PalmLib::FlatFile::Field::FLOAT:
+ case PalmLib::FlatFile::Field::DATE:
+ case PalmLib::FlatFile::Field::TIME:
+ case PalmLib::FlatFile::Field::NOTE:
+ case PalmLib::FlatFile::Field::LIST:
+ case PalmLib::FlatFile::Field::LINK:
+ case PalmLib::FlatFile::Field::LINKED:
+ case PalmLib::FlatFile::Field::CALCULATED:
+ return true;
+ default:
+ return false;
+ }
+}
+
+std::vector<std::string>
+PalmLib::FlatFile::DB::field_argumentf(int i, std::string& format)
+{
+ std::vector<std::string> vtitles(0, std::string(""));
+ int j;
+
+ switch (field_type(i)) {
+ case PalmLib::FlatFile::Field::STRING:
+ format = std::string("%s");
+ vtitles.push_back(std::string("default value"));
+ break;
+ case PalmLib::FlatFile::Field::INTEGER:
+ format = std::string("%ld/%d");
+ vtitles.push_back(std::string("default value"));
+ vtitles.push_back(std::string("increment"));
+ break;
+ case PalmLib::FlatFile::Field::FLOAT:
+ format = std::string("%f");
+ vtitles.push_back(std::string("default value"));
+ break;
+ case PalmLib::FlatFile::Field::DATE:
+ format = std::string("%d/%d/%d");
+ vtitles.push_back(std::string("Year (or now)"));
+ vtitles.push_back(std::string("Month"));
+ vtitles.push_back(std::string("Day in the month"));
+ break;
+ case PalmLib::FlatFile::Field::TIME:
+ format = std::string("%d/%d");
+ vtitles.push_back(std::string("Hour (or now)"));
+ vtitles.push_back(std::string("Minute"));
+ break;
+ case PalmLib::FlatFile::Field::LIST:
+ format = std::string("");
+ for (j = 0; j < 31; i++) {
+ format += std::string("%s/");
+ std::ostringstream title;
+ title << "item " << j;
+ vtitles.push_back(title.str());
+ }
+ format += std::string("%s");
+ vtitles.push_back(std::string("item 32"));
+ break;
+ case PalmLib::FlatFile::Field::LINK:
+ format = std::string("%s/%d");
+ vtitles.push_back(std::string("database"));
+ vtitles.push_back(std::string("field number"));
+ break;
+ case PalmLib::FlatFile::Field::LINKED:
+ format = std::string("%d/%d");
+ vtitles.push_back(std::string("link field number"));
+ vtitles.push_back(std::string("field number"));
+ break;
+ case PalmLib::FlatFile::Field::CALCULATED:
+ case PalmLib::FlatFile::Field::BOOLEAN:
+ case PalmLib::FlatFile::Field::NOTE:
+ default:
+ format = std::string("");
+ break;
+ }
+ return vtitles;
+}
+
+unsigned PalmLib::FlatFile::DB::getMaxNumOfListViews() const
+{
+ return 0;
+}
+
+void PalmLib::FlatFile::DB::doneWithSchema()
+{
+ // Let the superclass have a chance.
+ SUPERCLASS(PalmLib::FlatFile, Database, doneWithSchema, ());
+/* false from the 0.3.3 version
+ if (getNumOfListViews() < 1)
+ throw PalmLib::error("at least one list view must be specified");
+*/
+}
+
+void PalmLib::FlatFile::DB::setOption(const std::string& name,
+ const std::string& value)
+{
+ if (name == "find") {
+ if (!StrOps::string2boolean(value))
+ m_flags &= ~(1);
+ else
+ m_flags |= 1;
+ } else if (name == "read-only"
+ || name == "readonly") {
+ if (!StrOps::string2boolean(value))
+ m_flags &= ~(0x8000);
+ else
+ m_flags |= 0x8000;
+ } else {
+ SUPERCLASS(PalmLib::FlatFile, Database, setOption, (name, value));
+ }
+}
+
+PalmLib::FlatFile::Database::options_list_t
+PalmLib::FlatFile::DB::getOptions(void) const
+{
+ typedef PalmLib::FlatFile::Database::options_list_t::value_type value;
+ PalmLib::FlatFile::Database::options_list_t result;
+
+ result = SUPERCLASS(PalmLib::FlatFile, Database, getOptions, ());
+
+ if (m_flags & 1)
+ result.push_back(value("find", "true"));
+
+ if (m_flags & 0x8000)
+ result.push_back(value("read-only", "true"));
+
+ return result;
+}
diff --git a/src/translators/pilotdb/libflatfile/DB.h b/src/translators/pilotdb/libflatfile/DB.h
new file mode 100644
index 0000000..dd09d36
--- /dev/null
+++ b/src/translators/pilotdb/libflatfile/DB.h
@@ -0,0 +1,166 @@
+/*
+ * This class provides access to DB-format databases.
+ */
+
+#ifndef __PALMLIB_FLATFILE_DB_H__
+#define __PALMLIB_FLATFILE_DB_H__
+
+#include <map>
+#include <string>
+
+#include "../libpalm/Block.h"
+#include "../libpalm/Database.h"
+#include "Database.h"
+
+namespace PalmLib {
+ namespace FlatFile {
+
+ class DB : public Database {
+ public:
+ /**
+ * Return true if this class can handle the given PalmOS
+ * database.
+ *
+ * @param pdb PalmOS database to check for support.
+ */
+ static bool classify(PalmLib::Database& pdb);
+
+ /**
+ * Return true if this class is the database identified by
+ * name.
+ *
+ * @param name A database type name to check.
+ */
+ static bool match_name(const std::string& name);
+
+ /**
+ * Default constructor for an initially empty database.
+ */
+ DB():Database("db"), m_flags(0) { }
+
+ /**
+ * Constructor which fills the flat-file structure from a
+ * PalmOS database.
+ */
+ DB(PalmLib::Database&);
+
+ // destructor
+ virtual ~DB() { }
+
+ /**
+ * After all processing to add fields and records is done,
+ * outputPDB is called to create the actual file format
+ * used by the flat-file database product.
+ *
+ * @param pdb An instance of PalmLib::Database.
+ */
+ virtual void outputPDB(PalmLib::Database& pdb) const;
+
+ /**
+ * Return the maximum number of fields allowed in the
+ * database. This class returns 0 since there is no limit.
+ */
+ virtual unsigned getMaxNumOfFields() const;
+
+ /**
+ * Return true for the field types that this class
+ * currently supports. Returns false otherwise.
+ *
+ * @param type The field type to check for support.
+ */
+ virtual bool supportsFieldType(const Field::FieldType& type) const;
+
+ /**
+ * write the format of the field's argument in format,
+ * and return a strings' vector with name of each argument part.
+ * the format use the same display as used by printf
+ */
+ virtual std::vector<std::string> field_argumentf(int i, std::string& format);
+
+ /**
+ * Return the maximum number of views supported by this
+ * type of flat-file database.
+ */
+ virtual unsigned getMaxNumOfListViews() const;
+
+ /**
+ * Hook the end of the schema processing.
+ */
+ virtual void doneWithSchema();
+
+ /**
+ * Set a extra option.
+ *
+ * @param opt_name The name of the option to set.
+ * @param opt_value The value to assign to this option.
+ */
+ virtual void setOption(const std::string& name,
+ const std::string& value);
+
+ /**
+ * Get a list of extra options.
+ */
+ virtual options_list_t getOptions(void) const;
+
+ // Produce a PalmOS record from a flat-file record.
+ void make_record(PalmLib::Record& pdb_record,
+ const PalmLib::FlatFile::Record& record) const;
+
+ private:
+ pi_uint16_t m_flags;
+
+ class Chunk : public PalmLib::Block {
+ public:
+ Chunk() : PalmLib::Block(), chunk_type(0) { }
+ Chunk(const Chunk& rhs)
+ : PalmLib::Block(rhs), chunk_type(rhs.chunk_type) { }
+ Chunk(PalmLib::Block::const_pointer data,
+ const PalmLib::Block::size_type size)
+ : PalmLib::Block(data, size), chunk_type(0) { }
+ Chunk& operator = (const Chunk& rhs) {
+ Block::operator = (rhs);
+ chunk_type = rhs.chunk_type;
+ return *this;
+ }
+
+ pi_uint16_t chunk_type;
+ };
+
+ typedef std::map<pi_uint16_t, std::vector<Chunk> > chunks_t;
+ chunks_t m_chunks;
+
+ // Extract the chunks from an app info block to m_chunks.
+ void extract_chunks(const PalmLib::Block&);
+
+ // Extract the schema.
+ void extract_schema(unsigned numFields);
+
+ // Extract the list views from the app info block.
+ void extract_listviews();
+
+ //extract the field data
+ std::string extract_fieldsdata(pi_uint16_t field_search,
+ PalmLib::FlatFile::Field::FieldType type);
+
+ void extract_aboutinfo();
+
+ // Determine location and size of each field.
+ void parse_record(PalmLib::Record& record,
+ std::vector<pi_char_t *>& ptrs,
+ std::vector<size_t>& sizes);
+
+ // The following routines build various types of chunks
+ // for the app info block and assemble them all.
+ void build_fieldsdata_chunks(std::vector<Chunk>& chunks) const;
+ void build_standard_chunks(std::vector<Chunk>&) const;
+ void build_listview_chunk(std::vector<Chunk>&,
+ const ListView&) const;
+ void build_about_chunk(std::vector<Chunk>& chunks) const;
+ void build_appinfo_block(const std::vector<Chunk>&,
+ PalmLib::Block&) const;
+ };
+
+ }
+}
+
+#endif
diff --git a/src/translators/pilotdb/libflatfile/Database.cpp b/src/translators/pilotdb/libflatfile/Database.cpp
new file mode 100644
index 0000000..578b82d
--- /dev/null
+++ b/src/translators/pilotdb/libflatfile/Database.cpp
@@ -0,0 +1,331 @@
+/*
+ * palm-db-tools: Abstract adaptor for flat-file databases.
+ * Copyright (C) 1999-2000 by Tom Dyas (tdyas@users.sourceforge.net)
+ */
+
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <sstream>
+#include <utility>
+#include <cctype>
+
+#include <kdebug.h>
+
+#include "Database.h"
+
+PalmLib::FlatFile::Database::Database(std::string p_Type, const PalmLib::Database& pdb)
+ : m_Type(p_Type)
+{
+ title(pdb.name());
+ m_backup = pdb.backup();
+ m_readonly = pdb.readonly();
+ m_copy_prevention = pdb.copy_prevention();
+}
+
+void
+PalmLib::FlatFile::Database::outputPDB(PalmLib::Database& pdb) const
+{
+ pdb.name(title());
+ pdb.backup(m_backup);
+ pdb.readonly(m_readonly);
+ pdb.copy_prevention(m_copy_prevention);
+}
+
+std::string
+PalmLib::FlatFile::Database::title() const
+{
+ return m_title;
+}
+
+void
+PalmLib::FlatFile::Database::title(const std::string& title)
+{
+ m_title = title;
+}
+
+unsigned
+PalmLib::FlatFile::Database::getNumOfFields() const
+{
+ return m_fields.size();
+}
+
+std::string
+PalmLib::FlatFile::Database::field_name(int i) const
+{
+ return m_fields[i].title();
+/* return m_fields[i].first;*/
+}
+
+PalmLib::FlatFile::Field::FieldType
+PalmLib::FlatFile::Database::field_type(int i) const
+{
+ return m_fields[i].type();
+/* return m_fields[i].second;*/
+}
+
+PalmLib::FlatFile::FType
+PalmLib::FlatFile::Database::field(int i) const
+{
+ return m_fields[i];
+}
+
+void
+PalmLib::FlatFile::Database::appendField(PalmLib::FlatFile::FType field)
+{
+ if (! supportsFieldType(field.type())) {
+// throw PalmLib::error("unsupported field type");
+ kdDebug() << "unsupported field type" << endl;
+ return;
+ }
+ if (getMaxNumOfFields() != 0 && getNumOfFields() + 1 > getMaxNumOfFields()) {
+// throw PalmLib::error("maximum number of fields reached");
+ kdDebug() << "maximum number of fields reached" << endl;
+ return;
+ }
+ m_fields.push_back(field);
+}
+
+void
+PalmLib::FlatFile::Database::appendField(const std::string& name,
+ Field::FieldType type, std::string data)
+{
+ if (! supportsFieldType(type)) {
+ kdDebug() << "PalmLib::FlatFile::Database::appendField() - unsupported field type" << endl;
+ return;
+ }
+// throw PalmLib::error("unsupported field type");
+ if (getMaxNumOfFields() != 0 && getNumOfFields() + 1 > getMaxNumOfFields()) {
+ kdDebug() << "PalmLib::FlatFile::Database::appendField() - maximum number of fields reached" << endl;
+ return;
+ }
+// throw PalmLib::error("maximum number of fields reached");
+
+/* m_fields.push_back(std::make_pair(name, type));*/
+/* m_fields.push_back(PalmLib::FlatFile::make_ftype(name, type));*/
+ m_fields.push_back(PalmLib::FlatFile::FType(name, type, data));
+}
+
+void
+PalmLib::FlatFile::Database::insertField(int i, PalmLib::FlatFile::FType field)
+{
+ if (! supportsFieldType(field.type())) {
+// throw PalmLib::error("unsupported field type");
+ kdDebug() << "unsupported field type" << endl;
+ return;
+ }
+ if (getMaxNumOfFields() != 0 && getNumOfFields() + 1 > getMaxNumOfFields()) {
+// throw PalmLib::error("maximum number of fields reached");
+ kdDebug() << "maximum number of fields reached" << endl;
+ return;
+ }
+/* m_fields.push_back(std::make_pair(name, type));*/
+/* m_fields.push_back(PalmLib::FlatFile::make_ftype(name, type));*/
+ m_fields.insert(m_fields.begin() + i, field);
+}
+
+void
+PalmLib::FlatFile::Database::insertField(int i, const std::string& name,
+ Field::FieldType type, std::string data)
+{
+ if (! supportsFieldType(type)) {
+// throw PalmLib::error("unsupported field type");
+ kdDebug() << "unsupported field type" << endl;
+ return;
+ }
+ if (getMaxNumOfFields() != 0 && getNumOfFields() + 1 > getMaxNumOfFields()) {
+// throw PalmLib::error("maximum number of fields reached");
+ kdDebug() << "maximum number of fields reached" << endl;
+ return;
+ }
+/* m_fields.push_back(std::make_pair(name, type));*/
+/* m_fields.push_back(PalmLib::FlatFile::make_ftype(name, type));*/
+ m_fields.insert(m_fields.begin() + i, PalmLib::FlatFile::FType(name, type, data));
+}
+
+void
+PalmLib::FlatFile::Database::removeField(int i)
+{
+ m_fields.erase(m_fields.begin() + i);
+}
+
+unsigned
+PalmLib::FlatFile::Database::getNumRecords() const
+{
+ return m_records.size();
+}
+
+PalmLib::FlatFile::Record
+PalmLib::FlatFile::Database::getRecord(unsigned index) const
+{
+ if (index >= getNumRecords()) {
+ kdDebug() << "invalid index" << endl;
+ //throw std::out_of_range("invalid index");
+ }
+ return m_records[index];
+}
+
+void
+PalmLib::FlatFile::Database::appendRecord(PalmLib::FlatFile::Record rec)
+{
+ if (rec.fields().size() != getNumOfFields()) {
+// throw PalmLib::error("the number of fields mismatch");
+ kdDebug() << "the number of fields mismatch" << endl;
+ return;
+ }
+ for (unsigned int i = 0; i < getNumOfFields(); i++) {
+#ifdef HAVE_VECTOR_AT
+ const Field field = rec.fields().at(i);
+#else
+ const Field field = rec.fields()[i];
+#endif
+ if (field.type != field_type(i)) {
+ kdDebug() << "field " << i << " type " << field_type(i) << " mismatch: " << field.type << endl;
+ return;
+// throw PalmLib::error(buffer.str());
+ }
+ }
+ m_records.push_back(rec);
+}
+
+void
+PalmLib::FlatFile::Database::deleteRecord(unsigned index)
+{
+ m_records.erase(m_records.begin() + index);
+}
+
+void
+PalmLib::FlatFile::Database::clearRecords()
+{
+ m_records.clear();
+}
+
+unsigned
+PalmLib::FlatFile::Database::getNumOfListViews() const
+{
+ return m_listviews.size();
+}
+
+PalmLib::FlatFile::ListView
+PalmLib::FlatFile::Database::getListView(unsigned index) const
+{
+ return m_listviews[index];
+}
+
+void
+PalmLib::FlatFile::Database::setListView(unsigned index,
+ const PalmLib::FlatFile::ListView& lv)
+{
+ // Ensure that the field numbers are within range.
+ for (PalmLib::FlatFile::ListView::const_iterator i = lv.begin();
+ i != lv.end(); ++i) {
+ if ((*i).field >= getNumOfFields())
+ return;
+ }
+
+ m_listviews[index] = lv;
+}
+
+void
+PalmLib::FlatFile::Database::appendListView(const ListView& lv)
+{
+ // Enforce any limit of the maximum number of list views.
+ if (getMaxNumOfListViews() != 0
+ && getNumOfListViews() + 1 > getMaxNumOfListViews())
+ return;
+// throw PalmLib::error("too many list views for this database type");
+
+ // Ensure that the field numbers are within range.
+ for (PalmLib::FlatFile::ListView::const_iterator i = lv.begin();
+ i != lv.end(); ++i) {
+ if ((*i).field >= getNumOfFields())
+ return;
+ }
+ m_listviews.push_back(lv);
+}
+
+void
+PalmLib::FlatFile::Database::removeListView(unsigned index)
+{
+ if (index < getNumOfListViews())
+ m_listviews.erase( m_listviews.begin()+index);
+}
+
+static void
+strlower(std::string& str)
+{
+ for (std::string::iterator p = str.begin(); p != str.end(); ++p) {
+ if (isupper(*p))
+ *p = tolower(*p);
+ }
+}
+
+static bool
+string2boolean(std::string str)
+{
+ strlower(str);
+ if (str == "on")
+ return true;
+ else if (str == "off")
+ return false;
+ else if (str == "true")
+ return true;
+ else if (str == "t")
+ return true;
+ else if (str == "false")
+ return false;
+ else if (str == "f")
+ return false;
+ else {
+ int num = 0;
+
+ std::istringstream(str.c_str()) >> num;
+ return num != 0 ? true : false;
+ }
+}
+
+void
+PalmLib::FlatFile::Database::setOption(const std::string& name,
+ const std::string& value)
+{
+ if (name == "backup")
+ m_backup = string2boolean(value);
+ else if (name == "inROM")
+ m_readonly = string2boolean(value);
+ else if (name == "copy-prevention")
+ m_copy_prevention = string2boolean(value);
+}
+
+PalmLib::FlatFile::Database::options_list_t
+PalmLib::FlatFile::Database::getOptions() const
+{
+ PalmLib::FlatFile::Database::options_list_t set;
+ typedef PalmLib::FlatFile::Database::options_list_t::value_type value;
+
+ if (m_backup)
+ set.push_back(value("backup", "true"));
+ else
+ set.push_back(value("backup", "false"));
+
+ if (m_readonly)
+ set.push_back(value("inROM", "true"));
+
+ if (m_copy_prevention)
+ set.push_back(value("copy-prevention", "true"));
+
+ return set;
+}
+
+void
+PalmLib::FlatFile::Database::doneWithSchema()
+{
+ // Ensure that the database has at least one field.
+ if (getNumOfFields() == 0)
+ return;
+// throw PalmLib::error("at least one field must be specified");
+
+ // Ensure that the database has a title.
+ if (title().empty())
+ return;
+// throw PalmLib::error("a title must be specified");
+}
diff --git a/src/translators/pilotdb/libflatfile/Database.h b/src/translators/pilotdb/libflatfile/Database.h
new file mode 100644
index 0000000..5bcba32
--- /dev/null
+++ b/src/translators/pilotdb/libflatfile/Database.h
@@ -0,0 +1,320 @@
+/*
+ * palm-db-tools: Abstract adaptor for flat-file databases.
+ * Copyright (C) 1999-2000 by Tom Dyas (tdyas@users.sourceforge.net)
+ */
+
+#ifndef __PALMLIB_FLATFILE_DATABASE_H__
+#define __PALMLIB_FLATFILE_DATABASE_H__
+
+#include <vector>
+#include <string>
+#include <utility>
+
+#include "../libpalm/Database.h"
+#include "Field.h"
+#include "Record.h"
+#include "ListView.h"
+#include "FType.h"
+
+#define NOTETITLE_LENGTH 32
+
+namespace PalmLib {
+ namespace FlatFile {
+
+ // This class is an in-memory representation of a typical
+ // PalmOS flat-file database. The caller can request write the
+ // data to a real PalmLib::Database object at any time to
+ // actually obtain the data in a format usable on the Palm
+ // Pilot.
+
+ class Database {
+ public:
+ // convenience type for the options list parsing
+ typedef std::vector< std::pair< std::string, std::string> > options_list_t;
+
+ /**
+ * Default constructor which creates an empty
+ * database. Subclasses should provide a default
+ * constructor and an additional constructorwhich takes a
+ * PalmOS::Database as an argument.
+ */
+ Database(std::string p_Type)
+ : m_backup(false), m_readonly(false),
+ m_copy_prevention(false), m_Type(p_Type)
+ { }
+
+ /**
+ * Constructor which fills the flat-file structure from a
+ * PalmOS database.
+ *
+ * @param pdb PalmOS database to read from.
+ */
+ Database(std::string p_Type, const PalmLib::Database& pdb);
+
+ /**
+ * The destructor is empty since we have no other objects
+ * to dispose of. It is virtual since we have subclasses
+ * for specific flat-file database products.
+ */
+ virtual ~Database() { }
+
+ /**
+ * After all processing to add fields and records is done,
+ * outputPDB is called to create the actual file format
+ * used by the flat-file database product. This method is
+ * abstract since only subclasses know the specific file
+ * formats.
+ *
+ * @param pdb An instance of PalmLib::Database.
+ */
+ virtual void outputPDB(PalmLib::Database& pdb) const;
+
+ /**
+ * Return the title of this flat-file database.
+ */
+ virtual std::string title() const;
+
+ /**
+ * Set the title of this database.
+ *
+ * @param title New title of the database.
+ */
+ virtual void title(const std::string& title);
+
+ /**
+ * Return the maximum number of fields allowed in the
+ * database. The object will not allow the number of
+ * fields to exceed the returned value. This method is
+ * abstract since only the subclasses know the limit on
+ * fields. 0 is returned if there is no limit.
+ */
+ virtual unsigned getMaxNumOfFields() const = 0;
+
+ /**
+ * Return the number of fields in the database.
+ */
+ virtual unsigned getNumOfFields() const;
+
+ /**
+ * Accessor function for the name of a field.
+ */
+ virtual std::string field_name(int i) const;
+
+ /**
+ * Accessor function for type of a field.
+ */
+ virtual Field::FieldType field_type(int i) const;
+
+ /**
+ * Accessor function for the field informations
+ */
+ virtual FType field(int i) const;
+
+ /**
+ * write the format of the field's argument in format,
+ * and return a strings' vector with name of each argument part.
+ * the format use the same display as used by printf
+ */
+ virtual std::vector<std::string> field_argumentf(int, std::string& format)
+ { format = std::string(""); return std::vector<std::string>(0, std::string(""));}
+
+ /**
+ * Add a field to the flat-file database. An exception
+ * will be thrown if the maximum number of fields would be
+ * exceeded or the field type is unsupported.
+ *
+ * @param name Name of the new field.
+ * @param type The type of the new field.
+ */
+ virtual void appendField(FType field);
+ virtual void appendField(const std::string& name,
+ Field::FieldType type, std::string data = std::string(""));
+
+ /**
+ * Insert a field to the flat-file database. An exception
+ * will be thrown if the maximum number of fields would be
+ * exceeded or the field type is unsupported.
+ *
+ * @param name Name of the new field.
+ * @param type The type of the new field.
+ */
+ virtual void insertField(int i, FType field);
+ virtual void insertField(int i, const std::string& name,
+ Field::FieldType type, std::string data = std::string(""));
+
+ /**
+ * Remove a Field in the flat-file database. An Exception
+ * will thrown if the field doesn't exist.
+ */
+ virtual void removeField(int i);
+
+ /**
+ * Returns true if this database supports a specific field
+ * type. This method is abstract since only the subclasses
+ * know which field types are supported.
+ *
+ * @param type The field type that should be checked for support.
+ */
+ virtual bool supportsFieldType(const Field::FieldType& type) const = 0;
+
+ /**
+ * Return the number of records in the database.
+ */
+ virtual unsigned getNumRecords() const;
+
+ /**
+ * Return the record with the given index. The caller gets
+ * a private copy of the data and _not_ a reference to the
+ * data.
+ *
+ * @param index Index of the record to retrieve.
+ */
+ virtual Record getRecord(unsigned index) const;
+
+ /**
+ * Append a record to the database. An exception will be
+ * thrown if their are not enough fields or if field types
+ * mismatch.
+ *
+ * @param rec The record to append.
+ */
+ virtual void appendRecord(Record rec);
+
+ /**
+ * Remove all records from the database
+ */
+ virtual void clearRecords();
+
+ /**
+ * Remove a record from the database
+ */
+ virtual void deleteRecord(unsigned index);
+
+ /**
+ * Return the maximum number of views supported by this
+ * type of flat-file database. This method is abstract
+ * since only the subclasses know the exact value.
+ */
+ virtual unsigned getMaxNumOfListViews() const = 0;
+
+ /**
+ * Return the actual number of views present in this
+ * database.
+ */
+ virtual unsigned getNumOfListViews() const;
+
+ /**
+ * Return a copy of the list view at the given index.
+ *
+ * @param index Index of the list view to return.
+ */
+ virtual ListView getListView(unsigned index) const;
+
+ /**
+ * Set the list view at the given index to the new list
+ * view. An exception may be thrown if field numbers are
+ * invalid or the list view doesn't pass muster with the
+ * subclass.
+ *
+ * @param index Index of the list view to set.
+ * @param listview The new list view.
+ */
+ virtual void setListView(unsigned index, const ListView& listview);
+
+ /**
+ * Append a new list view. This will fail if the maximum
+ * number of list views would be exceeded.
+ *
+ * @param listview The new list view to append.
+ */
+ virtual void appendListView(const ListView& listview);
+
+ /**
+ * Remove a list view.
+ *
+ * @param index Index of the list view to remove.
+ */
+ virtual void removeListView(unsigned index);
+
+ /**
+ * Process a special option. If the option is not
+ * supported, then it is silently ignored. Subclasses
+ * should call the base class first so that options common
+ * to all flat-file databases can be processed.
+ *
+ * @param name Name of the option.
+ * @param value String value assigned to the option. */
+ virtual void setOption(const std::string& name,
+ const std::string& value);
+
+ /**
+ * Return a list of of all extra options supported by this
+ * database. Subclasses should call the base class first
+ * and then merge any extra options. Get a list of extra
+ * options.
+ */
+ virtual options_list_t getOptions(void) const;
+
+ /**
+ * Hook function which should be invoked by a caller after
+ * all calls the meta-deta functions have completed. This
+ * allows the database type-specific code to do final
+ * checks on the meta-data. An exception will be throw if
+ * there is an error. Otherwise, nothing will happen.
+ */
+ virtual void doneWithSchema();
+
+ /**
+ * Change and Return the about information
+ * of the database when it's supportted
+ */
+ virtual void setAboutInformation(std::string _string)
+ {
+ about.information = _string;
+ }
+
+ virtual std::string getAboutInformation() const
+ {
+ return about.information;
+ }
+
+ std::string type() const
+ {
+ return m_Type;
+ }
+
+ private:
+ // We provide a dummy copy constructor and assignment
+ // operator in order to prevent any copying of the object.
+ Database(const Database&) { }
+ Database& operator = (const Database&) { return *this; }
+
+/* typedef std::vector< std::pair< std::string, Field::FieldType > >*/
+ typedef std::vector< FType>
+ field_list_t;
+ typedef std::vector<Record> record_list_t;
+ typedef std::vector<ListView> listview_list_t;
+
+ typedef std::vector< std::pair< std::string, std::vector< std::string > > >
+ listitems_list_t;
+
+ field_list_t m_fields; // database schema
+ record_list_t m_records; // the database itself
+ listitems_list_t m_list; // the items lists include in the database
+ listview_list_t m_listviews; // list views
+ bool m_backup; // backup flag for PDB
+ bool m_readonly; // readonly flag for PDB
+ bool m_copy_prevention; // copy prevention for PDB
+ std::string m_title; // name of database
+ class About
+ {
+ public:
+ std::string information;
+ } about;
+ std::string m_Type;
+ };
+
+ } // namespace FlatFile
+} // namespace PalmLib
+
+#endif
diff --git a/src/translators/pilotdb/libflatfile/FType.h b/src/translators/pilotdb/libflatfile/FType.h
new file mode 100644
index 0000000..86396b3
--- /dev/null
+++ b/src/translators/pilotdb/libflatfile/FType.h
@@ -0,0 +1,48 @@
+/*
+ * palm-db-tools: Field Type definitions for flat-file database objects.
+ * Copyright (C) 2000 by Tom Dyas (tdyas@users.sourceforge.net)
+ */
+
+#ifndef __PALMLIB_FLATFILE_FTYPE_H__
+#define __PALMLIB_FLATFILE_FTYPE_H__
+
+#include <string>
+#include <utility>
+
+#include "../libpalm/palmtypes.h"
+#include "Field.h"
+
+namespace PalmLib {
+ namespace FlatFile {
+
+ class FType {
+ public:
+ friend class PalmLib::FlatFile::Field;
+ FType(std::string title, PalmLib::FlatFile::Field::FieldType type) :
+ m_title(title), m_type(type), m_data("") { }
+
+ FType(std::string title, PalmLib::FlatFile::Field::FieldType type, std::string data) :
+ m_title(title), m_type(type), m_data(data) { }
+
+ virtual ~FType() { }
+
+ std::string title() const {return m_title;}
+ virtual PalmLib::FlatFile::Field::FieldType type() const
+ { return m_type;}
+
+ virtual std::string argument() const { return m_data;}
+
+ void set_argument( const std::string data) { m_data = data;}
+
+ void setTitle( const std::string value) { m_title = value;}
+ void setType( const PalmLib::FlatFile::Field::FieldType value) { m_type = value;}
+ private:
+ std::string m_title;
+ PalmLib::FlatFile::Field::FieldType m_type;
+
+ std::string m_data;
+ };
+ }
+}
+
+#endif
diff --git a/src/translators/pilotdb/libflatfile/Field.h b/src/translators/pilotdb/libflatfile/Field.h
new file mode 100644
index 0000000..583bc21
--- /dev/null
+++ b/src/translators/pilotdb/libflatfile/Field.h
@@ -0,0 +1,119 @@
+/*
+ * palm-db-tools: Field definitions for flat-file database objects.
+ * Copyright (C) 2000 by Tom Dyas (tdyas@users.sourceforge.net)
+ */
+
+#ifndef __PALMLIB_FLATFILE_FIELD_H__
+#define __PALMLIB_FLATFILE_FIELD_H__
+
+#include <string>
+
+#include "../libpalm/palmtypes.h"
+
+namespace PalmLib {
+ namespace FlatFile {
+
+ class Field {
+ public:
+ Field() : no_value(false), type(STRING), v_boolean(false),
+ v_integer(0), v_float(0) { }
+ ~Field() { }
+
+ // True if this field has no value. (NULL in SQL terms)
+ bool no_value;
+
+ enum FieldType {
+ STRING,
+ BOOLEAN,
+ INTEGER,
+ FLOAT,
+ DATE,
+ TIME,
+ DATETIME,
+ LIST,
+ LINK,
+ NOTE,
+ CALCULATED,
+ LINKED,
+ LAST
+ };
+
+ enum FieldType type;
+
+ std::string v_string;
+ std::string v_note;
+ bool v_boolean;
+ PalmLib::pi_int32_t v_integer;
+ long double v_float;
+ struct {
+ int month;
+ int day;
+ int year;
+ } v_date; // valid for DATE and DATETIME
+ struct {
+ int hour;
+ int minute;
+ } v_time; // valid for TIME and DATETIME
+
+ /*
+ friend Field operator = (const Field& y)
+ {
+ this.v_string = y.v_string;
+ this.v_boolean = y.v_boolean;
+ this.v_integer = y.v_integer;
+ this.v_float = y.v_float;
+ this.v_date.month = y.v_date.month;
+ this.v_date.day = y.v_date.day;
+ this.v_date.year = y.v_date.year;
+ this.v_time.hour = y.v_time.hour;
+ this.v_time.minute = y.v_time.minute;
+ this.v_note = y.v_note;
+ }
+*/
+ friend bool operator==(const Field& x, const Field& y)
+ {
+ if (x.type != y.type)
+ return false;
+ switch (x.type) {
+ case STRING:
+ return (x.v_string == y.v_string);
+ case BOOLEAN:
+ return (x.v_boolean == y.v_boolean);
+ case INTEGER:
+ return (x.v_integer == y.v_integer);
+ case FLOAT:
+ return (x.v_float == y.v_float);
+ case DATE:
+ return (x.v_date.month == y.v_date.month
+ && x.v_date.day == y.v_date.day
+ && x.v_date.year == y.v_date.year);
+ case TIME:
+ return (x.v_time.hour == y.v_time.hour
+ && x.v_time.minute == y.v_time.minute);
+ case DATETIME:
+ return (x.v_date.month == y.v_date.month
+ && x.v_date.day == y.v_date.day
+ && x.v_date.year == y.v_date.year
+ && x.v_time.hour == y.v_time.hour
+ && x.v_time.minute == y.v_time.minute);
+ case LIST:
+ return (x.v_string == y.v_string);
+ case LINK:
+ return (x.v_string == y.v_string);
+ case NOTE:
+ return (x.v_string == y.v_string
+ && x.v_note == y.v_note);
+ case CALCULATED:
+ return true; //a calculated field could be recalculate at each time
+ case LINKED:
+ return (x.v_string == y.v_string);
+ default:
+ return (x.v_string == y.v_string);
+ }
+ }
+ };
+
+ }
+}
+
+#endif
diff --git a/src/translators/pilotdb/libflatfile/ListView.h b/src/translators/pilotdb/libflatfile/ListView.h
new file mode 100644
index 0000000..4229548
--- /dev/null
+++ b/src/translators/pilotdb/libflatfile/ListView.h
@@ -0,0 +1,77 @@
+#ifndef __PALMOS__FLATFILE__VIEW_H__
+#define __PALMOS__FLATFILE__VIEW_H__
+
+#include <string>
+#include <vector>
+
+#include "ListViewColumn.h"
+
+namespace PalmLib {
+ namespace FlatFile {
+
+ // The ListView class represents the a "list view" as
+ // implemented by the major PalmOS flat-file programs. The
+ // main idea is a series of columns that display a field of
+ // the database.
+ //
+ // For fun, this class exports the STL interface of the STL
+ // class it uses to store the ListViewColumn classes.
+
+ class ListView {
+ private:
+ typedef std::vector<ListViewColumn> rep_type;
+ rep_type rep;
+
+ public:
+ typedef rep_type::value_type value_type;
+ typedef rep_type::iterator iterator;
+ typedef rep_type::const_iterator const_iterator;
+ typedef rep_type::reference reference;
+ typedef rep_type::const_reference const_reference;
+ typedef rep_type::size_type size_type;
+ typedef rep_type::difference_type difference_type;
+ typedef rep_type::reverse_iterator reverse_iterator;
+ typedef rep_type::const_reverse_iterator const_reverse_iterator;
+
+ // global fields
+ std::string name;
+ bool editoruse;
+
+ // STL pull-up interface (probably not complete)
+ iterator begin() { return rep.begin(); }
+ const_iterator begin() const { return rep.begin(); }
+ iterator end() { return rep.end(); }
+ const_iterator end() const { return rep.end(); }
+ reverse_iterator rbegin() { return rep.rbegin(); }
+ const_reverse_iterator rbegin() const { return rep.rbegin(); }
+ reverse_iterator rend() { return rep.rend(); }
+ const_reverse_iterator rend() const { return rep.rend(); }
+ size_type size() const { return rep.size(); }
+ size_type max_size() const { return rep.max_size(); }
+ bool empty() const { return rep.empty(); }
+ reference front() { return rep.front(); }
+ const_reference front() const { return rep.front(); }
+ reference back() { return rep.back(); }
+ const_reference back() const { return rep.back(); }
+ void push_back(const ListViewColumn& x) { rep.push_back(x); }
+ void pop_back() { rep.pop_back(); }
+ void clear() { rep.clear(); }
+ void resize(size_type new_size, const ListViewColumn& x)
+ { rep.resize(new_size, x); }
+ void resize(size_type new_size)
+ { rep.resize(new_size, ListViewColumn()); }
+
+ ListView() : rep(), name(""), editoruse(false) { }
+ ListView(const ListView& rhs) : rep(rhs.rep), name(rhs.name), editoruse(false) { }
+ ListView& operator = (const ListView& rhs) {
+ name = rhs.name;
+ rep = rhs.rep;
+ return *this;
+ }
+
+ };
+
+ }
+}
+
+#endif
diff --git a/src/translators/pilotdb/libflatfile/ListViewColumn.h b/src/translators/pilotdb/libflatfile/ListViewColumn.h
new file mode 100644
index 0000000..7b5330e
--- /dev/null
+++ b/src/translators/pilotdb/libflatfile/ListViewColumn.h
@@ -0,0 +1,19 @@
+#ifndef __PALMLIB_FLATFILE_LISTVIEWCOLUMN_H__
+#define __PALMLIB_FLATFILE_LISTVIEWCOLUMN_H__
+
+namespace PalmLib {
+ namespace FlatFile {
+
+ // The ListViewColumn class stores the field number and column
+ // width for a column in a list view.
+
+ struct ListViewColumn {
+ ListViewColumn() : field(0), width(80) { }
+ ListViewColumn(unsigned a1, unsigned a2) : field(a1), width(a2) { }
+ unsigned field;
+ unsigned width;
+ };
+ }
+}
+
+#endif
diff --git a/src/translators/pilotdb/libflatfile/Makefile.am b/src/translators/pilotdb/libflatfile/Makefile.am
new file mode 100644
index 0000000..d3ab012
--- /dev/null
+++ b/src/translators/pilotdb/libflatfile/Makefile.am
@@ -0,0 +1,20 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+noinst_LIBRARIES = liblibflatfile.a
+
+AM_CPPFLAGS = $(all_includes)
+
+liblibflatfile_a_METASOURCES = AUTO
+
+liblibflatfile_a_SOURCES = DB.cpp Database.cpp
+
+
+EXTRA_DIST = Database.cpp Database.h DB.cpp DB.h Field.h FType.h ListView.h ListViewColumn.h Record.h
+
+####### kdevelop will overwrite this part!!! (end)############
+
+# is this the right way to do this? I need to include the strop.o object file since its
+# in the parent directory
+liblibflatfile_a_LIBADD = ../strop.o
+CLEANFILES = strop.Po
+
+KDE_OPTIONS = noautodist
diff --git a/src/translators/pilotdb/libflatfile/Record.h b/src/translators/pilotdb/libflatfile/Record.h
new file mode 100644
index 0000000..537953e
--- /dev/null
+++ b/src/translators/pilotdb/libflatfile/Record.h
@@ -0,0 +1,45 @@
+/*
+ * palm-db-tools: Field definitions for flat-file database objects.
+ * Copyright (C) 2000 by Tom Dyas (tdyas@users.sourceforge.net)
+ */
+
+#ifndef __PALMLIB_FLATFILE_RECORD_H__
+#define __PALMLIB_FLATFILE_RECORD_H__
+
+#include <vector>
+
+#include "Field.h"
+
+namespace PalmLib {
+ namespace FlatFile {
+// typedef std::vector<Field> Record;
+
+ class Record{
+ public:
+
+ const std::vector<Field> fields() const { return m_Fields; }
+
+ void appendField(Field newfield) { m_Fields.push_back(newfield); }
+ bool created() const { return m_New;}
+ void created(bool on){ m_New = on;}
+ bool secret() const { return m_Secret;}
+ void secret(bool on) { m_Secret = on;}
+
+ bool dirty() const { return m_Dirty; }
+ void dirty( bool on) { m_Dirty = on; }
+
+ pi_uint32_t unique_id() const { return m_UID; }
+ void unique_id(pi_uint32_t id) { m_UID = id; }
+ private:
+
+ std::vector<Field> m_Fields;
+ bool m_Secret;
+ bool m_New;
+
+ bool m_Dirty;
+ pi_uint32_t m_UID;
+ };
+ }
+}
+
+#endif
diff --git a/src/translators/pilotdb/libpalm/Block.cpp b/src/translators/pilotdb/libpalm/Block.cpp
new file mode 100644
index 0000000..c58f6f1
--- /dev/null
+++ b/src/translators/pilotdb/libpalm/Block.cpp
@@ -0,0 +1,85 @@
+/*
+ * palm-db-tools: Encapsulate "blocks" of data.
+ * Copyright (C) 2000 by Tom Dyas (tdyas@users.sourceforge.net)
+ *
+ * The PalmLib::Block class represents a generic block of data. It is
+ * used to simplify passing arrays of pi_char_t around.
+ */
+
+#include <cstring>
+
+#include "Block.h"
+
+void PalmLib::Block::reserve(PalmLib::Block::size_type new_size)
+{
+ if (new_size > capacity()) {
+ // Allocate a new buffer containing a copy of the old with the
+ // remainder zero'ed out.
+ pointer new_data = new pi_char_t[new_size];
+ memcpy(new_data, m_data, m_size);
+ memset(new_data + m_size, 0, new_size - m_size);
+
+ // Replace the existing buffer.
+ delete [] m_data;
+ m_data = new_data;
+ m_size = new_size;
+ }
+}
+
+void PalmLib::Block::resize(size_type new_size)
+{
+ if (new_size < m_size) {
+ // Copy the data that will remain to a new buffer and switch to it.
+ pointer new_data = new pi_char_t[new_size];
+ memcpy(new_data, m_data, new_size);
+
+ // Replace the existing buffer.
+ delete [] m_data;
+ m_data = new_data;
+ m_size = new_size;
+ } else if (new_size > m_size) {
+ // Copy the data that will remain to a new buffer and switch to it.
+ pointer new_data = new pi_char_t[new_size];
+ memcpy(new_data, m_data, m_size);
+ memset(new_data + m_size, 0, new_size - m_size);
+
+ // Replace the existing buffer.
+ delete [] m_data;
+ m_data = new_data;
+ m_size = new_size;
+ }
+}
+
+void PalmLib::Block::assign(PalmLib::Block::const_pointer data,
+ const PalmLib::Block::size_type size)
+{
+ clear();
+ if (data && size > 0) {
+ m_size = size;
+ m_data = new pi_char_t[m_size];
+ memcpy(m_data, data, m_size);
+ }
+}
+
+void PalmLib::Block::assign(const PalmLib::Block::size_type size,
+ const PalmLib::Block::value_type value)
+{
+ clear();
+ if (size > 0) {
+ m_size = size;
+ m_data = new pi_char_t[m_size];
+ memset(m_data, value, m_size);
+ }
+}
+
+bool operator == (const PalmLib::Block& lhs, const PalmLib::Block& rhs)
+{
+ if (lhs.size() == rhs.size()) {
+ if (lhs.data()) {
+ if (memcmp(lhs.data(), rhs.data(), lhs.size()) != 0)
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
diff --git a/src/translators/pilotdb/libpalm/Block.h b/src/translators/pilotdb/libpalm/Block.h
new file mode 100644
index 0000000..6ed6069
--- /dev/null
+++ b/src/translators/pilotdb/libpalm/Block.h
@@ -0,0 +1,186 @@
+/*
+ * palm-db-tools: Encapsulate "blocks" of data.
+ * Copyright (C) 2000 by Tom Dyas (tdyas@users.sourceforge.net)
+ *
+ * The PalmLib::Block class represents a generic block of data. It is
+ * used to make passing pi_char_t buffers around very easy. The Record
+ * and Resource classes both inherit from this class. A STL interface
+ * is also attempted though it is probably not complete.
+ */
+
+#ifndef __PALMLIB_BLOCK_H__
+#define __PALMLIB_BLOCK_H__
+
+#include <algorithm>
+#include <iterator>
+
+#include "palmtypes.h"
+
+namespace PalmLib {
+
+ class Block {
+ public:
+ // STL: container type definitions
+ typedef PalmLib::pi_char_t value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type* iterator;
+ typedef const value_type* const_iterator;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+ // STL: reverisible container type definitions
+#ifdef __GNUG__
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+#endif
+
+ /**
+ * Default constructor.
+ */
+ Block() : m_data(0), m_size(0) { }
+
+ /**
+ * Constructor which fills the block from buffer "raw" with
+ * length "len".
+ */
+ Block(const_pointer raw, const size_type len) : m_data(0), m_size(0) {
+ assign(raw, len);
+ }
+
+ /**
+ * Constructor which takes a size and allocates a zero'ed out
+ * buffer of that size. (STL: Sequence: default fill
+ * constructor)
+ */
+ Block(const size_type size, const value_type value = 0)
+ : m_data(0), m_size(0) {
+ assign(size, value);
+ }
+
+ /**
+ * Constructor which takes two iterators and builds the block
+ * from the region between the iterators. (STL: Sequence:
+ * range constructor)
+ */
+ Block(const_iterator a, const_iterator b) : m_data(0), m_size(0) {
+ assign(a, b - a);
+ }
+
+ /**
+ * Copy constructor. Just copies the data from the other block
+ * into this block.
+ */
+ Block(const Block& rhs) : m_data(0), m_size(0) {
+ assign(rhs.data(), rhs.size());
+ }
+
+ /**
+ * Destructor. Just frees the buffer if it exists.
+ */
+ virtual ~Block() { clear(); }
+
+ /**
+ * Assignment operator.
+ *
+ * @param rhs The block whose contents should be copied.
+ */
+ Block& operator = (const Block& rhs) {
+ assign(rhs.data(), rhs.size());
+ return *this;
+ }
+
+ // STL: Container
+ iterator begin() { return m_data; }
+ const_iterator begin() const { return m_data; }
+ iterator end() { return (m_data != 0) ? (m_data + m_size) : (0); }
+ const_iterator end() const
+ { return (m_data != 0) ? (m_data + m_size) : (0); }
+ size_type size() const { return m_size; }
+ size_type max_size() const {
+ return size_type(-1) / sizeof(value_type);
+ }
+ bool empty() const { return m_size == 0; }
+
+ // STL: Reversible Container
+#ifdef __GNUG__
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+#endif
+
+ // STL: Random Access Container
+ reference operator [] (size_type index) { return m_data[index]; }
+ const_reference operator [] (size_type index) const
+ { return m_data[index]; }
+
+ // STL: Sequence (not complete)
+ void clear() {
+ if (m_data) {
+ delete [] m_data;
+ m_data = 0;
+ m_size = 0;
+ }
+ }
+ void resize(size_type n);
+ reference front() { return m_data[0]; }
+ const_reference front() const { return m_data[0]; }
+
+ // STL: (present in vector but not part of a interface spec)
+ size_type capacity() const { return m_size; }
+ void reserve(size_type size);
+
+ /**
+ * Return a pointer to the data area. If there are no
+ * contents, then the return value will be NULL. This is not
+ * an STL method but goes with this class as a singular data
+ * block and not a container (even though it is).
+ */
+ iterator data() { return m_data; }
+ const_iterator data() const { return m_data; }
+
+ /**
+ * Replace the existing contents of the Block with the buffer
+ * that starts at raw of size len.
+ *
+ * @param raw Pointer to the new contents.
+ * @param len Size of the new contents.
+ */
+ void assign(const_pointer data, const size_type size);
+
+ /**
+ * Replace the existing contents of the Block with a buffer
+ * consisting of size elements equal to fill.
+ *
+ * @param size The size of the new contents.
+ * @param value Value to fill the contents with.
+ */
+ void assign(const size_type size, const value_type value = 0);
+
+ // compatiblity functions (remove before final 0.3.0 release)
+ const_pointer raw_data() const { return data(); }
+ pointer raw_data() { return data(); }
+ size_type raw_size() const { return size(); }
+ void set_raw(const_pointer raw, const size_type len)
+ { assign(raw, len); }
+
+ private:
+ pointer m_data;
+ size_type m_size;
+ };
+
+}
+
+bool operator == (const PalmLib::Block& lhs, const PalmLib::Block& rhs);
+
+inline bool operator != (const PalmLib::Block& lhs, const PalmLib::Block& rhs)
+{ return ! (lhs == rhs); }
+
+#endif
diff --git a/src/translators/pilotdb/libpalm/Database.cpp b/src/translators/pilotdb/libpalm/Database.cpp
new file mode 100644
index 0000000..38d896f
--- /dev/null
+++ b/src/translators/pilotdb/libpalm/Database.cpp
@@ -0,0 +1,43 @@
+/*
+ * palm-db-tools: General interface to a PalmOS database.
+ * Copyright (C) 2000 by Tom Dyas (tdyas@users.sourceforge.net)
+ *
+ * This file implens an abstract interface to PalmOS
+ * databases. Subclasses would include the class that reads/writes PDB
+ * files and possibly databases that can be accessed over the HotSync
+ * protocols.
+ */
+
+#include "palmtypes.h"
+#include "Record.h"
+#include "Database.h"
+
+#ifndef __GNUG__
+
+// MSVC: Visual C++ doesn't like initializers in the header ...
+const PalmLib::pi_uint16_t PalmLib::Database::FLAG_HDR_RESOURCE = 0x0001;
+const PalmLib::pi_uint16_t PalmLib::Database::FLAG_HDR_READ_ONLY = 0x0002;
+const PalmLib::pi_uint16_t PalmLib::Database::FLAG_HDR_APPINFO_DIRTY = 0x0004;
+const PalmLib::pi_uint16_t PalmLib::Database::FLAG_HDR_BACKUP = 0x0008;
+const PalmLib::pi_uint16_t PalmLib::Database::FLAG_HDR_OK_TO_INSTALL_NEWER = 0x0010;
+const PalmLib::pi_uint16_t PalmLib::Database::FLAG_HDR_RESET_AFTER_INSTALL = 0x0020;
+const PalmLib::pi_uint16_t PalmLib::Database::FLAG_HDR_COPY_PREVENTION = 0x0040;
+const PalmLib::pi_uint16_t PalmLib::Database::FLAG_HDR_STREAM = 0x0080;
+const PalmLib::pi_uint16_t PalmLib::Database::FLAG_HDR_HIDDEN = 0x0100;
+const PalmLib::pi_uint16_t PalmLib::Database::FLAG_HDR_LAUNCHABLE_DATA = 0x0200;
+const PalmLib::pi_uint16_t PalmLib::Database::FLAG_HDR_OPEN = 0x8000;
+const PalmLib::pi_char_t PalmLib::Record::FLAG_ATTR_DELETED = 0x80;
+const PalmLib::pi_char_t PalmLib::Record::FLAG_ATTR_DIRTY = 0x40;
+const PalmLib::pi_char_t PalmLib::Record::FLAG_ATTR_BUSY = 0x20;
+const PalmLib::pi_char_t PalmLib::Record::FLAG_ATTR_SECRET = 0x10;
+
+#endif
+
+PalmLib::Database::Database(bool resourceDB)
+ : m_name(""), m_version(0), m_time_created(0), m_time_modified(0),
+ m_time_backup(0), m_modification(0), m_unique_id_seed(0)
+{
+ m_flags = resourceDB ? FLAG_HDR_RESOURCE : 0;
+ m_type = PalmLib::mktag(' ', ' ', ' ', ' ');
+ m_creator = PalmLib::mktag(' ', ' ', ' ', ' ');
+}
diff --git a/src/translators/pilotdb/libpalm/Database.h b/src/translators/pilotdb/libpalm/Database.h
new file mode 100644
index 0000000..bcde8c0
--- /dev/null
+++ b/src/translators/pilotdb/libpalm/Database.h
@@ -0,0 +1,181 @@
+/*
+ * palm-db-tools: General interface to a PalmOS database.
+ * Copyright (C) 2000 by Tom Dyas (tdyas@users.sourceforge.net)
+ *
+ * This header defines an abstract interface to PalmOS
+ * databases. Subclasses would include the class that reads/writes PDB
+ * files and possibly databases that can be accessed over the HotSync
+ * protocols.
+ */
+
+#ifndef __PALMLIB_DATABASE_H__
+#define __PALMLIB_DATABASE_H__
+
+#include <string>
+
+#include "palmtypes.h"
+#include "Block.h"
+#include "Record.h"
+#include "Resource.h"
+
+namespace PalmLib {
+
+ class Database {
+ public:
+ // Constants for bits in the flags field of a PalmOS database.
+#ifdef __GNUG__
+ static const pi_uint16_t FLAG_HDR_RESOURCE = 0x0001;
+ static const pi_uint16_t FLAG_HDR_READ_ONLY = 0x0002;
+ static const pi_uint16_t FLAG_HDR_APPINFO_DIRTY = 0x0004;
+ static const pi_uint16_t FLAG_HDR_BACKUP = 0x0008;
+ static const pi_uint16_t FLAG_HDR_OK_TO_INSTALL_NEWER = 0x0010;
+ static const pi_uint16_t FLAG_HDR_RESET_AFTER_INSTALL = 0x0020;
+ static const pi_uint16_t FLAG_HDR_COPY_PREVENTION = 0x0040;
+ static const pi_uint16_t FLAG_HDR_STREAM = 0x0080;
+ static const pi_uint16_t FLAG_HDR_HIDDEN = 0x0100;
+ static const pi_uint16_t FLAG_HDR_LAUNCHABLE_DATA = 0x0200;
+ static const pi_uint16_t FLAG_HDR_OPEN = 0x8000;
+#else
+ static const pi_uint16_t FLAG_HDR_RESOURCE;
+ static const pi_uint16_t FLAG_HDR_READ_ONLY;
+ static const pi_uint16_t FLAG_HDR_APPINFO_DIRTY;
+ static const pi_uint16_t FLAG_HDR_BACKUP;
+ static const pi_uint16_t FLAG_HDR_OK_TO_INSTALL_NEWER;
+ static const pi_uint16_t FLAG_HDR_RESET_AFTER_INSTALL;
+ static const pi_uint16_t FLAG_HDR_COPY_PREVENTION;
+ static const pi_uint16_t FLAG_HDR_STREAM;
+ static const pi_uint16_t FLAG_HDR_HIDDEN;
+ static const pi_uint16_t FLAG_HDR_LAUNCHABLE_DATA;
+ static const pi_uint16_t FLAG_HDR_OPEN;
+#endif
+
+ Database(bool resourceDB = false);
+ virtual ~Database() { }
+
+ bool isResourceDB() const {return (m_flags & FLAG_HDR_RESOURCE) != 0;}
+
+ virtual pi_uint32_t type() const { return m_type; }
+ virtual void type(pi_uint32_t new_type) { m_type = new_type; }
+
+ virtual pi_uint32_t creator() const { return m_creator; }
+ virtual void creator(pi_uint32_t new_creator)
+ { m_creator = new_creator; }
+
+ virtual pi_uint16_t version() const { return m_version; }
+ virtual void version(pi_uint16_t v) { m_version = v; }
+
+ virtual pi_int32_t creation_time() const { return m_time_created; }
+ virtual void creation_time(pi_int32_t ct) { m_time_created = ct; }
+
+ virtual pi_uint32_t modification_time() const
+ { return m_time_modified; }
+ virtual void modification_time(pi_uint32_t mt)
+ { m_time_modified = mt; }
+
+ virtual pi_uint32_t backup_time() const { return m_time_backup; }
+ virtual void backup_time(pi_uint32_t bt) { m_time_backup = bt; }
+
+ virtual pi_uint32_t modnum() const { return m_modification; }
+ virtual void modnum(pi_uint32_t new_modnum)
+ { m_modification = new_modnum; }
+
+ virtual pi_uint32_t unique_id_seed() const
+ { return m_unique_id_seed; }
+ virtual void unique_id_seed(pi_uint32_t uid_seed)
+ { m_unique_id_seed = uid_seed; }
+
+ virtual pi_uint16_t flags() const { return m_flags; }
+ virtual void flags(pi_uint16_t flags)
+ { m_flags = flags & ~(FLAG_HDR_RESOURCE | FLAG_HDR_OPEN); }
+
+ virtual std::string name() const { return m_name; }
+ virtual void name(const std::string& new_name) { m_name = new_name; }
+
+ virtual bool backup() const
+ { return (m_flags & FLAG_HDR_BACKUP) != 0; }
+ virtual void backup(bool state) {
+ if (state)
+ m_flags |= FLAG_HDR_BACKUP;
+ else
+ m_flags &= ~(FLAG_HDR_BACKUP);
+ }
+
+ virtual bool readonly() const
+ { return (m_flags & FLAG_HDR_READ_ONLY) != 0; }
+ virtual void readonly(bool state) {
+ if (state)
+ m_flags |= FLAG_HDR_READ_ONLY;
+ else
+ m_flags &= ~(FLAG_HDR_READ_ONLY);
+ }
+
+ virtual bool copy_prevention() const
+ { return (m_flags & FLAG_HDR_COPY_PREVENTION) != 0; }
+ virtual void copy_prevention(bool state) {
+ if (state)
+ m_flags |= FLAG_HDR_COPY_PREVENTION;
+ else
+ m_flags &= ~(FLAG_HDR_COPY_PREVENTION);
+ }
+
+ // Return the total number of records/resources in this
+ // database.
+ virtual unsigned getNumRecords() const = 0;
+
+ // Return the database's application info block as a Block
+ // object.
+ virtual Block getAppInfoBlock() const { return Block(); }
+
+ // Set the database's app info block to the contents of the
+ // passed Block object.
+ virtual void setAppInfoBlock(const Block &) { }
+
+ // Return the database's sort info block as a Block object.
+ virtual Block getSortInfoBlock() const { return Block(); }
+
+ // Set the database's sort info block to the contents of the
+ // passed Block object.
+ virtual void setSortInfoBlock(const Block &) { }
+
+ // Return the record identified by the given index. The caller
+ // owns the returned RawRecord object.
+ virtual Record getRecord(unsigned index) const = 0;
+
+ // Set the record identified by the given index to the given
+ // record.
+ virtual void setRecord(unsigned index, const Record& rec) = 0;
+
+ // Append the given record to the database.
+ virtual void appendRecord(const Record& rec) = 0;
+
+ // returned if the specified (type, ID) combination is not
+ // present in the database. The caller owns the returned
+ // RawRecord object.
+ virtual Resource getResourceByType(pi_uint32_t type,
+ pi_uint32_t id) const = 0;
+
+ // Return the resource present at the given index. NULL is
+ // returned if the index is invalid. The caller owns the
+ // returned RawRecord object.
+ virtual Resource getResourceByIndex(unsigned index) const = 0;
+
+ // Set the resouce at given index to passed Resource object.
+ virtual void setResource(unsigned index, const Resource& rsrc) = 0;
+
+ private:
+ std::string m_name;
+ pi_uint16_t m_flags;
+ pi_uint16_t m_version;
+ pi_uint32_t m_time_created;
+ pi_uint32_t m_time_modified;
+ pi_uint32_t m_time_backup;
+ pi_uint32_t m_modification;
+ pi_uint32_t m_type;
+ pi_uint32_t m_creator;
+ pi_uint32_t m_unique_id_seed;
+
+ };
+
+} // namespace PalmLib
+
+#endif
diff --git a/src/translators/pilotdb/libpalm/Makefile.am b/src/translators/pilotdb/libpalm/Makefile.am
new file mode 100644
index 0000000..ea92331
--- /dev/null
+++ b/src/translators/pilotdb/libpalm/Makefile.am
@@ -0,0 +1,15 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+noinst_LIBRARIES = liblibpalm.a
+
+AM_CPPFLAGS = $(all_includes)
+
+liblibpalm_a_METASOURCES = AUTO
+
+liblibpalm_a_SOURCES = Database.cpp Block.cpp
+
+
+EXTRA_DIST = Block.cpp Block.h palmtypes.h Record.h Resource.h Database.h Database.cpp
+
+####### kdevelop will overwrite this part!!! (end)############
+
+KDE_OPTIONS = noautodist
diff --git a/src/translators/pilotdb/libpalm/Record.h b/src/translators/pilotdb/libpalm/Record.h
new file mode 100644
index 0000000..ecf19e3
--- /dev/null
+++ b/src/translators/pilotdb/libpalm/Record.h
@@ -0,0 +1,168 @@
+/*
+ * palm-db-tools: Raw PalmOS Records
+ * Copyright (C) 2000 by Tom Dyas (tdyas@users.sourceforge.net)
+ */
+
+#ifndef __PALMLIB_RECORD_H__
+#define __PALMLIB_RECORD_H__
+
+#include "Block.h"
+
+namespace PalmLib {
+
+ class Record : public Block {
+ public:
+#ifdef __GNUG__
+ static const pi_char_t FLAG_ATTR_DELETED = 0x80;
+ static const pi_char_t FLAG_ATTR_DIRTY = 0x40;
+ static const pi_char_t FLAG_ATTR_BUSY = 0x20;
+ static const pi_char_t FLAG_ATTR_SECRET = 0x10;
+#else
+ static const pi_char_t FLAG_ATTR_DELETED;
+ static const pi_char_t FLAG_ATTR_DIRTY;
+ static const pi_char_t FLAG_ATTR_BUSY;
+ static const pi_char_t FLAG_ATTR_SECRET;
+#endif
+
+ /**
+ * Default constructor.
+ */
+ Record() : Block(), m_attrs(0), m_unique_id(0) { }
+
+ /**
+ * Copy constructor.
+ */
+ Record(const Record& rhs) : Block(rhs.data(), rhs.size()) {
+ m_attrs = rhs.attrs();
+ m_unique_id = rhs.unique_id();
+ }
+
+ /**
+ * Destructor.
+ */
+ virtual ~Record() { }
+
+ /**
+ * Constructor which lets the caller specify all the
+ * parameters.
+ *
+ * @param attrs Attribute byte (flags + category).
+ * @param unique_id Unique ID for this record.
+ * @param data Start of buffer to copy (or 0 for empty).
+ * @param size Size of the buffer to copy.
+ */
+ Record(pi_char_t attrs, pi_uint32_t unique_id,
+ Block::const_pointer data, const Block::size_type size)
+ : Block(data, size), m_attrs(attrs), m_unique_id(unique_id) { }
+
+ /**
+ * Constructor which lets the caller use the default fill
+ * constructor.
+ * @param attrs Attribute byte (flags + category).
+ * @param unique_id Unique ID for this record.
+ * @param size Size of buffer to generate.
+ * @param value Value to fill buffer with.
+ */
+ Record(pi_char_t attrs, pi_uint32_t unique_id,
+ const size_type size, const value_type value = 0)
+ : Block(size, value), m_attrs(attrs), m_unique_id(unique_id) { }
+
+ /**
+ * Assignment operator.
+ *
+ * @param rhs The PalmLib::Record we should become. */
+ Record& operator = (const Record& rhs) {
+ Block::operator = (rhs);
+ m_attrs = rhs.attrs();
+ m_unique_id = rhs.unique_id();
+ return *this;
+ }
+
+ /**
+ * Return the attributes byte which contains the category and
+ * flags.
+ */
+ pi_char_t attrs() const { return m_attrs; }
+
+ /**
+ * Return the state of the record's "deleted" flag.
+ */
+ bool deleted() const { return (m_attrs & FLAG_ATTR_DELETED) != 0; }
+
+ /**
+ * Set the state of the record's "deleted" flag.
+ *
+ * @param state New state of the "deleted" flag.
+ */
+ void deleted(bool state) {
+ if (state)
+ m_attrs |= FLAG_ATTR_DELETED;
+ else
+ m_attrs &= ~(FLAG_ATTR_DELETED);
+ }
+
+ /**
+ * Return the state of the record's "dirty" flag.
+ */
+ bool dirty() const { return (m_attrs & FLAG_ATTR_DIRTY) != 0; }
+
+ /**
+ * Set the state of the record's "dirty" flag.
+ *
+ * @param state New state of the "dirty" flag.
+ */
+ void dirty(bool state) {
+ if (state)
+ m_attrs |= FLAG_ATTR_DIRTY;
+ else
+ m_attrs &= ~(FLAG_ATTR_DIRTY);
+ }
+
+ /**
+ * Return the state of the record's "secret" flag.
+ */
+ bool secret() const { return (m_attrs & FLAG_ATTR_SECRET) != 0; }
+
+ /**
+ * Set the state of the record's "secret" flag.
+ *
+ * @param state New state of the "secret" flag.
+ */
+ void secret(bool state) {
+ if (state)
+ m_attrs |= FLAG_ATTR_SECRET;
+ else
+ m_attrs &= ~(FLAG_ATTR_SECRET);
+ }
+
+ /**
+ * Return the category of this record.
+ */
+ pi_char_t category() const { return (m_attrs & 0x0F); }
+
+ /**
+ * Set the category of this record.
+ */
+ void category(pi_char_t cat)
+ { m_attrs &= ~(0x0F); m_attrs |= (cat & 0x0F); }
+
+ /**
+ * Return the unique ID of this record.
+ */
+ pi_uint32_t unique_id() const { return m_unique_id; }
+
+ /**
+ * Set the unique ID of this record to uid.
+ *
+ * @param uid New unique ID for this record.
+ */
+ void unique_id(pi_uint32_t uid) { m_unique_id = uid; }
+
+ private:
+ pi_char_t m_attrs;
+ pi_uint32_t m_unique_id;
+ };
+
+}
+
+#endif
diff --git a/src/translators/pilotdb/libpalm/Resource.h b/src/translators/pilotdb/libpalm/Resource.h
new file mode 100644
index 0000000..b98f718
--- /dev/null
+++ b/src/translators/pilotdb/libpalm/Resource.h
@@ -0,0 +1,85 @@
+/*
+ * palm-db-tools: PalmOS Resources
+ * Copyright (C) 2000 by Tom Dyas (tdyas@users.sourceforge.net)
+ */
+
+#ifndef __PALMLIB_RESOURCE_H__
+#define __PALMLIB_RESOURCE_H__
+
+#include "Block.h"
+#include "palmtypes.h"
+
+namespace PalmLib {
+
+ class Resource : public Block {
+ public:
+ /**
+ * Default constructor.
+ */
+ Resource() : Block(), m_type(0), m_id(0) { }
+
+ /**
+ * Copy constructor.
+ */
+ Resource(const Resource& rhs) : Block(rhs.data(), rhs.size()) {
+ m_type = rhs.type();
+ m_id = rhs.id();
+ }
+
+ /**
+ * Destructor.
+ */
+ virtual ~Resource() { }
+
+ /**
+ * Constructor which lets the caller specify all the
+ * parameters.
+ *
+ * @param type Resource type
+ * @param id Resource ID
+ * @param data Start of buffer to copy.
+ * @param size Size of the buffer to copy.
+ */
+ Resource(pi_uint32_t type, pi_uint32_t id,
+ const_pointer data, const size_type size)
+ : Block(data, size), m_type(type), m_id(id) { }
+
+ /**
+ * Constructor which lets the caller use the default fill
+ * constructor.
+ *
+ * @param type Resource type
+ * @param id Resource ID
+ * @param size Size of buffer to generate.
+ * @param value Value to fill buffer with.
+ */
+ Resource(pi_uint32_t type, pi_uint32_t id,
+ const size_type size, const value_type value = 0)
+ : Block(size, value), m_type(type), m_id(id) { }
+
+ /**
+ * Assignment operator.
+ */
+ Resource& operator = (const Resource& rhs) {
+ Block::operator = (rhs);
+ m_type = rhs.type();
+ m_id = rhs.id();
+ return *this;
+ }
+
+ // Accessor functions for the resource type.
+ pi_uint32_t type() const { return m_type; }
+ void type(const pi_uint32_t _type) { m_type = _type; }
+
+ // Accessor functions for the resource ID.
+ pi_uint32_t id() const { return m_id; }
+ void id(const pi_uint32_t _id) { m_id = _id; }
+
+ private:
+ pi_uint32_t m_type;
+ pi_uint32_t m_id;
+ };
+
+}
+
+#endif
diff --git a/src/translators/pilotdb/libpalm/palmtypes.h b/src/translators/pilotdb/libpalm/palmtypes.h
new file mode 100644
index 0000000..5c12262
--- /dev/null
+++ b/src/translators/pilotdb/libpalm/palmtypes.h
@@ -0,0 +1,117 @@
+/*
+ * This file contains type definitions and helper functions to make
+ * access to data in Palm Pilot order easier.
+ */
+
+#ifndef __LIBPALM_PALMTYPES_H__
+#define __LIBPALM_PALMTYPES_H__
+
+#include <stdexcept>
+
+#include "../portability.h"
+
+namespace PalmLib {
+
+#if SIZEOF_UNSIGNED_CHAR == 1
+ typedef unsigned char pi_char_t;
+#else
+#error Unable to determine the size of pi_char_t.
+#endif
+
+#if SIZEOF_UNSIGNED_LONG == 2
+ typedef unsigned long pi_uint16_t;
+#elif SIZEOF_UNSIGNED_INT == 2
+ typedef unsigned int pi_uint16_t;
+#elif SIZEOF_UNSIGNED_SHORT == 2
+ typedef unsigned short pi_uint16_t;
+#else
+#error Unable to determine the size of pi_uint16_t.
+#endif
+
+#if SIZEOF_LONG == 2
+ typedef long pi_int16_t;
+#elif SIZEOF_INT == 2
+ typedef int pi_int16_t;
+#elif SIZEOF_SHORT == 2
+ typedef short pi_int16_t;
+#else
+#error Unable to determine the size of pi_int16_t.
+#endif
+
+#if SIZEOF_UNSIGNED_LONG == 4
+ typedef unsigned long pi_uint32_t;
+#elif SIZEOF_UNSIGNED_INT == 4
+ typedef unsigned int pi_uint32_t;
+#elif SIZEOF_UNSIGNED_SHORT == 4
+ typedef unsigned short pi_uint32_t;
+#else
+#error Unable to determine the size of pi_uint32_t.
+#endif
+
+#if SIZEOF_LONG == 4
+ typedef long pi_int32_t;
+#elif SIZEOF_INT == 4
+ typedef int pi_int32_t;
+#elif SIZEOF_SHORT == 4
+ typedef short pi_int32_t;
+#else
+#error Unable to determine the size of pi_int32_t.
+#endif
+
+typedef union {
+ double number;
+#ifdef WORDS_BIGENDIAN
+ struct {
+ PalmLib::pi_uint32_t hi;
+ PalmLib::pi_uint32_t lo;
+ } words;
+#else
+ struct {
+ PalmLib::pi_uint32_t lo;
+ PalmLib::pi_uint32_t hi;
+ } words;
+#endif
+} pi_double_t;
+
+ inline pi_int32_t get_long(const pi_char_t* p) {
+ return ( (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3] );
+ }
+
+ inline pi_int32_t get_treble(const pi_char_t* p) {
+ return ( (p[0] << 16) || (p[1] << 8) || p[0]);
+ }
+
+ inline pi_int16_t get_short(const pi_char_t* p) {
+ return ( (p[0] << 8) | p[1] );
+ }
+
+ inline void set_long(pi_char_t *p, pi_int32_t v) {
+ p[0] = (v >> 24) & 0xFF;
+ p[1] = (v >> 16) & 0xFF;
+ p[2] = (v >> 8 ) & 0xFF;
+ p[3] = (v ) & 0xFF;
+ }
+
+ inline void set_treble(pi_char_t *p, pi_int32_t v) {
+ p[0] = (v >> 16) & 0xFF;
+ p[1] = (v >> 8 ) & 0xFF;
+ p[2] = (v ) & 0xFF;
+ }
+
+ inline void set_short(pi_char_t *p, pi_int16_t v) {
+ p[0] = (v >> 8) & 0xFF;
+ p[1] = (v ) & 0xFF;
+ }
+
+ inline pi_uint32_t mktag(pi_char_t c1, pi_char_t c2,
+ pi_char_t c3, pi_char_t c4)
+ { return (((c1)<<24)|((c2)<<16)|((c3)<<8)|(c4)); }
+
+ class error : public std::runtime_error {
+ public:
+ error(const std::string & what_arg) : std::runtime_error(what_arg) { }
+ };
+
+} // namespace PalmLib
+
+#endif
diff --git a/src/translators/pilotdb/pilotdb.cpp b/src/translators/pilotdb/pilotdb.cpp
new file mode 100644
index 0000000..d7779e4
--- /dev/null
+++ b/src/translators/pilotdb/pilotdb.cpp
@@ -0,0 +1,277 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "pilotdb.h"
+#include "strop.h"
+#include "libflatfile/Record.h"
+
+#include <kdebug.h>
+
+#include <qbuffer.h>
+
+using namespace PalmLib;
+using Tellico::Export::PilotDB;
+
+namespace {
+ static const int PI_HDR_SIZE = 78;
+ static const int PI_RESOURCE_ENT_SIZE = 10;
+ static const int PI_RECORD_ENT_SIZE = 8;
+}
+
+PilotDB::PilotDB() : Database(false), m_app_info(), m_sort_info(),
+ m_next_record_list_id(0) {
+ pi_int32_t now = StrOps::get_current_time();
+ creation_time(now);
+ modification_time(now);
+ backup_time(now);
+}
+
+PilotDB::~PilotDB() {
+ for(record_list_t::iterator i = m_records.begin(); i != m_records.end(); ++i) {
+ delete (*i);
+ }
+}
+
+QByteArray PilotDB::data() {
+ QBuffer b;
+ b.open(IO_WriteOnly);
+
+ pi_char_t buf[PI_HDR_SIZE];
+ pi_int16_t ent_hdr_size = isResourceDB() ? PI_RESOURCE_ENT_SIZE : PI_RECORD_ENT_SIZE;
+ std::streampos offset = PI_HDR_SIZE + m_records.size() * ent_hdr_size + 2;
+
+ for(int i=0; i<32; ++i) {
+ buf[i] = 0;
+ }
+ memcpy(buf, name().c_str(), QMIN(31, name().length()));
+ set_short(buf + 32, flags());
+ set_short(buf + 34, version());
+ set_long(buf + 36, creation_time());
+ set_long(buf + 40, modification_time());
+ set_long(buf + 44, backup_time());
+ set_long(buf + 48, modnum());
+ if(m_app_info.raw_size() > 0) {
+ set_long(buf + 52, offset);
+ offset += m_app_info.raw_size();
+ } else {
+ set_long(buf + 52, 0);
+ }
+ if(m_sort_info.raw_size() > 0) {
+ set_long(buf + 56, offset);
+ offset += m_sort_info.raw_size();
+ } else {
+ set_long(buf + 56, 0);
+ }
+ set_long(buf + 60, type());
+ set_long(buf + 64, creator());
+ set_long(buf + 68, unique_id_seed());
+ set_long(buf + 72, m_next_record_list_id);
+ set_short(buf + 76, m_records.size());
+
+ // Write the PDB/PRC header to the string.
+ b.writeBlock(reinterpret_cast<char *>(buf), sizeof(buf));
+
+ for(record_list_t::iterator i = m_records.begin(); i != m_records.end(); ++i) {
+ Block* entry = *i;
+
+ if(isResourceDB()) {
+ Resource * resource = reinterpret_cast<Resource *> (entry);
+ set_long(buf, resource->type());
+ set_short(buf + 4, resource->id());
+ set_long(buf + 6, offset);
+ } else {
+ Record * record = reinterpret_cast<Record *> (entry);
+ set_long(buf, offset);
+ buf[4] = record->attrs();
+ set_treble(buf + 5, record->unique_id());
+ }
+ b.writeBlock(reinterpret_cast<char *>(buf), ent_hdr_size);
+ offset += entry->raw_size();
+ }
+
+ b.writeBlock("\0", 1);
+ b.writeBlock("\0", 1);
+
+ if(m_app_info.raw_size() > 0) {
+ b.writeBlock((char *) m_app_info.raw_data(), m_app_info.raw_size());
+ }
+
+ if(m_sort_info.raw_size() > 0) {
+ b.writeBlock((char *) m_sort_info.raw_data(), m_sort_info.raw_size());
+ }
+
+ for(record_list_t::iterator q = m_records.begin(); q != m_records.end(); ++q) {
+ Block* entry = *q;
+ b.writeBlock((char *) entry->raw_data(), entry->raw_size());
+ }
+
+ b.close();
+ return b.buffer();
+}
+
+// Return the record identified by the given index. The caller owns
+// the returned RawRecord object.
+Record PilotDB::getRecord(unsigned index) const
+{
+ if (index >= m_records.size()) kdDebug() << "invalid index" << endl;
+ return *(reinterpret_cast<Record *> (m_records[index]));
+}
+
+// Set the record identified by the given index to the given record.
+void PilotDB::setRecord(unsigned index, const Record& rec)
+{
+// if (index >= m_records.size()) kdDebug() << "invalid index");
+ *(reinterpret_cast<Record *> (m_records[index])) = rec;
+}
+
+// Append the given record to the database.
+void PilotDB::appendRecord(const Record& rec)
+{
+ Record* record = new Record(rec);
+
+ // If this new record has a unique ID that duplicates any other
+ // record, then reset the unique ID to an unused value.
+ if (m_uid_map.find(record->unique_id()) != m_uid_map.end()) {
+ uid_map_t::iterator iter = max_element(m_uid_map.begin(),
+ m_uid_map.end());
+ pi_uint32_t maxuid = (*iter).first;
+
+ // The new unique ID becomes the max plus one.
+ record->unique_id(maxuid + 1);
+ }
+
+ m_uid_map[record->unique_id()] = record;
+ m_records.push_back(record);
+}
+
+
+void PilotDB::clearRecords()
+{
+ m_records.erase(m_records.begin(), m_records.end());
+}
+
+// Return the resource with the given type and ID. NULL is returned if
+// the specified (type, ID) combination is not present in the
+// database. The caller owns the returned RawRecord object.
+Resource PilotDB::getResourceByType(pi_uint32_t type, pi_uint32_t id) const
+{
+ for (record_list_t::const_iterator i = m_records.begin();
+ i != m_records.end(); ++i) {
+ Resource* resource = reinterpret_cast<Resource *> (*i);
+ if (resource->type() == type && resource->id() == id)
+ return *resource;
+ }
+
+ kdWarning() << "PilotDB::getResourceByType() - not found!" << endl;
+ return Resource();
+}
+
+// Return the resource present at the given index. NULL is returned if
+// the index is invalid. The caller owns the returned RawRecord
+// object.
+Resource PilotDB::getResourceByIndex(unsigned index) const
+{
+ if (index >= m_records.size()) kdDebug() << "invalid index" << endl;
+ return *(reinterpret_cast<Resource *> (m_records[index]));
+}
+
+// Set the resouce at given index to passed RawResource object.
+void PilotDB::setResource(unsigned index, const Resource& resource)
+{
+ if (index >= m_records.size()) kdDebug() << "invalid index" << endl;
+ *(reinterpret_cast<Resource *> (m_records[index])) = resource;
+}
+
+FlatFile::Field PilotDB::string2field(FlatFile::Field::FieldType type, const std::string& fldstr) {
+ FlatFile::Field field;
+
+ switch (type) {
+ case FlatFile::Field::STRING:
+ field.type = FlatFile::Field::STRING;
+ field.v_string = fldstr;
+ break;
+
+ case FlatFile::Field::BOOLEAN:
+ field.type = FlatFile::Field::BOOLEAN;
+ field.v_boolean = StrOps::string2boolean(fldstr);
+ break;
+
+ case FlatFile::Field::INTEGER:
+ field.type = FlatFile::Field::INTEGER;
+ StrOps::convert_string(fldstr, field.v_integer);
+ break;
+
+ case FlatFile::Field::FLOAT:
+ field.type = FlatFile::Field::FLOAT;
+ StrOps::convert_string(fldstr, field.v_float);
+ break;
+
+ case FlatFile::Field::NOTE:
+ field.type = FlatFile::Field::NOTE;
+ field.v_string = fldstr.substr(0,NOTETITLE_LENGTH - 1);
+ field.v_note = fldstr;
+ break;
+
+ case FlatFile::Field::LIST:
+ field.type = FlatFile::Field::LIST;
+ field.v_string = fldstr;
+ break;
+
+ case FlatFile::Field::LINK:
+ field.type = FlatFile::Field::LINK;
+ field.v_integer = 0;
+ field.v_string = fldstr;
+ break;
+
+ case FlatFile::Field::LINKED:
+ field.type = FlatFile::Field::LINKED;
+ field.v_string = fldstr;
+ break;
+
+ case FlatFile::Field::CALCULATED:
+ field.type = FlatFile::Field::CALCULATED;
+ field.v_string = fldstr;
+ break;
+
+ case FlatFile::Field::DATE:
+ field.type = FlatFile::Field::DATE;
+ struct tm time;
+ if (!fldstr.empty()) {
+#ifdef strptime
+ if(!strptime(fldstr.c_str(), "%Y/%m/%d", &time)) {
+#else
+ if(!StrOps::strptime(fldstr.c_str(), "%Y/%m/%d", &time)) {
+#endif
+ kdDebug() << "invalid date in field" << endl;
+ }
+ field.v_date.month = time.tm_mon + 1;
+ field.v_date.day = time.tm_mday;
+ field.v_date.year = time.tm_year + 1900;
+ field.v_time.hour = time.tm_hour;
+ field.v_time.minute = time.tm_min;
+ } else {
+ field.v_date.month = 0;
+ field.v_date.day = 0;
+ field.v_date.year = 0;
+ field.v_time.hour = 24;
+ field.v_time.minute = 0;
+ }
+ break;
+
+ default:
+ kdWarning() << "PilotDB::string2field() - unsupported field type" << endl;
+ break;
+ }
+
+ return field;
+}
diff --git a/src/translators/pilotdb/pilotdb.h b/src/translators/pilotdb/pilotdb.h
new file mode 100644
index 0000000..dd21c7b
--- /dev/null
+++ b/src/translators/pilotdb/pilotdb.h
@@ -0,0 +1,127 @@
+/***************************************************************************
+ pilotdb.h
+ -------------------
+ begin : Thu Nov 20 2003
+ copyright : (C) 2003 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef PILOTDB_H
+#define PILOTDB_H
+
+#include <map>
+#include <vector>
+
+#include "libpalm/Database.h"
+#include "libflatfile/Field.h"
+
+#include <qcstring.h>
+
+namespace Tellico {
+ namespace Export {
+
+/**
+ * @author Robby Stephenson
+ */
+class PilotDB : public PalmLib::Database {
+public:
+ PilotDB();
+ ~PilotDB();
+
+ QByteArray data();
+
+ /**
+ * Return the total number of records/resources in this database.
+ */
+ virtual unsigned getNumRecords() const { return m_records.size(); }
+
+ /**
+ * Return the database's application info block as a Block
+ * object. The caller owns the returned object.
+ */
+ virtual PalmLib::Block getAppInfoBlock() const { return m_app_info; }
+
+ /**
+ * Set the database's app info block to the contents of the
+ * passed Block object.
+ */
+ virtual void setAppInfoBlock(const PalmLib::Block& new_app_info) { m_app_info = new_app_info; }
+
+ /**
+ * Return the database's sort info block as a Block
+ * object. The caller owns the returned object.
+ */
+ virtual PalmLib::Block getSortInfoBlock() const { return m_sort_info; }
+
+ /**
+ * Set the database's sort info block to the contents of the
+ * passed Block object.
+ */
+ virtual void setSortInfoBlock(const PalmLib::Block& new_sort_info) { m_sort_info = new_sort_info; }
+
+ /**
+ * Return the record identified by the given index. The caller
+ * owns the returned RawRecord object.
+ */
+ virtual PalmLib::Record getRecord(unsigned index) const;
+
+ /**
+ * Set the record identified by the given index to the given record.
+ */
+ virtual void setRecord(unsigned index, const PalmLib::Record& rec);
+
+ /**
+ * Append the given record to the database.
+ */
+ virtual void appendRecord(const PalmLib::Record& rec);
+
+ /**
+ * Delete all records
+ */
+ virtual void clearRecords();
+
+ /**
+ * returned if the specified (type, ID) combination is not
+ * present in the database. The caller owns the returned RawRecord object.
+ */
+ virtual PalmLib::Resource getResourceByType(PalmLib::pi_uint32_t type, PalmLib::pi_uint32_t id) const;
+
+ /**
+ * Return the resource present at the given index. NULL is
+ * returned if the index is invalid. The caller owns the
+ * returned RawRecord object.
+ */
+ virtual PalmLib::Resource getResourceByIndex(unsigned index) const;
+
+ /**
+ * Set the resource at given index to passed Resource object.
+ */
+ virtual void setResource(unsigned index, const PalmLib::Resource& rsrc);
+
+ static PalmLib::FlatFile::Field string2field(PalmLib::FlatFile::Field::FieldType type,
+ const std::string& fldstr);
+
+protected:
+ typedef std::vector<PalmLib::Block *> record_list_t;
+ typedef std::map<PalmLib::pi_uint32_t, PalmLib::Record *> uid_map_t;
+
+ record_list_t m_records;
+ uid_map_t m_uid_map;
+
+private:
+ PalmLib::Block m_app_info;
+ PalmLib::Block m_sort_info;
+ PalmLib::pi_int32_t m_next_record_list_id;
+};
+
+ } //end namespace
+} // end namespace
+#endif
diff --git a/src/translators/pilotdb/portability.h b/src/translators/pilotdb/portability.h
new file mode 100644
index 0000000..cb41f79
--- /dev/null
+++ b/src/translators/pilotdb/portability.h
@@ -0,0 +1,72 @@
+/*
+ * palm-db-tools: Support Library: String Parsing Utility Functions
+ * Copyright (C) 1999-2000 by Tom Dyas (tdyas@users.sourceforge.net)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifh Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __LIBSUPPORT_PORTABILITY_H__
+#define __LIBSUPPORT_PORTABILITY_H__
+
+/*
+ * Pull in the correct configuration header.
+ */
+
+#ifndef WIN32
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#else
+#include "win32/win32-config.h"
+#endif
+
+#ifdef _MSC_VER
+/* Borrowed from GLib: Make MSVC more pedantic, this is a recommended
+ * pragma list from _Win32_Programming_ by Rector and Newcomer.
+ */
+#pragma warning(error:4002)
+#pragma warning(error:4003)
+#pragma warning(1:4010)
+#pragma warning(error:4013)
+#pragma warning(1:4016)
+#pragma warning(error:4020)
+#pragma warning(error:4021)
+#pragma warning(error:4027)
+#pragma warning(error:4029)
+#pragma warning(error:4033)
+#pragma warning(error:4035)
+#pragma warning(error:4045)
+#pragma warning(error:4047)
+#pragma warning(error:4049)
+#pragma warning(error:4053)
+#pragma warning(error:4071)
+#pragma warning(disable:4101)
+#pragma warning(error:4150)
+
+#pragma warning(disable:4244) /* No possible loss of data warnings */
+#pragma warning(disable:4305) /* No truncation from int to char warnings */
+#endif /* _MSC_VER */
+
+/* MSVC is screwed up when it comes to calling base class virtual
+ * functions from a subclass. Thus, the following macro which makes
+ * calling the superclass nice and simple.
+ */
+#ifndef _MSC_VER
+#define SUPERCLASS(namespace, class, function, args) namespace::class::function args
+#else
+#define SUPERCLASS(namespace, class, function, args) this-> class::function args
+#endif
+
+#endif
diff --git a/src/translators/pilotdb/strop.cpp b/src/translators/pilotdb/strop.cpp
new file mode 100644
index 0000000..b8c7f55
--- /dev/null
+++ b/src/translators/pilotdb/strop.cpp
@@ -0,0 +1,589 @@
+/*
+ * palm-db-tools: Support Library: String Parsing Utility Functions
+ * Copyright (C) 1999-2000 by Tom Dyas (tdyas@users.sourceforge.net)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifh Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <cctype>
+#include <sstream>
+
+#include "strop.h"
+#include <kdebug.h>
+
+extern std::ostream* err;
+
+void StrOps::lower(std::string& str)
+{
+ for (std::string::iterator p = str.begin(); p != str.end(); ++p) {
+ if (isupper(*p))
+ *p = tolower(*p);
+ }
+}
+
+bool StrOps::string2boolean(const std::string& str)
+{
+ std::string value(str);
+
+ StrOps::lower(value);
+
+ if (value == "on") return true;
+ else if (str == "off") return false;
+ else if (str == "true") return true;
+ else if (str == "t") return true;
+ else if (str == "false") return false;
+ else if (str == "f") return false;
+ else {
+ int num = 0;
+
+ std::istringstream(str.c_str()) >> num;
+ return num != 0 ? true : false;
+ }
+}
+
+std::string StrOps::type2string(PalmLib::FlatFile::Field::FieldType t)
+{
+ switch (t) {
+ case PalmLib::FlatFile::Field::STRING:
+ return "string";
+
+ case PalmLib::FlatFile::Field::BOOLEAN:
+ return "boolean";
+
+ case PalmLib::FlatFile::Field::INTEGER:
+ return "integer";
+
+ case PalmLib::FlatFile::Field::FLOAT:
+ return "float";
+
+ case PalmLib::FlatFile::Field::DATE:
+ return "date";
+
+ case PalmLib::FlatFile::Field::TIME:
+ return "time";
+
+ case PalmLib::FlatFile::Field::DATETIME:
+ return "datetime";
+
+ case PalmLib::FlatFile::Field::NOTE:
+ return "note";
+
+ case PalmLib::FlatFile::Field::LIST:
+ return "list";
+
+ case PalmLib::FlatFile::Field::LINK:
+ return "link";
+
+ case PalmLib::FlatFile::Field::CALCULATED:
+ return "calculated";
+
+ case PalmLib::FlatFile::Field::LINKED:
+ return "linked";
+
+ default:
+ // If we don't support the field type, then fake it as a string.
+ return "string";
+ }
+}
+
+PalmLib::FlatFile::Field::FieldType StrOps::string2type(std::string typestr)
+{
+ StrOps::lower(typestr);
+ if (typestr == "string")
+ return PalmLib::FlatFile::Field::STRING;
+ else if (typestr == "str")
+ return PalmLib::FlatFile::Field::STRING;
+ else if (typestr == "note")
+ return PalmLib::FlatFile::Field::NOTE;
+ else if (typestr == "bool")
+ return PalmLib::FlatFile::Field::BOOLEAN;
+ else if (typestr == "boolean")
+ return PalmLib::FlatFile::Field::BOOLEAN;
+ else if (typestr == "integer")
+ return PalmLib::FlatFile::Field::INTEGER;
+ else if (typestr == "int")
+ return PalmLib::FlatFile::Field::INTEGER;
+ else if (typestr == "float")
+ return PalmLib::FlatFile::Field::FLOAT;
+ else if (typestr == "date")
+ return PalmLib::FlatFile::Field::DATE;
+ else if (typestr == "time")
+ return PalmLib::FlatFile::Field::TIME;
+ else if (typestr == "datetime")
+ return PalmLib::FlatFile::Field::DATETIME;
+ else if (typestr == "list")
+ return PalmLib::FlatFile::Field::LIST;
+ else if (typestr == "link")
+ return PalmLib::FlatFile::Field::LINK;
+ else if (typestr == "linked")
+ return PalmLib::FlatFile::Field::LINKED;
+ else if (typestr == "calculated")
+ return PalmLib::FlatFile::Field::CALCULATED;
+ else
+ kdDebug() << "unknown field type" << endl;
+ return PalmLib::FlatFile::Field::STRING;
+}
+
+std::string StrOps::strip_back(const std::string& str, const std::string& what)
+{
+ std::string result(str);
+ std::string::reverse_iterator p = result.rbegin();
+
+ while (p != result.rend()
+ && (std::find(what.begin(), what.end(), *p) != what.end())) ++p;
+
+ result.erase(p.base(), result.end());
+
+ return result;
+}
+
+std::string StrOps::strip_front(const std::string& str,const std::string& what)
+{
+ std::string result(str);
+ std::string::iterator p = result.begin();
+
+ while (p != result.end()
+ && (std::find(what.begin(), what.end(), *p) != what.end())) ++p;
+
+ result.erase(result.begin(), p);
+
+ return result;
+}
+
+StrOps::string_list_t StrOps::csv_to_array(const std::string& str, char delim, bool quoted_string)
+{
+ enum { STATE_NORMAL, STATE_QUOTES } state;
+ StrOps::string_list_t result;
+ std::string elem;
+
+ state = STATE_NORMAL;
+ for (std::string::const_iterator p = str.begin(); p != str.end(); ++p) {
+ switch (state) {
+ case STATE_NORMAL:
+ if (quoted_string && *p == '"') {
+ state = STATE_QUOTES;
+ } else if (*p == delim) {
+ result.push_back(elem);
+ elem = "";
+ } else {
+ elem += *p;
+ }
+ break;
+
+ case STATE_QUOTES:
+ if (quoted_string && *p == '"') {
+ if ((p + 1) != str.end() && *(p+1) == '"') {
+ ++p;
+ elem += '"';
+ } else {
+ state = STATE_NORMAL;
+ }
+ } else {
+ elem += *p;
+ }
+ break;
+ }
+ }
+
+ switch (state) {
+ case STATE_NORMAL:
+ result.push_back(elem);
+ break;
+ case STATE_QUOTES:
+ kdDebug() << "unterminated quotes" << endl;
+ break;
+ }
+
+ return result;
+}
+
+StrOps::string_list_t
+StrOps::str_to_array(const std::string& str, const std::string& delim,
+ bool multiple_delim, bool handle_comments)
+{
+ enum { STATE_NORMAL, STATE_COMMENT, STATE_QUOTE_DOUBLE, STATE_QUOTE_SINGLE,
+ STATE_BACKSLASH, STATE_BACKSLASH_DOUBLEQUOTE } state;
+ StrOps::string_list_t result;
+ std::string elem;
+
+ state = STATE_NORMAL;
+ for (std::string::const_iterator p = str.begin(); p != str.end(); ++p) {
+ switch (state) {
+ case STATE_NORMAL:
+ if (*p == '"') {
+ state = STATE_QUOTE_DOUBLE;
+ } else if (*p == '\'') {
+ state = STATE_QUOTE_SINGLE;
+ } else if (std::find(delim.begin(), delim.end(), *p) != delim.end()) {
+ if (multiple_delim) {
+ ++p;
+ while (p != str.end()
+ && std::find(delim.begin(), delim.end(), *p) != delim.end()) {
+ ++p;
+ }
+ --p;
+ }
+ result.push_back(elem);
+ elem = "";
+ } else if (*p == '\\') {
+ state = STATE_BACKSLASH;
+ } else if (handle_comments && *p == '#') {
+ state = STATE_COMMENT;
+ } else {
+ elem += *p;
+ }
+ break;
+
+ case STATE_COMMENT:
+ break;
+
+ case STATE_QUOTE_DOUBLE:
+ if (*p == '"')
+ state = STATE_NORMAL;
+ else if (*p == '\\')
+ state = STATE_BACKSLASH_DOUBLEQUOTE;
+ else
+ elem += *p;
+ break;
+
+ case STATE_QUOTE_SINGLE:
+ if (*p == '\'')
+ state = STATE_NORMAL;
+ else
+ elem += *p;
+ break;
+
+ case STATE_BACKSLASH:
+ elem += *p;
+ state = STATE_NORMAL;
+ break;
+
+ case STATE_BACKSLASH_DOUBLEQUOTE:
+ switch (*p) {
+ case '\\':
+ elem += '\\';
+ break;
+
+ case 'n':
+ elem += '\n';
+ break;
+
+ case 'r':
+ elem += '\r';
+ break;
+
+ case 't':
+ elem += '\t';
+ break;
+
+ case 'v':
+ elem += '\v';
+ break;
+
+ case '"':
+ elem += '"';
+ break;
+
+ case 'x':
+ {
+ char buf[3];
+
+ // Extract and check the first hexadecimal character.
+ if ((p + 1) == str.end())
+ kdDebug() << "truncated escape" << endl;
+ if (! isxdigit(*(p + 1)))
+ kdDebug() << "invalid hex character" << endl;
+ buf[0] = *++p;
+
+ // Extract and check the second (if any) hex character.
+ if ((p + 1) != str.end() && isxdigit(*(p + 1))) {
+ buf[1] = *++p;
+ buf[2] = '\0';
+ } else {
+ buf[1] = buf[2] = '\0';
+ }
+
+ std::istringstream stream(buf);
+ stream.setf(std::ios::hex, std::ios::basefield);
+ unsigned value;
+ stream >> value;
+
+ elem += static_cast<char> (value & 0xFFu);
+ }
+ break;
+ }
+
+ // Escape is done. Go back to the normal double quote state.
+ state = STATE_QUOTE_DOUBLE;
+ break;
+ }
+ }
+
+ switch (state) {
+ case STATE_NORMAL:
+ result.push_back(elem);
+ break;
+
+ case STATE_QUOTE_DOUBLE:
+ kdDebug() << "unterminated double quotes" << endl;
+ break;
+
+ case STATE_QUOTE_SINGLE:
+ kdDebug() << "unterminated single quotes" << endl;
+ break;
+
+ case STATE_BACKSLASH:
+ case STATE_BACKSLASH_DOUBLEQUOTE:
+ kdDebug() << "an escape character must follow a backslash" << endl;
+ break;
+
+ default:
+ break;
+ }
+
+ return result;
+}
+
+PalmLib::pi_uint32_t
+StrOps::get_current_time(void)
+{
+ time_t now;
+
+ time(&now);
+ return static_cast<PalmLib::pi_uint32_t> (now) + PalmLib::pi_uint32_t(2082844800);
+}
+
+char *
+StrOps::strptime(const char *s, const char *format, struct tm *tm)
+{
+ char *data = (char *)s;
+ char option = false;
+
+ while (*format != 0) {
+ if (*data == 0)
+ return NULL;
+ switch (*format) {
+ case '%':
+ option = true;
+ format++;
+ break;
+ case 'd':
+ if (option) {
+ tm->tm_mday = strtol(data, &data, 10);
+ if (tm->tm_mday < 1 || tm->tm_mday > 31)
+ return NULL;
+ } else if (*data != 'd') {
+ return data;
+ }
+ option = false;
+ format++;
+ break;
+ case 'm':
+ if (option) {
+ /* tm_mon between 0 and 11 */
+ tm->tm_mon = strtol(data, &data, 10) - 1;
+ if (tm->tm_mon < 0 || tm->tm_mon > 11)
+ return NULL;
+ } else if (*data != 'm') {
+ return data;
+ }
+ option = false;
+ format++;
+ break;
+ case 'y':
+ if (option) {
+ tm->tm_year = strtol(data, &data, 10);
+ if (tm->tm_year < 60) tm->tm_year += 100;
+ } else if (*data != 'y') {
+ return data;
+ }
+ option = false;
+ format++;
+ break;
+ case 'Y':
+ if (option) {
+ tm->tm_year = strtol(data, &data, 10) - 1900;
+ } else if (*data != 'Y') {
+ return data;
+ }
+ option = false;
+ format++;
+ break;
+ case 'H':
+ if (option) {
+ tm->tm_hour = strtol(data, &data, 10);
+ if (tm->tm_hour < 0 || tm->tm_hour > 23)
+ return NULL;
+ } else if (*data != 'H') {
+ return data;
+ }
+ option = false;
+ format++;
+ break;
+ case 'M':
+ if (option) {
+ tm->tm_min = strtol(data, &data, 10);
+ if (tm->tm_min < 0 || tm->tm_min > 59)
+ return NULL;
+ } else if (*data != 'M') {
+ return data;
+ }
+ option = false;
+ format++;
+ break;
+ default:
+ if (option)
+ return data;
+ if (*data != *format)
+ return data;
+ format++;
+ data++;
+ }
+ }
+ return data;
+}
+
+// Read a line from an istream w/o concern for buffer limitations.
+std::string
+StrOps::readline(std::istream& stream)
+{
+ std::string line;
+ char buf[1024];
+
+ while (1) {
+ // Read the next line (or part thereof) from the stream.
+ stream.getline(buf, sizeof(buf));
+ // Bail out of the loop if the stream has reached end-of-file.
+ if ((stream.eof() && !buf[0]) || stream.bad())
+ break;
+
+ // Append the data read to the result string.
+ line.append(buf);
+
+ // If the stream is good, then stop. Otherwise, clear the
+ // error indicator so that getline will work again.
+ if ((stream.eof() && buf[0]) || stream.good())
+ break;
+ stream.clear();
+ }
+
+ return line;
+}
+
+std::string
+StrOps::quote_string(std::string str, bool extended_mode)
+{
+ std::string result;
+ std::ostringstream error;
+
+ if (extended_mode) {
+ result += '"';
+ for (std::string::iterator c = str.begin(); c != str.end(); ++c) {
+ switch (*c) {
+ case '\\':
+ result += '\\';
+ result += '\\';
+ break;
+
+ case '\r':
+ result += '\\';
+ result += 'r';
+ break;
+
+ case '\n':
+ result += '\\';
+ result += 'n';
+ break;
+
+ case '\t':
+ result += '\\';
+ result += 't';
+ break;
+
+ case '\v':
+ result += '\\';
+ result += 'v';
+ break;
+
+ case '"':
+ result += '\\';
+ result += '"';
+ break;
+
+ default:
+ if (isprint(*c)) {
+ result += *c;
+ } else {
+ std::ostringstream buf;
+ buf.width(2);
+ buf.setf(std::ios::hex, std::ios::basefield);
+ buf.setf(std::ios::left);
+ buf << ((static_cast<unsigned> (*c)) & 0xFF) << std::ends;
+
+ result += "\\x";
+ result += buf.str();
+ }
+ break;
+ }
+ }
+ result += '"';
+ } else {
+ result += '"';
+ for (std::string::iterator c = str.begin(); c != str.end(); ++c) {
+ if (*c == '"') {
+ result += "\"\"";
+ } else if (*c == '\n' || *c == '\r') {
+ error << "use extended csv mode for newlines\n";
+ *err << error.str();
+ kdDebug() << error.str().c_str() << endl;
+ } else {
+ result += *c;
+ }
+ }
+ result += '"';
+ }
+
+ return result;
+}
+
+std::string
+StrOps::concatenatepath(std::string p_Path,
+ std::string p_FileName, std::string p_Ext)
+{
+ std::string l_FilePath;
+#ifdef WIN32
+ if (p_FileName[1] == ':' || p_FileName[0] == '\\')
+ return p_FileName;
+ else if (p_Path.empty())
+ l_FilePath = p_FileName;
+ else
+ l_FilePath = p_Path + std::string("\\") + p_FileName;
+#else
+ if (p_FileName[0] == '/')
+ return p_FileName;
+ else if (p_Path.empty())
+ l_FilePath = p_FileName;
+ else
+ l_FilePath = p_Path + std::string("/") + p_FileName;
+
+#endif
+ if (!p_Ext.empty() && (p_FileName.rfind(p_Ext) == std::string::npos))
+ l_FilePath += p_Ext;
+
+ return l_FilePath;
+}
diff --git a/src/translators/pilotdb/strop.h b/src/translators/pilotdb/strop.h
new file mode 100644
index 0000000..3d9dc8d
--- /dev/null
+++ b/src/translators/pilotdb/strop.h
@@ -0,0 +1,153 @@
+/*
+ * palm-db-tools: Support Library: String Parsing Utility Functions
+ * Copyright (C) 1999-2000 by Tom Dyas (tdyas@users.sourceforge.net)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifh Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __LIBSUPPORT_STROP_H__
+#define __LIBSUPPORT_STROP_H__
+
+#include <stdexcept>
+#include <vector>
+#include <string>
+#include <sstream>
+#include <time.h>
+#include "libflatfile/Database.h"
+
+namespace StrOps {
+
+ // This exception is thrown whenever an error is encountered in
+ // csv_to_array and str_to_array.
+ class csv_parse_error : public std::runtime_error {
+ public:
+ csv_parse_error(const std::string& msg) : std::runtime_error(msg) { }
+ };
+
+ class csv_unterminated_quote : public std::runtime_error {
+ public:
+ csv_unterminated_quote(const std::string& msg) : std::runtime_error(msg) { }
+ };
+
+ // The results of any parse are returned as this type.
+ typedef std::vector<std::string> string_list_t;
+
+
+ /**
+ * Convert all uppercase characters in a string to lowercase.
+ */
+ void lower(std::string& str);
+
+ /**
+ * Convert a string to a boolean value.
+ *
+ * @param str The string containing a boolean value to convert.
+ */
+ bool string2boolean(const std::string& str);
+
+ /**
+ * Convert a string to a FieldType value.
+ *
+ * @param typestr The string containing a FieldType value to convert.
+ */
+ PalmLib::FlatFile::Field::FieldType string2type(std::string typestr);
+
+ /**
+ * Convert a FieldType value to a string.
+ *
+ * @param t The FieldType value containing a string to convert.
+ */
+ std::string type2string(PalmLib::FlatFile::Field::FieldType t);
+
+ /**
+ * Strip trailing characters from a string.
+ *
+ * @param str The string to strip characters from.
+ * @param what The string containing characters to strip.
+ */
+ std::string strip_back(const std::string& str, const std::string& what);
+
+ /**
+ * Strip leading characters from a string.
+ *
+ * @param str The string to strip characters from.
+ * @param what The string containing characters to strip.
+ */
+ std::string strip_front(const std::string& str, const std::string& what);
+
+ /**
+ * Convert a string to a target type using a istringstream.
+ */
+ template<class T>
+ inline void convert_string(const std::string& str, T& result) {
+ std::istringstream(str.c_str()) >> result;
+ }
+
+ /**
+ * Parse a string in CSV (comman-seperated values) format and
+ * return it as a list.
+ *
+ * @param str The string containing the CSV fields.
+ * @param delim The field delimiter. Defaults to a comma.
+ */
+ string_list_t csv_to_array(const std::string& str, char delim = ',', bool quoted_string = true);
+
+
+ /**
+ * Parse an argv-style array and return it as a list.
+ *
+ * @param str The string to parse.
+ * @param delim String containing the delimiter characters.
+ * @param multiple_delim Should multiple delimiters count as one?
+ * @param handle_comments Handle # as a comment character.
+ */
+ string_list_t str_to_array(const std::string& str,
+ const std::string& delim,
+ bool multiple_delim,
+ bool handle_comments);
+
+ /**
+ * return the current date in the palm format.
+ */
+ PalmLib::pi_uint32_t get_current_time(void);
+
+ /**
+ * fill a char array with a tm structure in the format passed.
+ * @param s the char array filled.
+ * @param format the string of the format to use to print the date.
+ * @param tm a pointer to time structure.
+ */
+ char *strptime(const char *s, const char *format, struct tm *tm);
+
+ /**
+ * read one line from the input stream of a file
+ */
+ std::string readline(std::istream& stream);
+
+ /**
+ * add the quotes to a string
+ */
+ std::string quote_string(std::string str, bool extended_mode);
+
+ /**
+ * concatenate the path directory, the file name and the extension
+ * to give the file path to a file
+ */
+ std::string concatenatepath(std::string p_Path, std::string p_FileName,
+ std::string p_Ext = std::string(""));
+
+} // namespace StrOps
+
+#endif
diff --git a/src/translators/pilotdbexporter.cpp b/src/translators/pilotdbexporter.cpp
new file mode 100644
index 0000000..b9e7367
--- /dev/null
+++ b/src/translators/pilotdbexporter.cpp
@@ -0,0 +1,232 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "pilotdbexporter.h"
+#include "pilotdb/pilotdb.h"
+#include "pilotdb/libflatfile/DB.h"
+
+#include "../collection.h"
+#include "../filehandler.h"
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kconfig.h>
+#include <kglobal.h>
+#include <kcharsets.h>
+
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qcheckbox.h>
+#include <qwhatsthis.h>
+#include <qtextcodec.h>
+#include <qdatetime.h>
+
+using Tellico::Export::PilotDBExporter;
+
+PilotDBExporter::PilotDBExporter() : Tellico::Export::Exporter(),
+ m_backup(true),
+ m_widget(0),
+ m_checkBackup(0) {
+}
+
+QString PilotDBExporter::formatString() const {
+ return i18n("PilotDB");
+}
+
+QString PilotDBExporter::fileFilter() const {
+ return i18n("*.pdb|Pilot Database Files (*.pdb)") + QChar('\n') + i18n("*|All Files");
+}
+
+bool PilotDBExporter::exec() {
+ Data::CollPtr coll = collection();
+ if(!coll) {
+ return false;
+ }
+
+ // This is something of a hidden preference cause I don't want to put it in the GUI right now
+ // Latin1 by default
+ QTextCodec* codec = 0;
+ {
+ // Latin1 is default
+ KConfigGroup group(KGlobal::config(), QString::fromLatin1("ExportOptions - %1").arg(formatString()));
+ codec = KGlobal::charsets()->codecForName(group.readEntry("Charset"));
+ }
+ if(!codec) {
+ kdWarning() << "PilotDBExporter::exec() - no QTextCodec!" << endl;
+ return false;
+#ifndef NDEBUG
+ } else {
+ kdDebug() << "PilotDBExporter::exec() - encoding with " << codec->name() << endl;
+#endif
+ }
+
+ // DB 0.3.x format
+ PalmLib::FlatFile::DB db;
+
+ // set database title
+ db.title(codec->fromUnicode(coll->title()).data());
+
+ // set backup option
+// db.setOption("backup", (m_checkBackup && m_checkBackup->isChecked()) ? "true" : "false");
+
+ // all fields are added
+ // except that only one field of type NOTE
+ bool hasNote = false;
+ Data::FieldVec outputFields; // not all fields will be output
+ Data::FieldVec fields = coll->fields();
+ for(Data::FieldVec::Iterator fIt = fields.begin(); fIt != fields.end(); ++fIt) {
+ switch(fIt->type()) {
+ case Data::Field::Choice:
+ // the charSeparator is actually defined in DB.h
+ db.appendField(codec->fromUnicode(fIt->title()).data(), PalmLib::FlatFile::Field::LIST,
+ codec->fromUnicode(fIt->allowed().join(QChar('/'))).data());
+ outputFields.append(fIt);
+ break;
+
+ case Data::Field::Number:
+ // the DB only supports single values of integers
+ if(fIt->flags() & Data::Field::AllowMultiple) {
+ db.appendField(codec->fromUnicode(fIt->title()).data(), PalmLib::FlatFile::Field::STRING);
+ } else {
+ db.appendField(codec->fromUnicode(fIt->title()).data(), PalmLib::FlatFile::Field::INTEGER);
+ }
+ outputFields.append(fIt);
+ break;
+
+ case Data::Field::Bool:
+ db.appendField(codec->fromUnicode(fIt->title()).data(), PalmLib::FlatFile::Field::BOOLEAN);
+ outputFields.append(fIt);
+ break;
+
+ case Data::Field::Para:
+ if(hasNote) { // only one is allowed, according to palm-db-tools documentation
+ kdDebug() << "PilotDBExporter::data() - adding note as string" << endl;
+ db.appendField(codec->fromUnicode(fIt->title()).data(), PalmLib::FlatFile::Field::STRING);
+ } else {
+ kdDebug() << "PilotDBExporter::data() - adding note" << endl;
+ db.appendField(codec->fromUnicode(fIt->title()).data(), PalmLib::FlatFile::Field::NOTE);
+ hasNote = true;
+ }
+ outputFields.append(fIt);
+ break;
+
+ case Data::Field::Date:
+ db.appendField(codec->fromUnicode(fIt->title()).data(), PalmLib::FlatFile::Field::DATE);
+ outputFields.append(fIt);
+ break;
+
+ case Data::Field::Image:
+ // don't include images
+ kdDebug() << "PilotDBExporter::data() - skipping " << fIt->title() << " image field" << endl;
+ break;
+
+ default:
+ db.appendField(codec->fromUnicode(fIt->title()).data(), PalmLib::FlatFile::Field::STRING);
+ outputFields.append(fIt);
+ break;
+ }
+ }
+
+ // add view with visible fields
+ if(m_columns.count() > 0) {
+ PalmLib::FlatFile::ListView lv;
+ lv.name = codec->fromUnicode(i18n("View Columns")).data();
+ for(QStringList::ConstIterator it = m_columns.begin(); it != m_columns.end(); ++it) {
+ PalmLib::FlatFile::ListViewColumn col;
+ col.field = coll->fieldTitles().findIndex(*it);
+ lv.push_back(col);
+ }
+ db.appendListView(lv);
+ }
+ db.doneWithSchema();
+
+ Data::FieldVec::ConstIterator fIt, end = outputFields.constEnd();
+ bool format = options() & Export::ExportFormatted;
+
+ QRegExp br(QString::fromLatin1("<br/?>"), false /*case-sensitive*/);
+ QRegExp tags(QString::fromLatin1("<.*>"));
+ tags.setMinimal(true);
+
+ QString value;
+ for(Data::EntryVec::ConstIterator entryIt = entries().begin(); entryIt != entries().end(); ++entryIt) {
+ PalmLib::FlatFile::Record record;
+ unsigned i = 0;
+ for(fIt = outputFields.constBegin(); fIt != end; ++fIt, ++i) {
+ value = entryIt->field(fIt->name(), format);
+
+ if(fIt->type() == Data::Field::Date) {
+ QStringList s = QStringList::split('-', value, true);
+ bool ok = true;
+ int y = s.count() > 0 ? s[0].toInt(&ok) : QDate::currentDate().year();
+ if(!ok) {
+ y = QDate::currentDate().year();
+ }
+ int m = s.count() > 1 ? s[1].toInt(&ok) : 1;
+ if(!ok) {
+ m = 1;
+ }
+ int d = s.count() > 2 ? s[2].toInt(&ok) : 1;
+ if(!ok) {
+ d = 1;
+ }
+ QDate date(y, m, d);
+ value = date.toString(QString::fromLatin1("yyyy/MM/dd"));
+ } else if(fIt->type() == Data::Field::Para) {
+ value.replace(br, QChar('\n'));
+ value.replace(tags, QString::null);
+ }
+ // the number of fields in the record must match the number of fields in the database
+ record.appendField(PilotDB::string2field(db.field_type(i),
+ value.isEmpty() ? std::string() : codec->fromUnicode(value).data()));
+ }
+ // Add the record to the database.
+ db.appendRecord(record);
+ }
+
+ PilotDB pdb;
+ db.outputPDB(pdb);
+
+ return FileHandler::writeDataURL(url(), pdb.data(), options() & Export::ExportForce);
+}
+
+QWidget* PilotDBExporter::widget(QWidget* parent_, const char* name_/*=0*/) {
+ if(m_widget && m_widget->parent() == parent_) {
+ return m_widget;
+ }
+
+ m_widget = new QWidget(parent_, name_);
+ QVBoxLayout* l = new QVBoxLayout(m_widget);
+
+ QGroupBox* box = new QGroupBox(1, Qt::Horizontal, i18n("PilotDB Options"), m_widget);
+ l->addWidget(box);
+
+ m_checkBackup = new QCheckBox(i18n("Set PDA backup flag for database"), box);
+ m_checkBackup->setChecked(m_backup);
+ QWhatsThis::add(m_checkBackup, i18n("Set PDA backup flag for database"));
+
+ l->addStretch(1);
+ return m_widget;
+}
+
+void PilotDBExporter::readOptions(KConfig* config_) {
+ KConfigGroup group(config_, QString::fromLatin1("ExportOptions - %1").arg(formatString()));
+ m_backup = group.readBoolEntry("Backup", m_backup);
+}
+
+void PilotDBExporter::saveOptions(KConfig* config_) {
+ KConfigGroup group(config_, QString::fromLatin1("ExportOptions - %1").arg(formatString()));
+ m_backup = m_checkBackup->isChecked();
+ group.writeEntry("Backup", m_backup);
+}
+
+#include "pilotdbexporter.moc"
diff --git a/src/translators/pilotdbexporter.h b/src/translators/pilotdbexporter.h
new file mode 100644
index 0000000..13d603b
--- /dev/null
+++ b/src/translators/pilotdbexporter.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef PILOTDBEXPORTER_H
+#define PILOTDBEXPORTER_H
+
+class QCheckBox;
+
+#include "exporter.h"
+
+#include <qstringlist.h>
+
+namespace Tellico {
+ namespace Export {
+
+/**
+ * @author Robby Stephenson
+ */
+class PilotDBExporter : public Exporter {
+Q_OBJECT
+
+public:
+ PilotDBExporter();
+
+ virtual bool exec();
+ virtual QString formatString() const;
+ virtual QString fileFilter() const;
+
+ virtual QWidget* widget(QWidget* parent, const char* name=0);
+ virtual void readOptions(KConfig* cfg);
+ virtual void saveOptions(KConfig* cfg);
+
+ void setColumns(const QStringList& columns) { m_columns = columns; }
+
+private:
+ bool m_backup;
+
+ QWidget* m_widget;
+ QCheckBox* m_checkBackup;
+ QStringList m_columns;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/referencerimporter.cpp b/src/translators/referencerimporter.cpp
new file mode 100644
index 0000000..32ba251
--- /dev/null
+++ b/src/translators/referencerimporter.cpp
@@ -0,0 +1,71 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "referencerimporter.h"
+#include "../collection.h"
+#include "../core/netaccess.h"
+#include "../imagefactory.h"
+
+#include <kstandarddirs.h>
+
+using Tellico::Import::ReferencerImporter;
+
+ReferencerImporter::ReferencerImporter(const KURL& url_) : XSLTImporter(url_) {
+ QString xsltFile = locate("appdata", QString::fromLatin1("referencer2tellico.xsl"));
+ if(!xsltFile.isEmpty()) {
+ KURL u;
+ u.setPath(xsltFile);
+ XSLTImporter::setXSLTURL(u);
+ } else {
+ kdWarning() << "ReferencerImporter() - unable to find referencer2tellico.xml!" << endl;
+ }
+}
+
+bool ReferencerImporter::canImport(int type) const {
+ return type == Data::Collection::Bibtex;
+}
+
+Tellico::Data::CollPtr ReferencerImporter::collection() {
+ Data::CollPtr coll = XSLTImporter::collection();
+ if(!coll) {
+ return 0;
+ }
+
+ Data::FieldPtr field = coll->fieldByName(QString::fromLatin1("cover"));
+ if(!field && !coll->imageFields().isEmpty()) {
+ field = coll->imageFields().front();
+ } else if(!field) {
+ field = new Data::Field(QString::fromLatin1("cover"), i18n("Front Cover"), Data::Field::Image);
+ coll->addField(field);
+ }
+
+ Data::EntryVec entries = coll->entries();
+ for(Data::EntryVecIt entry = entries.begin(); entry != entries.end(); ++entry) {
+ QString url = entry->field(QString::fromLatin1("url"));
+ if(url.isEmpty()) {
+ continue;
+ }
+ QPixmap pix = NetAccess::filePreview(url);
+ if(pix.isNull()) {
+ continue;
+ }
+ QString id = ImageFactory::addImage(pix, QString::fromLatin1("PNG"));
+ if(id.isEmpty()) {
+ continue;
+ }
+ entry->setField(field, id);
+ }
+ return coll;
+}
+
+#include "referencerimporter.moc"
diff --git a/src/translators/referencerimporter.h b/src/translators/referencerimporter.h
new file mode 100644
index 0000000..65cc3a0
--- /dev/null
+++ b/src/translators/referencerimporter.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_IMPORT_REFERENCERIMPORTER_H
+#define TELLICO_IMPORT_REFERENCERIMPORTER_H
+
+#include "xsltimporter.h"
+#include "../datavectors.h"
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ * @author Robby Stephenson
+*/
+class ReferencerImporter : public XSLTImporter {
+Q_OBJECT
+
+public:
+ /**
+ */
+ ReferencerImporter(const KURL& url);
+
+ /**
+ */
+ virtual Data::CollPtr collection();
+ /**
+ */
+ virtual QWidget* widget(QWidget*, const char*) { return 0; }
+ virtual bool canImport(int type) const;
+
+private:
+ // private so it can't be changed accidently
+ void setXSLTURL(const KURL& url);
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/risimporter.cpp b/src/translators/risimporter.cpp
new file mode 100644
index 0000000..0420f66
--- /dev/null
+++ b/src/translators/risimporter.cpp
@@ -0,0 +1,315 @@
+/***************************************************************************
+ copyright : (C) 2004-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "risimporter.h"
+#include "../collections/bibtexcollection.h"
+#include "../document.h"
+#include "../entry.h"
+#include "../field.h"
+#include "../latin1literal.h"
+#include "../progressmanager.h"
+#include "../filehandler.h"
+#include "../isbnvalidator.h"
+#include "../tellico_debug.h"
+
+#include <kapplication.h>
+
+#include <qdict.h>
+#include <qregexp.h>
+#include <qmap.h>
+
+using Tellico::Import::RISImporter;
+QMap<QString, QString>* RISImporter::s_tagMap = 0;
+QMap<QString, QString>* RISImporter::s_typeMap = 0;
+
+// static
+void RISImporter::initTagMap() {
+ if(!s_tagMap) {
+ s_tagMap = new QMap<QString, QString>();
+ // BT is special and is handled separately
+ s_tagMap->insert(QString::fromLatin1("TY"), QString::fromLatin1("entry-type"));
+ s_tagMap->insert(QString::fromLatin1("ID"), QString::fromLatin1("bibtex-key"));
+ s_tagMap->insert(QString::fromLatin1("T1"), QString::fromLatin1("title"));
+ s_tagMap->insert(QString::fromLatin1("TI"), QString::fromLatin1("title"));
+ s_tagMap->insert(QString::fromLatin1("T2"), QString::fromLatin1("booktitle"));
+ s_tagMap->insert(QString::fromLatin1("A1"), QString::fromLatin1("author"));
+ s_tagMap->insert(QString::fromLatin1("AU"), QString::fromLatin1("author"));
+ s_tagMap->insert(QString::fromLatin1("ED"), QString::fromLatin1("editor"));
+ s_tagMap->insert(QString::fromLatin1("YR"), QString::fromLatin1("year"));
+ s_tagMap->insert(QString::fromLatin1("PY"), QString::fromLatin1("year"));
+ s_tagMap->insert(QString::fromLatin1("N1"), QString::fromLatin1("note"));
+ s_tagMap->insert(QString::fromLatin1("AB"), QString::fromLatin1("abstract")); // should be note?
+ s_tagMap->insert(QString::fromLatin1("N2"), QString::fromLatin1("abstract"));
+ s_tagMap->insert(QString::fromLatin1("KW"), QString::fromLatin1("keyword"));
+ s_tagMap->insert(QString::fromLatin1("JF"), QString::fromLatin1("journal"));
+ s_tagMap->insert(QString::fromLatin1("JO"), QString::fromLatin1("journal"));
+ s_tagMap->insert(QString::fromLatin1("JA"), QString::fromLatin1("journal"));
+ s_tagMap->insert(QString::fromLatin1("VL"), QString::fromLatin1("volume"));
+ s_tagMap->insert(QString::fromLatin1("IS"), QString::fromLatin1("number"));
+ s_tagMap->insert(QString::fromLatin1("PB"), QString::fromLatin1("publisher"));
+ s_tagMap->insert(QString::fromLatin1("SN"), QString::fromLatin1("isbn"));
+ s_tagMap->insert(QString::fromLatin1("AD"), QString::fromLatin1("address"));
+ s_tagMap->insert(QString::fromLatin1("CY"), QString::fromLatin1("address"));
+ s_tagMap->insert(QString::fromLatin1("UR"), QString::fromLatin1("url"));
+ s_tagMap->insert(QString::fromLatin1("L1"), QString::fromLatin1("pdf"));
+ s_tagMap->insert(QString::fromLatin1("T3"), QString::fromLatin1("series"));
+ s_tagMap->insert(QString::fromLatin1("EP"), QString::fromLatin1("pages"));
+ }
+}
+
+// static
+void RISImporter::initTypeMap() {
+ if(!s_typeMap) {
+ s_typeMap = new QMap<QString, QString>();
+ // leave capitalized, except for bibtex types
+ s_typeMap->insert(QString::fromLatin1("ABST"), QString::fromLatin1("Abstract"));
+ s_typeMap->insert(QString::fromLatin1("ADVS"), QString::fromLatin1("Audiovisual material"));
+ s_typeMap->insert(QString::fromLatin1("ART"), QString::fromLatin1("Art Work"));
+ s_typeMap->insert(QString::fromLatin1("BILL"), QString::fromLatin1("Bill/Resolution"));
+ s_typeMap->insert(QString::fromLatin1("BOOK"), QString::fromLatin1("book")); // bibtex
+ s_typeMap->insert(QString::fromLatin1("CASE"), QString::fromLatin1("Case"));
+ s_typeMap->insert(QString::fromLatin1("CHAP"), QString::fromLatin1("inbook")); // == "inbook" ?
+ s_typeMap->insert(QString::fromLatin1("COMP"), QString::fromLatin1("Computer program"));
+ s_typeMap->insert(QString::fromLatin1("CONF"), QString::fromLatin1("inproceedings")); // == "conference" ?
+ s_typeMap->insert(QString::fromLatin1("CTLG"), QString::fromLatin1("Catalog"));
+ s_typeMap->insert(QString::fromLatin1("DATA"), QString::fromLatin1("Data file"));
+ s_typeMap->insert(QString::fromLatin1("ELEC"), QString::fromLatin1("Electronic Citation"));
+ s_typeMap->insert(QString::fromLatin1("GEN"), QString::fromLatin1("Generic"));
+ s_typeMap->insert(QString::fromLatin1("HEAR"), QString::fromLatin1("Hearing"));
+ s_typeMap->insert(QString::fromLatin1("ICOMM"), QString::fromLatin1("Internet Communication"));
+ s_typeMap->insert(QString::fromLatin1("INPR"), QString::fromLatin1("In Press"));
+ s_typeMap->insert(QString::fromLatin1("JFULL"), QString::fromLatin1("Journal (full)")); // = "periodical" ?
+ s_typeMap->insert(QString::fromLatin1("JOUR"), QString::fromLatin1("article")); // "Journal"
+ s_typeMap->insert(QString::fromLatin1("MAP"), QString::fromLatin1("Map"));
+ s_typeMap->insert(QString::fromLatin1("MGZN"), QString::fromLatin1("article")); // bibtex
+ s_typeMap->insert(QString::fromLatin1("MPCT"), QString::fromLatin1("Motion picture"));
+ s_typeMap->insert(QString::fromLatin1("MUSIC"), QString::fromLatin1("Music score"));
+ s_typeMap->insert(QString::fromLatin1("NEWS"), QString::fromLatin1("Newspaper"));
+ s_typeMap->insert(QString::fromLatin1("PAMP"), QString::fromLatin1("Pamphlet")); // = "booklet" ?
+ s_typeMap->insert(QString::fromLatin1("PAT"), QString::fromLatin1("Patent"));
+ s_typeMap->insert(QString::fromLatin1("PCOMM"), QString::fromLatin1("Personal communication"));
+ s_typeMap->insert(QString::fromLatin1("RPRT"), QString::fromLatin1("Report")); // = "techreport" ?
+ s_typeMap->insert(QString::fromLatin1("SER"), QString::fromLatin1("Serial (BookMonograph)"));
+ s_typeMap->insert(QString::fromLatin1("SLIDE"), QString::fromLatin1("Slide"));
+ s_typeMap->insert(QString::fromLatin1("SOUND"), QString::fromLatin1("Sound recording"));
+ s_typeMap->insert(QString::fromLatin1("STAT"), QString::fromLatin1("Statute"));
+ s_typeMap->insert(QString::fromLatin1("THES"), QString::fromLatin1("phdthesis")); // "mastersthesis" ?
+ s_typeMap->insert(QString::fromLatin1("UNBILL"), QString::fromLatin1("Unenacted bill/resolution"));
+ s_typeMap->insert(QString::fromLatin1("UNPB"), QString::fromLatin1("unpublished")); // bibtex
+ s_typeMap->insert(QString::fromLatin1("VIDEO"), QString::fromLatin1("Video recording"));
+ }
+}
+
+RISImporter::RISImporter(const KURL::List& urls_) : Tellico::Import::Importer(urls_), m_coll(0), m_cancelled(false) {
+ initTagMap();
+ initTypeMap();
+}
+
+bool RISImporter::canImport(int type) const {
+ return type == Data::Collection::Bibtex;
+}
+
+Tellico::Data::CollPtr RISImporter::collection() {
+ if(m_coll) {
+ return m_coll;
+ }
+
+ m_coll = new Data::BibtexCollection(true);
+
+ QDict<Data::Field> risFields;
+
+ // need to know if any extended properties in current collection point to RIS
+ // if so, add to collection
+ Data::CollPtr currColl = Data::Document::self()->collection();
+ Data::FieldVec vec = currColl->fields();
+ for(Data::FieldVec::Iterator it = vec.begin(); it != vec.end(); ++it) {
+ // continue if property is empty
+ QString ris = it->property(QString::fromLatin1("ris"));
+ if(ris.isEmpty()) {
+ continue;
+ }
+ // if current collection has one with the same name, set the property
+ Data::FieldPtr f = m_coll->fieldByName(it->name());
+ if(!f) {
+ f = new Data::Field(*it);
+ m_coll->addField(f);
+ }
+ f->setProperty(QString::fromLatin1("ris"), ris);
+ risFields.insert(ris, f);
+ }
+
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, progressLabel(), true);
+ item.setTotalSteps(urls().count() * 100);
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+ ProgressItem::Done done(this);
+
+ int count = 0;
+ KURL::List urls = this->urls();
+ for(KURL::List::ConstIterator it = urls.begin(); it != urls.end() && !m_cancelled; ++it, ++count) {
+ readURL(*it, count, risFields);
+ }
+
+ if(m_cancelled) {
+ m_coll = 0;
+ }
+ return m_coll;
+}
+
+void RISImporter::readURL(const KURL& url_, int n, const QDict<Data::Field>& risFields_) {
+ QString str = FileHandler::readTextFile(url_);
+ if(str.isEmpty()) {
+ return;
+ }
+
+ ISBNValidator isbnval(this);
+
+ QTextIStream t(&str);
+
+ const uint length = str.length();
+ const uint stepSize = QMAX(s_stepSize, length/100);
+ const bool showProgress = options() & ImportProgress;
+
+ bool needToAddFinal = false;
+
+ QString sp, ep;
+
+ uint j = 0;
+ Data::EntryPtr entry = new Data::Entry(m_coll);
+ // technically, the spec requires a space immediately after the hyphen
+ // however, at least one website (Springer) outputs RIS with no space after the final "ER -"
+ // so just strip the white space later
+ // also be gracious and allow only any amount of space before hyphen
+ QRegExp rx(QString::fromLatin1("^(\\w\\w)\\s+-(.*)$"));
+ QString currLine, nextLine;
+ for(currLine = t.readLine(); !m_cancelled && !currLine.isNull(); currLine = nextLine, j += currLine.length()) {
+ nextLine = t.readLine();
+ rx.search(currLine);
+ QString tag = rx.cap(1);
+ QString value = rx.cap(2).stripWhiteSpace();
+ if(tag.isEmpty()) {
+ continue;
+ }
+// myDebug() << tag << ": " << value << endl;
+ // if the next line is not empty and does not match start regexp, append to value
+ while(!nextLine.isEmpty() && nextLine.find(rx) == -1) {
+ value += nextLine.stripWhiteSpace();
+ nextLine = t.readLine();
+ }
+
+ // every entry ends with "ER"
+ if(tag == Latin1Literal("ER")) {
+ m_coll->addEntries(entry);
+ entry = new Data::Entry(m_coll);
+ needToAddFinal = false;
+ continue;
+ } else if(tag == Latin1Literal("TY") && s_typeMap->contains(value)) {
+ // for entry-type, switch it to normalized type name
+ value = (*s_typeMap)[value];
+ } else if(tag == Latin1Literal("SN")) {
+ // test for valid isbn, sometimes the issn gets stuck here
+ int pos = 0;
+ if(isbnval.validate(value, pos) != ISBNValidator::Acceptable) {
+ continue;
+ }
+ } else if(tag == Latin1Literal("SP")) {
+ sp = value;
+ if(!ep.isEmpty()) {
+ value = sp + '-' + ep;
+ tag = QString::fromLatin1("EP");
+ sp = QString();
+ ep = QString();
+ } else {
+ // nothing else to do
+ continue;
+ }
+ } else if(tag == Latin1Literal("EP")) {
+ ep = value;
+ if(!sp.isEmpty()) {
+ value = sp + '-' + ep;
+ sp = QString();
+ ep = QString();
+ } else {
+ continue;
+ }
+ } else if(tag == Latin1Literal("YR") || tag == Latin1Literal("PY")) { // for now, just grab the year
+ value = value.section('/', 0, 0);
+ }
+
+ // the lookup scheme is:
+ // 1. any field has an RIS property that matches the tag name
+ // 2. default field mapping tag -> field name
+ Data::FieldPtr f = risFields_.find(tag);
+ if(!f) {
+ // special case for BT
+ // primary title for books, secondary for everything else
+ if(tag == Latin1Literal("BT")) {
+ if(entry->field(QString::fromLatin1("entry-type")) == Latin1Literal("book")) {
+ f = m_coll->fieldByName(QString::fromLatin1("title"));
+ } else {
+ f = m_coll->fieldByName(QString::fromLatin1("booktitle"));
+ }
+ } else {
+ f = fieldByTag(tag);
+ }
+ }
+ if(!f) {
+ continue;
+ }
+ needToAddFinal = true;
+
+ // harmless for non-choice fields
+ // for entry-type, want it in lower case
+ f->addAllowed(value);
+ // if the field can have multiple values, append current values to new value
+ if((f->flags() & Data::Field::AllowMultiple) && !entry->field(f->name()).isEmpty()) {
+ value.prepend(entry->field(f->name()) + QString::fromLatin1("; "));
+ }
+ entry->setField(f, value);
+
+ if(showProgress && j%stepSize == 0) {
+ ProgressManager::self()->setProgress(this, n*100 + 100*j/length);
+ kapp->processEvents();
+ }
+ }
+
+ if(needToAddFinal) {
+ m_coll->addEntries(entry);
+ }
+}
+
+Tellico::Data::FieldPtr RISImporter::fieldByTag(const QString& tag_) {
+ Data::FieldPtr f = 0;
+ const QString& fieldTag = (*s_tagMap)[tag_];
+ if(!fieldTag.isEmpty()) {
+ f = m_coll->fieldByName(fieldTag);
+ if(f) {
+ f->setProperty(QString::fromLatin1("ris"), tag_);
+ return f;
+ }
+ }
+
+ // add non-default fields if not already there
+ if(tag_== Latin1Literal("L1")) {
+ f = new Data::Field(QString::fromLatin1("pdf"), i18n("PDF"), Data::Field::URL);
+ f->setProperty(QString::fromLatin1("ris"), QString::fromLatin1("L1"));
+ f->setCategory(i18n("Miscellaneous"));
+ }
+ m_coll->addField(f);
+ return f;
+}
+
+void RISImporter::slotCancel() {
+ m_cancelled = true;
+}
+
+#include "risimporter.moc"
diff --git a/src/translators/risimporter.h b/src/translators/risimporter.h
new file mode 100644
index 0000000..c7d08d2
--- /dev/null
+++ b/src/translators/risimporter.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ copyright : (C) 2004-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef RISIMPORTER_H
+#define RISIMPORTER_H
+
+#include "importer.h"
+#include "../datavectors.h"
+
+#include <qstring.h>
+#include <qmap.h>
+
+template<class type>
+class QDict;
+
+namespace Tellico {
+ namespace Data {
+ class Field;
+ }
+ namespace Import {
+
+/**
+ * @author Robby Stephenson
+ */
+class RISImporter : public Importer {
+Q_OBJECT
+
+public:
+ /**
+ */
+ RISImporter(const KURL::List& urls);
+
+ /**
+ * @return A pointer to a @ref Data::Collection, or 0 if none can be created.
+ */
+ virtual Data::CollPtr collection();
+ /**
+ */
+ virtual QWidget* widget(QWidget*, const char*) { return 0; }
+ virtual bool canImport(int type) const;
+
+public slots:
+ void slotCancel();
+
+private:
+ static void initTagMap();
+ static void initTypeMap();
+
+ Data::FieldPtr fieldByTag(const QString& tag);
+ void readURL(const KURL& url, int n, const QDict<Data::Field>& risFields);
+
+ Data::CollPtr m_coll;
+ bool m_cancelled;
+
+ static QMap<QString, QString>* s_tagMap;
+ static QMap<QString, QString>* s_typeMap;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/tellico_xml.cpp b/src/translators/tellico_xml.cpp
new file mode 100644
index 0000000..8e7ac61
--- /dev/null
+++ b/src/translators/tellico_xml.cpp
@@ -0,0 +1,98 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "tellico_xml.h"
+
+#include <libxml/parserInternals.h> // needed for IS_LETTER
+#include <libxml/parser.h> // has to be before valid.h
+#include <libxml/valid.h>
+
+#include <qregexp.h>
+
+const QString Tellico::XML::nsXSL = QString::fromLatin1("http://www.w3.org/1999/XSL/Transform");
+const QString Tellico::XML::nsBibtexml = QString::fromLatin1("http://bibtexml.sf.net/");
+const QString Tellico::XML::dtdBibtexml = QString::fromLatin1("bibtexml.dtd");
+
+/*
+ * VERSION 2 added namespaces, changed to multiple elements,
+ * and changed the "keywords" field to "keyword"
+ *
+ * VERSION 3 broke out the formatFlag, and changed NoComplete to AllowCompletion
+ *
+ * VERSION 4 added a bibtex-field name for Bibtex collections, element name was
+ * changed to 'entry', field elements changed to 'field', and boolean fields are now "true"
+ *
+ * VERSION 5 moved the bibtex-field and any other extended field property to property elements
+ * inside the field element, and added the image element.
+ *
+ * VERSION 6 added id, i18n attributes, and year, month, day elements in date fields with a calendar name
+ * attribute.
+ *
+ * VERSION 7 changed the application name to Tellico, renamed unitTitle to entryTitle, and made the id permanent.
+ *
+ * VERSION 8 added loans and saved filters.
+ *
+ * VERSION 9 changed music collections to always have three columns by default, with title/artist/length and
+ * added file catalog collection.
+ *
+ * VERSION 10 added the game board collection.
+ */
+const uint Tellico::XML::syntaxVersion = 10;
+const QString Tellico::XML::nsTellico = QString::fromLatin1("http://periapsis.org/tellico/");
+
+const QString Tellico::XML::nsBookcase = QString::fromLatin1("http://periapsis.org/bookcase/");
+const QString Tellico::XML::nsDublinCore = QString::fromLatin1("http://purl.org/dc/elements/1.1/");
+const QString Tellico::XML::nsZing = QString::fromLatin1("http://www.loc.gov/zing/srw/");
+const QString Tellico::XML::nsZingDiag = QString::fromLatin1("http://www.loc.gov/zing/srw/diagnostic/");
+
+QString Tellico::XML::pubTellico(int version) {
+ return QString::fromLatin1("-//Robby Stephenson/DTD Tellico V%1.0//EN").arg(version);
+}
+
+QString Tellico::XML::dtdTellico(int version) {
+ return QString::fromLatin1("http://periapsis.org/tellico/dtd/v%1/tellico.dtd").arg(version);
+}
+
+bool Tellico::XML::validXMLElementName(const QString& name_) {
+ return xmlValidateNameValue((xmlChar *)name_.utf8().data());
+}
+
+QString Tellico::XML::elementName(const QString& name_) {
+ QString name = name_;
+ // change white space to dashes
+ name.replace(QRegExp(QString::fromLatin1("\\s+")), QString::fromLatin1("-"));
+ // first cut, if it passes, we're done
+ if(XML::validXMLElementName(name)) {
+ return name;
+ }
+
+ // next check first characters IS_DIGIT is defined in libxml/vali.d
+ for(uint i = 0; i < name.length() && (!IS_LETTER(name[i].unicode()) || name[i] == '_'); ++i) {
+ name = name.mid(1);
+ }
+ if(name.isEmpty() || XML::validXMLElementName(name)) {
+ return name; // empty names are handled later
+ }
+
+ // now brute-force it, one character at a time
+ uint i = 0;
+ while(i < name.length()) {
+ if(!XML::validXMLElementName(name.left(i+1))) {
+ name.remove(i, 1); // remember it's zero-indexed
+ } else {
+ // character is ok, increment i
+ ++i;
+ }
+ }
+ return name;
+}
diff --git a/src/translators/tellico_xml.h b/src/translators/tellico_xml.h
new file mode 100644
index 0000000..7c1a3e2
--- /dev/null
+++ b/src/translators/tellico_xml.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_XML_H
+#define TELLICO_XML_H
+
+#include <qstring.h>
+
+namespace Tellico {
+ namespace XML {
+ extern const QString nsXSL;
+ extern const QString nsBibtexml;
+ extern const QString dtdBibtexml;
+
+ extern const uint syntaxVersion;
+ extern const QString nsTellico;
+
+ QString pubTellico(int version = syntaxVersion);
+ QString dtdTellico(int version = syntaxVersion);
+
+ extern const QString nsBookcase;
+ extern const QString nsDublinCore;
+ extern const QString nsZing;
+ extern const QString nsZingDiag;
+
+ bool validXMLElementName(const QString& name);
+ QString elementName(const QString& name);
+ }
+}
+
+#endif
diff --git a/src/translators/tellicoimporter.cpp b/src/translators/tellicoimporter.cpp
new file mode 100644
index 0000000..cb3c7a3
--- /dev/null
+++ b/src/translators/tellicoimporter.cpp
@@ -0,0 +1,1021 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "tellicoimporter.h"
+#include "tellico_xml.h"
+#include "../collectionfactory.h"
+#include "../collections/bibtexcollection.h"
+#include "../entry.h"
+#include "../field.h"
+#include "../imagefactory.h"
+#include "../image.h"
+#include "../isbnvalidator.h"
+#include "../latin1literal.h"
+#include "../tellico_strings.h"
+#include "../tellico_kernel.h"
+#include "../tellico_utils.h"
+#include "../tellico_debug.h"
+#include "../progressmanager.h"
+
+#include <klocale.h>
+#include <kmdcodec.h>
+#include <kzip.h>
+#include <kapplication.h>
+
+#include <qdom.h>
+#include <qbuffer.h>
+#include <qfile.h>
+#include <qtimer.h>
+
+using Tellico::Import::TellicoImporter;
+
+bool TellicoImporter::versionConversion(uint from, uint to) {
+ // version 10 only added board games to version 9
+ return from < to && (from != 9 || to != 10);
+}
+
+TellicoImporter::TellicoImporter(const KURL& url_, bool loadAllImages_) : DataImporter(url_),
+ m_coll(0), m_loadAllImages(loadAllImages_), m_format(Unknown), m_modified(false),
+ m_cancelled(false), m_hasImages(false), m_buffer(0), m_zip(0), m_imgDir(0) {
+}
+
+TellicoImporter::TellicoImporter(const QString& text_) : DataImporter(text_),
+ m_coll(0), m_loadAllImages(true), m_format(Unknown), m_modified(false),
+ m_cancelled(false), m_hasImages(false), m_buffer(0), m_zip(0), m_imgDir(0) {
+}
+
+TellicoImporter::~TellicoImporter() {
+ if(m_zip) {
+ m_zip->close();
+ }
+ delete m_zip;
+ m_zip = 0;
+ delete m_buffer;
+ m_buffer = 0;
+}
+
+Tellico::Data::CollPtr TellicoImporter::collection() {
+ if(m_coll) {
+ return m_coll;
+ }
+
+ QCString s; // read first 5 characters
+ if(source() == URL) {
+ if(!fileRef().open()) {
+ return 0;
+ }
+ QIODevice* f = fileRef().file();
+ for(uint i = 0; i < 5; ++i) {
+ s += static_cast<char>(f->getch());
+ }
+ f->reset();
+ } else {
+ if(data().size() < 5) {
+ m_format = Error;
+ return 0;
+ }
+ s = QCString(data(), 6);
+ }
+
+ // need to decide if the data is xml text, or a zip file
+ // if the first 5 characters are <?xml then treat it like text
+ if(s[0] == '<' && s[1] == '?' && s[2] == 'x' && s[3] == 'm' && s[4] == 'l') {
+ m_format = XML;
+ loadXMLData(source() == URL ? fileRef().file()->readAll() : data(), true);
+ } else {
+ m_format = Zip;
+ loadZipData();
+ }
+ return m_coll;
+}
+
+void TellicoImporter::loadXMLData(const QByteArray& data_, bool loadImages_) {
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, progressLabel(), true);
+ item.setTotalSteps(100);
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+ ProgressItem::Done done(this);
+
+ QDomDocument dom;
+ QString errorMsg;
+ int errorLine, errorColumn;
+ if(!dom.setContent(data_, true, &errorMsg, &errorLine, &errorColumn)) {
+ QString str = i18n(errorLoad).arg(url().fileName()) + QChar('\n');
+ str += i18n("There is an XML parsing error in line %1, column %2.").arg(errorLine).arg(errorColumn);
+ str += QString::fromLatin1("\n");
+ str += i18n("The error message from Qt is:");
+ str += QString::fromLatin1("\n\t") + errorMsg;
+ myDebug() << str << endl;
+ setStatusMessage(str);
+ m_format = Error;
+ return;
+ }
+
+ QDomElement root = dom.documentElement();
+
+ // the syntax version field name changed from "version" to "syntaxVersion" in version 3
+ uint syntaxVersion;
+ if(root.hasAttribute(QString::fromLatin1("syntaxVersion"))) {
+ syntaxVersion = root.attribute(QString::fromLatin1("syntaxVersion")).toInt();
+ } else if (root.hasAttribute(QString::fromLatin1("version"))) {
+ syntaxVersion = root.attribute(QString::fromLatin1("version")).toInt();
+ } else {
+ if(!url().isEmpty()) {
+ setStatusMessage(i18n(errorLoad).arg(url().fileName()));
+ }
+ m_format = Error;
+ return;
+ }
+// myDebug() << "TellicoImporter::loadXMLData() - syntaxVersion = " << syntaxVersion << endl;
+
+ if((syntaxVersion > 6 && root.tagName() != Latin1Literal("tellico"))
+ || (syntaxVersion < 7 && root.tagName() != Latin1Literal("bookcase"))) {
+ if(!url().isEmpty()) {
+ setStatusMessage(i18n(errorLoad).arg(url().fileName()));
+ }
+ m_format = Error;
+ return;
+ }
+
+ if(syntaxVersion > XML::syntaxVersion) {
+ if(!url().isEmpty()) {
+ QString str = i18n(errorLoad).arg(url().fileName()) + QChar('\n');
+ str += i18n("It is from a future version of Tellico.");
+ myDebug() << str << endl;
+ setStatusMessage(str);
+ } else {
+ myDebug() << "Unable to load collection, from a future version (" << syntaxVersion << ")" << endl;
+ }
+ m_format = Error;
+ return;
+ } else if(versionConversion(syntaxVersion, XML::syntaxVersion)) {
+ // going form version 9 to 10, there's no conversion needed
+ QString str = i18n("Tellico is converting the file to a more recent document format. "
+ "Information loss may occur if an older version of Tellico is used "
+ "to read this file in the future.");
+ myDebug() << str << endl;
+// setStatusMessage(str);
+ m_modified = true; // mark as modified
+ }
+
+ m_namespace = syntaxVersion > 6 ? XML::nsTellico : XML::nsBookcase;
+
+ // the collection item should be the first dom element child of the root
+ QDomElement collelem;
+ for(QDomNode n = root.firstChild(); !n.isNull(); n = n.nextSibling()) {
+ if(n.namespaceURI() != m_namespace) {
+ continue;
+ }
+ if(n.isElement() && n.localName() == Latin1Literal("collection")) {
+ collelem = n.toElement();
+ break;
+ }
+ }
+ if(collelem.isNull()) {
+ kdWarning() << "TellicoImporter::loadDomDocument() - No collection item found." << endl;
+ return;
+ }
+
+ QString title = collelem.attribute(QString::fromLatin1("title"));
+
+ // be careful not to have element name collision
+ // for fields, each true field element is a child of a fields element
+ QDomNodeList fieldelems;
+ for(QDomNode n = collelem.firstChild(); !n.isNull(); n = n.nextSibling()) {
+ if(n.namespaceURI() != m_namespace) {
+ continue;
+ }
+ // Latin1Literal is a macro, so can't say Latin1Literal(syntaxVersion > 3 ? "fields" : "attributes")
+ if((syntaxVersion > 3 && n.localName() == Latin1Literal("fields"))
+ || (syntaxVersion < 4 && n.localName() == Latin1Literal("attributes"))) {
+ QDomElement e = n.toElement();
+ fieldelems = e.elementsByTagNameNS(m_namespace, (syntaxVersion > 3) ? QString::fromLatin1("field")
+ : QString::fromLatin1("attribute"));
+ break;
+ }
+ }
+// myDebug() << "TellicoImporter::loadXMLData() - " << fieldelems.count() << " field(s)" << endl;
+
+ // the dilemma is when to force the new collection to have all the default attributes
+ // if there are no attributes or if the first one has the special name of _default
+ bool addFields = (fieldelems.count() == 0);
+ if(!addFields) {
+ QString name = fieldelems.item(0).toElement().attribute(QString::fromLatin1("name"));
+ addFields = (name == Latin1Literal("_default"));
+ // removeChild only works for immediate children
+ // remove _default field
+ if(addFields) {
+ fieldelems.item(0).parentNode().removeChild(fieldelems.item(0));
+ }
+ }
+
+ QString entryName;
+ // in syntax 4, the element name was changed to "entry", always, rather than depending on
+ // on the entryName of the collection. A type field was added to the collection element
+ // to specify what type of collection it is.
+ if(syntaxVersion > 3) {
+ entryName = QString::fromLatin1("entry");
+ QString typeStr = collelem.attribute(QString::fromLatin1("type"));
+ Data::Collection::Type type = static_cast<Data::Collection::Type>(typeStr.toInt());
+ m_coll = CollectionFactory::collection(type, addFields);
+ } else {
+ entryName = collelem.attribute(QString::fromLatin1("unit"));
+ m_coll = CollectionFactory::collection(entryName, addFields);
+ }
+
+ if(!title.isEmpty()) {
+ m_coll->setTitle(title);
+ }
+
+ for(uint j = 0; j < fieldelems.count(); ++j) {
+ readField(syntaxVersion, fieldelems.item(j).toElement());
+ }
+
+ if(m_coll->type() == Data::Collection::Bibtex) {
+ Data::BibtexCollection* c = static_cast<Data::BibtexCollection*>(m_coll.data());
+ QDomNodeList macroelems;
+ for(QDomNode n = collelem.firstChild(); !n.isNull(); n = n.nextSibling()) {
+ if(n.namespaceURI() != m_namespace) {
+ continue;
+ }
+ if(n.localName() == Latin1Literal("macros")) {
+ macroelems = n.toElement().elementsByTagNameNS(m_namespace, QString::fromLatin1("macro"));
+ break;
+ }
+ }
+// myDebug() << "TellicoImporter::loadXMLData() - found " << macroelems.count() << " macros" << endl;
+ for(uint j = 0; c && j < macroelems.count(); ++j) {
+ QDomElement elem = macroelems.item(j).toElement();
+ c->addMacro(elem.attribute(QString::fromLatin1("name")), elem.text());
+ }
+
+ for(QDomNode n = collelem.firstChild(); !n.isNull(); n = n.nextSibling()) {
+ if(n.namespaceURI() != m_namespace) {
+ continue;
+ }
+ if(n.localName() == Latin1Literal("bibtex-preamble")) {
+ c->setPreamble(n.toElement().text());
+ break;
+ }
+ }
+ }
+
+ if(m_cancelled) {
+ m_coll = 0;
+ return;
+ }
+
+// as a special case, for old book collections with a bibtex-id field, convert to Bibtex
+ if(syntaxVersion < 4 && m_coll->type() == Data::Collection::Book
+ && m_coll->hasField(QString::fromLatin1("bibtex-id"))) {
+ m_coll = Data::BibtexCollection::convertBookCollection(m_coll);
+ }
+
+ const uint count = collelem.childNodes().count();
+ const uint stepSize = QMAX(s_stepSize, count/100);
+ const bool showProgress = options() & ImportProgress;
+
+ item.setTotalSteps(count);
+
+ // have to read images before entries so we can figure out if
+ // linkOnly() is true
+ // m_loadAllImages only pertains to zip files
+ QDomNodeList imgelems;
+ for(QDomNode n = collelem.firstChild(); !n.isNull(); n = n.nextSibling()) {
+ if(n.namespaceURI() != m_namespace) {
+ continue;
+ }
+ if(n.localName() == Latin1Literal("images")) {
+ imgelems = n.toElement().elementsByTagNameNS(m_namespace, QString::fromLatin1("image"));
+ break;
+ }
+ }
+ for(uint j = 0; j < imgelems.count(); ++j) {
+ readImage(imgelems.item(j).toElement(), loadImages_);
+ }
+
+ if(m_cancelled) {
+ m_coll = 0;
+ return;
+ }
+
+ uint j = 0;
+ for(QDomNode n = collelem.firstChild(); !n.isNull() && !m_cancelled; n = n.nextSibling(), ++j) {
+ if(n.namespaceURI() != m_namespace) {
+ continue;
+ }
+ if(n.localName() == entryName) {
+ readEntry(syntaxVersion, n.toElement());
+
+ // not exactly right, but close enough
+ if(showProgress && j%stepSize == 0) {
+ ProgressManager::self()->setProgress(this, j);
+ kapp->processEvents();
+ }
+ } else {
+// myDebug() << "...skipping " << n.localName() << " (" << n.namespaceURI() << ")" << endl;
+ }
+ } // end entry loop
+
+ if(m_cancelled) {
+ m_coll = 0;
+ return;
+ }
+
+ // filters and borrowers are at document root level, not collection
+ for(QDomNode n = root.firstChild(); !n.isNull() && !m_cancelled; n = n.nextSibling()) {
+ if(n.namespaceURI() != m_namespace) {
+ continue;
+ }
+ if(n.localName() == Latin1Literal("borrowers")) {
+ QDomNodeList borrowerElems = n.toElement().elementsByTagNameNS(m_namespace, QString::fromLatin1("borrower"));
+ for(uint j = 0; j < borrowerElems.count(); ++j) {
+ readBorrower(borrowerElems.item(j).toElement());
+ }
+ } else if(n.localName() == Latin1Literal("filters")) {
+ QDomNodeList filterElems = n.toElement().elementsByTagNameNS(m_namespace, QString::fromLatin1("filter"));
+ for(uint j = 0; j < filterElems.count(); ++j) {
+ readFilter(filterElems.item(j).toElement());
+ }
+ }
+ }
+
+ // special for user, if using an older document format, add some nice new filters
+ if(syntaxVersion < 8) {
+ addDefaultFilters();
+ }
+
+ if(m_cancelled) {
+ m_coll = 0;
+ }
+}
+
+void TellicoImporter::readField(uint syntaxVersion_, const QDomElement& elem_) {
+ // special case: if the i18n attribute equals true, then translate the title, description, and category
+ bool isI18n = elem_.attribute(QString::fromLatin1("i18n")) == Latin1Literal("true");
+
+ QString name = elem_.attribute(QString::fromLatin1("name"), QString::fromLatin1("unknown"));
+ QString title = elem_.attribute(QString::fromLatin1("title"), i18n("Unknown"));
+ if(isI18n) {
+ title = i18n(title.utf8());
+ }
+
+ QString typeStr = elem_.attribute(QString::fromLatin1("type"), QString::number(Data::Field::Line));
+ Data::Field::Type type = static_cast<Data::Field::Type>(typeStr.toInt());
+
+ Data::FieldPtr field;
+ if(type == Data::Field::Choice) {
+ QStringList allowed = QStringList::split(QString::fromLatin1(";"),
+ elem_.attribute(QString::fromLatin1("allowed")));
+ if(isI18n) {
+ for(QStringList::Iterator it = allowed.begin(); it != allowed.end(); ++it) {
+ (*it) = i18n((*it).utf8());
+ }
+ }
+ field = new Data::Field(name, title, allowed);
+ } else {
+ field = new Data::Field(name, title, type);
+ }
+
+ if(elem_.hasAttribute(QString::fromLatin1("category"))) {
+ // at one point, the categories had keyboard accels
+ QString cat = elem_.attribute(QString::fromLatin1("category"));
+ if(syntaxVersion_ < 9 && cat.find('&') > -1) {
+ cat.remove('&');
+ }
+ if(isI18n) {
+ cat = i18n(cat.utf8());
+ }
+ field->setCategory(cat);
+ }
+
+ if(elem_.hasAttribute(QString::fromLatin1("flags"))) {
+ int flags = elem_.attribute(QString::fromLatin1("flags")).toInt();
+ // I also changed the enum values for syntax 3, but the only custom field
+ // would have been bibtex-id
+ if(syntaxVersion_ < 3 && field->name() == Latin1Literal("bibtex-id")) {
+ flags = 0;
+ }
+
+ // in syntax version 4, added a flag to disallow deleting attributes
+ // if it's a version before that and is the title, then add the flag
+ if(syntaxVersion_ < 4 && field->name() == Latin1Literal("title")) {
+ flags |= Data::Field::NoDelete;
+ }
+ field->setFlags(flags);
+ }
+
+ QString formatStr = elem_.attribute(QString::fromLatin1("format"), QString::number(Data::Field::FormatNone));
+ Data::Field::FormatFlag format = static_cast<Data::Field::FormatFlag>(formatStr.toInt());
+ field->setFormatFlag(format);
+
+ if(elem_.hasAttribute(QString::fromLatin1("description"))) {
+ QString desc = elem_.attribute(QString::fromLatin1("description"));
+ if(isI18n) {
+ desc = i18n(desc.utf8());
+ }
+ field->setDescription(desc);
+ }
+
+ if(syntaxVersion_ >= 5) {
+ QDomNodeList props = elem_.elementsByTagNameNS(m_namespace, QString::fromLatin1("prop"));
+ for(uint i = 0; i < props.count(); ++i) {
+ QDomElement e = props.item(i).toElement();
+ field->setProperty(e.attribute(QString::fromLatin1("name")), e.text());
+ }
+ // all track fields in music collections prior to version 9 get converted to three columns
+ if(syntaxVersion_ < 9) {
+ if(m_coll->type() == Data::Collection::Album && field->name() == Latin1Literal("track")) {
+ field->setProperty(QString::fromLatin1("columns"), QChar('3'));
+ field->setProperty(QString::fromLatin1("column1"), i18n("Title"));
+ field->setProperty(QString::fromLatin1("column2"), i18n("Artist"));
+ field->setProperty(QString::fromLatin1("column3"), i18n("Length"));
+ } else if(m_coll->type() == Data::Collection::Video && field->name() == Latin1Literal("cast")) {
+ field->setProperty(QString::fromLatin1("column1"), i18n("Actor/Actress"));
+ field->setProperty(QString::fromLatin1("column2"), i18n("Role"));
+ }
+ }
+ } else if(elem_.hasAttribute(QString::fromLatin1("bibtex-field"))) {
+ field->setProperty(QString::fromLatin1("bibtex"), elem_.attribute(QString::fromLatin1("bibtex-field")));
+ }
+
+ // Table2 is deprecated
+ if(field->type() == Data::Field::Table2) {
+ field->setType(Data::Field::Table);
+ field->setProperty(QString::fromLatin1("columns"), QChar('2'));
+ }
+ // for syntax 8, rating fields got their own type
+ if(syntaxVersion_ < 8) {
+ Data::Field::convertOldRating(field); // does all its own checking
+ }
+ m_coll->addField(field);
+// myDebug() << QString(" Added field: %1, %2").arg(field->name()).arg(field->title()) << endl;
+}
+
+void TellicoImporter::readEntry(uint syntaxVersion_, const QDomElement& entryElem_) {
+ const int id = entryElem_.attribute(QString::fromLatin1("id")).toInt();
+ Data::EntryPtr entry;
+ if(id > 0) {
+ entry = new Data::Entry(m_coll, id);
+ } else {
+ entry = new Data::Entry(m_coll);
+ }
+
+ bool oldMusic = (syntaxVersion_ < 9 && m_coll->type() == Data::Collection::Album);
+
+ // iterate over all field value children
+ for(QDomNode node = entryElem_.firstChild(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement elem = node.toElement();
+ if(elem.isNull()) {
+ continue;
+ }
+
+ bool isI18n = elem.attribute(QString::fromLatin1("i18n")) == Latin1Literal("true");
+
+ // Entry::setField checks to see if an field of 'name' is allowed
+ // in version 3 and prior, checkbox attributes had no text(), set it to "true" now
+ if(syntaxVersion_ < 4 && elem.text().isEmpty()) {
+ // "true" means checked
+ entry->setField(elem.localName(), QString::fromLatin1("true"));
+ continue;
+ }
+
+ QString name = elem.localName();
+ Data::FieldPtr f = m_coll->fieldByName(name);
+
+ // if the first child of the node is a text node, just set the attribute text
+ // otherwise, recurse over the node's children
+ // this is the case for <authors><author>..</author></authors>
+ // but if there's nothing but white space, then it's a BaseNode for some reason
+// if(node.firstChild().nodeType() == QDomNode::TextNode) {
+ if(f) {
+ // if it's a derived value, no field value is added
+ if(f->type() == Data::Field::Dependent) {
+ continue;
+ }
+
+ // special case for Date fields
+ if(f->type() == Data::Field::Date) {
+ if(elem.hasChildNodes()) {
+ QString value;
+ QDomNode yNode = elem.elementsByTagNameNS(m_namespace, QString::fromLatin1("year")).item(0);
+ if(!yNode.isNull()) {
+ value += yNode.toElement().text();
+ }
+ value += '-';
+ QDomNode mNode = elem.elementsByTagNameNS(m_namespace, QString::fromLatin1("month")).item(0);
+ if(!mNode.isNull()) {
+ value += mNode.toElement().text();
+ }
+ value += '-';
+ QDomNode dNode = elem.elementsByTagNameNS(m_namespace, QString::fromLatin1("day")).item(0);
+ if(!dNode.isNull()) {
+ value += dNode.toElement().text();
+ }
+ entry->setField(name, value);
+ } else {
+ // if no child nodes, the code will later assume the value to be the year
+ entry->setField(name, elem.text());
+ }
+ // go to next value in loop
+ continue;
+ }
+
+ // this may be a performance hit to be stripping white space all the time
+ // unfortunately, text() will include a carriage-return in cases like
+ // <value>
+ // text
+ // </value
+ // so we arbitrarily decide that only paragraphs get to have CRs?
+ QString value = elem.text();
+ if(f->type() != Data::Field::Para) {
+ value = value.stripWhiteSpace();
+ }
+
+ if(value.isEmpty()) {
+ continue;
+ }
+
+ if(f->type() == Data::Field::Image) {
+ // image info should have already been loaded
+ const Data::ImageInfo& info = ImageFactory::imageInfo(value);
+ // possible that value needs to be cleaned first in which case info is null
+ if(info.isNull() || !info.linkOnly) {
+ // for local files only, allow paths here
+ KURL u = KURL::fromPathOrURL(value);
+ if(u.isValid() && u.isLocalFile()) {
+ QString result = ImageFactory::addImage(u, false /* quiet */);
+ if(!result.isEmpty()) {
+ value = result;
+ }
+ }
+ value = Data::Image::idClean(value);
+ }
+ }
+
+ // in version 8, old rating fields get changed
+ if(syntaxVersion_ < 8 && f->type() == Data::Field::Rating) {
+ bool ok;
+ uint i = Tellico::toUInt(value, &ok);
+ if(ok) {
+ value = QString::number(i);
+ }
+ } else if(syntaxVersion_ < 2 && name == Latin1Literal("keywords")) {
+ // in version 2, "keywords" changed to "keyword"
+ name = QString::fromLatin1("keyword");
+ }
+ // special case: if the i18n attribute equals true, then translate the title, description, and category
+ if(isI18n) {
+ entry->setField(name, i18n(value.utf8()));
+ } else {
+ // special case for isbn fields, go ahead and validate
+ if(name == Latin1Literal("isbn")) {
+ const ISBNValidator val(0);
+ if(elem.attribute(QString::fromLatin1("validate")) != Latin1Literal("no")) {
+ val.fixup(value);
+ }
+ }
+ entry->setField(name, value);
+ }
+ } else { // if no field by the tag name, then it has children, iterate through them
+ // the field name has the final 's', so remove it
+ name.truncate(name.length() - 1);
+ f = m_coll->fieldByName(name);
+
+ // if it's a derived value, no field value is added
+ if(!f || f->type() == Data::Field::Dependent) {
+ continue;
+ }
+
+ const bool oldTracks = (oldMusic && name == Latin1Literal("track"));
+
+ QStringList values;
+ // concatenate values
+ for(QDomNode childNode = node.firstChild(); !childNode.isNull(); childNode = childNode.nextSibling()) {
+ QString value;
+ // don't worry about i18n here, Tables are never translated
+ QDomNodeList cols = childNode.toElement().elementsByTagNameNS(m_namespace, QString::fromLatin1("column"));
+ if(cols.count() > 0) {
+ for(uint i = 0; i < cols.count(); ++i) {
+ // special case for old tracks
+ if(oldTracks && i == 1) {
+ // if the second column holds the track length, bump it to next column
+ QRegExp rx(QString::fromLatin1("\\d+:\\d\\d"));
+ if(rx.exactMatch(cols.item(i).toElement().text())) {
+ value += entry->field(QString::fromLatin1("artist"));
+ value += QString::fromLatin1("::");
+ }
+ }
+ value += cols.item(i).toElement().text().stripWhiteSpace();
+ if(i < cols.count()-1) {
+ value += QString::fromLatin1("::");
+ } else if(oldTracks && cols.count() == 1) {
+ value += QString::fromLatin1("::");
+ value += entry->field(QString::fromLatin1("artist"));
+ }
+ }
+ values += value;
+ } else {
+ // really loose here, we don't even check that the element name
+ // is what we think it is
+ QString s = childNode.toElement().text().stripWhiteSpace();
+ if(isI18n && !s.isEmpty()) {
+ value += i18n(s.utf8());
+ } else {
+ value += s;
+ }
+ if(oldTracks) {
+ value += QString::fromLatin1("::");
+ value += entry->field(QString::fromLatin1("artist"));
+ }
+ if(values.findIndex(value) == -1) {
+ values += value;
+ }
+ }
+ }
+ entry->setField(name, values.join(QString::fromLatin1("; ")));
+ }
+ } // end field value loop
+
+ m_coll->addEntries(entry);
+}
+
+void TellicoImporter::readImage(const QDomElement& elem_, bool loadImage_) {
+ QString format = elem_.attribute(QString::fromLatin1("format"));
+ const bool link = elem_.attribute(QString::fromLatin1("link")) == Latin1Literal("true");
+ QString id = shareString(link ? elem_.attribute(QString::fromLatin1("id"))
+ : Data::Image::idClean(elem_.attribute(QString::fromLatin1("id"))));
+
+ bool readInfo = true;
+ if(loadImage_) {
+ QByteArray ba;
+ KCodecs::base64Decode(QCString(elem_.text().latin1()), ba);
+ if(!ba.isEmpty()) {
+ QString result = ImageFactory::addImage(ba, format, id);
+ if(result.isEmpty()) {
+ myDebug() << "TellicoImporter::readImage(XML) - null image for " << id << endl;
+ }
+ m_hasImages = true;
+ readInfo = false;
+ }
+ }
+ if(readInfo) {
+ // a width or height of 0 is ok here
+ int width = elem_.attribute(QString::fromLatin1("width")).toInt();
+ int height = elem_.attribute(QString::fromLatin1("height")).toInt();
+ Data::ImageInfo info(id, format.latin1(), width, height, link);
+ ImageFactory::cacheImageInfo(info);
+ }
+}
+
+void TellicoImporter::readFilter(const QDomElement& elem_) {
+ FilterPtr f = new Filter(Filter::MatchAny);
+ f->setName(elem_.attribute(QString::fromLatin1("name")));
+
+ QString match = elem_.attribute(QString::fromLatin1("match"));
+ if(match == Latin1Literal("all")) {
+ f->setMatch(Filter::MatchAll);
+ }
+
+ QDomNodeList rules = elem_.elementsByTagNameNS(m_namespace, QString::fromLatin1("rule"));
+ for(uint i = 0; i < rules.count(); ++i) {
+ QDomElement e = rules.item(i).toElement();
+ if(e.isNull()) {
+ continue;
+ }
+
+ QString field = e.attribute(QString::fromLatin1("field"));
+ // empty field means match any of them
+ QString pattern = e.attribute(QString::fromLatin1("pattern"));
+ // empty pattern is bad
+ if(pattern.isEmpty()) {
+ kdWarning() << "TellicoImporter::readFilter() - empty rule!" << endl;
+ continue;
+ }
+ QString function = e.attribute(QString::fromLatin1("function")).lower();
+ FilterRule::Function func;
+ if(function == Latin1Literal("contains")) {
+ func = FilterRule::FuncContains;
+ } else if(function == Latin1Literal("notcontains")) {
+ func = FilterRule::FuncNotContains;
+ } else if(function == Latin1Literal("equals")) {
+ func = FilterRule::FuncEquals;
+ } else if(function == Latin1Literal("notequals")) {
+ func = FilterRule::FuncNotEquals;
+ } else if(function == Latin1Literal("regexp")) {
+ func = FilterRule::FuncRegExp;
+ } else if(function == Latin1Literal("notregexp")) {
+ func = FilterRule::FuncNotRegExp;
+ } else {
+ kdWarning() << "TellicoImporter::readFilter() - invalid rule function: " << function << endl;
+ continue;
+ }
+ f->append(new FilterRule(field, pattern, func));
+ }
+
+ if(!f->isEmpty()) {
+ m_coll->addFilter(f);
+ }
+}
+
+void TellicoImporter::readBorrower(const QDomElement& elem_) {
+ QString name = elem_.attribute(QString::fromLatin1("name"));
+ QString uid = elem_.attribute(QString::fromLatin1("uid"));
+ Data::BorrowerPtr b = new Data::Borrower(name, uid);
+
+ QDomNodeList loans = elem_.elementsByTagNameNS(m_namespace, QString::fromLatin1("loan"));
+ for(uint i = 0; i < loans.count(); ++i) {
+ QDomElement e = loans.item(i).toElement();
+ if(e.isNull()) {
+ continue;
+ }
+ long id = e.attribute(QString::fromLatin1("entryRef")).toLong();
+ Data::EntryPtr entry = m_coll->entryById(id);
+ if(!entry) {
+ myDebug() << "TellicoImporter::readBorrower() - no entry with id = " << id << endl;
+ continue;
+ }
+ QString uid = e.attribute(QString::fromLatin1("uid"));
+ QDate loanDate, dueDate;
+ QString s = e.attribute(QString::fromLatin1("loanDate"));
+ if(!s.isEmpty()) {
+ loanDate = QDate::fromString(s, Qt::ISODate);
+ }
+ s = e.attribute(QString::fromLatin1("dueDate"));
+ if(!s.isEmpty()) {
+ dueDate = QDate::fromString(s, Qt::ISODate);
+ }
+ Data::LoanPtr loan = new Data::Loan(entry, loanDate, dueDate, e.text());
+ loan->setUID(uid);
+ b->addLoan(loan);
+ s = e.attribute(QString::fromLatin1("calendar"));
+ loan->setInCalendar(s == Latin1Literal("true"));
+ }
+ if(!b->isEmpty()) {
+ m_coll->addBorrower(b);
+ }
+}
+
+void TellicoImporter::loadZipData() {
+ delete m_buffer;
+ delete m_zip;
+ if(source() == URL) {
+ m_buffer = 0;
+ m_zip = new KZip(fileRef().fileName());
+ } else {
+ m_buffer = new QBuffer(data());
+ m_zip = new KZip(m_buffer);
+ }
+ if(!m_zip->open(IO_ReadOnly)) {
+ setStatusMessage(i18n(errorLoad).arg(url().fileName()));
+ m_format = Error;
+ delete m_zip;
+ m_zip = 0;
+ delete m_buffer;
+ m_buffer = 0;
+ return;
+ }
+
+ const KArchiveDirectory* dir = m_zip->directory();
+ if(!dir) {
+ QString str = i18n(errorLoad).arg(url().fileName()) + QChar('\n');
+ str += i18n("The file is empty.");
+ setStatusMessage(str);
+ m_format = Error;
+ m_zip->close();
+ delete m_zip;
+ m_zip = 0;
+ delete m_buffer;
+ m_buffer = 0;
+ return;
+ }
+
+ // main file was changed from bookcase.xml to tellico.xml as of version 0.13
+ const KArchiveEntry* entry = dir->entry(QString::fromLatin1("tellico.xml"));
+ if(!entry) {
+ entry = dir->entry(QString::fromLatin1("bookcase.xml"));
+ }
+ if(!entry || !entry->isFile()) {
+ QString str = i18n(errorLoad).arg(url().fileName()) + QChar('\n');
+ str += i18n("The file contains no collection data.");
+ setStatusMessage(str);
+ m_format = Error;
+ m_zip->close();
+ delete m_zip;
+ m_zip = 0;
+ delete m_buffer;
+ m_buffer = 0;
+ return;
+ }
+
+ const QByteArray xmlData = static_cast<const KArchiveFile*>(entry)->data();
+ loadXMLData(xmlData, false);
+ if(!m_coll) {
+ m_format = Error;
+ m_zip->close();
+ delete m_zip;
+ m_zip = 0;
+ delete m_buffer;
+ m_buffer = 0;
+ return;
+ }
+
+ if(m_cancelled) {
+ m_zip->close();
+ delete m_zip;
+ m_zip = 0;
+ delete m_buffer;
+ m_buffer = 0;
+ return;
+ }
+
+ const KArchiveEntry* imgDirEntry = dir->entry(QString::fromLatin1("images"));
+ if(!imgDirEntry || !imgDirEntry->isDirectory()) {
+ m_zip->close();
+ delete m_zip;
+ m_zip = 0;
+ delete m_buffer;
+ m_buffer = 0;
+ return;
+ }
+ m_imgDir = static_cast<const KArchiveDirectory*>(imgDirEntry);
+ m_images.clear();
+ m_images.add(m_imgDir->entries());
+ m_hasImages = !m_images.isEmpty();
+
+ // if all the images are not to be loaded, then we're done
+ if(!m_loadAllImages) {
+// myLog() << "TellicoImporter::loadZipData() - delayed loading for " << m_images.count() << " images" << endl;
+ return;
+ }
+
+ const QStringList images = static_cast<const KArchiveDirectory*>(imgDirEntry)->entries();
+ const uint stepSize = QMAX(s_stepSize, images.count()/100);
+
+ uint j = 0;
+ for(QStringList::ConstIterator it = images.begin(); !m_cancelled && it != images.end(); ++it, ++j) {
+ const KArchiveEntry* file = m_imgDir->entry(*it);
+ if(file && file->isFile()) {
+ ImageFactory::addImage(static_cast<const KArchiveFile*>(file)->data(),
+ (*it).section('.', -1).upper(), (*it));
+ m_images.remove(*it);
+ }
+ if(j%stepSize == 0) {
+ kapp->processEvents();
+ }
+ }
+
+ if(m_images.isEmpty()) {
+ // give it some time
+ QTimer::singleShot(3000, this, SLOT(deleteLater()));
+ }
+}
+
+bool TellicoImporter::loadImage(const QString& id_) {
+// myLog() << "TellicoImporter::loadImage() - id = " << id_ << endl;
+ if(m_format != Zip || !m_imgDir) {
+ return false;
+ }
+ const KArchiveEntry* file = m_imgDir->entry(id_);
+ if(!file || !file->isFile()) {
+ return false;
+ }
+ QString newID = ImageFactory::addImage(static_cast<const KArchiveFile*>(file)->data(),
+ id_.section('.', -1).upper(), id_);
+ m_images.remove(id_);
+ if(m_images.isEmpty()) {
+ // give it some time
+ QTimer::singleShot(3000, this, SLOT(deleteLater()));
+ }
+ return !newID.isEmpty();
+}
+
+// static
+bool TellicoImporter::loadAllImages(const KURL& url_) {
+ // only local files are allowed
+ if(url_.isEmpty() || !url_.isValid() || !url_.isLocalFile()) {
+// myDebug() << "TellicoImporter::loadAllImages() - returning" << endl;
+ return false;
+ }
+
+ // keep track of url for error reporting
+ static KURL u;
+
+ KZip zip(url_.path());
+ if(!zip.open(IO_ReadOnly)) {
+ if(u != url_) {
+ Kernel::self()->sorry(i18n(errorImageLoad).arg(url_.fileName()));
+ }
+ u = url_;
+ return false;
+ }
+
+ const KArchiveDirectory* dir = zip.directory();
+ if(!dir) {
+ if(u != url_) {
+ Kernel::self()->sorry(i18n(errorImageLoad).arg(url_.fileName()));
+ }
+ u = url_;
+ zip.close();
+ return false;
+ }
+
+ const KArchiveEntry* imgDirEntry = dir->entry(QString::fromLatin1("images"));
+ if(!imgDirEntry || !imgDirEntry->isDirectory()) {
+ zip.close();
+ return false;
+ }
+ const QStringList images = static_cast<const KArchiveDirectory*>(imgDirEntry)->entries();
+ for(QStringList::ConstIterator it = images.begin(); it != images.end(); ++it) {
+ const KArchiveEntry* file = static_cast<const KArchiveDirectory*>(imgDirEntry)->entry(*it);
+ if(file && file->isFile()) {
+ ImageFactory::addImage(static_cast<const KArchiveFile*>(file)->data(),
+ (*it).section('.', -1).upper(), (*it));
+ }
+ }
+ zip.close();
+ return true;
+}
+
+void TellicoImporter::addDefaultFilters() {
+ switch(m_coll->type()) {
+ case Data::Collection::Book:
+ if(m_coll->hasField(QString::fromLatin1("read"))) {
+ FilterPtr f = new Filter(Filter::MatchAny);
+ f->setName(i18n("Unread Books"));
+ f->append(new FilterRule(QString::fromLatin1("read"), QString::fromLatin1("true"), FilterRule::FuncNotContains));
+ m_coll->addFilter(f);
+ m_modified = true;
+ }
+ break;
+
+ case Data::Collection::Video:
+ if(m_coll->hasField(QString::fromLatin1("year"))) {
+ FilterPtr f = new Filter(Filter::MatchAny);
+ f->setName(i18n("Old Movies"));
+ // old movies from before 1960
+ f->append(new FilterRule(QString::fromLatin1("year"), QString::fromLatin1("19[012345]\\d"), FilterRule::FuncRegExp));
+ m_coll->addFilter(f);
+ m_modified = true;
+ }
+ if(m_coll->hasField(QString::fromLatin1("widescreen"))) {
+ FilterPtr f = new Filter(Filter::MatchAny);
+ f->setName(i18n("Widescreen"));
+ f->append(new FilterRule(QString::fromLatin1("widescreen"), QString::fromLatin1("true"), FilterRule::FuncContains));
+ m_coll->addFilter(f);
+ m_modified = true;
+ }
+ break;
+
+ case Data::Collection::Album:
+ if(m_coll->hasField(QString::fromLatin1("year"))) {
+ FilterPtr f = new Filter(Filter::MatchAny);
+ f->setName(i18n("80's Music"));
+ f->append(new FilterRule(QString::fromLatin1("year"), QString::fromLatin1("198\\d"),FilterRule::FuncRegExp));
+ m_coll->addFilter(f);
+ m_modified = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ if(m_coll->hasField(QString::fromLatin1("rating"))) {
+ FilterPtr filter = new Filter(Filter::MatchAny);
+ filter->setName(i18n("Favorites"));
+ // check all the numbers, and use top 20% or so
+ Data::FieldPtr field = m_coll->fieldByName(QString::fromLatin1("rating"));
+ bool ok;
+ uint min = Tellico::toUInt(field->property(QString::fromLatin1("minimum")), &ok);
+ if(!ok) {
+ min = 1;
+ }
+ uint max = Tellico::toUInt(field->property(QString::fromLatin1("maximum")), &ok);
+ if(!ok) {
+ min = 5;
+ }
+ for(uint i = QMAX(min, static_cast<uint>(0.8*(max-min+1))); i <= max; ++i) {
+ filter->append(new FilterRule(QString::fromLatin1("rating"), QString::number(i), FilterRule::FuncContains));
+ }
+ if(!filter->isEmpty()) {
+ m_coll->addFilter(filter);
+ m_modified = true;
+ }
+ }
+}
+
+void TellicoImporter::slotCancel() {
+ m_cancelled = true;
+ m_format = Cancel;
+}
+
+#include "tellicoimporter.moc"
diff --git a/src/translators/tellicoimporter.h b/src/translators/tellicoimporter.h
new file mode 100644
index 0000000..d4c6e13
--- /dev/null
+++ b/src/translators/tellicoimporter.h
@@ -0,0 +1,100 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_IMPORTER_H
+#define TELLICO_IMPORTER_H
+
+class QBuffer;
+class KZip;
+class KArchiveDirectory;
+
+#include "dataimporter.h"
+#include "../datavectors.h"
+#include "../stringset.h"
+
+class QDomElement;
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ * Reading the @ref Tellico data files is done by the TellicoImporter.
+ *
+ * @author Robby Stephenson
+ */
+class TellicoImporter : public DataImporter {
+Q_OBJECT
+
+public:
+ enum Format { Unknown, Error, XML, Zip, Cancel };
+
+ /**
+ * @param url The tellico data file.
+ */
+ TellicoImporter(const KURL& url, bool loadAllImages=true);
+ /**
+ * Constructor used to convert arbitrary text to a @ref Collection
+ *
+ * @param text The text
+ */
+ TellicoImporter(const QString& text);
+ virtual ~TellicoImporter();
+
+ /**
+ * sometimes, a new document format might add data
+ */
+ bool modifiedOriginal() const { return m_modified; }
+
+ /**
+ */
+ virtual Data::CollPtr collection();
+ Format format() const { return m_format; }
+
+ bool hasImages() const { return m_hasImages; }
+ bool loadImage(const QString& id_);
+
+ static bool loadAllImages(const KURL& url);
+
+public slots:
+ void slotCancel();
+
+private:
+ static bool versionConversion(uint from, uint to);
+
+ void loadXMLData(const QByteArray& data, bool loadImages);
+ void loadZipData();
+
+ void readField(uint syntaxVersion, const QDomElement& elem);
+ void readEntry(uint syntaxVersion, const QDomElement& elem);
+ void readImage(const QDomElement& elem, bool loadImage);
+ void readFilter(const QDomElement& elem);
+ void readBorrower(const QDomElement& elem);
+ void addDefaultFilters();
+
+ Data::CollPtr m_coll;
+ bool m_loadAllImages;
+ QString m_namespace;
+ Format m_format;
+ bool m_modified : 1;
+ bool m_cancelled : 1;
+ bool m_hasImages : 1;
+ StringSet m_images;
+
+ QBuffer* m_buffer;
+ KZip* m_zip;
+ const KArchiveDirectory* m_imgDir;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/tellicoxmlexporter.cpp b/src/translators/tellicoxmlexporter.cpp
new file mode 100644
index 0000000..6335ed1
--- /dev/null
+++ b/src/translators/tellicoxmlexporter.cpp
@@ -0,0 +1,505 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "tellicoxmlexporter.h"
+#include "../collections/bibtexcollection.h"
+#include "../imagefactory.h"
+#include "../image.h"
+#include "../controller.h" // needed for getting groupView pointer
+#include "../entryitem.h"
+#include "../latin1literal.h"
+#include "../filehandler.h"
+#include "../groupiterator.h"
+#include "../tellico_utils.h"
+#include "../tellico_kernel.h"
+#include "../tellico_debug.h"
+#include "tellico_xml.h"
+#include "../document.h" // needed for sorting groups
+#include "../translators/bibtexhandler.h" // needed for cleaning text
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kmdcodec.h>
+#include <kglobal.h>
+#include <kcalendarsystem.h>
+
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qcheckbox.h>
+#include <qwhatsthis.h>
+#include <qdom.h>
+#include <qtextcodec.h>
+
+using Tellico::Export::TellicoXMLExporter;
+
+TellicoXMLExporter::TellicoXMLExporter() : Exporter(),
+ m_includeImages(false), m_includeGroups(false), m_widget(0) {
+ setOptions(options() | Export::ExportImages | Export::ExportImageSize); // not included by default
+}
+
+TellicoXMLExporter::TellicoXMLExporter(Data::CollPtr coll) : Exporter(coll),
+ m_includeImages(false), m_includeGroups(false), m_widget(0) {
+ setOptions(options() | Export::ExportImages | Export::ExportImageSize); // not included by default
+}
+
+QString TellicoXMLExporter::formatString() const {
+ return i18n("XML");
+}
+
+QString TellicoXMLExporter::fileFilter() const {
+ return i18n("*.xml|XML Files (*.xml)") + QChar('\n') + i18n("*|All Files");
+}
+
+bool TellicoXMLExporter::exec() {
+ QDomDocument doc = exportXML();
+ if(doc.isNull()) {
+ return false;
+ }
+ return FileHandler::writeTextURL(url(), doc.toString(),
+ options() & ExportUTF8,
+ options() & Export::ExportForce);
+}
+
+QDomDocument TellicoXMLExporter::exportXML() const {
+ // don't be hard on people with older versions. The only difference with DTD 10 was adding
+ // a board game collection, so use 9 still unless it's a board game
+ int exportVersion = (XML::syntaxVersion == 10 && collection()->type() != Data::Collection::BoardGame)
+ ? 9
+ : XML::syntaxVersion;
+
+ QDomImplementation impl;
+ QDomDocumentType doctype = impl.createDocumentType(QString::fromLatin1("tellico"),
+ XML::pubTellico(exportVersion),
+ XML::dtdTellico(exportVersion));
+ //default namespace
+ const QString& ns = XML::nsTellico;
+
+ QDomDocument dom = impl.createDocument(ns, QString::fromLatin1("tellico"), doctype);
+
+ // root tellico element
+ QDomElement root = dom.documentElement();
+
+ QString encodeStr = QString::fromLatin1("version=\"1.0\" encoding=\"");
+ if(options() & Export::ExportUTF8) {
+ encodeStr += QString::fromLatin1("UTF-8");
+ } else {
+ encodeStr += QString::fromLatin1(QTextCodec::codecForLocale()->mimeName());
+ }
+ encodeStr += QChar('"');
+
+ // createDocument creates a root node, insert the processing instruction before it
+ dom.insertBefore(dom.createProcessingInstruction(QString::fromLatin1("xml"), encodeStr), root);
+
+ root.setAttribute(QString::fromLatin1("syntaxVersion"), exportVersion);
+
+ exportCollectionXML(dom, root, options() & Export::ExportFormatted);
+
+ // clear image list
+ m_images.clear();
+
+ return dom;
+}
+
+QString TellicoXMLExporter::exportXMLString() const {
+ return exportXML().toString();
+}
+
+void TellicoXMLExporter::exportCollectionXML(QDomDocument& dom_, QDomElement& parent_, bool format_) const {
+ Data::CollPtr coll = collection();
+ if(!coll) {
+ kdWarning() << "TellicoXMLExporter::exportCollectionXML() - no collection pointer!" << endl;
+ return;
+ }
+
+ QDomElement collElem = dom_.createElement(QString::fromLatin1("collection"));
+ collElem.setAttribute(QString::fromLatin1("type"), coll->type());
+ collElem.setAttribute(QString::fromLatin1("title"), coll->title());
+
+ QDomElement fieldsElem = dom_.createElement(QString::fromLatin1("fields"));
+ collElem.appendChild(fieldsElem);
+
+ Data::FieldVec fields = coll->fields();
+ for(Data::FieldVec::Iterator fIt = fields.begin(); fIt != fields.end(); ++fIt) {
+ exportFieldXML(dom_, fieldsElem, fIt);
+ }
+
+ if(coll->type() == Data::Collection::Bibtex) {
+ const Data::BibtexCollection* c = static_cast<const Data::BibtexCollection*>(coll.data());
+ if(!c->preamble().isEmpty()) {
+ QDomElement preElem = dom_.createElement(QString::fromLatin1("bibtex-preamble"));
+ preElem.appendChild(dom_.createTextNode(c->preamble()));
+ collElem.appendChild(preElem);
+ }
+
+ QDomElement macrosElem = dom_.createElement(QString::fromLatin1("macros"));
+ for(StringMap::ConstIterator macroIt = c->macroList().constBegin(); macroIt != c->macroList().constEnd(); ++macroIt) {
+ if(!macroIt.data().isEmpty()) {
+ QDomElement macroElem = dom_.createElement(QString::fromLatin1("macro"));
+ macroElem.setAttribute(QString::fromLatin1("name"), macroIt.key());
+ macroElem.appendChild(dom_.createTextNode(macroIt.data()));
+ macrosElem.appendChild(macroElem);
+ }
+ }
+ if(macrosElem.childNodes().count() > 0) {
+ collElem.appendChild(macrosElem);
+ }
+ }
+
+ Data::EntryVec evec = entries();
+ for(Data::EntryVec::Iterator entry = evec.begin(); entry != evec.end(); ++entry) {
+ exportEntryXML(dom_, collElem, entry, format_);
+ }
+
+ if(!m_images.isEmpty() && (options() & Export::ExportImages)) {
+ QDomElement imgsElem = dom_.createElement(QString::fromLatin1("images"));
+ collElem.appendChild(imgsElem);
+ const QStringList imageIds = m_images.toList();
+ for(QStringList::ConstIterator it = imageIds.begin(); it != imageIds.end(); ++it) {
+ exportImageXML(dom_, imgsElem, *it);
+ }
+ }
+
+ if(m_includeGroups) {
+ exportGroupXML(dom_, collElem);
+ }
+
+ parent_.appendChild(collElem);
+
+ // the borrowers and filters are in the tellico object, not the collection
+ if(options() & Export::ExportComplete) {
+ QDomElement bElem = dom_.createElement(QString::fromLatin1("borrowers"));
+ Data::BorrowerVec borrowers = coll->borrowers();
+ for(Data::BorrowerVec::Iterator bIt = borrowers.begin(); bIt != borrowers.end(); ++bIt) {
+ exportBorrowerXML(dom_, bElem, bIt);
+ }
+ if(bElem.hasChildNodes()) {
+ parent_.appendChild(bElem);
+ }
+
+ QDomElement fElem = dom_.createElement(QString::fromLatin1("filters"));
+ FilterVec filters = coll->filters();
+ for(FilterVec::Iterator fIt = filters.begin(); fIt != filters.end(); ++fIt) {
+ exportFilterXML(dom_, fElem, fIt);
+ }
+ if(fElem.hasChildNodes()) {
+ parent_.appendChild(fElem);
+ }
+ }
+}
+
+void TellicoXMLExporter::exportFieldXML(QDomDocument& dom_, QDomElement& parent_, Data::FieldPtr field_) const {
+ QDomElement elem = dom_.createElement(QString::fromLatin1("field"));
+
+ elem.setAttribute(QString::fromLatin1("name"), field_->name());
+ elem.setAttribute(QString::fromLatin1("title"), field_->title());
+ elem.setAttribute(QString::fromLatin1("category"), field_->category());
+ elem.setAttribute(QString::fromLatin1("type"), field_->type());
+ elem.setAttribute(QString::fromLatin1("flags"), field_->flags());
+ elem.setAttribute(QString::fromLatin1("format"), field_->formatFlag());
+
+ if(field_->type() == Data::Field::Choice) {
+ elem.setAttribute(QString::fromLatin1("allowed"), field_->allowed().join(QString::fromLatin1(";")));
+ }
+
+ // only save description if it's not equal to title, which is the default
+ // title is never empty, so this indirectly checks for empty descriptions
+ if(field_->description() != field_->title()) {
+ elem.setAttribute(QString::fromLatin1("description"), field_->description());
+ }
+
+ for(StringMap::ConstIterator it = field_->propertyList().begin(); it != field_->propertyList().end(); ++it) {
+ if(it.data().isEmpty()) {
+ continue;
+ }
+ QDomElement e = dom_.createElement(QString::fromLatin1("prop"));
+ e.setAttribute(QString::fromLatin1("name"), it.key());
+ e.appendChild(dom_.createTextNode(it.data()));
+ elem.appendChild(e);
+ }
+
+ parent_.appendChild(elem);
+}
+
+void TellicoXMLExporter::exportEntryXML(QDomDocument& dom_, QDomElement& parent_, Data::EntryPtr entry_, bool format_) const {
+ QDomElement entryElem = dom_.createElement(QString::fromLatin1("entry"));
+ entryElem.setAttribute(QString::fromLatin1("id"), entry_->id());
+
+ // iterate through every field for the entry
+ Data::FieldVec fields = entry_->collection()->fields();
+ for(Data::FieldVec::Iterator fIt = fields.begin(); fIt != fields.end(); ++fIt) {
+ QString fieldName = fIt->name();
+
+ // Date fields are special, don't format in export
+ QString fieldValue = (format_ && fIt->type() != Data::Field::Date) ? entry_->formattedField(fieldName)
+ : entry_->field(fieldName);
+ if(options() & ExportClean) {
+ BibtexHandler::cleanText(fieldValue);
+ }
+
+ // if empty, then no field element is added and just continue
+ if(fieldValue.isEmpty()) {
+ continue;
+ }
+
+ // optionally, verify images exist
+ if(fIt->type() == Data::Field::Image && (options() & Export::ExportVerifyImages)) {
+ if(!ImageFactory::validImage(fieldValue)) {
+ myDebug() << "TellicoXMLExporter::exportEntryXML() - entry: " << entry_->title() << endl;
+ myDebug() << "TellicoXMLExporter::exportEntryXML() - skipping image: " << fieldValue << endl;
+ continue;
+ }
+ }
+
+ // if multiple versions are allowed, split them into separate elements
+ if(fIt->flags() & Data::Field::AllowMultiple) {
+ // parent element if field contains multiple values, child of entryElem
+ // who cares about grammar, just add an 's' to the name
+ QDomElement parElem = dom_.createElement(fieldName + 's');
+ entryElem.appendChild(parElem);
+
+ // the space after the semi-colon is enforced when the field is set for the entry
+ QStringList fields = QStringList::split(QString::fromLatin1("; "), fieldValue, true);
+ for(QStringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) {
+ // element for field value, child of either entryElem or ParentElem
+ QDomElement fieldElem = dom_.createElement(fieldName);
+ // special case for multi-column tables
+ int ncols = 0;
+ if(fIt->type() == Data::Field::Table) {
+ bool ok;
+ ncols = Tellico::toUInt(fIt->property(QString::fromLatin1("columns")), &ok);
+ if(!ok) {
+ ncols = 1;
+ }
+ }
+ if(ncols > 1) {
+ for(int col = 0; col < ncols; ++col) {
+ QDomElement elem;
+ elem = dom_.createElement(QString::fromLatin1("column"));
+ elem.appendChild(dom_.createTextNode((*it).section(QString::fromLatin1("::"), col, col)));
+ fieldElem.appendChild(elem);
+ }
+ } else {
+ fieldElem.appendChild(dom_.createTextNode(*it));
+ }
+ parElem.appendChild(fieldElem);
+ }
+ } else {
+ QDomElement fieldElem = dom_.createElement(fieldName);
+ entryElem.appendChild(fieldElem);
+ // Date fields get special treatment
+ if(fIt->type() == Data::Field::Date) {
+ fieldElem.setAttribute(QString::fromLatin1("calendar"), KGlobal::locale()->calendar()->calendarName());
+ QStringList s = QStringList::split('-', fieldValue, true);
+ if(s.count() > 0 && !s[0].isEmpty()) {
+ QDomElement e = dom_.createElement(QString::fromLatin1("year"));
+ fieldElem.appendChild(e);
+ e.appendChild(dom_.createTextNode(s[0]));
+ }
+ if(s.count() > 1 && !s[1].isEmpty()) {
+ QDomElement e = dom_.createElement(QString::fromLatin1("month"));
+ fieldElem.appendChild(e);
+ e.appendChild(dom_.createTextNode(s[1]));
+ }
+ if(s.count() > 2 && !s[2].isEmpty()) {
+ QDomElement e = dom_.createElement(QString::fromLatin1("day"));
+ fieldElem.appendChild(e);
+ e.appendChild(dom_.createTextNode(s[2]));
+ }
+ } else if(fIt->type() == Data::Field::URL &&
+ fIt->property(QString::fromLatin1("relative")) == Latin1Literal("true") &&
+ !url().isEmpty()) {
+ // if a relative URL and url() is not empty, change the value!
+ KURL old_url(Kernel::self()->URL(), fieldValue);
+ fieldElem.appendChild(dom_.createTextNode(KURL::relativeURL(url(), old_url)));
+ } else {
+ fieldElem.appendChild(dom_.createTextNode(fieldValue));
+ }
+ }
+
+ if(fIt->type() == Data::Field::Image) {
+ // possible to have more than one entry with the same image
+ // only want to include it in the output xml once
+ m_images.add(fieldValue);
+ }
+ } // end field loop
+
+ parent_.appendChild(entryElem);
+}
+
+void TellicoXMLExporter::exportImageXML(QDomDocument& dom_, QDomElement& parent_, const QString& id_) const {
+ if(id_.isEmpty()) {
+ myDebug() << "TellicoXMLExporter::exportImageXML() - empty image!" << endl;
+ return;
+ }
+// myLog() << "TellicoXMLExporter::exportImageXML() - id = " << id_ << endl;
+
+ QDomElement imgElem = dom_.createElement(QString::fromLatin1("image"));
+ if(m_includeImages) {
+ const Data::Image& img = ImageFactory::imageById(id_);
+ if(img.isNull()) {
+ myDebug() << "TellicoXMLExporter::exportImageXML() - null image - " << id_ << endl;
+ return;
+ }
+ imgElem.setAttribute(QString::fromLatin1("format"), img.format());
+ imgElem.setAttribute(QString::fromLatin1("id"), img.id());
+ imgElem.setAttribute(QString::fromLatin1("width"), img.width());
+ imgElem.setAttribute(QString::fromLatin1("height"), img.height());
+ if(img.linkOnly()) {
+ imgElem.setAttribute(QString::fromLatin1("link"), QString::fromLatin1("true"));
+ }
+ QCString imgText = KCodecs::base64Encode(img.byteArray());
+ imgElem.appendChild(dom_.createTextNode(QString::fromLatin1(imgText)));
+ } else {
+ const Data::ImageInfo& info = ImageFactory::imageInfo(id_);
+ if(info.isNull()) {
+ return;
+ }
+ imgElem.setAttribute(QString::fromLatin1("format"), info.format);
+ imgElem.setAttribute(QString::fromLatin1("id"), info.id);
+ // only load the images to read the size if necessary
+ const bool loadImageIfNecessary = options() & Export::ExportImageSize;
+ imgElem.setAttribute(QString::fromLatin1("width"), info.width(loadImageIfNecessary));
+ imgElem.setAttribute(QString::fromLatin1("height"), info.height(loadImageIfNecessary));
+ if(info.linkOnly) {
+ imgElem.setAttribute(QString::fromLatin1("link"), QString::fromLatin1("true"));
+ }
+ }
+ parent_.appendChild(imgElem);
+}
+
+void TellicoXMLExporter::exportGroupXML(QDomDocument& dom_, QDomElement& parent_) const {
+ Data::EntryVec vec = entries(); // need a copy for ::contains();
+ bool exportAll = collection()->entries().count() == vec.count();
+ // iterate over each group, which are the first children
+ for(GroupIterator gIt = Controller::self()->groupIterator(); gIt.group(); ++gIt) {
+ if(gIt.group()->isEmpty()) {
+ continue;
+ }
+ QDomElement groupElem = dom_.createElement(QString::fromLatin1("group"));
+ groupElem.setAttribute(QString::fromLatin1("title"), gIt.group()->groupName());
+ // now iterate over all entry items in the group
+ Data::EntryVec sorted = Data::Document::self()->sortEntries(*gIt.group());
+ for(Data::EntryVec::Iterator eIt = sorted.begin(); eIt != sorted.end(); ++eIt) {
+ if(!exportAll && !vec.contains(eIt)) {
+ continue;
+ }
+ QDomElement entryRefElem = dom_.createElement(QString::fromLatin1("entryRef"));
+ entryRefElem.setAttribute(QString::fromLatin1("id"), eIt->id());
+ groupElem.appendChild(entryRefElem);
+ }
+ if(groupElem.hasChildNodes()) {
+ parent_.appendChild(groupElem);
+ }
+ }
+}
+
+void TellicoXMLExporter::exportFilterXML(QDomDocument& dom_, QDomElement& parent_, FilterPtr filter_) const {
+ QDomElement filterElem = dom_.createElement(QString::fromLatin1("filter"));
+ filterElem.setAttribute(QString::fromLatin1("name"), filter_->name());
+
+ QString match = (filter_->op() == Filter::MatchAll) ? QString::fromLatin1("all") : QString::fromLatin1("any");
+ filterElem.setAttribute(QString::fromLatin1("match"), match);
+
+ for(QPtrListIterator<FilterRule> it(*filter_); it.current(); ++it) {
+ QDomElement ruleElem = dom_.createElement(QString::fromLatin1("rule"));
+ ruleElem.setAttribute(QString::fromLatin1("field"), it.current()->fieldName());
+ ruleElem.setAttribute(QString::fromLatin1("pattern"), it.current()->pattern());
+ switch(it.current()->function()) {
+ case FilterRule::FuncContains:
+ ruleElem.setAttribute(QString::fromLatin1("function"), QString::fromLatin1("contains"));
+ break;
+ case FilterRule::FuncNotContains:
+ ruleElem.setAttribute(QString::fromLatin1("function"), QString::fromLatin1("notcontains"));
+ break;
+ case FilterRule::FuncEquals:
+ ruleElem.setAttribute(QString::fromLatin1("function"), QString::fromLatin1("equals"));
+ break;
+ case FilterRule::FuncNotEquals:
+ ruleElem.setAttribute(QString::fromLatin1("function"), QString::fromLatin1("notequals"));
+ break;
+ case FilterRule::FuncRegExp:
+ ruleElem.setAttribute(QString::fromLatin1("function"), QString::fromLatin1("regexp"));
+ break;
+ case FilterRule::FuncNotRegExp:
+ ruleElem.setAttribute(QString::fromLatin1("function"), QString::fromLatin1("notregexp"));
+ break;
+ default:
+ kdWarning() << "TellicoXMLExporter::exportFilterXML() - no matching rule function!" << endl;
+ }
+ filterElem.appendChild(ruleElem);
+ }
+
+ parent_.appendChild(filterElem);
+}
+
+void TellicoXMLExporter::exportBorrowerXML(QDomDocument& dom_, QDomElement& parent_,
+ Data::BorrowerPtr borrower_) const {
+ if(borrower_->isEmpty()) {
+ return;
+ }
+
+ QDomElement bElem = dom_.createElement(QString::fromLatin1("borrower"));
+ parent_.appendChild(bElem);
+
+ bElem.setAttribute(QString::fromLatin1("name"), borrower_->name());
+ bElem.setAttribute(QString::fromLatin1("uid"), borrower_->uid());
+
+ const Data::LoanVec& loans = borrower_->loans();
+ for(Data::LoanVec::ConstIterator it = loans.constBegin(); it != loans.constEnd(); ++it) {
+ QDomElement lElem = dom_.createElement(QString::fromLatin1("loan"));
+ bElem.appendChild(lElem);
+
+ lElem.setAttribute(QString::fromLatin1("uid"), it->uid());
+ lElem.setAttribute(QString::fromLatin1("entryRef"), it->entry()->id());
+ lElem.setAttribute(QString::fromLatin1("loanDate"), it->loanDate().toString(Qt::ISODate));
+ lElem.setAttribute(QString::fromLatin1("dueDate"), it->dueDate().toString(Qt::ISODate));
+ if(it->inCalendar()) {
+ lElem.setAttribute(QString::fromLatin1("calendar"), QString::fromLatin1("true"));
+ }
+
+ lElem.appendChild(dom_.createTextNode(it->note()));
+ }
+}
+
+QWidget* TellicoXMLExporter::widget(QWidget* parent_, const char* name_/*=0*/) {
+ if(m_widget && m_widget->parent() == parent_) {
+ return m_widget;
+ }
+
+ m_widget = new QWidget(parent_, name_);
+ QVBoxLayout* l = new QVBoxLayout(m_widget);
+
+ QGroupBox* box = new QGroupBox(1, Qt::Horizontal, i18n("Tellico XML Options"), m_widget);
+ l->addWidget(box);
+
+ m_checkIncludeImages = new QCheckBox(i18n("Include images in XML document"), box);
+ m_checkIncludeImages->setChecked(m_includeImages);
+ QWhatsThis::add(m_checkIncludeImages, i18n("If checked, the images in the document will be included "
+ "in the XML stream as base64 encoded elements."));
+
+ return m_widget;
+}
+
+void TellicoXMLExporter::readOptions(KConfig* config_) {
+ KConfigGroup group(config_, QString::fromLatin1("ExportOptions - %1").arg(formatString()));
+ m_includeImages = group.readBoolEntry("Include Images", m_includeImages);
+}
+
+void TellicoXMLExporter::saveOptions(KConfig* config_) {
+ m_includeImages = m_checkIncludeImages->isChecked();
+
+ KConfigGroup group(config_, QString::fromLatin1("ExportOptions - %1").arg(formatString()));
+ group.writeEntry("Include Images", m_includeImages);
+}
+
+#include "tellicoxmlexporter.moc"
diff --git a/src/translators/tellicoxmlexporter.h b/src/translators/tellicoxmlexporter.h
new file mode 100644
index 0000000..705c2dc
--- /dev/null
+++ b/src/translators/tellicoxmlexporter.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICOXMLEXPORTER_H
+#define TELLICOXMLEXPORTER_H
+
+namespace Tellico {
+ class Filter;
+}
+
+class QDomDocument;
+class QDomElement;
+class QCheckBox;
+
+#include "exporter.h"
+#include "../stringset.h"
+
+namespace Tellico {
+ namespace Export {
+
+/**
+ * @author Robby Stephenson
+ */
+class TellicoXMLExporter : public Exporter {
+Q_OBJECT
+
+public:
+ TellicoXMLExporter();
+ TellicoXMLExporter(Data::CollPtr coll);
+
+ virtual bool exec();
+ virtual QString formatString() const;
+ virtual QString fileFilter() const;
+
+ QDomDocument exportXML() const;
+ QString exportXMLString() const;
+
+ void setIncludeImages(bool b) { m_includeImages = b; }
+ void setIncludeGroups(bool b) { m_includeGroups = b; }
+
+ virtual QWidget* widget(QWidget*, const char*);
+ virtual void readOptions(KConfig* cfg);
+ virtual void saveOptions(KConfig* cfg);
+
+ /**
+ * An integer indicating format version.
+ */
+ static const unsigned syntaxVersion;
+
+private:
+ void exportCollectionXML(QDomDocument& doc, QDomElement& parent, bool format) const;
+ void exportFieldXML(QDomDocument& doc, QDomElement& parent, Data::FieldPtr field) const;
+ void exportEntryXML(QDomDocument& doc, QDomElement& parent, Data::EntryPtr entry, bool format) const;
+ void exportImageXML(QDomDocument& doc, QDomElement& parent, const QString& imageID) const;
+ void exportGroupXML(QDomDocument& doc, QDomElement& parent) const;
+ void exportFilterXML(QDomDocument& doc, QDomElement& parent, FilterPtr filter) const;
+ void exportBorrowerXML(QDomDocument& doc, QDomElement& parent, Data::BorrowerPtr borrower) const;
+
+ // keep track of which images were written, since some entries could have same image
+ mutable StringSet m_images;
+ bool m_includeImages : 1;
+ bool m_includeGroups : 1;
+
+ QWidget* m_widget;
+ QCheckBox* m_checkIncludeImages;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/tellicozipexporter.cpp b/src/translators/tellicozipexporter.cpp
new file mode 100644
index 0000000..42e0e70
--- /dev/null
+++ b/src/translators/tellicozipexporter.cpp
@@ -0,0 +1,133 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "tellicozipexporter.h"
+#include "tellicoxmlexporter.h"
+#include "../collection.h"
+#include "../imagefactory.h"
+#include "../image.h"
+#include "../filehandler.h"
+#include "../stringset.h"
+#include "../tellico_debug.h"
+#include "../progressmanager.h"
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kzip.h>
+#include <kapplication.h>
+
+#include <qdom.h>
+#include <qbuffer.h>
+
+using Tellico::Export::TellicoZipExporter;
+
+QString TellicoZipExporter::formatString() const {
+ return i18n("Tellico Zip File");
+}
+
+QString TellicoZipExporter::fileFilter() const {
+ return i18n("*.tc *.bc|Tellico Files (*.tc)") + QChar('\n') + i18n("*|All Files");
+}
+
+bool TellicoZipExporter::exec() {
+ m_cancelled = false;
+ Data::CollPtr coll = collection();
+ if(!coll) {
+ return false;
+ }
+
+ // TODO: maybe need label?
+ ProgressItem& item = ProgressManager::self()->newProgressItem(this, QString::null, true);
+ item.setTotalSteps(100);
+ connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
+ ProgressItem::Done done(this);
+
+ TellicoXMLExporter exp;
+ exp.setEntries(entries());
+ exp.setURL(url()); // needed in case of relative URL values
+ long opt = options();
+ opt |= Export::ExportUTF8; // always export to UTF-8
+ opt |= Export::ExportImages; // always list the images in the xml
+ opt &= ~Export::ExportProgress; // don't show progress for xml export
+ exp.setOptions(opt);
+ exp.setIncludeImages(false); // do not include the images themselves in XML
+ QCString xml = exp.exportXML().toCString(); // encoded in utf-8
+ ProgressManager::self()->setProgress(this, 5);
+
+ QByteArray data;
+ QBuffer buf(data);
+
+ if(m_cancelled) {
+ return true; // intentionally cancelled
+ }
+
+ KZip zip(&buf);
+ zip.open(IO_WriteOnly);
+ zip.writeFile(QString::fromLatin1("tellico.xml"), QString::null, QString::null, xml.length(), xml);
+
+ if(m_includeImages) {
+ ProgressManager::self()->setProgress(this, 10);
+ // gonna be lazy and just increment progress every 3 images
+ // it might be less, might be more
+ uint j = 0;
+ const QString imagesDir = QString::fromLatin1("images/");
+ StringSet imageSet;
+ Data::FieldVec imageFields = coll->imageFields();
+ // already took 10%, only 90% left
+ const uint stepSize = QMAX(1, (coll->entryCount() * imageFields.count()) / 90);
+ for(Data::EntryVec::ConstIterator it = entries().begin(); it != entries().end() && !m_cancelled; ++it) {
+ for(Data::FieldVec::Iterator fIt = imageFields.begin(); fIt != imageFields.end(); ++fIt, ++j) {
+ const QString id = it->field(fIt);
+ if(id.isEmpty() || imageSet.has(id)) {
+ continue;
+ }
+ const Data::ImageInfo& info = ImageFactory::imageInfo(id);
+ if(info.linkOnly) {
+ myLog() << "TellicoZipExporter::exec() - not copying linked image: " << id << endl;
+ continue;
+ }
+ const Data::Image& img = ImageFactory::imageById(id);
+ // if no image, continue
+ if(img.isNull()) {
+ kdWarning() << "TellicoZipExporter::exec() - no image found for " << fIt->title() << " field" << endl;
+ kdWarning() << "...for the entry titled " << it->title() << endl;
+ continue;
+ }
+ QByteArray ba = img.byteArray();
+// myDebug() << "TellicoZipExporter::data() - adding image id = " << it->field(fIt) << endl;
+ zip.writeFile(imagesDir + id, QString::null, QString::null, ba.size(), ba);
+ imageSet.add(id);
+ if(j%stepSize == 0) {
+ ProgressManager::self()->setProgress(this, QMIN(10+j/stepSize, 99));
+ kapp->processEvents();
+ }
+ }
+ }
+ } else {
+ ProgressManager::self()->setProgress(this, 80);
+ }
+
+ zip.close();
+ if(m_cancelled) {
+ return true;
+ }
+
+ bool success = FileHandler::writeDataURL(url(), data, options() & Export::ExportForce);
+ return success;
+}
+
+void TellicoZipExporter::slotCancel() {
+ m_cancelled = true;
+}
+
+#include "tellicozipexporter.moc"
diff --git a/src/translators/tellicozipexporter.h b/src/translators/tellicozipexporter.h
new file mode 100644
index 0000000..da167d5
--- /dev/null
+++ b/src/translators/tellicozipexporter.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICOZIPEXPORTER_H
+#define TELLICOZIPEXPORTER_H
+
+#include "exporter.h"
+
+namespace Tellico {
+ namespace Export {
+
+/**
+ * @author Robby Stephenson
+ */
+class TellicoZipExporter : public Exporter {
+Q_OBJECT
+
+public:
+ TellicoZipExporter() : Exporter(), m_includeImages(true), m_cancelled(false) {}
+
+ virtual bool exec();
+ virtual QString formatString() const;
+ virtual QString fileFilter() const;
+
+ // no options
+ virtual QWidget* widget(QWidget*, const char*) { return 0; }
+
+ void setIncludeImages(bool b) { m_includeImages = b; }
+
+public slots:
+ void slotCancel();
+
+private:
+ bool m_includeImages : 1;
+ bool m_cancelled : 1;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/textimporter.cpp b/src/translators/textimporter.cpp
new file mode 100644
index 0000000..3130a0f
--- /dev/null
+++ b/src/translators/textimporter.cpp
@@ -0,0 +1,29 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "textimporter.h"
+#include "../filehandler.h"
+
+using Tellico::Import::TextImporter;
+
+TextImporter::TextImporter(const KURL& url_, bool useUTF8_)
+ : Import::Importer(url_) {
+ if(url_.isValid()) {
+ setText(FileHandler::readTextFile(url_, false, useUTF8_));
+ }
+}
+
+TextImporter::TextImporter(const QString& text_) : Import::Importer(text_) {
+}
+
+#include "textimporter.moc"
diff --git a/src/translators/textimporter.h b/src/translators/textimporter.h
new file mode 100644
index 0000000..c4500e5
--- /dev/null
+++ b/src/translators/textimporter.h
@@ -0,0 +1,42 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TEXTIMPORTER_H
+#define TEXTIMPORTER_H
+
+#include "importer.h"
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ * The TextImporter class is meant as an abstract class for any importer which reads text files.
+ *
+ * @author Robby Stephenson
+ */
+class TextImporter : public Importer {
+Q_OBJECT
+
+public:
+ /**
+ * In the constructor, the contents of the file are read.
+ *
+ * @param url The file to be imported
+ */
+ TextImporter(const KURL& url, bool useUTF8_=false);
+ TextImporter(const QString& text);
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/translators.h b/src/translators/translators.h
new file mode 100644
index 0000000..c6c3bc3
--- /dev/null
+++ b/src/translators/translators.h
@@ -0,0 +1,77 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TRANSLATORS_H
+#define TRANSLATORS_H
+
+namespace Tellico {
+ namespace Import {
+ enum Format {
+ TellicoXML = 0,
+ Bibtex,
+ Bibtexml,
+ CSV,
+ XSLT,
+ AudioFile,
+ MODS,
+ Alexandria,
+ FreeDB,
+ RIS,
+ GCfilms,
+ FileListing,
+ GRS1,
+ AMC,
+ Griffith,
+ PDF,
+ Referencer,
+ Delicious
+ };
+
+ enum Action {
+ Replace,
+ Append,
+ Merge
+ };
+
+ enum Target {
+ None,
+ File,
+ Dir
+ };
+ }
+
+ namespace Export {
+ enum Format {
+ TellicoXML = 0,
+ TellicoZip,
+ Bibtex,
+ Bibtexml,
+ HTML,
+ CSV,
+ XSLT,
+ Text,
+ PilotDB,
+ Alexandria,
+ ONIX,
+ GCfilms
+ };
+
+ enum Target {
+ None,
+ File,
+ Dir
+ };
+ }
+}
+
+#endif
diff --git a/src/translators/xmlimporter.cpp b/src/translators/xmlimporter.cpp
new file mode 100644
index 0000000..ce345c4
--- /dev/null
+++ b/src/translators/xmlimporter.cpp
@@ -0,0 +1,72 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "xmlimporter.h"
+#include "../filehandler.h"
+#include "../collection.h"
+
+#include <klocale.h>
+
+using Tellico::Import::XMLImporter;
+
+XMLImporter::XMLImporter(const KURL& url_) : Import::Importer(url_) {
+ if(!url_.isEmpty() && url_.isValid()) {
+ m_dom = FileHandler::readXMLFile(url_, true);
+ }
+}
+
+XMLImporter::XMLImporter(const QString& text_) : Import::Importer(text_) {
+ if(text_.isEmpty()) {
+ return;
+ }
+ setText(text_);
+}
+
+XMLImporter::XMLImporter(const QByteArray& data_) : Import::Importer(KURL()) {
+ if(data_.isEmpty()) {
+ return;
+ }
+
+ QString errorMsg;
+ int errorLine, errorColumn;
+ if(!m_dom.setContent(data_, true, &errorMsg, &errorLine, &errorColumn)) {
+ QString str = i18n("There is an XML parsing error in line %1, column %2.").arg(errorLine).arg(errorColumn);
+ str += QString::fromLatin1("\n");
+ str += i18n("The error message from Qt is:");
+ str += QString::fromLatin1("\n\t") + errorMsg;
+ setStatusMessage(str);
+ return;
+ }
+}
+
+XMLImporter::XMLImporter(const QDomDocument& dom_) : Import::Importer(KURL()), m_dom(dom_) {
+}
+
+void XMLImporter::setText(const QString& text_) {
+ Importer::setText(text_);
+ QString errorMsg;
+ int errorLine, errorColumn;
+ if(!m_dom.setContent(text_, true, &errorMsg, &errorLine, &errorColumn)) {
+ QString str = i18n("There is an XML parsing error in line %1, column %2.").arg(errorLine).arg(errorColumn);
+ str += QString::fromLatin1("\n");
+ str += i18n("The error message from Qt is:");
+ str += QString::fromLatin1("\n\t") + errorMsg;
+ setStatusMessage(str);
+ }
+}
+
+Tellico::Data::CollPtr XMLImporter::collection() {
+ return 0;
+}
+
+#include "xmlimporter.moc"
diff --git a/src/translators/xmlimporter.h b/src/translators/xmlimporter.h
new file mode 100644
index 0000000..743a1c1
--- /dev/null
+++ b/src/translators/xmlimporter.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef XMLIMPORTER_H
+#define XMLIMPORTER_H
+
+#include "importer.h"
+
+#include <qdom.h>
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ * The XMLImporter class is meant as an abstract class for any importer which reads xml files.
+ *
+ * @author Robby Stephenson
+ */
+class XMLImporter : public Importer {
+Q_OBJECT
+
+public:
+ /**
+ * In the constructor, the contents of the file are read.
+ *
+ * @param url The file to be imported
+ */
+ XMLImporter(const KURL& url);
+ /**
+ * Imports xml text.
+ *
+ * @param text The text
+ */
+ XMLImporter(const QString& text);
+ /**
+ * Imports xml text from a byte array.
+ *
+ * @param data The Data
+ */
+ XMLImporter(const QByteArray& data);
+ XMLImporter(const QDomDocument& dom);
+
+ virtual void setText(const QString& text);
+
+ /**
+ * This class gets used as a utility XML loader. This should never get called,
+ * but cannot be abstract.
+ */
+ virtual Data::CollPtr collection();
+
+ /**
+ * Returns the contents of the imported file.
+ *
+ * @return The file contents
+ */
+ const QDomDocument& domDocument() const { return m_dom; }
+
+private:
+ QDomDocument m_dom;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/xsltexporter.cpp b/src/translators/xsltexporter.cpp
new file mode 100644
index 0000000..54ca8aa
--- /dev/null
+++ b/src/translators/xsltexporter.cpp
@@ -0,0 +1,80 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "xsltexporter.h"
+#include "xslthandler.h"
+#include "tellicoxmlexporter.h"
+#include "../filehandler.h"
+
+#include <klocale.h>
+#include <kurlrequester.h>
+
+#include <qlabel.h>
+#include <qgroupbox.h>
+#include <qlayout.h>
+#include <qhbox.h>
+#include <qdom.h>
+#include <qwhatsthis.h>
+
+using Tellico::Export::XSLTExporter;
+
+XSLTExporter::XSLTExporter() : Export::Exporter(),
+ m_widget(0),
+ m_URLRequester(0) {
+}
+
+QString XSLTExporter::formatString() const {
+ return i18n("XSLT");
+}
+
+QString XSLTExporter::fileFilter() const {
+ return i18n("*|All Files");
+}
+
+
+bool XSLTExporter::exec() {
+ KURL u = m_URLRequester->url();
+ if(u.isEmpty() || !u.isValid()) {
+ return QString::null;
+ }
+ // XSLTHandler handler(FileHandler::readXMLFile(url));
+ XSLTHandler handler(u);
+
+ TellicoXMLExporter exporter;
+ exporter.setEntries(entries());
+ exporter.setOptions(options());
+ QDomDocument dom = exporter.exportXML();
+ return FileHandler::writeTextURL(url(), handler.applyStylesheet(dom.toString()),
+ options() & ExportUTF8, options() & Export::ExportForce);
+}
+
+QWidget* XSLTExporter::widget(QWidget* parent_, const char* name_/*=0*/) {
+ if(m_widget && m_widget->parent() == parent_) {
+ return m_widget;
+ }
+
+ m_widget = new QWidget(parent_, name_);
+ QVBoxLayout* l = new QVBoxLayout(m_widget);
+
+ QGroupBox* group = new QGroupBox(1, Qt::Horizontal, i18n("XSLT Options"), m_widget);
+ l->addWidget(group);
+
+ QHBox* box = new QHBox(group);
+ box->setSpacing(4);
+ (void) new QLabel(i18n("XSLT file:"), box);
+ m_URLRequester = new KURLRequester(box);
+ QWhatsThis::add(m_URLRequester, i18n("Choose the XSLT file used to transform the Tellico XML data."));
+
+ l->addStretch(1);
+ return m_widget;
+}
diff --git a/src/translators/xsltexporter.h b/src/translators/xsltexporter.h
new file mode 100644
index 0000000..ae353d2
--- /dev/null
+++ b/src/translators/xsltexporter.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef XSLTEXPORTER_H
+#define XSLTEXPORTER_H
+
+class KURLRequester;
+
+#include "exporter.h"
+
+namespace Tellico {
+ namespace Export {
+
+/**
+ * @author Robby Stephenson
+ */
+class XSLTExporter : public Exporter {
+public:
+ XSLTExporter();
+
+ virtual bool exec();
+ virtual QString formatString() const;
+ virtual QString fileFilter() const;
+
+ virtual QWidget* widget(QWidget* parent, const char* name=0);
+
+private:
+ QWidget* m_widget;
+ KURLRequester* m_URLRequester;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/translators/xslthandler.cpp b/src/translators/xslthandler.cpp
new file mode 100644
index 0000000..e25eef5
--- /dev/null
+++ b/src/translators/xslthandler.cpp
@@ -0,0 +1,267 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "xslthandler.h"
+#include "../latin1literal.h"
+#include "../tellico_debug.h"
+#include "../tellico_utils.h"
+
+#include <qdom.h>
+#include <qtextcodec.h>
+
+#include <kurl.h>
+
+extern "C" {
+#include <libxslt/xslt.h>
+#include <libxslt/transform.h>
+#include <libxslt/xsltutils.h>
+#include <libxslt/extensions.h>
+
+#include <libexslt/exslt.h>
+}
+
+// I don't want any network I/O at all
+static const int xml_options = XML_PARSE_NOENT | XML_PARSE_NONET | XML_PARSE_NOCDATA;
+static const int xslt_options = xml_options;
+
+/* some functions to pass to the XSLT libs */
+static int writeToQString(void* context, const char* buffer, int len) {
+ QString* t = static_cast<QString*>(context);
+ *t += QString::fromUtf8(buffer, len);
+ return len;
+}
+
+static void closeQString(void* context) {
+ QString* t = static_cast<QString*>(context);
+ *t += QString::fromLatin1("\n");
+}
+
+using Tellico::XSLTHandler;
+
+XSLTHandler::XMLOutputBuffer::XMLOutputBuffer() : m_res(QString::null) {
+ m_buf = xmlOutputBufferCreateIO((xmlOutputWriteCallback)writeToQString,
+ (xmlOutputCloseCallback)closeQString,
+ &m_res, 0);
+ if(m_buf) {
+ m_buf->written = 0;
+ } else {
+ myDebug() << "XMLOutputBuffer::XMLOutputBuffer() - error writing output buffer!" << endl;
+ }
+}
+
+XSLTHandler::XMLOutputBuffer::~XMLOutputBuffer() {
+ if(m_buf) {
+ xmlOutputBufferClose(m_buf); //also flushes
+ m_buf = 0;
+ }
+}
+
+int XSLTHandler::s_initCount = 0;
+
+XSLTHandler::XSLTHandler(const QCString& xsltFile_) :
+ m_stylesheet(0),
+ m_docIn(0),
+ m_docOut(0) {
+ init();
+ QString file = KURL::encode_string(QString::fromLocal8Bit(xsltFile_));
+ if(!file.isEmpty()) {
+ xmlDocPtr xsltDoc = xmlReadFile(file.utf8(), NULL, xslt_options);
+ m_stylesheet = xsltParseStylesheetDoc(xsltDoc);
+ if(!m_stylesheet) {
+ myDebug() << "XSLTHandler::applyStylesheet() - null stylesheet pointer for " << xsltFile_ << endl;
+ }
+ }
+}
+
+XSLTHandler::XSLTHandler(const KURL& xsltURL_) :
+ m_stylesheet(0),
+ m_docIn(0),
+ m_docOut(0) {
+ init();
+ if(xsltURL_.isValid() && xsltURL_.isLocalFile()) {
+ xmlDocPtr xsltDoc = xmlReadFile(xsltURL_.encodedPathAndQuery().utf8(), NULL, xslt_options);
+ m_stylesheet = xsltParseStylesheetDoc(xsltDoc);
+ if(!m_stylesheet) {
+ myDebug() << "XSLTHandler::applyStylesheet() - null stylesheet pointer for " << xsltURL_.path() << endl;
+ }
+ }
+}
+
+XSLTHandler::XSLTHandler(const QDomDocument& xsltDoc_, const QCString& xsltFile_, bool translate_) :
+ m_stylesheet(0),
+ m_docIn(0),
+ m_docOut(0) {
+ init();
+ QString file = KURL::encode_string(QString::fromLocal8Bit(xsltFile_));
+ if(!xsltDoc_.isNull() && !file.isEmpty()) {
+ setXSLTDoc(xsltDoc_, file.utf8(), translate_);
+ }
+}
+
+XSLTHandler::~XSLTHandler() {
+ if(m_stylesheet) {
+ xsltFreeStylesheet(m_stylesheet);
+ }
+
+ if(m_docIn) {
+ xmlFreeDoc(m_docIn);
+ }
+
+ if(m_docOut) {
+ xmlFreeDoc(m_docOut);
+ }
+
+ --s_initCount;
+ if(s_initCount == 0) {
+ xsltUnregisterExtModule(EXSLT_STRINGS_NAMESPACE);
+ xsltUnregisterExtModule(EXSLT_DYNAMIC_NAMESPACE);
+ xsltCleanupGlobals();
+ xmlCleanupParser();
+ }
+}
+
+void XSLTHandler::init() {
+ if(s_initCount == 0) {
+ xmlSubstituteEntitiesDefault(1);
+ xmlLoadExtDtdDefaultValue = 0;
+
+ // register all exslt extensions
+ exsltRegisterAll();
+ }
+ ++s_initCount;
+
+ m_params.clear();
+}
+
+void XSLTHandler::setXSLTDoc(const QDomDocument& dom_, const QCString& xsltFile_, bool translate_) {
+ bool utf8 = true; // XML defaults to utf-8
+
+ // need to find out if utf-8 or not
+ const QDomNodeList childs = dom_.childNodes();
+ for(uint j = 0; j < childs.count(); ++j) {
+ if(childs.item(j).isProcessingInstruction()) {
+ QDomProcessingInstruction pi = childs.item(j).toProcessingInstruction();
+ if(pi.data().lower().contains(QString::fromLatin1("encoding"))) {
+ if(!pi.data().lower().contains(QString::fromLatin1("utf-8"))) {
+ utf8 = false;
+// } else {
+// myDebug() << "XSLTHandler::setXSLTDoc() - PI = " << pi.data() << endl;
+ }
+ break;
+ }
+ }
+ }
+
+ QString s;
+ if(translate_) {
+ s = Tellico::i18nReplace(dom_.toString(0 /* indent */));
+ } else {
+ s = dom_.toString();
+ }
+
+ xmlDocPtr xsltDoc;
+ if(utf8) {
+ xsltDoc = xmlReadDoc(reinterpret_cast<xmlChar*>(s.utf8().data()), xsltFile_.data(), NULL, xslt_options);
+ } else {
+ xsltDoc = xmlReadDoc(reinterpret_cast<xmlChar*>(s.local8Bit().data()), xsltFile_.data(), NULL, xslt_options);
+ }
+
+ if(m_stylesheet) {
+ xsltFreeStylesheet(m_stylesheet);
+ }
+ m_stylesheet = xsltParseStylesheetDoc(xsltDoc);
+ if(!m_stylesheet) {
+ myDebug() << "XSLTHandler::applyStylesheet() - null stylesheet pointer for " << xsltFile_ << endl;
+ }
+// xmlFreeDoc(xsltDoc); // this causes a crash for some reason
+}
+
+void XSLTHandler::addStringParam(const QCString& name_, const QCString& value_) {
+ QCString value = value_;
+ value.replace('\'', "&apos;");
+ addParam(name_, QCString("'") + value + QCString("'"));
+}
+
+void XSLTHandler::addParam(const QCString& name_, const QCString& value_) {
+ m_params.insert(name_, value_);
+// myDebug() << "XSLTHandler::addParam() - " << name_ << ":" << value_ << endl;
+}
+
+void XSLTHandler::removeParam(const QCString& name_) {
+ m_params.remove(name_);
+}
+
+const QCString& XSLTHandler::param(const QCString& name_) {
+ return m_params[name_];
+}
+
+QString XSLTHandler::applyStylesheet(const QString& text_) {
+ if(!m_stylesheet) {
+ myDebug() << "XSLTHandler::applyStylesheet() - null stylesheet pointer!" << endl;
+ return QString::null;
+ }
+
+ m_docIn = xmlReadDoc(reinterpret_cast<xmlChar*>(text_.utf8().data()), NULL, NULL, xml_options);
+
+ return process();
+}
+
+QString XSLTHandler::process() {
+ if(!m_docIn) {
+ myDebug() << "XSLTHandler::process() - error parsing input string!" << endl;
+ return QString::null;
+ }
+
+ QMemArray<const char*> params(2*m_params.count() + 1);
+ params[0] = NULL;
+ QMap<QCString, QCString>::ConstIterator it = m_params.constBegin();
+ QMap<QCString, QCString>::ConstIterator end = m_params.constEnd();
+ for(uint i = 0; it != end; ++it) {
+ params[i ] = qstrdup(it.key());
+ params[i+1] = qstrdup(it.data());
+ params[i+2] = NULL;
+ i += 2;
+ }
+ // returns NULL on error
+ m_docOut = xsltApplyStylesheet(m_stylesheet, m_docIn, params.data());
+ for(uint i = 0; i < 2*m_params.count(); ++i) {
+ delete[] params[i];
+ }
+ if(!m_docOut) {
+ myDebug() << "XSLTHandler::applyStylesheet() - error applying stylesheet!" << endl;
+ return QString::null;
+ }
+
+ XMLOutputBuffer output;
+ if(output.isValid()) {
+ int num_bytes = xsltSaveResultTo(output.buffer(), m_docOut, m_stylesheet);
+ if(num_bytes == -1) {
+ myDebug() << "XSLTHandler::applyStylesheet() - error saving output buffer!" << endl;
+ }
+ }
+ return output.result();
+}
+
+//static
+QDomDocument& XSLTHandler::setLocaleEncoding(QDomDocument& dom_) {
+ const QDomNodeList childs = dom_.documentElement().childNodes();
+ for(unsigned j = 0; j < childs.count(); ++j) {
+ if(childs.item(j).isElement() && childs.item(j).nodeName() == Latin1Literal("xsl:output")) {
+ QDomElement e = childs.item(j).toElement();
+ const QString encoding = QString::fromLatin1(QTextCodec::codecForLocale()->name());
+ e.setAttribute(QString::fromLatin1("encoding"), encoding);
+ break;
+ }
+ }
+ return dom_;
+}
diff --git a/src/translators/xslthandler.h b/src/translators/xslthandler.h
new file mode 100644
index 0000000..f51b47c
--- /dev/null
+++ b/src/translators/xslthandler.h
@@ -0,0 +1,112 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef XSLTHANDLER_H
+#define XSLTHANDLER_H
+
+#include <qmap.h>
+
+extern "C" {
+// for xmlDocPtr
+#include <libxml/tree.h>
+// for xsltStyleSheetPtr
+#include <libxslt/xsltInternals.h>
+}
+
+class KURL;
+class QDomDocument;
+
+namespace Tellico {
+
+/**
+ * The XSLTHandler contains all the code which uses XSLT processing to generate HTML or to
+ * translate to other formats.
+ *
+ * @author Robby Stephenson
+ */
+class XSLTHandler {
+
+public:
+ class XMLOutputBuffer {
+ public:
+ XMLOutputBuffer();
+ ~XMLOutputBuffer();
+ bool isValid() const { return (m_buf != 0); }
+ xmlOutputBuffer* buffer() const { return m_buf; }
+ QString result() const { return m_res; }
+ private:
+ xmlOutputBuffer* m_buf;
+ QString m_res;
+ };
+
+ /**
+ * @param xsltFile The XSLT file
+ */
+ XSLTHandler(const QCString& xsltFile);
+ /**
+ * @param xsltURL The XSLT URL
+ */
+ XSLTHandler(const KURL& xsltURL);
+ /**
+ * @param xsltDoc The XSLT DOM document
+ * @param xsltFile The XSLT file, should be a url?
+ */
+ XSLTHandler(const QDomDocument& xsltDoc, const QCString& xsltFile, bool translate=false);
+ /**
+ */
+ ~XSLTHandler();
+
+ bool isValid() const { return (m_stylesheet != NULL); }
+ /**
+ * Set the XSLT text
+ *
+ * @param dom The XSLT DOM document
+ * @param xsltFile The XSLT file, should be a url?
+ */
+ void setXSLTDoc(const QDomDocument& dom, const QCString& xsltFile, bool translate=false);
+ /**
+ * Adds a param
+ */
+ void addParam(const QCString& name, const QCString& value);
+ /**
+ * Adds a string param
+ */
+ void addStringParam(const QCString& name, const QCString& value);
+ void removeParam(const QCString& name);
+ const QCString& param(const QCString& name);
+ /**
+ * Processes text through the XSLT transformation.
+ *
+ * @param text The text to be transformed
+ * @param encodedUTF8 Whether the text is encoded in utf-8 or not
+ * @return The transformed text
+ */
+ QString applyStylesheet(const QString& text);
+
+ static QDomDocument& setLocaleEncoding(QDomDocument& dom);
+
+private:
+ void init();
+ QString process();
+
+ xsltStylesheetPtr m_stylesheet;
+ xmlDocPtr m_docIn;
+ xmlDocPtr m_docOut;
+
+ QMap<QCString, QCString> m_params;
+
+ static int s_initCount;
+};
+
+} // end namespace
+#endif
diff --git a/src/translators/xsltimporter.cpp b/src/translators/xsltimporter.cpp
new file mode 100644
index 0000000..67f1fd2
--- /dev/null
+++ b/src/translators/xsltimporter.cpp
@@ -0,0 +1,112 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "xsltimporter.h"
+#include "xslthandler.h"
+#include "tellicoimporter.h"
+#include "../filehandler.h"
+#include "../collection.h"
+
+#include <klocale.h>
+#include <kurlrequester.h>
+
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qgroupbox.h>
+
+#include <memory>
+
+using Tellico::Import::XSLTImporter;
+
+namespace {
+
+static bool isUTF8(const KURL& url_) {
+ // read first line to check encoding
+ std::auto_ptr<Tellico::FileHandler::FileRef> ref(Tellico::FileHandler::fileRef(url_));
+ if(!ref->isValid()) {
+ return false;
+ }
+
+ ref->open();
+ QTextStream stream(ref->file());
+ QString line = stream.readLine().lower();
+ return line.find(QString::fromLatin1("utf-8")) > 0;
+}
+
+}
+
+// always use utf8 for xslt
+XSLTImporter::XSLTImporter(const KURL& url_) : Tellico::Import::TextImporter(url_, isUTF8(url_)),
+ m_coll(0),
+ m_widget(0),
+ m_URLRequester(0) {
+}
+
+Tellico::Data::CollPtr XSLTImporter::collection() {
+ if(m_coll) {
+ return m_coll;
+ }
+
+ if(m_xsltURL.isEmpty()) {
+ // if there's also no widget, then something went wrong
+ if(!m_widget) {
+ setStatusMessage(i18n("A valid XSLT file is needed to import the file."));
+ return 0;
+ }
+ m_xsltURL = m_URLRequester->url();
+ }
+ if(m_xsltURL.isEmpty() || !m_xsltURL.isValid()) {
+ setStatusMessage(i18n("A valid XSLT file is needed to import the file."));
+ return 0;
+ }
+
+ XSLTHandler handler(m_xsltURL);
+ if(!handler.isValid()) {
+ setStatusMessage(i18n("Tellico encountered an error in XSLT processing."));
+ return 0;
+ }
+// kdDebug() << text() << endl;
+ QString str = handler.applyStylesheet(text());
+// kdDebug() << str << endl;
+
+ Import::TellicoImporter imp(str);
+ m_coll = imp.collection();
+ setStatusMessage(imp.statusMessage());
+ return m_coll;
+}
+
+QWidget* XSLTImporter::widget(QWidget* parent_, const char* name_) {
+ // if the url has already been set, then there's no widget
+ if(!m_xsltURL.isEmpty()) {
+ return 0;
+ }
+
+ m_widget = new QWidget(parent_, name_);
+ QVBoxLayout* l = new QVBoxLayout(m_widget);
+
+ QGroupBox* box = new QGroupBox(1, Qt::Vertical, i18n("XSLT Options"), m_widget);
+ l->addWidget(box);
+
+ (void) new QLabel(i18n("XSLT file:"), box);
+ m_URLRequester = new KURLRequester(box);
+
+ QString filter = i18n("*.xsl|XSL Files (*.xsl)") + QChar('\n');
+ filter += i18n("*|All Files");
+ m_URLRequester->setFilter(filter);
+
+ l->addStretch(1);
+ return m_widget;
+}
+
+#include "xsltimporter.moc"
diff --git a/src/translators/xsltimporter.h b/src/translators/xsltimporter.h
new file mode 100644
index 0000000..578b552
--- /dev/null
+++ b/src/translators/xsltimporter.h
@@ -0,0 +1,56 @@
+/***************************************************************************
+ copyright : (C) 2003-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef XSLTIMPORTER_H
+#define XSLTIMPORTER_H
+
+class KURLRequester;
+
+#include "textimporter.h"
+#include "../datavectors.h"
+
+namespace Tellico {
+ namespace Import {
+
+/**
+ * The XSLTImporter class takes care of transforming XML data using an XSL stylesheet.
+ *
+ * @author Robby Stephenson
+ */
+class XSLTImporter : public TextImporter {
+Q_OBJECT
+
+public:
+ /**
+ */
+ XSLTImporter(const KURL& url);
+
+ /**
+ */
+ virtual Data::CollPtr collection();
+ /**
+ */
+ virtual QWidget* widget(QWidget* parent, const char* name=0);
+ void setXSLTURL(const KURL& url) { m_xsltURL = url; }
+
+private:
+ Data::CollPtr m_coll;
+
+ QWidget* m_widget;
+ KURLRequester* m_URLRequester;
+ KURL m_xsltURL;
+};
+
+ } // end namespace
+} // end namespace
+#endif
diff --git a/src/upcvalidator.cpp b/src/upcvalidator.cpp
new file mode 100644
index 0000000..2d5b7a2
--- /dev/null
+++ b/src/upcvalidator.cpp
@@ -0,0 +1,133 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "upcvalidator.h"
+#include "isbnvalidator.h"
+
+#include <kmdcodec.h>
+
+using Tellico::UPCValidator;
+
+UPCValidator::UPCValidator(QObject* parent_, const char* name_/*=0*/)
+ : QValidator(parent_, name_), m_checkISBN(false) {
+}
+
+QValidator::State UPCValidator::validate(QString& input_, int& pos_) const {
+ // check if it's a cuecat first
+ State catState = decodeCat(input_);
+ if(catState == Acceptable) {
+ pos_ = input_.length();
+ return catState;
+ }
+
+ // no spaces allowed
+ if(input_.contains(' ')) {
+ return QValidator::Invalid;
+ }
+
+ // no real checking, just if starts with 978, use isbnvalidator
+ const uint len = input_.length();
+ if(len < 10) {
+ m_isbn = false;
+ }
+
+ if(!m_checkISBN || (!m_isbn && len < 13)) {
+ return QValidator::Intermediate;
+ }
+
+ // once it gets converted to an ISBN, remember that, and use it for later
+ if(input_.startsWith(QString::fromLatin1("978")) || input_.startsWith(QString::fromLatin1("979"))) {
+ ISBNValidator val(0);
+ QValidator::State s = val.validate(input_, pos_);
+ if(s == QValidator::Acceptable) {
+ m_isbn = true;
+ // bad hack
+ UPCValidator* that = const_cast<UPCValidator*>(this);
+ that->signalISBN();
+ }
+ return s;
+ }
+
+ return QValidator::Intermediate;
+}
+
+void UPCValidator::fixup(QString& input_) const {
+ if(input_.isEmpty()) {
+ return;
+ }
+ input_ = input_.stripWhiteSpace();
+
+ int pos = input_.find(' ');
+ if(pos > -1) {
+ input_ = input_.left(pos);
+ }
+
+ if(!m_checkISBN) {
+ return;
+ }
+
+ const uint len = input_.length();
+ if(len > 12 && (input_.startsWith(QString::fromLatin1("978")) || input_.startsWith(QString::fromLatin1("979")))) {
+ QString s = input_;
+ ISBNValidator val(0);
+ int p = 0;
+ int state = val.validate(s, p);
+ if(state == QValidator::Acceptable) {
+ // bad hack
+ UPCValidator* that = const_cast<UPCValidator*>(this);
+ that->signalISBN();
+ input_ = s;
+ }
+ }
+}
+
+QValidator::State UPCValidator::decodeCat(QString& input_) const {
+ if(input_.length() < 3) {
+ return Intermediate;
+ }
+ if(!input_.startsWith(QString::fromLatin1(".C3"))) { // all cuecat codes start with .C3
+ return Invalid;
+ }
+ const int periods = input_.contains('.');
+ if(periods < 4) {
+ return Intermediate; // not enough yet
+ } else if(periods > 4) {
+ return Invalid;
+ }
+
+ // ok, let's have a go, take the third token
+ QString code = QStringList::split('.', input_)[2];
+ while(code.length() % 4 > 0) {
+ code += '=';
+ }
+
+ for(uint i = 0; i < code.length(); ++i) {
+ if(code[i] >= 'A' && code[i] <= 'Z') {
+ code.replace(i, 1, code[i].lower());
+ } else if(code[i] >= 'a' && code[i] <= 'z') {
+ code.replace(i, 1, code[i].upper());
+ }
+ }
+
+ code = QString::fromLatin1(KCodecs::base64Decode(code.latin1()));
+
+ for(uint i = 0; i < code.length(); ++i) {
+ char c = code[i].latin1() ^ 'C';
+ code.replace(i, 1, c);
+ }
+
+ input_ = code;
+ return Acceptable;
+}
+
+#include "upcvalidator.moc"
diff --git a/src/upcvalidator.h b/src/upcvalidator.h
new file mode 100644
index 0000000..73afa09
--- /dev/null
+++ b/src/upcvalidator.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef UPCVALIDATOR_H
+#define UPCVALIDATOR_H
+
+#include <qvalidator.h>
+
+namespace Tellico {
+
+/**
+ * @author Robby Stephenson
+ */
+class UPCValidator : public QValidator {
+Q_OBJECT
+
+public:
+ UPCValidator(QObject* parent, const char* name=0);
+
+ virtual QValidator::State validate(QString& input, int& pos) const;
+ virtual void fixup(QString& input) const;
+
+ void setCheckISBN(bool b) { m_checkISBN = b; }
+
+signals:
+ void signalISBN();
+
+private:
+ State decodeCat(QString& str) const;
+
+ bool m_checkISBN : 1;
+ mutable bool m_isbn : 1;
+};
+
+} // end namespace
+#endif
diff --git a/src/viewstack.cpp b/src/viewstack.cpp
new file mode 100644
index 0000000..69d6ff8
--- /dev/null
+++ b/src/viewstack.cpp
@@ -0,0 +1,55 @@
+/***************************************************************************
+ copyright : (C) 2002-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "viewstack.h"
+#include "entryview.h"
+#include "entryiconview.h"
+#include "tellico_debug.h"
+#include "imagefactory.h"
+
+#include <khtmlview.h>
+#include <klocale.h>
+
+#include <qwhatsthis.h>
+
+using Tellico::ViewStack;
+
+ViewStack::ViewStack(QWidget* parent_, const char* name_/*=0*/) : QWidgetStack(parent_, name_),
+ m_entryView(new EntryView(this)), m_iconView(new EntryIconView(this)) {
+ QWhatsThis::add(m_entryView->view(), i18n("<qt>The <i>Entry View</i> shows a formatted view of the entry's "
+ "contents.</qt>"));
+ QWhatsThis::add(m_iconView, i18n("<qt>The <i>Icon View</i> shows each entry in the collection or group using "
+ "an icon, which may be an image in the entry.</qt>"));
+}
+
+void ViewStack::clear() {
+ m_entryView->clear();
+ m_iconView->clear();
+}
+
+void ViewStack::refresh() {
+ m_entryView->slotRefresh();
+ m_iconView->refresh();
+}
+
+void ViewStack::showEntry(Data::EntryPtr entry_) {
+ m_entryView->showEntry(entry_);
+ raiseWidget(m_entryView->view());
+}
+
+void ViewStack::showEntries(const Data::EntryVec& entries_) {
+ m_iconView->showEntries(entries_);
+ raiseWidget(m_iconView);
+}
+
+#include "viewstack.moc"
diff --git a/src/viewstack.h b/src/viewstack.h
new file mode 100644
index 0000000..73fa814
--- /dev/null
+++ b/src/viewstack.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ copyright : (C) 2002-2006 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_VIEWSTACK_H
+#define TELLICO_VIEWSTACK_H
+
+#include "datavectors.h"
+
+#include <qwidgetstack.h>
+
+namespace Tellico {
+ class EntryView;
+ class EntryIconView;
+
+/**
+ * @author Robby Stephenson
+ */
+class ViewStack : public QWidgetStack {
+Q_OBJECT
+
+public:
+ ViewStack(QWidget* parent, const char* name = 0);
+
+ EntryView* entryView() const { return m_entryView; }
+ EntryIconView* iconView() const { return m_iconView; }
+
+ void clear();
+ void refresh();
+ void showEntry(Data::EntryPtr entry);
+ void showEntries(const Data::EntryVec& entries);
+
+private:
+ EntryView* m_entryView;
+ EntryIconView* m_iconView;
+};
+
+} // end namespace
+#endif
diff --git a/src/xmphandler.cpp b/src/xmphandler.cpp
new file mode 100644
index 0000000..de5d5d6
--- /dev/null
+++ b/src/xmphandler.cpp
@@ -0,0 +1,90 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "xmphandler.h"
+#include "tellico_debug.h"
+#include <config.h>
+
+#include <qfile.h>
+#include <qtextstream.h>
+#ifdef HAVE_EXEMPI
+#include <exempi/xmp.h>
+#endif
+
+using Tellico::XMPHandler;
+
+int XMPHandler::s_initCount = 0;
+
+bool XMPHandler::isXMPEnabled() {
+#ifdef HAVE_EXEMPI
+ return true;
+#else
+ return false;
+#endif
+}
+
+XMPHandler::XMPHandler() {
+ init();
+}
+
+XMPHandler::~XMPHandler() {
+#ifdef HAVE_EXEMPI
+ --s_initCount;
+ if(s_initCount == 0) {
+ xmp_terminate();
+ }
+#endif
+}
+
+void XMPHandler::init() {
+#ifdef HAVE_EXEMPI
+ if(s_initCount == 0) {
+ xmp_init();
+ }
+ ++s_initCount;
+#endif
+}
+
+QString XMPHandler::extractXMP(const QString& file) {
+ QString result;
+#ifdef HAVE_EXEMPI
+ XmpFilePtr xmpfile = xmp_files_open_new(QFile::encodeName(file), XMP_OPEN_READ);
+ if(!xmpfile) {
+ myDebug() << "XMPHandler::parse() - unable to open " << file << endl;
+ return result;
+ }
+ XmpPtr xmp = xmp_files_get_new_xmp(xmpfile);
+ if(xmp) {
+ XmpStringPtr buffer = xmp_string_new();
+ xmp_serialize(xmp, buffer, 0, 0);
+ result = QString::fromUtf8(xmp_string_cstr(buffer));
+ xmp_string_free(buffer);
+// myDebug() << result << endl;
+#if 0
+ kdWarning() << "XMPHandler::parse() - turn me off!" << endl;
+ QFile f1(QString::fromLatin1("/tmp/xmp.xml"));
+ if(f1.open(IO_WriteOnly)) {
+ QTextStream t(&f1);
+ t << result;
+ }
+ f1.close();
+#endif
+ xmp_free(xmp);
+ xmp_files_close(xmpfile, XMP_CLOSE_NOOPTION);
+ xmp_files_free(xmpfile);
+ } else {
+ myDebug() << "XMPHandler::parse() - unable to parse " << file << endl;
+ }
+#endif
+ return result;
+}
diff --git a/src/xmphandler.h b/src/xmphandler.h
new file mode 100644
index 0000000..07c0631
--- /dev/null
+++ b/src/xmphandler.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+ copyright : (C) 2007 by Robby Stephenson
+ email : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#ifndef TELLICO_XMPHANDLER_H
+#define TELLICO_XMPHANDLER_H
+
+class QString;
+
+namespace Tellico {
+
+class XMPHandler {
+public:
+ XMPHandler();
+ ~XMPHandler();
+
+ QString extractXMP(const QString& file);
+
+ static bool isXMPEnabled();
+
+private:
+ void init();
+
+ static int s_initCount;
+};
+
+}
+#endif
diff --git a/subdirs b/subdirs
new file mode 100644
index 0000000..a03571a
--- /dev/null
+++ b/subdirs
@@ -0,0 +1,5 @@
+doc
+icons
+po
+src
+xslt
diff --git a/tellico.desktop b/tellico.desktop
new file mode 100644
index 0000000..ba70c5a
--- /dev/null
+++ b/tellico.desktop
@@ -0,0 +1,27 @@
+# KDE Config File
+[Desktop Entry]
+Version=1.0
+Type=Application
+Exec=tellico -caption "%c" %i %u
+Icon=tellico
+X-KDE-DocPath=tellico/index.html
+Comment=A collection manager
+Comment[ru]=Менеджер коллекций
+Comment[cs]=Správce sbírek
+Comment[de]=Ein Programm zum Verwalten von Sammlungen
+Comment[fr]=Un gestionnaire de collection
+Comment[tr]=Bir koleksiyon yöneticisi
+Comment[sv]=Program för hantering av samlingar
+Comment[pt]=Um gestor de colecção
+Terminal=false
+Name=Tellico
+GenericName=Collection Manager
+GenericName[cs]=Správce sbírek
+GenericName[de]=Verwaltung von Sammlungen
+GenericName[ru]=Менеджер коллекций
+GenericName[fr]=Gestionnaire de collection
+GenericName[tr]=Koleksiyon yöneticisi
+GenericName[sv]=Samlingsorganisatör
+GenericName[pt]=Gestor de Colecção
+MimeType=application/x-tellico;
+Categories=KDE;Office;Database;
diff --git a/tellico.dtd b/tellico.dtd
new file mode 100644
index 0000000..455669e
--- /dev/null
+++ b/tellico.dtd
@@ -0,0 +1,264 @@
+<!--
+ ================================================================
+ Tellico XML DTD version 10.0
+
+ Copyright (c) 2006 Robby Stephenson
+
+ This DTD describes the XML data files for the
+ Tellico application, which can be found at:
+ http://www.periapsis.org/tellico/
+
+ The formal public identifer for this DTD should be:
+
+ "-//Robby Stephenson/DTD Tellico V10.0//EN"
+
+ ================================================================
+-->
+<!ELEMENT tellico (collection+, borrowers?, filters?)>
+<!ATTLIST tellico syntaxVersion CDATA #FIXED "10">
+<!ATTLIST tellico xmlns CDATA #FIXED "http://periapsis.org/tellico/">
+
+<!ELEMENT collection (fields | bibtex-preamble | macros | entry |
+images | borrowers | filters)+>
+<!ATTLIST collection title CDATA #REQUIRED>
+<!ATTLIST collection type (1|2|3|4|5|6|7|8|9|10|11|12|13) #REQUIRED>
+<!ATTLIST collection entryTitle CDATA #IMPLIED>
+
+<!ELEMENT images (image+)>
+<!ELEMENT image (#PCDATA)>
+<!ATTLIST image id CDATA #REQUIRED>
+<!ATTLIST image format CDATA #REQUIRED>
+<!ATTLIST image width CDATA #REQUIRED>
+<!ATTLIST image height CDATA #REQUIRED>
+
+<!ELEMENT fields (field+)>
+<!ELEMENT field (prop*)>
+<!ATTLIST field i18n (true|false) "true">
+<!ATTLIST field name CDATA #REQUIRED>
+<!ATTLIST field title CDATA #REQUIRED>
+<!ATTLIST field category CDATA #REQUIRED>
+<!ATTLIST field allowed CDATA #IMPLIED>
+<!ATTLIST field flags CDATA #IMPLIED>
+<!ATTLIST field format CDATA #IMPLIED>
+<!ATTLIST field description CDATA #IMPLIED>
+<!ATTLIST field type (1|2|3|4|5|6|7|8|9|10|11|12|14) #REQUIRED>
+
+<!ELEMENT prop (#PCDATA)>
+<!ATTLIST prop name CDATA #REQUIRED>
+
+<!-- bibliography, or bibtex, collections may have a preamble and macros -->
+<!ELEMENT bibtex-preamble (#PCDATA)>
+<!ELEMENT macros (macro+)>
+<!ELEMENT macro (#PCDATA)>
+<!ATTLIST macro name CDATA #REQUIRED>
+
+<!-- general -->
+<!-- columns are used in 2-column tables to split the values -->
+<!ELEMENT column (#PCDATA)>
+<!-- year, month, day are used in dates -->
+<!ELEMENT year (#PCDATA)>
+<!ELEMENT month (#PCDATA)>
+<!ELEMENT day (#PCDATA)>
+
+<!-- borrowing -->
+<!ELEMENT borrowers (borrower+)>
+<!ELEMENT borrower (loan)>
+<!ELEMENT loan (#PCDATA)>
+<!ATTLIST loan dueDate CDATA #IMPLIED>
+<!ATTLIST loan loanDate CDATA #REQUIRED>
+<!ATTLIST loan entryRef CDATA #REQUIRED>
+<!ATTLIST loan uid CDATA #REQUIRED>
+
+<!-- filters -->
+<!ELEMENT filters (filter+)>
+<!ELEMENT filter (rule)>
+<!ATTLIST filter name CDATA #REQUIRED>
+<!ATTLIST filter match CDATA #REQUIRED>
+<!ELEMENT rule (#PCDATA)>
+<!ATTLIST rule field CDATA #REQUIRED>
+<!ATTLIST rule function CDATA #REQUIRED>
+<!ATTLIST rule pattern CDATA #REQUIRED>
+
+<!ELEMENT entry (title | subtitle | authors | binding | pur_date |
+pur_price | publisher | edition | cr_years | pub_year | isbn | lccn |
+pages | languages | genres | keywords | series | series_num |
+condition | signed | read | gift | loaned | rating | comments |
+entry-type | bibtex-key | booktitle | editors | organization | year |
+journal | month | number | howpublished | chapter | volume | crossref
+| note | medium | artists | album | label | tracks | certification |
+region | nationalitys | format | casts | directors | producers |
+writers | composers | studios | subtitles | audio-tracks |
+running-time | aspect-ratios | widescreen | color | directors-cut |
+plot | player | team | brand | location | quantity | front | back |
+mintmark | set | grade | service | obverse | reverse | issue | cover |
+description | scott | cancelled | hinged | centering | gummed |
+producer | appellation | varietal | vintage | type | drink-by |
+platform | publishers | developers | completed |url |
+mimetype | size | permissions | owner | group | created | modified |
+metainfos | icon | amazon | imdb | imdb-rating | alttitle |
+allcertification | address | abstract | designer | bggid |
+mechanism | num-players )+>
+<!ATTLIST entry id CDATA #REQUIRED>
+
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT subtitle (#PCDATA)>
+<!ELEMENT authors (author+)>
+<!ELEMENT author (#PCDATA)>
+<!ELEMENT binding (#PCDATA)>
+<!ELEMENT pur_date (#PCDATA)>
+<!ELEMENT pur_price (#PCDATA)>
+<!ELEMENT publisher (#PCDATA)>
+<!ELEMENT edition (#PCDATA)>
+<!ELEMENT cr_years (cr_year+)>
+<!ELEMENT cr_year (#PCDATA)>
+<!ELEMENT pub_year (#PCDATA)>
+<!ELEMENT isbn (#PCDATA)>
+<!ELEMENT lccn (#PCDATA)>
+<!ELEMENT pages (#PCDATA)>
+<!ELEMENT languages (language+)>
+<!ELEMENT language (#PCDATA)>
+<!ELEMENT genres (genre+)>
+<!ELEMENT genre (#PCDATA)>
+<!ELEMENT keywords (keyword+)>
+<!ELEMENT keyword (#PCDATA)>
+<!ELEMENT series (#PCDATA)>
+<!ELEMENT series_num (#PCDATA)>
+<!ELEMENT condition (#PCDATA)>
+<!ELEMENT signed (#PCDATA)>
+<!ELEMENT read (#PCDATA)>
+<!ELEMENT gift (#PCDATA)>
+<!ELEMENT rating (#PCDATA)>
+<!ELEMENT loaned (#PCDATA)>
+<!ELEMENT comments (#PCDATA)>
+
+<!-- bibtex -->
+<!ELEMENT entry-type (#PCDATA)>
+<!ELEMENT bibtex-key (#PCDATA)>
+<!ELEMENT booktitle (#PCDATA)>
+<!ELEMENT editors (editor+)>
+<!ELEMENT editor (#PCDATA)>
+<!ELEMENT organization (#PCDATA)>
+<!ELEMENT journal (#PCDATA)>
+<!ELEMENT number (#PCDATA)>
+<!ELEMENT howpublished (#PCDATA)>
+<!ELEMENT chapter (#PCDATA)>
+<!ELEMENT volume (#PCDATA)>
+<!ELEMENT crossref (#PCDATA)>
+<!ELEMENT note (#PCDATA)>
+<!ELEMENT address (#PCDATA)>
+<!ELEMENT abstract (#PCDATA)>
+
+<!-- music -->
+<!ELEMENT medium (#PCDATA)>
+<!ELEMENT artists (artist+)>
+<!ELEMENT artist (#PCDATA)>
+<!ELEMENT album (#PCDATA)>
+<!ELEMENT label (#PCDATA)>
+<!ELEMENT tracks (track+)>
+<!ELEMENT track (#PCDATA)>
+
+<!-- video -->
+<!ELEMENT certification (#PCDATA)>
+<!ELEMENT region (#PCDATA)>
+<!ELEMENT nationalitys (nationality+)>
+<!ELEMENT nationality (#PCDATA)>
+<!ELEMENT format (#PCDATA)>
+<!ELEMENT casts (cast+)>
+<!ELEMENT cast (column, column)>
+<!ELEMENT directors (director+)>
+<!ELEMENT director (#PCDATA)>
+<!ELEMENT producers (producer+)>
+<!ELEMENT producer (#PCDATA)>
+<!ELEMENT writers (writer+)>
+<!ELEMENT writer (#PCDATA)>
+<!ELEMENT composers (composer+)>
+<!ELEMENT composer (#PCDATA)>
+<!ELEMENT studios (studio+)>
+<!ELEMENT studio (#PCDATA)>
+<!ELEMENT subtitles (subtitle+)>
+<!-- subtitle element is defined above -->
+<!ELEMENT audio-tracks (audio-track+)>
+<!ELEMENT audio-track (#PCDATA)>
+<!ELEMENT running-time (#PCDATA)>
+<!ELEMENT aspect-ratios (aspect-ratio+)>
+<!ELEMENT aspect-ratio (#PCDATA)>
+<!ELEMENT widescreen (#PCDATA)>
+<!ELEMENT color (#PCDATA)>
+<!ELEMENT directors-cut (#PCDATA)>
+<!ELEMENT plot (#PCDATA)>
+
+<!-- cards -->
+<!ELEMENT player (#PCDATA)>
+<!ELEMENT team (#PCDATA)>
+<!ELEMENT brand (#PCDATA)>
+<!ELEMENT location (#PCDATA)>
+<!ELEMENT quantity (#PCDATA)>
+<!ELEMENT front (#PCDATA)>
+<!ELEMENT back (#PCDATA)>
+
+<!-- coins -->
+<!ELEMENT mintmark (#PCDATA)>
+<!ELEMENT set (#PCDATA)>
+<!ELEMENT grade (#PCDATA)>
+<!ELEMENT service (#PCDATA)>
+<!ELEMENT obverse (#PCDATA)>
+<!ELEMENT reverse (#PCDATA)>
+
+<!-- comic book -->
+<!ELEMENT issue (#PCDATA)>
+<!ELEMENT cover (#PCDATA)>
+
+<!-- stamps -->
+<!ELEMENT description (#PCDATA)>
+<!ELEMENT scott (#PCDATA)>
+<!ELEMENT cancelled (#PCDATA)>
+<!ELEMENT hinged (#PCDATA)>
+<!ELEMENT centering (#PCDATA)>
+<!ELEMENT gummed (#PCDATA)>
+
+<!-- wine -->
+<!ELEMENT appellation (#PCDATA)>
+<!ELEMENT varietal (#PCDATA)>
+<!ELEMENT vintage (#PCDATA)>
+<!ELEMENT type (#PCDATA)>
+<!ELEMENT drink-by (#PCDATA)>
+
+<!-- games -->
+<!ELEMENT platform (#PCDATA)>
+<!-- publisher is defined above -->
+<!ELEMENT publishers (publisher+)>
+<!ELEMENT developers (developer+)>
+<!ELEMENT developer (#PCDATA)>
+<!ELEMENT completed (#PCDATA)>
+
+<!-- file catalogs -->
+<!-- description is above -->
+<!ELEMENT url (#PCDATA)>
+<!ELEMENT mimetype (#PCDATA)>
+<!ELEMENT size (#PCDATA)>
+<!ELEMENT permissions (#PCDATA)>
+<!ELEMENT owner (#PCDATA)>
+<!ELEMENT group (#PCDATA)>
+<!ELEMENT created (#PCDATA)>
+<!ELEMENT modified (#PCDATA)>
+<!ELEMENT metainfos (metainfo+)>
+<!ELEMENT metainfo (#PCDATA)>
+<!ELEMENT icon (#PCDATA)>
+
+<!-- boardgames --?
+<!-- publisher is defined above -->
+<!-- publishers is defined above -->
+<!ELEMENT designers (designer+)>
+<!ELEMENT designer (#PCDATA)>
+<!ELEMENT mechanisms (mechanism+)>
+<!ELEMENT mechanism (#PCDATA)>
+<!ELEMENT bggid (#PCDATA)>
+<!ELEMENT num-players (num-player+)>
+<!ELEMENT num-player (#PCDATA)>
+
+<!-- special -->
+<!ELEMENT amazon (#PCDATA)>
+<!ELEMENT imdb (#PCDATA)>
+<!ELEMENT imdb-rating (#PCDATA)>
+<!ELEMENT alttitle (#PCDATA)>
+<!ELEMENT allcertification (#PCDATA)>
diff --git a/tellico.lsm b/tellico.lsm
new file mode 100644
index 0000000..1bdf44b
--- /dev/null
+++ b/tellico.lsm
@@ -0,0 +1,16 @@
+Begin4
+Title: Tellico
+Version: 1.3.2.1
+Entered-date: 2007-04-08
+Description: Tellico is a collection manager for books, bibliographies,
+ video, music, comic books, video games, coins, stamps,
+ trading cards, and wines.
+Primary-site: http://www.periapsis.org/tellico/
+Keywords: collection, books, bibliographies, video, music, comic books,
+ video games, coins, stamps, trading cards, wine
+Author: robby@periapsis.org (Robby Stephenson)
+Maintained-by: robby@periapsis.org (Robby Stephenson)
+Original-site:
+Platforms:
+Copying-policy: GPL
+End
diff --git a/tellico.tips b/tellico.tips
new file mode 100644
index 0000000..ffd8d87
--- /dev/null
+++ b/tellico.tips
@@ -0,0 +1,107 @@
+<tip category="Tellico">
+<html>
+<p>...that if a book has more than one author, you should separate
+their names by a semi-colon, so that Tellico will know how to split them
+and use them separately.</p>
+<p>Any other field which allows multiple values should be entered the
+same way, with a semi-colon (;) separating each value.</p>
+</html>
+</tip>
+<tip category="Tellico">
+<html>
+<p>...that you can change which fields are shown in the list view by
+right-clicking on the column header.
+</html>
+</tip>
+<tip category="Tellico">
+<html>
+<p>...that you can add, edit, or modify the fields in the collection using
+the Field Editor. The arrow buttons below the field list can be used to change the
+position of the field in the list, which affects the placement in the entry
+editor.</p>
+</html>
+</tip>
+<tip category="Tellico">
+<html>
+<p>...that if you want to filter by a Checkbox field, a value of
+"true" should be used. If you'd like to filter to
+show only the science fiction books which you've not read, for
+example, check the <em>Match all of the
+following</em> button, set the first rule to have "Genre"
+"contains" "Science Fiction" (no quotes) and the second rule to
+have "Read" "does not contain" "true" (no quotes).</p>
+</html>
+</tip>
+<tip category="Tellico">
+<html>
+<p>...that if a non-word character is used in the Quick Filter, the text is
+interpreted as a regular expression.</p>
+<p>To show only books which are by Weber or Bujold, for example, then
+type "weber|bujold" (no quotes) in the filter box.</p>
+</html>
+</tip>
+<tip category="Tellico">
+<html>
+<p>...that you can edit more than one entry at a time, by holding down
+the Shift or Ctrl key and selecting multiple entries.</p>
+</html>
+</tip>
+<tip category="Tellico">
+<html>
+<p>...that you can convert an existing book collection to a bibliography,
+which can then be exported to bibtex or Bibtexml format.</p>
+</html>
+</tip>
+<tip category="Tellico">
+<html>
+<p>...that you can add, edit, and delete string macros for bibliographies.</p>
+</html>
+</tip>
+<tip category="Tellico">
+<html>
+<p>...that if more than one field is formatted as a name, then an additional
+group named "People" is added to the collection, allowing authors and editors
+to be sorted or printed together, for example.</p>
+</html>
+</tip>
+<tip category="Tellico">
+<html>
+<p>...that you can modify the appearance of the printed output by modifying
+the <tt>tellico-printing.xsl</tt> file. The file generates HTML, and the CSS
+within the stylesheet governs things like the font, the margins, etc.</p>
+</html>
+</tip>
+<tip category="Tellico">
+<html>
+<p>...that you can import using any generic XSL stylesheet which
+outputs a valid Tellico XML file.</p>
+</html>
+</tip>
+<tip category="Tellico">
+<html>
+<p>...that double-clicking an entry item opens the Entry Editor.</p>
+</html>
+</tip>
+<tip category="Tellico">
+<html>
+<p>...that you can add HTML tags to any Paragraph field for formatting, such as
+&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>
+</html>
+</tip>
+<tip category="Tellico">
+<html>
+<p>...that in the Detailed View, you can press a letter on the
+keyboard to skip to the next entry that starts with that letter.</p>
+</html>
+</tip>
+<tip category="Tellico">
+<html>
+<p>...that you can use Dependent Fields to combine multiple separated fields
+into a single field. Just select the type Dependent and use a description
+similar to "Value: %{fielda}%{fieldb}" where %{...} gets replaced with the
+appropriate field value. This is useful to collect multiple values in a
+single field, e.g. for better grouping, and to combine fields of different
+types by respecting proper sorting at the same time. Consider for example
+a number field followed by a text subfield with entries 3b, 14a.</p>
+</html>
+</tip>
diff --git a/tellico.xml b/tellico.xml
new file mode 100644
index 0000000..2c29ef4
--- /dev/null
+++ b/tellico.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
+ <mime-type type="application/x-tellico">
+ <sub-class-of type="application/zip"/>
+ <comment>Tellico Data File</comment>
+ <comment xml:lang="cs">Datový soubor Tellico</comment>
+ <comment xml:lang="fr">Fichier Tellico</comment>
+ <comment xml:lang="ru">Файл Tellico</comment>
+ <glob pattern="*.tc"/>
+ <glob pattern="*.bc"/>
+ </mime-type>
+</mime-info>
diff --git a/x-tellico.desktop b/x-tellico.desktop
new file mode 100644
index 0000000..1476197
--- /dev/null
+++ b/x-tellico.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Comment=Tellico Data File
+Comment[ru]=Файл Tellico
+Comment[cs]=Datový soubor Tellico
+DefaultApp=tellico
+Icon=application-x-tellico
+MimeType=application/x-tellico
+Patterns=*.bc;*.tc;
+Type=MimeType;
+X-KDE-AutoEmbed=false
diff --git a/xslt/MARC21slim2MODS3.xsl b/xslt/MARC21slim2MODS3.xsl
new file mode 100644
index 0000000..f33e0bc
--- /dev/null
+++ b/xslt/MARC21slim2MODS3.xsl
@@ -0,0 +1,2517 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns="http://www.loc.gov/mods/v3" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xlink marc">
+ <xsl:include href="MARC21slimUtils.xsl"/>
+ <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
+
+<!-- This file is in the public domain. -->
+
+<!--
+
+Revision 1.10 MODS 3.1 revisions to language and classification elements 2006/02/06 ggar
+
+Revision 1.9 subfield $y was added to field 242 2004/09/02 10:57 jrad
+
+Revision 1.8 Subject chopPunctuation expanded and attribute fixes 2004/08/12 jrad
+
+Revision 1.7 2004/03/25 08:29 jrad
+
+Revision 1.6 various validation fixes 2004/02/20 ntra
+
+Revision 1.5 2003/10/02 16:18:58 ntra
+MODS2 to MODS3 updates, language unstacking and
+de-duping, chopPunctuation expanded
+
+Revision 1.3 2003/04/03 00:07:19 ntra
+Revision 1.3 Additional Changes not related to MODS Version 2.0 by ntra
+
+Revision 1.2 2003/03/24 19:37:42 ckeith
+Added Log Comment
+
+-->
+ <xsl:template match="/">
+ <modsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-1.xsd">
+ <xsl:for-each select=".//marc:record">
+ <mods version="3.1">
+ <xsl:call-template name="marcRecord"/>
+ </mods>
+ </xsl:for-each>
+ </modsCollection>
+ </xsl:template>
+ <xsl:template name="marcRecord">
+ <xsl:variable name="leader" select="marc:leader"/>
+ <xsl:variable name="leader6" select="substring($leader,7,1)"/>
+ <xsl:variable name="leader7" select="substring($leader,8,1)"/>
+ <xsl:variable name="controlField008" select="marc:controlfield[@tag=008]"/>
+ <xsl:variable name="typeOf008">
+ <xsl:choose>
+ <xsl:when test="$leader6='a'">
+ <xsl:choose>
+ <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">BK</xsl:when>
+ <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">SE</xsl:when>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="$leader6='t'">BK</xsl:when>
+ <xsl:when test="$leader6='p'">MM</xsl:when>
+ <xsl:when test="$leader6='m'">CF</xsl:when>
+ <xsl:when test="$leader6='e' or $leader6='f'">MP</xsl:when>
+ <xsl:when test="$leader6='g' or $leader6='k' or $leader6='o' or $leader6='r'">VM</xsl:when>
+ <xsl:when test="$leader6='c' or $leader6='d' or $leader6='i' or $leader6='j'">MU</xsl:when>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:for-each select="marc:datafield[@tag=245]">
+ <titleInfo>
+ <xsl:variable name="title">
+ <xsl:choose>
+ <xsl:when test="marc:subfield[@code='b']">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="axis">b</xsl:with-param>
+ <xsl:with-param name="beforeCodes">afghk</xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abfgk</xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="titleChop">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="$title"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="@ind2&gt;0">
+ <nonSort>
+ <xsl:value-of select="substring($titleChop,1,@ind2)"/>
+ </nonSort>
+ <title>
+ <xsl:value-of select="substring($titleChop,@ind2+1)"/>
+ </title>
+ </xsl:when>
+ <xsl:otherwise>
+ <title>
+ <xsl:value-of select="$titleChop"/>
+ </title>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:if test="marc:subfield[@code='b']">
+ <subTitle>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="axis">b</xsl:with-param>
+ <xsl:with-param name="anyCodes">b</xsl:with-param>
+ <xsl:with-param name="afterCodes">afghk</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </subTitle>
+ </xsl:if>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=210]">
+ <titleInfo type="abbreviated">
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">a</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="subtitle"/>
+ </titleInfo>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=242]">
+ <titleInfo type="translated">
+ <!--09/01/04 Added subfield $y-->
+ <xsl:for-each select="marc:subfield[@code='y']">
+ <xsl:attribute name="lang"><xsl:value-of select="text()"/></xsl:attribute>
+ </xsl:for-each>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <!-- 1/04 removed $h, b -->
+ <xsl:with-param name="codes">a</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <!-- 1/04 fix -->
+ <xsl:call-template name="subtitle"/>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=246]">
+ <titleInfo type="alternative">
+ <xsl:for-each select="marc:subfield[@code='i']">
+ <xsl:attribute name="displayLabel"><xsl:value-of select="text()"/></xsl:attribute>
+ </xsl:for-each>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <!-- 1/04 removed $h, $b -->
+ <xsl:with-param name="codes">af</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="subtitle"/>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=130]|marc:datafield[@tag=240]|marc:datafield[@tag=730][@ind2!=2]">
+ <titleInfo type="uniform">
+ <title>
+ <xsl:variable name="str">
+ <xsl:for-each select="marc:subfield">
+ <xsl:if test="(contains('adfklmor',@code) and (not(../marc:subfield[@code='n' or @code='p']) or (following-sibling::marc:subfield[@code='n' or @code='p'])))">
+ <xsl:value-of select="text()"/>
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=740][@ind2!=2]">
+ <titleInfo type="alternative">
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ah</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=100]">
+ <name type="personal">
+ <xsl:call-template name="nameABCDQ"/>
+ <xsl:call-template name="affiliation"/>
+ <role>
+ <roleTerm authority="marcrelator" type="text">creator</roleTerm>
+ </role>
+ <xsl:call-template name="role"/>
+ </name>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=110]">
+ <name type="corporate">
+ <xsl:call-template name="nameABCDN"/>
+ <role>
+ <roleTerm authority="marcrelator" type="text">creator</roleTerm>
+ </role>
+ <xsl:call-template name="role"/>
+ </name>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=111]">
+ <name type="conference">
+ <xsl:call-template name="nameACDEQ"/>
+ <role>
+ <roleTerm authority="marcrelator" type="text">creator</roleTerm>
+ </role>
+ <xsl:call-template name="role"/>
+ </name>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=700][not(marc:subfield[@code='t'])]">
+ <name type="personal">
+ <xsl:call-template name="nameABCDQ"/>
+ <xsl:call-template name="affiliation"/>
+ <xsl:call-template name="role"/>
+ </name>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=710][not(marc:subfield[@code='t'])]">
+ <name type="corporate">
+ <xsl:call-template name="nameABCDN"/>
+ <xsl:call-template name="role"/>
+ </name>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=711][not(marc:subfield[@code='t'])]">
+ <name type="conference">
+ <xsl:call-template name="nameACDEQ"/>
+ <xsl:call-template name="role"/>
+ </name>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=720][not(marc:subfield[@code='t'])]">
+ <name>
+ <xsl:if test="@ind1=1">
+ <xsl:attribute name="type"><xsl:text>personal</xsl:text></xsl:attribute>
+ </xsl:if>
+ <namePart>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </namePart>
+ <xsl:call-template name="role"/>
+ </name>
+ </xsl:for-each>
+ <typeOfResource>
+ <xsl:if test="$leader7='c'">
+ <xsl:attribute name="collection">yes</xsl:attribute>
+ </xsl:if>
+ <xsl:if test="$leader6='d' or $leader6='f' or $leader6='p' or $leader6='t'">
+ <xsl:attribute name="manuscript">yes</xsl:attribute>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="$leader6='a' or $leader6='t'">text</xsl:when>
+ <xsl:when test="$leader6='e' or $leader6='f'">cartographic</xsl:when>
+ <xsl:when test="$leader6='c' or $leader6='d'">notated music</xsl:when>
+ <xsl:when test="$leader6='i'">sound recording-nonmusical</xsl:when>
+ <xsl:when test="$leader6='j'">sound recording-musical</xsl:when>
+ <xsl:when test="$leader6='k'">still image</xsl:when>
+ <xsl:when test="$leader6='g'">moving image</xsl:when>
+ <xsl:when test="$leader6='r'">three dimensional object</xsl:when>
+ <xsl:when test="$leader6='m'">software, multimedia</xsl:when>
+ <xsl:when test="$leader6='p'">mixed material</xsl:when>
+ </xsl:choose>
+ </typeOfResource>
+ <xsl:if test="substring($controlField008,26,1)='d'">
+ <genre authority="marc">globe</genre>
+ </xsl:if>
+ <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
+ <genre authority="marc">remote sensing image</genre>
+ </xsl:if>
+ <xsl:if test="$typeOf008='MP'">
+ <xsl:variable name="controlField008-25" select="substring($controlField008,26,1)"/>
+ <xsl:choose>
+ <xsl:when test="$controlField008-25='a' or $controlField008-25='b' or $controlField008-25='c' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
+ <genre authority="marc">map</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-25='e' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
+ <genre authority="marc">atlas</genre>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+ <xsl:if test="$typeOf008='SE'">
+ <xsl:variable name="controlField008-21" select="substring($controlField008,22,1)"/>
+ <xsl:choose>
+ <xsl:when test="$controlField008-21='d'">
+ <genre authority="marc">database</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-21='l'">
+ <genre authority="marc">loose-leaf</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-21='m'">
+ <genre authority="marc">series</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-21='n'">
+ <genre authority="marc">newspaper</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-21='p'">
+ <genre authority="marc">periodical</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-21='w'">
+ <genre authority="marc">web site</genre>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+ <xsl:if test="$typeOf008='BK' or $typeOf008='SE'">
+ <xsl:variable name="controlField008-24" select="substring($controlField008,25,4)"/>
+ <xsl:choose>
+ <xsl:when test="contains($controlField008-24,'a')">
+ <genre authority="marc">abstract or summary</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'b')">
+ <genre authority="marc">bibliography</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'c')">
+ <genre authority="marc">catalog</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'d')">
+ <genre authority="marc">dictionary</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'e')">
+ <genre authority="marc">encyclopedia</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'f')">
+ <genre authority="marc">handbook</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'g')">
+ <genre authority="marc">legal article</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'i')">
+ <genre authority="marc">index</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'k')">
+ <genre authority="marc">discography</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'l')">
+ <genre authority="marc">legislation</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'m')">
+ <genre authority="marc">theses</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'n')">
+ <genre authority="marc">survey of literature</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'o')">
+ <genre authority="marc">review</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'p')">
+ <genre authority="marc">programmed text</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'q')">
+ <genre authority="marc">filmography</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'r')">
+ <genre authority="marc">directory</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'s')">
+ <genre authority="marc">statistics</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'t')">
+ <genre authority="marc">technical report</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'v')">
+ <genre authority="marc">legal case and case notes</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'w')">
+ <genre authority="marc">law report or digest</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'z')">
+ <genre authority="marc">treaty</genre>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"/>
+ <xsl:choose>
+ <xsl:when test="$controlField008-29='1'">
+ <genre authority="marc">conference publication</genre>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+ <xsl:if test="$typeOf008='CF'">
+ <xsl:variable name="controlField008-26" select="substring($controlField008,27,1)"/>
+ <xsl:choose>
+ <xsl:when test="$controlField008-26='a'">
+ <genre authority="marc">numeric data</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-26='e'">
+ <genre authority="marc">database</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-26='f'">
+ <genre authority="marc">font</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-26='g'">
+ <genre authority="marc">game</genre>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+ <xsl:if test="$typeOf008='BK'">
+ <xsl:if test="substring($controlField008,25,1)='j'">
+ <genre authority="marc">patent</genre>
+ </xsl:if>
+ <xsl:if test="substring($controlField008,31,1)='1'">
+ <genre authority="marc">festschrift</genre>
+ </xsl:if>
+ <xsl:variable name="controlField008-34" select="substring($controlField008,35,1)"/>
+ <xsl:if test="$controlField008-34='a' or $controlField008-34='b' or $controlField008-34='c' or $controlField008-34='d'">
+ <genre authority="marc">biography</genre>
+ </xsl:if>
+ <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"/>
+ <xsl:choose>
+ <xsl:when test="$controlField008-33='e'">
+ <genre authority="marc">essay</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='d'">
+ <genre authority="marc">drama</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='c'">
+ <genre authority="marc">comic strip</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='l'">
+ <genre authority="marc">fiction</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='h'">
+ <genre authority="marc">humor, satire</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='i'">
+ <genre authority="marc">letter</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='f'">
+ <genre authority="marc">novel</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='j'">
+ <genre authority="marc">short story</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='s'">
+ <genre authority="marc">speech</genre>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+ <xsl:if test="$typeOf008='MU'">
+ <xsl:variable name="controlField008-30-31" select="substring($controlField008,31,2)"/>
+ <xsl:if test="contains($controlField008-30-31,'b')">
+ <genre authority="marc">biography</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'c')">
+ <genre authority="marc">conference publication</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'d')">
+ <genre authority="marc">drama</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'e')">
+ <genre authority="marc">essay</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'f')">
+ <genre authority="marc">fiction</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'o')">
+ <genre authority="marc">folktale</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'h')">
+ <genre authority="marc">history</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'k')">
+ <genre authority="marc">humor, satire</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'m')">
+ <genre authority="marc">memoir</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'p')">
+ <genre authority="marc">poetry</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'r')">
+ <genre authority="marc">rehearsal</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'g')">
+ <genre authority="marc">reporting</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'s')">
+ <genre authority="marc">sound</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'l')">
+ <genre authority="marc">speech</genre>
+ </xsl:if>
+ </xsl:if>
+ <xsl:if test="$typeOf008='VM'">
+ <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"/>
+ <xsl:choose>
+ <xsl:when test="$controlField008-33='a'">
+ <genre authority="marc">art original</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='b'">
+ <genre authority="marc">kit</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='c'">
+ <genre authority="marc">art reproduction</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='d'">
+ <genre authority="marc">diorama</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='f'">
+ <genre authority="marc">filmstrip</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='g'">
+ <genre authority="marc">legal article</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='i'">
+ <genre authority="marc">picture</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='k'">
+ <genre authority="marc">graphic</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='l'">
+ <genre authority="marc">technical drawing</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='m'">
+ <genre authority="marc">motion picture</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='n'">
+ <genre authority="marc">chart</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='o'">
+ <genre authority="marc">flash card</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='p'">
+ <genre authority="marc">microscope slide</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='q' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
+ <genre authority="marc">model</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='r'">
+ <genre authority="marc">realia</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='s'">
+ <genre authority="marc">slide</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='t'">
+ <genre authority="marc">transparency</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='v'">
+ <genre authority="marc">videorecording</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='w'">
+ <genre authority="marc">toy</genre>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+ <xsl:for-each select="marc:datafield[@tag=655]">
+ <genre authority="marc">
+ <xsl:attribute name="authority"><xsl:value-of select="marc:subfield[@code='2']"/></xsl:attribute>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abvxyz</xsl:with-param>
+ <xsl:with-param name="delimeter">-</xsl:with-param>
+ </xsl:call-template>
+ </genre>
+ </xsl:for-each>
+ <originInfo>
+ <xsl:variable name="MARCpublicationCode" select="normalize-space(substring($controlField008,16,3))"/>
+ <xsl:if test="translate($MARCpublicationCode,'|','')">
+ <place>
+ <placeTerm>
+ <xsl:attribute name="type">code</xsl:attribute>
+ <xsl:attribute name="authority">marccountry</xsl:attribute>
+ <xsl:value-of select="$MARCpublicationCode"/>
+ </placeTerm>
+ </place>
+ </xsl:if>
+ <xsl:for-each select="marc:datafield[@tag=044]/marc:subfield[@code='c']">
+ <place>
+ <placeTerm>
+ <xsl:attribute name="type">code</xsl:attribute>
+ <xsl:attribute name="authority">iso3166</xsl:attribute>
+ <xsl:value-of select="."/>
+ </placeTerm>
+ </place>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='a']">
+ <place>
+ <placeTerm>
+ <xsl:attribute name="type">text</xsl:attribute>
+ <xsl:call-template name="chopPunctuationFront">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </placeTerm>
+ </place>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='m']">
+ <dateValid point="start">
+ <xsl:value-of select="."/>
+ </dateValid>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='n']">
+ <dateValid point="end">
+ <xsl:value-of select="."/>
+ </dateValid>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='j']">
+ <dateModified>
+ <xsl:value-of select="."/>
+ </dateModified>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='b' or @code='c' or @code='g']">
+ <xsl:choose>
+ <xsl:when test="@code='b'">
+ <publisher>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ <xsl:with-param name="punctuation">
+ <xsl:text>:,;/ </xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </publisher>
+ </xsl:when>
+ <xsl:when test="@code='c'">
+ <dateIssued>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </dateIssued>
+ </xsl:when>
+ <xsl:when test="@code='g'">
+ <dateCreated>
+ <xsl:value-of select="."/>
+ </dateCreated>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:for-each>
+ <xsl:variable name="dataField260c">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="marc:datafield[@tag=260]/marc:subfield[@code='c']"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="controlField008-7-10" select="normalize-space(substring($controlField008, 8, 4))"/>
+ <xsl:variable name="controlField008-11-14" select="normalize-space(substring($controlField008, 12, 4))"/>
+ <xsl:variable name="controlField008-6" select="normalize-space(substring($controlField008, 7, 1))"/>
+ <xsl:if test="$controlField008-6='e' or $controlField008-6='p' or $controlField008-6='r' or $controlField008-6='t' or $controlField008-6='s'">
+ <xsl:if test="$controlField008-7-10 and ($controlField008-7-10 != $dataField260c)">
+ <dateIssued encoding="marc">
+ <xsl:value-of select="$controlField008-7-10"/>
+ </dateIssued>
+ </xsl:if>
+ </xsl:if>
+ <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
+ <xsl:if test="$controlField008-7-10">
+ <dateIssued encoding="marc" point="start">
+ <xsl:value-of select="$controlField008-7-10"/>
+ </dateIssued>
+ </xsl:if>
+ </xsl:if>
+ <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
+ <xsl:if test="$controlField008-11-14">
+ <dateIssued encoding="marc" point="end">
+ <xsl:value-of select="$controlField008-11-14"/>
+ </dateIssued>
+ </xsl:if>
+ </xsl:if>
+ <xsl:if test="$controlField008-6='q'">
+ <xsl:if test="$controlField008-7-10">
+ <dateIssued encoding="marc" point="start" qualifier="questionable">
+ <xsl:value-of select="$controlField008-7-10"/>
+ </dateIssued>
+ </xsl:if>
+ </xsl:if>
+ <xsl:if test="$controlField008-6='q'">
+ <xsl:if test="$controlField008-11-14">
+ <dateIssued encoding="marc" point="end" qualifier="questionable">
+ <xsl:value-of select="$controlField008-11-14"/>
+ </dateIssued>
+ </xsl:if>
+ </xsl:if>
+ <xsl:if test="$controlField008-6='t'">
+ <xsl:if test="$controlField008-11-14">
+ <copyrightDate encoding="marc">
+ <xsl:value-of select="$controlField008-11-14"/>
+ </copyrightDate>
+ </xsl:if>
+ </xsl:if>
+ <xsl:for-each select="marc:datafield[@tag=033][@ind1=0 or @ind1=1]/marc:subfield[@code='a']">
+ <dateCaptured encoding="iso8601">
+ <xsl:value-of select="."/>
+ </dateCaptured>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][1]">
+ <dateCaptured encoding="iso8601" point="start">
+ <xsl:value-of select="."/>
+ </dateCaptured>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][2]">
+ <dateCaptured encoding="iso8601" point="end">
+ <xsl:value-of select="."/>
+ </dateCaptured>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=250]/marc:subfield[@code='a']">
+ <edition>
+ <xsl:value-of select="."/>
+ </edition>
+ </xsl:for-each>
+ <xsl:for-each select="marc:leader">
+ <issuance>
+ <xsl:choose>
+ <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">monographic</xsl:when>
+ <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">continuing</xsl:when>
+ </xsl:choose>
+ </issuance>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=310]|marc:datafield[@tag=321]">
+ <frequency>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </frequency>
+ </xsl:for-each>
+ </originInfo>
+ <xsl:variable name="controlField008-35-37" select="normalize-space(translate(substring($controlField008,36,3),'|#',''))"/>
+ <xsl:if test="$controlField008-35-37">
+ <language>
+ <languageTerm authority="iso639-2b" type="code">
+ <xsl:value-of select="substring($controlField008,36,3)"/>
+ </languageTerm>
+ </language>
+ </xsl:if>
+ <xsl:for-each select="marc:datafield[@tag=041]">
+ <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='d' or @code='e' or @code='f' or @code='g' or @code='h']">
+ <xsl:variable name="langCodes" select="."/>
+ <xsl:choose>
+ <xsl:when test="../marc:subfield[@code='2']='rfc3066'">
+ <!-- not stacked but could be repeated -->
+ <xsl:call-template name="rfcLanguages">
+ <xsl:with-param name="nodeNum">
+ <xsl:value-of select="1"/>
+ </xsl:with-param>
+ <xsl:with-param name="usedLanguages">
+ <xsl:text/>
+ </xsl:with-param>
+ <xsl:with-param name="controlField008-35-37">
+ <xsl:value-of select="$controlField008-35-37"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- iso -->
+ <xsl:variable name="allLanguages">
+ <xsl:copy-of select="$langCodes"/>
+ </xsl:variable>
+ <xsl:variable name="currentLanguage">
+ <xsl:value-of select="substring($allLanguages,1,3)"/>
+ </xsl:variable>
+ <xsl:call-template name="isoLanguage">
+ <xsl:with-param name="currentLanguage">
+ <xsl:value-of select="substring($allLanguages,1,3)"/>
+ </xsl:with-param>
+ <xsl:with-param name="remainingLanguages">
+ <xsl:value-of select="substring($allLanguages,4,string-length($allLanguages)-3)"/>
+ </xsl:with-param>
+ <xsl:with-param name="usedLanguages">
+ <xsl:if test="$controlField008-35-37">
+ <xsl:value-of select="$controlField008-35-37"/>
+ </xsl:if>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:for-each>
+ <xsl:variable name="physicalDescription">
+ <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='a' or substring(.,12,1)='b']">
+ <digitalOrigin>reformatted digital</digitalOrigin>
+ </xsl:if>
+ <xsl:variable name="controlField008-23" select="substring($controlField008,24,1)"/>
+ <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"/>
+ <xsl:variable name="check008-23">
+ <xsl:if test="$typeOf008='BK' or $typeOf008='MU' or $typeOf008='SE' or $typeOf008='MM'">
+ <xsl:value-of select="true()"/>
+ </xsl:if>
+ </xsl:variable>
+ <xsl:variable name="check008-29">
+ <xsl:if test="$typeOf008='MP' or $typeOf008='VM'">
+ <xsl:value-of select="true()"/>
+ </xsl:if>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="($check008-23 and $controlField008-23='f') or ($check008-29 and $controlField008-29='f')">
+ <form authority="marcform">braille</form>
+ </xsl:when>
+ <xsl:when test="($controlField008-23=' ' and ($leader6='c' or $leader6='d')) or (($typeOf008='BK' or $typeOf008='SE') and ($controlField008-23=' ' or $controlField008='r'))">
+ <form authority="marcform">print</form>
+ </xsl:when>
+ <xsl:when test="$leader6 = 'm' or ($check008-23 and $controlField008-23='s') or ($check008-29 and $controlField008-29='s')">
+ <form authority="marcform">electronic</form>
+ </xsl:when>
+ <xsl:when test="($check008-23 and $controlField008-23='b') or ($check008-29 and $controlField008-29='b')">
+ <form authority="marcform">microfiche</form>
+ </xsl:when>
+ <xsl:when test="($check008-23 and $controlField008-23='a') or ($check008-29 and $controlField008-29='a')">
+ <form authority="marcform">microfilm</form>
+ </xsl:when>
+ </xsl:choose>
+ <!-- 1/04 fix -->
+ <xsl:if test="marc:datafield[@tag=130]/marc:subfield[@code='h']">
+ <form authority="gmd">
+ <xsl:call-template name="chopBrackets">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:datafield[@tag=130]/marc:subfield[@code='h']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </form>
+ </xsl:if>
+ <xsl:if test="marc:datafield[@tag=240]/marc:subfield[@code='h']">
+ <form authority="gmd">
+ <xsl:call-template name="chopBrackets">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:datafield[@tag=240]/marc:subfield[@code='h']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </form>
+ </xsl:if>
+ <xsl:if test="marc:datafield[@tag=242]/marc:subfield[@code='h']">
+ <form authority="gmd">
+ <xsl:call-template name="chopBrackets">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:datafield[@tag=242]/marc:subfield[@code='h']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </form>
+ </xsl:if>
+ <xsl:if test="marc:datafield[@tag=245]/marc:subfield[@code='h']">
+ <form authority="gmd">
+ <xsl:call-template name="chopBrackets">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:datafield[@tag=245]/marc:subfield[@code='h']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </form>
+ </xsl:if>
+ <xsl:if test="marc:datafield[@tag=246]/marc:subfield[@code='h']">
+ <form authority="gmd">
+ <xsl:call-template name="chopBrackets">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:datafield[@tag=246]/marc:subfield[@code='h']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </form>
+ </xsl:if>
+ <xsl:if test="marc:datafield[@tag=730]/marc:subfield[@code='h']">
+ <form authority="gmd">
+ <xsl:call-template name="chopBrackets">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:datafield[@tag=730]/marc:subfield[@code='h']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </form>
+ </xsl:if>
+ <xsl:for-each select="marc:datafield[@tag=256]/marc:subfield[@code='a']">
+ <form>
+ <xsl:value-of select="."/>
+ </form>
+ </xsl:for-each>
+ <xsl:for-each select="marc:controlfield[@tag=007][substring(text(),1,1)='c']">
+ <xsl:choose>
+ <xsl:when test="substring(text(),14,1)='a'">
+ <reformattingQuality>access</reformattingQuality>
+ </xsl:when>
+ <xsl:when test="substring(text(),14,1)='p'">
+ <reformattingQuality>preservation</reformattingQuality>
+ </xsl:when>
+ <xsl:when test="substring(text(),14,1)='r'">
+ <reformattingQuality>replacement</reformattingQuality>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=856]/marc:subfield[@code='q'][string-length(.)&gt;1]">
+ <internetMediaType>
+ <xsl:value-of select="."/>
+ </internetMediaType>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=300]">
+ <extent>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abce</xsl:with-param>
+ </xsl:call-template>
+ </extent>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:if test="string-length(normalize-space($physicalDescription))">
+ <physicalDescription>
+ <xsl:copy-of select="$physicalDescription"/>
+ </physicalDescription>
+ </xsl:if>
+ <xsl:for-each select="marc:datafield[@tag=520]">
+ <abstract>
+ <xsl:call-template name="uri"/>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </abstract>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=505]">
+ <tableOfContents>
+ <xsl:call-template name="uri"/>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">agrt</xsl:with-param>
+ </xsl:call-template>
+ </tableOfContents>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=521]">
+ <targetAudience>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </targetAudience>
+ </xsl:for-each>
+ <xsl:if test="$typeOf008='BK' or $typeOf008='CF' or $typeOf008='MU' or $typeOf008='VM'">
+ <xsl:variable name="controlField008-22" select="substring($controlField008,23,1)"/>
+ <xsl:choose>
+ <!-- 01/04 fix -->
+ <xsl:when test="$controlField008-22='d'">
+ <targetAudience authority="marctarget">adolescent</targetAudience>
+ </xsl:when>
+ <xsl:when test="$controlField008-22='e'">
+ <targetAudience authority="marctarget">adult</targetAudience>
+ </xsl:when>
+ <xsl:when test="$controlField008-22='g'">
+ <targetAudience authority="marctarget">general</targetAudience>
+ </xsl:when>
+ <xsl:when test="$controlField008-22='b' or $controlField008-22='c' or $controlField008-22='j'">
+ <targetAudience authority="marctarget">juvenile</targetAudience>
+ </xsl:when>
+ <xsl:when test="$controlField008-22='a'">
+ <targetAudience authority="marctarget">preschool</targetAudience>
+ </xsl:when>
+ <xsl:when test="$controlField008-22='f'">
+ <targetAudience authority="marctarget">specialized</targetAudience>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+ <xsl:for-each select="marc:datafield[@tag=245]/marc:subfield[@code='c']">
+ <note type="statement of responsibility">
+ <xsl:value-of select="."/>
+ </note>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=500]">
+ <note>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ <xsl:call-template name="uri"/>
+ </note>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=511]">
+ <note type="performers">
+ <xsl:call-template name="uri"/>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </note>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=518]">
+ <note type="venue">
+ <xsl:call-template name="uri"/>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </note>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=501 or @tag=502 or @tag=504 or @tag=506 or @tag=507 or @tag=508 or @tag=513 or @tag=514 or @tag=515 or @tag=516 or @tag=522 or @tag=524 or @tag=525 or @tag=526 or @tag=530 or @tag=533 or @tag=534 or @tag=535 or @tag=536 or @tag=538 or @tag=540 or @tag=541 or @tag=544 or @tag=545 or @tag=546 or @tag=547 or @tag=550 or @tag=552 or @tag=555 or @tag=556 or @tag=561 or @tag=562 or @tag=565 or @tag=567 or @tag=580 or @tag=581 or @tag=583 or @tag=584 or @tag=585 or @tag=586]">
+ <note>
+ <xsl:call-template name="uri"/>
+ <xsl:variable name="str">
+ <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+ <xsl:value-of select="."/>
+ <xsl:text> </xsl:text>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+ </note>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=034][marc:subfield[@code='d' or @code='e' or @code='f' or @code='g']]">
+ <subject>
+ <cartographics>
+ <coordinates>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">defg</xsl:with-param>
+ </xsl:call-template>
+ </coordinates>
+ </cartographics>
+ </subject>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=043]">
+ <subject>
+ <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
+ <geographicCode>
+ <xsl:attribute name="authority"><xsl:if test="@code='a'"><xsl:text>marcgac</xsl:text></xsl:if><xsl:if test="@code='b'"><xsl:value-of select="following-sibling::marc:subfield[@code=2]"/></xsl:if><xsl:if test="@code='c'"><xsl:text>iso3166</xsl:text></xsl:if></xsl:attribute>
+ <xsl:value-of select="self::marc:subfield"/>
+ </geographicCode>
+ </xsl:for-each>
+ </subject>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=255]">
+ <subject>
+ <cartographics>
+ <xsl:for-each select="marc:subfield[@code='c']">
+ <coordinates>
+ <xsl:value-of select="."/>
+ </coordinates>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <scale>
+ <xsl:value-of select="."/>
+ </scale>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <projection>
+ <xsl:value-of select="."/>
+ </projection>
+ </xsl:for-each>
+ </cartographics>
+ </subject>
+ </xsl:for-each>
+ <xsl:apply-templates select="marc:datafield[653 &gt;= @tag and @tag &gt;= 600]"/>
+ <xsl:apply-templates select="marc:datafield[@tag=656]"/>
+ <xsl:for-each select="marc:datafield[@tag=752]">
+ <subject>
+ <hierarchicalGeographic>
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <country>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </country>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <state>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </state>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='c']">
+ <county>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </county>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='d']">
+ <city>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </city>
+ </xsl:for-each>
+ </hierarchicalGeographic>
+ </subject>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=045][marc:subfield[@code='b']]">
+ <subject>
+ <xsl:choose>
+ <xsl:when test="@ind1=2">
+ <temporal encoding="iso8601" point="start">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:subfield[@code='b'][1]"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </temporal>
+ <temporal encoding="iso8601" point="end">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:subfield[@code='b'][2]"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </temporal>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <temporal encoding="iso8601">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </temporal>
+ </xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
+ </subject>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=055]">
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <classification authority="lcc">
+ <xsl:value-of select="preceding-sibling::marc:subfield[@code='a'][1]"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="text()"/>
+ </classification>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='a'][not(following-sibling::marc:subfield[@code='b'])]">
+ <classification authority="lcc">
+ <xsl:value-of select="text()"/>
+ </classification>
+ </xsl:for-each>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=050]">
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <classification authority="lcc">
+ <xsl:if test="../marc:subfield[@code='3']">
+ <xsl:attribute name="displayLabel"><xsl:value-of select="../marc:subfield[@code='3']"/></xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="preceding-sibling::marc:subfield[@code='a'][1]"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="text()"/>
+ </classification>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='a'][not(following-sibling::marc:subfield[@code='b'])]">
+ <classification authority="lcc">
+ <xsl:if test="../marc:subfield[@code='3']">
+ <xsl:attribute name="displayLabel"><xsl:value-of select="../marc:subfield[@code='3']"/></xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="text()"/>
+ </classification>
+ </xsl:for-each>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=082]">
+ <classification authority="ddc">
+ <xsl:if test="marc:subfield[@code='2']">
+ <xsl:attribute name="edition"><xsl:value-of select="marc:subfield[@code='2']"/></xsl:attribute>
+ </xsl:if>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </classification>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=080]">
+ <classification authority="udc">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abx</xsl:with-param>
+ </xsl:call-template>
+ </classification>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=060]">
+ <classification authority="nlm">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </classification>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=086][@ind1=0]">
+ <classification authority="sudocs">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </classification>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=086][@ind1=1]">
+ <classification authority="candoc">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </classification>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=086]">
+ <classification>
+ <xsl:attribute name="authority"><xsl:value-of select="marc:subfield[@code='2']"/></xsl:attribute>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </classification>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=084]">
+ <classification>
+ <xsl:attribute name="authority"><xsl:value-of select="marc:subfield[@code='2']"/></xsl:attribute>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </classification>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=440]">
+ <relatedItem type="series">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">av</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=490][@ind1=0]">
+ <relatedItem type="series">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">av</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=510]">
+ <relatedItem type="isReferencedBy">
+ <note>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcx3</xsl:with-param>
+ </xsl:call-template>
+ </note>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=534]">
+ <relatedItem type="original">
+ <xsl:call-template name="relatedTitle"/>
+ <xsl:call-template name="relatedName"/>
+ <xsl:if test="marc:subfield[@code='b' or @code='c']">
+ <originInfo>
+ <xsl:for-each select="marc:subfield[@code='c']">
+ <publisher>
+ <xsl:value-of select="."/>
+ </publisher>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <edition>
+ <xsl:value-of select="."/>
+ </edition>
+ </xsl:for-each>
+ </originInfo>
+ </xsl:if>
+ <xsl:call-template name="relatedIdentifierISSN"/>
+ <xsl:for-each select="marc:subfield[@code='z']">
+ <identifier type="isbn">
+ <xsl:value-of select="."/>
+ </identifier>
+ </xsl:for-each>
+ <xsl:call-template name="relatedNote"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=700][marc:subfield[@code='t']]">
+ <relatedItem>
+ <xsl:call-template name="constituentOrRelatedType"/>
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="afterCodes">g</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ <name type="personal">
+ <namePart>
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">aq</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="beforeCodes">g</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ <xsl:call-template name="termsOfAddress"/>
+ <xsl:call-template name="nameDate"/>
+ <xsl:call-template name="role"/>
+ </name>
+ <xsl:call-template name="relatedForm"/>
+ <xsl:call-template name="relatedIdentifierISSN"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=710][marc:subfield[@code='t']]">
+ <relatedItem>
+ <xsl:call-template name="constituentOrRelatedType"/>
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="afterCodes">dg</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="relatedPartNumName"/>
+ </titleInfo>
+ <name type="corporate">
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </xsl:for-each>
+ <xsl:variable name="tempNamePart">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">c</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:if test="normalize-space($tempNamePart)">
+ <namePart>
+ <xsl:value-of select="$tempNamePart"/>
+ </namePart>
+ </xsl:if>
+ <xsl:call-template name="role"/>
+ </name>
+ <xsl:call-template name="relatedForm"/>
+ <xsl:call-template name="relatedIdentifierISSN"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=711][marc:subfield[@code='t']]">
+ <relatedItem>
+ <xsl:call-template name="constituentOrRelatedType"/>
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="afterCodes">g</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="relatedPartNumName"/>
+ </titleInfo>
+ <name type="conference">
+ <namePart>
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="beforeCodes">gn</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ </name>
+ <xsl:call-template name="relatedForm"/>
+ <xsl:call-template name="relatedIdentifierISSN"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=730][@ind2=2]">
+ <relatedItem>
+ <xsl:call-template name="constituentOrRelatedType"/>
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ <xsl:call-template name="relatedForm"/>
+ <xsl:call-template name="relatedIdentifierISSN"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=740][@ind2=2]">
+ <relatedItem>
+ <xsl:call-template name="constituentOrRelatedType"/>
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ <xsl:call-template name="relatedForm"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=760]|marc:datafield[@tag=762]">
+ <relatedItem type="series">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=765]|marc:datafield[@tag=767]|marc:datafield[@tag=777]|marc:datafield[@tag=787]">
+ <relatedItem>
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=775]">
+ <relatedItem type="otherVersion">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=770]|marc:datafield[@tag=774]">
+ <relatedItem type="constituent">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=772]|marc:datafield[@tag=773]">
+ <relatedItem type="host">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=776]">
+ <relatedItem type="otherFormat">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=780]">
+ <relatedItem type="preceding">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=785]">
+ <relatedItem type="succeeding">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=786]">
+ <relatedItem type="original">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=800]">
+ <relatedItem type="series">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="afterCodes">g</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ <name type="personal">
+ <namePart>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">aq</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="beforeCodes">g</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ <xsl:call-template name="termsOfAddress"/>
+ <xsl:call-template name="nameDate"/>
+ <xsl:call-template name="role"/>
+ </name>
+ <xsl:call-template name="relatedForm"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=810]">
+ <relatedItem type="series">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="afterCodes">dg</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="relatedPartNumName"/>
+ </titleInfo>
+ <name type="corporate">
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </xsl:for-each>
+ <namePart>
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">c</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ <xsl:call-template name="role"/>
+ </name>
+ <xsl:call-template name="relatedForm"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=811]">
+ <relatedItem type="series">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="afterCodes">g</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="relatedPartNumName"/>
+ </titleInfo>
+ <name type="conference">
+ <namePart>
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="beforeCodes">gn</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ <xsl:call-template name="role"/>
+ </name>
+ <xsl:call-template name="relatedForm"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=830]">
+ <relatedItem type="series">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ <xsl:call-template name="relatedForm"/>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=856][@ind2=2]/marc:subfield[@code='q']">
+ <relatedItem>
+ <internetMediaType>
+ <xsl:value-of select="."/>
+ </internetMediaType>
+ </relatedItem>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=020]">
+ <identifier type="isbn">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </identifier>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=024][@ind1=0]">
+ <identifier type="isrc">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </identifier>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=024][@ind1=2]">
+ <identifier type="ismn">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </identifier>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=022]">
+ <identifier type="issn">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </identifier>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=010]">
+ <identifier type="lccn">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:value-of select="normalize-space(marc:subfield[@code='a'])"/>
+ </identifier>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=028]">
+ <identifier>
+ <xsl:call-template name="isInvalid"/>
+ <xsl:attribute name="type"><xsl:choose><xsl:when test="@ind1=0">issue number</xsl:when><xsl:when test="@ind1=1">matrix number</xsl:when><xsl:when test="@ind1=2">music plate</xsl:when><xsl:when test="@ind1=3">music publisher</xsl:when><xsl:when test="@ind1=4">videorecording identifier</xsl:when></xsl:choose></xsl:attribute>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">
+ <xsl:choose>
+ <xsl:when test="@ind1=0">ba</xsl:when>
+ <xsl:otherwise>ab</xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ </xsl:call-template>
+ </identifier>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=024][@ind1='4']">
+ <identifier type="sici">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </identifier>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=037]">
+ <identifier type="stock number">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </identifier>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=856][marc:subfield[@code='u']]">
+ <identifier>
+ <xsl:attribute name="type"><xsl:choose><xsl:when test="starts-with(marc:subfield[@code='u'],'urn:doi') or starts-with(marc:subfield[@code='u'],'doi')">doi</xsl:when><xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov')">hdl</xsl:when><xsl:otherwise>uri</xsl:otherwise></xsl:choose></xsl:attribute>
+ <xsl:choose>
+ <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov') ">
+ <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="marc:subfield[@code='u']"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </identifier>
+ <xsl:if test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl')">
+ <identifier type="hdl">
+ <xsl:if test="marc:subfield[@code='y' or @code='3' or @code='z']">
+ <xsl:attribute name="displayLabel"><xsl:call-template name="subfieldSelect"><xsl:with-param name="codes">y3z</xsl:with-param></xsl:call-template></xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"/>
+ </identifier>
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=024][@ind1=1]">
+ <identifier type="upc">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </identifier>
+ </xsl:for-each>
+ <!-- 1/04 fix added $y -->
+ <xsl:for-each select="marc:datafield[@tag=856][marc:subfield[@code='u']]">
+ <location>
+ <url>
+ <xsl:if test="marc:subfield[@code='y' or @code='3']">
+ <xsl:attribute name="displayLabel"><xsl:call-template name="subfieldSelect"><xsl:with-param name="codes">y3</xsl:with-param></xsl:call-template></xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="marc:subfield[@code='u']"/>
+ </url>
+ </location>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=852]">
+ <location>
+ <physicalLocation>
+ <xsl:call-template name="displayLabel"/>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abje</xsl:with-param>
+ </xsl:call-template>
+ </physicalLocation>
+ </location>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=506]">
+ <accessCondition type="restrictionOnAccess">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcd35</xsl:with-param>
+ </xsl:call-template>
+ </accessCondition>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=540]">
+ <accessCondition type="useAndReproduction">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcde35</xsl:with-param>
+ </xsl:call-template>
+ </accessCondition>
+ </xsl:for-each>
+ <recordInfo>
+ <xsl:for-each select="marc:datafield[@tag=040]">
+ <recordContentSource authority="marcorg">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </recordContentSource>
+ </xsl:for-each>
+ <xsl:for-each select="marc:controlfield[@tag=008]">
+ <recordCreationDate encoding="marc">
+ <xsl:value-of select="substring(.,1,6)"/>
+ </recordCreationDate>
+ </xsl:for-each>
+ <xsl:for-each select="marc:controlfield[@tag=005]">
+ <recordChangeDate encoding="iso8601">
+ <xsl:value-of select="."/>
+ </recordChangeDate>
+ </xsl:for-each>
+ <xsl:for-each select="marc:controlfield[@tag=001]">
+ <recordIdentifier>
+ <xsl:if test="../marc:controlfield[@tag=003]">
+ <xsl:attribute name="source"><xsl:value-of select="../marc:controlfield[@tag=003]"/></xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="."/>
+ </recordIdentifier>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=040]/marc:subfield[@code='b']">
+ <languageOfCataloging>
+ <languageTerm authority="iso639-2b" type="code">
+ <xsl:value-of select="."/>
+ </languageTerm>
+ </languageOfCataloging>
+ </xsl:for-each>
+ </recordInfo>
+ </xsl:template>
+ <xsl:template name="displayForm">
+ <xsl:for-each select="marc:subfield[@code='c']">
+ <displayForm>
+ <xsl:value-of select="."/>
+ </displayForm>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="affiliation">
+ <xsl:for-each select="marc:subfield[@code='u']">
+ <affiliation>
+ <xsl:value-of select="."/>
+ </affiliation>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="uri">
+ <xsl:for-each select="marc:subfield[@code='u']">
+ <xsl:attribute name="xlink:href"><xsl:value-of select="."/></xsl:attribute>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="role">
+ <xsl:for-each select="marc:subfield[@code='e']">
+ <role>
+ <roleTerm type="text">
+ <xsl:value-of select="."/>
+ </roleTerm>
+ </role>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='4']">
+ <role>
+ <roleTerm authority="marcrelator" type="code">
+ <xsl:value-of select="."/>
+ </roleTerm>
+ </role>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="part">
+ <xsl:variable name="partNumber">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="axis">n</xsl:with-param>
+ <xsl:with-param name="anyCodes">n</xsl:with-param>
+ <xsl:with-param name="afterCodes">fghkdlmor</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="partName">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="axis">p</xsl:with-param>
+ <xsl:with-param name="anyCodes">p</xsl:with-param>
+ <xsl:with-param name="afterCodes">fghkdlmor</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:if test="string-length(normalize-space($partNumber))">
+ <partNumber>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="$partNumber"/>
+ </xsl:call-template>
+ </partNumber>
+ </xsl:if>
+ <xsl:if test="string-length(normalize-space($partName))">
+ <partName>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="$partName"/>
+ </xsl:call-template>
+ </partName>
+ </xsl:if>
+ </xsl:template>
+ <xsl:template name="relatedPart">
+ <xsl:if test="@tag=773">
+ <xsl:for-each select="marc:subfield[@code='g']">
+ <part>
+ <text>
+ <xsl:value-of select="."/>
+ </text>
+ </part>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='q']">
+ <part>
+ <xsl:call-template name="parsePart"/>
+ </part>
+ </xsl:for-each>
+ </xsl:if>
+ </xsl:template>
+ <xsl:template name="relatedPartNumName">
+ <xsl:variable name="partNumber">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="axis">g</xsl:with-param>
+ <xsl:with-param name="anyCodes">g</xsl:with-param>
+ <xsl:with-param name="afterCodes">pst</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="partName">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="axis">p</xsl:with-param>
+ <xsl:with-param name="anyCodes">p</xsl:with-param>
+ <xsl:with-param name="afterCodes">fghkdlmor</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:if test="string-length(normalize-space($partNumber))">
+ <partNumber>
+ <xsl:value-of select="$partNumber"/>
+ </partNumber>
+ </xsl:if>
+ <xsl:if test="string-length(normalize-space($partName))">
+ <partName>
+ <xsl:value-of select="$partName"/>
+ </partName>
+ </xsl:if>
+ </xsl:template>
+ <xsl:template name="relatedName">
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <name>
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </name>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="relatedForm">
+ <xsl:for-each select="marc:subfield[@code='h']">
+ <physicalDescription>
+ <form>
+ <xsl:value-of select="."/>
+ </form>
+ </physicalDescription>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="relatedExtent">
+ <xsl:for-each select="marc:subfield[@code='h']">
+ <physicalDescription>
+ <extent>
+ <xsl:value-of select="."/>
+ </extent>
+ </physicalDescription>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="relatedNote">
+ <xsl:for-each select="marc:subfield[@code='n']">
+ <note>
+ <xsl:value-of select="."/>
+ </note>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="relatedSubject">
+ <xsl:for-each select="marc:subfield[@code='j']">
+ <subject>
+ <temporal encoding="iso8601">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </temporal>
+ </subject>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="relatedIdentifierISSN">
+ <xsl:for-each select="marc:subfield[@code='x']">
+ <identifier type="issn">
+ <xsl:value-of select="."/>
+ </identifier>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="relatedIdentifierLocal">
+ <xsl:for-each select="marc:subfield[@code='w']">
+ <identifier type="local">
+ <xsl:value-of select="."/>
+ </identifier>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="relatedIdentifier">
+ <xsl:for-each select="marc:subfield[@code='o']">
+ <identifier>
+ <xsl:value-of select="."/>
+ </identifier>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="relatedItem76X-78X">
+ <xsl:call-template name="displayLabel"/>
+ <xsl:call-template name="relatedTitle76X-78X"/>
+ <xsl:call-template name="relatedName"/>
+ <xsl:call-template name="relatedOriginInfo"/>
+ <xsl:call-template name="relatedLanguage"/>
+ <xsl:call-template name="relatedExtent"/>
+ <xsl:call-template name="relatedNote"/>
+ <xsl:call-template name="relatedSubject"/>
+ <xsl:call-template name="relatedIdentifier"/>
+ <xsl:call-template name="relatedIdentifierISSN"/>
+ <xsl:call-template name="relatedIdentifierLocal"/>
+ <xsl:call-template name="relatedPart"/>
+ </xsl:template>
+ <xsl:template name="subjectGeographicZ">
+ <geographic>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </geographic>
+ </xsl:template>
+ <xsl:template name="subjectTemporalY">
+ <temporal>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </temporal>
+ </xsl:template>
+ <xsl:template name="subjectTopic">
+ <topic>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </topic>
+ </xsl:template>
+ <xsl:template name="nameABCDN">
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <namePart>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </namePart>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </xsl:for-each>
+ <xsl:if test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
+ <namePart>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">cdn</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ </xsl:if>
+ </xsl:template>
+ <xsl:template name="nameABCDQ">
+ <namePart>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">aq</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ <xsl:with-param name="punctuation">
+ <xsl:text>:,;/ </xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ <xsl:call-template name="termsOfAddress"/>
+ <xsl:call-template name="nameDate"/>
+ </xsl:template>
+ <xsl:template name="nameACDEQ">
+ <namePart>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">acdeq</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ </xsl:template>
+ <xsl:template name="constituentOrRelatedType">
+ <xsl:if test="@ind2=2">
+ <xsl:attribute name="type">constituent</xsl:attribute>
+ </xsl:if>
+ </xsl:template>
+ <xsl:template name="relatedTitle">
+ <xsl:for-each select="marc:subfield[@code='t']">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ </titleInfo>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="relatedTitle76X-78X">
+ <xsl:for-each select="marc:subfield[@code='t']">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
+ <xsl:call-template name="relatedPartNumName"/>
+ </xsl:if>
+ </titleInfo>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='p']">
+ <titleInfo type="abbreviated">
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
+ <xsl:call-template name="relatedPartNumName"/>
+ </xsl:if>
+ </titleInfo>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='s']">
+ <titleInfo type="uniform">
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
+ <xsl:call-template name="relatedPartNumName"/>
+ </xsl:if>
+ </titleInfo>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="relatedOriginInfo">
+ <xsl:if test="marc:subfield[@code='b' or @code='d'] or marc:subfield[@code='f']">
+ <originInfo>
+ <xsl:if test="@tag=775">
+ <xsl:for-each select="marc:subfield[@code='f']">
+ <place>
+ <placeTerm>
+ <xsl:attribute name="type">code</xsl:attribute>
+ <xsl:attribute name="authority">marcgac</xsl:attribute>
+ <xsl:value-of select="."/>
+ </placeTerm>
+ </place>
+ </xsl:for-each>
+ </xsl:if>
+ <xsl:for-each select="marc:subfield[@code='d']">
+ <publisher>
+ <xsl:value-of select="."/>
+ </publisher>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <edition>
+ <xsl:value-of select="."/>
+ </edition>
+ </xsl:for-each>
+ </originInfo>
+ </xsl:if>
+ </xsl:template>
+ <xsl:template name="relatedLanguage">
+ <xsl:for-each select="marc:subfield[@code='e']">
+ <xsl:call-template name="getLanguage">
+ <xsl:with-param name="langString">
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="nameDate">
+ <xsl:for-each select="marc:subfield[@code='d']">
+ <namePart type="date">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </namePart>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="subjectAuthority">
+ <xsl:if test="@ind2!=4">
+ <xsl:if test="@ind2!=' '">
+ <xsl:if test="@ind2!=8">
+ <xsl:if test="@ind2!=9">
+ <xsl:attribute name="authority"><xsl:choose><xsl:when test="@ind2=0">lcsh</xsl:when><xsl:when test="@ind2=1">lcshac</xsl:when><xsl:when test="@ind2=2">mesh</xsl:when><!-- 1/04 fix --><xsl:when test="@ind2=3">nal</xsl:when><xsl:when test="@ind2=5">csh</xsl:when><xsl:when test="@ind2=6">rvm</xsl:when><xsl:when test="@ind2=7"><xsl:value-of select="marc:subfield[@code='2']"/></xsl:when></xsl:choose></xsl:attribute>
+ </xsl:if>
+ </xsl:if>
+ </xsl:if>
+ </xsl:if>
+ </xsl:template>
+ <xsl:template name="subjectAnyOrder">
+ <xsl:for-each select="marc:subfield[@code='v' or @code='x' or @code='y' or @code='z']">
+ <xsl:choose>
+ <xsl:when test="@code='v'">
+ <xsl:call-template name="subjectTopic"/>
+ </xsl:when>
+ <xsl:when test="@code='x'">
+ <xsl:call-template name="subjectTopic"/>
+ </xsl:when>
+ <xsl:when test="@code='y'">
+ <xsl:call-template name="subjectTemporalY"/>
+ </xsl:when>
+ <xsl:when test="@code='z'">
+ <xsl:call-template name="subjectGeographicZ"/>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="specialSubfieldSelect">
+ <xsl:param name="anyCodes"/>
+ <xsl:param name="axis"/>
+ <xsl:param name="beforeCodes"/>
+ <xsl:param name="afterCodes"/>
+ <xsl:variable name="str">
+ <xsl:for-each select="marc:subfield">
+ <xsl:if test="contains($anyCodes, @code) or (contains($beforeCodes,@code) and following-sibling::marc:subfield[@code=$axis]) or (contains($afterCodes,@code) and preceding-sibling::marc:subfield[@code=$axis])">
+ <xsl:value-of select="text()"/>
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=600]">
+ <subject>
+ <xsl:call-template name="subjectAuthority"/>
+ <name type="personal">
+ <xsl:call-template name="termsOfAddress"/>
+ <namePart>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">aq</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ <xsl:call-template name="nameDate"/>
+ <xsl:call-template name="affiliation"/>
+ <xsl:call-template name="role"/>
+ </name>
+ <xsl:call-template name="subjectAnyOrder"/>
+ </subject>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=610]">
+ <subject>
+ <xsl:call-template name="subjectAuthority"/>
+ <name type="corporate">
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </xsl:for-each>
+ <xsl:if test="marc:subfield[@code='c' or @code='d' or @code='n' or @code='p']">
+ <namePart>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">cdnp</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ </xsl:if>
+ <xsl:call-template name="role"/>
+ </name>
+ <xsl:call-template name="subjectAnyOrder"/>
+ </subject>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=611]">
+ <subject>
+ <xsl:call-template name="subjectAuthority"/>
+ <name type="conference">
+ <namePart>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcdeqnp</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ <xsl:for-each select="marc:subfield[@code='4']">
+ <role>
+ <roleTerm authority="marcrelator" type="code">
+ <xsl:value-of select="."/>
+ </roleTerm>
+ </role>
+ </xsl:for-each>
+ </name>
+ <xsl:call-template name="subjectAnyOrder"/>
+ </subject>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=630]">
+ <subject>
+ <xsl:call-template name="subjectAuthority"/>
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">adfhklor</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="part"/>
+ </title>
+ </titleInfo>
+ <xsl:call-template name="subjectAnyOrder"/>
+ </subject>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=650]">
+ <subject>
+ <xsl:call-template name="subjectAuthority"/>
+ <topic>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcd</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </topic>
+ <xsl:call-template name="subjectAnyOrder"/>
+ </subject>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=651]">
+ <subject>
+ <xsl:call-template name="subjectAuthority"/>
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <geographic>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </geographic>
+ </xsl:for-each>
+ <xsl:call-template name="subjectAnyOrder"/>
+ </subject>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=653]">
+ <subject>
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <topic>
+ <xsl:value-of select="."/>
+ </topic>
+ </xsl:for-each>
+ </subject>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=656]">
+ <subject>
+ <xsl:if test="marc:subfield[@code=2]">
+ <xsl:attribute name="authority"><xsl:value-of select="marc:subfield[@code=2]"/></xsl:attribute>
+ </xsl:if>
+ <occupation>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </occupation>
+ </subject>
+ </xsl:template>
+ <xsl:template name="termsOfAddress">
+ <xsl:if test="marc:subfield[@code='b' or @code='c']">
+ <namePart type="termsOfAddress">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">bc</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ </xsl:if>
+ </xsl:template>
+ <xsl:template name="displayLabel">
+ <xsl:if test="marc:subfield[@code='i']">
+ <xsl:attribute name="displayLabel"><xsl:value-of select="marc:subfield[@code='i']"/></xsl:attribute>
+ </xsl:if>
+ <xsl:if test="marc:subfield[@code='3']">
+ <xsl:attribute name="displayLabel"><xsl:value-of select="marc:subfield[@code='3']"/></xsl:attribute>
+ </xsl:if>
+ </xsl:template>
+ <xsl:template name="isInvalid">
+ <xsl:if test="marc:subfield[@code='z']">
+ <xsl:attribute name="invalid">yes</xsl:attribute>
+ </xsl:if>
+ </xsl:template>
+ <xsl:template name="subtitle">
+ <xsl:if test="marc:subfield[@code='b']">
+ <subTitle>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:subfield[@code='b']"/>
+ <!--<xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">b</xsl:with-param>
+ </xsl:call-template>-->
+ </xsl:with-param>
+ </xsl:call-template>
+ </subTitle>
+ </xsl:if>
+ </xsl:template>
+ <xsl:template name="script">
+ <xsl:param name="scriptCode"/>
+ <xsl:attribute name="script"><xsl:choose><xsl:when test="$scriptCode='(3'">Arabic</xsl:when><xsl:when test="$scriptCode='(B'">Latin</xsl:when><xsl:when test="$scriptCode='$1'">Chinese, Japanese, Korean</xsl:when><xsl:when test="$scriptCode='(N'">Cyrillic</xsl:when><xsl:when test="$scriptCode='(2'">Hebrew</xsl:when><xsl:when test="$scriptCode='(S'">Greek</xsl:when></xsl:choose></xsl:attribute>
+ </xsl:template>
+ <xsl:template name="parsePart">
+ <!-- assumes 773$q= 1:2:3<4
+ with up to 3 levels and one optional start page
+ -->
+ <xsl:variable name="level1">
+ <xsl:choose>
+ <xsl:when test="contains(text(),':')">
+ <!-- 1:2 -->
+ <xsl:value-of select="substring-before(text(),':')"/>
+ </xsl:when>
+ <xsl:when test="not(contains(text(),':'))">
+ <!-- 1 or 1<3 -->
+ <xsl:if test="contains(text(),'&lt;')">
+ <!-- 1<3 -->
+ <xsl:value-of select="substring-before(text(),'&lt;')"/>
+ </xsl:if>
+ <xsl:if test="not(contains(text(),'&lt;'))">
+ <!-- 1 -->
+ <xsl:value-of select="text()"/>
+ </xsl:if>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="sici2">
+ <xsl:choose>
+ <xsl:when test="starts-with(substring-after(text(),$level1),':')">
+ <xsl:value-of select="substring(substring-after(text(),$level1),2)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="substring-after(text(),$level1)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="level2">
+ <xsl:choose>
+ <xsl:when test="contains($sici2,':')">
+ <!-- 2:3<4 -->
+ <xsl:value-of select="substring-before($sici2,':')"/>
+ </xsl:when>
+ <xsl:when test="contains($sici2,'&lt;')">
+ <!-- 1: 2<4 -->
+ <xsl:value-of select="substring-before($sici2,'&lt;')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$sici2"/>
+ <!-- 1:2 -->
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="sici3">
+ <xsl:choose>
+ <xsl:when test="starts-with(substring-after($sici2,$level2),':')">
+ <xsl:value-of select="substring(substring-after($sici2,$level2),2)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="substring-after($sici2,$level2)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="level3">
+ <xsl:choose>
+ <xsl:when test="contains($sici3,'&lt;')">
+ <!-- 2<4 -->
+ <xsl:value-of select="substring-before($sici3,'&lt;')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$sici3"/>
+ <!-- 3 -->
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="page">
+ <xsl:if test="contains(text(),'&lt;')">
+ <xsl:value-of select="substring-after(text(),'&lt;')"/>
+ </xsl:if>
+ </xsl:variable>
+ <xsl:if test="$level1">
+ <detail level="1">
+ <number>
+ <xsl:value-of select="$level1"/>
+ </number>
+ </detail>
+ </xsl:if>
+ <xsl:if test="$level2">
+ <detail level="2">
+ <number>
+ <xsl:value-of select="$level2"/>
+ </number>
+ </detail>
+ </xsl:if>
+ <xsl:if test="$level3">
+ <detail level="3">
+ <number>
+ <xsl:value-of select="$level3"/>
+ </number>
+ </detail>
+ </xsl:if>
+ <xsl:if test="$page">
+ <extent unit="page">
+ <start>
+ <xsl:value-of select="$page"/>
+ </start>
+ </extent>
+ </xsl:if>
+ </xsl:template>
+ <xsl:template name="getLanguage">
+ <xsl:param name="langString"/>
+ <xsl:param name="controlField008-35-37"/>
+ <xsl:variable name="length" select="string-length($langString)"/>
+ <xsl:choose>
+ <xsl:when test="$length=0"/>
+ <xsl:when test="$controlField008-35-37=substring($langString,1,3)">
+ <xsl:call-template name="getLanguage">
+ <xsl:with-param name="langString" select="substring($langString,4,$length)"/>
+ <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <language>
+ <languageTerm authority="iso639-2b" type="code">
+ <xsl:value-of select="substring($langString,1,3)"/>
+ </languageTerm>
+ </language>
+ <xsl:call-template name="getLanguage">
+ <xsl:with-param name="langString" select="substring($langString,4,$length)"/>
+ <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+ <xsl:template name="isoLanguage">
+ <xsl:param name="currentLanguage"/>
+ <xsl:param name="usedLanguages"/>
+ <xsl:param name="remainingLanguages"/>
+ <xsl:choose>
+ <xsl:when test="string-length($currentLanguage)=0"/>
+ <xsl:when test="not(contains($usedLanguages, $currentLanguage))">
+ <language>
+ <languageTerm authority="iso639-2b" type="code">
+ <xsl:if test="@code!='a'">
+ <xsl:attribute name="objectPart"><xsl:choose><xsl:when test="@code='b'">summary or subtitle</xsl:when><xsl:when test="@code='d'">sung or spoken text</xsl:when><xsl:when test="@code='e'">libretto</xsl:when><xsl:when test="@code='f'">table of contents</xsl:when><xsl:when test="@code='g'">accompanying material</xsl:when><xsl:when test="@code='h'">translation</xsl:when></xsl:choose></xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="$currentLanguage"/>
+ </languageTerm>
+ </language>
+ <xsl:call-template name="isoLanguage">
+ <xsl:with-param name="currentLanguage">
+ <xsl:value-of select="substring($remainingLanguages,1,3)"/>
+ </xsl:with-param>
+ <xsl:with-param name="usedLanguages">
+ <xsl:value-of select="concat($usedLanguages,$currentLanguage)"/>
+ </xsl:with-param>
+ <xsl:with-param name="remainingLanguages">
+ <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="isoLanguage">
+ <xsl:with-param name="currentLanguage">
+ <xsl:value-of select="substring($remainingLanguages,1,3)"/>
+ </xsl:with-param>
+ <xsl:with-param name="usedLanguages">
+ <xsl:value-of select="concat($usedLanguages,$currentLanguage)"/>
+ </xsl:with-param>
+ <xsl:with-param name="remainingLanguages">
+ <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+ <xsl:template name="chopBrackets">
+ <xsl:param name="chopString"/>
+ <xsl:variable name="string">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="$chopString"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:if test="substring($string, 1,1)='['">
+ <xsl:value-of select="substring($string,2, string-length($string)-2)"/>
+ </xsl:if>
+ <xsl:if test="substring($string, 1,1)!='['">
+ <xsl:value-of select="$string"/>
+ </xsl:if>
+ </xsl:template>
+ <xsl:template name="rfcLanguages">
+ <xsl:param name="nodeNum"/>
+ <xsl:param name="usedLanguages"/>
+ <xsl:param name="controlField008-35-37"/>
+ <xsl:variable name="currentLanguage" select="."/>
+ <xsl:choose>
+ <xsl:when test="not($currentLanguage)"/>
+ <xsl:when test="$currentLanguage!=$controlField008-35-37 and $currentLanguage!='rfc3066'">
+ <xsl:if test="not(contains($usedLanguages,$currentLanguage))">
+ <language>
+ <languageTerm authority="rfc3066" type="code">
+ <xsl:if test="@code!='a'">
+ <xsl:attribute name="objectPart"><xsl:choose><xsl:when test="@code='b'">summary or subtitle</xsl:when><xsl:when test="@code='d'">sung or spoken text</xsl:when><xsl:when test="@code='e'">libretto</xsl:when><xsl:when test="@code='f'">table of contents</xsl:when><xsl:when test="@code='g'">accompanying material</xsl:when><xsl:when test="@code='h'">translation</xsl:when></xsl:choose></xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="$currentLanguage"/>
+ </languageTerm>
+ </language>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>
+
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+</xsl:stylesheet>
+<!-- Stylus Studio meta-information - (c)1998-2003 Copyright Sonic Software Corporation. All rights reserved.
+<metaInformation>
+<scenarios ><scenario default="no" name="Apr 02 Test" userelativepaths="yes" externalpreview="no" url="file://n:\jackie\test_files\v3.xml" htmlbaseurl="" outputurl="file://n:\temp\x.xml" processortype="xalan" commandline="" additionalpath="" additionalclasspath="" postprocessortype="none" postprocesscommandline="" postprocessadditionalpath="" postprocessgeneratedext=""/><scenario default="no" name="v3Test1" userelativepaths="yes" externalpreview="no" url="file://n:\jackie\test_files\v3.xml" htmlbaseurl="" outputurl="file://n:\jackie\test_files\modsv3Converted.xml" processortype="internal" commandline="" additionalpath="" additionalclasspath="" postprocessortype="none" postprocesscommandline="" postprocessadditionalpath="" postprocessgeneratedext=""/><scenario default="no" name="Scenario1" userelativepaths="yes" externalpreview="no" url="file://n:\ckeith\DESKTOP\test.xml" htmlbaseurl="" outputurl="" processortype="xalan" commandline="" additionalpath="" additionalclasspath="" postprocessortype="none" postprocesscommandline="" postprocessadditionalpath="" postprocessgeneratedext=""/><scenario default="yes" name="Test" userelativepaths="yes" externalpreview="no" url="file://n:\jackie\MARCXML\marcxmlfile.xml" htmlbaseurl="" outputurl="" processortype="xalan" commandline="" additionalpath="" additionalclasspath="" postprocessortype="none" postprocesscommandline="" postprocessadditionalpath="" postprocessgeneratedext=""/></scenarios><MapperInfo srcSchemaPath="" srcSchemaRoot="" srcSchemaPathIsRelative="yes" srcSchemaInterpretAsXML="no" destSchemaPath="" destSchemaRoot="" destSchemaPathIsRelative="yes" destSchemaInterpretAsXML="no"/>
+</metaInformation>
+-->
diff --git a/xslt/MARC21slimUtils.xsl b/xslt/MARC21slimUtils.xsl
new file mode 100644
index 0000000..b1104ce
--- /dev/null
+++ b/xslt/MARC21slimUtils.xsl
@@ -0,0 +1,82 @@
+<?xml version='1.0'?>
+<xsl:stylesheet version="1.0" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<!-- This file is in the public domain. -->
+
+<!-- 8/19/04: ntra added "marc:" prefix to datafield element -->
+ <xsl:template name="datafield">
+ <xsl:param name="tag"/>
+ <xsl:param name="ind1"><xsl:text> </xsl:text></xsl:param>
+ <xsl:param name="ind2"><xsl:text> </xsl:text></xsl:param>
+ <xsl:param name="subfields"/>
+ <xsl:element name="marc:datafield">
+ <xsl:attribute name="tag">
+ <xsl:value-of select="$tag"/>
+ </xsl:attribute>
+ <xsl:attribute name="ind1">
+ <xsl:value-of select="$ind1"/>
+ </xsl:attribute>
+ <xsl:attribute name="ind2">
+ <xsl:value-of select="$ind2"/>
+ </xsl:attribute>
+ <xsl:copy-of select="$subfields"/>
+ </xsl:element>
+ </xsl:template>
+
+ <xsl:template name="subfieldSelect">
+ <xsl:param name="codes"/>
+ <xsl:param name="delimeter"><xsl:text> </xsl:text></xsl:param>
+ <xsl:variable name="str">
+ <xsl:for-each select="marc:subfield">
+ <xsl:if test="contains($codes, @code)">
+ <xsl:value-of select="text()"/><xsl:value-of select="$delimeter"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
+ </xsl:template>
+
+ <xsl:template name="buildSpaces">
+ <xsl:param name="spaces"/>
+ <xsl:param name="char"><xsl:text> </xsl:text></xsl:param>
+ <xsl:if test="$spaces>0">
+ <xsl:value-of select="$char"/>
+ <xsl:call-template name="buildSpaces">
+ <xsl:with-param name="spaces" select="$spaces - 1"/>
+ <xsl:with-param name="char" select="$char"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="chopPunctuation">
+ <xsl:param name="chopString"/>
+ <xsl:param name="punctuation"><xsl:text>.:,;/ </xsl:text></xsl:param>
+ <xsl:variable name="length" select="string-length($chopString)"/>
+ <xsl:choose>
+ <xsl:when test="$length=0"/>
+ <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
+ <xsl:with-param name="punctuation" select="$punctuation"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="not($chopString)"/>
+ <xsl:otherwise><xsl:value-of select="$chopString"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="chopPunctuationFront">
+ <xsl:param name="chopString"/>
+ <xsl:variable name="length" select="string-length($chopString)"/>
+ <xsl:choose>
+ <xsl:when test="$length=0"/>
+ <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
+ <xsl:call-template name="chopPunctuationFront">
+ <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="not($chopString)"/>
+ <xsl:otherwise><xsl:value-of select="$chopString"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/xslt/Makefile.am b/xslt/Makefile.am
new file mode 100644
index 0000000..d0fb0c4
--- /dev/null
+++ b/xslt/Makefile.am
@@ -0,0 +1,29 @@
+EXTRA_DIST = tellico-by-author.xsl tellico-by-title.xsl \
+ tellico-printing.xsl tellico2html.xsl shadowAlpha.png \
+ cd-logo.png dvd-logo.png cassette-logo.png record-logo.png \
+ vhs-logo.png tellico-common.xsl mods2tellico.xsl \
+ amazon2tellico.xsl MARC21slim2MODS3.xsl MARC21slimUtils.xsl \
+ pubmed2tellico.xsl tellico2onix.xsl UNIMARC2MODS3.xsl \
+ tellico2html.js yahoo2tellico.xsl isbndb2tellico.xsl \
+ bluray-logo.png hddvd-logo.png gcstar2tellico.xsl \
+ xmp2tellico.xsl crossref2tellico.xsl arxiv2tellico.xsl \
+ referencer2tellico.xsl delicious2tellico.xsl welcome.html \
+ unixref2tellico.xsl discogs2tellico.xsl tellico2gcstar.xsl
+
+xsldir = $(kde_datadir)/tellico
+xsl_DATA = tellico-printing.xsl tellico-by-author.xsl tellico-by-title.xsl \
+ tellico2html.xsl shadowAlpha.png cassette-logo.png cd-logo.png \
+ dvd-logo.png record-logo.png vhs-logo.png tellico-common.xsl \
+ mods2tellico.xsl amazon2tellico.xsl MARC21slim2MODS3.xsl \
+ MARC21slimUtils.xsl pubmed2tellico.xsl tellico2onix.xsl \
+ UNIMARC2MODS3.xsl tellico2html.js yahoo2tellico.xsl \
+ isbndb2tellico.xsl bluray-logo.png hddvd-logo.png gcstar2tellico.xsl \
+ xmp2tellico.xsl crossref2tellico.xsl arxiv2tellico.xsl \
+ referencer2tellico.xsl delicious2tellico.xsl welcome.html \
+ unixref2tellico.xsl discogs2tellico.xsl tellico2gcstar.xsl
+
+SUBDIRS = entry-templates report-templates
+
+KDE_OPTIONS = noautodist
+
+CLEANFILES = *~
diff --git a/xslt/UNIMARC2MODS3.xsl b/xslt/UNIMARC2MODS3.xsl
new file mode 100644
index 0000000..30035f5
--- /dev/null
+++ b/xslt/UNIMARC2MODS3.xsl
@@ -0,0 +1,2920 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns="http://www.loc.gov/mods/v3" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xlink marc">
+ <xsl:include href="MARC21slimUtils.xsl"/>
+ <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
+
+<!-- This file is in the public domain. -->
+
+<!--
+
+Revised version of MARC21slim2MODS3.xsl from Library of Congress
+with input from Yves Pratter's version of UNIMARC2MODS.xsl
+
+-->
+ <xsl:template match="/">
+ <modsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-1.xsd">
+ <xsl:for-each select=".//marc:record">
+ <mods version="3.1">
+ <xsl:call-template name="marcRecord"/>
+ </mods>
+ </xsl:for-each>
+ </modsCollection>
+ </xsl:template>
+
+ <xsl:template name="marcRecord">
+ <xsl:variable name="leader" select="marc:leader"/>
+ <xsl:variable name="leader6" select="substring($leader,7,1)"/>
+ <xsl:variable name="leader7" select="substring($leader,8,1)"/>
+ <xsl:variable name="controlField008" select="marc:controlfield[@tag=008]"/>
+ <xsl:variable name="typeOf008">
+ <xsl:choose>
+ <xsl:when test="$leader6='a'">
+ <xsl:choose>
+ <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">BK</xsl:when>
+ <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">SE</xsl:when>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="$leader6='t'">BK</xsl:when>
+ <xsl:when test="$leader6='p'">MM</xsl:when>
+ <xsl:when test="$leader6='m'">CF</xsl:when>
+ <xsl:when test="$leader6='e' or $leader6='f'">MP</xsl:when>
+ <xsl:when test="$leader6='g' or $leader6='k' or $leader6='o' or $leader6='r'">VM</xsl:when>
+ <xsl:when test="$leader6='c' or $leader6='d' or $leader6='i' or $leader6='j'">MU</xsl:when>
+ </xsl:choose>
+ </xsl:variable>
+
+ <!-- MARC21 tag 245 - TITLE STATEMENT -->
+ <xsl:for-each select="marc:datafield[@tag=200]">
+ <titleInfo>
+ <xsl:variable name="title">
+ <xsl:choose>
+ <xsl:when test="marc:subfield[@code='e']">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="axis">e</xsl:with-param>
+ <xsl:with-param name="beforeCodes">a</xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ae</xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="titleChop">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="$title"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="@ind2&gt;0">
+ <nonSort>
+ <xsl:value-of select="substring($titleChop,1,@ind2)"/>
+ </nonSort>
+ <title>
+ <xsl:value-of select="substring($titleChop,@ind2+1)"/>
+ </title>
+ </xsl:when>
+ <xsl:when test="contains($title,'ˆ') and contains($title,'‰')">
+ <nonSort>
+ <xsl:value-of select="substring(substring-before($title,'‰'),2)"/>
+ </nonSort>
+ <title>
+ <xsl:value-of select="substring-after($title,'‰')"/>
+ </title>
+ </xsl:when>
+ <xsl:otherwise>
+ <title>
+ <xsl:value-of select="$titleChop"/>
+ </title>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:if test="marc:subfield[@code='e']">
+ <subTitle>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="axis">e</xsl:with-param>
+ <xsl:with-param name="anyCodes">e</xsl:with-param>
+ <xsl:with-param name="afterCodes">a</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </subTitle>
+ </xsl:if>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ </xsl:for-each>
+
+ <!-- MARC21 - ABBREVIATED TITLE / tag 210 ab -->
+ <xsl:for-each select="marc:datafield[@tag=531]">
+ <titleInfo type="abbreviated">
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">a</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="subtitle"/>
+ </titleInfo>
+ </xsl:for-each>
+
+ <!-- MARC21 - translated title / 242 -->
+ <xsl:for-each select="marc:datafield[@tag=541]">
+ <titleInfo type="translated">
+ <!-- 541/z is 242/y -->
+ <xsl:for-each select="marc:subfield[@code='z']">
+ <xsl:attribute name="lang">
+ <xsl:value-of select="text()"/>
+ </xsl:attribute>
+ </xsl:for-each>
+ <title>
+
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">a</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+
+ </title>
+
+
+ <!-- 1/04 fix -->
+ <xsl:call-template name="subtitle"/>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ </xsl:for-each>
+
+ <!-- MARC21 - Expanded title / 246 -->
+ <xsl:for-each select="marc:datafield[@tag=532]|marc:datafield[@tag=540]">
+ <titleInfo type="alternative">
+ <xsl:for-each select="marc:subfield[@code='i']">
+ <xsl:attribute name="displayLabel">
+ <xsl:value-of select="text()"/>
+ </xsl:attribute>
+ </xsl:for-each>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <!-- 1/04 removed $h, $b -->
+ <xsl:with-param name="codes">af</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="subtitle"/>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ </xsl:for-each>
+
+ <!-- MARC21 - Expanded title / 130, 240, 730i2 -->
+ <xsl:for-each select="marc:datafield[@tag=500]">
+ <titleInfo type="uniform">
+ <title>
+ <xsl:variable name="str">
+ <xsl:for-each select="marc:subfield">
+ <xsl:if test="(contains('anklmrtuv',@code) and (not(../marc:subfield[@code='h' or @code='s' or @code='i']) or (following-sibling::marc:subfield[@code='h' or @code='s' or @code='i'])))">
+ <xsl:value-of select="text()"/>
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ </xsl:for-each>
+
+ <!--
+ <xsl:for-each select="marc:datafield[@tag=740][@ind2!=2]">
+ <titleInfo type="alternative">
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ah</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ </xsl:for-each>
+-->
+
+ <!-- MARC21 - creator / 100 -->
+ <xsl:for-each select="marc:datafield[@tag=700]">
+ <name type="personal">
+ <xsl:call-template name="nameABCDFG"/>
+ <xsl:call-template name="affiliation"/>
+ <role>
+ <roleTerm authority="marcrelator" type="text">creator</roleTerm>
+ </role>
+ <xsl:call-template name="role"/>
+ </name>
+ </xsl:for-each>
+
+ <!-- MARC21 - creator / 110 and 111 -->
+ <xsl:for-each select="marc:datafield[@tag=710]">
+ <name>
+ <xsl:if test="@ind1=0">
+ <xsl:attribute name="type">
+ <xsl:text>corporate</xsl:text>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:if test="@ind1=1">
+ <xsl:attribute name="type">
+ <xsl:text>conference</xsl:text>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:call-template name="nameABCDEF"/>
+ <role>
+ <roleTerm authority="marcrelator" type="text">creator</roleTerm>
+ </role>
+ <xsl:call-template name="role"/>
+ </name>
+ </xsl:for-each>
+
+ <!-- MARC21 - creator / 700 -->
+ <xsl:for-each select="marc:datafield[@tag=701 or @tag=702]">
+ <name type="personal">
+ <xsl:call-template name="nameABCDFG"/>
+ <xsl:call-template name="affiliation"/>
+ <xsl:call-template name="role"/>
+ </name>
+ </xsl:for-each>
+
+ <!-- MARC21 - creator / 710 and 711 -->
+ <xsl:for-each select="marc:datafield[@tag=711 or @tag=712]">
+ <name>
+ <xsl:if test="@ind1=0">
+ <xsl:attribute name="type">
+ <xsl:text>corporate</xsl:text>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:if test="@ind1=1">
+ <xsl:attribute name="type">
+ <xsl:text>conference</xsl:text>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:call-template name="nameABCDEF"/>
+ <xsl:call-template name="role"/>
+ </name>
+ </xsl:for-each>
+
+<!--
+ <xsl:for-each select="marc:datafield[@tag=720][not(marc:subfield[@code='t'])]">
+ <name>
+ <xsl:if test="@ind1=1">
+ <xsl:attribute name="type">
+ <xsl:text>personal</xsl:text>
+ </xsl:attribute>
+ </xsl:if>
+ <namePart>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </namePart>
+ <xsl:call-template name="role"/>
+ </name>
+ </xsl:for-each>
+-->
+
+ <typeOfResource>
+ <xsl:if test="$leader7='c'">
+ <xsl:attribute name="collection">yes</xsl:attribute>
+ </xsl:if>
+ <xsl:if test="$leader6='d' or $leader6='f' or $leader6='p' or $leader6='t'">
+ <xsl:attribute name="manuscript">yes</xsl:attribute>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="$leader6='a' or $leader6='b' or $leader6='h' or $leader6='t'">text</xsl:when>
+ <xsl:when test="$leader6='e' or $leader6='f'">cartographic</xsl:when>
+ <xsl:when test="$leader6='c' or $leader6='d'">notated music</xsl:when>
+ <xsl:when test="$leader6='i'">sound recording-nonmusical</xsl:when>
+ <xsl:when test="$leader6='j'">sound recording-musical</xsl:when>
+ <xsl:when test="$leader6='k'">still image</xsl:when>
+ <xsl:when test="$leader6='g'">moving image</xsl:when>
+ <xsl:when test="$leader6='n'">three dimensional object</xsl:when>
+ <xsl:when test="$leader6='l'">software, multimedia</xsl:when>
+ <xsl:when test="$leader6='p'">mixed material</xsl:when>
+ </xsl:choose>
+ </typeOfResource>
+
+ <!-- MARC21 controlField008 -->
+ <xsl:if test="substring(marc:field[@tag=124],26,1)='d'">
+ <genre authority="marc">globe</genre>
+ </xsl:if>
+
+ <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
+ <genre authority="marc">remote sensing image</genre>
+ </xsl:if>
+
+ <xsl:if test="$typeOf008='MP'">
+ <xsl:variable name="controlField008-25" select="substring($controlField008,26,1)"/>
+ <xsl:choose>
+ <xsl:when test="$controlField008-25='a' or $controlField008-25='b' or $controlField008-25='c' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
+ <genre authority="marc">map</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-25='e' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
+ <genre authority="marc">atlas</genre>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+
+ <xsl:if test="$typeOf008='SE'">
+ <xsl:variable name="controlField008-21" select="substring($controlField008,22,1)"/>
+ <xsl:choose>
+ <xsl:when test="$controlField008-21='d'">
+ <genre authority="marc">database</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-21='l'">
+ <genre authority="marc">loose-leaf</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-21='m'">
+ <genre authority="marc">series</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-21='n'">
+ <genre authority="marc">newspaper</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-21='p'">
+ <genre authority="marc">periodical</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-21='w'">
+ <genre authority="marc">web site</genre>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+
+ <xsl:if test="$typeOf008='BK' or $typeOf008='SE'">
+ <xsl:variable name="controlField008-24" select="substring($controlField008,25,4)"/>
+ <xsl:choose>
+ <xsl:when test="contains($controlField008-24,'a')">
+ <genre authority="marc">abstract or summary</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'b')">
+ <genre authority="marc">bibliography</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'c')">
+ <genre authority="marc">catalog</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'d')">
+ <genre authority="marc">dictionary</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'e')">
+ <genre authority="marc">encyclopedia</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'f')">
+ <genre authority="marc">handbook</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'g')">
+ <genre authority="marc">legal article</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'i')">
+ <genre authority="marc">index</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'k')">
+ <genre authority="marc">discography</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'l')">
+ <genre authority="marc">legislation</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'m')">
+ <genre authority="marc">theses</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'n')">
+ <genre authority="marc">survey of literature</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'o')">
+ <genre authority="marc">review</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'p')">
+ <genre authority="marc">programmed text</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'q')">
+ <genre authority="marc">filmography</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'r')">
+ <genre authority="marc">directory</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'s')">
+ <genre authority="marc">statistics</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'t')">
+ <genre authority="marc">technical report</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'v')">
+ <genre authority="marc">legal case and case notes</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'w')">
+ <genre authority="marc">law report or digest</genre>
+ </xsl:when>
+ <xsl:when test="contains($controlField008-24,'z')">
+ <genre authority="marc">treaty</genre>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"/>
+ <xsl:choose>
+ <xsl:when test="$controlField008-29='1'">
+ <genre authority="marc">conference publication</genre>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+
+ <xsl:if test="$typeOf008='CF'">
+ <xsl:variable name="controlField008-26" select="substring($controlField008,27,1)"/>
+ <xsl:choose>
+ <xsl:when test="$controlField008-26='a'">
+ <genre authority="marc">numeric data</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-26='e'">
+ <genre authority="marc">database</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-26='f'">
+ <genre authority="marc">font</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-26='g'">
+ <genre authority="marc">game</genre>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+
+ <xsl:if test="$typeOf008='BK'">
+ <xsl:if test="substring($controlField008,25,1)='j'">
+ <genre authority="marc">patent</genre>
+ </xsl:if>
+ <xsl:if test="substring($controlField008,31,1)='1'">
+ <genre authority="marc">festschrift</genre>
+ </xsl:if>
+
+ <xsl:variable name="controlField008-34" select="substring($controlField008,35,1)"/>
+ <xsl:if test="$controlField008-34='a' or $controlField008-34='b' or $controlField008-34='c' or $controlField008-34='d'">
+ <genre authority="marc">biography</genre>
+ </xsl:if>
+
+ <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"/>
+ <xsl:choose>
+ <xsl:when test="$controlField008-33='e'">
+ <genre authority="marc">essay</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='d'">
+ <genre authority="marc">drama</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='c'">
+ <genre authority="marc">comic strip</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='l'">
+ <genre authority="marc">fiction</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='h'">
+ <genre authority="marc">humor, satire</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='i'">
+ <genre authority="marc">letter</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='f'">
+ <genre authority="marc">novel</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='j'">
+ <genre authority="marc">short story</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='s'">
+ <genre authority="marc">speech</genre>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+
+ <xsl:if test="$typeOf008='MU'">
+ <xsl:variable name="controlField008-30-31" select="substring($controlField008,31,2)"/>
+ <xsl:if test="contains($controlField008-30-31,'b')">
+ <genre authority="marc">biography</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'c')">
+ <genre authority="marc">conference publication</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'d')">
+ <genre authority="marc">drama</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'e')">
+ <genre authority="marc">essay</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'f')">
+ <genre authority="marc">fiction</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'o')">
+ <genre authority="marc">folktale</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'h')">
+ <genre authority="marc">history</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'k')">
+ <genre authority="marc">humor, satire</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'m')">
+ <genre authority="marc">memoir</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'p')">
+ <genre authority="marc">poetry</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'r')">
+ <genre authority="marc">rehearsal</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'g')">
+ <genre authority="marc">reporting</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'s')">
+ <genre authority="marc">sound</genre>
+ </xsl:if>
+ <xsl:if test="contains($controlField008-30-31,'l')">
+ <genre authority="marc">speech</genre>
+ </xsl:if>
+ </xsl:if>
+
+ <xsl:if test="$typeOf008='VM'">
+ <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"/>
+ <xsl:choose>
+ <xsl:when test="$controlField008-33='a'">
+ <genre authority="marc">art original</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='b'">
+ <genre authority="marc">kit</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='c'">
+ <genre authority="marc">art reproduction</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='d'">
+ <genre authority="marc">diorama</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='f'">
+ <genre authority="marc">filmstrip</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='g'">
+ <genre authority="marc">legal article</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='i'">
+ <genre authority="marc">picture</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='k'">
+ <genre authority="marc">graphic</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='l'">
+ <genre authority="marc">technical drawing</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='m'">
+ <genre authority="marc">motion picture</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='n'">
+ <genre authority="marc">chart</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='o'">
+ <genre authority="marc">flash card</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='p'">
+ <genre authority="marc">microscope slide</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='q' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
+ <genre authority="marc">model</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='r'">
+ <genre authority="marc">realia</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='s'">
+ <genre authority="marc">slide</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='t'">
+ <genre authority="marc">transparency</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='v'">
+ <genre authority="marc">videorecording</genre>
+ </xsl:when>
+ <xsl:when test="$controlField008-33='w'">
+ <genre authority="marc">toy</genre>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+
+ <xsl:for-each select="marc:datafield[@tag=655]">
+ <genre authority="marc">
+ <xsl:attribute name="authority">
+ <xsl:value-of select="marc:subfield[@code='2']"/>
+ </xsl:attribute>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abvxyz</xsl:with-param>
+ <xsl:with-param name="delimeter">-</xsl:with-param>
+ </xsl:call-template>
+ </genre>
+ </xsl:for-each>
+
+ <originInfo>
+ <xsl:variable name="MARCpublicationCode" select="normalize-space(substring($controlField008,16,3))"/>
+
+ <xsl:if test="translate($MARCpublicationCode,'|','')">
+ <place>
+ <placeTerm>
+ <xsl:attribute name="type">code</xsl:attribute>
+ <xsl:attribute name="authority">marccountry</xsl:attribute>
+ <xsl:value-of select="$MARCpublicationCode"/>
+ </placeTerm>
+ </place>
+ </xsl:if>
+
+ <!-- MARC21 44a -->
+ <xsl:for-each select="marc:datafield[@tag=102]/marc:subfield[@code='a']">
+ <place>
+ <placeTerm>
+ <xsl:attribute name="type">code</xsl:attribute>
+ <xsl:attribute name="authority">iso3166</xsl:attribute>
+ <xsl:value-of select="."/>
+ </placeTerm>
+ </place>
+ </xsl:for-each>
+
+ <!-- MARC21 260a -->
+ <xsl:for-each select="marc:datafield[@tag=210]/marc:subfield[@code='a']">
+ <place>
+ <placeTerm>
+ <xsl:attribute name="type">text</xsl:attribute>
+ <xsl:call-template name="chopPunctuationFront">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ <xsl:with-param name="chopString" select="../marc:subfield[@code='a']"/>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </placeTerm>
+ </place>
+ </xsl:for-each>
+
+ <!-- Unknown -->
+ <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='m']">
+ <dateValid point="start">
+ <xsl:value-of select="."/>
+ </dateValid>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='n']">
+ <dateValid point="end">
+ <xsl:value-of select="."/>
+ </dateValid>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='j']">
+ <dateModified>
+ <xsl:value-of select="."/>
+ </dateModified>
+ </xsl:for-each>
+
+ <!-- MARC21 260bcg -->
+ <xsl:for-each select="marc:datafield[@tag=210]/marc:subfield[@code='c' or @code='d' or @code='h']">
+ <xsl:choose>
+ <xsl:when test="@code='c'">
+ <publisher>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ <xsl:with-param name="punctuation">
+ <xsl:text>:,;/ </xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </publisher>
+ </xsl:when>
+ <xsl:when test="@code='d'">
+ <dateIssued>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="chopPunctuationFront">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </xsl:with-param>
+ <xsl:with-param name="punctuation"> <!-- add closing bracket -->
+ <xsl:text>:,;/] </xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </dateIssued>
+ </xsl:when>
+ <xsl:when test="@code='h'">
+ <dateCreated>
+ <xsl:value-of select="."/>
+ </dateCreated>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:for-each>
+
+ <!-- Unknown
+ <xsl:variable name="dataField260d">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="marc:datafield[@tag=260]/marc:subfield[@code='d']"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="controlField008-7-10" select="normalize-space(substring($controlField008, 8, 4))"/>
+ <xsl:variable name="controlField008-11-14" select="normalize-space(substring($controlField008, 12, 4))"/>
+ <xsl:variable name="controlField008-6" select="normalize-space(substring($controlField008, 7, 1))"/>
+
+ <xsl:if test="$controlField008-6='e' or $controlField008-6='p' or $controlField008-6='r' or $controlField008-6='t' or $controlField008-6='s'">
+ <xsl:if test="$controlField008-7-10 and ($controlField008-7-10 != $dataField260d)">
+ <dateIssued encoding="marc">
+ <xsl:value-of select="$controlField008-7-10"/>
+ </dateIssued>
+ </xsl:if>
+ </xsl:if>
+
+ <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
+ <xsl:if test="$controlField008-7-10">
+ <dateIssued encoding="marc" point="start">
+ <xsl:value-of select="$controlField008-7-10"/>
+ </dateIssued>
+ </xsl:if>
+ </xsl:if>
+
+ <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
+ <xsl:if test="$controlField008-11-14">
+ <dateIssued encoding="marc" point="end">
+ <xsl:value-of select="$controlField008-11-14"/>
+ </dateIssued>
+ </xsl:if>
+ </xsl:if>
+
+ <xsl:if test="$controlField008-6='q'">
+ <xsl:if test="$controlField008-7-10">
+ <dateIssued encoding="marc" point="start" qualifier="questionable">
+ <xsl:value-of select="$controlField008-7-10"/>
+ </dateIssued>
+ </xsl:if>
+ </xsl:if>
+
+ <xsl:if test="$controlField008-6='q'">
+ <xsl:if test="$controlField008-11-14">
+ <dateIssued encoding="marc" point="end" qualifier="questionable">
+ <xsl:value-of select="$controlField008-11-14"/>
+ </dateIssued>
+ </xsl:if>
+ </xsl:if>
+
+ <xsl:if test="$controlField008-6='t'">
+ <xsl:if test="$controlField008-11-14">
+ <copyrightDate encoding="marc">
+ <xsl:value-of select="$controlField008-11-14"/>
+ </copyrightDate>
+ </xsl:if>
+ </xsl:if>
+
+ <xsl:for-each select="marc:datafield[@tag=033][@ind1=0 or @ind1=1]/marc:subfield[@code='a']">
+ <dateCaptured encoding="iso8601">
+ <xsl:value-of select="."/>
+ </dateCaptured>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][1]">
+ <dateCaptured encoding="iso8601" point="start">
+ <xsl:value-of select="."/>
+ </dateCaptured>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][2]">
+ <dateCaptured encoding="iso8601" point="end">
+ <xsl:value-of select="."/>
+ </dateCaptured>
+ </xsl:for-each>
+-->
+
+ <!-- MARC21 250a -->
+ <xsl:for-each select="marc:datafield[@tag=205]/marc:subfield[@code='a']">
+ <edition>
+ <xsl:value-of select="."/>
+ </edition>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:leader">
+ <issuance>
+ <xsl:choose>
+ <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">monographic</xsl:when>
+ <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">continuing</xsl:when>
+ </xsl:choose>
+ </issuance>
+ </xsl:for-each>
+
+ <!-- MARC21 310 and 321 -->
+ <xsl:for-each select="marc:datafield[@tag=326]">
+ <frequency>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </frequency>
+ </xsl:for-each>
+ </originInfo>
+
+ <xsl:for-each select="marc:datafield[@tag=101]">
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <language>
+ <languageTerm authority="iso639-2b" type="code">
+ <xsl:value-of select="text()"/>
+ </languageTerm>
+ </language>
+ </xsl:for-each>
+ </xsl:for-each>
+ <xsl:variable name="controlField008-35-37" select="normalize-space(translate(substring($controlField008,36,3),'|#',''))"/>
+ <xsl:if test="$controlField008-35-37">
+ <language>
+ <languageTerm authority="iso639-2b" type="code">
+ <xsl:value-of select="substring($controlField008,36,3)"/>
+ </languageTerm>
+ </language>
+ </xsl:if>
+
+ <xsl:for-each select="marc:datafield[@tag=041]">
+
+ <!-- <xsl:variable name="langCodes">
+ <xsl:copy-of select="marc:subfield[@code='a'or @code='d' or @code='e' or @code='2']"/>
+ </xsl:variable>
+ -->
+ <xsl:variable name="langCodes" select="marc:subfield[@code='a'or @code='d' or @code='e' or @code='2']"/>
+
+ <xsl:choose>
+ <xsl:when test="marc:subfield[@code='2']='rfc3066'">
+ <!-- not stacked but could be repeated -->
+ <xsl:call-template name="rfcLanguages">
+ <xsl:with-param name="nodeNum">
+ <xsl:value-of select="1"/>
+ </xsl:with-param>
+ <xsl:with-param name="usedLanguages">
+ <xsl:text></xsl:text>
+ </xsl:with-param>
+ <xsl:with-param name="controlField008-35-37">
+ <xsl:value-of select="$controlField008-35-37"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- iso -->
+ <xsl:variable name="allLanguages">
+ <xsl:copy-of select="$langCodes"/>
+ </xsl:variable>
+ <xsl:variable name="currentLanguage">
+ <xsl:value-of select="substring($allLanguages,1,3)"/>
+ </xsl:variable>
+ <xsl:call-template name="isoLanguage">
+ <xsl:with-param name="currentLanguage">
+ <xsl:value-of select="substring($allLanguages,1,3)"/>
+ </xsl:with-param>
+ <xsl:with-param name="remainingLanguages">
+ <xsl:value-of select="substring($allLanguages,4,string-length($allLanguages)-3)"/>
+ </xsl:with-param>
+ <xsl:with-param name="usedLanguages">
+ <xsl:if test="$controlField008-35-37">
+ <xsl:value-of select="$controlField008-35-37"/>
+ </xsl:if>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+
+ <xsl:variable name="physicalDescription">
+ <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='a' or substring(.,12,1)='b']">
+ <digitalOrigin>reformatted digital</digitalOrigin>
+ </xsl:if>
+
+ <xsl:variable name="controlField008-23" select="substring($controlField008,24,1)"/>
+ <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"/>
+
+ <xsl:variable name="check008-23">
+ <xsl:if test="$typeOf008='BK' or $typeOf008='MU' or $typeOf008='SE' or $typeOf008='MM'">
+ <xsl:value-of select="true()"/>
+ </xsl:if>
+ </xsl:variable>
+
+ <xsl:variable name="check008-29">
+ <xsl:if test="$typeOf008='MP' or $typeOf008='VM'">
+ <xsl:value-of select="true()"/>
+ </xsl:if>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="($check008-23 and $controlField008-23='f') or ($check008-29 and $controlField008-29='f')">
+ <form authority="marcform">braille</form>
+ </xsl:when>
+ <xsl:when test="($controlField008-23=' ' and ($leader6='c' or $leader6='d')) or (($typeOf008='BK' or $typeOf008='SE') and ($controlField008-23=' ' or $controlField008='r'))">
+ <form authority="marcform">print</form>
+ </xsl:when>
+ <xsl:when test="$leader6 = 'm' or ($check008-23 and $controlField008-23='s') or ($check008-29 and $controlField008-29='s')">
+ <form authority="marcform">electronic</form>
+ </xsl:when>
+ <xsl:when test="($check008-23 and $controlField008-23='b') or ($check008-29 and $controlField008-29='b')">
+ <form authority="marcform">microfiche</form>
+ </xsl:when>
+ <xsl:when test="($check008-23 and $controlField008-23='a') or ($check008-29 and $controlField008-29='a')">
+ <form authority="marcform">microfilm</form>
+ </xsl:when>
+ </xsl:choose>
+<!--
+ <xsl:if test="marc:datafield[@tag=130]/marc:subfield[@code='h']">
+ <form authority="gmd">
+ <xsl:call-template name="chopBrackets">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:datafield[@tag=130]/marc:subfield[@code='h']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </form>
+ </xsl:if>
+
+ <xsl:if test="marc:datafield[@tag=240]/marc:subfield[@code='h']">
+ <form authority="gmd">
+ <xsl:call-template name="chopBrackets">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:datafield[@tag=240]/marc:subfield[@code='h']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </form>
+ </xsl:if>
+ <xsl:if test="marc:datafield[@tag=242]/marc:subfield[@code='h']">
+ <form authority="gmd">
+ <xsl:call-template name="chopBrackets">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:datafield[@tag=242]/marc:subfield[@code='h']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </form>
+ </xsl:if>
+ <xsl:if test="marc:datafield[@tag=245]/marc:subfield[@code='h']">
+ <form authority="gmd">
+ <xsl:call-template name="chopBrackets">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:datafield[@tag=245]/marc:subfield[@code='h']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </form>
+ </xsl:if>
+ <xsl:if test="marc:datafield[@tag=246]/marc:subfield[@code='h']">
+ <form authority="gmd">
+ <xsl:call-template name="chopBrackets">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:datafield[@tag=246]/marc:subfield[@code='h']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </form>
+ </xsl:if>
+ <xsl:if test="marc:datafield[@tag=730]/marc:subfield[@code='h']">
+ <form authority="gmd">
+ <xsl:call-template name="chopBrackets">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:datafield[@tag=730]/marc:subfield[@code='h']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </form>
+ </xsl:if>
+ <xsl:for-each select="marc:datafield[@tag=256]/marc:subfield[@code='a']">
+ <form>
+ <xsl:value-of select="."/>
+ </form>
+ </xsl:for-each>
+-->
+ <xsl:for-each select="marc:controlfield[@tag=007][substring(text(),1,1)='c']">
+ <xsl:choose>
+ <xsl:when test="substring(text(),14,1)='a'">
+ <reformattingQuality>access</reformattingQuality>
+ </xsl:when>
+ <xsl:when test="substring(text(),14,1)='p'">
+ <reformattingQuality>preservation</reformattingQuality>
+ </xsl:when>
+ <xsl:when test="substring(text(),14,1)='r'">
+ <reformattingQuality>replacement</reformattingQuality>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=856]/marc:subfield[@code='q'][string-length(.)&gt;1]">
+ <internetMediaType>
+ <xsl:value-of select="."/>
+ </internetMediaType>
+ </xsl:for-each>
+
+ <!-- MARC21 tag 300 - PHYSICAL DESCRIPTION (R) subfields abce-->
+ <xsl:for-each select="marc:datafield[@tag=215]">
+ <extent>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">acde</xsl:with-param>
+ </xsl:call-template>
+ </extent>
+ </xsl:for-each>
+ </xsl:variable>
+
+ <xsl:if test="string-length(normalize-space($physicalDescription))">
+ <physicalDescription>
+ <xsl:copy-of select="$physicalDescription"/>
+ </physicalDescription>
+ </xsl:if>
+
+ <!-- MARC21 tag 520 -->
+ <xsl:for-each select="marc:datafield[@tag=330]">
+ <abstract>
+ <xsl:call-template name="uri"/>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </abstract>
+ </xsl:for-each>
+
+ <!-- MARC21 tag 505 -->
+ <xsl:for-each select="marc:datafield[@tag=327]">
+ <tableOfContents>
+ <xsl:call-template name="uri"/>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">agrt</xsl:with-param>
+ </xsl:call-template>
+ </tableOfContents>
+ </xsl:for-each>
+
+ <!-- MARC21 tag 521 -->
+ <xsl:for-each select="marc:datafield[@tag=333]">
+ <targetAudience>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </targetAudience>
+ </xsl:for-each>
+
+ <xsl:if test="$typeOf008='BK' or $typeOf008='CF' or $typeOf008='MU' or $typeOf008='VM'">
+ <xsl:variable name="controlField008-22" select="substring($controlField008,23,1)"/>
+ <xsl:choose>
+ <!-- 01/04 fix -->
+ <xsl:when test="$controlField008-22='d'">
+ <targetAudience authority="marctarget">adolescent</targetAudience>
+ </xsl:when>
+ <xsl:when test="$controlField008-22='e'">
+ <targetAudience authority="marctarget">adult</targetAudience>
+ </xsl:when>
+ <xsl:when test="$controlField008-22='g'">
+ <targetAudience authority="marctarget">general</targetAudience>
+ </xsl:when>
+ <xsl:when test="$controlField008-22='b' or $controlField008-22='c' or $controlField008-22='j'">
+ <targetAudience authority="marctarget">juvenile</targetAudience>
+ </xsl:when>
+ <xsl:when test="$controlField008-22='a'">
+ <targetAudience authority="marctarget">preschool</targetAudience>
+ </xsl:when>
+ <xsl:when test="$controlField008-22='f'">
+ <targetAudience authority="marctarget">specialized</targetAudience>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+
+ <!-- MARC21 tag 245c -->
+ <xsl:for-each select="marc:datafield[@tag=200]/marc:subfield[@code='f' or @code='g']">
+ <note type="statement of responsibility">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="punctuation">
+ <xsl:text>.:,;/] </xsl:text> <!-- have to add the closing bracket -->
+ </xsl:with-param>
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="chopPunctuationFront">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </note>
+ </xsl:for-each>
+
+ <!-- MARC21 tag 500 -->
+ <xsl:for-each select="marc:datafield[@tag &gt; 299 and @tag &lt; 316]">
+ <note>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ <xsl:call-template name="uri"/>
+ </note>
+ </xsl:for-each>
+
+ <!-- MARC21 tag 511 -->
+ <xsl:for-each select="marc:datafield[@tag=323]">
+ <note type="performers">
+ <xsl:call-template name="uri"/>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </note>
+ </xsl:for-each>
+
+<!--
+ <xsl:for-each select="marc:datafield[@tag=518]">
+ <note type="venue">
+ <xsl:call-template name="uri"/>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </note>
+ </xsl:for-each>
+
+
+ <xsl:for-each select="marc:datafield[@tag=501 or @tag=502 or @tag=504 or @tag=506 or @tag=507 or @tag=508 or @tag=513 or @tag=514 or @tag=515 or @tag=516 or @tag=522 or @tag=524 or @tag=525 or @tag=526 or @tag=530 or @tag=533 or @tag=534 or @tag=535 or @tag=536 or @tag=538 or @tag=540 or @tag=541 or @tag=544 or @tag=545 or @tag=546 or @tag=547 or @tag=550 or @tag=552 or @tag=555 or @tag=556 or @tag=561 or @tag=562 or @tag=565 or @tag=567 or @tag=580 or @tag=581 or @tag=583 or @tag=584 or @tag=585 or @tag=586]">
+ <note>
+ <xsl:call-template name="uri"/>
+ <xsl:variable name="str">
+ <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
+ <xsl:value-of select="."/>
+ <xsl:text> </xsl:text>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+ </note>
+ </xsl:for-each>
+-->
+
+ <!-- MARC21 tag 034 -->
+ <xsl:for-each select="marc:datafield[@tag=123][marc:subfield[@code='d' or @code='e' or @code='f' or @code='g']]">
+ <subject>
+ <cartographics>
+ <coordinates>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">defg</xsl:with-param>
+ </xsl:call-template>
+ </coordinates>
+ </cartographics>
+ </subject>
+ </xsl:for-each>
+
+ <!-- Unknown -->
+ <xsl:for-each select="marc:datafield[@tag=043]">
+ <subject>
+ <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
+ <geographicCode>
+ <xsl:attribute name="authority">
+ <xsl:if test="@code='a'">
+ <xsl:text>marcgac</xsl:text>
+ </xsl:if>
+ <xsl:if test="@code='b'">
+ <xsl:value-of select="following-sibling::marc:subfield[@code=2]"/>
+ </xsl:if>
+ <xsl:if test="@code='c'">
+ <xsl:text>iso3166</xsl:text>
+ </xsl:if>
+ </xsl:attribute>
+ <xsl:value-of select="self::marc:subfield"/>
+ </geographicCode>
+ </xsl:for-each>
+ </subject>
+ </xsl:for-each>
+
+ <!-- MARC21 tag 255 -->
+ <!-- needs parsing -->
+<!--
+ <xsl:for-each select="marc:datafield[@tag=206]">
+ <subject>
+ <cartographics>
+ <xsl:for-each select="marc:subfield[@code='c']">
+ <coordinates>
+ <xsl:value-of select="."/>
+ </coordinates>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <scale>
+ <xsl:value-of select="."/>
+ </scale>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <projection>
+ <xsl:value-of select="."/>
+ </projection>
+ </xsl:for-each>
+ </cartographics>
+ </subject>
+ </xsl:for-each>
+-->
+
+ <xsl:apply-templates select="marc:datafield[653 &gt;= @tag and @tag &gt;= 600]"/>
+
+ <xsl:apply-templates select="marc:datafield[@tag=656]"/>
+
+ <!-- MARC21 tag 752 -->
+ <xsl:for-each select="marc:datafield[@tag=620]">
+ <subject>
+ <hierarchicalGeographic>
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <country>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </country>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <state>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </state>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='c']">
+ <county>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </county>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='d']">
+ <city>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </city>
+ </xsl:for-each>
+ </hierarchicalGeographic>
+ </subject>
+ </xsl:for-each>
+
+ <!-- MARC21 tag 045 -->
+ <xsl:for-each select="marc:datafield[@tag=122][marc:subfield[@code='a']]">
+ <subject>
+
+ <xsl:choose>
+
+ <xsl:when test="@ind1=2">
+
+ <temporal encoding="iso8601" point="start">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:subfield[@code='a'][1]"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </temporal>
+ <temporal encoding="iso8601" point="end">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+
+
+ <xsl:value-of select="marc:subfield[@code='a'][2]"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </temporal>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <temporal encoding="iso8601">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </temporal>
+ </xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
+ </subject>
+ </xsl:for-each>
+
+<!--
+ <xsl:for-each select="marc:datafield[@tag=050]">
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <classification authority="lcc">
+ <xsl:value-of select="preceding-sibling::marc:subfield[@code='a'][1]"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="text()"/>
+ </classification>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='a'][not(following-sibling::marc:subfield[@code='b'])]">
+ <classification authority="lcc">
+ <xsl:value-of select="text()"/>
+ </classification>
+ </xsl:for-each>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=082]">
+ <classification authority="ddc">
+ <xsl:if test="marc:subfield[@code='2']">
+ <xsl:attribute name="edition">
+ <xsl:value-of select="marc:subfield[@code='2']"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </classification>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=080]">
+ <classification authority="udc">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abx</xsl:with-param>
+ </xsl:call-template>
+ </classification>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=060]">
+ <classification authority="nlm">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </classification>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=086][@ind1=0]">
+ <classification authority="sudocs">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </classification>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=086][@ind1=1]">
+ <classification authority="candoc">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </classification>
+ </xsl:for-each>
+-->
+ <!-- MARC21 086a -->
+ <xsl:for-each select="marc:datafield[@tag=022]">
+ <classification>
+ <xsl:attribute name="authority">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </xsl:attribute>
+ <xsl:value-of select="marc:subfield[@code='b']"/>
+ </classification>
+ </xsl:for-each>
+
+ <!--
+ <xsl:for-each select="marc:datafield[@tag=084]">
+ <classification>
+ <xsl:attribute name="authority">
+ <xsl:value-of select="marc:subfield[@code='2']"/>
+ </xsl:attribute>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </classification>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=440]">
+ <relatedItem type="series">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">av</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ </relatedItem>
+ </xsl:for-each>
+-->
+
+ <!-- MARC21 490/0 -->
+ <xsl:for-each select="marc:datafield[@tag=490]">
+ <relatedItem type="series">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">adefhv</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ </relatedItem>
+ </xsl:for-each>
+
+<!--
+ <xsl:for-each select="marc:datafield[@tag=510]">
+ <relatedItem type="isReferencedBy">
+ <note>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcx3</xsl:with-param>
+ </xsl:call-template>
+ </note>
+ </relatedItem>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=534]">
+ <relatedItem type="original">
+ <xsl:call-template name="relatedTitle"/>
+ <xsl:call-template name="relatedName"/>
+ <xsl:if test="marc:subfield[@code='b' or @code='c']">
+ <originInfo>
+ <xsl:for-each select="marc:subfield[@code='c']">
+ <publisher>
+ <xsl:value-of select="."/>
+ </publisher>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <edition>
+ <xsl:value-of select="."/>
+ </edition>
+ </xsl:for-each>
+ </originInfo>
+ </xsl:if>
+ <xsl:call-template name="relatedIdentifierISSN"/>
+ <xsl:for-each select="marc:subfield[@code='z']">
+ <identifier type="isbn">
+ <xsl:value-of select="."/>
+ </identifier>
+ </xsl:for-each>
+ <xsl:call-template name="relatedNote"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=700][marc:subfield[@code='t']]">
+ <relatedItem>
+ <xsl:call-template name="constituentOrRelatedType"/>
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="afterCodes">g</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ <name type="personal">
+ <namePart>
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">aq</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="beforeCodes">g</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ <xsl:call-template name="termsOfAddress"/>
+ <xsl:call-template name="nameDate"/>
+ <xsl:call-template name="role"/>
+ </name>
+ <xsl:call-template name="relatedForm"/>
+ <xsl:call-template name="relatedIdentifierISSN"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=710][marc:subfield[@code='t']]">
+ <relatedItem>
+ <xsl:call-template name="constituentOrRelatedType"/>
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="afterCodes">dg</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="relatedPartNumName"/>
+ </titleInfo>
+ <name type="corporate">
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </xsl:for-each>
+ <xsl:variable name="tempNamePart">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">c</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:if test="normalize-space($tempNamePart)">
+ <namePart>
+ <xsl:value-of select="$tempNamePart"/>
+ </namePart>
+ </xsl:if>
+ <xsl:call-template name="role"/>
+ </name>
+ <xsl:call-template name="relatedForm"/>
+ <xsl:call-template name="relatedIdentifierISSN"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=711][marc:subfield[@code='t']]">
+ <relatedItem>
+ <xsl:call-template name="constituentOrRelatedType"/>
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="afterCodes">g</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="relatedPartNumName"/>
+ </titleInfo>
+ <name type="conference">
+ <namePart>
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="beforeCodes">gn</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ </name>
+ <xsl:call-template name="relatedForm"/>
+ <xsl:call-template name="relatedIdentifierISSN"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=730][@ind2=2]">
+ <relatedItem>
+ <xsl:call-template name="constituentOrRelatedType"/>
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ <xsl:call-template name="relatedForm"/>
+ <xsl:call-template name="relatedIdentifierISSN"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=740][@ind2=2]">
+ <relatedItem>
+ <xsl:call-template name="constituentOrRelatedType"/>
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ <xsl:call-template name="relatedForm"/>
+ </relatedItem>
+ </xsl:for-each>
+-->
+
+ <!-- MARC21 760 and 762 -->
+ <xsl:for-each select="marc:datafield[@tag=410]|marc:datafield[@tag=411]">
+ <relatedItem type="series">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <!-- MARC21 777 and 787 -->
+ <xsl:for-each select="marc:datafield[@tag=423]|marc:datafield[@tag=455]">
+ <relatedItem>
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <!-- MARC21 775 -->
+ <xsl:for-each select="marc:datafield[@tag=451]">
+ <relatedItem type="otherVersion">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <!-- MARC21 770 and 774 -->
+ <xsl:for-each select="marc:datafield[@tag=421]|marc:datafield[@tag=461]|marc:datafield[@tag=462]">
+ <relatedItem type="constituent">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <!-- MARC21 772 and 773 -->
+ <xsl:for-each select="marc:datafield[@tag=442]|marc:datafield[@tag=463]">
+ <relatedItem type="host">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <!-- MARC21 776 -->
+ <xsl:for-each select="marc:datafield[@tag=452]">
+ <relatedItem type="otherFormat">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <!-- MARC21 780 -->
+ <xsl:for-each select="marc:datafield[@tag &gt; 429 and @tag &lt; 438]">
+ <relatedItem type="preceding">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <!-- MARC21 785 -->
+ <xsl:for-each select="marc:datafield[@tag &gt; 439 and @tag &lt; 449]">
+ <relatedItem type="succeeding">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+
+<!--
+ <xsl:for-each select="marc:datafield[@tag=786]">
+ <relatedItem type="original">
+ <xsl:call-template name="relatedItem76X-78X"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=800]">
+ <relatedItem type="series">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="afterCodes">g</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ <name type="personal">
+ <namePart>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">aq</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="beforeCodes">g</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ <xsl:call-template name="termsOfAddress"/>
+ <xsl:call-template name="nameDate"/>
+ <xsl:call-template name="role"/>
+ </name>
+ <xsl:call-template name="relatedForm"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=810]">
+ <relatedItem type="series">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="afterCodes">dg</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="relatedPartNumName"/>
+ </titleInfo>
+ <name type="corporate">
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </xsl:for-each>
+ <namePart>
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">c</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ <xsl:call-template name="role"/>
+ </name>
+ <xsl:call-template name="relatedForm"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=811]">
+ <relatedItem type="series">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="afterCodes">g</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="relatedPartNumName"/>
+ </titleInfo>
+ <name type="conference">
+ <namePart>
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
+ <xsl:with-param name="axis">t</xsl:with-param>
+ <xsl:with-param name="beforeCodes">gn</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ <xsl:call-template name="role"/>
+ </name>
+ <xsl:call-template name="relatedForm"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=830]">
+ <relatedItem type="series">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:call-template name="part"/>
+ </titleInfo>
+ <xsl:call-template name="relatedForm"/>
+ </relatedItem>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=856][@ind2=2]/marc:subfield[@code='q']">
+ <relatedItem>
+ <internetMediaType>
+ <xsl:value-of select="."/>
+ </internetMediaType>
+ </relatedItem>
+ </xsl:for-each>
+-->
+
+ <!-- MARC21 020 -->
+ <xsl:for-each select="marc:datafield[@tag=010]">
+ <identifier type="isbn">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:value-of select="translate(marc:subfield[@code='a'],'-','')"/>
+ </identifier>
+ </xsl:for-each>
+
+<!--
+ <xsl:for-each select="marc:datafield[@tag=024][@ind1=0]">
+ <identifier type="isrc">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </identifier>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=024][@ind1=2]">
+ <identifier type="ismn">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </identifier>
+ </xsl:for-each>
+-->
+
+ <!-- MARC21 022 -->
+ <xsl:for-each select="marc:datafield[@tag=011]">
+ <identifier type="issn">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </identifier>
+ </xsl:for-each>
+<!--
+ <xsl:for-each select="marc:datafield[@tag=010]">
+ <identifier type="lccn">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:value-of select="normalize-space(marc:subfield[@code='a'])"/>
+ </identifier>
+ </xsl:for-each>
+-->
+ <!-- MARC21 028 -->
+ <xsl:for-each select="marc:datafield[@tag=071]">
+ <identifier>
+ <xsl:call-template name="isInvalid"/>
+ <xsl:attribute name="type">
+ <xsl:choose>
+ <xsl:when test="@ind1=0">issue number</xsl:when>
+ <xsl:when test="@ind1=1">matrix number</xsl:when>
+ <xsl:when test="@ind1=2">music plate</xsl:when>
+ <xsl:when test="@ind1=3">music publisher</xsl:when>
+ <xsl:when test="@ind1=4">videorecording identifier</xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">
+ <xsl:choose>
+ <xsl:when test="@ind1=0">ba</xsl:when>
+ <xsl:otherwise>ab</xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ </xsl:call-template>
+ </identifier>
+ </xsl:for-each>
+
+<!--
+ <xsl:for-each select="marc:datafield[@tag=024][@ind1='4']">
+ <identifier type="sici">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </identifier>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=037]">
+ <identifier type="stock number">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </identifier>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=856][marc:subfield[@code='u']]">
+ <identifier>
+ <xsl:attribute name="type">
+ <xsl:choose>
+ <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:doi') or starts-with(marc:subfield[@code='u'],'doi')">doi</xsl:when>
+ <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov')">hdl</xsl:when>
+ <xsl:otherwise>uri</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <xsl:choose>
+ <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov') ">
+ <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="marc:subfield[@code='u']"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </identifier>
+ <xsl:if test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl')">
+ <identifier type="hdl">
+ <xsl:if test="marc:subfield[@code='y' or @code='3' or @code='z']">
+ <xsl:attribute name="displayLabel">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">y3z</xsl:with-param>
+ </xsl:call-template>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"/>
+ </identifier>
+ </xsl:if>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=024][@ind1=1]">
+ <identifier type="upc">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </identifier>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=856][marc:subfield[@code='u']]">
+ <location>
+ <url>
+ <xsl:if test="marc:subfield[@code='y' or @code='3']">
+ <xsl:attribute name="displayLabel">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">y3</xsl:with-param>
+ </xsl:call-template>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="marc:subfield[@code='u']"/>
+ </url>
+ </location>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=852]">
+ <location>
+ <physicalLocation>
+ <xsl:call-template name="displayLabel"/>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abje</xsl:with-param>
+ </xsl:call-template>
+ </physicalLocation>
+ </location>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=506]">
+ <accessCondition type="restrictionOnAccess">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcd35</xsl:with-param>
+ </xsl:call-template>
+ </accessCondition>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=540]">
+ <accessCondition type="useAndReproduction">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcde35</xsl:with-param>
+ </xsl:call-template>
+ </accessCondition>
+ </xsl:for-each>
+-->
+ <recordInfo>
+<!--
+ <xsl:for-each select="marc:datafield[@tag=040]">
+ <recordContentSource authority="marcorg">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </recordContentSource>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:controlfield[@tag=008]">
+ <recordCreationDate encoding="marc">
+ <xsl:value-of select="substring(.,1,6)"/>
+ </recordCreationDate>
+ </xsl:for-each>
+-->
+
+ <xsl:for-each select="marc:controlfield[@tag=005]">
+ <recordChangeDate encoding="iso8601">
+ <xsl:value-of select="."/>
+ </recordChangeDate>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:controlfield[@tag=001]">
+ <recordIdentifier>
+ <xsl:if test="../marc:controlfield[@tag=003]">
+ <xsl:attribute name="source">
+ <xsl:value-of select="../marc:controlfield[@tag=003]"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="."/>
+ </recordIdentifier>
+ </xsl:for-each>
+
+ <!-- needs to process tag 100 -->
+ <xsl:for-each select="marc:datafield[@tag=040]/marc:subfield[@code='b']">
+ <languageOfCataloging>
+ <languageTerm authority="iso639-2b" type="code">
+ <xsl:value-of select="."/>
+ </languageTerm>
+ </languageOfCataloging>
+ </xsl:for-each>
+ </recordInfo>
+ </xsl:template>
+
+ <xsl:template name="displayForm">
+ <xsl:for-each select="marc:subfield[@code='c']">
+ <displayForm>
+ <xsl:value-of select="."/>
+ </displayForm>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="affiliation">
+ <xsl:for-each select="marc:subfield[@code='p']">
+ <affiliation>
+ <xsl:value-of select="."/>
+ </affiliation>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="uri">
+ <xsl:for-each select="marc:subfield[@code='u']">
+ <xsl:attribute name="xlink:href">
+ <xsl:value-of select="."/>
+ </xsl:attribute>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="role">
+ <xsl:for-each select="marc:subfield[@code='e']">
+ <role>
+ <roleTerm type="text">
+ <xsl:value-of select="."/>
+ </roleTerm>
+ </role>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='4']">
+ <role>
+ <roleTerm authority="marcrelator" type="code">
+ <xsl:value-of select="."/>
+ </roleTerm>
+ </role>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="part">
+ <xsl:variable name="partNumber">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="axis">h</xsl:with-param>
+ <xsl:with-param name="anyCodes">h</xsl:with-param>
+ <xsl:with-param name="afterCodes">bfgvz</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="partName">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="axis">i</xsl:with-param>
+ <xsl:with-param name="anyCodes">i</xsl:with-param>
+ <xsl:with-param name="afterCodes">bfgvz</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:if test="string-length(normalize-space($partNumber))">
+ <partNumber>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="$partNumber"/>
+ </xsl:call-template>
+ </partNumber>
+ </xsl:if>
+ <xsl:if test="string-length(normalize-space($partName))">
+ <partName>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="$partName"/>
+ </xsl:call-template>
+ </partName>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="relatedPart">
+ <xsl:if test="@tag=773">
+ <xsl:for-each select="marc:subfield[@code='g']">
+ <part>
+ <text>
+ <xsl:value-of select="."/>
+ </text>
+ </part>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='q']">
+ <part>
+ <xsl:call-template name="parsePart"/>
+ </part>
+ </xsl:for-each>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="relatedPartNumName">
+ <xsl:variable name="partNumber">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="axis">g</xsl:with-param>
+ <xsl:with-param name="anyCodes">g</xsl:with-param>
+ <xsl:with-param name="afterCodes">pst</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="partName">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="axis">p</xsl:with-param>
+ <xsl:with-param name="anyCodes">p</xsl:with-param>
+ <xsl:with-param name="afterCodes">fghkdlmor</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:if test="string-length(normalize-space($partNumber))">
+ <partNumber>
+ <xsl:value-of select="$partNumber"/>
+ </partNumber>
+ </xsl:if>
+ <xsl:if test="string-length(normalize-space($partName))">
+ <partName>
+ <xsl:value-of select="$partName"/>
+ </partName>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="relatedName">
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <name>
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </name>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="relatedForm">
+ <xsl:for-each select="marc:subfield[@code='h']">
+ <physicalDescription>
+ <form>
+ <xsl:value-of select="."/>
+ </form>
+ </physicalDescription>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="relatedExtent">
+ <xsl:for-each select="marc:subfield[@code='h']">
+ <physicalDescription>
+ <extent>
+ <xsl:value-of select="."/>
+ </extent>
+ </physicalDescription>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="relatedNote">
+ <xsl:for-each select="marc:subfield[@code='n']">
+ <note>
+ <xsl:value-of select="."/>
+ </note>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="relatedSubject">
+ <xsl:for-each select="marc:subfield[@code='j']">
+ <subject>
+ <temporal encoding="iso8601">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </temporal>
+ </subject>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="relatedIdentifierISSN">
+ <xsl:for-each select="marc:subfield[@code='x']">
+ <identifier type="issn">
+ <xsl:value-of select="."/>
+ </identifier>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="relatedIdentifierISBN">
+ <xsl:for-each select="marc:subfield[@code='y']">
+ <identifier type="isbn">
+ <xsl:value-of select="."/>
+ </identifier>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="relatedIdentifierLocal">
+ <xsl:for-each select="marc:subfield[@code='w']">
+ <identifier type="local">
+ <xsl:value-of select="."/>
+ </identifier>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="relatedIdentifier">
+ <xsl:for-each select="marc:subfield[@code='o']">
+ <identifier>
+ <xsl:value-of select="."/>
+ </identifier>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="relatedItem76X-78X">
+ <xsl:call-template name="displayLabel"/>
+ <xsl:call-template name="relatedTitle76X-78X"/>
+ <xsl:call-template name="relatedName"/>
+ <xsl:call-template name="relatedOriginInfo"/>
+ <xsl:call-template name="relatedLanguage"/>
+ <xsl:call-template name="relatedExtent"/>
+ <xsl:call-template name="relatedNote"/>
+ <xsl:call-template name="relatedSubject"/>
+ <xsl:call-template name="relatedIdentifier"/>
+ <xsl:call-template name="relatedIdentifierISSN"/>
+ <xsl:call-template name="relatedIdentifierISBN"/>
+ <xsl:call-template name="relatedIdentifierLocal"/>
+ <xsl:call-template name="relatedPart"/>
+ </xsl:template>
+
+ <xsl:template name="subjectGeographicZ">
+ <geographic>
+
+
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </geographic>
+ </xsl:template>
+
+ <xsl:template name="subjectTemporalY">
+ <temporal>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </temporal>
+ </xsl:template>
+
+ <xsl:template name="subjectTopic">
+ <topic>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </topic>
+ </xsl:template>
+
+ <xsl:template name="nameABCDN">
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <namePart>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </namePart>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </xsl:for-each>
+ <xsl:if test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
+ <namePart>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">cdn</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="nameABCDQ">
+ <namePart>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">aq</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ <xsl:with-param name="punctuation">
+ <xsl:text>:,;/ </xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ <xsl:call-template name="termsOfAddress"/>
+ <xsl:call-template name="nameDate"/>
+ </xsl:template>
+
+ <!-- added for unimarc -->
+ <xsl:template name="nameABCDFG">
+ <namePart>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abdg</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ <xsl:with-param name="punctuation">
+ <xsl:text>:,;/ </xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ <xsl:call-template name="termsOfAddress"/>
+ <xsl:call-template name="nameDate"/>
+ </xsl:template>
+
+ <xsl:template name="nameACDEQ">
+ <namePart>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">acdeq</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ </xsl:template>
+
+ <!-- added for unimarc -->
+ <xsl:template name="nameABCDEF">
+ <namePart>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcdef</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ </xsl:template>
+
+ <xsl:template name="constituentOrRelatedType">
+ <xsl:if test="@ind2=2">
+ <xsl:attribute name="type">constituent</xsl:attribute>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="relatedTitle">
+ <xsl:for-each select="marc:subfield[@code='t']">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ </titleInfo>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="relatedTitle76X-78X">
+ <xsl:for-each select="marc:subfield[@code='t']">
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
+ <xsl:call-template name="relatedPartNumName"/>
+ </xsl:if>
+ </titleInfo>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='p']">
+ <titleInfo type="abbreviated">
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
+ <xsl:call-template name="relatedPartNumName"/>
+ </xsl:if>
+ </titleInfo>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='s']">
+ <titleInfo type="uniform">
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </title>
+ <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
+ <xsl:call-template name="relatedPartNumName"/>
+ </xsl:if>
+ </titleInfo>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="relatedOriginInfo">
+ <xsl:if test="marc:subfield[@code='b' or @code='d'] or marc:subfield[@code='f']">
+ <originInfo>
+ <xsl:if test="@tag=775">
+ <xsl:for-each select="marc:subfield[@code='f']">
+ <place>
+ <placeTerm>
+ <xsl:attribute name="type">code</xsl:attribute>
+ <xsl:attribute name="authority">marcgac</xsl:attribute>
+ <xsl:value-of select="."/>
+ </placeTerm>
+ </place>
+ </xsl:for-each>
+ </xsl:if>
+ <xsl:for-each select="marc:subfield[@code='d']">
+ <publisher>
+ <xsl:value-of select="."/>
+ </publisher>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <edition>
+ <xsl:value-of select="."/>
+ </edition>
+ </xsl:for-each>
+ </originInfo>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="relatedLanguage">
+ <xsl:for-each select="marc:subfield[@code='e']">
+ <xsl:call-template name="getLanguage">
+ <xsl:with-param name="langString">
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:for-each>
+ </xsl:template>
+ <xsl:template name="nameDate">
+ <xsl:for-each select="marc:subfield[@code='f']">
+ <namePart type="date">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </namePart>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="subjectAuthority">
+
+ <xsl:if test="@ind2!=4">
+ <xsl:if test="@ind2!=' '">
+ <xsl:if test="@ind2!=8">
+ <xsl:if test="@ind2!=9">
+ <xsl:attribute name="authority">
+ <xsl:choose>
+
+ <xsl:when test="@ind2=0">lcsh</xsl:when>
+ <xsl:when test="@ind2=1">lcshac</xsl:when>
+ <xsl:when test="@ind2=2">mesh</xsl:when>
+ <!-- 1/04 fix -->
+ <xsl:when test="@ind2=3">nal</xsl:when>
+ <xsl:when test="@ind2=5">csh</xsl:when>
+ <xsl:when test="@ind2=6">rvm</xsl:when>
+ <xsl:when test="@ind2=7">
+ <xsl:value-of select="marc:subfield[@code='2']"/>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+ </xsl:if>
+ </xsl:if>
+ </xsl:if>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="subjectAnyOrder">
+ <xsl:for-each select="marc:subfield[@code='v' or @code='x' or @code='y' or @code='z']">
+ <xsl:choose>
+ <xsl:when test="@code='v'">
+ <xsl:call-template name="subjectTopic"/>
+ </xsl:when>
+ <xsl:when test="@code='x'">
+ <xsl:call-template name="subjectTopic"/>
+ </xsl:when>
+ <xsl:when test="@code='y'">
+ <xsl:call-template name="subjectTemporalY"/>
+ </xsl:when>
+ <xsl:when test="@code='z'">
+ <xsl:call-template name="subjectGeographicZ"/>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="specialSubfieldSelect">
+ <xsl:param name="anyCodes"/>
+ <xsl:param name="axis"/>
+ <xsl:param name="beforeCodes"/>
+ <xsl:param name="afterCodes"/>
+ <xsl:variable name="str">
+ <xsl:for-each select="marc:subfield">
+ <xsl:if test="contains($anyCodes, @code) or (contains($beforeCodes,@code) and following-sibling::marc:subfield[@code=$axis]) or (contains($afterCodes,@code) and preceding-sibling::marc:subfield[@code=$axis])">
+ <xsl:value-of select="text()"/>
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=600 or @tag=602 or @Tag=604]">
+ <subject>
+ <xsl:call-template name="subjectAuthority"/>
+ <name type="personal">
+ <xsl:call-template name="termsOfAddress"/>
+ <namePart>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">a</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ <xsl:call-template name="nameDate"/>
+ <xsl:call-template name="affiliation"/>
+ <xsl:call-template name="role"/>
+ </name>
+ <xsl:call-template name="subjectAnyOrder"/>
+ </subject>
+ </xsl:template>
+
+ <!-- MARC21 field 610 -->
+ <xsl:template match="marc:datafield[@tag=601 and @ind1=0]">
+ <subject>
+ <xsl:call-template name="subjectAuthority"/>
+ <name type="corporate">
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <namePart>
+ <xsl:value-of select="."/>
+ </namePart>
+ </xsl:for-each>
+ <xsl:if test="marc:subfield[@code='d' or @code='e' or @code='f']">
+ <namePart>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">def</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ </xsl:if>
+ <xsl:call-template name="role"/>
+ </name>
+ <xsl:call-template name="subjectAnyOrder"/>
+ </subject>
+ </xsl:template>
+
+ <!-- MARC21 field 611 -->
+ <xsl:template match="marc:datafield[@tag=601 and @ind1=01]">
+ <subject>
+ <xsl:call-template name="subjectAuthority"/>
+ <name type="conference">
+ <namePart>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcdefghqnp</xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ <xsl:for-each select="marc:subfield[@code='4']">
+ <role>
+ <roleTerm authority="marcrelator" type="code">
+ <xsl:value-of select="."/>
+ </roleTerm>
+ </role>
+ </xsl:for-each>
+ </name>
+ <xsl:call-template name="subjectAnyOrder"/>
+ </subject>
+ </xsl:template>
+
+ <!-- MARC21 field 630 -->
+ <xsl:template match="marc:datafield[@tag=605]">
+ <subject>
+ <xsl:call-template name="subjectAuthority"/>
+ <titleInfo>
+ <title>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">adfkloqr</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ <xsl:call-template name="part"/>
+ </title>
+ </titleInfo>
+ <xsl:call-template name="subjectAnyOrder"/>
+ </subject>
+ </xsl:template>
+
+ <!-- MARC21 field 650 -->
+ <xsl:template match="marc:datafield[@tag=606]">
+ <subject>
+ <xsl:call-template name="subjectAuthority"/>
+ <topic>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcd</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </topic>
+ <xsl:call-template name="subjectAnyOrder"/>
+ </subject>
+ </xsl:template>
+
+ <!-- MARC21 field 651 -->
+ <xsl:template match="marc:datafield[@tag=607]">
+ <subject>
+ <xsl:call-template name="subjectAuthority"/>
+ <xsl:for-each select="marc:subfield[@code='a']">
+
+ <geographic>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </geographic>
+ </xsl:for-each>
+
+ <xsl:call-template name="subjectAnyOrder"/>
+ </subject>
+ </xsl:template>
+
+ <!-- MARC21 field 610, empty ind2 -->
+ <xsl:template match="marc:datafield[@tag=610 and not(@ind2=0) and not(@ind2=1)]">
+ <subject>
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <topic>
+ <xsl:value-of select="."/>
+ </topic>
+ </xsl:for-each>
+ </subject>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=656]">
+ <subject>
+ <xsl:if test="marc:subfield[@code=2]">
+ <xsl:attribute name="authority">
+ <xsl:value-of select="marc:subfield[@code=2]"/>
+ </xsl:attribute>
+ </xsl:if>
+ <occupation>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </occupation>
+ </subject>
+ </xsl:template>
+
+ <xsl:template name="termsOfAddress">
+ <xsl:if test="marc:subfield[@code='c']">
+ <namePart type="termsOfAddress">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">c</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </namePart>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="displayLabel">
+ <xsl:if test="marc:subfield[@code='i']">
+ <xsl:attribute name="displayLabel">
+ <xsl:value-of select="marc:subfield[@code='i']"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:if test="marc:subfield[@code='3']">
+ <xsl:attribute name="displayLabel">
+ <xsl:value-of select="marc:subfield[@code='3']"/>
+ </xsl:attribute>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="isInvalid">
+ <xsl:if test="marc:subfield[@code='z']">
+ <xsl:attribute name="invalid">yes</xsl:attribute>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="subtitle">
+ <xsl:if test="marc:subfield[@code='b']">
+ <subTitle>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="marc:subfield[@code='b']"/>
+
+ <!--<xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">b</xsl:with-param>
+ </xsl:call-template>-->
+ </xsl:with-param>
+ </xsl:call-template>
+ </subTitle>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="script">
+ <xsl:param name="scriptCode"/>
+ <xsl:attribute name="script">
+ <xsl:choose>
+ <xsl:when test="$scriptCode='(3'">Arabic</xsl:when>
+ <xsl:when test="$scriptCode='(B'">Latin</xsl:when>
+ <xsl:when test="$scriptCode='$1'">Chinese, Japanese, Korean</xsl:when>
+ <xsl:when test="$scriptCode='(N'">Cyrillic</xsl:when>
+ <xsl:when test="$scriptCode='(2'">Hebrew</xsl:when>
+ <xsl:when test="$scriptCode='(S'">Greek</xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+ </xsl:template>
+
+ <xsl:template name="parsePart">
+ <!-- assumes 773$q= 1:2:3<4
+ with up to 3 levels and one optional start page
+ -->
+ <xsl:variable name="level1">
+ <xsl:choose>
+ <xsl:when test="contains(text(),':')">
+ <!-- 1:2 -->
+ <xsl:value-of select="substring-before(text(),':')"/>
+ </xsl:when>
+ <xsl:when test="not(contains(text(),':'))">
+ <!-- 1 or 1<3 -->
+ <xsl:if test="contains(text(),'&lt;')">
+ <!-- 1<3 -->
+ <xsl:value-of select="substring-before(text(),'&lt;')"/>
+ </xsl:if>
+ <xsl:if test="not(contains(text(),'&lt;'))">
+ <!-- 1 -->
+ <xsl:value-of select="text()"/>
+ </xsl:if>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="sici2">
+ <xsl:choose>
+ <xsl:when test="starts-with(substring-after(text(),$level1),':')">
+ <xsl:value-of select="substring(substring-after(text(),$level1),2)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="substring-after(text(),$level1)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="level2">
+ <xsl:choose>
+ <xsl:when test="contains($sici2,':')">
+ <!-- 2:3<4 -->
+ <xsl:value-of select="substring-before($sici2,':')"/>
+ </xsl:when>
+ <xsl:when test="contains($sici2,'&lt;')">
+ <!-- 1: 2<4 -->
+ <xsl:value-of select="substring-before($sici2,'&lt;')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$sici2"/>
+ <!-- 1:2 -->
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="sici3">
+ <xsl:choose>
+ <xsl:when test="starts-with(substring-after($sici2,$level2),':')">
+ <xsl:value-of select="substring(substring-after($sici2,$level2),2)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="substring-after($sici2,$level2)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="level3">
+ <xsl:choose>
+ <xsl:when test="contains($sici3,'&lt;')">
+ <!-- 2<4 -->
+ <xsl:value-of select="substring-before($sici3,'&lt;')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$sici3"/>
+ <!-- 3 -->
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="page">
+ <xsl:if test="contains(text(),'&lt;')">
+ <xsl:value-of select="substring-after(text(),'&lt;')"/>
+ </xsl:if>
+ </xsl:variable>
+ <xsl:if test="$level1">
+ <detail level="1">
+ <number>
+ <xsl:value-of select="$level1"/>
+ </number>
+ </detail>
+ </xsl:if>
+ <xsl:if test="$level2">
+ <detail level="2">
+ <number>
+ <xsl:value-of select="$level2"/>
+ </number>
+ </detail>
+ </xsl:if>
+ <xsl:if test="$level3">
+ <detail level="3">
+ <number>
+ <xsl:value-of select="$level3"/>
+ </number>
+ </detail>
+ </xsl:if>
+ <xsl:if test="$page">
+ <extent unit="page">
+ <start>
+ <xsl:value-of select="$page"/>
+ </start>
+ </extent>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="getLanguage">
+ <xsl:param name="langString"/>
+ <xsl:param name="controlField008-35-37"/>
+ <xsl:variable name="length" select="string-length($langString)"/>
+ <xsl:choose>
+ <xsl:when test="$length=0"/>
+ <xsl:when test="$controlField008-35-37=substring($langString,1,3)">
+ <xsl:call-template name="getLanguage">
+ <xsl:with-param name="langString" select="substring($langString,4,$length)"/>
+ <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <language>
+ <languageTerm authority="iso639-2b" type="code">
+ <xsl:value-of select="substring($langString,1,3)"/>
+ </languageTerm>
+ </language>
+ <xsl:call-template name="getLanguage">
+ <xsl:with-param name="langString" select="substring($langString,4,$length)"/>
+ <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="isoLanguage">
+ <xsl:param name="currentLanguage"/>
+ <xsl:param name="usedLanguages"/>
+ <xsl:param name="remainingLanguages"/>
+ <xsl:choose>
+ <xsl:when test="string-length($currentLanguage)=0"/>
+ <xsl:when test="not(contains($usedLanguages, $currentLanguage))">
+ <language>
+ <languageTerm authority="iso639-2b" type="code">
+ <xsl:value-of select="$currentLanguage"/>
+ </languageTerm>
+ </language>
+ <xsl:call-template name="isoLanguage">
+ <xsl:with-param name="currentLanguage">
+ <xsl:value-of select="substring($remainingLanguages,1,3)"/>
+ </xsl:with-param>
+ <xsl:with-param name="usedLanguages">
+ <xsl:value-of select="concat($usedLanguages,$currentLanguage)"/>
+ </xsl:with-param>
+ <xsl:with-param name="remainingLanguages">
+ <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="isoLanguage">
+ <xsl:with-param name="currentLanguage">
+ <xsl:value-of select="substring($remainingLanguages,1,3)"/>
+ </xsl:with-param>
+ <xsl:with-param name="usedLanguages">
+ <xsl:value-of select="concat($usedLanguages,$currentLanguage)"/>
+ </xsl:with-param>
+ <xsl:with-param name="remainingLanguages">
+ <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="chopBrackets">
+ <xsl:param name="chopString"/>
+ <xsl:variable name="string">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="$chopString"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:if test="substring($string, 1,1)='['">
+ <xsl:value-of select="substring($string,2, string-length($string)-2)"/>
+ </xsl:if>
+ <xsl:if test="substring($string, 1,1)!='['">
+ <xsl:value-of select="$string"/>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="rfcLanguages">
+ <xsl:param name="nodeNum"/>
+ <xsl:param name="usedLanguages"/>
+ <xsl:param name="controlField008-35-37"/>
+ <!-- ??? xalan -->
+
+ <xsl:variable name="currentLanguage" select="marc:subfield[position()=$nodeNum]/text()"/>
+ <xsl:choose>
+ <xsl:when test="not($currentLanguage)"/>
+ <xsl:when test="$currentLanguage!=$controlField008-35-37 and $currentLanguage!='rfc3066'">
+ <xsl:if test="not(contains($usedLanguages,$currentLanguage))">
+ <language>
+ <languageTerm authority="rfc3066" type="code">
+ <xsl:value-of select="$currentLanguage"/>
+ </languageTerm>
+ </language>
+ </xsl:if>
+ <xsl:call-template name="rfcLanguages">
+ <!-- ??? xalan -->
+ <xsl:with-param name="nodeNum">
+ <xsl:value-of select="$nodeNum+1"/>
+ </xsl:with-param>
+ <xsl:with-param name="usedLanguages">
+ <xsl:value-of select="concat($usedLanguages,'|',$currentLanguage)"/>
+ </xsl:with-param>
+ <xsl:with-param name="controlField008-35-37">
+ <xsl:value-of select="$controlField008-35-37"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="rfcLanguages">
+ <xsl:with-param name="nodeNum">
+ <xsl:value-of select="$nodeNum+1"/>
+ </xsl:with-param>
+ <xsl:with-param name="usedLanguages">
+ <xsl:value-of select="concat($usedLanguages,$currentLanguage)"/>
+ </xsl:with-param>
+ <xsl:with-param name="controlField008-35-37">
+ <xsl:value-of select="$controlField008-35-37"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- added for Tellico, don't print unrecognized datafields -->
+ <xsl:template match="marc:datafield">
+ </xsl:template>
+
+</xsl:stylesheet><!-- Stylus Studio meta-information - (c)1998-2003 Copyright Sonic Software Corporation. All rights reserved.
+<metaInformation>
+<scenarios ><scenario default="no" name="Apr 02 Test" userelativepaths="yes" externalpreview="no" url="file://n:\jackie\test_files\v3.xml" htmlbaseurl="" outputurl="file://n:\temp\x.xml" processortype="xalan" commandline="" additionalpath="" additionalclasspath="" postprocessortype="none" postprocesscommandline="" postprocessadditionalpath="" postprocessgeneratedext=""/><scenario default="no" name="v3Test1" userelativepaths="yes" externalpreview="no" url="file://n:\jackie\test_files\v3.xml" htmlbaseurl="" outputurl="file://n:\jackie\test_files\modsv3Converted.xml" processortype="internal" commandline="" additionalpath="" additionalclasspath="" postprocessortype="none" postprocesscommandline="" postprocessadditionalpath="" postprocessgeneratedext=""/><scenario default="no" name="Scenario1" userelativepaths="yes" externalpreview="no" url="file://n:\ckeith\DESKTOP\test.xml" htmlbaseurl="" outputurl="" processortype="xalan" commandline="" additionalpath="" additionalclasspath="" postprocessortype="none" postprocesscommandline="" postprocessadditionalpath="" postprocessgeneratedext=""/><scenario default="yes" name="Test" userelativepaths="yes" externalpreview="no" url="file://n:\jackie\MARCXML\marcxmlfile.xml" htmlbaseurl="" outputurl="" processortype="xalan" commandline="" additionalpath="" additionalclasspath="" postprocessortype="none" postprocesscommandline="" postprocessadditionalpath="" postprocessgeneratedext=""/></scenarios><MapperInfo srcSchemaPath="" srcSchemaRoot="" srcSchemaPathIsRelative="yes" srcSchemaInterpretAsXML="no" destSchemaPath="" destSchemaRoot="" destSchemaPathIsRelative="yes" destSchemaInterpretAsXML="no"/>
+</metaInformation>
+-->
diff --git a/xslt/amazon2tellico.xsl b/xslt/amazon2tellico.xsl
new file mode 100644
index 0000000..065886a
--- /dev/null
+++ b/xslt/amazon2tellico.xsl
@@ -0,0 +1,590 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://periapsis.org/tellico/"
+ xmlns:aws="http://webservices.amazon.com/AWSECommerceService/2007-10-29"
+ xmlns:exsl="http://exslt.org/common"
+ extension-element-prefixes="exsl"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for importing Amazon Web Services data.
+
+ Copyright (C) 2004-2007 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ doctype-public="-//Robby Stephenson/DTD Tellico V10.0//EN"
+ doctype-system="http://periapsis.org/tellico/dtd/v10/tellico.dtd"/>
+
+
+<!-- need to figure out what type of collection -->
+<xsl:variable name="args" select="//aws:OperationRequest/aws:Arguments"/>
+<xsl:variable name="tmp">
+ <xsl:choose>
+ <!-- SearchIndex is mode, unless doing ISBN or UPC search -->
+ <xsl:when test="$args/aws:Argument[@Name='SearchIndex']">
+ <xsl:value-of select="$args/aws:Argument[@Name='SearchIndex']/@Value"/>
+ </xsl:when>
+ <!-- only happens for books -->
+ <xsl:when test="$args/aws:Argument[@Name='Operation']/@Value='ItemLookup'">
+ <xsl:text>Books</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+</xsl:variable>
+<!-- France might have DVD instead of Video -->
+<xsl:variable name="mode">
+ <xsl:choose>
+ <xsl:when test="$tmp='DVD'">
+ <xsl:text>Video</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$tmp"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:variable>
+
+<!-- for lower-casing -->
+<xsl:variable name="lcletters">abcdefghijklmnopqrstuvwxyz</xsl:variable>
+<xsl:variable name="ucletters">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
+
+<xsl:template match="/">
+ <tellico syntaxVersion="10">
+ <collection title="Amazon Import">
+ <xsl:attribute name="type">
+ <xsl:choose>
+ <xsl:when test="$mode='Books'">
+ <xsl:text>2</xsl:text>
+ </xsl:when>
+ <xsl:when test="$mode='Video'">
+ <xsl:text>3</xsl:text>
+ </xsl:when>
+ <!-- also can be pop-music-de -->
+ <xsl:when test="$mode='Music'">
+ <xsl:text>4</xsl:text>
+ </xsl:when>
+ <xsl:when test="$mode='VideoGames'">
+ <xsl:text>11</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+ <fields>
+ <field name="_default"/>
+ <field flags="0" title="Amazon Link" category="General" format="4" type="7" name="amazon" i18n="true"/>
+ <!-- the amazon importer will actually download the images and ignore these fields -->
+ <field flags="0" title="Small Image" category="Images" format="4" type="7" name="small-image"/>
+ <field flags="0" title="Medium Image" category="Images" format="4" type="7" name="medium-image"/>
+ <field flags="0" title="Large Image" category="Images" format="4" type="7" name="large-image"/>
+ </fields>
+ <xsl:for-each select="//aws:Items/aws:Item">
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+ </collection>
+ </tellico>
+</xsl:template>
+
+<xsl:template match="aws:Item">
+ <entry>
+ <amazon>
+ <xsl:value-of select="aws:DetailPageURL"/>
+ </amazon>
+
+ <small-image>
+ <xsl:value-of select="aws:SmallImage/aws:URL"/>
+ </small-image>
+
+ <medium-image>
+ <xsl:value-of select="aws:MediumImage/aws:URL"/>
+ </medium-image>
+
+ <large-image>
+ <xsl:value-of select="aws:LargeImage/aws:URL"/>
+ </large-image>
+
+ <xsl:choose>
+ <xsl:when test="$mode='Books'">
+ <comments>
+ <xsl:value-of select="aws:EditorialReviews/aws:EditorialReview/aws:Content"/>
+ </comments>
+
+ <keywords i18n="true">
+ <xsl:for-each select="aws:BrowseNodes/aws:BrowseNode">
+ <keyword>
+ <xsl:call-template name="nodes">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </keyword>
+ </xsl:for-each>
+ </keywords>
+ </xsl:when>
+
+ <xsl:when test="$mode='Music'">
+ <comments>
+ <xsl:value-of select="aws:EditorialReviews/aws:EditorialReview[1]/aws:Content"/>
+ </comments>
+
+ <tracks>
+ <!-- too hard to know which artist goes with which track, just grab first -->
+ <xsl:variable name="artist" select="aws:ItemAttributes/aws:Artist[1]"/>
+ <xsl:for-each select="aws:Tracks//aws:Track">
+ <track>
+ <xsl:value-of select="."/>
+ <xsl:text>::</xsl:text>
+ <!-- too hard to know which artist goes with which track, just grab first -->
+ <xsl:value-of select="$artist"/>
+ </track>
+ </xsl:for-each>
+ </tracks>
+
+ <!-- these get cleaned up within Tellico itself -->
+ <genres i18n="true">
+ <xsl:for-each select="aws:BrowseNodes/aws:BrowseNode">
+ <genre>
+ <xsl:call-template name="nodes">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </genre>
+ </xsl:for-each>
+ </genres>
+ </xsl:when>
+
+ <xsl:when test="$mode='Video'">
+ <plot>
+ <xsl:value-of select="aws:EditorialReviews/aws:EditorialReview[1]/aws:Content"/>
+ </plot>
+
+ <!-- these get cleaned up within Tellico itself -->
+ <genres i18n="true">
+ <xsl:for-each select="aws:BrowseNodes/aws:BrowseNode">
+ <genre>
+ <xsl:call-template name="nodes">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ </genre>
+ </xsl:for-each>
+ </genres>
+ </xsl:when>
+
+ <xsl:when test="$mode='VideoGames'">
+ <description>
+ <xsl:value-of select="aws:EditorialReviews/aws:EditorialReview[1]/aws:Content"/>
+ </description>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:apply-templates select="aws:ItemAttributes"/>
+ </entry>
+</xsl:template>
+
+<xsl:template match="aws:ItemAttributes">
+ <title>
+ <xsl:value-of select="aws:Title"/>
+ </title>
+
+ <languages>
+ <xsl:for-each select="aws:Languages/aws:Language[not(aws:Name=preceding-sibling::aws:Language/aws:Name)]">
+ <language>
+ <xsl:value-of select="aws:Name"/>
+ </language>
+ </xsl:for-each>
+ </languages>
+
+ <xsl:choose>
+ <!-- book collection stuff -->
+ <xsl:when test="$mode='Books'">
+ <authors>
+ <xsl:for-each select="aws:Author">
+ <author>
+ <xsl:value-of select="."/>
+ </author>
+ </xsl:for-each>
+ </authors>
+
+ <isbn>
+ <!-- the EAN is the isbn-13 value for books -->
+ <xsl:choose>
+ <xsl:when test="aws:ISBN">
+ <xsl:value-of select="aws:ISBN"/>
+ </xsl:when>
+ <xsl:when test="aws:EAN">
+ <xsl:value-of select="aws:EAN"/>
+ </xsl:when>
+ </xsl:choose>
+ </isbn>
+
+ <publisher>
+ <xsl:value-of select="aws:Publisher"/>
+ </publisher>
+
+ <editors>
+ <xsl:for-each select="aws:Creator[@Role='Editor']">
+ <editor>
+ <xsl:value-of select="."/>
+ </editor>
+ </xsl:for-each>
+ </editors>
+
+ <binding i18n="true">
+ <xsl:choose>
+ <xsl:when test="aws:Binding='Hardcover'">
+ <xsl:text>Hardback</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains(aws:Binding, 'Paperback')">
+ <xsl:text>Paperback</xsl:text>
+ </xsl:when>
+ <!-- specifically for France -->
+ <xsl:when test="aws:Binding='Broché' or aws:Binding='Poche'">
+ <xsl:text>Souple</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="aws:Binding"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </binding>
+
+ <pub_year>
+ <xsl:call-template name="year">
+ <xsl:with-param name="value" select="aws:PublicationDate"/>
+ </xsl:call-template>
+ </pub_year>
+
+ <edition>
+ <xsl:value-of select="aws:Edition"/>
+ </edition>
+
+ <pages>
+ <xsl:value-of select="aws:NumberOfPages"/>
+ </pages>
+ </xsl:when>
+
+ <!-- music collection stuff -->
+ <xsl:when test="$mode='Music'">
+ <artists>
+ <xsl:for-each select="aws:Artist">
+ <artist>
+ <xsl:value-of select="."/>
+ </artist>
+ </xsl:for-each>
+ <!-- only add composers if no artist -->
+ <xsl:if test="not(aws:Artist)">
+ <xsl:for-each select="aws:Creator[@Role='Composer']">
+ <artist>
+ <xsl:value-of select="."/>
+ </artist>
+ </xsl:for-each>
+ </xsl:if>
+ </artists>
+
+ <year>
+ <xsl:call-template name="year">
+ <xsl:with-param name="value" select="aws:ReleaseDate"/>
+ </xsl:call-template>
+ </year>
+
+ <labels>
+ <label>
+ <xsl:value-of select="aws:Label"/>
+ </label>
+ </labels>
+
+ <medium i18n="true">
+ <xsl:variable name="medium" select="aws:Binding"/>
+ <xsl:choose>
+ <xsl:when test="$medium='Audio CD'">
+ <xsl:text>Compact Disc</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:comment>
+ <xsl:value-of select="$medium"/>
+ </xsl:comment>
+ </xsl:otherwise>
+ </xsl:choose>
+ </medium>
+ </xsl:when>
+
+ <!-- video collection stuff -->
+ <xsl:when test="$mode='Video'">
+ <directors>
+ <xsl:for-each select="aws:Director">
+ <director>
+ <xsl:value-of select="."/>
+ </director>
+ </xsl:for-each>
+ </directors>
+
+ <casts>
+ <!-- special case for french, there might be more actors than aws:Actor elements -->
+ <xsl:for-each select="aws:Creator[@Role='Acteur']">
+ <!-- cast is a 2-column table -->
+ <cast>
+ <column>
+ <xsl:value-of select="."/>
+ </column>
+ </cast>
+ </xsl:for-each>
+ <!-- assume only add actor if no creators -->
+ <xsl:if test="not(aws:Creator[@Role='Acteur'])">
+ <xsl:for-each select="aws:Actor">
+ <!-- cast is a 2-column table -->
+ <cast>
+ <column>
+ <xsl:value-of select="."/>
+ </column>
+ </cast>
+ </xsl:for-each>
+ </xsl:if>
+ </casts>
+
+ <year>
+ <xsl:call-template name="year">
+ <xsl:with-param name="value" select="aws:TheatricalReleaseDate"/>
+ </xsl:call-template>
+ </year>
+
+ <medium i18n="true">
+ <xsl:variable name="medium" select="aws:ProductGroup"/>
+ <xsl:choose>
+ <xsl:when test="$medium='Video'">
+ <xsl:text>VHS</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains(translate($medium,$lcletters,$ucletters),'blu-ray')">
+ <xsl:text>Blu-ray</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$medium"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </medium>
+
+ <color i18n="true">
+ <xsl:choose>
+ <xsl:when test="aws:Format[.='Black &amp; White']">
+ <xsl:text>Black &amp; White</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>Color</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </color>
+
+ <aspect-ratios>
+ <xsl:for-each select="aws:AspectRatio">
+ <aspect-ratio>
+ <xsl:value-of select="."/>
+ </aspect-ratio>
+ </xsl:for-each>
+ </aspect-ratios>
+
+ <xsl:if test="aws:Format[.='Widescreen']">
+ <widescreen>
+ <xsl:text>true</xsl:text>
+ </widescreen>
+ </xsl:if>
+
+ <languages>
+ <xsl:for-each select="aws:Languages/aws:Language[not(aws:Name=preceding-sibling::aws:Language/aws:Name)]">
+ <language>
+ <xsl:value-of select="aws:Name"/>
+ </language>
+ </xsl:for-each>
+ </languages>
+
+ <audio-tracks>
+ <xsl:choose>
+ <xsl:when test="aws:Languages/aws:Language/aws:AudioFormat[starts-with(.,'Dolby')]">
+ <audio-track>
+ <xsl:value-of select="aws:Languages/aws:Language/aws:AudioFormat[starts-with(.,'Dolby')][1]"/>
+ </audio-track>
+ </xsl:when>
+ <xsl:when test="aws:Format[starts-with(.,'Dolby')]">
+ <audio-track>
+ <xsl:value-of select="aws:Format[starts-with(.,'Dolby')][1]"/>
+ </audio-track>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:if test="aws:Languages/aws:Language/aws:AudioFormat[starts-with(.,'DTS')]">
+ <audio-track>
+ <xsl:value-of select="aws:Languages/aws:Language/aws:AudioFormat[starts-with(.,'DTS')][1]"/>
+ </audio-track>
+ </xsl:if>
+ </audio-tracks>
+
+ <certification i18n="true">
+ <xsl:variable name="mpaa" select="aws:AudienceRating"/>
+ <xsl:choose>
+ <xsl:when test="starts-with($mpaa, 'PG-13')">
+ <xsl:text>PG-13 (USA)</xsl:text>
+ </xsl:when>
+ <xsl:when test="starts-with($mpaa, 'PG')">
+ <xsl:text>PG (USA)</xsl:text>
+ </xsl:when>
+ <xsl:when test="starts-with($mpaa, 'R')">
+ <xsl:text>R (USA)</xsl:text>
+ </xsl:when>
+ <xsl:when test="starts-with($mpaa, 'G')">
+ <xsl:text>G (USA)</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:comment>
+ <xsl:value-of select="$mpaa"/>
+ </xsl:comment>
+ </xsl:otherwise>
+ </xsl:choose>
+ </certification>
+
+ <studios>
+ <studio>
+ <xsl:value-of select="aws:Studio"/>
+ </studio>
+ </studios>
+
+ <xsl:if test="aws:RegionCode">
+ <region i18n="true">
+ <xsl:value-of select="concat('Region ', aws:RegionCode)"/>
+ </region>
+ </xsl:if>
+
+ <xsl:if test="aws:RunningTime[@Units='minutes']">
+ <running-time>
+ <xsl:value-of select="aws:RunningTime[@Units='minutes']"/>
+ </running-time>
+ </xsl:if>
+
+ </xsl:when>
+
+ <!-- video game collection stuff -->
+ <xsl:when test="$mode='VideoGames'">
+ <publisher>
+ <xsl:value-of select="aws:Publisher"/>
+ </publisher>
+
+ <!-- assume year is last four characters of ReleaseDate -->
+ <year>
+ <xsl:call-template name="year">
+ <xsl:with-param name="value" select="aws:ReleaseDate"/>
+ </xsl:call-template>
+ </year>
+
+ <!-- assume that the only time there are multiple platforms is when it's for multiple versions of windows -->
+ <platform i18n="true">
+ <xsl:call-template name="platform">
+ <xsl:with-param name="value" select="aws:Platform"/>
+ </xsl:call-template>
+ </platform>
+
+ <genres i18n="true">
+ <xsl:for-each select="aws:Feature[starts-with(., 'Genre:')]">
+ <genre>
+ <xsl:value-of select="substring(., 7)"/> <!-- ends with a space -->
+ </genre>
+ </xsl:for-each>
+ </genres>
+
+ <certification i18n="true">
+ <xsl:choose>
+ <xsl:when test="aws:ESRBAgeRating = 'Rating Pending'">
+ <xsl:text>Pending</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="aws:ESRBAgeRating"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </certification>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="nodes">
+ <xsl:param name="node"/>
+
+ <xsl:variable name="firstNode" select="$node/aws:Name"/>
+
+ <xsl:variable name="tailNodes">
+ <xsl:choose>
+ <xsl:when test="$node/aws:Ancestors/aws:BrowseNode[1]/aws:Name">
+ <xsl:call-template name="nodes">
+ <xsl:with-param name="node" select="$node/aws:Ancestors/aws:BrowseNode[1]"/>
+ </xsl:call-template>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="string-length($firstNode)">
+ <xsl:choose>
+ <xsl:when test="string-length($tailNodes)">
+ <xsl:value-of select="concat($tailNodes, '/', $firstNode)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$firstNode"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="string-length($tailNodes)">
+ <xsl:value-of select="$tailNodes"/>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="year">
+ <xsl:param name="value"/>
+ <xsl:variable name="numbers">
+ <xsl:value-of select="translate($value, translate($value, '0123456789', ''), '')"/>
+ </xsl:variable>
+ <!-- assume that Amazon always encodes the date with the 4-digit year first -->
+ <xsl:value-of select="substring($numbers, 0, 5)"/>
+</xsl:template>
+
+<xsl:template name="platform">
+ <xsl:param name="value"/>
+ <xsl:variable name="lcvalue">
+ <xsl:value-of select="translate($value, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ 'abcdefghijklmnopqrstuvwxyz')"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="contains($lcvalue, '360')">
+ <xsl:text>Xbox 360</xsl:text>
+ </xsl:when>
+ <xsl:when test="starts-with($lcvalue, 'x')">
+ <xsl:text>Xbox</xsl:text> <!-- as defined in the default field -->
+ </xsl:when>
+ <xsl:when test="contains($lcvalue, 'wii')">
+ <xsl:text>Nintendo Wii</xsl:text> <!-- as defined in the default field -->
+ </xsl:when>
+ <xsl:when test="$lcvalue = 'sony psp'">
+ <xsl:text>PSP</xsl:text> <!-- as defined in the default field -->
+ </xsl:when>
+ <xsl:when test="starts-with($lcvalue, 'windows')">
+ <xsl:text>Windows</xsl:text> <!-- as defined in the default field -->
+ </xsl:when>
+ <xsl:when test="starts-with($lcvalue, 'mac')">
+ <xsl:text>Mac OS</xsl:text> <!-- as defined in the default field -->
+ </xsl:when>
+ <xsl:when test="$lcvalue = 'sega dreamcast'">
+ <xsl:text>Dreamcast</xsl:text> <!-- as defined in the default field -->
+ </xsl:when>
+ <xsl:when test="starts-with($lcvalue, 'playstation')">
+ <xsl:choose>
+ <xsl:when test="contains($lcvalue, '3')">
+ <xsl:text>PlayStation3</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains($lcvalue, '2')">
+ <xsl:text>PlayStation2</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$value"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$value"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/arxiv2tellico.xsl b/xslt/arxiv2tellico.xsl
new file mode 100644
index 0000000..8028e6c
--- /dev/null
+++ b/xslt/arxiv2tellico.xsl
@@ -0,0 +1,277 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://periapsis.org/tellico/"
+ xmlns:atom="http://www.w3.org/2005/Atom"
+ xmlns:arxiv="http://arxiv.org/schemas/atom"
+ xmlns:str="http://exslt.org/strings"
+ xmlns:exsl="http://exslt.org/common"
+ xmlns:c="uri:category"
+ exclude-result-prefixes="atom arxiv"
+ extension-element-prefixes="str exsl"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for importing data from crossref.org
+
+ See http://www.crossref.org/schema/queryResultSchema/crossref_query_output2.0.7.xsd
+
+ Copyright (C) 2007 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<!-- lookup table for categories -->
+<c:categories>
+ <c:category id="astro-ph">Astrophysics</c:category>
+ <c:category id="cond-mat">Condensed Matter</c:category>
+ <c:category id="cond-mat.dis-nn">Disordered Systems and Neural Networks</c:category>
+ <c:category id="cond-mat.mtrl-sci">Materials Science</c:category>
+ <c:category id="cond-mat.mes-hall">Mesoscopic Systems and Quantum Hall Effect</c:category>
+ <c:category id="cond-mat.other">Other</c:category>
+ <c:category id="cond-mat.soft">Soft Condensed Matter</c:category>
+ <c:category id="cond-mat.stat-mech">Statistical Mechanics</c:category>
+ <c:category id="cond-mat.str-el">Strongly Correlated Electrons</c:category>
+ <c:category id="cond-mat.supr-con">Superconductivity</c:category>
+ <c:category id="gr-qc">General Relativity and Quantum Cosmology</c:category>
+ <c:category id="hep-ex">High Energy Physics - Experiment</c:category>
+ <c:category id="hep-lat">High Energy Physics - Lattice</c:category>
+ <c:category id="hep-ph">High Energy Physics - Phenomenology</c:category>
+ <c:category id="hep-th">High Energy Physics - Theory</c:category>
+ <c:category id="math-ph">Mathematical Physics</c:category>
+ <c:category id="nucl-ex">Nuclear Experiment</c:category>
+ <c:category id="nucl-th">Nuclear Theory</c:category>
+ <c:category id="physics">Physics</c:category>
+ <c:category id="physics.acc-ph">Accelerator Physics</c:category>
+ <c:category id="physics.ao-ph">Atmospheric and Oceanic Physics</c:category>
+ <c:category id="physics.atom-ph">Atomic Physics</c:category>
+ <c:category id="physics.atm-clus">Atomic and Molecular Clusters</c:category>
+ <c:category id="physics.bio-ph">Biological Physics</c:category>
+ <c:category id="physics.chem-ph">Chemical Physics</c:category>
+ <c:category id="physics.class-ph">Classical Physics</c:category>
+ <c:category id="physics.comp-ph">Computational Physics</c:category>
+ <c:category id="physics.data-an">Data Analysis, Statistics and Probability</c:category>
+ <c:category id="physics.flu-dyn">Fluid Dynamics</c:category>
+ <c:category id="physics.gen-ph">General Physics</c:category>
+ <c:category id="physics.geo-ph">Geophysics</c:category>
+ <c:category id="physics.hist-ph">History of Physics</c:category>
+ <c:category id="physics.ins-det">Instrumentation and Detectors</c:category>
+ <c:category id="physics.med-ph">Medical Physics</c:category>
+ <c:category id="physics.optics">Optics</c:category>
+ <c:category id="physics.ed-ph">Physics Education</c:category>
+ <c:category id="physics.soc-ph">Physics and Society</c:category>
+ <c:category id="physics.plasm-ph">Plasma Physics</c:category>
+ <c:category id="physics.pop-ph">Popular Physics</c:category>
+ <c:category id="physics.space-ph">Space Physics</c:category>
+ <c:category id="quant-ph">Quantum Physics</c:category>
+ <c:category id="math">Mathematics</c:category>
+ <c:category id="math.AG">Algebraic Geometry</c:category>
+ <c:category id="math.AT">Algebraic Topology</c:category>
+ <c:category id="math.AP">Analysis of PDEs</c:category>
+ <c:category id="math.CT">Category Theory</c:category>
+ <c:category id="math.CA">Classical Analysis and ODEs</c:category>
+ <c:category id="math.CO">Combinatorics</c:category>
+ <c:category id="math.AC">Commutative Algebra</c:category>
+ <c:category id="math.CV">Complex Variables</c:category>
+ <c:category id="math.DG">Differential Geometry</c:category>
+ <c:category id="math.DS">Dynamical Systems</c:category>
+ <c:category id="math.FA">Functional Analysis</c:category>
+ <c:category id="math.GM">General Mathematics</c:category>
+ <c:category id="math.GN">General Topology</c:category>
+ <c:category id="math.GT">Geometric Topology</c:category>
+ <c:category id="math.GR">Group Theory</c:category>
+ <c:category id="math.HO">History and Overview</c:category>
+ <c:category id="math.IT">Information Theory</c:category>
+ <c:category id="math.KT">K-Theory and Homology</c:category>
+ <c:category id="math.LO">Logic</c:category>
+ <c:category id="math.MP">Mathematical Physics</c:category>
+ <c:category id="math.MG">Metric Geometry</c:category>
+ <c:category id="math.NT">Number Theory</c:category>
+ <c:category id="math.NA">Numerical Analysis</c:category>
+ <c:category id="math.OA">Operator Algebras</c:category>
+ <c:category id="math.OC">Optimization and Control</c:category>
+ <c:category id="math.PR">Probability</c:category>
+ <c:category id="math.QA">Quantum Algebra</c:category>
+ <c:category id="math.RT">Representation Theory</c:category>
+ <c:category id="math.RA">Rings and Algebras</c:category>
+ <c:category id="math.SP">Spectral Theory</c:category>
+ <c:category id="math.ST">Statistics</c:category>
+ <c:category id="math.SG">Symplectic Geometry</c:category>
+ <c:category id="nlin">Nonlinear Sciences</c:category>
+ <c:category id="nlin.AO">Adaptation and Self-Organizing Systems</c:category>
+ <c:category id="nlin.CG">Cellular Automata and Lattice Gases</c:category>
+ <c:category id="nlin.CD">Chaotic Dynamics</c:category>
+ <c:category id="nlin.SI">Exactly Solvable and Integrable Systems</c:category>
+ <c:category id="nlin.PS">Pattern Formation and Solitons</c:category>
+ <c:category id="cs.AR">Architecture</c:category>
+ <c:category id="cs.AI">Artificial Intelligence</c:category>
+ <c:category id="cs.CL">Computation and Language</c:category>
+ <c:category id="cs.CC">Computational Complexity</c:category>
+ <c:category id="cs.CE">Computational Engineering, Finance, and Science</c:category>
+ <c:category id="cs.CG">Computational Geometry</c:category>
+ <c:category id="cs.GT">Computer Science and Game Theory</c:category>
+ <c:category id="cs.CV">Computer Vision and Pattern Recognition</c:category>
+ <c:category id="cs.CY">Computers and Society</c:category>
+ <c:category id="cs.CR">Cryptography and Security</c:category>
+ <c:category id="cs.DS">Data Structures and Algorithms</c:category>
+ <c:category id="cs.DB">Databases</c:category>
+ <c:category id="cs.DL">Digital Libraries</c:category>
+ <c:category id="cs.DM">Discrete Mathematics</c:category>
+ <c:category id="cs.DC">Distributed, Parallel, and Cluster Computing</c:category>
+ <c:category id="cs.GL">General Literature</c:category>
+ <c:category id="cs.GR">Graphics</c:category>
+ <c:category id="cs.HC">Human-Computer Interaction</c:category>
+ <c:category id="cs.IR">Information Retrieval</c:category>
+ <c:category id="cs.IT">Information Theory</c:category>
+ <c:category id="cs.LG">Learning</c:category>
+ <c:category id="cs.LO">Logic in Computer Science</c:category>
+ <c:category id="cs.MS">Mathematical Software</c:category>
+ <c:category id="cs.MA">Multiagent Systems</c:category>
+ <c:category id="cs.MM">Multimedia</c:category>
+ <c:category id="cs.NI">Networking and Internet Architecture</c:category>
+ <c:category id="cs.NE">Neural and Evolutionary Computing</c:category>
+ <c:category id="cs.NA">Numerical Analysis</c:category>
+ <c:category id="cs.OS">Operating Systems</c:category>
+ <c:category id="cs.OH">Other</c:category>
+ <c:category id="cs.PF">Performance</c:category>
+ <c:category id="cs.PL">Programming Languages</c:category>
+ <c:category id="cs.RO">Robotics</c:category>
+ <c:category id="cs.SE">Software Engineering</c:category>
+ <c:category id="cs.SD">Sound</c:category>
+ <c:category id="cs.SC">Symbolic Computation</c:category>
+ <c:category id="q-bio">Quantitative Biology</c:category>
+ <c:category id="q-bio.BM">Biomolecules</c:category>
+ <c:category id="q-bio.CB">Cell Behavior</c:category>
+ <c:category id="q-bio.GN">Genomics</c:category>
+ <c:category id="q-bio.MN">Molecular Networks</c:category>
+ <c:category id="q-bio.NC">Neurons and Cognition</c:category>
+ <c:category id="q-bio.OT">Other</c:category>
+ <c:category id="q-bio.PE">Populations and Evolution</c:category>
+ <c:category id="q-bio.QM">Quantitative Methods</c:category>
+ <c:category id="q-bio.SC">Subcellular Processes</c:category>
+ <c:category id="q-bio.TO">Tissues and Organs</c:category>
+ <c:category id="stat">Statistics</c:category>
+ <c:category id="stat.AP">Applications</c:category>
+ <c:category id="stat.CO">Computation</c:category>
+ <c:category id="stat.ML">Machine Learning</c:category>
+ <c:category id="stat.ME">Methodology</c:category>
+ <c:category id="stat.TH">Theory</c:category>
+</c:categories>
+<xsl:key name="categories" match="c:category" use="@id"/>
+<xsl:variable name="categories-top" select="document('')/*/c:categories"/>
+
+<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ doctype-public="-//Robby Stephenson/DTD Tellico V10.0//EN"
+ doctype-system="http://periapsis.org/tellico/dtd/v10/tellico.dtd"/>
+
+<xsl:template match="/">
+ <tellico syntaxVersion="10">
+ <collection title="Arxiv Search" type="5">
+ <fields>
+ <field name="_default"/>
+ <field flags="0" title="arXiv ID" category="Publishing" format="4" type="1" name="arxiv" description="arXiv ID"/>
+ </fields>
+ <xsl:apply-templates select="atom:feed/atom:entry"/>
+ </collection>
+ </tellico>
+</xsl:template>
+
+<xsl:template match="atom:entry">
+ <entry>
+
+ <title>
+ <xsl:value-of select="normalize-space(atom:title)"/>
+ </title>
+
+ <entry-type>
+ <xsl:text>article</xsl:text>
+ </entry-type>
+
+ <authors>
+ <xsl:for-each select="atom:author">
+ <author>
+ <xsl:value-of select="normalize-space(atom:name)"/>
+ </author>
+ </xsl:for-each>
+ </authors>
+
+ <abstract>
+ <xsl:value-of select="normalize-space(atom:summary)"/>
+ </abstract>
+
+ <note>
+ <xsl:value-of select="normalize-space(arxiv:comment)"/>
+ </note>
+
+ <keywords>
+ <xsl:for-each select="atom:category">
+ <keyword>
+ <xsl:apply-templates select="$categories-top">
+ <xsl:with-param name="cat" select="@term"/>
+ </xsl:apply-templates>
+ </keyword>
+ </xsl:for-each>
+ </keywords>
+
+ <url>
+ <xsl:choose>
+ <xsl:when test="atom:link[@title='pdf']">
+ <xsl:value-of select="atom:link[@title='pdf']/@href"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="atom:link[1]/@href"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </url>
+
+ <doi>
+ <xsl:value-of select="arxiv:doi"/>
+ </doi>
+
+ <xsl:call-template name="journal_ref">
+ <xsl:with-param name="value" select="arxiv:journal_ref"/>
+ </xsl:call-template>
+
+ <arxiv>
+ <!-- remove http://arxiv.org/abs/ from beginning -->
+ <xsl:value-of select="substring(atom:id, string-length('http://arxiv.org/abs/')+1)"/>
+ </arxiv>
+
+ </entry>
+
+</xsl:template>
+
+<xsl:template name="journal_ref">
+ <xsl:param name="value"/>
+
+ <journal>
+ <xsl:value-of select="substring-before($value, '(')"/>
+ </journal>
+
+ <xsl:variable name="after1" select="substring-after($value, '(')"/>
+ <xsl:variable name="year" select="substring-before($after1, ')')"/>
+ <year>
+ <xsl:value-of select="normalize-space($year)"/>
+ </year>
+
+ <xsl:variable name="after2" select="substring-after($after1, ')')"/>
+ <pages>
+ <xsl:value-of select="normalize-space($after2)"/>
+ </pages>
+</xsl:template>
+
+<xsl:template match="c:categories">
+ <xsl:param name="cat"/>
+ <xsl:variable name="c" select="key('categories', $cat)"/>
+ <xsl:if test="$c">
+ <xsl:value-of select="$c"/>
+ </xsl:if>
+ <xsl:if test="not($c)">
+ <xsl:value-of select="$cat"/>
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/bluray-logo.png b/xslt/bluray-logo.png
new file mode 100644
index 0000000..62ae5c9
--- /dev/null
+++ b/xslt/bluray-logo.png
Binary files differ
diff --git a/xslt/cassette-logo.png b/xslt/cassette-logo.png
new file mode 100644
index 0000000..ea88f46
--- /dev/null
+++ b/xslt/cassette-logo.png
Binary files differ
diff --git a/xslt/cd-logo.png b/xslt/cd-logo.png
new file mode 100644
index 0000000..c55d2e8
--- /dev/null
+++ b/xslt/cd-logo.png
Binary files differ
diff --git a/xslt/crossref2tellico.xsl b/xslt/crossref2tellico.xsl
new file mode 100644
index 0000000..17cddd3
--- /dev/null
+++ b/xslt/crossref2tellico.xsl
@@ -0,0 +1,121 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://periapsis.org/tellico/"
+ xmlns:cr="http://www.crossref.org/qrschema/2.0"
+ xmlns:str="http://exslt.org/strings"
+ xmlns:exsl="http://exslt.org/common"
+ exclude-result-prefixes="cr"
+ extension-element-prefixes="str exsl"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for importing data from crossref.org
+
+ See http://www.crossref.org/schema/queryResultSchema/crossref_query_output2.0.7.xsd
+
+ Copyright (C) 2007 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ doctype-public="-//Robby Stephenson/DTD Tellico V10.0//EN"
+ doctype-system="http://periapsis.org/tellico/dtd/v10/tellico.dtd"/>
+
+<xsl:template match="/">
+ <tellico syntaxVersion="10">
+ <collection title="CrossRef Import" type="5">
+ <fields>
+ <field name="_default"/>
+
+ <xsl:if test=".//cr:issn">
+ <field flags="0" title="ISSN" category="Publishing" format="4" type="1" name="issn" i18n="true"/>
+ </xsl:if>
+
+ </fields>
+ <xsl:apply-templates select="cr:crossref_result/cr:query_result/cr:body/cr:query"/>
+ </collection>
+ </tellico>
+</xsl:template>
+
+<xsl:template match="cr:query">
+ <entry>
+
+ <title>
+ <xsl:value-of select="cr:article_title"/>
+ </title>
+
+ <booktitle>
+ <xsl:value-of select="cr:volume_title"/>
+ </booktitle>
+
+ <entry-type>
+ <xsl:choose>
+ <xsl:when test="cr:doi/@type = 'conference_paper'">
+ <xsl:text>inproceedings</xsl:text>
+ </xsl:when>
+ <xsl:when test="cr:doi/@type = 'book_title'">
+ <xsl:text>book</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>article</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </entry-type>
+
+ <year>
+ <xsl:value-of select="cr:year"/>
+ </year>
+
+ <doi>
+ <xsl:value-of select="cr:doi"/>
+ </doi>
+
+ <pages>
+ <xsl:value-of select="cr:first_page"/>
+ </pages>
+
+ <journal>
+ <xsl:value-of select="cr:journal_title"/>
+ </journal>
+
+ <volume>
+ <xsl:value-of select="cr:volume"/>
+ </volume>
+
+ <isbn>
+ <xsl:value-of select="cr:isbn"/>
+ </isbn>
+
+ <issn>
+ <xsl:choose>
+ <xsl:when test="cr:issn[@type='print']">
+ <xsl:value-of select="cr:issn[@type='print']"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="cr:issn[1]"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </issn>
+
+ <authors>
+ <xsl:for-each select="cr:author">
+ <author>
+ <xsl:value-of select="."/>
+ </author>
+ </xsl:for-each>
+ </authors>
+
+ <series>
+ <xsl:value-of select="cr:series_title"/>
+ </series>
+
+ </entry>
+
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/delicious2tellico.xsl b/xslt/delicious2tellico.xsl
new file mode 100644
index 0000000..e185d58
--- /dev/null
+++ b/xslt/delicious2tellico.xsl
@@ -0,0 +1,164 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ xmlns:str="http://exslt.org/strings"
+ extension-element-prefixes="str"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for importing Delicious Library data.
+
+ Copyright (C) 2007 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ doctype-public="-//Robby Stephenson/DTD Tellico V10.0//EN"
+ doctype-system="http://periapsis.org/tellico/dtd/v10/tellico.dtd"/>
+
+<xsl:template match="/">
+ <tc:tellico syntaxVersion="10">
+ <tc:collection title="Delicious Library Import" type="2">
+ <tc:fields>
+ <tc:field name="_default"/>
+ <tc:field flags="0" title="Amazon Link" category="General" format="4" type="7" name="amazon" i18n="true"/>
+ <tc:field flags="0" title="UUID" category="General" format="0" type="1" name="uuid"/>
+ </tc:fields>
+ <xsl:for-each select="library/items/book">
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+ </tc:collection>
+ </tc:tellico>
+</xsl:template>
+
+<xsl:template match="book">
+ <tc:entry>
+ <tc:uuid>
+ <xsl:value-of select="@uuid"/>
+ </tc:uuid>
+
+ <tc:amazon>
+ <xsl:if test="@asin">
+ <xsl:value-of select="concat('http://www.amazon.com/dp/',@asin,'/?tag=tellico-20')"/>
+ </xsl:if>
+ </tc:amazon>
+
+ <tc:title>
+ <xsl:choose>
+ <xsl:when test="contains(@title, ':')">
+ <xsl:value-of select="substring-before(@title,':')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@title"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </tc:title>
+
+ <tc:subtitle>
+ <xsl:value-of select="substring-after(@title,':')"/>
+ </tc:subtitle>
+
+ <xsl:call-template name="split">
+ <xsl:with-param name="name" select="'tc:author'"/>
+ <xsl:with-param name="value" select="@author"/>
+ </xsl:call-template>
+
+ <xsl:call-template name="split">
+ <xsl:with-param name="name" select="'tc:genre'"/>
+ <xsl:with-param name="value" select="@genre"/>
+ <xsl:with-param name="i18n" select="true()"/>
+ </xsl:call-template>
+
+ <tc:publisher>
+ <xsl:value-of select="@publisher"/>
+ </tc:publisher>
+
+ <tc:isbn>
+ <xsl:value-of select="@asin"/>
+ </tc:isbn>
+
+ <tc:binding i18n="true">
+ <xsl:choose>
+ <xsl:when test="contains(@aspect, 'Hardcover')">
+ <xsl:text>Hardback</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains(@aspect, 'Paperback')">
+ <xsl:text>Paperback</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@aspect"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </tc:binding>
+
+ <tc:pub_year>
+ <xsl:call-template name="year">
+ <xsl:with-param name="value" select="@published"/>
+ </xsl:call-template>
+ </tc:pub_year>
+
+ <tc:pages>
+ <xsl:value-of select="@pages"/>
+ </tc:pages>
+
+ <tc:pur_price>
+ <xsl:value-of select="@price"/>
+ </tc:pur_price>
+
+ <tc:pur_date>
+ <xsl:value-of select="@purchaseDate"/>
+ </tc:pur_date>
+
+ <tc:rating>
+ <!-- tellico automatically rounds down -->
+ <xsl:value-of select="netrating"/>
+ </tc:rating>
+
+ <xsl:call-template name="split">
+ <xsl:with-param name="name" select="'tc:nationality'"/>
+ <xsl:with-param name="value" select="@country"/>
+ </xsl:call-template>
+
+ <tc:comments>
+ <!-- it gets cleaned up inside of Tellico -->
+ <xsl:value-of select="description"/>
+ </tc:comments>
+
+ </tc:entry>
+</xsl:template>
+
+<xsl:template name="split">
+ <xsl:param name="name"/>
+ <xsl:param name="value"/>
+ <xsl:param name="i18n" value="false()"/>
+
+ <xsl:element name="{concat($name,'s')}">
+ <xsl:for-each select="str:split($value, '&#10;')">
+ <xsl:element name="{$name}">
+
+ <xsl:if test="$i18n">
+ <xsl:attribute name="i18n">true</xsl:attribute>
+ </xsl:if>
+
+ <xsl:value-of select="."/>
+
+ </xsl:element>
+ </xsl:for-each>
+ </xsl:element>
+</xsl:template>
+
+<xsl:template name="year">
+ <xsl:param name="value"/>
+ <xsl:variable name="numbers">
+ <xsl:value-of select="translate($value, translate($value, '0123456789', ''), '')"/>
+ </xsl:variable>
+ <!-- assume that Amazon always encodes the date with the 4-digit year last -->
+ <xsl:value-of select="substring($numbers, string-length($numbers)-3, 4)"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/discogs2tellico.xsl b/xslt/discogs2tellico.xsl
new file mode 100644
index 0000000..3f5539e
--- /dev/null
+++ b/xslt/discogs2tellico.xsl
@@ -0,0 +1,206 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://periapsis.org/tellico/"
+ xmlns:str="http://exslt.org/strings"
+ extension-element-prefixes="str"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for importing Discogs release search data.
+
+ Copyright (C) 2008 Robby Stephenson -robby@periapsis.org
+ Roman L. Senn - roman.l.senn@gmail.com
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ doctype-public="-//Robby Stephenson/DTD Tellico V10.0//EN"
+ doctype-system="http://periapsis.org/tellico/dtd/v10/tellico.dtd"/>
+
+<xsl:template match="/">
+ <tellico syntaxVersion="10">
+ <collection title="Discogs API" type="4"> <!-- 4 is music -->
+ <fields>
+ <field name="_default"/>
+ <!-- the importer will actually download the image and ignore this field -->
+ <field flags="0" title="Discogs ID" category="General" format="4" type="1" name="discogs-id"/>
+ <field flags="0" title="Discogs Link" category="General" format="4" type="7" name="discogs"/>
+ <field flags="7" title="Nationality" category="General" format="0" type="1" name="nationality" i18n="true"/>
+ <xsl:if test="contains(resp/release/extraartists/artist/role, 'Producer')">
+ <field flags="7" title="Producer" category="General" format="2" type="1" name="producer" i18n="true"/>
+ </xsl:if>
+
+ </fields>
+ <xsl:apply-templates select="/resp/searchresults/result[@type='release'] | resp/artist | resp/release"/>
+ </collection>
+ </tellico>
+</xsl:template>
+
+<xsl:template match="resp/searchresults/result">
+ <entry>
+ <title>
+ <xsl:value-of select="substring-after(title,' - ')"/>
+ </title>
+
+ <artists>
+ <artist>
+ <xsl:value-of select="substring-before(title,' - ')"/>
+ </artist>
+ </artists>
+
+ <labels>
+ <label>
+ <xsl:value-of select="substring-before(substring-after(normalize-space(summary),'Label: '),' Catalog#:')"/>
+ </label>
+ </labels>
+
+ <comments>
+ <xsl:value-of select="summary"/>
+ </comments>
+
+ <discogs>
+ <xsl:value-of select="uri"/>
+ </discogs>
+
+ <discogs-id>
+ <xsl:variable name="tokens" select="str:tokenize(uri, '/')"/>
+ <xsl:value-of select="$tokens[count($tokens)]"/>
+ </discogs-id>
+ </entry>
+</xsl:template>
+
+<xsl:template match="resp/artist">
+ <xsl:for-each select="releases/release">
+ <entry>
+ <title>
+ <xsl:value-of select="title"/>
+ </title>
+
+ <artists>
+ <artist>
+ <xsl:value-of select="../../name"/>
+ </artist>
+ </artists>
+
+ <labels>
+ <label>
+ <xsl:value-of select="label"/>
+ </label>
+ </labels>
+
+ <discogs-id>
+ <xsl:value-of select="@id"/>
+ </discogs-id>
+
+ </entry>
+ </xsl:for-each>
+
+</xsl:template>
+
+<xsl:template match="resp/release">
+ <entry>
+ <title>
+ <xsl:value-of select="title"/>
+ </title>
+
+ <artists>
+ <xsl:for-each select="artists/artist">
+ <artist>
+ <xsl:value-of select="."/>
+ </artist>
+ </xsl:for-each>
+ </artists>
+
+ <labels>
+ <xsl:for-each select="labels/label">
+ <label>
+ <xsl:value-of select="@name"/>
+ </label>
+ </xsl:for-each>
+ </labels>
+
+ <genres i18n="true">
+ <xsl:for-each select="genres/genre">
+ <genre>
+ <xsl:value-of select="."/>
+ </genre>
+ </xsl:for-each>
+ </genres>
+
+ <keywords i18n="true">
+ <xsl:for-each select="styles/style">
+ <keyword>
+ <xsl:value-of select="."/>
+ </keyword>
+ </xsl:for-each>
+ </keywords>
+
+ <discogs-id>
+ <xsl:value-of select="@id"/>
+ </discogs-id>
+
+ <comments>
+ <xsl:value-of select="notes"/>
+ </comments>
+
+ <medium i18n="true">
+ <xsl:variable name="medium" select="formats/format[1]/@name"/>
+ <xsl:choose>
+ <xsl:when test="$medium='CD'">
+ <xsl:text>Compact Disc</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$medium"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </medium>
+
+ <year>
+ <xsl:value-of select="substring(released,0,5)"/>
+ </year>
+
+ <tracks>
+ <xsl:for-each select="tracklist/track">
+ <xsl:sort select="position" data-type="number"/>
+ <track>
+ <column><xsl:value-of select="title"/></column>
+ <column><xsl:value-of select="../../artists/artist[1]"/></column>
+ <column><xsl:value-of select="duration"/></column>
+ </track>
+ </xsl:for-each>
+ </tracks>
+
+ <producers>
+ <xsl:for-each select="extraartists/artist[contains(role, 'Producer')]">
+ <producer>
+ <xsl:value-of select="name"/>
+ </producer>
+ </xsl:for-each>
+ </producers>
+
+ <nationalitys>
+ <nationality>
+ <xsl:value-of select="country"/>
+ </nationality>
+ </nationalitys>
+
+ <cover>
+ <xsl:for-each select="images/image">
+ <xsl:sort select="type"/> <!-- 'primary' before 'secondary' -->
+ <xsl:sort select="height*width" data-type="number" order="descending"/>
+ <xsl:if test="position() = 1">
+ <xsl:value-of select="@uri150"/><!-- I wish I could put a 'break' statement here -->
+ <!-- use small image -->
+ </xsl:if>
+ </xsl:for-each>
+ </cover>
+
+ </entry>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/dvd-logo.png b/xslt/dvd-logo.png
new file mode 100644
index 0000000..982b1b2
--- /dev/null
+++ b/xslt/dvd-logo.png
Binary files differ
diff --git a/xslt/entry-templates/Album.xsl b/xslt/entry-templates/Album.xsl
new file mode 100644
index 0000000..9b6e6f0
--- /dev/null
+++ b/xslt/entry-templates/Album.xsl
@@ -0,0 +1,497 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - Entry template for videos
+
+ Copyright (C) 2003-2006 Robby Stephenson - robby@periapsis.org
+
+ Known Issues:
+ o If there is more an one image, there's a lot of white space under
+ the top tables.
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="../tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
+ doctype-system="http://www.w3.org/TR/html4/loose.dtd"
+ encoding="utf-8"/>
+
+<xsl:param name="datadir"/> <!-- dir where Tellico data are located -->
+<xsl:param name="imgdir"/> <!-- dir where field images are located -->
+<xsl:param name="font"/> <!-- font family -->
+<xsl:param name="fontsize"/> <!-- font size -->
+<xsl:param name="fgcolor"/> <!-- foreground color -->
+<xsl:param name="bgcolor"/> <!-- background color -->
+<xsl:param name="color1"/> <!-- highlighted text color -->
+<xsl:param name="color2"/> <!-- highlighted background color -->
+
+<xsl:param name="collection-file"/> <!-- might have a link to parent collection -->
+
+<xsl:key name="fieldsByName" match="tc:field" use="@name"/>
+<xsl:key name="fieldsByCat" match="tc:field" use="@category"/>
+<xsl:key name="imagesById" match="tc:image" use="@id"/>
+
+<xsl:variable name="endl">
+<xsl:text>
+</xsl:text>
+</xsl:variable>
+
+<!-- all the categories -->
+<xsl:variable name="categories" select="/tc:tellico/tc:collection/tc:fields/tc:field[generate-id(.)=generate-id(key('fieldsByCat',@category)[1])]/@category"/>
+<!-- all the tracks -->
+<xsl:variable name="tracks" select="/tc:tellico/tc:collection/tc:fields/tc:field[starts-with(@name,'track')]"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<!-- The default layout is pretty boring, but catches every field value in
+ the entry. The title is in the top H1 element. -->
+<xsl:template match="tc:tellico">
+ <!-- This stylesheet is designed for Tellico document syntax version 10 -->
+ <xsl:call-template name="syntax-version">
+ <xsl:with-param name="this-version" select="'10'"/>
+ <xsl:with-param name="data-version" select="@syntaxVersion"/>
+ </xsl:call-template>
+
+ <html>
+ <head>
+ <style type="text/css">
+ body {
+ margin: .2em 1%;
+ padding: 0;
+ font-family: "<xsl:value-of select="$font"/>", Arial, Helvetica, sans-serif;
+ font-size: <xsl:value-of select="$fontsize"/>pt;
+ background-color: <xsl:value-of select="$bgcolor"/>;
+ color: <xsl:value-of select="$fgcolor"/>;
+ line-height: 1.6;
+ }
+ #banner {
+ padding-bottom: .2em;
+ margin-bottom: .2em;
+ }
+ img#logo {
+ padding-top: .3em; /* match h1 */
+ }
+ h1 {
+ color: <xsl:value-of select="$color1"/>;
+ background-color: <xsl:value-of select="$color2"/>;
+ background-image: url(<xsl:value-of select="concat($imgdir, 'gradient_header.png')"/>);
+ background-repeat: repeat-x;
+ font-size: 1.8em;
+ text-align: left;
+ padding: .1em .5em;
+ margin: 0;
+ font-weight: bold;
+ }
+ span.title {
+ font-style: italic
+ }
+ img {
+ padding-right: 6px;
+ padding-bottom: 6px;
+ border: 0px;
+ }
+ table.category {
+ margin-bottom: 6px;
+ float: left;
+ }
+ tr.category {
+ font-weight: bold;
+ font-size: 1.2em;
+ color: #fff;
+ background-color: #666;
+ text-align: center;
+ }
+ th {
+ font-weight: bold;
+ text-align: left;
+ color: black;
+ background: #ccc;
+ }
+ td.fieldValue {
+ color: black;
+ background: #ddd;
+ }
+ th, td.fieldValue {
+ padding: .1em .3em;
+ }
+ p {
+ margin-top: 0px;
+ text-align: justify;
+ }
+ img {
+ border: 0px solid;
+ }
+ <!-- since text is our own color, links have to be, too -->
+ a {
+ color: #006;
+ }
+ p.navigation {
+ font-weight: bold;
+ text-align: center;
+ clear: both;
+ }
+ </style>
+ <title>
+ <xsl:value-of select="tc:collection/tc:entry[1]//tc:title[1]"/>
+ <xsl:text>&#xa0;&#8211; </xsl:text>
+ <xsl:value-of select="tc:collection/@title"/>
+ </title>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection[1]"/>
+ <xsl:if test="$collection-file">
+ <p class="navigation">
+ <a href="{$collection-file}">&lt;&lt; <xsl:value-of select="tc:collection/@title"/></a>
+ </p>
+ </xsl:if>
+ </body>
+ </html>
+</xsl:template>
+
+<!-- type 3 is video collections -->
+<!-- warn user that this template is meant for videos only. -->
+<xsl:template match="tc:collection[@type!=4]">
+ <h1><i18n>This template is meant for music collections only.</i18n></h1>
+</xsl:template>
+
+<xsl:template match="tc:collection[@type=4]">
+ <xsl:apply-templates select="tc:entry[1]"/>
+</xsl:template>
+
+<xsl:template match="tc:entry">
+ <xsl:variable name="entry" select="."/>
+ <xsl:variable name="titleCat" select="key('fieldsByName','title')/@category"/>
+
+ <!-- the top table has images in the left cell and main fields in the right.
+ 2 images can be on the left -->
+ <table width="100%" class="category">
+ <tr>
+ <!-- now, show all the images in the entry, type 10 -->
+ <xsl:variable name="images" select="../tc:fields/tc:field[@type=10]"/>
+ <!-- only insert cell if at least one image -->
+ <xsl:if test="$entry/*[local-name(.) = $images[1]/@name]">
+ <td valign="top" rowspan="2">
+ <xsl:for-each select="$images">
+
+ <!-- images will never be multiple, so no need to check for that -->
+ <!-- find the value of the image field in the entry -->
+ <xsl:variable name="image" select="$entry/*[local-name(.) = current()/@name]"/>
+ <!-- check if the value is not empty -->
+ <xsl:if test="$image">
+ <a>
+ <xsl:attribute name="href">
+ <xsl:choose>
+ <!-- Amazon license requires the image to be linked to the amazon website -->
+ <xsl:when test="$entry/tc:amazon">
+ <xsl:value-of select="$entry/tc:amazon"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="image-link">
+ <xsl:with-param name="image" select="key('imagesById', $image)"/>
+ <xsl:with-param name="dir" select="$imgdir"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <img alt="">
+ <xsl:attribute name="src">
+ <xsl:call-template name="image-link">
+ <xsl:with-param name="image" select="key('imagesById', $image)"/>
+ <xsl:with-param name="dir" select="$imgdir"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <!-- limit to maximum width of 150 and height of 200 -->
+ <xsl:call-template name="image-size">
+ <xsl:with-param name="limit-width" select="150"/>
+ <xsl:with-param name="limit-height" select="200"/>
+ <xsl:with-param name="image" select="key('imagesById', $image)"/>
+ </xsl:call-template>
+ </img>
+ </a>
+ </xsl:if>
+ </xsl:for-each>
+ </td>
+ </xsl:if>
+
+ <!-- want all the width we can get -->
+ <td valign="top">
+ <!-- now a nested table with the general fields -->
+ <div id="banner">
+
+ <h1>
+ <xsl:choose>
+ <xsl:when test="count(.//tc:artist) = 1">
+ <xsl:value-of select=".//tc:artist[1]"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <i18n>(Various)</i18n>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>&#xa0;&#8211; </xsl:text>
+ <span class="title">
+ <xsl:value-of select=".//tc:title[1]"/>
+ </span>
+
+ <!-- Tellico 0.8 had multiple years in the default video collection -->
+ <xsl:if test=".//tc:year">
+ <span class="year">
+ <xsl:text> (</xsl:text>
+ <xsl:value-of select=".//tc:year[1]"/>
+ <xsl:text>)</xsl:text>
+ </span>
+ </xsl:if>
+
+ </h1>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+
+ <table width="100%">
+ <xsl:for-each select="key('fieldsByCat', $titleCat)">
+ <xsl:if test="@name != 'title'">
+ <tr>
+ <th>
+ <xsl:value-of select="@title"/>
+ </th>
+ <td class="fieldValue" width="100%">
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="@name"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:if>
+ </xsl:for-each>
+ </table>
+
+ </td>
+ </tr>
+ </table>
+
+ <!-- doo all the track fields first -->
+ <xsl:variable name="artist" select="tc:artists/tc:artist[1]"/>
+ <xsl:for-each select="$tracks">
+ <xsl:variable name="fieldName" select="current()/@name"/>
+ <xsl:call-template name="trackField">
+ <xsl:with-param name="values" select="$entry/*[local-name()=concat($fieldName,'s')]"/>
+ <xsl:with-param name="name" select="$fieldName"/>
+ <xsl:with-param name="artist" select="$artist"/>
+ </xsl:call-template>
+ <!-- special case for tracks, since they're usually long tables.
+ clear after every 2nd table -->
+ <xsl:if test="position() mod 2 = 0">
+ <br style="clear:left" />
+ </xsl:if>
+ </xsl:for-each>
+
+ <!-- now for every thing else -->
+ <!-- write categories other than general and images -->
+ <xsl:for-each select="$categories[. != $titleCat and
+ not(starts-with(key('fieldsByCat',.)[1]/@name,'track')) and
+ key('fieldsByCat',.)[1]/@type != 10]">
+
+ <xsl:variable name="category" select="."/>
+ <xsl:variable name="fields" select="key('fieldsByCat', $category)"/>
+ <xsl:variable name="first-type" select="$fields[1]/@type"/>
+
+ <xsl:variable name="n" select="count($entry//*[key('fieldsByName',local-name(.))/@category=$category])"/>
+
+ <!-- only output if there are field values in this category -->
+ <xsl:if test="$n &gt; 0">
+ <table width="50%" class="category">
+ <tr class="category">
+ <td colspan="2">
+ <xsl:attribute name="colspan">
+ <xsl:if test="$first-type = 2">1</xsl:if>
+ <xsl:if test="not($first-type = 2)">2</xsl:if>
+ </xsl:attribute>
+ <xsl:value-of select="."/>
+ </td>
+ </tr>
+ <xsl:for-each select="$fields">
+ <xsl:if test="$entry//*[local-name(.)=current()/@name]">
+ <tr>
+ <xsl:choose>
+ <!-- paragraphs -->
+ <xsl:when test="@type = 2">
+ <td class="fieldValue" width="100%">
+ <p>
+ <xsl:value-of select="$entry/*[local-name(.)=current()/@name]" disable-output-escaping="yes"/>
+ </p>
+ </td>
+ </xsl:when>
+
+ <!-- tables are field type 8 -->
+ <!-- ok to put category name inside div instead of table here -->
+ <xsl:when test="@type = 8">
+ <td>
+ <!-- look at number of columns -->
+ <xsl:choose>
+ <xsl:when test="tc:prop[@name = 'columns'] &gt; 1">
+ <table>
+ <xsl:if test="tc:prop[@name = 'column1']">
+ <thead>
+ <tr>
+ <xsl:call-template name="columnTitle">
+ <xsl:with-param name="index" select="1"/>
+ <xsl:with-param name="max" select="tc:prop[@name = 'columns']"/>
+ <xsl:with-param name="elem" select="'th'"/>
+ <xsl:with-param name="field" select="."/>
+ </xsl:call-template>
+ </tr>
+ </thead>
+ </xsl:if>
+ <tbody>
+ <xsl:for-each select="$entry//*[local-name(.) = current()/@name]">
+ <tr>
+ <xsl:for-each select="tc:column">
+ <td>
+ <xsl:value-of select="."/>
+ <xsl:text>&#160;</xsl:text>
+ </td>
+ </xsl:for-each>
+ </tr>
+ </xsl:for-each>
+ </tbody>
+ </table>
+ </xsl:when>
+ <xsl:otherwise>
+ <ul>
+ <xsl:for-each select="$entry//*[local-name(.) = current()/@name]">
+ <li>
+ <xsl:value-of select="."/>
+ </li>
+ </xsl:for-each>
+ </ul>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ </xsl:when>
+
+ <!-- everything else -->
+ <xsl:otherwise>
+ <th>
+ <xsl:value-of select="@title"/>
+ </th>
+ <td class="fieldValue" width="100%">
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="@name"/>
+ </xsl:call-template>
+ </td>
+ </xsl:otherwise>
+ </xsl:choose>
+ </tr>
+ </xsl:if>
+ </xsl:for-each>
+ </table>
+ </xsl:if>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="trackField">
+ <xsl:param name="values"/>
+ <xsl:param name="name"/>
+ <xsl:param name="artist"/>
+ <xsl:variable name="field" select="key('fieldsByName', $name)"/>
+ <table width="50%" class="category">
+ <xsl:variable name="cols" select="count($values/*[1]/tc:column)"/>
+
+ <tr class="category">
+ <td colspan="{$cols}">
+ <xsl:value-of select="$field/@category"/>
+ </td>
+ </tr>
+ <xsl:if test="$field/tc:prop[@name = 'column1']">
+ <tr>
+ <th colspan="2" style="text-align:center">
+ <xsl:value-of select="$field/tc:prop[@name = 'column1']"/>
+ <xsl:if test="not($values/*[1]/tc:column[2] = $artist)">
+ <xsl:text> / </xsl:text>
+ <em><xsl:value-of select="$field/tc:prop[@name = 'column2']"/></em>
+ </xsl:if>
+ </th>
+ <th style="text-align:center">
+ <xsl:value-of select="$field/tc:prop[@name = 'column3']"/>
+ </th>
+ <xsl:call-template name="columnTitle">
+ <xsl:with-param name="index" select="4"/>
+ <xsl:with-param name="max" select="$cols"/>
+ <xsl:with-param name="elem" select="'th'"/>
+ <xsl:with-param name="field" select="$field"/>
+ </xsl:call-template>
+
+ </tr>
+ </xsl:if>
+
+ <xsl:for-each select="$values/*">
+ <tr>
+ <th style="text-align:center">
+ <xsl:value-of select="format-number(position(), '00')"/>
+ </th>
+ <xsl:choose>
+ <!-- a three column table could have an empty third column -->
+ <xsl:when test="$cols &gt; 1">
+ <!-- if it has three columns, assume first is title,
+ second is artist and third is track length. -->
+ <td class="fieldValue">
+ <xsl:if test="string-length(tc:column[1])">
+ <xsl:value-of select="tc:column[1]"/>
+ </xsl:if>
+ <xsl:if test="string-length(tc:column[2]) and not(tc:column[2] = $artist)">
+ <xsl:text> / </xsl:text>
+ <em><xsl:value-of select="tc:column[2]"/></em>
+ </xsl:if>
+ </td>
+ <td class="fieldValue" style="text-align: right; padding-right: 10px">
+ <em><xsl:value-of select="tc:column[3]"/></em>
+ </td>
+ </xsl:when>
+ <xsl:otherwise>
+ <td class="fieldValue">
+ <xsl:value-of select="."/>
+ </td>
+ </xsl:otherwise>
+ </xsl:choose>
+ </tr>
+ </xsl:for-each>
+
+ <!-- if it has multiple columns,
+ and the final one has a ':', add the time together -->
+ <!-- it should still work if the first row itself doesn't contain a ':' -->
+ <xsl:if test="$cols &gt; 1 and
+ count($values/*[contains(tc:column[number($cols)], ':')])">
+ <tr>
+ <th colspan="2" style="text-align: right; padding-right: 10px;">
+ <strong><i18n>Total:</i18n> </strong>
+ </th>
+ <td class="fieldValue" style="text-align: right; padding-right: 10px">
+ <em>
+ <xsl:call-template name="sumTime">
+ <xsl:with-param name="nodes" select="$values//tc:column[number($cols)]"/>
+ </xsl:call-template>
+ </em>
+ </td>
+ </tr>
+ </xsl:if>
+ </table>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/entry-templates/Compact.xsl b/xslt/entry-templates/Compact.xsl
new file mode 100644
index 0000000..f523d68
--- /dev/null
+++ b/xslt/entry-templates/Compact.xsl
@@ -0,0 +1,294 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - compact template for viewing entry data
+
+ Copyright (C) 2003-2006 Robby Stephenson - robby@periapsis.org
+
+ The drop-shadow effect is based on the "A List Apart" method
+ at http://www.alistapart.com/articles/cssdropshadows/
+
+ Known Issues:
+ o Dependent titles have no value in the entry element.
+ o Bool and URL fields are assumed to never have multiple values.
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="../tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<xsl:param name="datadir"/> <!-- dir where Tellico data are located -->
+<xsl:param name="imgdir"/> <!-- dir where field images are located -->
+<xsl:param name="font"/> <!-- font family -->
+<xsl:param name="fontsize"/> <!-- font size -->
+<xsl:param name="fgcolor"/> <!-- foreground color -->
+<xsl:param name="bgcolor"/> <!-- background color -->
+
+<xsl:param name="collection-file"/> <!-- might have a link to parent collection -->
+
+<xsl:key name="fieldsByName" match="tc:field" use="@name"/>
+<xsl:key name="imagesById" match="tc:image" use="@id"/>
+
+<xsl:variable name="endl">
+<xsl:text>
+</xsl:text>
+</xsl:variable>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<!-- The default layout is pretty boring, but catches every field value in
+ the entry. The title is in the top H1 element. -->
+<xsl:template match="tc:tellico">
+ <!-- This stylesheet is designed for Tellico document syntax version 10 -->
+ <xsl:call-template name="syntax-version">
+ <xsl:with-param name="this-version" select="'10'"/>
+ <xsl:with-param name="data-version" select="@syntaxVersion"/>
+ </xsl:call-template>
+
+ <html>
+ <head>
+ <style type="text/css">
+ body {
+ margin: 0px;
+ padding: 0px;
+ font-family: <xsl:value-of select="$font"/>;
+ font-size: <xsl:value-of select="$fontsize"/>pt;
+ color: <xsl:value-of select="$fgcolor"/>;
+ background-color: <xsl:value-of select="$bgcolor"/>;
+ }
+ #content {
+ padding-right: 160px;
+ }
+ #images {
+ margin: 6px 5px 0px 5px;
+ float: right;
+ min-width: 150px;
+ }
+ div.img-shadow {
+ float: left;
+ background: url(<xsl:value-of select="concat($datadir,'shadowAlpha.png')"/>) no-repeat bottom right;
+ margin: 10px 0 0 10px;
+ }
+ div.img-shadow img {
+ display: block;
+ position: relative;
+ border: 1px solid #a9a9a9;
+ margin: -6px 6px 6px -6px;
+ }
+ table {
+ border-collapse: collapse;
+ border-spacing: 0px;
+ }
+ th.fieldName {
+ font-weight: bold;
+ text-align: left;
+ padding: 0px 4px 0px 2px;
+ white-space: nowrap;
+ }
+ td.fieldValue {
+ text-align: left;
+ padding: 0px 10px 0px 2px;
+ }
+ td.column1 {
+ text-align: left;
+ padding: 0px;
+ }
+ td.column2 {
+ font-style: italic;
+ text-align: left;
+ padding: 0px 10px;
+ }
+ p {
+ margin-top: 0px;
+ text-align: left;
+ }
+ ul {
+ margin-top: 0px;
+ margin-bottom: 0px;
+ padding: 0px 0px 0px 20px;
+ }
+ img {
+ border: 0px;
+ }
+ p.navigation {
+ font-weight: bold;
+ text-align: center;
+ clear: both;
+ }
+ </style>
+ <title>
+ <xsl:value-of select="tc:collection/tc:entry[1]//tc:title[1]"/>
+ <xsl:text>&#xa0;&#8211; </xsl:text>
+ <xsl:value-of select="tc:collection/@title"/>
+ </title>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection[1]"/>
+ <xsl:if test="$collection-file">
+ <p class="navigation">
+ <a href="{$collection-file}">&lt;&lt; <xsl:value-of select="tc:collection/@title"/></a>
+ </p>
+ </xsl:if>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="tc:collection">
+ <xsl:apply-templates select="tc:entry[1]"/>
+</xsl:template>
+
+<xsl:template match="tc:entry">
+ <xsl:variable name="entry" select="."/>
+
+ <!-- all the images are in a div, aligned to the right side and floated-->
+ <div id="images">
+ <!-- images are field type 10 -->
+ <xsl:for-each select="../tc:fields/tc:field[@type=10]">
+
+ <!-- find the value of the image field in the entry -->
+ <xsl:variable name="image" select="$entry/*[local-name(.) = current()/@name]"/>
+ <!-- check if the value is not empty -->
+ <xsl:if test="$image">
+ <div class="img-shadow">
+ <a>
+ <xsl:attribute name="href">
+ <xsl:choose>
+ <!-- Amazon license requires the image to be linked to the amazon website -->
+ <xsl:when test="$entry/tc:amazon">
+ <xsl:value-of select="$entry/tc:amazon"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="image-link">
+ <xsl:with-param name="image" select="key('imagesById', $image)"/>
+ <xsl:with-param name="dir" select="$imgdir"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <img alt="">
+ <xsl:attribute name="src">
+ <xsl:call-template name="image-link">
+ <xsl:with-param name="image" select="key('imagesById', $image)"/>
+ <xsl:with-param name="dir" select="$imgdir"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <!-- limit to maximum width of 150 and height of 200 -->
+ <xsl:call-template name="image-size">
+ <xsl:with-param name="limit-width" select="150"/>
+ <xsl:with-param name="limit-height" select="200"/>
+ <xsl:with-param name="image" select="key('imagesById', $image)"/>
+ </xsl:call-template>
+ </img>
+ </a>
+ </div>
+ <br/> <!-- needed since the img-shadow block floats -->
+ </xsl:if>
+ </xsl:for-each>
+ </div>
+
+ <!-- all the data is in the content block -->
+ <div id="content">
+
+ <!-- now for all the rest of the data -->
+ <!-- iterate over the categories, but skip images -->
+ <table>
+ <tbody>
+ <xsl:for-each select="../tc:fields/tc:field[@type!=10]">
+ <xsl:variable name="field" select="."/>
+
+ <xsl:if test="$entry//*[local-name(.) = $field/@name]">
+ <tr>
+ <th class="fieldName" valign="top">
+ <xsl:value-of select="@title"/>
+ <xsl:text>:</xsl:text>
+ </th>
+
+ <td class="fieldValue">
+ <!-- ok, big xsl:choose loop for field type -->
+ <xsl:choose>
+
+ <!-- paragraphs are field type 2 -->
+ <xsl:when test="@type = 2">
+ <p>
+ <xsl:value-of select="$entry/*[local-name(.) = $field/@name]" disable-output-escaping="yes"/>
+ </p>
+ </xsl:when>
+
+ <!-- tables are field type 8 -->
+ <!-- ok to put category name inside div instead of table here -->
+ <xsl:when test="@type = 8">
+ <!-- look at number of columns -->
+ <xsl:choose>
+ <xsl:when test="$field/tc:prop[@name = 'columns'] &gt; 1">
+ <table>
+ <tbody>
+ <xsl:for-each select="$entry//*[local-name(.) = $field/@name]">
+ <tr>
+ <xsl:for-each select="tc:column">
+ <xsl:choose>
+ <xsl:when test="position() = 1">
+ <td class="column1">
+ <xsl:value-of select="."/>
+ <xsl:text>&#160;</xsl:text>
+ </td>
+ </xsl:when>
+ <xsl:otherwise>
+ <td class="column2">
+ <xsl:value-of select="."/>
+ <xsl:text>&#160;</xsl:text>
+ </td>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </tr>
+ </xsl:for-each>
+ </tbody>
+ </table>
+ </xsl:when>
+ <xsl:otherwise>
+ <ul>
+ <xsl:for-each select="$entry//*[local-name(.) = $field/@name]">
+ <li>
+ <xsl:value-of select="."/>
+ </li>
+ </xsl:for-each>
+ </ul>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$field/@name"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+
+ </xsl:choose>
+ </td>
+ </tr>
+ </xsl:if>
+ </xsl:for-each>
+ </tbody>
+ </table>
+ </div>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/entry-templates/Default.xsl b/xslt/entry-templates/Default.xsl
new file mode 100644
index 0000000..fcd01fd
--- /dev/null
+++ b/xslt/entry-templates/Default.xsl
@@ -0,0 +1,346 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - classic template for viewing entry data
+
+ Copyright (C) 2003-2006 Robby Stephenson - robby@periapsis.org
+
+ Known Issues:
+ o Dependent titles have no value in the entry element.
+ o Bool and URL fields are assumed to never have multiple values.
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="../tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
+ doctype-system="http://www.w3.org/TR/html4/loose.dtd"
+ encoding="utf-8"/>
+
+<xsl:param name="datadir"/> <!-- dir where Tellico data are located -->
+<xsl:param name="imgdir"/> <!-- dir where field images are located -->
+<xsl:param name="font"/> <!-- font family -->
+<xsl:param name="fontsize"/> <!-- font size -->
+<xsl:param name="fgcolor"/> <!-- foreground color -->
+<xsl:param name="bgcolor"/> <!-- background color -->
+<xsl:param name="color1"/> <!-- highlighted text color -->
+<xsl:param name="color2"/> <!-- highlighted background color -->
+
+<xsl:param name="collection-file"/> <!-- might have a link to parent collection -->
+
+<xsl:key name="fieldsByName" match="tc:field" use="@name"/>
+<xsl:key name="fieldsByCat" match="tc:field" use="@category"/>
+<xsl:key name="imagesById" match="tc:image" use="@id"/>
+
+<xsl:variable name="endl">
+<xsl:text>
+</xsl:text>
+</xsl:variable>
+
+<!-- all the categories -->
+<xsl:variable name="categories" select="/tc:tellico/tc:collection/tc:fields/tc:field[generate-id(.)=generate-id(key('fieldsByCat',@category)[1])]/@category"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<!-- The default layout is pretty boring, but catches every field value in
+ the entry. The title is in the top H1 element. -->
+<xsl:template match="tc:tellico">
+ <!-- This stylesheet is designed for Tellico document syntax version 10 -->
+ <xsl:call-template name="syntax-version">
+ <xsl:with-param name="this-version" select="'10'"/>
+ <xsl:with-param name="data-version" select="@syntaxVersion"/>
+ </xsl:call-template>
+
+ <html>
+ <head>
+ <style type="text/css">
+ body {
+ margin: 4px;
+ padding: 0px;
+ font-family: "<xsl:value-of select="$font"/>";
+ font-size: <xsl:value-of select="$fontsize"/>pt;
+ color: <xsl:value-of select="$fgcolor"/>;
+ background-color: <xsl:value-of select="$bgcolor"/>;
+ }
+ h1.title {
+ font-size: 1.8em;
+ padding: 0px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+ margin: 0px;
+ text-align: center;
+ font-weight: bold;
+ }
+ img {
+ padding-right: 10px;
+ border: 0px;
+ }
+ table.category {
+ margin-bottom: 1em;
+ float: left;
+ }
+ tr.category {
+ font-weight: bold;
+ font-size: 1.2em;
+ color: <xsl:value-of select="$color1"/>;
+ background-color: <xsl:value-of select="$color2"/>;
+ text-align: center;
+ }
+ th {
+ font-weight: bold;
+ text-align: left;
+ color: #fff;
+ background-color: #666;
+ padding-left: 3px;
+ padding-right: 3px;
+ }
+ td {
+ padding: 0 .2em;
+ }
+ p {
+ margin-top: 0px;
+ text-align: justify;
+ }
+ img {
+ border: 0px solid;
+ }
+ p.navigation {
+ clear: both;
+ font-weight: bold;
+ text-align: center;
+ clear: both;
+ }
+ </style>
+ <title>
+ <xsl:value-of select="tc:collection/tc:entry[1]//tc:title[1]"/>
+ <xsl:text>&#xa0;&#8211; </xsl:text>
+ <xsl:value-of select="tc:collection/@title"/>
+ </title>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection[1]"/>
+ <xsl:if test="$collection-file">
+ <p class="navigation">
+ <a href="{$collection-file}">&lt;&lt; <xsl:value-of select="tc:collection/@title"/></a>
+ </p>
+ </xsl:if>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="tc:collection">
+ <xsl:apply-templates select="tc:entry[1]"/>
+</xsl:template>
+
+<xsl:template match="tc:entry">
+ <xsl:variable name="entry" select="."/>
+
+ <!-- first, show the title -->
+ <xsl:if test=".//tc:title">
+ <h1>
+ <xsl:for-each select=".//tc:title">
+ <xsl:value-of select="."/>
+ <xsl:if test="position() &lt; last()">
+ <br/>
+ </xsl:if>
+ </xsl:for-each>
+ </h1>
+ </xsl:if>
+
+ <!-- put the general category and all images in top table, one cell for each -->
+ <xsl:variable name="cat1" select="key('fieldsByName','title')/@category"/>
+ <table width="100%">
+ <tr>
+ <td valign="top">
+ <!-- show the general group, or more accurately, the title's group -->
+ <table class="category" width="100%">
+ <tr class="category">
+ <td colspan="2">
+ <xsl:value-of select="$cat1"/>
+ </td>
+ </tr>
+ <xsl:for-each select="key('fieldsByCat', $cat1)">
+ <xsl:if test="@name!='title'">
+ <tr>
+ <th>
+ <xsl:value-of select="@title"/>
+ </th>
+ <td width="75%">
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="@name"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:if>
+ </xsl:for-each>
+ </table>
+ </td>
+ <!-- now, show all the images in the entry, type 10 -->
+ <xsl:variable name="images" select="../tc:fields/tc:field[@type=10]"/>
+ <xsl:if test="count($images) &gt; 0">
+ <!-- now, show all the images in the entry, type 10 -->
+ <xsl:for-each select="$images">
+
+ <!-- images will never be multiple, so no need to check for that -->
+ <!-- find the value of the image field in the entry -->
+ <xsl:variable name="image" select="$entry/*[local-name(.) = current()/@name]"/>
+ <!-- check if the value is not empty -->
+ <xsl:if test="$image">
+ <td valign="top">
+ <table class="category">
+ <tr class="category">
+ <td>
+ <xsl:value-of select="current()/@title"/>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:choose>
+ <!-- Amazon license requires the image to be linked to the amazon website -->
+ <xsl:when test="$entry/tc:amazon">
+ <xsl:value-of select="$entry/tc:amazon"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="image-link">
+ <xsl:with-param name="image" select="key('imagesById', $image)"/>
+ <xsl:with-param name="dir" select="$imgdir"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <img alt="">
+ <xsl:attribute name="src">
+ <xsl:call-template name="image-link">
+ <xsl:with-param name="image" select="key('imagesById', $image)"/>
+ <xsl:with-param name="dir" select="$imgdir"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <!-- limit to maximum width of 150 of height of 200 -->
+ <xsl:call-template name="image-size">
+ <xsl:with-param name="limit-width" select="150"/>
+ <xsl:with-param name="limit-height" select="200"/>
+ <xsl:with-param name="image" select="key('imagesById', $image)"/>
+ </xsl:call-template>
+ </img>
+ </a>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:if>
+ </tr>
+ </table>
+
+ <!-- write categories other than general and images -->
+ <xsl:for-each select="$categories[. != $cat1 and
+ key('fieldsByCat',.)[1]/@type!=10]">
+ <table width="50%" class="category">
+ <tr class="category">
+ <td colspan="2">
+ <xsl:value-of select="."/>
+ </td>
+ </tr>
+ <xsl:for-each select="key('fieldsByCat', .)">
+ <tr>
+ <xsl:choose>
+ <!-- paragraphs -->
+ <xsl:when test="@type = 2">
+ <td>
+ <p>
+ <xsl:value-of select="$entry/*[local-name(.)=current()/@name]" disable-output-escaping="yes"/>
+ </p>
+ </td>
+ </xsl:when>
+
+ <!-- tables are field type 8 -->
+ <!-- ok to put category name inside div instead of table here -->
+ <xsl:when test="@type = 8">
+ <td>
+ <!-- look at number of columns -->
+ <xsl:choose>
+ <xsl:when test="tc:prop[@name = 'columns'] &gt; 1">
+ <table width="100%">
+ <xsl:if test="tc:prop[@name = 'column1']">
+ <thead>
+ <tr>
+ <th width="50%">
+ <xsl:value-of select="tc:prop[@name = 'column1']"/>
+ </th>
+ <th width="50%">
+ <xsl:value-of select="tc:prop[@name = 'column2']"/>
+ </th>
+ <xsl:call-template name="columnTitle">
+ <xsl:with-param name="index" select="3"/>
+ <xsl:with-param name="max" select="tc:prop[@name = 'columns']"/>
+ <xsl:with-param name="elem" select="'th'"/>
+ <xsl:with-param name="field" select="."/>
+ </xsl:call-template>
+ </tr>
+ </thead>
+ </xsl:if>
+ <tbody>
+ <xsl:for-each select="$entry//*[local-name(.) = current()/@name]">
+ <tr>
+ <xsl:for-each select="tc:column">
+ <td width="{floor(100 div count(../tc:column))}%">
+ <xsl:value-of select="."/>
+ <xsl:text>&#160;</xsl:text>
+ </td>
+ </xsl:for-each>
+ </tr>
+ </xsl:for-each>
+ </tbody>
+ </table>
+ </xsl:when>
+ <xsl:otherwise>
+ <ul>
+ <xsl:for-each select="$entry//*[local-name(.) = current()/@name]">
+ <li>
+ <xsl:value-of select="."/>
+ </li>
+ </xsl:for-each>
+ </ul>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ </xsl:when>
+
+ <!-- everything else -->
+ <xsl:otherwise>
+ <th>
+ <xsl:value-of select="@title"/>
+ </th>
+ <td>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="@name"/>
+ </xsl:call-template>
+ </td>
+ </xsl:otherwise>
+ </xsl:choose>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </xsl:for-each>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/entry-templates/Fancy.xsl b/xslt/entry-templates/Fancy.xsl
new file mode 100644
index 0000000..875309f
--- /dev/null
+++ b/xslt/entry-templates/Fancy.xsl
@@ -0,0 +1,444 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - fancy template for viewing entry data
+
+ Copyright (C) 2003-2006 Robby Stephenson - robby@periapsis.org
+
+ The drop-shadow effect is based on the "A List Apart" method
+ at http://www.alistapart.com/articles/cssdropshadows/
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="../tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<xsl:param name="datadir"/> <!-- dir where Tellico data are located -->
+<xsl:param name="imgdir"/> <!-- dir where field images are located -->
+<xsl:param name="font"/> <!-- font family -->
+<xsl:param name="fontsize"/> <!-- font size -->
+<xsl:param name="fgcolor"/> <!-- foreground color -->
+<xsl:param name="bgcolor"/> <!-- background color -->
+<xsl:param name="color1"/> <!-- highlighted text color -->
+<xsl:param name="color2"/> <!-- highlighted background color -->
+
+<xsl:param name="collection-file"/> <!-- might have a link to parent collection -->
+
+<xsl:key name="fieldsByName" match="tc:field" use="@name"/>
+<xsl:key name="fieldsByCat" match="tc:field" use="@category"/>
+<xsl:key name="imagesById" match="tc:image" use="@id"/>
+
+<xsl:variable name="image-width" select="'150'"/>
+<xsl:variable name="image-height" select="'200'"/>
+<xsl:variable name="endl">
+<xsl:text>
+</xsl:text>
+</xsl:variable>
+
+<!-- all the categories -->
+<xsl:variable name="categories" select="/tc:tellico/tc:collection/tc:fields/tc:field[generate-id(.)=generate-id(key('fieldsByCat',@category)[1])]/@category"/>
+<!-- layout changes depending on whether there are images or not -->
+<xsl:variable name="num-images" select="count(tc:tellico/tc:collection/tc:entry[1]/*[key('fieldsByName',local-name(.))/@type = 10])"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<!-- The default layout is pretty boring, but catches every field value in
+ the entry. The title is in the top H1 element. -->
+<xsl:template match="tc:tellico">
+ <!-- This stylesheet is designed for Tellico document syntax version 10 -->
+ <xsl:call-template name="syntax-version">
+ <xsl:with-param name="this-version" select="'10'"/>
+ <xsl:with-param name="data-version" select="@syntaxVersion"/>
+ </xsl:call-template>
+
+ <html>
+ <head>
+ <style type="text/css">
+ body {
+ margin: 0px;
+ padding: 0px;
+ font-family: "<xsl:value-of select="$font"/>";
+ font-size: <xsl:value-of select="$fontsize"/>pt;
+ color: <xsl:value-of select="$fgcolor"/>;
+ background-color: <xsl:value-of select="$bgcolor"/>;
+ background-image: url(<xsl:value-of select="concat($imgdir, 'gradient_bg.png')"/>);
+ background-repeat: repeat;
+ }
+ h1 {
+ margin: 0px;
+ padding: 0px;
+ font-size: 1.8em;
+ color: <xsl:value-of select="$color1"/>;
+ background-color: <xsl:value-of select="$color2"/>;
+ background-image: url(<xsl:value-of select="concat($imgdir, 'gradient_header.png')"/>);
+ background-repeat: repeat-x;
+ border-bottom: 1px outset black;
+ text-align: center;
+ }
+ <xsl:if test="$num-images &gt; 0">
+ div#images {
+ margin: 10px 5px 0px 5px;
+ float: right;
+ min-width: <xsl:value-of select="$image-width"/>px; /* min-width instead of width, stylesheet actually scales image */
+ }
+ </xsl:if>
+ div.img-shadow {
+ float: left;
+ background: url(<xsl:value-of select="concat($datadir,'shadowAlpha.png')"/>) no-repeat bottom right;
+ margin: 6px 0 10px 10px;
+ clear: left;
+ }
+ div.img-shadow img {
+ display: block;
+ position: relative;
+ border: 1px solid #a9a9a9;
+ margin: -6px 6px 6px -6px;
+ }
+ h3 {
+ text-align: center;
+ font-size: 1.1em;
+ }
+ div#content {
+ padding-left: 1%;
+ padding-right: 1%;
+ }
+ div.category {
+ padding: 0px 0px 0px 4px;
+ margin: 8px;
+ border: 1px solid <xsl:value-of select="$fgcolor"/>;
+ text-align: center;
+ /* if background is grey, text has to be black */
+ color: #000;
+ background-color: #ccc;
+ min-height: 1em;
+ overflow: hidden;
+ }
+ h2 {
+ color: <xsl:value-of select="$color1"/>;
+ background-color: <xsl:value-of select="$color2"/>;
+ background-image: url(<xsl:value-of select="concat($imgdir, 'gradient_header.png')"/>);
+ background-repeat: repeat-x;
+ border-bottom: 1px outset;
+ border-color: <xsl:value-of select="$fgcolor"/>;
+ padding: 0px 8px 0px 0px;
+ margin: 0px 0px 2px -4px; /* -4px to match .category padding */
+ font-size: 1.0em;
+ top: -1px;
+ font-style: normal;
+ text-align: right;
+ }
+ table {
+ border-collapse: collapse;
+ border-spacing: 0px;
+ max-width: 100%;
+ }
+ tr.table-columns {
+ font-style: italic;
+ }
+ th.fieldName {
+ font-weight: bolder;
+ text-align: left;
+ padding: 0px 4px 0px 2px;
+ white-space: nowrap;
+ }
+ td.fieldValue {
+ text-align: left;
+ padding: 0px 10px 0px 2px;
+ vertical-align: top;
+ width: 90%; /* nowrap is set on the fieldName column, so just want enough width to take the rest */
+ }
+ td.column1 {
+ font-weight: bold;
+ text-align: left;
+ padding: 0px 2px 0px 2px;
+/* white-space: nowrap;*/
+ }
+ td.column2 {
+ font-style: italic;
+ text-align: left;
+ padding: 0px 10px 0px 10px;
+/* width: 90%; nowrap is set on the fieldName column, so just want enough width to take the rest */
+ }
+ p {
+ margin: 2px 10px 2px 0;
+ padding: 0px;
+ text-align: justify;
+ font-size: 90%;
+ }
+ ul {
+ text-align: left;
+ margin: 0px 0px 0px 0px;
+ padding-left: 20px;
+ }
+ img {
+ border: 0px;
+ }
+ p.navigation {
+ font-weight: bold;
+ text-align: center;
+ clear: both;
+ }
+ </style>
+ <title>
+ <xsl:value-of select="tc:collection[1]/tc:entry[1]//tc:title[1]"/>
+ <xsl:text>&#xa0;&#8211; </xsl:text>
+ <xsl:value-of select="tc:collection[1]/@title"/>
+ </title>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection[1]"/>
+ <xsl:if test="$collection-file">
+ <p class="navigation">
+ <a href="{$collection-file}">&lt;&lt; <xsl:value-of select="tc:collection/@title"/></a>
+ </p>
+ </xsl:if>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="tc:collection">
+ <xsl:apply-templates select="tc:entry[1]"/>
+</xsl:template>
+
+<xsl:template match="tc:entry">
+ <xsl:variable name="entry" select="."/>
+
+ <!-- first, show the title -->
+ <xsl:if test=".//tc:title">
+ <h1>
+ <xsl:for-each select=".//tc:title">
+ <xsl:value-of select="."/>
+ <xsl:if test="position() &lt; last()">
+ <br/>
+ </xsl:if>
+ </xsl:for-each>
+ </h1>
+ </xsl:if>
+
+ <!-- all the images are in a div, aligned to the right side and floated -->
+ <!-- only want this div if there are any images in the entry -->
+ <xsl:if test="$num-images &gt; 0">
+ <div id="images">
+ <!-- images are field type 10 -->
+ <xsl:for-each select="../tc:fields/tc:field[@type=10]">
+
+ <!-- find the value of the image field in the entry -->
+ <xsl:variable name="image" select="$entry/*[local-name(.) = current()/@name]"/>
+ <!-- check if the value is not empty -->
+ <xsl:if test="$image">
+ <div class="img-shadow">
+ <a>
+ <xsl:attribute name="href">
+ <xsl:choose>
+ <!-- Amazon license requires the image to be linked to the amazon website -->
+ <xsl:when test="$entry/tc:amazon">
+ <xsl:value-of select="$entry/tc:amazon"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="image-link">
+ <xsl:with-param name="image" select="key('imagesById', $image)"/>
+ <xsl:with-param name="dir" select="$imgdir"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <img alt="" style="vertical-align:bottom;">
+ <xsl:attribute name="src">
+ <xsl:call-template name="image-link">
+ <xsl:with-param name="image" select="key('imagesById', $image)"/>
+ <xsl:with-param name="dir" select="$imgdir"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <!-- limit to maximum width of 150 and height of 200 -->
+ <xsl:call-template name="image-size">
+ <xsl:with-param name="limit-width" select="$image-width"/>
+ <xsl:with-param name="limit-height" select="$image-height"/>
+ <xsl:with-param name="image" select="key('imagesById', $image)"/>
+ </xsl:call-template>
+ </img>
+ </a>
+ </div>
+ <br/> <!-- needed since the img-shadow block floats -->
+ </xsl:if>
+ </xsl:for-each>
+ </div>
+ </xsl:if>
+
+ <!-- all the data is in the content block -->
+ <div id="content">
+ <!-- now for all the rest of the data -->
+ <!-- iterate over the categories, but skip paragraphs and images -->
+ <xsl:for-each select="$categories[key('fieldsByCat',.)[1]/@type != 2 and key('fieldsByCat',.)[1]/@type != 10]">
+ <xsl:call-template name="output-category">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="category" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <!-- now do paragraphs -->
+ <xsl:for-each select="$categories[key('fieldsByCat',.)[1]/@type = 2]">
+ <xsl:call-template name="output-category">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="category" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ </div>
+
+</xsl:template>
+
+<xsl:template name="output-category">
+ <xsl:param name="entry"/>
+ <xsl:param name="category"/>
+
+ <xsl:variable name="fields" select="key('fieldsByCat', $category)"/>
+ <xsl:variable name="first-type" select="$fields[1]/@type"/>
+
+ <xsl:variable name="n" select="count($entry//*[key('fieldsByName',local-name(.))/@category=$category])"/>
+ <!-- only output if there are fields in this category
+ also, special case, don't output empty paragraphs -->
+ <xsl:if test="$n &gt; 0 and (not($first-type = 2) or $entry/*[local-name(.) = $fields[1]/@name])">
+ <div class="container">
+ <xsl:if test="$num-images = 0 and $first-type != 2">
+ <xsl:attribute name="style">
+ <xsl:text>width: 50%; </xsl:text>
+ <!-- two columns of divs -->
+ <xsl:choose>
+ <xsl:when test="$categories[. = $category and position() mod 2 = 1]">
+ <xsl:text>float: left; clear: both;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>float: right;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:if test="$num-images = 0 and $first-type = 2">
+ <xsl:attribute name="style">
+ <xsl:text>width: 100%; float: left; clear: both;</xsl:text>
+ </xsl:attribute>
+ </xsl:if>
+ <div class="category">
+
+ <h2>
+ <xsl:value-of select="$category"/>
+ </h2>
+ <!-- ok, big xsl:choose loop for field type -->
+ <xsl:choose>
+
+ <!-- paragraphs are field type 2 -->
+ <xsl:when test="$first-type = 2">
+ <p>
+ <!-- disabling the output escaping allows html -->
+ <xsl:value-of select="$entry/*[local-name(.) = $fields[1]/@name]" disable-output-escaping="yes"/>
+ </p>
+ </xsl:when>
+
+ <!-- tables are field type 8 -->
+ <!-- ok to put category name inside div instead of table here -->
+ <xsl:when test="$first-type = 8">
+ <!-- look at number of columns -->
+ <xsl:choose>
+ <xsl:when test="$fields[1]/tc:prop[@name = 'columns'] &gt; 1">
+ <table width="100%">
+ <xsl:if test="$fields[1]/tc:prop[@name = 'column1']">
+ <thead>
+ <tr class="table-columns">
+ <th width="50%">
+ <xsl:value-of select="$fields[1]/tc:prop[@name = 'column1']"/>
+ </th>
+ <th width="50%">
+ <xsl:value-of select="$fields[1]/tc:prop[@name = 'column2']"/>
+ </th>
+ <xsl:call-template name="columnTitle">
+ <xsl:with-param name="index" select="3"/>
+ <xsl:with-param name="max" select="$fields[1]/tc:prop[@name = 'columns']"/>
+ <xsl:with-param name="elem" select="'th'"/>
+ <xsl:with-param name="field" select="$fields[1]"/>
+ </xsl:call-template>
+ </tr>
+ </thead>
+ </xsl:if>
+ <tbody>
+ <xsl:for-each select="$entry//*[local-name(.) = $fields[1]/@name]">
+ <tr>
+ <xsl:for-each select="tc:column">
+ <xsl:choose>
+ <xsl:when test="position() = 1">
+ <td class="column1">
+ <xsl:value-of select="."/>
+ <xsl:text>&#160;</xsl:text>
+ </td>
+ </xsl:when>
+ <xsl:otherwise>
+ <td class="column2">
+ <xsl:value-of select="."/>
+ <xsl:text>&#160;</xsl:text>
+ </td>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </tr>
+ </xsl:for-each>
+ </tbody>
+ </table>
+ </xsl:when>
+ <xsl:otherwise>
+ <ul>
+ <xsl:for-each select="$entry//*[local-name(.) = $fields[1]/@name]">
+ <li>
+ <xsl:value-of select="."/>
+ </li>
+ </xsl:for-each>
+ </ul>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <table>
+ <tbody>
+ <!-- already used title, so skip it -->
+ <xsl:for-each select="$fields[@name != 'title']">
+ <tr>
+ <th class="fieldName" valign="top">
+ <xsl:value-of select="@title"/>
+ <xsl:text>:</xsl:text>
+ </th>
+ <td class="fieldValue">
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="@name"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </tbody>
+ </table>
+
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </div>
+ </div>
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/entry-templates/Makefile.am b/xslt/entry-templates/Makefile.am
new file mode 100644
index 0000000..5b1b875
--- /dev/null
+++ b/xslt/entry-templates/Makefile.am
@@ -0,0 +1,17 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+
+EXTRA_DIST = Default.xsl Video.xsl Album.xsl Fancy.xsl Compact.xsl
+
+####### kdevelop will overwrite this part!!! (end)############
+
+xsldir = $(kde_datadir)/tellico/entry-templates
+xsl_DATA = Default.xsl Video.xsl Album.xsl Fancy.xsl Compact.xsl
+
+KDE_OPTIONS = noautodist
+
+CLEANFILES = *~
+
+# probably a better way to do this
+uninstall-hook:
+ -if [ -d $(xsldir) ]; then rmdir $(xsldir); fi
diff --git a/xslt/entry-templates/Video.xsl b/xslt/entry-templates/Video.xsl
new file mode 100644
index 0000000..c74e88e
--- /dev/null
+++ b/xslt/entry-templates/Video.xsl
@@ -0,0 +1,512 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - Entry template for videos
+
+ Copyright (C) 2003-2006 Robby Stephenson - robby@periapsis.org
+
+ Known Issues:
+ o If there is more an one image, there's a lot of white space under
+ the top tables.
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="../tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<xsl:param name="datadir"/> <!-- dir where Tellico data are located -->
+<xsl:param name="imgdir"/> <!-- dir where field images are located -->
+<xsl:param name="font"/> <!-- font family -->
+<xsl:param name="fontsize"/> <!-- font size -->
+<xsl:param name="fgcolor"/> <!-- foreground color -->
+<xsl:param name="bgcolor"/> <!-- background color -->
+<xsl:param name="color1"/> <!-- highlighted text color -->
+<xsl:param name="color2"/> <!-- highlighted background color -->
+
+<xsl:param name="collection-file"/> <!-- might have a link to parent collection -->
+
+<xsl:key name="fieldsByName" match="tc:field" use="@name"/>
+<xsl:key name="fieldsByCat" match="tc:field" use="@category"/>
+<xsl:key name="imagesById" match="tc:image" use="@id"/>
+
+<xsl:variable name="endl">
+<xsl:text>
+</xsl:text>
+</xsl:variable>
+
+<!-- all the categories -->
+<xsl:variable name="categories" select="/tc:tellico/tc:collection/tc:fields/tc:field[generate-id(.)=generate-id(key('fieldsByCat',@category)[1])]/@category"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<!-- The default layout is pretty boring, but catches every field value in
+ the entry. The title is in the top H1 element. -->
+<xsl:template match="tc:tellico">
+ <!-- This stylesheet is designed for Tellico document syntax version 10 -->
+ <xsl:call-template name="syntax-version">
+ <xsl:with-param name="this-version" select="'10'"/>
+ <xsl:with-param name="data-version" select="@syntaxVersion"/>
+ </xsl:call-template>
+
+ <html>
+ <head>
+ <style type="text/css">
+ body {
+ margin: .2em 1%;
+ padding: 0;
+ font-family: "<xsl:value-of select="$font"/>", Arial, Helvetica, sans-serif;
+ font-size: <xsl:value-of select="$fontsize"/>pt;
+ color: <xsl:value-of select="$fgcolor"/>;
+ background: <xsl:value-of select="$bgcolor"/>;
+ line-height: 1.6;
+ }
+ div#banner {
+ padding-bottom: .1em;
+ margin-bottom: .4em;
+ border-bottom: .2em ridge <xsl:value-of select="$color2"/>;
+ }
+ img#logo {
+ padding-left: .5em;
+ padding-top: .4em;
+ float: right;
+ }
+ h1 {
+ color: <xsl:value-of select="$color2"/>;
+ font-size: 1.8em;
+ text-align: left;
+ padding: .2em;
+ margin: 0;
+ font-weight: bold;
+ }
+ span.year {
+ font-size: 0.8em;
+ }
+ span.country {
+ font-style: italic;
+ }
+ h2 {
+ font-size: 1.2em;
+ margin: 0;
+ padding: 0;
+ padding-left: .2em;
+ }
+ img {
+ padding-right: 1em;
+ padding-bottom: 1em;
+ }
+ table.category {
+ margin-right: 1%;
+ margin-bottom: 1em;
+ float: left;
+ border-collapse: collapse;
+ border-spacing: 0px;
+ }
+ tr.category {
+ font-weight: bold;
+ font-size: 1.2em;
+ color: <xsl:value-of select="$color1"/>;
+ background: <xsl:value-of select="$color2"/>;
+ text-align: center;
+ }
+ /* there seems to be a khtml bug, in 3.4.x at least, repeat-x doesn't
+ work on the tr element, so have to put it on the th element */
+ tr.category th {
+ background-image: url(<xsl:value-of select="concat($imgdir, 'gradient_header.png')"/>);
+ background-repeat: repeat-x;
+ }
+ th {
+ font-weight: bold;
+ text-align: left;
+ color: <xsl:value-of select="$color2"/>;
+ background <xsl:value-of select="$color1"/>;
+ padding: 0px 0.2em 0px 0.2em;
+ white-space: nowrap;
+ }
+ thead th {
+ color: <xsl:value-of select="$color1"/>;
+ background <xsl:value-of select="$color2"/>;
+ text-align: center;
+ }
+ td {
+ padding: 0px 0.2em 0px 0.2em;
+ }
+ td.role {
+ font-style: italic;
+ }
+ p {
+ margin-top: 0;
+ text-align: justify;
+ font-size: .9em;
+ }
+ ul {
+ margin-top: .3em;
+ margin-bottom: .3em;
+ margin-left: 0;
+ padding: 0 0 0 1.5em;
+ }
+ img {
+ border: 0px;
+ }
+ p.navigation {
+ font-weight: bold;
+ text-align: center;
+ clear: both;
+ }
+ </style>
+ <title>
+ <xsl:value-of select="tc:collection/tc:entry[1]//tc:title[1]"/>
+ <xsl:text>&#xa0;&#8211; </xsl:text>
+ <xsl:value-of select="tc:collection/@title"/>
+ </title>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection[1]"/>
+ <xsl:if test="$collection-file">
+ <p class="navigation">
+ <a href="{$collection-file}">&lt;&lt; <xsl:value-of select="tc:collection/@title"/></a>
+ </p>
+ </xsl:if>
+ </body>
+ </html>
+</xsl:template>
+
+<!-- type 3 is video collections -->
+<!-- warn user that this template is meant for videos only. -->
+<xsl:template match="tc:collection[@type!=3]">
+ <h1><i18n>This template is meant for video collections only.</i18n></h1>
+</xsl:template>
+
+<xsl:template match="tc:collection[@type=3]">
+ <xsl:apply-templates select="tc:entry[1]"/>
+</xsl:template>
+
+<xsl:template match="tc:entry">
+ <xsl:variable name="entry" select="."/>
+ <xsl:variable name="titleCat" select="key('fieldsByName','title')/@category"/>
+ <!-- there might not be a cast -->
+ <xsl:variable name="castCat">
+ <xsl:choose>
+ <xsl:when test="tc:casts">
+ <xsl:value-of select="key('fieldsByName','cast')/@category"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="''"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <div id="banner">
+ <!-- do format logo -->
+ <xsl:choose>
+ <xsl:when test="$datadir and tc:medium = 'DVD'">
+ <img width="74" height="30" id="logo" alt="(DVD)">
+ <xsl:attribute name="src">
+ <xsl:value-of select="concat($datadir,'dvd-logo.png')"/>
+ </xsl:attribute>
+ </img>
+ </xsl:when>
+ <xsl:when test="$datadir and tc:medium = 'VHS'">
+ <img width="56" height="30" id="logo" alt="(VHS)">
+ <xsl:attribute name="src">
+ <xsl:value-of select="concat($datadir,'vhs-logo.png')"/>
+ </xsl:attribute>
+ </img>
+ </xsl:when>
+ <xsl:when test="$datadir and tc:medium = 'Blu-ray'">
+ <img width="56" height="30" id="logo" alt="(Blu-ray)">
+ <xsl:attribute name="src">
+ <xsl:value-of select="concat($datadir,'bluray-logo.png')"/>
+ </xsl:attribute>
+ </img>
+ </xsl:when>
+ <xsl:when test="$datadir and tc:medium = 'HD DVD'">
+ <img width="119" height="30" id="logo" alt="(HD DVD)">
+ <xsl:attribute name="src">
+ <xsl:value-of select="concat($datadir,'hddvd-logo.png')"/>
+ </xsl:attribute>
+ </img>
+ </xsl:when>
+ </xsl:choose>
+
+ <!-- title block -->
+ <h1>
+ <xsl:value-of select=".//tc:title[1]"/>
+ <xsl:if test="tc:widescreen"><xsl:text/>
+ <xsl:text>&#xa0;&#8211; </xsl:text><xsl:value-of select="key('fieldsByName', 'widescreen')/@title"/><xsl:text/>
+ </xsl:if>
+ <xsl:if test="tc:directors-cut"><xsl:text/>
+ <xsl:text>&#xa0;&#8211; </xsl:text><xsl:value-of select="key('fieldsByName', 'directors-cut')/@title"/><xsl:text/>
+ </xsl:if>
+ <xsl:if test=".//tc:year|.//tc:nationality">
+ <span class="year">
+ <xsl:text> (</xsl:text>
+ <xsl:if test=".//tc:year">
+ <xsl:value-of select=".//tc:year[1]"/>
+ </xsl:if>
+ <xsl:if test=".//tc:nationality">
+ <xsl:if test=".//tc:year">
+ <xsl:text>&#xa0;&#8211; </xsl:text>
+ </xsl:if>
+ <span class="country">
+ <xsl:value-of select=".//tc:nationality[1]"/>
+ </span>
+ </xsl:if>
+ <xsl:text>)</xsl:text>
+ </span>
+ </xsl:if>
+ </h1>
+
+ </div>
+
+ <!-- the images and the rest of the categories are each in a table in a table cell -->
+ <table class="category" width="100%">
+ <tbody>
+ <tr>
+ <td valign="top">
+
+ <!-- now, show all the images in the entry, field type 10 -->
+ <xsl:variable name="images" select="../tc:fields/tc:field[@type=10]"/>
+ <xsl:if test="count($images) &gt; 0">
+ <table>
+ <tbody>
+ <!-- now, show all the images in the entry, type 10 -->
+ <xsl:for-each select="$images">
+ <tr>
+ <td>
+
+ <!-- images will never be multiple, so no need to check for that -->
+ <!-- find the value of the image field in the entry -->
+ <xsl:variable name="image" select="$entry/*[local-name(.) = current()/@name]"/>
+ <!-- check if the value is not empty -->
+ <xsl:if test="$image">
+ <a>
+ <xsl:attribute name="href">
+ <xsl:choose>
+ <!-- Amazon license requires the image to be linked to the amazon website -->
+ <xsl:when test="$entry/tc:amazon">
+ <xsl:value-of select="$entry/tc:amazon"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="image-link">
+ <xsl:with-param name="image" select="key('imagesById', $image)"/>
+ <xsl:with-param name="dir" select="$imgdir"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <img alt="">
+ <xsl:attribute name="src">
+ <xsl:call-template name="image-link">
+ <xsl:with-param name="image" select="key('imagesById', $image)"/>
+ <xsl:with-param name="dir" select="$imgdir"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <!-- limit to maximum width of 200 of height of 300 -->
+ <xsl:call-template name="image-size">
+ <xsl:with-param name="limit-width" select="200"/>
+ <xsl:with-param name="limit-height" select="300"/>
+ <xsl:with-param name="image" select="key('imagesById', $image)"/>
+ </xsl:call-template>
+ </img>
+ </a>
+ </xsl:if>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </tbody>
+ </table>
+ </xsl:if>
+ </td>
+
+ <td valign="top">
+
+ <!-- show the general group, or more accurately, the title's group -->
+ <table width="49%" class="category">
+ <thead>
+ <tr class="category">
+ <th colspan="2">
+ <xsl:value-of select="$titleCat"/>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <!-- the year and nationality have already been shown, but the film
+ might have multiple values, so go ahead and show them again -->
+ <xsl:for-each select="key('fieldsByCat', $titleCat)">
+ <xsl:if test="@name != 'title'">
+ <tr>
+ <th>
+ <xsl:value-of select="@title"/>
+ </th>
+ <td>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="@name"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:if>
+ </xsl:for-each>
+ </tbody>
+ </table>
+
+ <!-- now for the cast -->
+ <xsl:if test="tc:casts">
+ <xsl:variable name="castField" select="key('fieldsByName', 'cast')"/>
+ <table width="49%" class="category">
+ <thead>
+ <tr class="category">
+ <th colspan="2">
+ <xsl:value-of select="$castField/@title"/>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <xsl:if test="$castField/tc:prop[@name = 'column1']">
+ <xsl:variable name="castCols" select="$castField/tc:prop[@name = 'columns']"/>
+ <tr>
+ <xsl:call-template name="columnTitle">
+ <xsl:with-param name="index" select="1"/>
+ <xsl:with-param name="max" select="$castCols"/>
+ <xsl:with-param name="elem" select="'th'"/>
+ <xsl:with-param name="field" select="$castField"/>
+ </xsl:call-template>
+ </tr>
+ </xsl:if>
+ <xsl:for-each select="$entry/tc:casts/tc:cast">
+ <tr>
+ <xsl:for-each select="tc:column">
+ <td>
+ <xsl:if test="position() = 1">
+ <xsl:attribute name="class">person</xsl:attribute><xsl:value-of select="."/>
+ </xsl:if>
+ <xsl:if test="position() &gt; 1">
+ <xsl:attribute name="class">role</xsl:attribute><xsl:value-of select="."/>
+ </xsl:if>
+ <xsl:text>&#160;</xsl:text>
+ </td>
+ </xsl:for-each>
+ </tr>
+ </xsl:for-each>
+ </tbody>
+ </table>
+ </xsl:if>
+
+ <!-- now for every thing else -->
+ <!-- write categories other than general and images -->
+ <!-- $castcat might be empty, be careful -->
+ <xsl:for-each select="$categories[. != $titleCat and
+ ($castCat = '' or . != $castCat) and
+ key('fieldsByCat',.)[1]/@type != 10]">
+ <table width="49%" class="category">
+ <thead>
+ <tr class="category">
+ <th colspan="2">
+ <xsl:value-of select="."/>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <xsl:for-each select="key('fieldsByCat', .)[@name != 'directors-cut' and
+ @name != 'widescreen']">
+ <tr>
+ <xsl:choose>
+ <!-- paragraphs -->
+ <xsl:when test="@type=2">
+ <td colspan="2">
+ <p>
+ <xsl:value-of select="$entry/*[local-name(.)=current()/@name]" disable-output-escaping="yes"/>
+ </p>
+ </td>
+ </xsl:when>
+
+ <!-- tables are field type 8 -->
+ <!-- ok to put category name inside div instead of table here -->
+ <xsl:when test="@type = 8">
+ <td colspan="2">
+ <!-- look at number of columns -->
+ <xsl:choose>
+ <xsl:when test="tc:prop[@name = 'columns'] &gt; 1">
+ <table>
+ <xsl:if test="tc:prop[@name = 'column1']">
+ <thead>
+ <tr>
+ <xsl:call-template name="columnTitle">
+ <xsl:with-param name="index" select="1"/>
+ <xsl:with-param name="max" select="tc:prop[@name = 'columns']"/>
+ <xsl:with-param name="elem" select="'th'"/>
+ <xsl:with-param name="field" select="."/>
+ </xsl:call-template>
+ </tr>
+ </thead>
+ </xsl:if>
+ <tbody>
+ <xsl:for-each select="$entry//*[local-name(.) = current()/@name]">
+ <tr>
+ <xsl:for-each select="tc:column">
+ <td width="{100 div count(../tc:column)}%">
+ <xsl:value-of select="."/>
+ <xsl:text>&#160;</xsl:text>
+ </td>
+ </xsl:for-each>
+ </tr>
+ </xsl:for-each>
+ </tbody>
+ </table>
+ </xsl:when>
+ <xsl:otherwise>
+ <ul>
+ <xsl:for-each select="$entry//*[local-name(.) = current()/@name]">
+ <li>
+ <xsl:value-of select="."/>
+ </li>
+ </xsl:for-each>
+ </ul>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ </xsl:when>
+
+ <!-- everything else -->
+ <xsl:otherwise>
+ <th>
+ <xsl:value-of select="@title"/>
+ </th>
+ <td>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="@name"/>
+ </xsl:call-template>
+ </td>
+ </xsl:otherwise>
+ </xsl:choose>
+ </tr>
+ </xsl:for-each>
+ </tbody>
+ </table>
+ </xsl:for-each>
+</td>
+</tr>
+</tbody>
+</table>
+
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/gcstar2tellico.xsl b/xslt/gcstar2tellico.xsl
new file mode 100644
index 0000000..a45df87
--- /dev/null
+++ b/xslt/gcstar2tellico.xsl
@@ -0,0 +1,503 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ xmlns:exsl="http://exslt.org/common"
+ xmlns:str="http://exslt.org/strings"
+ extension-element-prefixes="str exsl"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for importing GCstar data.
+
+ Copyright (C) 2007-2008 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ doctype-public="-//Robby Stephenson/DTD Tellico V9.0//EN"
+ doctype-system="http://periapsis.org/tellico/dtd/v9/tellico.dtd"/>
+
+<xsl:variable name="coll">
+ <xsl:choose>
+ <xsl:when test="/collection[1]/@type='GCbooks'">
+ <xsl:text>2</xsl:text>
+ </xsl:when>
+ <xsl:when test="/collection[1]/@type='GCfilms'">
+ <xsl:text>3</xsl:text>
+ </xsl:when>
+ <xsl:when test="/collection[1]/@type='GCmusics'">
+ <xsl:text>4</xsl:text>
+ </xsl:when>
+ <xsl:when test="/collection[1]/@type='GCwines'">
+ <xsl:text>7</xsl:text>
+ </xsl:when>
+ <xsl:when test="/collection[1]/@type='GCcoins'">
+ <xsl:text>8</xsl:text>
+ </xsl:when>
+ <xsl:when test="/collection[1]/@type='GCgames'">
+ <xsl:text>11</xsl:text>
+ </xsl:when>
+ <xsl:when test="/collection[1]/@type='GCboardgames'">
+ <xsl:text>13</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+</xsl:variable>
+
+<xsl:template match="/">
+ <tc:tellico syntaxVersion="9">
+ <xsl:apply-templates select="collection"/>
+ </tc:tellico>
+</xsl:template>
+
+<xsl:template match="collection">
+ <tc:collection title="GCstar Import" type="{$coll}">
+ <tc:fields>
+ <tc:field name="_default"/>
+ <tc:field flags="0" title="Favorite" category="Personal" format="4" type="4" name="favorite" i18n="true"/>
+ <xsl:if test="item/@web or item/@webPage">
+ <tc:field flags="0" title="URL" category="General" format="4" type="7" name="url" i18n="true"/>
+ </xsl:if>
+ <xsl:if test="item/@location">
+ <tc:field flags="6" title="Location" category="Personal" format="4" type="1" name="location" i18n="true"/>
+ </xsl:if>
+ <xsl:if test="item/@composer">
+ <tc:field flags="7" title="Composer" category="General" format="2" type="1" name="composer" i18n="true"/>
+ </xsl:if>
+ <xsl:if test="item/@producer">
+ <tc:field flags="7" title="Producer" category="General" format="2" type="1" name="producer" i18n="true"/>
+ </xsl:if>
+ <xsl:if test="@type='GCmusics' and item/@format">
+ <tc:field flags="7" title="Format" category="General" format="0" type="1" name="format" i18n="true"/>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="@type='GCfilms'">
+ <tc:field flags="8" title="Original Title" category="General" format="1" type="1" name="origtitle" i18n="true"/>
+ <tc:field flags="0" title="Seen" category="Personal" format="4" type="4" name="seen" i18n="true"/>
+ </xsl:when>
+ </xsl:choose>
+ </tc:fields>
+ <xsl:apply-templates select="item"/>
+ </tc:collection>
+</xsl:template>
+
+<xsl:template match="item">
+ <!-- For GCstar 1.2, the XML schema changed to use attributes for all
+ the 'simple' value types. The workaround here is to parse all
+ the attributes and elements. For each attribute, a dummy
+ element is created with the same name as the attribute, and
+ that dummy element is then parsed. This way, I can use the same
+ stylesheet for either format without having to repeat a lot
+ of XPath expression. -->
+ <!-- simplicity, the id will either be an attribute or an element -->
+ <tc:entry id="{concat(id,@id)}">
+ <xsl:apply-templates select="@*|*"/>
+ </tc:entry>
+</xsl:template>
+
+<xsl:template match="item/@*">
+ <xsl:variable name="dummies">
+ <xsl:element name="{local-name(.)}">
+ <xsl:value-of select="."/>
+ </xsl:element>
+ </xsl:variable>
+ <xsl:for-each select="exsl:node-set($dummies)/*">
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+</xsl:template>
+
+<!-- the easy one matches identical local names -->
+<xsl:template match="title|isbn|edition|pages|label|platform|location">
+ <xsl:element name="{concat('tc:',local-name())}">
+ <xsl:value-of select="."/>
+ </xsl:element>
+</xsl:template>
+
+<xsl:template match="original">
+ <tc:origtitle><xsl:value-of select="."/></tc:origtitle>
+</xsl:template>
+
+<xsl:template match="author|authors|language|genre|artist|composer|producer">
+ <xsl:variable name="tag">
+ <xsl:choose>
+ <xsl:when test="local-name() = 'authors'">
+ <xsl:text>author</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="local-name()"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="line">
+ <xsl:element name="{concat('tc:',$tag,'s')}">
+ <xsl:for-each select="line">
+ <xsl:element name="{concat('tc:',$tag)}">
+ <xsl:attribute name="i18n">true</xsl:attribute>
+ <xsl:value-of select="col[1]"/>
+ </xsl:element>
+ </xsl:for-each>
+ </xsl:element>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:element name="{concat('tc:',$tag)}">
+ <xsl:attribute name="i18n">true</xsl:attribute>
+ <xsl:value-of select="."/>
+ </xsl:element>
+ </xsl:otherwise>
+
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="format">
+ <xsl:choose>
+ <xsl:when test="$coll = 2">
+ <tc:binding i18n="true">
+ <xsl:choose>
+ <xsl:when test="contains(., 'Paperback')">
+ <xsl:text>Paperback</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="."/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </tc:binding>
+ </xsl:when>
+ <xsl:when test="$coll = 3">
+ <tc:medium i18n="true"><xsl:value-of select="."/></tc:medium>
+ </xsl:when>
+ <xsl:when test="$coll = 4">
+ <tc:format i18n="true"><xsl:value-of select="."/></tc:format>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="country">
+ <xsl:if test="$coll != 8">
+ <tc:nationalitys>
+ <xsl:for-each select="str:tokenize(., ',/;')">
+ <tc:nationality i18n="true">
+ <xsl:value-of select="normalize-space(.)"/>
+ </tc:nationality>
+ </xsl:for-each>
+ </tc:nationalitys>
+ </xsl:if>
+ <xsl:if test="$coll = 8">
+ <tc:country><xsl:value-of select="."/></tc:country>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="actors">
+ <tc:casts>
+ <xsl:for-each select="line">
+ <tc:cast>
+ <tc:column>
+ <xsl:value-of select="col[1]"/>
+ </tc:column>
+ <tc:column>
+ <xsl:value-of select="col[2]"/>
+ </tc:column>
+ </tc:cast>
+ </xsl:for-each>
+ </tc:casts>
+</xsl:template>
+
+<xsl:template match="director">
+ <tc:directors>
+ <tc:director>
+ <xsl:value-of select="."/>
+ </tc:director>
+ </tc:directors>
+</xsl:template>
+
+<xsl:template match="translator">
+ <tc:translators>
+ <tc:translator>
+ <xsl:value-of select="."/>
+ </tc:translator>
+ </tc:translators>
+</xsl:template>
+
+<xsl:template match="audio">
+ <tc:languages>
+ <xsl:for-each select="line">
+ <tc:language>
+ <xsl:value-of select="col[1]"/>
+ </tc:language>
+ </xsl:for-each>
+ </tc:languages>
+ <tc:audio-tracks>
+ <xsl:for-each select="line">
+ <tc:audio-track>
+ <xsl:value-of select="col[2]"/>
+ </tc:audio-track>
+ </xsl:for-each>
+ </tc:audio-tracks>
+</xsl:template>
+
+<xsl:template match="synopsis">
+ <tc:plot><xsl:value-of select="."/></tc:plot>
+</xsl:template>
+
+<xsl:template match="comment">
+ <tc:comments><xsl:value-of select="."/></tc:comments>
+</xsl:template>
+
+<xsl:template match="image|boxpic">
+ <tc:cover><xsl:value-of select="."/></tc:cover>
+</xsl:template>
+
+<xsl:template match="web|webPage">
+ <tc:url><xsl:value-of select="."/></tc:url>
+</xsl:template>
+
+<xsl:template match="rating">
+ <xsl:if test=". &gt; 0">
+ <tc:rating><xsl:value-of select="floor(. div 2)"/></tc:rating>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="age">
+ <tc:certification i18n="true">
+ <xsl:choose>
+ <xsl:when test=". = 1">
+ <xsl:text>U (USA)</xsl:text>
+ </xsl:when>
+ <xsl:when test=". = 2">
+ <xsl:text>G (USA)</xsl:text>
+ </xsl:when>
+ <xsl:when test=". &lt; 6">
+ <xsl:text>PG (USA)</xsl:text>
+ </xsl:when>
+ <xsl:when test=". &lt; 14">
+ <xsl:text>PG-13 (USA)</xsl:text>
+ </xsl:when>
+ <xsl:when test=". &lt; 18">
+ <xsl:text>R (USA)</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+ </tc:certification>
+</xsl:template>
+
+<xsl:template match="time">
+ <tc:running-time>
+ <xsl:value-of select="translate(.,translate(.,'0123456789',''),'')"/>
+ </tc:running-time>
+</xsl:template>
+
+<xsl:template match="video">
+ <tc:format i18n="true">
+ <xsl:value-of select="translate(.,'abcdefghijklmnopqrstuvwxyz',
+ 'ABCDEFGHIJKLMNOPQRSTUCWXYZ')"/>
+ </tc:format>
+</xsl:template>
+
+<xsl:template match="borrower">
+ <xsl:if test="string-length(.) &gt; 0 and . != 'none'">
+ <tc:loaned>true</tc:loaned>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="read">
+ <xsl:if test=". &gt; 0">
+ <tc:read>true</tc:read>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="seen">
+ <xsl:if test=". &gt; 0">
+ <tc:seen>true</tc:seen>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="favourite">
+ <xsl:if test=". &gt; 0">
+ <tc:favorite>true</tc:favorite>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="publication">
+ <tc:pub_year>
+ <xsl:call-template name="year">
+ <xsl:with-param name="value" select="."/>
+ </xsl:call-template>
+ </tc:pub_year>
+</xsl:template>
+
+<xsl:template match="aquisition">
+ <tc:pur_date><xsl:value-of select="."/></tc:pur_date>
+</xsl:template>
+
+<xsl:template match="added">
+ <xsl:if test="not(../acquisition)">
+ <tc:pur_date><xsl:value-of select="."/></tc:pur_date>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="serie">
+ <tc:series><xsl:value-of select="."/></tc:series>
+</xsl:template>
+
+<xsl:template match="comments">
+ <tc:comments>
+ <xsl:if test="$coll = 2">
+ &lt;br/&gt;
+ <xsl:value-of select="../description"/>
+ &lt;br/&gt;
+ </xsl:if>
+ <xsl:value-of select="."/>
+ </tc:comments>
+</xsl:template>
+
+<xsl:template match="description">
+ <xsl:if test="$coll != 2">
+ <tc:description><xsl:value-of select="."/></tc:description>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="year|date|release|released">
+ <tc:year>
+ <xsl:call-template name="year">
+ <xsl:with-param name="value" select="."/>
+ </xsl:call-template>
+ </tc:year>
+</xsl:template>
+
+<xsl:template match="tracks">
+ <tc:tracks>
+ <xsl:for-each select="line">
+ <tc:track>
+ <tc:column>
+ <xsl:value-of select="col[2]"/>
+ </tc:column>
+ <tc:column>
+ <xsl:value-of select="../../artist"/>
+ </tc:column>
+ <tc:column>
+ <xsl:value-of select="col[3]"/>
+ </tc:column>
+ </tc:track>
+ </xsl:for-each>
+ </tc:tracks>
+</xsl:template>
+
+<xsl:template match="name">
+ <tc:title><xsl:value-of select="."/></tc:title>
+</xsl:template>
+
+<xsl:template match="completion">
+ <xsl:if test=". &gt; 99">
+ <tc:completed>true</tc:completed>
+ </xsl:if>
+</xsl:template>
+<xsl:template match="*"/>
+
+<xsl:template match="editor|publisher">
+ <tc:publishers>
+ <tc:publisher>
+ <xsl:value-of select="."/>
+ </tc:publisher>
+ </tc:publishers>
+</xsl:template>
+
+<xsl:template match="tags">
+ <tc:keywords>
+ <xsl:for-each select="line">
+ <tc:keyword>
+ <xsl:value-of select="col[1]"/>
+ </tc:keyword>
+ </xsl:for-each>
+ </tc:keywords>
+</xsl:template>
+
+<xsl:template match="subt">
+ <tc:subtitles>
+ <xsl:for-each select="line">
+ <tc:subtitle>
+ <xsl:value-of select="col[1]"/>
+ </tc:subtitle>
+ </xsl:for-each>
+ </tc:subtitles>
+</xsl:template>
+
+<xsl:template match="currency">
+ <tc:type><xsl:value-of select="."/></tc:type>
+</xsl:template>
+
+<xsl:template match="value">
+ <tc:denomination><xsl:value-of select="."/></tc:denomination>
+</xsl:template>
+
+<xsl:template match="estimate">
+ <tc:pur_price><xsl:value-of select="."/></tc:pur_price>
+</xsl:template>
+
+<xsl:template match="front">
+ <tc:obverse><xsl:value-of select="."/></tc:obverse>
+</xsl:template>
+
+<xsl:template match="back">
+ <tc:reverse><xsl:value-of select="."/></tc:reverse>
+</xsl:template>
+
+<xsl:template match="publishedby">
+ <tc:publishers>
+ <xsl:for-each select="str:tokenize(., ',/;')">
+ <tc:publisher>
+ <xsl:value-of select="normalize-space(.)"/>
+ </tc:publisher>
+ </xsl:for-each>
+ </tc:publishers>
+</xsl:template>
+
+<xsl:template match="designedby">
+ <tc:designers>
+ <xsl:for-each select="str:tokenize(., ',/;')">
+ <tc:designer>
+ <xsl:value-of select="normalize-space(.)"/>
+ </tc:designer>
+ </xsl:for-each>
+ </tc:designers>
+</xsl:template>
+
+<xsl:template match="players">
+ <tc:num-players>
+ <!-- need to parse ranges, like 2-6 -->
+ <xsl:for-each select="str:tokenize(., ',/;')">
+ <tc:num-player>
+ <xsl:value-of select="normalize-space(.)"/>
+ </tc:num-player>
+ </xsl:for-each>
+ </tc:num-players>
+</xsl:template>
+
+<xsl:template name="year">
+ <xsl:param name="value"/>
+ <!-- want to find a 4-digit number to treat as the year -->
+ <xsl:variable name="nondigits" select="translate($value,'0123456789','')"/>
+ <xsl:choose>
+
+ <xsl:when test="string-length($nondigits) = 0">
+ <xsl:if test="string-length($value) = 4">
+ <xsl:value-of select="."/>
+ </xsl:if>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:for-each select="str:tokenize($value,$nondigits)">
+ <xsl:if test="string-length() = 4">
+ <xsl:value-of select="."/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:otherwise>
+
+ </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/hddvd-logo.png b/xslt/hddvd-logo.png
new file mode 100644
index 0000000..67da5ad
--- /dev/null
+++ b/xslt/hddvd-logo.png
Binary files differ
diff --git a/xslt/isbndb2tellico.xsl b/xslt/isbndb2tellico.xsl
new file mode 100644
index 0000000..c4152f6
--- /dev/null
+++ b/xslt/isbndb2tellico.xsl
@@ -0,0 +1,205 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://periapsis.org/tellico/"
+ xmlns:str="http://exslt.org/strings"
+ xmlns:exsl="http://exslt.org/common"
+ xmlns:l="uri:langs"
+ extension-element-prefixes="str exsl"
+ exclude-result-prefixes="l"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for importing data from isbndb.com
+
+ Copyright (C) 2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<l:langs>
+ <l:lang id="ara">Arabic</l:lang>
+ <l:lang id="cat">Catalan</l:lang>
+ <l:lang id="cze">Czech</l:lang>
+ <l:lang id="dut">Dutch</l:lang>
+ <l:lang id="eng">English</l:lang>
+ <l:lang id="fre">French</l:lang>
+ <l:lang id="ger">German</l:lang>
+ <l:lang id="dut">Dutch</l:lang>
+ <l:lang id="heb">Hebrew</l:lang>
+ <l:lang id="gre">Greek</l:lang>
+ <l:lang id="hin">Hindi</l:lang>
+ <l:lang id="hun">Hungarian</l:lang>
+ <l:lang id="ita">Italian</l:lang>
+ <l:lang id="jpn">Japanese</l:lang>
+ <l:lang id="kor">Korean</l:lang>
+ <l:lang id="lat">Latin</l:lang>
+ <l:lang id="lit">Lithuanian</l:lang>
+ <l:lang id="nob">Norwegian Bokm&#229;l</l:lang>
+ <l:lang id="nor">Norwegian</l:lang>
+ <l:lang id="nno">Norwegian Nynorsk</l:lang>
+ <l:lang id="pol">Polish</l:lang>
+ <l:lang id="por">Portuguese</l:lang>
+ <l:lang id="rus">Russian</l:lang>
+ <l:lang id="slo">Slovak</l:lang>
+ <l:lang id="spa">Spanish</l:lang>
+ <l:lang id="swe">Swedish</l:lang>
+ <l:lang id="chi">Chinese</l:lang>
+</l:langs>
+<xsl:key name="langs" match="l:lang" use="@id"/>
+<xsl:variable name="langs-top" select="document('')/*/l:langs"/>
+
+<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ doctype-public="-//Robby Stephenson/DTD Tellico V10.0//EN"
+ doctype-system="http://periapsis.org/tellico/dtd/v10/tellico.dtd"/>
+
+<xsl:template match="/">
+ <tellico syntaxVersion="10">
+ <collection title="ISBNdb.com Import" type="2">
+ <fields>
+ <field name="_default"/>
+ <!-- Here so that we can retrive the real publisher name later, gets removed inside Tellico -->
+ <field name="pub_id" flags="0" title="Publisher Key" category="Publishing" format="0" type="1"/>
+ </fields>
+ <xsl:apply-templates select="ISBNdb/BookList/BookData"/>
+ </collection>
+ </tellico>
+</xsl:template>
+
+<xsl:template match="BookData">
+ <entry>
+
+ <title>
+ <xsl:value-of select="Title"/>
+ </title>
+
+ <isbn>
+ <xsl:value-of select="@isbn"/>
+ </isbn>
+
+ <pub_id>
+ <xsl:value-of select="PublisherText/@publisher_id"/>
+ </pub_id>
+
+ <publisher>
+ <xsl:value-of select="PublisherText"/>
+ </publisher>
+
+ <authors>
+ <xsl:for-each select="Authors/Person">
+ <author>
+ <xsl:value-of select="."/>
+ </author>
+ </xsl:for-each>
+ </authors>
+
+ <keywords>
+ <xsl:for-each select="Subjects/Subject">
+ <xsl:variable name="subject-tokens1">
+ <xsl:call-template name="split-string">
+ <xsl:with-param name="string" select="."/>
+ <xsl:with-param name="pattern" select="' -- '"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="subject-tokens2">
+ <xsl:call-template name="token-union">
+ <xsl:with-param name="tokens" select="exsl:node-set($subject-tokens1)/*"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:for-each select="exsl:node-set($subject-tokens2)/*">
+ <keyword>
+ <xsl:value-of select="normalize-space()"/>
+ </keyword>
+ </xsl:for-each>
+ </xsl:for-each>
+ </keywords>
+
+ <comments>
+ <xsl:value-of select="Details/@physical_description_text"/>
+ <xsl:text>&lt;br/&gt;&lt;br/&gt;</xsl:text>
+ <xsl:value-of select="Summary"/>
+ <xsl:if test="string-length(Summary) &gt; 0 and string-length(Notes) &gt; 0">
+ <xsl:text>&lt;br/&gt;&lt;br/&gt;</xsl:text>
+ </xsl:if>
+ <xsl:value-of select="Notes"/>
+ </comments>
+
+ <xsl:variable name="binding">
+ <xsl:value-of select="substring-before(Details/@edition_info, ';')"/>
+ </xsl:variable>
+ <binding i18n="true">
+ <xsl:choose>
+ <xsl:when test="$binding='Hardcover'">
+ <xsl:text>Hardback</xsl:text>
+ </xsl:when>
+ <xsl:when test="contains($binding, 'Paperback')">
+ <xsl:text>Paperback</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$binding"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </binding>
+
+ <languages i18n="true">
+ <language>
+ <xsl:apply-templates select="$langs-top">
+ <xsl:with-param name="lang-id" select="Details/@language"/>
+ </xsl:apply-templates>
+ </language>
+ </languages>
+
+ </entry>
+</xsl:template>
+
+<xsl:template name="split-string">
+ <xsl:param name="string"/>
+ <xsl:param name="pattern"/>
+ <xsl:choose>
+ <xsl:when test="contains($string, $pattern)">
+ <xsl:if test="not(starts-with($string, $pattern))">
+ <token>
+ <xsl:value-of select="substring-before($string, $pattern)"/>
+ </token>
+ </xsl:if>
+ <xsl:call-template name="split-string">
+ <xsl:with-param name="string" select="substring-after($string, $pattern)"/>
+ <xsl:with-param name="pattern" select="$pattern"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <token>
+ <xsl:value-of select="$string"/>
+ </token>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="token-union">
+ <xsl:param name="tokens"/>
+ <xsl:choose>
+ <xsl:when test="not($tokens)"/>
+ <xsl:otherwise>
+ <xsl:copy-of select="exsl:node-set(str:tokenize($tokens[1], ','))"/>
+ <xsl:call-template name="token-union">
+ <xsl:with-param name="tokens" select="$tokens[position() &gt; 1]"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="l:langs">
+ <xsl:param name="lang-id"/>
+ <xsl:variable name="l" select="key('langs', $lang-id)"/>
+ <xsl:if test="$l">
+ <xsl:value-of select="$l"/>
+ </xsl:if>
+ <xsl:if test="not($l)">
+ <xsl:value-of select="$lang-id"/>
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/mods2tellico.xsl b/xslt/mods2tellico.xsl
new file mode 100644
index 0000000..d471498
--- /dev/null
+++ b/xslt/mods2tellico.xsl
@@ -0,0 +1,521 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://periapsis.org/tellico/"
+ xmlns:mods="http://www.loc.gov/mods/v3"
+ xmlns:l="uri:langs"
+ exclude-result-prefixes="mods l"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for importing MODS files.
+
+ Copyright (C) 2004-2008 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<!-- lookup table for languages -->
+<!-- according to http://www.oasis-open.org/cover/iso639-2-en971019.html -->
+<!-- I just added common ones -->
+<l:langs>
+ <l:lang id="ara">Arabic</l:lang>
+ <l:lang id="cat">Catalan</l:lang>
+ <l:lang id="cze">Czech</l:lang>
+ <l:lang id="dut">Dutch</l:lang>
+ <l:lang id="eng">English</l:lang>
+ <l:lang id="fre">French</l:lang>
+ <l:lang id="ger">German</l:lang>
+ <l:lang id="dut">Dutch</l:lang>
+ <l:lang id="heb">Hebrew</l:lang>
+ <l:lang id="gre">Greek</l:lang>
+ <l:lang id="hin">Hindi</l:lang>
+ <l:lang id="hun">Hungarian</l:lang>
+ <l:lang id="ita">Italian</l:lang>
+ <l:lang id="jpn">Japanese</l:lang>
+ <l:lang id="kor">Korean</l:lang>
+ <l:lang id="lat">Latin</l:lang>
+ <l:lang id="lit">Lithuanian</l:lang>
+ <l:lang id="nob">Norwegian Bokm&#229;l</l:lang>
+ <l:lang id="nor">Norwegian</l:lang>
+ <l:lang id="nno">Norwegian Nynorsk</l:lang>
+ <l:lang id="pol">Polish</l:lang>
+ <l:lang id="por">Portuguese</l:lang>
+ <l:lang id="rus">Russian</l:lang>
+ <l:lang id="slo">Slovak</l:lang>
+ <l:lang id="spa">Spanish</l:lang>
+ <l:lang id="swe">Swedish</l:lang>
+ <l:lang id="chi">Chinese</l:lang>
+</l:langs>
+<xsl:key name="langs" match="l:lang" use="@id"/>
+<xsl:variable name="langs-top" select="document('')/*/l:langs"/>
+
+<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ doctype-public="-//Robby Stephenson/DTD Tellico V10.0//EN"
+ doctype-system="http://periapsis.org/tellico/dtd/v10/tellico.dtd"/>
+
+<!-- for now, it's a bibtex collection if it has an identifier,
+ book collection if not -->
+<xsl:variable name="type">
+ <xsl:choose>
+ <xsl:when test="count(//mods:mods[string-length(@ID)&gt;0 or mods:identifier[@type='citekey']]) &gt; 0">
+ <xsl:text>bibtex</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>book</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:variable>
+
+<xsl:variable name="npubs">
+ <xsl:value-of select="count(//mods:originInfo[count(mods:publisher) &gt; 1])"/>
+</xsl:variable>
+
+<!-- disable default behavior -->
+<xsl:template match="text()|@*"></xsl:template>
+
+<xsl:template match="/">
+ <tellico syntaxVersion="10">
+ <collection title="MODS Import">
+ <xsl:attribute name="type">
+ <xsl:choose>
+ <xsl:when test="$type='bibtex'">
+ <xsl:text>5</xsl:text>
+ </xsl:when>
+ <xsl:when test="$type='book'">
+ <xsl:text>2</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+ <fields>
+ <field name="_default"/>
+ <!-- the default collection does not have multiple publishers -->
+ <xsl:if test="$npubs &gt; 1">
+ <field flags="7" title="Publisher" category="Publishing" format="0" type="1" name="publisher" i18n="true">
+ <prop name="bibtex">publisher</prop>
+ </field>
+ </xsl:if>
+ <!-- default book collection does not include an abstract -->
+ <xsl:if test="$type='book' and .//mods:mods/mods:abstract">
+ <field flags="0" title="Abstract" format="4" type="2" name="abstract" i18n="true">
+ <prop name="bibtex">abstract</prop>
+ </field>
+ </xsl:if>
+ <!-- default book collection does not include an address -->
+ <xsl:if test="$type='book' and .//mods:originInfo/mods:place/mods:placeTerm[@type='text']">
+ <field flags="6" title="Address" category="Publishing" format="4" type="1" name="address" i18n="true">
+ <prop name="bibtex">address</prop>
+ </field>
+ </xsl:if>
+ <!-- add illustrator -->
+ <xsl:if test=".//mods:mods/mods:name[@type='personal']/mods:role/mods:roleTerm[@authority='marcrelator' and @type='code'] = 'ill.'">
+ <field flags="7" title="Illustrator" category="General" format="2" type="1" name="illustrator" i18n="true"/>
+ </xsl:if>
+ <xsl:if test=".//mods:identifier[@type='issn']">
+ <field flags="0" title="ISSN#" category="Publishing" format="4" type="1" name="issn" description="ISSN#" />
+ </xsl:if>
+ </fields>
+<!-- for now, go the route of bibliox, and assume only text records
+ with an originInfo/publisher or identifier[isbn] elements are actually books -->
+<!-- Changed in Tellico 1.1, don't be so strict about the text thing, not every library
+ includes that in the mods output, so just check for publisher
+ Changed in Tellico 1.2.9, allow anything that has typeOfResource='text'
+ //mods:mods[(mods:typeOfResource='text' and -->
+ <xsl:for-each select=".//mods:mods[ mods:typeOfResource='text' or
+ mods:originInfo/mods:publisher or
+ mods:identifier[@type='isbn'] or
+ mods:identifier[@type='lccn'] ]">
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+ </collection>
+ </tellico>
+</xsl:template>
+
+<xsl:template match="mods:mods">
+ <entry>
+
+ <xsl:if test="$type='bibtex'">
+ <entry-type>
+ <xsl:choose>
+ <xsl:when test="mods:genre[@authority='xbib']='article'">
+ <xsl:text>article</xsl:text>
+ </xsl:when>
+ <xsl:when test="mods:genre[@authority='xbib']='book'">
+ <xsl:text>book</xsl:text>
+ </xsl:when>
+ <xsl:when test="mods:identifier[@type='isbn']">
+ <xsl:text>book</xsl:text>
+ </xsl:when>
+ <xsl:when test="mods:genre[@authority='marc']='theses'">
+ <xsl:text>phdthesis</xsl:text>
+ </xsl:when>
+ <xsl:when test="mods:relatedItem[@type='host']/mods:genre[@authority='marc']='periodical'">
+ <xsl:text>article</xsl:text>
+ </xsl:when>
+ <xsl:when test="mods:relatedItem[@type='host']/mods:genre[@authority='marc']='book'">
+ <xsl:text>inbook</xsl:text>
+ </xsl:when>
+ <xsl:when test="mods:relatedItem[@type='host']/mods:name[@type='conference']">
+ <xsl:text>inproceedings</xsl:text>
+ </xsl:when>
+ <xsl:when test="mods:relatedItem[@type='host']">
+ <xsl:text>incollection</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>book</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </entry-type>
+
+ <!-- identifier overrides @ID -->
+ <xsl:for-each select="(mods:identifier[@type='citekey']|@ID)[1]">
+ <bibtex-key>
+ <xsl:value-of select="."/>
+ </bibtex-key>
+ </xsl:for-each>
+ </xsl:if>
+
+ <title>
+ <xsl:value-of select="mods:titleInfo/mods:nonSort"/>
+ <xsl:value-of select="mods:titleInfo/mods:title"/>
+ </title>
+
+ <xsl:call-template name="names">
+ <xsl:with-param name="elem" select="'author'"/>
+ <xsl:with-param name="nodes" select="mods:name[mods:role/mods:roleTerm[@authority='marcrelator' and @type='text'] = 'author' or
+ mods:role/mods:roleTerm[@authority='marcrelator' and @type='text'] = 'creator']"/>
+ </xsl:call-template>
+
+ <xsl:call-template name="names">
+ <xsl:with-param name="elem" select="'editor'"/>
+ <xsl:with-param name="nodes" select="mods:name[mods:role/mods:roleTerm[@authority='marcrelator' and @type='text'] = 'editor']"/>
+ </xsl:call-template>
+
+ <xsl:call-template name="names">
+ <xsl:with-param name="elem" select="'illustrator'"/>
+ <xsl:with-param name="nodes" select="mods:name[mods:role/mods:roleTerm[@authority='marcrelator' and @type='code'] = 'ill.']"/>
+ </xsl:call-template>
+
+ <genres i18n="true">
+ <xsl:for-each select="mods:genre">
+ <genre>
+ <xsl:value-of select="."/>
+ </genre>
+ </xsl:for-each>
+ </genres>
+
+ <xsl:choose>
+ <xsl:when test="$npubs &gt; 1">
+ <publishers>
+ <xsl:apply-templates select="mods:originInfo/mods:publisher"/>
+ </publishers>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="mods:originInfo/mods:publisher"/>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <!-- prefer the marc encoding for year -->
+ <!-- force numbers...is that ok? -->
+ <xsl:variable name="year-type">
+ <xsl:choose>
+ <xsl:when test="$type='bibtex'">
+ <xsl:text>year</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>pub_year</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="mods:originInfo/mods:dateIssued[@encoding='marc']">
+ <xsl:element name="{$year-type}">
+ <xsl:call-template name="numbers">
+ <xsl:with-param name="value" select="mods:originInfo/mods:dateIssued[@encoding='marc'][1]"/>
+ </xsl:call-template>
+ </xsl:element>
+ </xsl:when>
+ <xsl:when test="mods:originInfo/mods:dateIssued">
+ <xsl:element name="{$year-type}">
+ <xsl:call-template name="numbers">
+ <xsl:with-param name="value" select="mods:originInfo/mods:dateIssued[1]"/>
+ </xsl:call-template>
+ </xsl:element>
+ </xsl:when>
+ </xsl:choose>
+
+ <languages i18n="true">
+ <xsl:for-each select="mods:language/mods:languageTerm">
+ <language>
+ <xsl:apply-templates select="$langs-top">
+ <xsl:with-param name="lang-id" select="text()"/>
+ </xsl:apply-templates>
+ </language>
+ </xsl:for-each>
+ </languages>
+
+ <comments>
+ <xsl:for-each select="mods:note | mods:physicalDescription/*">
+ <xsl:value-of select="."/>
+ <!-- add separating line, Tellico understands HTML now -->
+ <xsl:text>&lt;br/&gt;&lt;br/&gt;</xsl:text>
+ </xsl:for-each>
+ </comments>
+
+ <keywords i18n="true">
+ <xsl:for-each select="mods:subject/mods:topic">
+ <keyword>
+ <xsl:value-of select="."/>
+ </keyword>
+ </xsl:for-each>
+ </keywords>
+
+ <xsl:apply-templates select="mods:relatedItem[@type='host'] |
+ mods:relatedItem[@type='series'] |
+ mods:part |
+ mods:identifier |
+ mods:subTitle |
+ mods:note |
+ mods:abstract |
+ mods:originInfo/mods:place |
+ mods:originInfo/mods:copyrightDate |
+ mods:originInfo/mods:edition |
+ mods:location/mods:url"/>
+
+ </entry>
+</xsl:template>
+
+<xsl:template match="mods:relatedItem">
+ <xsl:variable name="elem">
+ <xsl:choose>
+ <xsl:when test="@type='series'">
+ <xsl:text>series</xsl:text>
+ </xsl:when>
+ <xsl:when test="mods:genre[@authority='marc']='periodical'">
+ <xsl:text>journal</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>booktitle</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:element name="{$elem}">
+ <xsl:value-of select="mods:titleInfo/mods:nonSort"/>
+ <xsl:value-of select="mods:titleInfo/mods:title"/>
+ <xsl:if test="not(mods:titleInfo) and mods:name[@type='conference']">
+ <xsl:apply-templates select="mods:name[@type='conference']"/>
+ </xsl:if>
+ </xsl:element>
+
+ <xsl:call-template name="names">
+ <xsl:with-param name="elem" select="'editor'"/>
+ <xsl:with-param name="nodes" select="mods:name[mods:role/mods:roleTerm[@authority='marcrelator' and @type='text'] = 'editor']"/>
+ </xsl:call-template>
+
+ <xsl:choose>
+ <xsl:when test="$npubs &gt; 1">
+ <publishers>
+ <xsl:apply-templates select="mods:originInfo/mods:publisher"/>
+ </publishers>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="mods:originInfo/mods:publisher"/>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:choose>
+ <xsl:when test="mods:originInfo/mods:dateIssued[@encoding='marc']">
+ <year>
+ <xsl:call-template name="numbers">
+ <xsl:with-param name="value" select="mods:originInfo/mods:dateIssued[@encoding='marc'][1]"/>
+ </xsl:call-template>
+ </year>
+ </xsl:when>
+ <xsl:when test="mods:originInfo/mods:dateIssued">
+ <year>
+ <xsl:call-template name="numbers">
+ <xsl:with-param name="value" select="mods:originInfo/mods:dateIssued[1]"/>
+ </xsl:call-template>
+ </year>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:apply-templates select="mods:part |
+ mods:originInfo/mods:place |
+ mods:identifier |
+ mods:part |
+ mods:location/mods:url"/>
+
+</xsl:template>
+
+<xsl:template match="mods:part">
+ <xsl:apply-templates select="mods:detail | mods:extent"/>
+</xsl:template>
+
+<xsl:template name="names">
+ <xsl:param name="elem"/>
+ <xsl:param name="nodes"/>
+ <xsl:if test="$nodes">
+ <xsl:element name="{concat($elem,'s')}">
+ <xsl:for-each select="$nodes">
+ <xsl:element name="{$elem}">
+ <xsl:apply-templates select="."/>
+ </xsl:element>
+ </xsl:for-each>
+ </xsl:element>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="mods:name">
+ <!-- specific order -->
+ <xsl:apply-templates select="mods:namePart[@type='given']"/>
+ <xsl:apply-templates select="mods:namePart[@type='family']"/>
+ <xsl:apply-templates select="mods:namePart[not(@type)]"/>
+</xsl:template>
+
+<xsl:template match="mods:namePart">
+ <xsl:value-of select="."/>
+ <!-- assume single-character name parts are initials -->
+ <xsl:if test="string-length()=1">
+ <xsl:text>.</xsl:text>
+ </xsl:if>
+ <xsl:text> </xsl:text>
+</xsl:template>
+
+<xsl:template match="mods:identifier">
+ <xsl:choose>
+ <xsl:when test="@type='isbn'">
+ <isbn>
+ <xsl:value-of select="."/>
+ </isbn>
+ </xsl:when>
+ <xsl:when test="@type='lccn'">
+ <lccn>
+ <xsl:value-of select="."/>
+ </lccn>
+ </xsl:when>
+ <xsl:when test="@type='doi'">
+ <doi>
+ <xsl:value-of select="."/>
+ </doi>
+ </xsl:when>
+ <xsl:when test="@type='issn'">
+ <issn>
+ <xsl:value-of select="."/>
+ </issn>
+ </xsl:when>
+ <xsl:when test="@type='uri'">
+ <url>
+ <xsl:value-of select="."/>
+ </url>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="mods:subTitle">
+ <subtitle>
+ <xsl:value-of select="."/>
+ </subtitle>
+</xsl:template>
+
+<xsl:template match="mods:publisher">
+ <publisher>
+ <xsl:value-of select="."/>
+ </publisher>
+</xsl:template>
+
+<xsl:template match="mods:copyrightDate">
+ <cr_year>
+ <xsl:call-template name="numbers">
+ <xsl:with-param name="value" select="."/>
+ </xsl:call-template>
+ </cr_year>
+</xsl:template>
+
+<xsl:template match="mods:abstract">
+ <abstract>
+ <xsl:value-of select="."/>
+ </abstract>
+</xsl:template>
+
+<xsl:template match="mods:edition">
+ <edition i18n="true">
+ <xsl:value-of select="."/>
+ </edition>
+</xsl:template>
+
+<xsl:template match="mods:url">
+ <url>
+ <xsl:value-of select="."/>
+ </url>
+</xsl:template>
+
+<xsl:template match="mods:note">
+ <note>
+ <xsl:value-of select="."/>
+ </note>
+</xsl:template>
+
+<xsl:template match="mods:place">
+ <address>
+ <xsl:value-of select="mods:placeTerm[@type='text' or not(@type)][1]"/>
+ </address>
+</xsl:template>
+
+<xsl:template match="mods:detail">
+ <xsl:choose>
+ <xsl:when test="@type='volume'">
+ <volume>
+ <xsl:value-of select="mods:number"/>
+ </volume>
+ </xsl:when>
+ <xsl:when test="@type='issue'">
+ <number>
+ <xsl:value-of select="mods:number"/>
+ </number>
+ </xsl:when>
+ <xsl:when test="@type='number'">
+ <number>
+ <xsl:value-of select="mods:number"/>
+ </number>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="mods:extent">
+ <xsl:if test="@unit='page'">
+ <pages>
+ <xsl:choose>
+ <xsl:when test="mods:start and mods:end">
+ <xsl:value-of select="concat(mods:start,'-',mods:end)"/>
+ </xsl:when>
+ <xsl:when test="mods:list">
+ <xsl:value-of select="mods:list"/>
+ </xsl:when>
+ </xsl:choose>
+ </pages>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template name="numbers">
+ <xsl:param name="value"/>
+ <xsl:value-of select="translate($value, translate($value, '0123456789', ''), '')"/>
+</xsl:template>
+
+<xsl:template match="l:langs">
+ <xsl:param name="lang-id"/>
+ <xsl:variable name="l" select="key('langs', $lang-id)"/>
+ <xsl:if test="$l">
+ <xsl:value-of select="$l"/>
+ </xsl:if>
+ <xsl:if test="not($l)">
+ <xsl:value-of select="$lang-id"/>
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/pubmed2tellico.xsl b/xslt/pubmed2tellico.xsl
new file mode 100644
index 0000000..3f32ec6
--- /dev/null
+++ b/xslt/pubmed2tellico.xsl
@@ -0,0 +1,190 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://periapsis.org/tellico/"
+ xmlns:m="uri:months"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for importing PubMed data.
+
+ Copyright (C) 2005 Michaël Zugaro <michael.zugaro@college-de-france.fr>
+ 2005-2006 Robby Stephenson <robby@periapsis.org>
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<!-- lookup table for months -->
+<m:months>
+ <m:month id="Jan">1</m:month>
+ <m:month id="Feb">2</m:month>
+ <m:month id="Mar">3</m:month>
+ <m:month id="Apr">4</m:month>
+ <m:month id="May">5</m:month>
+ <m:month id="Jun">6</m:month>
+ <m:month id="Jul">7</m:month>
+ <m:month id="Aug">8</m:month>
+ <m:month id="Sep">9</m:month>
+ <m:month id="Oct">10</m:month>
+ <m:month id="Nov">11</m:month>
+ <m:month id="Dec">12</m:month>
+ <!-- months in other languages could be added easily -->
+</m:months>
+<xsl:key name="months" match="m:month" use="@id"/>
+<xsl:variable name="months-top" select="document('')/*/m:months"/>
+
+<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ doctype-public="-//Robby Stephenson/DTD Tellico V10.0//EN"
+ doctype-system="http://periapsis.org/tellico/dtd/v10/tellico.dtd"/>
+
+<xsl:template match="/">
+ <tellico syntaxVersion="10">
+ <collection title="PubMed Import" type="5">
+ <fields>
+ <field name="_default"/>
+ <field flags="0" title="Institution" category="Institution" format="4" type="2" name="institution" i18n="true">
+ <prop name="bibtex">institution</prop>
+ </field>
+ <field flags="0" title="Pubmed" category="Publishing" format="4" type="1" name="pmid" description="Pubmed" i18n="true" />
+ </fields>
+ <xsl:apply-templates select="/PubmedArticleSet/PubmedArticle"/>
+ </collection>
+ </tellico>
+</xsl:template>
+
+<xsl:template match="PubmedArticle">
+ <entry>
+ <xsl:apply-templates select="MedlineCitation"/>
+ <xsl:apply-templates select="PubmedData"/>
+ </entry>
+</xsl:template>
+
+<xsl:template match="MedlineCitation">
+ <entry-type>
+ <xsl:text>article</xsl:text>
+ </entry-type>
+
+ <volume>
+ <xsl:value-of select="Article/Journal/JournalIssue/Volume"/>
+ </volume>
+
+ <number>
+ <xsl:value-of select="Article/Journal/JournalIssue/Issue"/>
+ </number>
+
+ <xsl:variable name="year">
+ <xsl:variable name="year1" select="Article/Journal/JournalIssue/PubDate/Year"/>
+ <xsl:variable name="year2" select="Article/Journal/JournalIssue/PubDate/MedlineDate"/>
+ <xsl:choose>
+ <xsl:when test="string-length($year1) != 0">
+ <xsl:value-of select="$year1"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="substring($year2,1,4)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <year>
+ <xsl:value-of select="$year"/>
+ </year>
+
+ <month>
+ <xsl:apply-templates select="$months-top">
+ <xsl:with-param name="month-id" select="Article/Journal/JournalIssue/PubDate/Month"/>
+ </xsl:apply-templates>
+ </month>
+
+ <title>
+ <xsl:value-of select="Article/ArticleTitle"/>
+ </title>
+
+ <pages>
+ <xsl:value-of select="Article/Pagination/MedlinePgn"/>
+ </pages>
+
+ <abstract>
+ <xsl:value-of select="Article/Abstract/AbstractText"/>
+ </abstract>
+
+ <institution>
+ <xsl:value-of select="Article/Affiliation"/>
+ </institution>
+
+ <authors>
+ <xsl:for-each select="Article/AuthorList/Author">
+ <author>
+ <xsl:choose>
+ <xsl:when test="ForeName">
+ <xsl:value-of select="concat(ForeName, ' ')"/>
+ </xsl:when>
+ <xsl:when test="FirstName">
+ <xsl:value-of select="concat(FirstName, ' ')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="TransformInitials">
+ <xsl:with-param name="initials" select="Initials"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:value-of select="LastName"/>
+ </author>
+ </xsl:for-each>
+ </authors>
+
+ <journal>
+ <xsl:if test="Article/Journal/Title">
+ <xsl:value-of select="Article/Journal/Title"/>
+ </xsl:if>
+ <xsl:if test="not(Article/Journal/Title)">
+ <xsl:value-of select="MedlineJournalInfo/MedlineTA"/>
+ </xsl:if>
+ </journal>
+
+ <keywords>
+ <xsl:for-each select="MeshHeadingList/MeshHeading/QualifierName[@MajorTopicYN='Y'] | MeshHeadingList/MeshHeading/DescriptorName">
+ <keyword>
+ <xsl:value-of select="."/>
+ </keyword>
+ </xsl:for-each>
+ </keywords>
+
+ <pmid>
+ <xsl:value-of select="PMID"/>
+ </pmid>
+
+</xsl:template>
+
+<xsl:template match="PubmedData">
+ <doi>
+ <xsl:value-of select="ArticleIdList/ArticleId[@IdType='doi']"/>
+ </doi>
+</xsl:template>
+
+<xsl:template name="TransformInitials">
+ <xsl:param name="initials"/>
+ <xsl:variable name="n" select="string-length($initials)"/>
+ <xsl:if test="$n &gt;= 1">
+ <xsl:value-of select="substring($initials,1,1)"/>
+ <xsl:text>. </xsl:text>
+ <xsl:call-template name="TransformInitials">
+ <xsl:with-param name="initials" select="substring($initials,2,$n - 1)"/>
+ </xsl:call-template>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="m:months">
+ <xsl:param name="month-id"/>
+ <xsl:variable name="m" select="key('months', $month-id)"/>
+ <xsl:if test="$m">
+ <xsl:value-of select="$m"/>
+ </xsl:if>
+ <xsl:if test="not($m)">
+ <xsl:value-of select="$month-id"/>
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/record-logo.png b/xslt/record-logo.png
new file mode 100644
index 0000000..956c03e
--- /dev/null
+++ b/xslt/record-logo.png
Binary files differ
diff --git a/xslt/referencer2tellico.xsl b/xslt/referencer2tellico.xsl
new file mode 100644
index 0000000..5bb90be
--- /dev/null
+++ b/xslt/referencer2tellico.xsl
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://periapsis.org/tellico/"
+ xmlns:str="http://exslt.org/strings"
+ xmlns:exsl="http://exslt.org/common"
+ extension-element-prefixes="str exsl"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for importing data Referencer
+
+ Copyright (C) 2007 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ doctype-public="-//Robby Stephenson/DTD Tellico V10.0//EN"
+ doctype-system="http://periapsis.org/tellico/dtd/v10/tellico.dtd"/>
+
+<xsl:key name="tags" match="/library/taglist/tag" use="uid"/>
+
+<xsl:template match="/">
+ <tellico syntaxVersion="10">
+ <collection title="Referencer Import" type="5">
+ <fields>
+ <field name="_default"/>
+ </fields>
+ <xsl:apply-templates select="library/doclist/doc"/>
+ </collection>
+ </tellico>
+</xsl:template>
+
+<xsl:template match="doc">
+ <entry>
+
+ <title>
+ <xsl:value-of select="bib_title"/>
+ </title>
+
+ <entry-type>
+ <xsl:value-of select="translate(bib_type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ 'abcdefghijklmnopqrstuvwxyz')"/>
+ </entry-type>
+
+ <bibtex-key>
+ <xsl:value-of select="key"/>
+ </bibtex-key>
+
+ <year>
+ <xsl:value-of select="bib_year"/>
+ </year>
+
+ <doi>
+ <xsl:value-of select="bib_doi"/>
+ </doi>
+
+ <pages>
+ <xsl:value-of select="bib_pages"/>
+ </pages>
+
+ <journal>
+ <xsl:value-of select="bib_journal"/>
+ </journal>
+
+ <number>
+ <xsl:value-of select="bib_number"/>
+ </number>
+
+ <volume>
+ <xsl:value-of select="bib_volume"/>
+ </volume>
+
+ <url>
+ <xsl:value-of select="filename"/>
+ </url>
+
+ <authors>
+ <xsl:for-each select="str:tokenize(bib_authors, ',/;')">
+ <xsl:call-template name="author_split">
+ <xsl:with-param name="value" select="."/>
+ </xsl:call-template>
+ </xsl:for-each>
+ </authors>
+
+ <keywords>
+ <xsl:for-each select="tagged">
+ <keyword i18n="true">
+ <xsl:value-of select="key('tags', .)/name"/>
+ </keyword>
+ </xsl:for-each>
+ </keywords>
+
+</entry>
+
+</xsl:template>
+
+<xsl:template name="author_split">
+ <xsl:param name="value"/>
+ <xsl:if test="string-length($value) &gt; 0">
+ <xsl:variable name="before" select="substring-before($value, ' and ')"/>
+ <author>
+ <xsl:if test="string-length($before) &gt; 0">
+ <xsl:value-of select="normalize-space($before)"/>
+ </xsl:if>
+ <xsl:if test="string-length($before) = 0">
+ <xsl:value-of select="normalize-space($value)"/>
+ </xsl:if>
+ </author>
+ <xsl:call-template name="author_split">
+ <xsl:with-param name="value" select="substring-after($value, ' and ')"/>
+ </xsl:call-template>
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/report-templates/Column_View.xsl b/xslt/report-templates/Column_View.xsl
new file mode 100644
index 0000000..3b007fe
--- /dev/null
+++ b/xslt/report-templates/Column_View.xsl
@@ -0,0 +1,310 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ xmlns:str="http://exslt.org/strings"
+ xmlns:dyn="http://exslt.org/dynamic"
+ extension-element-prefixes="str dyn"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - Column View Report
+
+ Copyright (C) 2005-2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="../tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<xsl:param name="filename"/>
+<xsl:param name="cdate"/>
+
+<!-- To choose which fields of each entry are printed, change the
+ string to a space separated list of field names. To know what
+ fields are available, check the Tellico data file for <field>
+ elements. -->
+<xsl:param name="column-names" select="'title'"/>
+<xsl:variable name="columns" select="str:tokenize($column-names)"/>
+
+<!-- set the maximum image size -->
+<xsl:param name="image-height" select="'100'"/>
+<xsl:param name="image-width" select="'100'"/>
+
+<!-- Up to three fields may be used for sorting. -->
+<xsl:param name="sort-name1" select="'title'"/>
+<xsl:param name="sort-name2" select="''"/>
+<xsl:param name="sort-name3" select="''"/>
+<!-- This is the title just beside the collection name. It will
+ automatically list which fields are used for sorting. -->
+<xsl:param name="sort-title" select="''"/>
+<!-- Sort using user's preferred language -->
+<xsl:param name="lang"/>
+
+<xsl:param name="datadir"/> <!-- dir where Tellico data files are located -->
+<xsl:param name="imgdir"/> <!-- dir where field images are located -->
+
+<xsl:key name="fieldsByName" match="tc:field" use="@name"/>
+<xsl:key name="imagesById" match="tc:image" use="@id"/>
+
+<!-- In case the field has multiple values, only sort by first one -->
+<xsl:variable name="sort1">
+ <xsl:if test="string-length($sort-name1) &gt; 0">
+ <xsl:value-of select="concat('.//tc:', $sort-name1, '[1]')"/>
+ </xsl:if>
+</xsl:variable>
+
+<xsl:variable name="sort1-type">
+ <xsl:choose>
+ <xsl:when test=".//tc:field[@name=$sort-name1]/@type = 6">number</xsl:when>
+ <xsl:otherwise>text</xsl:otherwise>
+ </xsl:choose>
+</xsl:variable>
+
+<xsl:variable name="sort2">
+ <xsl:if test="string-length($sort-name2) &gt; 0">
+ <xsl:value-of select="concat('.//tc:', $sort-name2, '[1]')"/>
+ </xsl:if>
+</xsl:variable>
+
+<xsl:variable name="sort2-type">
+ <xsl:choose>
+ <xsl:when test=".//tc:field[@name=$sort-name2]/@type = 6">number</xsl:when>
+ <xsl:otherwise>text</xsl:otherwise>
+ </xsl:choose>
+</xsl:variable>
+
+<xsl:variable name="sort3">
+ <xsl:if test="string-length($sort-name3) &gt; 0">
+ <xsl:value-of select="concat('.//tc:', $sort-name3, '[1]')"/>
+ </xsl:if>
+</xsl:variable>
+
+<xsl:variable name="sort3-type">
+ <xsl:choose>
+ <xsl:when test=".//tc:field[@name=$sort-name3]/@type = 6">number</xsl:when>
+ <xsl:otherwise>text</xsl:otherwise>
+ </xsl:choose>
+</xsl:variable>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<xsl:template match="tc:tellico">
+ <html>
+ <head>
+ <style type="text/css">
+ body {
+ font-family: sans-serif;
+ <xsl:if test="count($columns) &gt; 3">
+ font-size: 80%;
+ </xsl:if>
+ background-color: #fff;
+ }
+ #header-left {
+ margin-top: 0;
+ float: left;
+ font-size: 80%;
+ font-style: italic;
+ }
+ #header-right {
+ margin-top: 0;
+ float: right;
+ font-size: 80%;
+ font-style: italic;
+ }
+ h1.colltitle {
+ margin: 0px;
+ padding-bottom: 5px;
+ font-size: 2em;
+ text-align: center;
+ }
+ table {
+ margin-left: auto;
+ margin-right: auto;
+ }
+ th {
+ color: #000;
+ background-color: #ccc;
+ border: 1px solid #999;
+ font-size: 1.1em;
+ font-weight: bold;
+ padding-left: 4px;
+ padding-right: 4px;
+ }
+ tr.r0 {
+ }
+ tr.r1 {
+ background-color: #eee;
+ }
+ td.field {
+ margin-left: 0px;
+ margin-right: 0px;
+ padding-left: 10px;
+ padding-right: 5px;
+ border: 1px solid #eee;
+ text-align: left;
+ }
+ </style>
+ <title>Tellico</title>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection"/>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="tc:collection">
+ <p id="header-left"><xsl:value-of select="$filename"/></p>
+ <p id="header-right"><xsl:value-of select="$cdate"/></p>
+ <h1 class="colltitle">
+ <xsl:value-of select="@title"/>
+ </h1>
+
+ <table>
+ <!-- always print headers -->
+ <thead>
+ <tr>
+ <xsl:variable name="fields" select="tc:fields"/>
+ <xsl:for-each select="$columns">
+ <th>
+ <xsl:call-template name="field-title">
+ <xsl:with-param name="fields" select="$fields"/>
+ <xsl:with-param name="name" select="."/>
+ </xsl:call-template>
+ </th>
+ </xsl:for-each>
+ </tr>
+ </thead>
+
+ <tbody>
+ <xsl:for-each select="tc:entry">
+ <xsl:sort lang="$lang" select="dyn:evaluate($sort1)" data-type="{$sort1-type}"/>
+ <xsl:sort lang="$lang" select="dyn:evaluate($sort2)" data-type="{$sort2-type}"/>
+ <xsl:sort lang="$lang" select="dyn:evaluate($sort3)" data-type="{$sort3-type}"/>
+ <tr class="r{position() mod 2}">
+ <xsl:apply-templates select="."/>
+ </tr>
+ </xsl:for-each>
+ </tbody>
+ </table>
+</xsl:template>
+
+<xsl:template name="field-title">
+ <xsl:param name="fields"/>
+ <xsl:param name="name"/>
+ <!-- remove namespace portion of qname -->
+ <xsl:variable name="name-tokens" select="str:tokenize($name, ':')"/>
+ <!-- the header is the title attribute of the field node whose
+ name equals the column name -->
+ <xsl:value-of select="$fields/tc:field[@name = $name-tokens[last()]]/@title"/>
+</xsl:template>
+
+<xsl:template match="tc:entry">
+ <!-- stick all the descendants into a variable -->
+ <xsl:variable name="current" select="descendant::*"/>
+ <xsl:variable name="entry" select="."/>
+
+ <xsl:for-each select="$columns">
+ <xsl:variable name="column" select="."/>
+
+ <!-- find all descendants whose name matches the column name -->
+ <xsl:variable name="numvalues" select="count($current[local-name() = $column])"/>
+ <!-- if the field node exists, output its value, otherwise put in a space -->
+ <td class="field">
+ <xsl:choose>
+ <!-- when there is at least one value... -->
+ <xsl:when test="$numvalues &gt; 1">
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test="$numvalues = 1">
+ <xsl:for-each select="$current[local-name() = $column]">
+
+ <xsl:variable name="field" select="key('fieldsByName', $column)"/>
+ <xsl:choose>
+
+ <!-- boolean and number values -->
+ <xsl:when test="$field/@type=4 or $field/@type=6">
+ <xsl:attribute name="style">
+ <xsl:text>text-align: center; padding-left: 5px</xsl:text>
+ </xsl:attribute>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- next, check for images -->
+ <xsl:when test="$field/@type=10">
+ <xsl:attribute name="style">
+ <xsl:text>text-align: center; padding-left: 5px</xsl:text>
+ </xsl:attribute>
+ <img>
+ <xsl:attribute name="src">
+ <xsl:value-of select="concat($imgdir, .)"/>
+ </xsl:attribute>
+ <xsl:call-template name="image-size">
+ <xsl:with-param name="limit-width" select="$image-width"/>
+ <xsl:with-param name="limit-height" select="$image-height"/>
+ <xsl:with-param name="image" select="key('imagesById', .)"/>
+ </xsl:call-template>
+ </img>
+ </xsl:when>
+
+ <!-- if it's a date, format with hyphens -->
+ <xsl:when test="$field/@type=12">
+ <xsl:attribute name="style">
+ <xsl:text>text-align: center; padding-left: 5px</xsl:text>
+ </xsl:attribute>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- handle URL here, so no link created -->
+ <xsl:when test="$field/@type=7">
+ <xsl:value-of select="."/>
+ </xsl:when>
+
+ <!-- finally, it's just a regular value -->
+ <xsl:otherwise>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text> </xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ </xsl:for-each>
+</xsl:template>
+
+</xsl:stylesheet>
+<!-- Local Variables: -->
+<!-- sgml-indent-step: 1 -->
+<!-- sgml-indent-data: 1 -->
+<!-- End: -->
diff --git a/xslt/report-templates/Group_Summary.xsl b/xslt/report-templates/Group_Summary.xsl
new file mode 100644
index 0000000..9058f78
--- /dev/null
+++ b/xslt/report-templates/Group_Summary.xsl
@@ -0,0 +1,323 @@
+<?xml version="1.0"?>
+<!-- WARNING: Tellico uses tc as the internal namespace declaration, and it must be identical here!! -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ xmlns:exsl="http://exslt.org/common"
+ xmlns:dyn="http://exslt.org/dynamic"
+ extension-element-prefixes="exsl dyn"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - Collection Summary Report
+
+ Copyright (C) 2005-2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="../tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<xsl:param name="filename"/>
+<xsl:param name="cdate"/>
+
+<!-- Sort using user's preferred language -->
+<xsl:param name="lang"/>
+
+<xsl:variable name="limit" select="5"/>
+
+<xsl:key name="fieldsByName" match="tc:field" use="@name"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<xsl:template match="tc:tellico">
+ <html>
+ <head>
+ <style type="text/css">
+ body {
+ font-family: sans-serif;
+ background-color: #fff;
+ color: #000;
+ }
+ #header-left {
+ margin-top: 0;
+ float: left;
+ font-size: 80%;
+ font-style: italic;
+ }
+ #header-right {
+ margin-top: 0;
+ float: right;
+ font-size: 80%;
+ font-style: italic;
+ }
+ h1.colltitle {
+ margin: 0px;
+ padding-bottom: 5px;
+ font-size: 2em;
+ text-align: center;
+ }
+ div.field {
+ margin-left: auto;
+ margin-right: auto;
+ margin-bottom: 20px;
+ width: 750px;
+ background-color: #ddd;
+ border: solid 1px #999;
+ overflow: auto;
+ padding: 0px 0px 0px 0px;
+ }
+ h2 {
+ font-size: 125%;
+ border-bottom: solid 1px #999;
+ text-align: center;
+ margin-top: 5px;
+ margin-bottom: 0px;
+ }
+ h3 {
+ font-size: 0.9em;
+ color: #666;
+ text-align: right;
+ padding-right: 4px;
+ margin-top: -1.1em;
+ margin-bottom: 0px;
+ }
+ h4 {
+ text-align: center;
+ }
+ table {
+ margin-left: auto;
+ margin-right: auto;
+ padding: 10px 0px 10px 0px;
+ }
+ div.row {
+ margin: 0px 0px 0px 0px;
+ padding: 0px 0px 0px 0px;
+ border: solid 1px transparent;
+ clear: left;
+ overflow: auto;
+ line-height: 120%;
+ }
+ div.group {
+ text-align: left;
+ margin: 0px 0px 0px 0px;
+ padding: 0px 10px 0px 4px;
+ float: left;
+ }
+ span.bar {
+ width: 590px;
+ margin: 1px 2px 1px 150px;
+ position: absolute;
+ float: left;
+ border-left: solid 5px #ddd; /* padding of a sort */
+ }
+ span.bar span {
+ border-top: outset 1px #669;
+ border-right: outset 2px #003;
+ border-bottom: outset 2px #003;
+ border-left: outset 2px #669;
+ float: left;
+ position: absolute;
+ background-color: #336;
+ color: white;
+ padding-right: 4px;
+ padding-bottom: 2px;
+ font-size: 0.9em;
+ line-height: 0.9em;
+ text-align: right;
+ font-style: italic;
+ }
+ </style>
+ <title>Tellico</title>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection"/>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="tc:collection">
+ <p id="header-left"><xsl:value-of select="$filename"/></p>
+ <p id="header-right"><xsl:value-of select="$cdate"/></p>
+ <h1 class="colltitle">
+ <xsl:value-of select="@title"/>
+ <i18n>: Group Summary</i18n>
+ </h1>
+
+ <xsl:variable name="coll" select="."/>
+
+ <table>
+ <tbody>
+ <tr>
+ <th><i18n>Total number of fields:</i18n></th>
+ <th style="padding-right: 50px; color: #006;">
+ <xsl:value-of select="count(tc:fields/tc:field)"/>
+ </th>
+ <th><i18n>Total number of entries:</i18n></th>
+ <th style="color:#006;">
+ <xsl:value-of select="count(tc:entry)"/>
+ </th>
+ </tr>
+ </tbody>
+ </table>
+ <!-- grouping flag is second bit from right -->
+ <xsl:for-each select="tc:fields/tc:field[boolean(floor(@flags div 2) mod 2)]">
+ <xsl:call-template name="output-group">
+ <xsl:with-param name="coll" select="$coll"/>
+ <xsl:with-param name="fieldname" select="@name"/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <!--
+ <h4><a href="http://www.periapsis.org/tellico/"><i18n>Generated by Tellico</i18n></a></h4>
+-->
+</xsl:template>
+
+<xsl:template name="output-group">
+ <xsl:param name="coll"/>
+ <xsl:param name="fieldname"/>
+
+ <xsl:variable name="str">
+ <xsl:choose>
+ <xsl:when test="boolean(floor(key('fieldsByName', $fieldname)/@flags mod 2))">
+ <xsl:choose>
+ <xsl:when test="key('fieldsByName', $fieldname)/@type=8">
+ <xsl:value-of select="concat('$coll/tc:entry/tc:',$fieldname,'s/tc:',$fieldname,'/tc:column[1]')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat('$coll/tc:entry/tc:',$fieldname,'s/tc:',$fieldname)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat('$coll/tc:entry/tc:',$fieldname)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="values" select="dyn:evaluate($str)"/>
+
+ <xsl:variable name="listing">
+ <xsl:for-each select="$values[not(. = preceding::*)]">
+ <!-- speed sorting by ignoring groups with a count of 1 -->
+ <xsl:variable name="c" select="count($values[. = current()])"/>
+ <xsl:if test="$c &gt; 1">
+ <group>
+ <xsl:attribute name="name">
+ <xsl:call-template name="text-value"/>
+ </xsl:attribute>
+ <xsl:attribute name="count">
+ <xsl:value-of select="$c"/>
+ </xsl:attribute>
+ </group>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+
+ <xsl:variable name="groups" select="exsl:node-set($listing)/group"/>
+ <xsl:variable name="total" select="count($groups)"/>
+
+ <xsl:variable name="max">
+ <xsl:call-template name="max-count">
+ <xsl:with-param name="nodes" select="$groups"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:if test="$total &gt; 2">
+
+ <div class="field">
+ <h2>
+ <xsl:value-of select="key('fieldsByName', $fieldname)/@title"/>
+ </h2>
+
+ <xsl:for-each select="$groups">
+ <xsl:sort lang="$lang" select="@count" data-type="number" order="descending" />
+ <xsl:sort lang="$lang" select="@name"/>
+ <xsl:if test="position() &lt;= $limit">
+ <div class="row">
+ <div class="group">
+ <xsl:value-of select="@name"/>
+ </div>
+ <span class="bar">
+ <span>
+ <xsl:attribute name="style">
+ <xsl:text>padding-left:</xsl:text>
+ <!-- the 540 is rather arbitrarily dependent on font-size, seem to work -->
+ <xsl:value-of select="floor(540 * @count div $max)"/>
+ <xsl:text>px;</xsl:text>
+ </xsl:attribute>
+ (<xsl:value-of select="@count"/>)
+ </span>
+ </span>
+ </div>
+ </xsl:if>
+ </xsl:for-each>
+
+ <h3>
+ <i18n>Distinct values: </i18n><xsl:value-of select="$total"/>
+ </h3>
+ </div>
+
+ </xsl:if>
+</xsl:template>
+
+<xsl:template name="max-count">
+ <xsl:param name="nodes" select="/.."/>
+ <xsl:param name="max"/>
+
+ <xsl:variable name="count" select="count($nodes)"/>
+ <xsl:variable name="aNode" select="$nodes[ceiling($count div 2)]"/>
+
+ <xsl:choose>
+ <xsl:when test="$count = 0">
+ <xsl:value-of select="number($max)"/>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:call-template name="max-count">
+
+ <xsl:with-param name="nodes" select="$nodes[not(@count &lt;= number($aNode/@count))]"/>
+ <xsl:with-param name="max">
+ <xsl:choose>
+ <xsl:when test="not($max) or $aNode/@count &gt; $max">
+ <xsl:value-of select="$aNode/@count"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$max"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="text-value">
+ <xsl:choose>
+ <xsl:when test="text()">
+ <xsl:value-of select="text()"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="..//tc:column[1]"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
+<!-- Local Variables: -->
+<!-- sgml-indent-step: 1 -->
+<!-- sgml-indent-data: 1 -->
+<!-- End: -->
diff --git a/xslt/report-templates/Group_View.xsl b/xslt/report-templates/Group_View.xsl
new file mode 100644
index 0000000..123559e
--- /dev/null
+++ b/xslt/report-templates/Group_View.xsl
@@ -0,0 +1,284 @@
+<?xml version="1.0"?>
+<!-- WARNING: Tellico uses tc as the internal namespace declaration, and it must be identical here!! -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ xmlns:str="http://exslt.org/strings"
+ extension-element-prefixes="str"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - Group View Report
+
+ Copyright (C) 2005-2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="../tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<xsl:param name="filename"/>
+<xsl:param name="cdate"/>
+
+<!-- Sort using user's preferred language -->
+<xsl:param name="lang"/>
+
+<!-- To choose which fields of each entry are printed, change the
+ string to a space separated list of field names. To know what
+ fields are available, check the Tellico data file for <field>
+ elements. -->
+<xsl:param name="column-names" select="'title'"/>
+<xsl:variable name="columns" select="str:tokenize($column-names)"/>
+
+<!-- If you want the header row printed, showing which fields
+ are printed, change this to true(), otherwise false() -->
+<xsl:param name="show-headers" select="true()"/>
+
+<!-- set the maximum image size -->
+<xsl:param name="image-height" select="'100'"/>
+<xsl:param name="image-width" select="'100'"/>
+
+<xsl:param name="datadir"/> <!-- dir where Tellico data files are located -->
+<xsl:param name="imgdir"/> <!-- dir where field images are located -->
+
+<xsl:key name="fieldsByName" match="tc:field" use="@name"/>
+<xsl:key name="imagesById" match="tc:image" use="@id"/>
+<xsl:key name="entriesById" match="tc:entry" use="@id"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<xsl:template match="tc:tellico">
+ <html>
+ <head>
+ <style type="text/css">
+ body {
+ font-family: sans-serif;
+ <xsl:if test="count($columns) &gt; 3">
+ font-size: 80%;
+ </xsl:if>
+ background-color: #fff;
+ }
+ #header-left {
+ margin-top: 0;
+ float: left;
+ font-size: 80%;
+ font-style: italic;
+ }
+ #header-right {
+ margin-top: 0;
+ float: right;
+ font-size: 80%;
+ font-style: italic;
+ }
+ h1.colltitle {
+ margin: 0px;
+ padding-bottom: 5px;
+ font-size: 2em;
+ text-align: center;
+ }
+ table {
+ margin-left: auto;
+ margin-right: auto;
+ }
+ td.groupName {
+ margin-top: 10px;
+ margin-bottom: 2px;
+ padding-left: 4px;
+ background: #ccc;
+ font-size: 1.1em;
+ font-weight: bolder;
+ }
+ td.fieldName {
+ margin-top: 10px;
+ margin-bottom: 2px;
+ color: #666;
+ background-color: #ccc;
+ font-size: 1em;
+ text-align: center;
+ font-style: italic;
+ padding-left: 4px;
+ padding-right: 4px;
+ }
+ tr.r0 {
+ }
+ tr.r1 {
+ background-color: #eee;
+ }
+ td.field {
+ margin-left: 0px;
+ margin-right: 0px;
+ padding-left: 10px;
+ padding-right: 5px;
+ border: 1px solid #eee;
+ text-align: left;
+ }
+ </style>
+ <title>Tellico</title>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection"/>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="tc:collection">
+ <p id="header-left"><xsl:value-of select="$filename"/></p>
+ <p id="header-right"><xsl:value-of select="$cdate"/></p>
+ <h1 class="colltitle">
+ <xsl:value-of select="@title"/>
+ </h1>
+
+ <table>
+ <tbody>
+ <xsl:variable name="fields" select="tc:fields"/>
+ <xsl:for-each select="tc:group">
+ <xsl:sort lang="$lang" select="@title"/>
+ <tr>
+ <td class="groupName">
+ <xsl:value-of select="@title"/>
+ </td>
+ <xsl:for-each select="$columns[position() &gt; 1]">
+ <td class="fieldName">
+ <xsl:call-template name="field-title">
+ <xsl:with-param name="fields" select="$fields"/>
+ <xsl:with-param name="name" select="."/>
+ </xsl:call-template>
+ </td>
+ </xsl:for-each>
+ </tr>
+
+ <xsl:for-each select="key('entriesById', tc:entryRef/@id)">
+ <tr class="r{position() mod 2}">
+ <xsl:apply-templates select="."/>
+ </tr>
+ </xsl:for-each>
+ </xsl:for-each>
+
+ </tbody>
+ </table>
+</xsl:template>
+
+<xsl:template name="field-title">
+ <xsl:param name="fields"/>
+ <xsl:param name="name"/>
+ <xsl:variable name="name-tokens" select="str:tokenize($name, ':')"/>
+ <!-- the header is the title field of the field node whose name equals the column name -->
+ <xsl:choose>
+ <xsl:when test="$fields">
+ <xsl:value-of select="$fields/tc:field[@name = $name-tokens[last()]]/@title"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$name-tokens[last()]"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="tc:entry">
+ <!-- stick all the descendants into a variable -->
+ <xsl:variable name="current" select="descendant::*"/>
+ <xsl:variable name="entry" select="."/>
+
+ <xsl:for-each select="$columns">
+ <xsl:variable name="column" select="."/>
+
+ <!-- find all descendants whose name matches the column name -->
+ <xsl:variable name="numvalues" select="count($current[local-name() = $column])"/>
+ <!-- if the field node exists, output its value, otherwise put in a space -->
+ <td class="field">
+ <xsl:choose>
+ <!-- when there is at least one value... -->
+ <xsl:when test="$numvalues &gt; 1">
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test="$numvalues = 1">
+ <xsl:for-each select="$current[local-name() = $column]">
+
+ <xsl:variable name="field" select="key('fieldsByName', $column)"/>
+ <xsl:choose>
+
+ <!-- boolean values end up as 'true', output 'X' -->
+ <xsl:when test="$field/@type=4 or $field/@type=6">
+ <xsl:attribute name="style">
+ <xsl:text>text-align: center; padding-left: 5px</xsl:text>
+ </xsl:attribute>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- next, check for images -->
+ <xsl:when test="$field/@type=10">
+ <xsl:attribute name="style">
+ <xsl:text>text-align: center; padding-left: 5px</xsl:text>
+ </xsl:attribute>
+ <img>
+ <xsl:attribute name="src">
+ <xsl:value-of select="concat($imgdir, .)"/>
+ </xsl:attribute>
+ <xsl:call-template name="image-size">
+ <xsl:with-param name="limit-width" select="$image-width"/>
+ <xsl:with-param name="limit-height" select="$image-height"/>
+ <xsl:with-param name="image" select="key('imagesById', .)"/>
+ </xsl:call-template>
+ </img>
+ </xsl:when>
+
+ <!-- if it's a date, format with hyphens -->
+ <xsl:when test="$field/@type=12">
+ <xsl:attribute name="style">
+ <xsl:text>text-align: center; padding-left: 5px</xsl:text>
+ </xsl:attribute>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- handle URL here, so no link created -->
+ <xsl:when test="$field/@type=7">
+ <xsl:value-of select="."/>
+ </xsl:when>
+
+ <!-- finally, it's just a regular value -->
+ <xsl:otherwise>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text> </xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ </xsl:for-each>
+</xsl:template>
+
+</xsl:stylesheet>
+<!-- Local Variables: -->
+<!-- sgml-indent-step: 1 -->
+<!-- sgml-indent-data: 1 -->
+<!-- End: -->
diff --git a/xslt/report-templates/Image_List.xsl b/xslt/report-templates/Image_List.xsl
new file mode 100644
index 0000000..78c596f
--- /dev/null
+++ b/xslt/report-templates/Image_List.xsl
@@ -0,0 +1,250 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ xmlns:str="http://exslt.org/strings"
+ xmlns:exsl="http://exslt.org/common"
+ extension-element-prefixes="str"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - Image List Report
+
+ Copyright (C) 2005-2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="../tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<xsl:param name="filename"/>
+<xsl:param name="cdate"/>
+
+<!-- Sort using user's preferred language -->
+<xsl:param name="lang"/>
+
+<!-- To choose which fields of each entry are printed, change the
+ string to a space separated list of field names. To know what
+ fields are available, check the Tellico data file for <field>
+ elements. -->
+<xsl:param name="column-names" select="'title'"/>
+<xsl:variable name="columns" select="str:tokenize($column-names)"/>
+
+<!-- set the maximum image size -->
+<xsl:param name="image-height" select="'150'"/>
+<xsl:param name="image-width" select="'150'"/>
+
+<xsl:param name="datadir"/> <!-- dir where Tellico data files are located -->
+<xsl:param name="imgdir"/> <!-- dir where field images are located -->
+
+<xsl:key name="imagesById" match="tc:image" use="@id"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<xsl:template match="tc:tellico">
+ <html>
+ <head>
+ <style type="text/css">
+ body {
+ font-family: sans-serif;
+ background-color: #fff;
+ color: #000;
+ }
+ #header-left {
+ margin-top: 0;
+ float: left;
+ font-size: 80%;
+ font-style: italic;
+ }
+ #header-right {
+ margin-top: 0;
+ float: right;
+ font-size: 80%;
+ font-style: italic;
+ }
+ h1.colltitle {
+ margin: 0px;
+ padding-bottom: 5px;
+ font-size: 2em;
+ text-align: center;
+ }
+ div.r0 {
+ border: 1px inset #666;
+ clear: left;
+ padding: 10px 10px 0px 10px;
+ background-color: #eee;
+ }
+ div.r1 {
+ border: 1px inset #666;
+ clear: left;
+ padding: 10px 10px 0px 10px;
+ background-color: #ddd;
+ }
+ img.float {
+ float: left;
+ margin-right: 10px;
+ margin-bottom: 10px;
+ border: 2px outset #ccc;
+ }
+ td.title {
+ font-size: 1.4em;
+ font-weight: bold;
+ }
+ td.fieldName {
+ color: #666;
+ vertical-align: top;
+ }
+ td.fieldValue {
+ padding-left: 4px;
+ font-weight: bold;
+ vertical-align: top;
+ }
+ </style>
+ <title>Tellico</title>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection"/>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="tc:collection">
+ <p id="header-left"><xsl:value-of select="$filename"/></p>
+ <p id="header-right"><xsl:value-of select="$cdate"/></p>
+ <h1 class="colltitle">
+ <xsl:value-of select="@title"/>
+ </h1>
+
+ <!-- find first image field -->
+ <xsl:variable name="image-field" select="tc:fields/tc:field[@type=10][1]/@name"/>
+
+ <xsl:for-each select="tc:entry">
+ <xsl:sort lang="$lang" select=".//tc:title[1]"/>
+ <xsl:variable name="entry" select="."/>
+
+ <div class="r{position() mod 2}">
+ <xsl:variable name="id" select="./*[local-name() = $image-field]"/>
+ <xsl:if test="$id">
+ <img class="float">
+ <xsl:attribute name="src">
+ <xsl:value-of select="concat($imgdir, $id)"/>
+ </xsl:attribute>
+ <xsl:call-template name="image-size">
+ <xsl:with-param name="limit-width" select="$image-width"/>
+ <xsl:with-param name="limit-height" select="$image-height"/>
+ <xsl:with-param name="image" select="key('imagesById', $id)"/>
+ </xsl:call-template>
+ </img>
+ </xsl:if>
+
+ <table>
+ <thead>
+ <tr>
+ <td colspan="2" class="title">
+ <xsl:value-of select=".//tc:title[1]"/>
+ </td>
+ </tr>
+ </thead>
+
+ <tbody>
+ <!-- don't repeat title -->
+ <xsl:for-each select="$columns[. != 'title']">
+ <!-- no other images allowed -->
+ <xsl:if test="$entry/../tc:fields/tc:field[@name = current()]/@type != 10">
+ <xsl:call-template name="field-output">
+ <xsl:with-param name="entry" select="$entry"/>
+ <!-- can't use a key, the context is not the document -->
+ <xsl:with-param name="field" select="$entry/../tc:fields/tc:field[@name = current()]"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:for-each>
+
+ <!-- add all paragraph fields, too -->
+ <xsl:for-each select="../tc:fields/tc:field[@type = 2]">
+ <xsl:call-template name="field-output">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="."/>
+ </xsl:call-template>
+
+ </xsl:for-each>
+ </tbody>
+ </table>
+ <div style="clear: left"/>
+ </div>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="field-output">
+ <xsl:param name="entry"/>
+ <xsl:param name="field"/>
+ <tr>
+ <td class="fieldName">
+ <!-- can't use key here, context is not in document -->
+ <xsl:value-of select="$field/@title"/>
+ <xsl:text>: </xsl:text>
+ </td>
+
+ <td class="fieldValue">
+ <xsl:variable name="numvalues" select="count($entry//*[local-name() = $field/@name])"/>
+
+ <xsl:choose>
+ <xsl:when test="$numvalues &gt; 1">
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$field/@name"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test="$numvalues = 1">
+ <xsl:choose>
+
+ <!-- boolean values end up as 'true', output 'X' -->
+ <xsl:when test="$field/@type=4 and . = 'true'">
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$field/@name"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- handle URL here, so no link created -->
+ <xsl:when test="$field/@type=7">
+ <xsl:value-of select="$entry/*[local-name() = $field/@name]"/>
+ </xsl:when>
+
+ <!-- finally, it's just a regular value -->
+ <xsl:otherwise>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$field/@name"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:text> </xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ </tr>
+</xsl:template>
+
+</xsl:stylesheet>
+<!-- Local Variables: -->
+<!-- sgml-indent-step: 1 -->
+<!-- sgml-indent-data: 1 -->
+<!-- End: -->
diff --git a/xslt/report-templates/Loan_View.xsl b/xslt/report-templates/Loan_View.xsl
new file mode 100644
index 0000000..d52f74c
--- /dev/null
+++ b/xslt/report-templates/Loan_View.xsl
@@ -0,0 +1,201 @@
+<?xml version="1.0"?>
+<!-- WARNING: Tellico uses tc as the internal namespace declaration, and it must be identical here!! -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ xmlns:str="http://exslt.org/strings"
+ extension-element-prefixes="str"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - Group View Report
+
+ Copyright (C) 2005-2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="../tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<xsl:param name="filename"/>
+<xsl:param name="cdate"/>
+
+<!-- Sort using user's preferred language -->
+<xsl:param name="lang"/>
+
+<xsl:key name="entriesById" match="tc:entry" use="@id"/>
+<xsl:key name="loansByDate" match="tc:loan" use="@dueDate"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<xsl:template match="tc:tellico">
+ <html>
+ <head>
+ <style type="text/css">
+ body {
+ font-family: sans-serif;
+ background-color: #fff;
+ }
+ #header-left {
+ margin-top: 0;
+ float: left;
+ font-size: 80%;
+ font-style: italic;
+ }
+ #header-right {
+ margin-top: 0;
+ float: right;
+ font-size: 80%;
+ font-style: italic;
+ }
+ h1.colltitle {
+ margin: 0px;
+ padding-bottom: 5px;
+ font-size: 2em;
+ text-align: center;
+ }
+ table {
+ margin-left: auto;
+ margin-right: auto;
+ margin-bottom: 30px;
+ }
+ td.groupName {
+ margin-top: 10px;
+ margin-bottom: 2px;
+ padding-left: 4px;
+ background: #ccc;
+ font-size: 1.1em;
+ font-weight: bolder;
+ }
+ td.fieldName {
+ margin-top: 10px;
+ margin-bottom: 2px;
+ color: #666;
+ background-color: #ccc;
+ font-size: 1.1em;
+ text-align: center;
+ font-style: italic;
+ padding-left: 4px;
+ padding-right: 4px;
+ }
+ tr.r0 {
+ }
+ tr.r1 {
+ background-color: #eee;
+ }
+ td.field {
+ margin: 0px;
+ padding: 0px 10px 0px 10px;
+ border: 1px solid #eee;
+ text-align: left;
+ }
+ </style>
+ <title>Tellico</title>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection"/>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="tc:collection">
+ <p id="header-left"><xsl:value-of select="$filename"/></p>
+ <p id="header-right"><xsl:value-of select="$cdate"/></p>
+ <h1 class="colltitle">
+ <xsl:value-of select="@title"/>
+ </h1>
+
+ <table>
+ <tbody>
+ <!-- TODO: this would need to be fixed for multiple collections -->
+ <xsl:for-each select="../tc:borrowers/tc:borrower/tc:loan[generate-id(.)=generate-id(key('loansByDate', @dueDate)[1])]">
+ <xsl:sort lang="$lang" select="@dueDate"/>
+ <tr>
+ <td class="groupName">
+ <xsl:value-of select="@dueDate"/>
+ </td>
+ <td class="fieldName"><i18n>Borrower</i18n></td>
+ <td class="fieldName"><i18n>Loan Date</i18n></td>
+ <td class="fieldName"><i18n>Note</i18n></td>
+ </tr>
+
+ <xsl:for-each select="key('loansByDate', @dueDate)">
+ <tr class="r{position() mod 2}">
+ <td class="field">
+ <xsl:value-of select="key('entriesById', @entryRef)//tc:title"/>
+ </td>
+ <td class="field">
+ <xsl:value-of select="../@name"/>
+ </td>
+ <td class="field">
+ <xsl:value-of select="@loanDate"/>
+ </td>
+ <td class="field">
+ <p><xsl:value-of select="text()"/></p>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </xsl:for-each>
+
+ </tbody>
+ </table>
+
+ <table>
+ <tbody>
+ <!-- TODO: this would need to be fixed for multiple collections -->
+ <xsl:for-each select="../tc:borrowers/tc:borrower">
+ <xsl:sort lang="$lang" select="@name"/>
+ <tr>
+ <td class="groupName">
+ <xsl:value-of select="@name"/>
+ </td>
+ <td class="fieldName"><i18n>Loan Date</i18n></td>
+ <td class="fieldName"><i18n>Due Date</i18n></td>
+ <td class="fieldName"><i18n>Note</i18n></td>
+ </tr>
+
+ <xsl:for-each select="tc:loan">
+ <tr class="r{position() mod 2}">
+ <td class="field">
+ <xsl:value-of select="key('entriesById', @entryRef)//tc:title"/>
+ </td>
+ <td class="field">
+ <xsl:value-of select="@loanDate"/>
+ </td>
+ <td class="field">
+ <xsl:value-of select="@dueDate"/>
+ </td>
+ <td class="field">
+ <p><xsl:value-of select="text()"/></p>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </xsl:for-each>
+
+ </tbody>
+ </table>
+
+ <!--
+ <h4><a href="http://www.periapsis.org/tellico/"><i18n>Generated by Tellico</i18n></a></h4>
+-->
+</xsl:template>
+
+</xsl:stylesheet>
+<!-- Local Variables: -->
+<!-- sgml-indent-step: 1 -->
+<!-- sgml-indent-data: 1 -->
+<!-- End: -->
diff --git a/xslt/report-templates/Makefile.am b/xslt/report-templates/Makefile.am
new file mode 100644
index 0000000..36c6dca
--- /dev/null
+++ b/xslt/report-templates/Makefile.am
@@ -0,0 +1,21 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+
+EXTRA_DIST = Column_View.xsl Title_Listing_(Horizontal).xsl\
+ Title_Listing_(Vertical).xsl Group_View.xsl Image_List.xsl \
+ Loan_View.xsl Group_Summary.xsl Tri-Column.xsl
+
+####### kdevelop will overwrite this part!!! (end)############
+
+xsldir = $(kde_datadir)/tellico/report-templates
+xsl_DATA = Column_View.xsl Title_Listing_(Horizontal).xsl \
+ Title_Listing_(Vertical).xsl Group_View.xsl Image_List.xsl \
+ Loan_View.xsl Group_Summary.xsl Tri-Column.xsl
+
+KDE_OPTIONS = noautodist
+
+CLEANFILES = *~
+
+# probably a better way to do this
+uninstall-hook:
+ -if [ -d $(xsldir) ]; then rmdir $(xsldir); fi
diff --git a/xslt/report-templates/Title_Listing_(Horizontal).xsl b/xslt/report-templates/Title_Listing_(Horizontal).xsl
new file mode 100644
index 0000000..30b9c95
--- /dev/null
+++ b/xslt/report-templates/Title_Listing_(Horizontal).xsl
@@ -0,0 +1,146 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ xmlns:exsl="http://exslt.org/common"
+ extension-element-prefixes="exsl"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - Title List Report
+
+ Copyright (C) 2005-2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="../tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<xsl:param name="filename"/>
+<xsl:param name="cdate"/>
+
+<!-- Sort using user's preferred language -->
+<xsl:param name="lang"/>
+
+<xsl:param name="num-columns" select="3"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<xsl:template match="tc:tellico">
+ <html>
+ <head>
+ <style type="text/css">
+ body {
+ font-family: sans-serif;
+ background-color: #fff;
+ color: #000;
+ }
+ #header-left {
+ margin-top: 0;
+ float: left;
+ font-size: 80%;
+ font-style: italic;
+ }
+ #header-right {
+ margin-top: 0;
+ float: right;
+ font-size: 80%;
+ font-style: italic;
+ }
+ h1.colltitle {
+ margin: 0px;
+ padding-bottom: 5px;
+ font-size: 2em;
+ text-align: center;
+ }
+ table {
+ margin-left: auto;
+ margin-right: auto;
+ }
+ td {
+ margin-left: 0px;
+ margin-right: 0px;
+ padding-left: 10px;
+ padding-right: 5px;
+ border: 1px solid #eee;
+ text-align: left;
+ }
+ tr.r0 {
+ background-color: #fff;
+ }
+ tr.r1 {
+ background-color: #eee;
+ }
+ </style>
+ <title>Tellico</title>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection"/>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="tc:collection">
+ <p id="header-left"><xsl:value-of select="$filename"/></p>
+ <p id="header-right"><xsl:value-of select="$cdate"/></p>
+ <h1 class="colltitle">
+ <xsl:value-of select="@title"/>
+ </h1>
+
+ <!-- first, build sorted list -->
+ <xsl:variable name="sorted-entries">
+ <xsl:for-each select="tc:entry">
+ <xsl:sort lang="$lang" select=".//tc:title[1]"/>
+ <xsl:copy-of select="."/>
+ </xsl:for-each>
+ </xsl:variable>
+
+ <table>
+ <tbody>
+
+<!--
+ <xsl:variable name="nrows"
+ select="ceiling(count(tc:entry) div $num-columns)"/>
+-->
+ <xsl:for-each select="exsl:node-set($sorted-entries)/tc:entry[position() mod $num-columns = 1]">
+ <tr class="r{position() mod 2}">
+ <xsl:apply-templates select=".|following-sibling::tc:entry[position() &lt; $num-columns]"/>
+ </tr>
+ </xsl:for-each>
+
+ </tbody>
+ </table>
+
+</xsl:template>
+
+<xsl:template match="tc:entry">
+ <td>
+ <xsl:for-each select=".//tc:title">
+ <xsl:value-of select="."/>
+ <xsl:if test="position() &lt; last()">
+ <xsl:text>; </xsl:text>
+ <br/>
+ </xsl:if>
+ </xsl:for-each>
+</td>
+</xsl:template>
+
+</xsl:stylesheet>
+<!-- Local Variables: -->
+<!-- sgml-indent-step: 1 -->
+<!-- sgml-indent-data: 1 -->
+<!-- End: -->
diff --git a/xslt/report-templates/Title_Listing_(Vertical).xsl b/xslt/report-templates/Title_Listing_(Vertical).xsl
new file mode 100644
index 0000000..79b6820
--- /dev/null
+++ b/xslt/report-templates/Title_Listing_(Vertical).xsl
@@ -0,0 +1,156 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ xmlns:exsl="http://exslt.org/common"
+ extension-element-prefixes="exsl"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - Title List Report
+
+ Copyright (C) 2005-2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="../tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<xsl:param name="filename"/>
+<xsl:param name="cdate"/>
+
+<!-- Sort using user's preferred language -->
+<xsl:param name="lang"/>
+
+<xsl:param name="num-columns" select="3"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<xsl:template match="tc:tellico">
+ <html>
+ <head>
+ <style type="text/css">
+ body {
+ font-family: sans-serif;
+ background-color: #fff;
+ color: #000;
+ }
+ #header-left {
+ margin-top: 0;
+ float: left;
+ font-size: 80%;
+ font-style: italic;
+ }
+ #header-right {
+ margin-top: 0;
+ float: right;
+ font-size: 80%;
+ font-style: italic;
+ }
+ h1.colltitle {
+ margin: 0px;
+ padding-bottom: 5px;
+ font-size: 2em;
+ text-align: center;
+ }
+ table {
+ margin-left: auto;
+ margin-right: auto;
+ }
+ td {
+ margin-left: 0px;
+ margin-right: 0px;
+ padding-left: 10px;
+ padding-right: 5px;
+ border: 1px solid #eee;
+ text-align: left;
+ }
+ tr.r0 {
+ background-color: #fff;
+ }
+ tr.r1 {
+ background-color: #eee;
+ }
+ </style>
+ <title>Tellico</title>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection"/>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="tc:collection">
+ <p id="header-left"><xsl:value-of select="$filename"/></p>
+ <p id="header-right"><xsl:value-of select="$cdate"/></p>
+ <h1 class="colltitle">
+ <xsl:value-of select="@title"/>
+ </h1>
+
+ <table>
+ <tbody>
+
+ <!-- first, build sorted list -->
+ <xsl:variable name="sorted-entries">
+ <xsl:for-each select="tc:entry">
+ <xsl:sort lang="$lang" select=".//tc:title[1]"/>
+ <xsl:copy-of select="."/>
+ </xsl:for-each>
+ </xsl:variable>
+
+ <xsl:variable name="nrows"
+ select="ceiling(count(tc:entry) div $num-columns)"/>
+
+ <!--
+ <xsl:for-each select="exsl:node-set($sorted-entries)/tc:entry[position() mod $num-columns = 1]">
+ <tr class="r{position() mod 2}">
+ <xsl:apply-templates select=".|following-sibling::tc:entry[position() &lt; $num-columns]"/>
+ </tr>
+ </xsl:for-each>
+-->
+ <xsl:for-each select="exsl:node-set($sorted-entries)/tc:entry[position() &lt;= $nrows]">
+ <xsl:variable name="idx" select="position()"/>
+ <tr class="r{$idx mod 2}">
+ <xsl:apply-templates select="."/>
+ <xsl:for-each
+ select="exsl:node-set($sorted-entries)/tc:entry[position() &gt;
+ $nrows and position() mod $nrows = ($idx mod $nrows)]">
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+ </tr>
+ </xsl:for-each>
+ </tbody>
+ </table>
+</xsl:template>
+
+<xsl:template match="tc:entry">
+ <td>
+ <xsl:for-each select=".//tc:title">
+ <xsl:value-of select="."/>
+ <xsl:if test="position() &lt; last()">
+ <xsl:text>; </xsl:text>
+ <br/>
+ </xsl:if>
+ </xsl:for-each>
+</td>
+</xsl:template>
+
+</xsl:stylesheet>
+<!-- Local Variables: -->
+<!-- sgml-indent-step: 1 -->
+<!-- sgml-indent-data: 1 -->
+<!-- End: -->
diff --git a/xslt/report-templates/Tri-Column.xsl b/xslt/report-templates/Tri-Column.xsl
new file mode 100644
index 0000000..d38dd5f
--- /dev/null
+++ b/xslt/report-templates/Tri-Column.xsl
@@ -0,0 +1,234 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ xmlns:exsl="http://exslt.org/common"
+ extension-element-prefixes="exsl"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - Tri-Column Report
+ Modified from VideoDB
+
+ Copyright (C) 2005-2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="../tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<xsl:param name="filename"/>
+<xsl:param name="cdate"/>
+
+<!-- Sort using user's preferred language -->
+<xsl:param name="lang"/>
+
+<xsl:variable name="image-field" select="tc:tellico/tc:collection[1]/tc:fields/tc:field[@type=10][1]/@name"/>
+
+<!-- set the maximum image size -->
+<xsl:param name="image-height" select="'150'"/>
+<xsl:param name="image-width" select="'150'"/>
+
+<xsl:param name="datadir"/> <!-- dir where Tellico data files are located -->
+<xsl:param name="imgdir"/> <!-- dir where field images are located -->
+
+<xsl:key name="imagesById" match="tc:image" use="@id"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<xsl:template match="tc:tellico">
+ <html>
+ <head>
+ <style type="text/css">
+ body {
+ font-family: sans-serif;
+ background-color: #fff;
+ color: #000;
+ }
+ #header-left {
+ margin-top: 0;
+ float: left;
+ font-size: 80%;
+ font-style: italic;
+ }
+ #header-right {
+ margin-top: 0;
+ float: right;
+ font-size: 80%;
+ font-style: italic;
+ }
+ h1.colltitle {
+ margin: 0px;
+ padding-bottom: 5px;
+ font-size: 2em;
+ text-align: center;
+ }
+ tr.r0 {
+ border: 1px inset #666;
+ background-color: #eee;
+ }
+ tr.r1 {
+ border: 1px inset #666;
+ background-color: #ddd;
+ }
+ img.float {
+ float: left;
+ margin-right: 10px;
+ margin-bottom: 10px;
+ border: 2px outset #ccc;
+ }
+ td {
+ vertical-align: top;
+ }
+ span.title {
+ font-size: 1.2em;
+ font-weight: bold;
+ }
+ span.info {
+ font-size: 1.1em;
+ font-style italic;
+ color: #006;
+ }
+ span.plot {
+ font-size: 1em;
+ }
+ </style>
+ <title>Tellico</title>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection"/>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="tc:collection[@type!=3]">
+ <h1 class="colltitle">
+ <i18n>This template is meant for video collections only.</i18n>
+ </h1>
+</xsl:template>
+
+<xsl:template match="tc:collection[@type=3]">
+ <p id="header-left"><xsl:value-of select="$filename"/></p>
+ <p id="header-right"><xsl:value-of select="$cdate"/></p>
+ <h1 class="colltitle">
+ <xsl:value-of select="@title"/>
+ </h1>
+
+ <!-- first, build sorted list -->
+ <xsl:variable name="sorted-entries">
+ <xsl:for-each select="tc:entry">
+ <xsl:sort lang="$lang" select=".//tc:title[1]"/>
+ <xsl:copy-of select="."/>
+ </xsl:for-each>
+ </xsl:variable>
+
+ <!-- needed for key context -->
+ <xsl:variable name="coll" select="."/>
+
+ <table class="tablelist" cellpadding="0" cellspacing="0" width="100%">
+ <colgroup width="33%"/>
+ <colgroup width="34%"/>
+ <colgroup width="33%"/>
+ <tbody>
+ <!-- three columns -->
+ <!-- have to pass in image width and height because
+ context changes inside the exsl:node-set -->
+ <xsl:variable name="entries" select="exsl:node-set($sorted-entries)/tc:entry"/>
+
+ <xsl:for-each select="$entries[position() mod 3 = 1]">
+ <xsl:variable name="e1" select="."/>
+ <xsl:variable name="e2" select="$e1/following-sibling::tc:entry[position() = 1]"/>
+ <xsl:variable name="e3" select="$e2/following-sibling::tc:entry[position() = 1]"/>
+
+ <tr class="r{position() mod 2}">
+
+ <!-- switch context back to document -->
+ <xsl:for-each select="$coll">
+
+ <td>
+ <xsl:apply-templates select="$e1">
+ <xsl:with-param name="img" select="key('imagesById', $e1/*[local-name() = $image-field])"/>
+ </xsl:apply-templates>
+ </td>
+ <td>
+ <xsl:apply-templates select="$e2">
+ <xsl:with-param name="img" select="key('imagesById', $e2/*[local-name() = $image-field])"/>
+ </xsl:apply-templates>
+ </td>
+ <td>
+ <xsl:apply-templates select="$e3">
+ <xsl:with-param name="img" select="key('imagesById', $e3/*[local-name() = $image-field])"/>
+ </xsl:apply-templates>
+ </td>
+ </xsl:for-each>
+ </tr>
+ </xsl:for-each>
+
+ </tbody>
+ </table>
+
+</xsl:template>
+
+<xsl:template match="tc:entry">
+ <xsl:param name="img"/>
+ <table>
+ <tbody>
+ <tr>
+ <td>
+ <xsl:variable name="id" select="./*[local-name() = $image-field]"/>
+ <xsl:if test="$id">
+ <img class="float" alt=" ">
+ <xsl:attribute name="src">
+ <xsl:value-of select="concat($imgdir, $id)"/>
+ </xsl:attribute>
+ <xsl:call-template name="image-size">
+ <xsl:with-param name="limit-width" select="$image-width"/>
+ <xsl:with-param name="limit-height" select="$image-height"/>
+ <xsl:with-param name="image" select="$img"/>
+ </xsl:call-template>
+ </img>
+ </xsl:if>
+ </td>
+ <td>
+ <span class="title">
+ <xsl:value-of select=".//tc:title[1]"/>
+ </span>
+ <br/>
+ <span class="info">
+ <xsl:text>[</xsl:text>
+ <xsl:value-of select=".//tc:year[1]"/>
+ <xsl:text>; </xsl:text>
+ <xsl:value-of select=".//tc:director[1]"/>
+ <xsl:text>]</xsl:text>
+ </span>
+ <br/>
+ <span class="plot">
+ <xsl:value-of select="normalize-space(substring(./tc:plot, 1, 150))" disable-output-escaping="yes"/>
+ <xsl:text>&#xa0;&#x2026;</xsl:text>
+ </span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+</xsl:template>
+
+</xsl:stylesheet>
+
+<!-- Local Variables: -->
+<!-- sgml-indent-step: 1 -->
+<!-- sgml-indent-data: 1 -->
+<!-- End: -->
diff --git a/xslt/shadowAlpha.png b/xslt/shadowAlpha.png
new file mode 100644
index 0000000..a24c9c4
--- /dev/null
+++ b/xslt/shadowAlpha.png
Binary files differ
diff --git a/xslt/tellico-by-author.xsl b/xslt/tellico-by-author.xsl
new file mode 100644
index 0000000..e71948e
--- /dev/null
+++ b/xslt/tellico-by-author.xsl
@@ -0,0 +1,159 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ================================================================
+ Tellico XSLT file - sort by author
+
+ Copyright (C) 2003-2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with XML data files
+ from the 'tellico' application, which can be found at:
+ http://www.periapsis.org/tellico/
+ ================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<!-- Sort using user's preferred language -->
+<xsl:param name="lang"/>
+
+<xsl:param name="version"/>
+
+<xsl:key name="books" match="tc:book" use=".//tc:author"/>
+<xsl:key name="authors" match="tc:author" use="."/>
+
+<!-- more efficient to specify complete XPath like this than to use //tc:author -->
+<xsl:variable name="unique-authors" select="/tc:tellico/tc:collection/tc:entry/tc:authors/tc:author[generate-id(.)=generate-id(key('authors', .)[1])]"/>
+
+<xsl:variable name="endl">
+<xsl:text>
+</xsl:text>
+</xsl:variable>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<xsl:template match="tc:tellico">
+ <xsl:call-template name="syntax-version">
+ <xsl:with-param name="this-version" select="'10'"/>
+ <xsl:with-param name="data-version" select="@syntaxVersion"/>
+ </xsl:call-template>
+
+ <html>
+ <head>
+ <title>My Book Collections - sorted by author</title>
+ <style type="text/css">
+ body {
+ background: #999999;
+ margin: 0px;
+ font-family: Verdana, Arial, sans-serif;
+ color: black;
+ }
+ #headerblock {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ margin-bottom: 5px;
+ }
+ .title {
+ padding: 4px;
+ line-height: 18px;
+ font-size: 24px;
+ border-top: 1px solid black;
+ border-bottom: 1px solid black;
+ margin: 0px;
+ }
+ .subtitle {
+ margin-left: 10px;
+ font-size: 12px;
+ }
+ .author {
+ margin-right: 3px;
+ margin-bottom: 2px;
+ background: #eee;
+ font-size: 14px;
+ font-weight: bold;
+ }
+ .books {
+ background: rgb(204,204,204);
+ padding-left: 4px;
+ margin-left: 15px;
+ margin-bottom: 5px;
+ margin-right: 15px;
+ font-size: 12px;
+ }
+ ul {
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection"/>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="tc:collection">
+ <div id="headerblock">
+ <div class="title">
+ <xsl:value-of select="@title"/>
+ <xsl:text> </xsl:text>
+ <span class="subtitle">sorted by author</span>
+ </div>
+ </div>
+
+ <!-- first output any with no author -->
+ <xsl:variable name="no-author" select="/tc:tellico/tc:collection/tc:entry[count(tc:authors/tc:author) = 0"/>
+ <xsl:if test="count($no-author) &gt; 0">
+ <div class="author">
+ <xsl:text>(Empty)</xsl:text>
+ </div>
+ <div class="books">
+ <ul>
+ <xsl:for-each select="$no-author">
+ <xsl:sort lang="$lang" select="tc:title"/>
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+ </ul>
+ </div>
+ </xsl:if>
+
+ <xsl:for-each select="$unique-authors">
+ <xsl:sort lang="$lang" select="."/>
+ <div class="author">
+ <xsl:value-of select="."/>
+ </div>
+ <div class="books">
+ <ul>
+ <xsl:for-each select="key('books', .)">
+ <xsl:sort lang="$lang" select="tc:title"/>
+<!-- or sort by series and number -->
+<!-- <xsl:sort select="tc:series"/>
+ <xsl:sort select="tc:series_num"/> -->
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+ </ul>
+ </div>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="tc:entry">
+ <li>
+ <xsl:value-of select="tc:title"/>
+ </li>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/tellico-by-title.xsl b/xslt/tellico-by-title.xsl
new file mode 100644
index 0000000..de023c4
--- /dev/null
+++ b/xslt/tellico-by-title.xsl
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ================================================================
+ Tellico XSLT file - sort by author
+
+ Copyright (C) 2003-2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with XML data files
+ from the 'tellico' application, which can be found at:
+ http://www.periapsis.org/tellico/
+ ================================================================
+-->
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<!-- Sort using user's preferred language -->
+<xsl:param name="lang"/>
+
+<xsl:variable name="endl">
+<xsl:text>
+</xsl:text>
+</xsl:variable>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<xsl:template match="tc:tellico">
+ <xsl:if test="@syntaxVersion &lt; '10'">
+ <xsl:message>
+ <xsl:text>This stylesheet was designed for Tellico DTD version </xsl:text>
+ <xsl:value-of select="'7'"/>
+ <xsl:text>or earlier, &#xa;but the input data file is version </xsl:text>
+ <xsl:value-of select="@syntaxVersion"/>
+ <xsl:text>. There might be some &#xa;problems with the output.</xsl:text>
+ </xsl:message>
+ </xsl:if>
+
+ <html>
+ <head>
+ <title>My Book Collections - sorted by title</title>
+ <style type="text/css">
+ body {
+ background: #999;
+ margin: 0px;
+ font-family: Verdana, Arial, sans-serif;
+ color: black;
+ }
+ #headerblock {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ margin-bottom: 5px;
+ }
+ .title {
+ padding: 4px;
+ line-height: 18px;
+ font-size: 24px;
+ border-top: 1px solid black;
+ border-bottom: 1px solid black;
+ margin: 0px;
+ }
+ .subtitle {
+ margin-left: 10px;
+ font-size: 12px;
+ }
+ .books {
+ background: rgb(204,204,204);
+ padding-left: 4px;
+ margin-left: 15px;
+ margin-bottom: 5px;
+ margin-right: 15px;
+ font-size: 12px;
+ }
+ ul {
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection"/>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="tc:collection">
+ <div id="headerblock">
+ <div class="title">
+ <xsl:value-of select="@title"/>
+ <xsl:text> </xsl:text>
+ <span class="subtitle">sorted by title</span>
+ </div>
+ </div>
+
+ <div class="books">
+ <ol>
+ <xsl:for-each select="/tc:tellico/tc:collection/tc:entry">
+ <xsl:sort lang="$lang" select="tc:title"/>
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+ </ol>
+ </div>
+</xsl:template>
+
+<xsl:template match="tc:entry">
+ <li>
+ <xsl:value-of select="tc:title"/><br/>
+ </li>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/tellico-common.xsl b/xslt/tellico-common.xsl
new file mode 100644
index 0000000..5a75efc
--- /dev/null
+++ b/xslt/tellico-common.xsl
@@ -0,0 +1,307 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - some common templates.
+
+ Copyright (C) 2004-2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+ ===================================================================
+-->
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<!-- Template for checking syntax version -->
+<xsl:template name="syntax-version">
+ <xsl:param name="this-version"/>
+ <xsl:param name="data-version"/>
+ <xsl:if test="$data-version &gt; $this-version">
+ <xsl:message>
+ <xsl:text>This stylesheet was designed for Tellico DTD version </xsl:text>
+ <xsl:value-of select="$this-version"/>
+ <xsl:text> or earlier, &#xa;but the input data file is version </xsl:text>
+ <xsl:value-of select="$data-version"/>
+ <xsl:text>. There might be some &#xa;problems with the output.</xsl:text>
+ </xsl:message>
+ </xsl:if>
+</xsl:template>
+
+<!-- template for creating attributes to scale an image to a max boundary size -->
+<xsl:template name="image-size">
+ <xsl:param name="limit-height" select="'0'"/>
+ <xsl:param name="limit-width" select="'0'"/>
+ <xsl:param name="image"/>
+
+ <xsl:variable name="actual-width" select="$image/@width"/>
+ <xsl:variable name="actual-height" select="$image/@height"/>
+
+ <xsl:choose>
+ <xsl:when test="$limit-width &gt; 0 and $limit-height &gt; 0 and
+ ($actual-width &gt; $limit-width or $actual-height &gt; $limit-height)">
+
+ <xsl:choose>
+
+ <xsl:when test="$actual-width * $limit-height &lt; $actual-height * $limit-width">
+ <xsl:attribute name="height">
+ <xsl:value-of select="round($limit-height)"/>
+ </xsl:attribute>
+ <xsl:attribute name="width">
+ <xsl:value-of select="round($actual-width * $limit-height div $actual-height)"/>
+ </xsl:attribute>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:attribute name="width">
+ <xsl:value-of select="round($limit-width)"/>
+ </xsl:attribute>
+ <xsl:attribute name="height">
+ <xsl:value-of select="round($actual-height * $limit-width div $actual-width)"/>
+ </xsl:attribute>
+ </xsl:otherwise>
+
+ </xsl:choose>
+
+ </xsl:when>
+
+ <!-- if both are smaller, no change -->
+ <xsl:when test="$actual-width &gt; 0 and $actual-height &gt; 0">
+ <xsl:attribute name="width">
+ <xsl:value-of select="$actual-width"/>
+ </xsl:attribute>
+ <xsl:attribute name="height">
+ <xsl:value-of select="$actual-height"/>
+ </xsl:attribute>
+ </xsl:when>
+
+ </xsl:choose>
+</xsl:template>
+
+<!-- template for outputing most value types -->
+<xsl:template name="simple-field-value">
+ <xsl:param name="entry"/>
+ <xsl:param name="field"/>
+
+ <!-- if the field has multiple values, then there is
+ no child of the entry with the field name -->
+ <xsl:variable name="child" select="$entry/*[local-name(.)=$field]"/>
+ <xsl:choose>
+ <xsl:when test="$child">
+ <xsl:variable name="f" select="$entry/../tc:fields/tc:field[@name = $field]"/>
+
+ <!-- if the field is a bool type, just ouput an X, or use data image -->
+ <xsl:choose>
+ <!-- paragraphs need to have output escaping disabled so HTML works -->
+ <xsl:when test="$f/@type=2">
+ <xsl:value-of select="$child" disable-output-escaping="yes"/>
+ </xsl:when>
+
+ <xsl:when test="$f/@type=4">
+ <img height="14" alt="&#x2713;">
+ <xsl:attribute name="src">
+ <xsl:value-of select="concat($datadir,'pics/checkmark.png')"/>
+ </xsl:attribute>
+ </img>
+ </xsl:when>
+
+ <!-- if it's a url, then add a hyperlink -->
+ <xsl:when test="$f/@type=7">
+ <a href="{$child}">
+ <!-- The Amazon Web Services license requires the link -->
+ <xsl:choose>
+ <xsl:when test="$field = 'amazon'">
+ <xsl:text>Buy from Amazon.com</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$child"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </a>
+ </xsl:when>
+
+ <!-- if it's a date, format with hyphens -->
+ <xsl:when test="$f/@type=12">
+ <xsl:value-of select="$child/tc:year"/>
+ <xsl:text>-</xsl:text>
+ <xsl:value-of select="format-number($child/tc:month,'00')"/>
+ <xsl:text>-</xsl:text>
+ <xsl:value-of select="format-number($child/tc:day,'00')"/>
+ </xsl:when>
+
+ <!-- special case for rating -->
+ <xsl:when test="$f/@type=14">
+ <!-- get the number, could be 10, so can't just grab first digit -->
+ <xsl:variable name="n">
+ <xsl:choose>
+ <xsl:when test="number(substring($child,1,1))">
+ <xsl:choose>
+ <xsl:when test="number(substring($child,1,2)) &lt; 11">
+ <xsl:value-of select="number(substring($child,1,2))"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="number(substring($child,1,1))"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="false()"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:if test="$n &gt; 0">
+ <!-- the image is really 18 pixels high, but make it smaller to match default font -->
+ <img height="14">
+ <xsl:attribute name="src">
+ <xsl:value-of select="concat($datadir,'pics/stars',$n,'.png')"/>
+ </xsl:attribute>
+ <xsl:attribute name="alt">
+ <xsl:value-of select="concat($n,' stars')"/>
+ </xsl:attribute>
+ </img>
+ </xsl:if>
+ <xsl:if test="not($n)">
+ <xsl:value-of select="$child"/>
+ </xsl:if>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:value-of select="$child"/>
+ <!-- hack for running-time in videos -->
+ <!--
+ <xsl:if test="$field='running-time' and key('fieldsByName',$field)/@type=6">
+ <xsl:text> minutes</xsl:text>
+ </xsl:if>
+ -->
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+
+ <!-- now handle fields with multiple values -->
+ <xsl:otherwise>
+ <xsl:for-each select="$entry/*[local-name()=concat($field,'s')]/*">
+ <xsl:value-of select="."/>
+ <xsl:if test="position() != last()">
+ <xsl:text>; </xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="image-link">
+ <xsl:param name="image"/>
+ <xsl:param name="dir"/>
+ <xsl:variable name="id" select="$image/@id"/>
+ <xsl:choose>
+ <xsl:when test="$image/@link = 'true'">
+ <!-- the id _is_ the link -->
+ <xsl:value-of select="$id"/>
+ </xsl:when>
+ <xsl:when test="string-length($dir) &gt; 0">
+ <xsl:value-of select="concat($dir, $id)"/>
+ </xsl:when>
+ <!-- otherwise try $imgdir and $datadir -->
+ <xsl:when test="string-length($datadir) &gt; 0">
+ <xsl:value-of select="concat($datadir, $id)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat($imgdir, $id)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="msqueeze">
+ <xsl:param name="str"/>
+ <xsl:param name="len"/>
+
+ <xsl:variable name="slen" select="string-length($str)"/>
+ <xsl:variable name="mid" select="floor($len div 2)"/>
+
+ <xsl:choose>
+ <xsl:when test="$slen &gt; $len">
+ <xsl:value-of select="substring($str, 0, $mid - 2)"/>
+ <xsl:text>[...]</xsl:text>
+ <xsl:value-of select="substring($str, $slen - $mid + 3, $mid - 2)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$str"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<!-- sums all nodes, assuming they are in MM:SS format -->
+<xsl:template name="sumTime">
+ <xsl:param name="nodes" select="/.."/>
+ <xsl:param name="totalMin" select="0"/>
+ <xsl:param name="totalSec" select="0"/>
+
+ <xsl:choose>
+
+ <xsl:when test="not($nodes)">
+ <xsl:value-of select="$totalMin + floor($totalSec div 60)"/>
+ <xsl:text>:</xsl:text>
+ <xsl:value-of select="format-number($totalSec mod 60, '00')"/>
+ </xsl:when>
+
+ <xsl:when test="string-length($nodes[1]) &gt; 0">
+ <xsl:variable name="min">
+ <xsl:value-of select="substring-before($nodes[1], ':')"/>
+ </xsl:variable>
+ <xsl:variable name="sec">
+ <xsl:value-of select="substring-after($nodes[1], ':')"/>
+ </xsl:variable>
+ <xsl:call-template name="sumTime">
+ <xsl:with-param name="nodes" select="$nodes[position() != 1]"/>
+ <xsl:with-param name="totalMin" select="$totalMin + $min"/>
+ <xsl:with-param name="totalSec" select="$totalSec + $sec"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:call-template name="sumTime">
+ <xsl:with-param name="nodes" select="$nodes[position() != 1]"/>
+ <xsl:with-param name="totalMin" select="$totalMin"/>
+ <xsl:with-param name="totalSec" select="$totalSec"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="columnTitle">
+ <xsl:param name="index" select="1"/>
+ <xsl:param name="max" select="10"/>
+ <xsl:param name="elem" select="'th'"/>
+ <xsl:param name="style"/>
+ <xsl:param name="field" select="/.."/>
+
+ <xsl:if test="not($index &gt; $max)">
+ <xsl:element name="{$elem}">
+ <xsl:if test="string-length($style)">
+ <xsl:attribute name="style">
+ <xsl:value-of select="$style"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="$field/tc:prop[@name = concat('column', $index)]"/>
+ </xsl:element>
+
+ <xsl:call-template name="columnTitle">
+ <xsl:with-param name="index" select="$index + 1"/>
+ <xsl:with-param name="max" select="$max"/>
+ <xsl:with-param name="elem" select="$elem"/>
+ <xsl:with-param name="style" select="$style"/>
+ <xsl:with-param name="field" select="$field"/>
+ </xsl:call-template>
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/tellico-printing.xsl b/xslt/tellico-printing.xsl
new file mode 100644
index 0000000..bbc8ee4
--- /dev/null
+++ b/xslt/tellico-printing.xsl
@@ -0,0 +1,381 @@
+<?xml version="1.0"?>
+<!-- WARNING: Tellico uses tc as the internal namespace declaration, and it must be identical here!! -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ xmlns:str="http://exslt.org/strings"
+ extension-element-prefixes="str"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for printing
+
+ Copyright (C) 2004-2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ The exslt extensions from http://www.exslt.org are required.
+ Specifically, the string and dynamic modules are used. For
+ libxslt, that means the minimum version is 1.0.19.
+
+ This is a horribly messy stylesheet. I would REALLY welcome any
+ recommendations in improving its efficiency.
+
+ There may be problems if this stylesheet is used to transform the
+ actual Tellico data file, since the application re-arranges the
+ DOM for printing. THe primary change is the addition of group
+ elements to speed up grouped printing.
+
+ Any version of this file in the user's home directory, such as
+ $KDEHOME/share/apps/tellico/, will override the system file.
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<!-- To choose which fields of each entry are printed, change the
+ string to a space separated list of field names. To know what
+ fields are available, check the Tellico data file for <field>
+ elements. -->
+<xsl:param name="column-names" select="'title'"/>
+<xsl:variable name="columns" select="str:tokenize($column-names)"/>
+
+<!-- If you want the header row printed, showing which fields
+ are printed, change this to true(), otherwise false() -->
+<xsl:param name="show-headers" select="true()"/>
+
+<!-- set the maximum image size -->
+<xsl:param name="image-height" select="50"/>
+<xsl:param name="image-width" select="50"/>
+
+<!-- This is the title just beside the collection name. It will
+ automatically list which fields are used for sorting. -->
+<xsl:param name="sort-title" select="''"/>
+
+<!--
+ ===================================================================
+ The only thing below here that you might want to change is the CSS
+ governing the appearance of the output HTML.
+ ===================================================================
+-->
+
+<!-- The page-title is used for the HTML title -->
+<xsl:param name="page-title" select="'Tellico'"/>
+<xsl:param name="imgdir"/> <!-- dir where field images are located -->
+
+<xsl:key name="fieldsByName" match="tc:field" use="@name"/>
+<xsl:key name="entriesById" match="tc:entry" use="@id"/>
+<xsl:key name="imagesById" match="tc:image" use="@id"/>
+
+<xsl:variable name="endl">
+<xsl:text>
+</xsl:text>
+</xsl:variable>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<xsl:template match="tc:tellico">
+ <!-- This stylesheet is designed for Tellico document syntax version 10 -->
+ <xsl:call-template name="syntax-version">
+ <xsl:with-param name="this-version" select="'10'"/>
+ <xsl:with-param name="data-version" select="@syntaxVersion"/>
+ </xsl:call-template>
+
+ <html>
+ <head>
+ <style type="text/css">
+ body {
+ font-family: sans-serif;
+ <xsl:if test="count($columns) &gt; 3">
+ font-size: 80%;
+ </xsl:if>
+ background-color: #fff;
+ }
+ #headerblock {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ width: 100%;
+ text-align: center;
+ }
+ div.colltitle {
+ padding: 4px;
+ font-size: 2em;
+ }
+ table {
+ margin-left: auto;
+ margin-right: auto;
+ }
+ td.groupName {
+ margin-top: 10px;
+ margin-bottom: 2px;
+ padding-left: 4px;
+ background: #ccc;
+ font-size: 1.1em;
+ font-weight: bolder;
+ }
+ th {
+ color: #000;
+ background-color: #ccc;
+ border: 1px solid #999;
+ font-size: 1.1em;
+ font-weight: bold;
+ padding-left: 4px;
+ padding-right: 4px;
+ }
+ tr.entry1 {
+ }
+ tr.entry2 {
+ background-color: #eee;
+ }
+ tr.groupEntry1 {
+ }
+ tr.groupEntry2 {
+ background-color: #eee;
+ }
+ td.field {
+ margin-left: 0px;
+ margin-right: 0px;
+ padding-left: 5px;
+ padding-right: 5px;
+ border: 1px solid #eee;
+ text-align: left;
+ }
+ </style>
+ <title>
+ <xsl:value-of select="$page-title"/>
+ </title>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection"/>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="tc:collection">
+ <div id="headerblock">
+ <div class="colltitle">
+ <xsl:value-of select="@title"/>
+ </div>
+ <div class="sortTitle">
+ <xsl:value-of select="$sort-title"/>
+ </div>
+ </div>
+
+ <table>
+
+ <xsl:if test="$show-headers">
+ <xsl:variable name="fields" select="tc:fields"/>
+ <thead>
+ <tr>
+ <xsl:for-each select="$columns">
+ <xsl:variable name="column" select="."/>
+ <th>
+ <xsl:call-template name="field-title">
+ <xsl:with-param name="fields" select="$fields"/>
+ <xsl:with-param name="name" select="$column"/>
+ </xsl:call-template>
+ </th>
+ </xsl:for-each>
+ </tr>
+ </thead>
+ </xsl:if>
+
+ <tbody>
+
+ <!-- If the entries are not being grouped, it's easy -->
+ <xsl:if test="not(tc:group)">
+ <xsl:for-each select="tc:entry">
+ <tr>
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">
+ <xsl:attribute name="class">
+ <xsl:text>entry1</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="class">
+ <xsl:text>entry2</xsl:text>
+ </xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:apply-templates select="."/>
+ </tr>
+ </xsl:for-each>
+ </xsl:if> <!-- end ungrouped output -->
+
+ <!-- If the entries are being grouped, it's a bit more involved -->
+ <xsl:if test="tc:group">
+ <xsl:variable name="coll" select="."/>
+ <xsl:for-each select="tc:group">
+ <tr>
+ <td class="groupName">
+ <xsl:attribute name="colspan">
+ <xsl:value-of select="count($columns)"/>
+ </xsl:attribute>
+ <xsl:value-of select="@title"/>
+ </td>
+ </tr>
+ <xsl:for-each select="tc:entryRef">
+ <tr>
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">
+ <xsl:attribute name="class">
+ <xsl:text>groupEntry1</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="class">
+ <xsl:text>groupEntry2</xsl:text>
+ </xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:apply-templates select="key('entriesById', @id)"/>
+ </tr>
+ </xsl:for-each>
+ </xsl:for-each>
+ </xsl:if>
+
+ </tbody>
+ </table>
+</xsl:template>
+
+<xsl:template name="field-title">
+ <xsl:param name="fields"/>
+ <xsl:param name="name"/>
+ <xsl:variable name="name-tokens" select="str:tokenize($name, ':')"/>
+ <!-- the header is the title field of the field node whose name equals the column name -->
+ <xsl:choose>
+ <xsl:when test="$fields">
+ <xsl:value-of select="$fields/tc:field[@name = $name-tokens[last()]]/@title"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$name-tokens[last()]"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="tc:entry">
+ <xsl:variable name="entry" select="."/>
+ <!-- stick all the descendants into a variable -->
+ <xsl:variable name="current" select="descendant::*"/>
+ <xsl:for-each select="$columns">
+ <xsl:variable name="column" select="."/>
+ <!-- find all descendants whose name matches the column name -->
+ <xsl:variable name="numvalues" select="count($current[local-name() = $column])"/>
+ <!-- if the field node exists, output its value, otherwise put in a space -->
+ <td class="field">
+ <!-- first column should not be centered -->
+ <!-- nor should rating images be centered -->
+ <xsl:if test="position()=1 or $entry/../tc:fields/tc:field[@name=$column]/@type=14">
+ <xsl:attribute name="style">
+ <xsl:text>text-align: left; padding-left: 10px</xsl:text>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:choose>
+ <!-- when there is at least one value... -->
+ <xsl:when test="$numvalues &gt; 1">
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test="$numvalues = 1">
+ <xsl:for-each select="$current[local-name() = $column]">
+ <xsl:variable name="field" select="key('fieldsByName', $column)"/>
+
+ <xsl:choose>
+
+ <!-- boolean and number values -->
+ <xsl:when test="$field/@type=4 or $field/@type=6">
+ <xsl:attribute name="style">
+ <xsl:text>text-align: center; padding-left: 5px</xsl:text>
+ </xsl:attribute>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- check for multi-column table -->
+ <xsl:when test="$field/@type=8 and $field/tc:prop[@name = 'columns'] &gt; 1">
+ <!-- italicize all columns after the first -->
+ <xsl:value-of select="tc:column[1]"/>
+ <xsl:for-each select="tc:column[position &gt; 1]">
+ <xsl:text> - </xsl:text>
+ <em>
+ <xsl:value-of select="."/>
+ </em>
+ </xsl:for-each>
+ <br/>
+ </xsl:when>
+
+ <!-- next, check for images -->
+ <xsl:when test="$field/@type=10">
+ <xsl:attribute name="style">
+ <xsl:text>text-align: center; padding-left: 5px</xsl:text>
+ </xsl:attribute>
+ <img>
+ <xsl:attribute name="src">
+ <xsl:value-of select="concat($imgdir, .)"/>
+ </xsl:attribute>
+ <xsl:call-template name="image-size">
+ <xsl:with-param name="limit-width" select="$image-width"/>
+ <xsl:with-param name="limit-height" select="$image-height"/>
+ <xsl:with-param name="image" select="key('imagesById', .)"/>
+ </xsl:call-template>
+ </img>
+ </xsl:when>
+
+ <!-- if it's a date, format with hyphens -->
+ <xsl:when test="$field/@type=12">
+ <xsl:attribute name="style">
+ <xsl:text>text-align: center; padding-left: 5px</xsl:text>
+ </xsl:attribute>
+ <xsl:value-of select="tc:year"/>
+ <xsl:text>-</xsl:text>
+ <xsl:value-of select="format-number(tc:month,'00')"/>
+ <xsl:text>-</xsl:text>
+ <xsl:value-of select="format-number(tc:day,'00')"/>
+ </xsl:when>
+
+ <!-- paragraphs need to have output escaping disabled so HTML works -->
+ <xsl:when test="$field/@type=2">
+ <xsl:value-of select="." disable-output-escaping="yes"/>
+ </xsl:when>
+
+ <!-- finally, it's just a regular value -->
+ <xsl:otherwise>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text> </xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ </xsl:for-each>
+</xsl:template>
+
+</xsl:stylesheet>
+<!-- Local Variables: -->
+<!-- sgml-indent-step: 1 -->
+<!-- sgml-indent-data: 1 -->
+<!-- End: -->
diff --git a/xslt/tellico2gcstar.xsl b/xslt/tellico2gcstar.xsl
new file mode 100644
index 0000000..b4cf394
--- /dev/null
+++ b/xslt/tellico2gcstar.xsl
@@ -0,0 +1,286 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ xmlns:math="http://exslt.org/math"
+ xmlns:a="uri:attribute"
+ exclude-result-prefixes="tc a"
+ extension-element-prefixes="math"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for exporting to GCstar
+
+ Copyright (C) 2008 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at
+ http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<!-- the mapping from gcstar attribute to tellico element is automated here -->
+<!-- @name is the gcstar attribute name, the value is the tellico element local-name() -->
+<!-- bool attributes are special, and some only apply to certain collection types -->
+<a:attributes>
+ <a:attribute name="isbn">isbn</a:attribute>
+ <a:attribute name="title">title</a:attribute>
+ <a:attribute name="publisher">publisher</a:attribute>
+ <a:attribute name="publication">pub_year</a:attribute>
+ <a:attribute name="language">language</a:attribute>
+ <a:attribute name="serie">series</a:attribute>
+ <a:attribute name="edition">edition</a:attribute>
+ <a:attribute name="pages">pages</a:attribute>
+ <a:attribute name="added">pur_date</a:attribute>
+ <a:attribute name="acquisition">pur_date</a:attribute>
+ <a:attribute name="location">location</a:attribute>
+ <a:attribute name="translator">translator</a:attribute>
+ <a:attribute name="artist">artist</a:attribute>
+ <a:attribute name="director">director</a:attribute>
+ <a:attribute name="date">year</a:attribute>
+ <a:attribute name="video">format</a:attribute>
+ <a:attribute name="original">origtitle</a:attribute>
+ <a:attribute name="format">binding</a:attribute>
+ <a:attribute name="format">medium</a:attribute>
+ <a:attribute name="format">format</a:attribute>
+ <a:attribute name="web">url</a:attribute>
+ <a:attribute name="webPage">url</a:attribute>
+ <a:attribute name="read" format="bool" type="GCbooks">read</a:attribute>
+ <a:attribute name="seen" format="bool" type="GCfilms">seen</a:attribute>
+ <a:attribute name="favourite" format="bool">favorite</a:attribute>
+ <a:attribute name="label">label</a:attribute>
+ <a:attribute name="release">year</a:attribute>
+ <a:attribute name="composer">composer</a:attribute>
+ <a:attribute name="producer">producer</a:attribute>
+</a:attributes>
+<xsl:variable name="collType">
+ <xsl:choose>
+ <xsl:when test="tc:tellico/tc:collection/@type=2 or tc:tellico/tc:collection/@type=5">
+ <xsl:text>GCbooks</xsl:text>
+ </xsl:when>
+ <xsl:when test="tc:tellico/tc:collection/@type=3">
+ <xsl:text>GCfilms</xsl:text>
+ </xsl:when>
+ <xsl:when test="tc:tellico/tc:collection/@type=4">
+ <xsl:text>GCmusics</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+</xsl:variable>
+<!-- grab all the applicable attributes once -->
+<xsl:variable name="attributes" select="document('')/*/a:attributes/a:attribute[not(@type) or @type=$collType]"/>
+
+<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<xsl:template match="tc:tellico">
+ <xsl:apply-templates select="tc:collection"/>
+</xsl:template>
+
+<xsl:template match="tc:collection[@type&lt;2 or @type&gt;5]">
+ <xsl:message terminate="yes">
+ <xsl:text>GCstar export is not supported for this collection type.</xsl:text>
+ </xsl:message>
+</xsl:template>
+
+<xsl:template match="tc:collection[@type&gt;1 and @type&lt;6]">
+ <collection items="{count(tc:entry)}" type="{$collType}">
+ <information>
+ <maxId>
+ <xsl:value-of select="math:max(tc:entry/@id)"/>
+ </maxId>
+ </information>
+ <xsl:apply-templates select="tc:entry"/>
+ </collection>
+</xsl:template>
+
+<!-- no output for fields or images -->
+<xsl:template match="tc:fields"/>
+<xsl:template match="tc:images"/>
+
+<xsl:template match="tc:entry">
+ <xsl:variable name="entry" select="."/>
+ <item id="{@id}" rating="{tc:rating * 2}">
+ <xsl:for-each select="$attributes">
+ <xsl:call-template name="handle-attribute">
+ <xsl:with-param name="att" select="."/>
+ <xsl:with-param name="entry" select="$entry"/>
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <xsl:if test="tc:running-time">
+ <xsl:attribute name="time">
+ <xsl:value-of select="concat(tc:running-time, ' min')"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:if test="tc:nationalitys">
+ <xsl:attribute name="country">
+ <xsl:for-each select="tc:nationalitys/tc:nationality">
+ <xsl:value-of select="."/>
+ <xsl:if test="position() &lt; last()">
+ <xsl:text> / </xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:if test="tc:certification">
+ <xsl:attribute name="age">
+ <xsl:choose>
+ <xsl:when test="tc:certification = 'U (USA)'">
+ <xsl:text>1</xsl:text>
+ </xsl:when>
+ <xsl:when test="tc:certification = 'G (USA)'">
+ <xsl:text>2</xsl:text>
+ </xsl:when>
+ <xsl:when test="tc:certification = 'PG (USA)'">
+ <xsl:text>5</xsl:text>
+ </xsl:when>
+ <xsl:when test="tc:certification = 'PG-13 (USA)'">
+ <xsl:text>13</xsl:text>
+ </xsl:when>
+ <xsl:when test="tc:certification = 'R (USA)'">
+ <xsl:text>18</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+ </xsl:if>
+
+ <!-- for books -->
+ <comments>
+ <xsl:value-of select="tc:comments"/>
+ </comments>
+ <authors>
+ <xsl:call-template name="multiline">
+ <xsl:with-param name="elem" select="tc:authors"/>
+ </xsl:call-template>
+ </authors>
+ <genre>
+ <xsl:call-template name="multiline">
+ <xsl:with-param name="elem" select="tc:genres"/>
+ </xsl:call-template>
+ </genre>
+ <tags>
+ <xsl:call-template name="multiline">
+ <xsl:with-param name="elem" select="tc:keywords"/>
+ </xsl:call-template>
+ </tags>
+
+ <!-- for movies -->
+ <comment> <!-- note the lack of an 's' -->
+ <xsl:value-of select="tc:comments"/>
+ </comment>
+ <synopsis>
+ <xsl:value-of select="tc:plot"/>
+ </synopsis>
+<!--
+ <directors>
+ <xsl:call-template name="multiline">
+ <xsl:with-param name="elem" select="tc:directors"/>
+ </xsl:call-template>
+ </directors>
+-->
+ <actors>
+ <xsl:call-template name="table">
+ <xsl:with-param name="elem" select="tc:casts"/>
+ </xsl:call-template>
+ </actors>
+ <subt>
+ <xsl:call-template name="multiline">
+ <xsl:with-param name="elem" select="tc:subtitles"/>
+ </xsl:call-template>
+ </subt>
+ <xsl:apply-templates select="tc:languages"/>
+
+ <!-- for music -->
+ <xsl:apply-templates select="tc:tracks"/>
+
+ </item>
+</xsl:template>
+
+<xsl:template match="tc:languages">
+ <audio>
+ <xsl:for-each select="tc:language">
+ <line>
+ <col>
+ <xsl:value-of select="."/>
+ </col>
+ <col>
+ <!-- expect a language to always have a track -->
+ <xsl:value-of select="../../tc:audio-tracks/tc:audio-track[position()]"/>
+ </col>
+ </line>
+ </xsl:for-each>
+ </audio>
+</xsl:template>
+
+<xsl:template match="tc:tracks">
+ <tracks>
+ <xsl:for-each select="tc:track">
+ <line>
+ <col>
+ <xsl:value-of select="position()"/>
+ </col>
+ <col>
+ <xsl:value-of select="tc:column[1]"/>
+ </col>
+ <col>
+ <xsl:value-of select="tc:column[3]"/>
+ </col>
+ </line>
+ </xsl:for-each>
+ </tracks>
+</xsl:template>
+
+<xsl:template name="multiline">
+ <xsl:param name="elem"/>
+ <xsl:for-each select="$elem/child::*">
+ <line>
+ <col>
+ <xsl:value-of select="."/>
+ </col>
+ </line>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="table">
+ <xsl:param name="elem"/>
+ <xsl:for-each select="$elem/child::*">
+ <line>
+ <xsl:for-each select="child::*">
+ <col>
+ <xsl:value-of select="."/>
+ </col>
+ </xsl:for-each>
+ </line>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="handle-attribute">
+ <xsl:param name="att"/>
+ <xsl:param name="entry"/>
+ <!-- should technically check namespace, too, but unlikely to match -->
+ <xsl:variable name="value" select="$entry//*[local-name()=$att][1]"/>
+ <xsl:choose>
+ <xsl:when test="$att/@format='bool'">
+ <xsl:attribute name="{$att/@name}">
+ <xsl:value-of select="number($value='true')"/>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:if test="string-length($value) &gt; 0">
+ <xsl:attribute name="{$att/@name}">
+ <xsl:value-of select="$value"/>
+ </xsl:attribute>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
+<!-- Local Variables: -->
+<!-- sgml-indent-step: 1 -->
+<!-- sgml-indent-data: 1 -->
+<!-- End: -->
diff --git a/xslt/tellico2html.js b/xslt/tellico2html.js
new file mode 100644
index 0000000..8a3f5df
--- /dev/null
+++ b/xslt/tellico2html.js
@@ -0,0 +1,620 @@
+function showAll() {
+ // for now, assume only 1 table
+ tbl = document.getElementsByTagName("table")[0];
+ bdy = tbl.getElementsByTagName("tbody")[0];
+ rows = bdy.getElementsByTagName("tr");
+ for(i=0;i<rows.length;i++) {
+// rows[i].style.display="table-row";
+ if(i % 2) { rows[i].className='entry0'; }
+ else { rows[i].className='entry1'; }
+ }
+}
+
+function checkQuery() {
+ s = queryVariable("searchText");
+ if(s=="") {
+ return;
+ }
+ doSearch(s);
+}
+
+function searchRows() {
+ s = document.getElementById("searchText").value;
+ if(s=="") {
+ showAll();
+ return;
+ }
+ doSearch(s);
+}
+
+function doSearch(s) {
+ re = new RegExp(s,"i")
+ tbl = document.getElementsByTagName("table")[0];
+ bdy = tbl.getElementsByTagName("tbody")[0];
+ rows = bdy.getElementsByTagName("tr");
+ j = 0;
+ for(i=0; i<rows.length; i++) {
+ s = ts_getInnerText(rows[i]);
+ if(re.test(s)) {
+// rows[i].style.display="table-row";
+ if(j % 2) { rows[i].className='entry1'; }
+ else { rows[i].className='entry0'; }
+ j++;
+ } else {
+// rows[i].style.display="none";
+ // for msie
+ rows[i].className='hidden';
+ }
+ }
+}
+
+function addEvent(elm, evType, fn, useCapture) {
+// addEvent and removeEvent
+// cross-browser event handling for IE5+, NS6 and Mozilla
+// By Scott Andrew
+ if (elm.addEventListener) {
+ elm.addEventListener(evType, fn, useCapture);
+ return true;
+ } else if (elm.attachEvent) {
+ var r = elm.attachEvent("on"+evType, fn);
+ return r;
+ }
+}
+
+addEvent(window, "load", checkQuery);
+
+function queryVariable(variable) {
+ var query = window.location.search.substring(1);
+ var vars = query.split("&");
+ for (var i=0;i<vars.length;i++) {
+ var pair = vars[i].split("=");
+ if (pair[0] == variable) {
+ return pair[1];
+ }
+ }
+ return "";
+}
+
+function ts_getInnerText(el) {
+ if (typeof el == "string") return el;
+ if (typeof el == "undefined") { return el };
+ if (el.innerText) return el.innerText; //Not needed but it is faster
+ var str = "";
+
+ var cs = el.childNodes;
+ var l = cs.length;
+ for (var i = 0; i < l; i++) {
+ switch (cs[i].nodeType) {
+ case 1: //ELEMENT_NODE
+ str += ts_getInnerText(cs[i]);
+ break;
+ case 3: //TEXT_NODE
+ str += cs[i].nodeValue;
+ break;
+ }
+ }
+ return str;
+}
+
+/*
+ SortTable
+ version 2
+ 7th April 2007
+ Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/
+
+ Instructions:
+ Download this file
+ Add <script src="sorttable.js"></script> to your HTML
+ Add class="sortable" to any table you'd like to make sortable
+ Click on the headers to sort
+
+ Thanks to many, many people for contributions and suggestions.
+ Licenced as X11: http://www.kryogenix.org/code/browser/licence.html
+ This basically means: do what you want with it.
+*/
+
+
+var stIsIE = /*@cc_on!@*/false;
+
+sorttable = {
+ init: function() {
+ // quit if this function has already been called
+ if (arguments.callee.done) return;
+ // flag this function so we don't do the same thing twice
+ arguments.callee.done = true;
+ // kill the timer
+ if (_timer) clearInterval(_timer);
+
+ if (!document.createElement || !document.getElementsByTagName) return;
+
+ sorttable.DATE_RE = /^(\d\d)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
+ sorttable.YYMMDD_RE = /^((\d\d)?\d\d)[\/\.-](\d\d?)[\/\.-](\d\d)$/;
+
+ forEach(document.getElementsByTagName('table'), function(table) {
+ if (table.className.search(/\bsortable\b/) != -1) {
+ sorttable.makeSortable(table);
+ }
+ });
+
+ },
+
+ makeSortable: function(table) {
+ if (table.getElementsByTagName('thead').length == 0) {
+ // table doesn't have a tHead. Since it should have, create one and
+ // put the first table row in it.
+ the = document.createElement('thead');
+ the.appendChild(table.rows[0]);
+ table.insertBefore(the,table.firstChild);
+ }
+ // Safari doesn't support table.tHead, sigh
+ if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0];
+
+ if (table.tHead.rows.length != 1) return; // can't cope with two header rows
+
+ // work through each column and calculate its type
+ headrow = table.tHead.rows[0].cells;
+ for (var i=0; i<headrow.length; i++) {
+ // manually override the type with a sorttable_type attribute
+ if (!headrow[i].className.match(/\bsorttable_nosort\b/)) { // skip this col
+ mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/);
+ if (mtch) { override = mtch[1]; }
+ if (mtch && typeof sorttable["sort_"+override] == 'function') {
+ headrow[i].sorttable_sortfunction = sorttable["sort_"+override];
+ } else {
+ var sortType = COL_SORT_ARRAY[i];
+ if (sortType == 0) headrow[i].sorttable_sortfunction = sorttable["sort_alpha"];
+ else if (sortType == 1) headrow[i].sorttable_sortfunction = sorttable["sort_numeric"];
+ else if (sortType == 2) headrow[i].sorttable_sortfunction = sorttable["sort_yymmdd"];
+ else headrow[i].sorttable_sortfunction = sorttable.guessType(table,i);
+ }
+ // make it clickable to sort
+ headrow[i].sorttable_columnindex = i;
+ headrow[i].sorttable_tbody = table.tBodies[0];
+ dean_addEvent(headrow[i],"click", function(e) {
+
+ if (this.className.search(/\bsorttable_sorted\b/) != -1) {
+ // if we're already sorted by this column, just
+ // reverse the table, which is quicker
+ sorttable.reverse(this.sorttable_tbody);
+ this.className = this.className.replace('sorttable_sorted',
+ 'sorttable_sorted_reverse');
+ this.removeChild(document.getElementById('sorttable_sortfwdind'));
+ sortrevind = document.createElement('span');
+ sortrevind.id = "sorttable_sortrevind";
+ sortrevind.innerHTML = stIsIE ? '&nbsp<font face="webdings">5</font>' : '&nbsp;&#x25B4;';
+ this.appendChild(sortrevind);
+ return;
+ }
+ if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
+ // if we're already sorted by this column in reverse, just
+ // re-reverse the table, which is quicker
+ sorttable.reverse(this.sorttable_tbody);
+ this.className = this.className.replace('sorttable_sorted_reverse',
+ 'sorttable_sorted');
+ this.removeChild(document.getElementById('sorttable_sortrevind'));
+ sortfwdind = document.createElement('span');
+ sortfwdind.id = "sorttable_sortfwdind";
+ sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;';
+ this.appendChild(sortfwdind);
+ return;
+ }
+
+ // remove sorttable_sorted classes
+ theadrow = this.parentNode;
+ forEach(theadrow.childNodes, function(cell) {
+ if (cell.nodeType == 1) { // an element
+ cell.className = cell.className.replace('sorttable_sorted_reverse','');
+ cell.className = cell.className.replace('sorttable_sorted','');
+ }
+ });
+ sortfwdind = document.getElementById('sorttable_sortfwdind');
+ if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); }
+ sortrevind = document.getElementById('sorttable_sortrevind');
+ if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); }
+
+ this.className += ' sorttable_sorted';
+ sortfwdind = document.createElement('span');
+ sortfwdind.id = "sorttable_sortfwdind";
+ sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;';
+ this.appendChild(sortfwdind);
+
+ // build an array to sort. This is a Schwartzian transform thing,
+ // i.e., we "decorate" each row with the actual sort key,
+ // sort based on the sort keys, and then put the rows back in order
+ // which is a lot faster because you only do getInnerText once per row
+ row_array = [];
+ col = this.sorttable_columnindex;
+ rows = this.sorttable_tbody.rows;
+ for (var j=0; j<rows.length; j++) {
+ row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]];
+ }
+ /* If you want a stable sort, uncomment the following line */
+ //sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
+ /* and comment out this one */
+ row_array.sort(this.sorttable_sortfunction);
+
+ tb = this.sorttable_tbody;
+ for (var j=0; j<row_array.length; j++) {
+ var row = row_array[j][1];
+ if(j % 2) { row.className='entry0'; }
+ else { row.className='entry1'; }
+ tb.appendChild(row);
+ }
+
+ delete row_array;
+ });
+ }
+ }
+ },
+
+ guessType: function(table, column) {
+ // guess the type of a column based on its first non-blank row
+ sortfn = sorttable.sort_alpha;
+ for (var i=0; i<table.tBodies[0].rows.length; i++) {
+ text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]);
+ if (text != '') {
+ if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) {
+ return sorttable.sort_numeric;
+ }
+ // check for a date: dd/mm/yyyy or dd/mm/yy
+ // can have / or . or - as separator
+ // can be mm/dd as well
+ possdate = text.match(sorttable.DATE_RE)
+ if (possdate) {
+ // looks like a date
+ first = parseInt(possdate[1]);
+ second = parseInt(possdate[2]);
+ if (first > 12) {
+ // definitely dd/mm
+ return sorttable.sort_ddmm;
+ } else if (second > 12) {
+ return sorttable.sort_mmdd;
+ } else {
+ // looks like a date, but we can't tell which, so assume
+ // that it's dd/mm (English imperialism!) and keep looking
+ sortfn = sorttable.sort_ddmm;
+ }
+ }
+ }
+ }
+ return sortfn;
+ },
+
+ getInnerText: function(node) {
+ // gets the text we want to use for sorting for a cell.
+ // strips leading and trailing whitespace.
+ // this is *not* a generic getInnerText function; it's special to sorttable.
+ // for example, you can override the cell text with a customkey attribute.
+ // it also gets .value for <input> fields.
+
+ hasInputs = (typeof node.getElementsByTagName == 'function') &&
+ node.getElementsByTagName('input').length;
+
+ if (node.getAttribute("sorttable_customkey") != null) {
+ return node.getAttribute("sorttable_customkey");
+ }
+ var innerText = '';
+ if (typeof node.textContent != 'undefined' && !hasInputs) {
+ innerText = node.textContent.replace(/^\s+|\s+$/g, '');
+ }
+ else if (typeof node.innerText != 'undefined' && !hasInputs) {
+ innerText = node.innerText.replace(/^\s+|\s+$/g, '');
+ }
+ else if (typeof node.text != 'undefined' && !hasInputs) {
+ innerText = node.text.replace(/^\s+|\s+$/g, '');
+ }
+ if(innerText != '') {
+ return innerText;
+ }
+ else {
+ switch (node.nodeType) {
+ case 3:
+ if (node.nodeName.toLowerCase() == 'input') {
+ return node.value.replace(/^\s+|\s+$/g, '');
+ }
+ case 4:
+ return node.nodeValue.replace(/^\s+|\s+$/g, '');
+ break;
+ case 1:
+ case 11:
+ if(node.nodeName.toLowerCase() == 'img') {
+ var tokens = node.src.split('/');
+ innerText += tokens[tokens.length-1];
+ }
+ for (var i = 0; i < node.childNodes.length; i++) {
+ innerText += sorttable.getInnerText(node.childNodes[i]);
+ }
+ return innerText.replace(/^\s+|\s+$/g, '');
+ break;
+ default:
+ return '';
+ }
+ }
+ },
+
+ reverse: function(tbody) {
+ // reverse the rows in a tbody
+ newrows = [];
+ for (var i=0; i<tbody.rows.length; i++) {
+ newrows[newrows.length] = tbody.rows[i];
+ }
+ for (var i=newrows.length-1; i>=0; i--) {
+ tbody.appendChild(newrows[i]);
+ }
+ delete newrows;
+ },
+
+ /* sort functions
+ each sort function takes two parameters, a and b
+ you are comparing a[0] and b[0] */
+ sort_numeric: function(a,b) {
+ /* could be multiple values separated by semi-colon */
+ aa = a[0].split(";")[0];
+ bb = b[0].split(";")[0];
+ aa = parseFloat(aa.replace(/[^0-9.-]/g,''));
+ if (isNaN(aa)) aa = 0;
+ bb = parseFloat(bb.replace(/[^0-9.-]/g,''));
+ if (isNaN(bb)) bb = 0;
+ return aa-bb;
+ },
+ sort_alpha: function(a,b) {
+ /* case-insensitive */
+ aa = a[0].toLowerCase();
+ bb = b[0].toLowerCase();
+ if(aa.localeCompare) return aa.localeCompare(bb); /* Robby Stephenson */
+ if (aa==bb) return 0;
+ if (aa<bb) return -1;
+ return 1;
+ },
+ sort_yymmdd: function(a,b) {
+ mtch = a[0].match(sorttable.YYMMDD_RE);
+ if (mtch) {
+ y = mtch[1]; m = mtch[2]; d = mtch[3];
+ // y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
+ if (parseInt(y) < 50) y = '20'+y; else y = '19'+y;
+ if (m.length == 1) m = '0'+m;
+ if (d.length == 1) d = '0'+d;
+ dt1 = y+m+d;
+ } else dt1 = a[0];
+ mtch = b[0].match(sorttable.YYMMDD_RE);
+ if (mtch) {
+ y = mtch[1]; m = mtch[2]; d = mtch[3];
+ if (parseInt(y) < 50) y = '20'+y; else y = '19'+y;
+ if (m.length == 1) m = '0'+m;
+ if (d.length == 1) d = '0'+d;
+ dt2 = y+m+d;
+ } else dt2 = b[0];
+ if (dt1==dt2) return 0;
+ if (dt1<dt2) return -1;
+ return 1;
+ },
+ sort_ddmm: function(a,b) {
+ mtch = a[0].match(sorttable.DATE_RE);
+ if (mtch) {
+ y = mtch[3]; m = mtch[2]; d = mtch[1];
+ if (m.length == 1) m = '0'+m;
+ if (d.length == 1) d = '0'+d;
+ dt1 = y+m+d;
+ } else dt1 = a[0];
+ mtch = b[0].match(sorttable.DATE_RE);
+ if (mtch) {
+ y = mtch[3]; m = mtch[2]; d = mtch[1];
+ if (m.length == 1) m = '0'+m;
+ if (d.length == 1) d = '0'+d;
+ dt2 = y+m+d;
+ } else dt2 = b[0];
+ if (dt1==dt2) return 0;
+ if (dt1<dt2) return -1;
+ return 1;
+ },
+ sort_mmdd: function(a,b) {
+ mtch = a[0].match(sorttable.DATE_RE);
+ if (mtch) {
+ y = mtch[3]; d = mtch[2]; m = mtch[1];
+ if (m.length == 1) m = '0'+m;
+ if (d.length == 1) d = '0'+d;
+ dt1 = y+m+d;
+ } else dt1 = a[0];
+ mtch = b[0].match(sorttable.DATE_RE);
+ if (mtch) {
+ y = mtch[3]; d = mtch[2]; m = mtch[1];
+ if (m.length == 1) m = '0'+m;
+ if (d.length == 1) d = '0'+d;
+ dt2 = y+m+d;
+ } else dt2 = b[0];
+ if (dt1==dt2) return 0;
+ if (dt1<dt2) return -1;
+ return 1;
+ },
+
+ shaker_sort: function(list, comp_func) {
+ // A stable sort function to allow multi-level sorting of data
+ // see: http://en.wikipedia.org/wiki/Cocktail_sort
+ // thanks to Joseph Nahmias
+ var b = 0;
+ var t = list.length - 1;
+ var swap = true;
+
+ while(swap) {
+ swap = false;
+ for(var i = b; i < t; ++i) {
+ if ( comp_func(list[i], list[i+1]) > 0 ) {
+ var q = list[i]; list[i] = list[i+1]; list[i+1] = q;
+ swap = true;
+ }
+ } // for
+ t--;
+
+ if (!swap) break;
+
+ for(var i = t; i > b; --i) {
+ if ( comp_func(list[i], list[i-1]) < 0 ) {
+ var q = list[i]; list[i] = list[i-1]; list[i-1] = q;
+ swap = true;
+ }
+ } // for
+ b++;
+
+ } // while(swap)
+ }
+}
+
+/* ******************************************************************
+ Supporting functions: bundled here to avoid depending on a library
+ ****************************************************************** */
+
+// Dean Edwards/Matthias Miller/John Resig
+
+/* for Mozilla/Opera9 */
+if (document.addEventListener) {
+ document.addEventListener("DOMContentLoaded", sorttable.init, false);
+}
+
+/* for Internet Explorer */
+/*@cc_on @*/
+/*@if (@_win32)
+ document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
+ var script = document.getElementById("__ie_onload");
+ script.onreadystatechange = function() {
+ if (this.readyState == "complete") {
+ sorttable.init(); // call the onload handler
+ }
+ };
+/*@end @*/
+
+/* for Safari */
+if (/WebKit/i.test(navigator.userAgent)) { // sniff
+ var _timer = setInterval(function() {
+ if (/loaded|complete/.test(document.readyState)) {
+ sorttable.init(); // call the onload handler
+ }
+ }, 10);
+}
+
+/* for other browsers */
+window.onload = sorttable.init;
+
+// written by Dean Edwards, 2005
+// with input from Tino Zijdel, Matthias Miller, Diego Perini
+
+// http://dean.edwards.name/weblog/2005/10/add-event/
+
+function dean_addEvent(element, type, handler) {
+ if (element.addEventListener) {
+ element.addEventListener(type, handler, false);
+ } else {
+ // assign each event handler a unique ID
+ if (!handler.$$guid) handler.$$guid = dean_addEvent.guid++;
+ // create a hash table of event types for the element
+ if (!element.events) element.events = {};
+ // create a hash table of event handlers for each element/event pair
+ var handlers = element.events[type];
+ if (!handlers) {
+ handlers = element.events[type] = {};
+ // store the existing event handler (if there is one)
+ if (element["on" + type]) {
+ handlers[0] = element["on" + type];
+ }
+ }
+ // store the event handler in the hash table
+ handlers[handler.$$guid] = handler;
+ // assign a global event handler to do all the work
+ element["on" + type] = handleEvent;
+ }
+};
+// a counter used to create unique IDs
+dean_addEvent.guid = 1;
+
+function removeEvent(element, type, handler) {
+ if (element.removeEventListener) {
+ element.removeEventListener(type, handler, false);
+ } else {
+ // delete the event handler from the hash table
+ if (element.events && element.events[type]) {
+ delete element.events[type][handler.$$guid];
+ }
+ }
+};
+
+function handleEvent(event) {
+ var returnValue = true;
+ // grab the event object (IE uses a global event object)
+ event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
+ // get a reference to the hash table of event handlers
+ var handlers = this.events[event.type];
+ // execute each event handler
+ for (var i in handlers) {
+ this.$$handleEvent = handlers[i];
+ if (this.$$handleEvent(event) === false) {
+ returnValue = false;
+ }
+ }
+ return returnValue;
+};
+
+function fixEvent(event) {
+ // add W3C standard event methods
+ event.preventDefault = fixEvent.preventDefault;
+ event.stopPropagation = fixEvent.stopPropagation;
+ return event;
+};
+fixEvent.preventDefault = function() {
+ this.returnValue = false;
+};
+fixEvent.stopPropagation = function() {
+ this.cancelBubble = true;
+}
+
+// Dean's forEach: http://dean.edwards.name/base/forEach.js
+/*
+ forEach, version 1.0
+ Copyright 2006, Dean Edwards
+ License: http://www.opensource.org/licenses/mit-license.php
+*/
+
+// array-like enumeration
+if (!Array.forEach) { // mozilla already supports this
+ Array.forEach = function(array, block, context) {
+ for (var i = 0; i < array.length; i++) {
+ block.call(context, array[i], i, array);
+ }
+ };
+}
+
+// generic enumeration
+Function.prototype.forEach = function(object, block, context) {
+ for (var key in object) {
+ if (typeof this.prototype[key] == "undefined") {
+ block.call(context, object[key], key, object);
+ }
+ }
+};
+
+// character enumeration
+String.forEach = function(string, block, context) {
+ Array.forEach(string.split(""), function(chr, index) {
+ block.call(context, chr, index, string);
+ });
+};
+
+// globally resolve forEach enumeration
+var forEach = function(object, block, context) {
+ if (object) {
+ var resolve = Object; // default
+ if (object instanceof Function) {
+ // functions have a "length" property
+ resolve = Function;
+ } else if (object.forEach instanceof Function) {
+ // the object implements a custom forEach method so use that
+ object.forEach(block, context);
+ return;
+ } else if (typeof object == "string") {
+ // the object is a string
+ resolve = String;
+ } else if (typeof object.length == "number") {
+ // the object is array-like
+ resolve = Array;
+ }
+ resolve.forEach(object, block, context);
+ }
+};
diff --git a/xslt/tellico2html.xsl b/xslt/tellico2html.xsl
new file mode 100644
index 0000000..ae23984
--- /dev/null
+++ b/xslt/tellico2html.xsl
@@ -0,0 +1,625 @@
+<?xml version="1.0"?>
+<!-- WARNING: Tellico uses tc as the internal namespace declaration, and it must be identical here!! -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ xmlns:str="http://exslt.org/strings"
+ xmlns:dyn="http://exslt.org/dynamic"
+ xmlns:exsl="http://exslt.org/common"
+ extension-element-prefixes="str dyn exsl"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for exporting to HTML
+
+ Copyright (C) 2004-2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ The exslt extensions from http://www.exslt.org are required.
+ Specifically, the string and dynamic modules are used. For
+ libxslt, that means the minimum version is 1.0.19.
+
+ This is a horribly messy stylesheet. I would REALLY welcome any
+ recommendations in improving its efficiency.
+
+ The app itself adds group elements that aren't in the data file
+ itself, in order to speed up exporting. So if this stylesheet is
+ being used outside the app, it should still work, but may give
+ slightly different results than when exporting to HTML from
+ within Tellico.
+
+ Customize this file in order to print different columns of
+ fields for each entry. Any version of this file in the user's
+ KDE home directory, such as $KDEHOME/share/apps/tellico/, will
+ override the system file.
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="tellico-common.xsl"/>
+
+<xsl:output method="html"
+ indent="yes"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"
+ encoding="utf-8"/>
+
+<!-- Sort using user's preferred language -->
+<xsl:param name="lang"/>
+
+<!-- To choose which fields of each entry are printed, change the
+ string to a space separated list of field names. To know what
+ fields are available, check the Tellico data file for <field>
+ elements. -->
+<xsl:param name="column-names" select="'title'"/>
+<xsl:variable name="columns" select="str:tokenize($column-names)"/>
+
+<!-- If you want the header row printed, showing which fields
+ are printed, change this to true(), otherwise false() -->
+<xsl:param name="show-headers" select="true()"/>
+
+<!-- The entries may be grouped by a certain field. Keys are needed
+ for both the entries and the grouped field values -->
+<xsl:param name="group-entries" select="false()"/>
+
+<!-- set the maximum image size -->
+<xsl:param name="image-height" select="'100'"/>
+<xsl:param name="image-width" select="'100'"/>
+
+<!-- Set the string representing the element name of the field to group by -->
+<!-- The string will be used to dynamically traverse and select the tree -->
+<!-- It should be an XPath relative to the tc:entry element -->
+<xsl:param name="group-fields" select="'tc:authors/tc:author'"/>
+<xsl:param name="empty-group" select="'(Empty)'"/>
+
+<!-- Up to three fields may be used for sorting. -->
+<xsl:param name="sort-name1" select="'title'"/>
+<xsl:param name="sort-name2" select="''"/>
+<xsl:param name="sort-name3" select="''"/>
+<!-- This is the title just beside the collection name. It will
+ automatically list which fields are used for sorting. -->
+<xsl:param name="sort-title" select="''"/>
+
+<!--
+ ===================================================================
+ The only thing below here that you might want to change is the CSS
+ governing the appearance of the output HTML.
+ ===================================================================
+-->
+
+<!-- The page-title is used for the HTML title -->
+<xsl:param name="page-title" select="'Tellico'"/>
+<xsl:param name="imgdir"/> <!-- dir where field images are located -->
+
+<xsl:param name="entrydir"/> <!-- dir where entry links are located -->
+<xsl:param name="link-entries" select="false()"/> <!-- link entries -->
+
+<!-- In case the field has multiple values, only sort by first one -->
+<xsl:variable name="sort1">
+ <xsl:if test="string-length($sort-name1) &gt; 0">
+ <xsl:value-of select="concat('.//tc:', $sort-name1, '[1]')"/>
+ </xsl:if>
+</xsl:variable>
+<xsl:variable name="sort2">
+ <xsl:if test="string-length($sort-name2) &gt; 0">
+ <xsl:value-of select="concat('.//tc:', $sort-name2, '[1]')"/>
+ </xsl:if>
+</xsl:variable>
+<xsl:variable name="sort3">
+ <xsl:if test="string-length($sort-name3) &gt; 0">
+ <xsl:value-of select="concat('.//tc:', $sort-name3, '[1]')"/>
+ </xsl:if>
+</xsl:variable>
+
+<!-- keys ends up useless since we're using exsl:node-set
+<xsl:key name="fieldsByName" match="tc:field" use="@name"/>
+<xsl:key name="imagesById" match="tc:image" use="@id"/>
+-->
+<xsl:key name="entriesById" match="tc:entry" use="@id"/>
+
+<!-- filename conversion is weird, need a variable for easy replacement -->
+<xsl:variable name="weird">&apos;&quot;</xsl:variable>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<xsl:template match="tc:tellico">
+ <!-- This stylesheet is designed for Tellico document syntax version 10 -->
+ <xsl:call-template name="syntax-version">
+ <xsl:with-param name="this-version" select="'10'"/>
+ <xsl:with-param name="data-version" select="@syntaxVersion"/>
+ </xsl:call-template>
+
+ <html>
+ <head>
+ <style type="text/css">
+ body {
+ font-family: sans-serif;
+ <xsl:if test="count($columns) &gt; 3">
+ font-size: 80%;
+ </xsl:if>
+ background-color: #fff;
+ }
+ #headerblock {
+ padding-top: 10px;
+ margin-bottom: 10px;
+ border-bottom: 1px solid black;
+ overflow: auto;
+ }
+ h1.colltitle {
+ padding: 4px;
+ font-size: 2em;
+ margin: 0px;
+ }
+ span.subtitle {
+ margin-left: 20px;
+ font-size: 0.8em;
+ }
+ form {
+ margin: 5px 0 0 0;
+ float: right;
+ }
+ #searchText {
+ background-color: #eee;
+ }
+ input {
+ padding: 0;
+ margin: 0 0 4px 4px;
+ }
+ .button {
+ padding: 0;
+ margin: 0 0 4px 4px;
+ }
+ table, h4 {
+ margin-left: auto;
+ margin-right: auto;
+ }
+ td.groupName {
+ margin-top: 10px;
+ margin-bottom: 2px;
+ padding-left: 4px;
+ background: #ccc;
+ font-size: 1.1em;
+ font-weight: bolder;
+ }
+ th {
+ color: #000;
+ background-color: #ccc;
+ border: 1px solid #999;
+ font-size: 1.1em;
+ font-weight: bold;
+ padding-left: 4px;
+ padding-right: 4px;
+ }
+ thead tr {
+ cursor: pointer;
+ }
+ tr.entry0 {
+ background-color: #eee;
+ }
+ tr.entry1 {
+ }
+ tr.hidden {
+ display: none;
+ }
+ tr.groupEntry0 {
+ }
+ tr.groupEntry1 {
+ background-color: #eee;
+ }
+ td.field {
+ margin-left: 0px;
+ margin-right: 0px;
+ padding-left: 5px;
+ padding-right: 5px;
+ border: 1px solid #eee;
+ text-align: left;
+ }
+ a.sortheader {
+ text-decoration: none;
+ /*display: block;*/
+ }
+ </style>
+
+ <script type="text/javascript">
+ <xsl:call-template name="sort-array">
+ <xsl:with-param name="fields" select="tc:collection[1]/tc:fields"/>
+ <xsl:with-param name="columns" select="$columns"/>
+ </xsl:call-template>
+ </script>
+
+ <script type="text/javascript" src="tellico2html.js"/>
+
+ <title>
+ <xsl:value-of select="$page-title"/>
+ </title>
+ </head>
+ <body>
+ <xsl:apply-templates select="tc:collection"/>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="tc:collection">
+ <div id="headerblock">
+
+ <form onsubmit="return false" action="">
+ <div>
+ <input type="text" id="searchText"/>
+ <input type="button" class="button" onclick="searchRows()">
+ <xsl:attribute name="value"><i18n>Search</i18n></xsl:attribute>
+ </input>
+ <input type="button" class="button" onclick="showAll()">
+ <xsl:attribute name="value"><i18n>Clear</i18n></xsl:attribute>
+ </input>
+ </div>
+ </form>
+
+ <h1 class="colltitle">
+ <xsl:value-of select="@title"/>
+ <span class="subtitle">
+ <xsl:value-of select="$sort-title"/>
+ </span>
+ </h1>
+ </div>
+
+ <table>
+ <!-- for now, only sort non-grouped tables -->
+ <xsl:if test="not($group-entries)">
+ <xsl:attribute name="class">
+ <xsl:text>sortable</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="id">
+ <xsl:text>table1</xsl:text>
+ </xsl:attribute>
+ </xsl:if>
+
+ <xsl:variable name="fields" select="tc:fields"/>
+ <thead>
+ <tr>
+ <xsl:if test="not($show-headers)">
+ <xsl:attribute name="style">
+ <xsl:text>display: none;</xsl:text>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:for-each select="$columns">
+ <xsl:variable name="column" select="."/>
+ <th>
+ <xsl:call-template name="field-title">
+ <xsl:with-param name="fields" select="$fields"/>
+ <xsl:with-param name="name" select="$column"/>
+ </xsl:call-template>
+ </th>
+ </xsl:for-each>
+ </tr>
+ </thead>
+
+ <tbody>
+ <xsl:choose>
+
+ <!-- If the entries are not being grouped, it's easy -->
+ <xsl:when test="not($group-entries)">
+ <xsl:for-each select="tc:entry">
+ <xsl:sort lang="$lang" select="dyn:evaluate($sort1)"/>
+ <xsl:sort lang="$lang" select="dyn:evaluate($sort2)"/>
+ <xsl:sort lang="$lang" select="dyn:evaluate($sort3)"/>
+ <tr class="entry{position() mod 2}">
+ <xsl:apply-templates select="."/>
+ </tr>
+ </xsl:for-each>
+ </xsl:when> <!-- end ungrouped output -->
+
+ <!-- If the entries are being grouped, it's a bit more involved
+ Tellico helps out by creating groups, but I also want this
+ stylesheet to stand alone, so add additional test for groups -->
+ <xsl:when test="$group-entries and tc:group">
+ <xsl:for-each select="tc:group">
+ <tr>
+ <td class="groupName">
+ <xsl:attribute name="colspan">
+ <xsl:value-of select="count($columns)"/>
+ </xsl:attribute>
+ <xsl:value-of select="@title"/>
+ </td>
+ </tr>
+ <xsl:for-each select="tc:entryRef">
+ <tr class="groupEntry{position() mod 2}">
+ <xsl:apply-templates select="key('entriesById', @id)"/>
+ </tr>
+ </xsl:for-each>
+ </xsl:for-each>
+ </xsl:when>
+
+ <!-- Now is the hard way, use XSL itself to do all the groups -->
+ <xsl:otherwise>
+
+ <xsl:variable name="coll" select="."/>
+
+ <!-- first, copy each entry and add a group attribute -->
+ <xsl:variable name="listing">
+ <xsl:for-each select="tc:entry">
+ <xsl:sort lang="$lang" select="dyn:evaluate($sort1)"/>
+ <xsl:sort lang="$lang" select="dyn:evaluate($sort2)"/>
+ <xsl:sort lang="$lang" select="dyn:evaluate($sort3)"/>
+ <xsl:variable name="entry" select="."/>
+ <xsl:for-each select="dyn:evaluate($group-fields)">
+ <tc:entry group="{.}" id="{$entry/@id}"/>
+ </xsl:for-each>
+ </xsl:for-each>
+ </xsl:variable>
+
+ <!-- now, loop again, while sorting by group and title -->
+ <xsl:variable name="sorted">
+ <xsl:for-each select="exsl:node-set($listing)/tc:entry">
+ <xsl:sort lang="$lang" select="@group"/>
+ <!-- don't repeat an entry in the same group -->
+ <xsl:if test="not(preceding-sibling::*[@group=current()/@group and @id=current()/@id])">
+ <xsl:copy-of select="."/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+
+ <!-- now finally, loop through and print out the entry -->
+ <xsl:for-each select="exsl:node-set($sorted)/tc:entry">
+ <xsl:variable name="g" select="@group"/>
+ <xsl:if test="not(preceding-sibling::tc:entry[@group=$g])">
+ <tr>
+ <td class="groupName">
+ <xsl:attribute name="colspan">
+ <xsl:value-of select="count($columns)"/>
+ </xsl:attribute>
+ <xsl:value-of select="$g"/>
+ </td>
+ </tr>
+ </xsl:if>
+ <tr class="groupEntry{count(preceding-sibling::tc:entry[@group=$g]) mod 2}">
+ <!-- I need the fields and images as variables since exsl:node-set
+ can't use keys in the current document -->
+ <xsl:apply-templates select="$coll/tc:entry[@id=current()/@id]">
+ <xsl:with-param name="fields" select="$coll/tc:fields"/>
+ <xsl:with-param name="images" select="$coll/tc:images"/>
+ </xsl:apply-templates>
+ </tr>
+ </xsl:for-each>
+
+ <!-- don't forget entries in no group -->
+ <xsl:for-each select="dyn:evaluate(concat('tc:entry[not(',$group-fields,')]'))">
+ <xsl:sort lang="$lang" select="dyn:evaluate($sort1)"/>
+ <xsl:sort lang="$lang" select="dyn:evaluate($sort2)"/>
+ <xsl:sort lang="$lang" select="dyn:evaluate($sort3)"/>
+ <xsl:if test="position()=1">
+ <tr>
+ <td class="groupName">
+ <xsl:attribute name="colspan">
+ <xsl:value-of select="count($columns)"/>
+ </xsl:attribute>
+ <xsl:value-of select="$empty-group"/>
+ </td>
+ </tr>
+ </xsl:if>
+ <tr class="groupEntry{position() mod 2}">
+ <xsl:apply-templates select="."/>
+ </tr>
+ </xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </tbody>
+ </table>
+
+ <hr/>
+ <p><a href="http://www.periapsis.org/tellico/"><i18n>Generated by Tellico</i18n></a></p>
+</xsl:template>
+
+<xsl:template name="sort-array">
+ <xsl:param name="fields"/>
+ <xsl:param name="columns"/>
+ var COL_SORT_ARRAY = new Array()
+ <xsl:for-each select="$columns">
+ <xsl:variable name="column" select="."/>
+ <xsl:variable name="field" select="$fields/tc:field[@name = $column]"/>
+ <!-- number sorting is 1, date is 2, everything else is 0 -->
+ <xsl:variable name="sort-type">
+ <xsl:choose>
+ <xsl:when test="$field/@type = 12">
+ <xsl:text>2</xsl:text>
+ </xsl:when>
+ <xsl:when test="$field/@type = 6">
+ <xsl:text>1</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>0</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ COL_SORT_ARRAY[<xsl:value-of select="position()-1"/>] = <xsl:value-of select="$sort-type"/>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="field-title">
+ <xsl:param name="fields"/>
+ <xsl:param name="name"/>
+ <xsl:variable name="name-tokens" select="str:tokenize($name, ':')"/>
+ <!-- the header is the title field of the field node whose name equals the column name -->
+ <xsl:choose>
+ <xsl:when test="$fields">
+ <xsl:value-of select="$fields/tc:field[@name = $name-tokens[last()]]/@title"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$name-tokens[last()]"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="filename">
+ <xsl:param name="entry"/>
+ <xsl:variable name="bad-chars">
+ <xsl:value-of select="translate($entry//tc:title[1],
+ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-',
+ '')"/>
+ </xsl:variable>
+ <xsl:variable name="name">
+ <!-- there should be at least as many underscores as bad characters -->
+ <xsl:value-of select="translate($entry//tc:title[1],
+ concat($bad-chars, $weird),
+ '_________________________________________________________________________________')"/>
+ </xsl:variable>
+ <xsl:value-of select="concat($entrydir, $name, '-', $entry/@id, '.html')"/>
+</xsl:template>
+
+<xsl:template match="tc:entry">
+ <xsl:param name="fields" select="../tc:fields"/>
+ <xsl:param name="images" select="../tc:images"/>
+ <!-- stick all the descendants into a variable -->
+ <xsl:variable name="current" select="descendant::*"/>
+ <xsl:variable name="entry" select="."/>
+ <xsl:for-each select="$columns">
+ <xsl:variable name="column" select="."/>
+ <!-- find all descendants whose name matches the column name -->
+ <xsl:variable name="numvalues" select="count($current[local-name() = $column])"/>
+ <!-- if the field node exists, output its value, otherwise put in a space -->
+ <td class="field">
+ <xsl:choose>
+ <!-- when there is at least one value... -->
+ <xsl:when test="$numvalues &gt; 1">
+ <xsl:variable name="field" select="$fields/tc:field[@name = $column]"/>
+ <xsl:if test="$field/@type=4 or $field/@type=6">
+ <xsl:attribute name="style">
+ <xsl:text>text-align: center; padding-left: 5px</xsl:text>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="$link-entries and $field/@name = 'title'">
+ <a>
+ <xsl:attribute name="href">
+ <xsl:call-template name="filename">
+ <xsl:with-param name="entry" select="$entry"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+
+ <xsl:when test="$numvalues = 1">
+ <xsl:for-each select="$current[local-name() = $column]">
+ <!-- key() doesn't work when using exsl:node-set since the context node
+ is no longer in the current document
+ <xsl:variable name="field" select="key('fieldsByName', $column)"/>
+ -->
+ <xsl:variable name="field" select="$fields/tc:field[@name = $column]"/>
+
+ <xsl:choose>
+
+ <!-- check for multi-column table -->
+ <xsl:when test="$field/@type=8 and $field/tc:prop[@name = 'columns'] &gt; 1">
+ <!-- italicize all columns after the first -->
+ <xsl:value-of select="tc:column[1]"/>
+ <xsl:for-each select="tc:column[position &gt; 1]">
+ <xsl:text> - </xsl:text>
+ <em>
+ <xsl:value-of select="."/>
+ </em>
+ </xsl:for-each>
+ <br/>
+ </xsl:when>
+
+ <!-- boolean and number values -->
+ <xsl:when test="$field/@type=4 or $field/@type=6">
+ <xsl:attribute name="style">
+ <xsl:text>text-align: center; padding-left: 5px</xsl:text>
+ </xsl:attribute>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- next, check for images -->
+ <xsl:when test="$field/@type=10">
+ <xsl:attribute name="style">
+ <xsl:text>text-align: center; padding-left: 5px</xsl:text>
+ </xsl:attribute>
+ <img>
+ <xsl:attribute name="src">
+ <xsl:value-of select="concat($imgdir, .)"/>
+ </xsl:attribute>
+ <xsl:attribute name="alt">
+ <xsl:value-of select="concat('[', $entry//tc:title[1], ']')"/>
+ </xsl:attribute>
+ <xsl:call-template name="image-size">
+ <xsl:with-param name="limit-width" select="$image-width"/>
+ <xsl:with-param name="limit-height" select="$image-height"/>
+ <xsl:with-param name="image" select="$images/tc:image[@id=current()]"/>
+ </xsl:call-template>
+ </img>
+ </xsl:when>
+
+ <!-- if it's a date, format with hyphens -->
+ <xsl:when test="$field/@type=12">
+ <xsl:attribute name="style">
+ <xsl:text>text-align: center; padding-left: 5px</xsl:text>
+ </xsl:attribute>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <!-- finally, it's just a regular value -->
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$link-entries and $field/@name = 'title'">
+ <a>
+ <xsl:attribute name="href">
+ <xsl:call-template name="filename">
+ <xsl:with-param name="entry" select="$entry"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:value-of select="."/>
+ </a>
+ <xsl:if test="position() &lt; $numvalues">
+ <br/>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="simple-field-value">
+ <xsl:with-param name="entry" select="$entry"/>
+ <xsl:with-param name="field" select="$column"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:otherwise>
+
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text> </xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ </xsl:for-each>
+</xsl:template>
+
+</xsl:stylesheet>
+<!-- Local Variables: -->
+<!-- sgml-indent-step: 1 -->
+<!-- sgml-indent-data: 1 -->
+<!-- End: -->
diff --git a/xslt/tellico2onix.xsl b/xslt/tellico2onix.xsl
new file mode 100644
index 0000000..000d451
--- /dev/null
+++ b/xslt/tellico2onix.xsl
@@ -0,0 +1,149 @@
+<?xml version="1.0"?>
+<!-- WARNING: Tellico uses tc as the internal namespace declaration, and it must be identical here!! -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:tc="http://periapsis.org/tellico/"
+ exclude-result-prefixes="tc"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for exporting to ONIX
+
+ Copyright (C) 2005-2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at
+ http://www.periapsis.org/tellico/
+
+ Most of the schema for this spreadsheet was copied from the
+ Alexandria application,(C) Laurent Sansonetti, released under
+ GNU GPL, as is Tellico.
+
+ ===================================================================
+-->
+
+<!-- import common templates -->
+<!-- location depends on being installed correctly -->
+<xsl:import href="tellico-common.xsl"/>
+
+<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ doctype-system="http://www.editeur.org/onix/2.1/reference/onix-international.dtd"/>
+
+<!-- sent date -->
+<xsl:param name="sentDate"/>
+<xsl:param name="version"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="tc:tellico"/>
+</xsl:template>
+
+<xsl:template match="tc:tellico">
+ <!-- This stylesheet is designed for Tellico document syntax version 10 -->
+ <xsl:call-template name="syntax-version">
+ <xsl:with-param name="this-version" select="'10'"/>
+ <xsl:with-param name="data-version" select="@syntaxVersion"/>
+ </xsl:call-template>
+
+ <ONIXMessage>
+ <xsl:apply-templates select="tc:collection"/>
+ </ONIXMessage>
+</xsl:template>
+
+<xsl:template match="tc:collection[not(@type=2) and not(@type=5)]">
+ <xsl:message terminate="yes">
+ <xsl:text>ONIX export only works for book collections and bibliographies.</xsl:text>
+ </xsl:message>
+</xsl:template>
+
+<xsl:template match="tc:collection[@type=2 or @type=5]">
+ <Header>
+ <SentDate>
+ <xsl:value-of select="$sentDate"/>
+ </SentDate>
+ <MessageNote>
+ <xsl:value-of select="@title"/>
+ </MessageNote>
+ </Header>
+ <xsl:apply-templates select="tc:entry"/>
+</xsl:template>
+
+<xsl:template match="tc:entry">
+ <Product>
+ <RecordReference>
+ <xsl:value-of select="@id"/>
+ </RecordReference>
+ <NotificationType>03</NotificationType>
+ <RecordSourceName>
+ <xsl:text>Tellico</xsl:text>
+ <xsl:if test="string-length($version) &gt; 0">
+ <xsl:value-of select="concat(' ', $version)"/>
+ </xsl:if>
+ </RecordSourceName>
+ <ISBN>
+ <xsl:value-of select="translate(tc:isbn, '-', '')"/>
+ </ISBN>
+ <ProductForm>BA</ProductForm> <!-- book -->
+ <DistinctiveTitle>
+ <xsl:value-of select=".//tc:title[1]"/>
+ </DistinctiveTitle>
+ <xsl:for-each select=".//tc:author">
+ <Contributor>
+ <ContributorRole>A01</ContributorRole>
+ <PersonName>
+ <xsl:value-of select="."/>
+ </PersonName>
+ </Contributor>
+ </xsl:for-each>
+ <xsl:if test="tc:comments">
+ <OtherText>
+ <TextTypeCode>12</TextTypeCode>
+ <TextFormat>00</TextFormat> <!-- ascii -->
+ <Text>
+ <xsl:value-of select="tc:comments"/>
+ </Text>
+ </OtherText>
+ </xsl:if>
+ <!-- png files are not supported by ONIX -->
+ <xsl:variable name="lowercase" select="translate(tc:cover, 'JPEGIF', 'jpegif')"/>
+ <xsl:if test="substring($lowercase, string-length($lowercase)-2)='jpg' or
+ substring($lowercase, string-length($lowercase)-3)='jpeg' or
+ substring($lowercase, string-length($lowercase)-2)='gif'">
+ <MediaFile>
+ <MediaFileTypeCode>04</MediaFileTypeCode>
+ <MediaFileFormatCode>
+ <xsl:choose>
+ <xsl:when test="substring($lowercase, string-length($lowercase)-2)='gif'">
+ <xsl:text>02</xsl:text>
+ </xsl:when>
+ <xsl:when test="substring($lowercase, string-length($lowercase)-2)='jpg' or
+ substring($lowercase, string-length($lowercase)-3)='jpeg'">
+ <xsl:text>03</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+ </MediaFileFormatCode>
+ <MediaFileLinkTypeCode>06</MediaFileLinkTypeCode>
+ <MediaFileLink>
+ <xsl:text>images/</xsl:text>
+ <xsl:value-of select="tc:cover"/>
+ </MediaFileLink>
+ </MediaFile>
+ </xsl:if>
+
+ <ProductWebsite>
+ <ProductWebsiteDescription>Amazon</ProductWebsiteDescription>
+ <ProductWebsiteLink>
+ <xsl:text>http://www.amazon.com/exec/obidos/ASIN/</xsl:text>
+ <xsl:value-of select="translate(tc:isbn, '-', '')"/>
+ </ProductWebsiteLink>
+ </ProductWebsite>
+ <PublisherName>
+ <xsl:value-of select=".//tc:publisher[1]"/>
+ </PublisherName>
+ </Product>
+</xsl:template>
+
+</xsl:stylesheet>
+<!-- Local Variables: -->
+<!-- sgml-indent-step: 1 -->
+<!-- sgml-indent-data: 1 -->
+<!-- End: -->
diff --git a/xslt/unixref2tellico.xsl b/xslt/unixref2tellico.xsl
new file mode 100644
index 0000000..b997cac
--- /dev/null
+++ b/xslt/unixref2tellico.xsl
@@ -0,0 +1,174 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://periapsis.org/tellico/"
+ xmlns:cr="http://www.crossref.org/xschema/1.0"
+ xmlns:str="http://exslt.org/strings"
+ xmlns:exsl="http://exslt.org/common"
+ exclude-result-prefixes="cr"
+ extension-element-prefixes="str exsl"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for importing data from crossref.org
+ in the 'unixref' format.
+
+ See http://www.crossref.org/schema/unixref1.0.xsd
+
+ Copyright (C) 2008 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ doctype-public="-//Robby Stephenson/DTD Tellico V10.0//EN"
+ doctype-system="http://periapsis.org/tellico/dtd/v10/tellico.dtd"/>
+
+<!-- by default, don't output text -->
+<xsl:template match="text()" />
+
+<xsl:template match="/">
+ <tellico syntaxVersion="10">
+ <!-- always bibliography -->
+ <collection title="CrossRef Import" type="5">
+ <fields>
+ <field name="_default"/>
+ <xsl:if test=".//cr:issn">
+ <field flags="0" title="ISSN" category="Publishing" format="4" type="1" name="issn" i18n="true"/>
+ </xsl:if>
+ </fields>
+ <xsl:apply-templates select="cr:doi_records/cr:doi_record/cr:crossref"/>
+ </collection>
+ </tellico>
+</xsl:template>
+
+<xsl:template match="cr:crossref">
+ <entry>
+ <xsl:apply-templates/>
+ </entry>
+</xsl:template>
+
+<xsl:template match="cr:book">
+ <entry-type>book</entry-type>
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="cr:journal">
+ <entry-type>article</entry-type>
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="cr:book_metadata">
+ <title>
+ <xsl:value-of select="cr:titles/cr:title[1]"/>
+ </title>
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="cr:journal_article">
+ <title>
+ <xsl:value-of select="cr:titles/cr:title[1]"/>
+ </title>
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="cr:isbn">
+ <isbn>
+ <xsl:value-of select="."/>
+ </isbn>
+</xsl:template>
+
+<xsl:template match="cr:issn">
+ <issn>
+ <xsl:value-of select="."/>
+ </issn>
+</xsl:template>
+
+<xsl:template match="cr:publisher">
+ <publisher>
+ <xsl:value-of select="cr:publisher_name"/>
+ </publisher>
+ <address>
+ <xsl:value-of select="cr:publisher_place"/>
+ </address>
+</xsl:template>
+
+<xsl:template match="cr:journal_metadata">
+ <journal>
+ <xsl:value-of select="cr:full_title"/>
+ </journal>
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="cr:edition">
+ <edition>
+ <xsl:value-of select="."/>
+ </edition>
+</xsl:template>
+
+<xsl:template match="cr:volume">
+ <volume>
+ <xsl:value-of select="."/>
+ </volume>
+</xsl:template>
+
+<xsl:template match="cr:issue">
+ <number>
+ <xsl:value-of select="."/>
+ </number>
+</xsl:template>
+
+<xsl:template match="cr:series_metadata">
+ <series>
+ <xsl:value-of select="cr:titles/cr:title[1]"/>
+ </series>
+</xsl:template>
+
+<xsl:template match="cr:doi_data">
+ <doi>
+ <xsl:value-of select="cr:doi"/>
+ </doi>
+ <url>
+ <xsl:value-of select="cr:resource"/>
+ </url>
+</xsl:template>
+
+<xsl:template match="cr:publication_date">
+ <year>
+ <xsl:value-of select="cr:year"/>
+ </year>
+ <month>
+ <xsl:value-of select="cr:month"/>
+ </month>
+</xsl:template>
+
+<xsl:template match="cr:pages">
+ <pages>
+ <xsl:value-of select="concat(cr:first_page,'-',cr:last_page)"/>
+ </pages>
+</xsl:template>
+
+<xsl:template match="cr:contributors">
+ <authors>
+ <xsl:for-each select="cr:person_name[@contributor_role='author']">
+ <author>
+ <xsl:value-of select="concat(cr:given_name,' ',cr:surname)"/>
+ </author>
+ </xsl:for-each>
+ </authors>
+ <editors>
+ <xsl:for-each select="cr:person_name[@contributor_role='editor']">
+ <editor>
+ <xsl:value-of select="concat(cr:given_name,' ',cr:surname)"/>
+ </editor>
+ </xsl:for-each>
+ </editors>
+ <organization>
+ <xsl:value-of select="cr:organization[1]"/>
+ </organization>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/vhs-logo.png b/xslt/vhs-logo.png
new file mode 100644
index 0000000..176d5c5
--- /dev/null
+++ b/xslt/vhs-logo.png
Binary files differ
diff --git a/xslt/welcome.html b/xslt/welcome.html
new file mode 100644
index 0000000..27bcd83
--- /dev/null
+++ b/xslt/welcome.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<style type="text/css">
+ body {
+ margin: 0px;
+ padding: 0px;
+ color: $FGCOLOR$;
+ background-color: $BGCOLOR$;
+ background-image: url($IMGDIR$gradient_bg.png);
+ background-repeat: repeat;
+ }
+ h1 {
+ margin: 0px;
+ padding: 8px;
+ font-size: 1.8em;
+ color: $COLOR1$;
+ background-color: $COLOR2$;
+ background-image: url($IMGDIR$gradient_header.png);
+ background-repeat: repeat-x;
+ border-bottom: 1px outset black;
+ text-align: center;
+ }
+ h3 {
+ text-align: center;
+ font-size: 1em;
+ margin-left:15%;
+ margin-right:15%;
+ }
+ div#content {
+ padding-left: 1%;
+ padding-right: 1%;
+ }
+ div.category {
+ padding: 0px 0px 0px 4px;
+ margin: 8px;
+ border: 1px solid #181818;
+ text-align: center;
+ /* if background is grey, text has to be black */
+ color: #000;
+ background-color: #ccc;
+ }
+ table {
+ border-collapse: collapse;
+ border-spacing: 0px;
+ max-width: 100%;
+ }
+ </style>
+</head>
+<body>
+<h1>$BANNER$</h1>
+<div id="content">
+<div class="category">
+$WELCOMETEXT$
+</div>
+
+</div>
+</body>
+</html>
diff --git a/xslt/xmp2tellico.xsl b/xslt/xmp2tellico.xsl
new file mode 100644
index 0000000..3bf9a31
--- /dev/null
+++ b/xslt/xmp2tellico.xsl
@@ -0,0 +1,176 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://periapsis.org/tellico/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:jabref="http://jabref.sourceforge.net/bibteXMP/"
+ xmlns:str="http://exslt.org/strings"
+ xmlns:m="uri:months"
+ extension-element-prefixes="str"
+ exclude-result-prefixes="rdf dc jabref"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for converting XMP data
+
+ Copyright (C) 2007 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<!-- lookup table for months -->
+<m:months>
+ <m:month id="Jan">1</m:month>
+ <m:month id="Feb">2</m:month>
+ <m:month id="Mar">3</m:month>
+ <m:month id="Apr">4</m:month>
+ <m:month id="May">5</m:month>
+ <m:month id="Jun">6</m:month>
+ <m:month id="Jul">7</m:month>
+ <m:month id="Aug">8</m:month>
+ <m:month id="Sep">9</m:month>
+ <m:month id="Oct">10</m:month>
+ <m:month id="Nov">11</m:month>
+ <m:month id="Dec">12</m:month>
+ <!-- months in other languages could be added easily -->
+</m:months>
+<xsl:key name="months" match="m:month" use="@id"/>
+<xsl:variable name="months-top" select="document('')/*/m:months"/>
+
+<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ doctype-public="-//Robby Stephenson/DTD Tellico V9.0//EN"
+ doctype-system="http://periapsis.org/tellico/dtd/v9/tellico.dtd"/>
+
+<!-- for lower-casing -->
+<xsl:variable name="lcletters">abcdefghijklmnopqrstuvwxyz</xsl:variable>
+<xsl:variable name="ucletters">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
+
+<!-- disable default behavior -->
+<xsl:template match="text()|@*"></xsl:template>
+
+<xsl:template match="/">
+ <tellico syntaxVersion="9">
+ <collection title="XMP Conversion" type="5">
+ <fields>
+ <field name="_default"/>
+ </fields>
+ <xsl:apply-templates select=".//rdf:RDF"/>
+ </collection>
+ </tellico>
+</xsl:template>
+
+<xsl:template match="rdf:RDF">
+ <entry>
+ <xsl:apply-templates/>
+ </entry>
+</xsl:template>
+
+<xsl:template match="dc:title">
+ <title><xsl:value-of select="normalize-space(.)"/></title>
+</xsl:template>
+
+<xsl:template match="dc:type">
+ <entry-type><xsl:value-of select="normalize-space(translate(., $ucletters, $lcletters))"/></entry-type>
+</xsl:template>
+
+<xsl:template match="dc:creator">
+ <authors>
+ <xsl:call-template name="multiple-values">
+ <xsl:with-param name="value" select="."/>
+ <xsl:with-param name="field" select="'author'"/>
+ </xsl:call-template>
+ </authors>
+</xsl:template>
+
+<xsl:template match="dc:subject">
+ <keywords>
+ <xsl:call-template name="multiple-values">
+ <xsl:with-param name="value" select="."/>
+ <xsl:with-param name="field" select="'keyword'"/>
+ </xsl:call-template>
+ </keywords>
+</xsl:template>
+
+<xsl:template match="dc:date">
+ <xsl:variable name="tokens" select="str:tokenize(., '-')"/>
+ <year><xsl:value-of select="normalize-space($tokens[1])"/></year>
+ <month><xsl:value-of select="normalize-space($tokens[2])"/></month>
+</xsl:template>
+
+<xsl:template match="dc:identifier">
+ <!-- assume DOI requires a period and a slash -->
+ <xsl:if test="not(//jabref:doi) and
+ (contains(.,'.') and contains(.,'/'))">
+ <doi><xsl:value-of select="normalize-space(.)"/></doi>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="jabref:year">
+ <xsl:if test="not(//dc:date)">
+ <year><xsl:value-of select="normalize-space(.)"/></year>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="jabref:month">
+ <xsl:if test="not(//dc:date)">
+ <month>
+ <xsl:apply-templates select="$months-top">
+ <xsl:with-param name="month-id" select="normalize-space(.)"/>
+ </xsl:apply-templates>
+ </month>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="jabref:jabrefkey">
+ <bibtex-key><xsl:value-of select="normalize-space(.)"/></bibtex-key>
+</xsl:template>
+
+<xsl:template match="jabref:journal">
+ <journal><xsl:value-of select="normalize-space(.)"/></journal>
+</xsl:template>
+
+<xsl:template match="jabref:url">
+ <url><xsl:value-of select="normalize-space(.)"/></url>
+</xsl:template>
+
+<xsl:template match="jabref:doi">
+ <doi><xsl:value-of select="normalize-space(.)"/></doi>
+</xsl:template>
+
+<xsl:template name="multiple-values">
+ <xsl:param name="value"/>
+ <xsl:param name="field"/>
+ <xsl:choose>
+ <xsl:when test="$value/rdf:Seq">
+ <xsl:for-each select="$value/rdf:Seq/rdf:li">
+ <xsl:element name="{$field}">
+ <xsl:value-of select="normalize-space(.)"/>
+ </xsl:element>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:for-each select="$value/*">
+ <xsl:element name="{$field}">
+ <xsl:value-of select="normalize-space(.)"/>
+ </xsl:element>
+ </xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="m:months">
+ <xsl:param name="month-id"/>
+ <xsl:variable name="m" select="key('months', $month-id)"/>
+ <xsl:if test="$m">
+ <xsl:value-of select="$m"/>
+ </xsl:if>
+ <xsl:if test="not($m)">
+ <xsl:value-of select="$month-id"/>
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/yahoo2tellico.xsl b/xslt/yahoo2tellico.xsl
new file mode 100644
index 0000000..4c6faf3
--- /dev/null
+++ b/xslt/yahoo2tellico.xsl
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://periapsis.org/tellico/"
+ xmlns:yh="urn:yahoo:srchmm"
+ xmlns:exsl="http://exslt.org/common"
+ extension-element-prefixes="exsl"
+ version="1.0">
+
+<!--
+ ===================================================================
+ Tellico XSLT file - used for importing Yahoo! album search data.
+
+ Copyright (C) 2004-2006 Robby Stephenson - robby@periapsis.org
+
+ This XSLT stylesheet is designed to be used with the 'Tellico'
+ application, which can be found at http://www.periapsis.org/tellico/
+
+ ===================================================================
+-->
+
+<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ doctype-public="-//Robby Stephenson/DTD Tellico V10.0//EN"
+ doctype-system="http://periapsis.org/tellico/dtd/v10/tellico.dtd"/>
+
+<xsl:template match="/">
+ <tellico syntaxVersion="10">
+ <collection title="Yahoo! Import" type="4"> <!-- 4 is music -->
+ <fields>
+ <field name="_default"/>
+ <!-- the importer will actually download the image and ignore this field -->
+ <field flags="0" title="Yahoo Album" category="General" format="4" type="7" name="yahoo"/>
+ <field flags="0" title="Image" category="Images" format="4" type="7" name="image"/>
+ </fields>
+ <xsl:for-each select="yh:ResultSet/yh:Result">
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+ </collection>
+ </tellico>
+</xsl:template>
+
+<xsl:template match="yh:Result">
+ <entry>
+ <yahoo>
+ <xsl:value-of select="@id"/>
+ </yahoo>
+
+ <image>
+ <xsl:value-of select="yh:Thumbnail/yh:Url"/>
+ </image>
+
+ <title>
+ <xsl:value-of select="yh:Title"/>
+ </title>
+
+ <artists>
+ <xsl:for-each select="yh:Artist">
+ <artist>
+ <xsl:value-of select="."/>
+ </artist>
+ </xsl:for-each>
+ </artists>
+
+ <year>
+ <xsl:call-template name="year">
+ <xsl:with-param name="value" select="yh:ReleaseDate"/>
+ </xsl:call-template>
+ </year>
+
+ <labels>
+ <xsl:for-each select="yh:Publisher">
+ <label>
+ <xsl:value-of select="."/>
+ </label>
+ </xsl:for-each>
+ </labels>
+ </entry>
+
+</xsl:template>
+
+<xsl:template name="year">
+ <xsl:param name="value"/>
+ <!-- assume that Yahoo always puts the year first -->
+ <xsl:value-of select="substring($value, 0, 5)"/>
+</xsl:template>
+
+</xsl:stylesheet>