Update to upstream version 1.3.6

pull/1/head
Slávek Banko 10 years ago
parent 3c13229d98
commit 2e02da046d

@ -1,3 +1,84 @@
2009-09-26 Robby Stephenson <robby@periapsis.org>
* Updated Amazon fetcher to use authentication.
* Released Tellico 1.3.6
2009-02-14 Robby Stephenson <robby@periapsis.org>
* Released Tellico 1.3.5.
2009-02-04 Robby Stephenson <robby@periapsis.org>
* Reverted change from 2007 that merged entries by combining all values in multiple-value fields.
2009-02-02 Robby Stephenson <robby@periapsis.org>
* Fixed the CueCat decoder to work for ISBN searches, as well as UPC.
2009-01-30 Robby Stephenson <robby@periapsis.org>
* Updated Deliciour Library 1 importer to handle movies and games.
* Fixed Ubuntu bug#317822, don't mark collection modified when image is found in local data directory.
* Fixed query bug with z39.50 ISBN search.
2008-12-07 Robby Stephenson <robby@periapsis.org>
* Updated it.po, thanks to Valerio Ricci.
2008-10-23 Robby Stephenson <robby@periapsis.org>
* Added date, time, and username as available params for the XSLT export.
2008-09-13 Robby Stephenson <robby@periapsis.org>
* Released Tellico 1.3.4.
2008-09-04 Robby Stephenson <robby@periapsis.org>
* Fixed error with consecutive tabs in CSV import.
2008-08-26 Robby Stephenson <robby@periapsis.org>
* Fixed bug with image links in reports not being linked correctly.
2008-08-20 Robby Stephenson <robby@periapsis.org>
* Added minimal searching for board games from Amazon.
2008-08-07 Robby Stephenson <robby@periapsis.org>
* Changed Choice fields to sort by position in list.
2008-07-25 Robby Stephenson <robby@periapsis.org>
* Added ESC key for clearing quick filter.
* Improved drag/drop to match on file extension after checking mimetype.
2008-07-22 Robby Stephenson <robby@periapsis.org>
* Updated IMDb plot regexp.
2008-07-09 Robby Stephenson <robby@periapsis.org>
* Fixed EntryView to honor copy() command properly, for clipboard.
* Released Tellico 1.3.3.
2008-06-24 Robby Stephenson <robby@periapsis.org>
* Updated Porbase URL in z39.50 server list.
2008-06-13 Robby Stephenson <robby@periapsis.org>
* Updated drag-and-drop to allow HTTP urls.
2008-06-12 Robby Stephenson <robby@periapsis.org>
* Changed Arxiv fetcher to remove ID version number for results.
2008-06-07 Robby Stephenson <robby@periapsis.org>
* Fixed bug with merging file catalogs, to properly match on URL.
2008-05-24 Robby Stephenson <robby@periapsis.org>
* Released Tellico 1.3.2.1.

@ -66,6 +66,9 @@
/* Define if you have libz */
#undef HAVE_LIBZ
/* Define to 1 if you have the <linux/videodev.h> header file. */
#undef HAVE_LINUX_VIDEODEV_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
@ -174,6 +177,9 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if the XML loader should use SAX */
#undef SAX_SUPPORT
/* The size of `char', as computed by sizeof. */
#undef SIZEOF_CHAR

@ -40,7 +40,7 @@ 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
AM_INIT_AUTOMAKE(tellico, 1.3.6) dnl searches for some needed programs
KDE_SET_PREFIX
@ -491,7 +491,8 @@ 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_ooo_datadir="${withval}/program"
ac_ooo_basisdir="${withval}/basis3.0"])
AC_ARG_WITH([ooo-libdir],
AC_HELP_STRING([--with-ooo-libdir=DIR],
[where the OpenOffice.org program libraries are installed (<ooo-dir>/program)]),
@ -542,6 +543,13 @@ 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']]))
AC_FIND_FILE([offapi.rdb],
[$ac_ooo_basisdir/program $ac_ooo_libdir $ac_ooo_datadir],
offapi_dir)
if test "$offapi_dir" != "NO"; then
OFFICE_registry="$OFFICE_registry $offapi_dir/offapi.rdb"
fi
dnl Substitute the values
AC_SUBST(OFFICE_SDK_includes)
AC_SUBST(OFFICE_libadd)
@ -562,7 +570,7 @@ AC_ARG_ENABLE(exempi,
)
if test x$enable_libexempi = xyes; then
KDE_PKG_CHECK_MODULES(EXEMPI,
KDE_PKG_CHECK_MODULES(EXEMPI,
[exempi-2.0 >= 1.99.0],
[have_exempi=yes],
[have_exempi=no])
@ -586,8 +594,8 @@ AC_ARG_ENABLE(poppler,
)
if test x$enable_libpoppler = xyes; then
KDE_PKG_CHECK_MODULES(POPPLER,
[poppler-qt >= 0.5],
KDE_PKG_CHECK_MODULES(POPPLER,
[poppler-tqt >= 0.5],
[have_poppler=yes],
[have_poppler=no])
AC_SUBST(POPPLER_LIBS)
@ -609,12 +617,32 @@ AC_ARG_ENABLE(webcam,
[enable_webcam=no]
)
if test x$enable_webcam = xyes; then
KDE_CHECK_HEADERS([linux/videodev.h],
[],
[enable_webcam="no"])
fi
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 ----------
dnl ---------- SAX CHECK ----------
AC_ARG_ENABLE(sax,
AC_HELP_STRING([--enable-sax], [enable SAX document loading (experimental), default=disable]),
[enable_sax=$enableval],
[enable_sax=no]
)
if test x$enable_sax = xyes; then
AC_DEFINE(SAX_SUPPORT, 1, [Define to 1 if the XML loader should use SAX])
fi
dnl ---------- END SAX CHECK ----------
KDE_CREATE_SUBDIRSLIST
AC_CONFIG_FILES([ Makefile ])
AC_CONFIG_FILES([ doc/Makefile ])

@ -2,7 +2,7 @@
KDE_ENABLE_HIDDEN_VISIBILITY
AM_INIT_AUTOMAKE(tellico,1.3.2.1)
AM_INIT_AUTOMAKE(tellico,1.3.6)
dnl AM_KDE_MIN_VERSION(MIN-VERSION-MAJOR, MIN-VERSION-MINOR, MIN-VERSION-MICRO)
dnl (taken from KMyMoney2)
@ -428,7 +428,8 @@ 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_ooo_datadir="${withval}/program"
ac_ooo_basisdir="${withval}/basis3.0"])
AC_ARG_WITH([ooo-libdir],
AC_HELP_STRING([--with-ooo-libdir=DIR],
[where the OpenOffice.org program libraries are installed (<ooo-dir>/program)]),
@ -479,6 +480,13 @@ 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']]))
AC_FIND_FILE([offapi.rdb],
[$ac_ooo_basisdir/program $ac_ooo_libdir $ac_ooo_datadir],
offapi_dir)
if test "$offapi_dir" != "NO"; then
OFFICE_registry="$OFFICE_registry $offapi_dir/offapi.rdb"
fi
dnl Substitute the values
AC_SUBST(OFFICE_SDK_includes)
AC_SUBST(OFFICE_libadd)
@ -499,7 +507,7 @@ AC_ARG_ENABLE(exempi,
)
if test x$enable_libexempi = xyes; then
KDE_PKG_CHECK_MODULES(EXEMPI,
KDE_PKG_CHECK_MODULES(EXEMPI,
[exempi-2.0 >= 1.99.0],
[have_exempi=yes],
[have_exempi=no])
@ -523,8 +531,8 @@ AC_ARG_ENABLE(poppler,
)
if test x$enable_libpoppler = xyes; then
KDE_PKG_CHECK_MODULES(POPPLER,
[poppler-qt >= 0.5],
KDE_PKG_CHECK_MODULES(POPPLER,
[poppler-tqt >= 0.5],
[have_poppler=yes],
[have_poppler=no])
AC_SUBST(POPPLER_LIBS)
@ -546,9 +554,36 @@ AC_ARG_ENABLE(webcam,
[enable_webcam=no]
)
if test x$enable_webcam = xyes; then
KDE_CHECK_HEADERS([linux/videodev.h],
[],
[enable_webcam="no"])
fi
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 ----------
dnl ---------- SAX CHECK ----------
AC_ARG_ENABLE(sax,
AC_HELP_STRING([--enable-sax], [enable SAX document loading (experimental), default=disable]),
[enable_sax=$enableval],
[enable_sax=no]
)
if test x$enable_sax = xyes; then
AC_DEFINE(SAX_SUPPORT, 1, [Define to 1 if the XML loader should use SAX])
fi
dnl ---------- END SAX CHECK ----------
dnl -------- fix TQTDCOPIDLNG ---------
if test "$kde_cv_tqt" = "no"; then
if test -z "$TQTDCOPIDLNG"; then
KDE_FIND_PATH(dcopidlng, TQTDCOPIDLNG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidlng)])
fi
fi

@ -2,4 +2,22 @@ To regenerate the message strings, type
make package-messages
from the top-level directory
from the top-level directory.
Please note that you need a special for KDE patched version of xgettext. You
can obtain it from http://packages.ubuntu.com/de/edgy/gettext-kde. Don't forget
to make this binary available as xgettext (instead of kde-xgettext) by e.g.
creating a link in your search path.
If you don't do this, code such as i18n("Comic Book Illustrator", "Artist")
would correspond to two separate strings "Comic Book Illustrator" and
"Artist" instead of a combined entry from which only the second one has to be
translated:
msgid ""
"_: Comic Book Illustrator\n"
"Artist"
msgstr "Künstler"
You also need the tool extractrc. In Debian it is available in the package
tdesdk-scripts.

@ -16,7 +16,7 @@ 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"
"PO-Revision-Date: 2008-05-24 22:47+0200\n"
"Last-Translator: Jens Seidel <jensseidel@users.sf.net>\n"
"Language-Team: german <de@li.org>\n"
"MIME-Version: 1.0\n"
@ -1094,7 +1094,7 @@ msgstr "Mechanismus"
#: collections/boardgamecollection.cpp:66
msgid "Designer"
msgstr ""
msgstr "Designer"
#: collections/boardgamecollection.cpp:72
msgid "Number of Players"
@ -1792,7 +1792,7 @@ msgstr ""
#: fetch/discogsfetcher.cpp:718
msgid "Discogs Link"
msgstr ""
msgstr "Discogs-Link"
#: newstuff/dialog.cpp:94
msgid "Get Hot New Stuff"
@ -1986,9 +1986,8 @@ msgid "Scanning audio files..."
msgstr "Taste Audio-Dateien ab ..."
#: translators/audiofileimporter.cpp:129
#, fuzzy
msgid "Bitrate"
msgstr "Bibtex"
msgstr "Bitrate"
#: translators/audiofileimporter.cpp:160 translators/audiofileimporter.cpp:170
msgid "Tracks (Disc %1)"
@ -2023,14 +2022,12 @@ msgstr ""
#: translators/audiofileimporter.cpp:352
msgid "Include &bitrate"
msgstr ""
msgstr "&Bitrate inkludieren"
#: 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."
"Wenn markiert, wird die Bitrate für jede Spur zu den Einträgen hinzugefügt."
#: translators/csvexporter.cpp:40
msgid "CSV"
@ -5369,7 +5366,7 @@ msgstr "Copac (Großbritannien und Irland)"
#: scripts.cpp:2
msgid "BoardGameGeek"
msgstr ""
msgstr "BoardGameGeek"
#: scripts.cpp:4
msgid "Dark Horse Comics"

1851
po/it.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,19 +1,22 @@
# translation of ru.po to Russian
# Copyright (C) 2007 Robby Stephenson <robby@periapsis.org>.
# Калимуллин Артур <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>.
# Denis Pesotsky <St.MPA3b@gmail.com>, 2008.
# Denis Pesotsky <denis@kde.ru>, 2008.
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"
"PO-Revision-Date: 2008-10-22 21:27+0400\n"
"Last-Translator: Denis Pesotsky <denis@kde.ru>\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"
"X-Generator: Lokalize 0.2\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: cite/lyxpipe.cpp:50
msgid "<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>"
@ -21,7 +24,7 @@ msgstr "<qt>Ошибка записи на канал сервера <b>%1</b>.<
#: cite/openoffice.cpp:82
msgid "Connecting to OpenOffice.org..."
msgstr "Подсоединение к OpenOffice.org..."
msgstr "Подсоединение к OpenOffice.org"
#: cite/openoffice.cpp:165 cite/openoffice.cpp:186
msgid "OpenOffice.org Connection"
@ -115,7 +118,7 @@ msgstr "Очистить"
#: gui/imagewidget.cpp:57
msgid "Select Image..."
msgstr "Выбрать изображение..."
msgstr "Выбрать изображение"
#: gui/imagewidget.cpp:63
msgid "Save link only"
@ -652,7 +655,7 @@ msgstr "Создан"
#: collections/filecatalog.cpp:89
msgid "Modified"
msgstr "Модифицирован"
msgstr "Изменён"
#: collections/filecatalog.cpp:93
msgid "Meta Info"
@ -1780,7 +1783,7 @@ msgstr "Описание выделенного отображается зде
#: newstuff/dialog.cpp:224
msgid "Downloading information..."
msgstr "Загрузка информации..."
msgstr "Загрузка информации"
#: controller.cpp:135 fetchdialog.cpp:226 fetchdialog.cpp:333
#: fetchdialog.cpp:451 fetchdialog.cpp:506 newstuff/dialog.cpp:297
@ -1796,7 +1799,7 @@ msgstr "Обновить"
#: newstuff/dialog.cpp:413
msgid "Installing item..."
msgstr "Установка...."
msgstr "Установка"
#: translators/bibteximporter.cpp:79
msgid "No valid bibtex entries were found"
@ -1913,7 +1916,7 @@ msgstr "Избранное"
#: translators/audiofileimporter.cpp:69
msgid "Scanning audio files..."
msgstr "Сканируются аудио-файлы..."
msgstr "Сканируются аудио-файлы"
#: translators/audiofileimporter.cpp:129
msgid "Bitrate"
@ -2025,7 +2028,7 @@ msgstr "Может быть использован любой другой ра
#: translators/filelistingimporter.cpp:63
msgid "Scanning files..."
msgstr "Сканируются файлы..."
msgstr "Сканируются файлы"
#: translators/filelistingimporter.cpp:191
msgid "File Listing Options"
@ -2192,11 +2195,11 @@ msgstr ""
#: translators/importer.h:100
msgid "Loading data..."
msgstr "Загружаются данные..."
msgstr "Загружаются данные"
#: translators/importer.h:100
msgid "Loading %1..."
msgstr "Загружается %1..."
msgstr "Загружается %1"
#: translators/bibtexexporter.cpp:48
msgid "Bibtex"
@ -2484,7 +2487,7 @@ msgstr "не соответствует выражению"
#: filterdialog.cpp:90
msgid "Edit..."
msgstr "Редактировать..."
msgstr "Редактировать"
#: filterdialog.cpp:282
msgid "Advanced Filter"
@ -2540,11 +2543,11 @@ msgstr "Дата"
#: entryupdater.cpp:81
msgid "Updating %1..."
msgstr "Обновление %1..."
msgstr "Обновление %1"
#: entryupdater.cpp:83
msgid "Updating entries..."
msgstr "Обновление записей..."
msgstr "Обновление записей"
#: entryupdater.cpp:85
msgid "Update Entries"
@ -2552,7 +2555,7 @@ msgstr "Обновить записи"
#: entryupdater.cpp:99
msgid "Updating <b>%1</b>..."
msgstr "Обновление <b>%1</b>..."
msgstr "Обновление <b>%1</b>"
#: entryupdater.cpp:209
msgid "Select Match"
@ -2875,11 +2878,11 @@ msgstr "Сохранить документ"
#: mainwindow.cpp:305
msgid "Save the document as a different file..."
msgstr "Сохранить документ в другой файл..."
msgstr "Сохранить документ в другой файл"
#: mainwindow.cpp:307
msgid "Print the contents of the document..."
msgstr "Напечатать содержимое этого документа..."
msgstr "Напечатать содержимое этого документа"
#: mainwindow.cpp:309
msgid "Quit the application"
@ -2891,7 +2894,7 @@ msgstr "Импортировать коллекцию из других форм
#: mainwindow.cpp:324
msgid "Import Tellico Data..."
msgstr "Импорт из файла Tellico..."
msgstr "Импорт из файла Tellico"
#: mainwindow.cpp:325
msgid "Import another Tellico data file"
@ -2899,7 +2902,7 @@ msgstr "Импортировать из другой коллекции Tellico"
#: mainwindow.cpp:331
msgid "Import CSV Data..."
msgstr "Импорт из CSV..."
msgstr "Импорт из CSV"
#: mainwindow.cpp:332
msgid "Import a CSV file"
@ -2907,7 +2910,7 @@ msgstr "Импорт из файла CSV"
#: mainwindow.cpp:338
msgid "Import MODS Data..."
msgstr "Импорт из MODS..."
msgstr "Импорт из MODS"
#: mainwindow.cpp:339
msgid "Import a MODS data file"
@ -2915,7 +2918,7 @@ msgstr "Импорт из файла MODS"
#: mainwindow.cpp:345
msgid "Import Alexandria Data..."
msgstr "Импорт из файла Alexandria..."
msgstr "Импорт из файла Alexandria"
#: mainwindow.cpp:346
msgid "Import data from the Alexandria book collection manager"
@ -2923,7 +2926,7 @@ msgstr "Импорт из менеджера коллекций книг Alexand
#: mainwindow.cpp:352
msgid "Import Delicious Library Data..."
msgstr "Импорт из файла Delicious..."
msgstr "Импорт из файла Delicious"
#: mainwindow.cpp:353
msgid "Import data from Delicious Library"
@ -2931,7 +2934,7 @@ msgstr "Импорт данных из файла Delicious"
#: mainwindow.cpp:359
msgid "Import Referencer Data..."
msgstr "Импорт из файла Referencer..."
msgstr "Импорт из файла Referencer"
#: mainwindow.cpp:360
msgid "Import data from Referencer"
@ -2939,7 +2942,7 @@ msgstr "Импортировать данные из Referencer"
#: mainwindow.cpp:366
msgid "Import Bibtex Data..."
msgstr "Импорт из Bibtex..."
msgstr "Импорт из Bibtex"
#: mainwindow.cpp:367
msgid "Import a bibtex bibliography file"
@ -2947,7 +2950,7 @@ msgstr "Импортировать из файла библиографии bibt
#: mainwindow.cpp:373
msgid "Import Bibtexml Data..."
msgstr "Импорт из Bibtexml..."
msgstr "Импорт из Bibtexml"
#: mainwindow.cpp:374
msgid "Import a Bibtexml bibliography file"
@ -2955,7 +2958,7 @@ msgstr "Импортировать из файла библиографии Bibt
#: mainwindow.cpp:380
msgid "Import RIS Data..."
msgstr "Импорт из RIS..."
msgstr "Импорт из RIS"
#: mainwindow.cpp:381
msgid "Import an RIS reference file"
@ -2963,7 +2966,7 @@ msgstr "Импортировать из файла RIS"
#: mainwindow.cpp:387
msgid "Import PDF File..."
msgstr "Импорт из PDF..."
msgstr "Импорт из PDF"
#: mainwindow.cpp:388
msgid "Import a PDF file"
@ -2971,7 +2974,7 @@ msgstr "Импортировать из файла PDF"
#: mainwindow.cpp:394
msgid "Import Audio File Metadata..."
msgstr "Импорт из данных аудио файла..."
msgstr "Импорт из данных аудио файла"
#: mainwindow.cpp:395
msgid "Import meta-data from audio files"
@ -2979,7 +2982,7 @@ msgstr "Импорт из данных тегов аудио файлов"
#: mainwindow.cpp:404
msgid "Import Audio CD Data..."
msgstr "Импорт из Audio CD..."
msgstr "Импорт из Audio CD"
#: mainwindow.cpp:405
msgid "Import audio CD information"
@ -2987,7 +2990,7 @@ msgstr "Импорт информации об Audio CD"
#: mainwindow.cpp:414
msgid "Import GCstar Data..."
msgstr "Импорт из файла GCstar..."
msgstr "Импорт из файла GCstar"
#: mainwindow.cpp:415
msgid "Import a GCstar data file"
@ -2995,7 +2998,7 @@ msgstr "Импорт данных из файла GCstar"
#: mainwindow.cpp:421
msgid "Import Griffith Data..."
msgstr "Импорт из файла Griffith..."
msgstr "Импорт из файла Griffith"
#: mainwindow.cpp:422
msgid "Import a Griffith database"
@ -3003,7 +3006,7 @@ msgstr "Импортировать из файла Griffith"
#: mainwindow.cpp:428
msgid "Import Ant Movie Catalog Data..."
msgstr "Импорт из файла Ant..."
msgstr "Импорт из файла Ant"
#: mainwindow.cpp:429
msgid "Import an Ant Movie Catalog data file"
@ -3011,7 +3014,7 @@ msgstr "Импортировать из файла менеджера колле
#: mainwindow.cpp:435
msgid "Import File Listing..."
msgstr "Импорт списка фалов..."
msgstr "Импорт списка фалов"
#: mainwindow.cpp:436
msgid "Import information about files in a folder"
@ -3019,7 +3022,7 @@ msgstr "Импортировать информацию о файлах в па
#: mainwindow.cpp:442
msgid "Import XSL Transform..."
msgstr "Импорт из XSLT..."
msgstr "Импорт из XSLT"
#: mainwindow.cpp:443
msgid "Import using an XSL Transform"
@ -3036,7 +3039,7 @@ msgstr "Экспортировать данные коллекции в друг
#: mainwindow.cpp:461
msgid "Export to XML..."
msgstr "Экспорт в XML..."
msgstr "Экспорт в XML"
#: mainwindow.cpp:462
msgid "Export to a Tellico XML file"
@ -3044,7 +3047,7 @@ msgstr "Экспорт в XML-файл Tellico"
#: mainwindow.cpp:468
msgid "Export to Zip..."
msgstr "Экспорт в ZIP..."
msgstr "Экспорт в ZIP"
#: mainwindow.cpp:469
msgid "Export to a Tellico Zip file"
@ -3052,7 +3055,7 @@ msgstr "Экспорт в сжатый ZIP файл Tellico"
#: mainwindow.cpp:475
msgid "Export to HTML..."
msgstr "Экспорт в HTML..."
msgstr "Экспорт в HTML"
#: mainwindow.cpp:476
msgid "Export to an HTML file"
@ -3060,7 +3063,7 @@ msgstr "Экспорт в файл HTML"
#: mainwindow.cpp:482
msgid "Export to CSV..."
msgstr "Экспорт в CSV..."
msgstr "Экспорт в CSV"
#: mainwindow.cpp:483
msgid "Export to a comma-separated values file"
@ -3068,7 +3071,7 @@ msgstr "Экспорт в текстовый файл с разделённым
#: mainwindow.cpp:489
msgid "Export to PilotDB..."
msgstr "Экспорт в PilotDB..."
msgstr "Экспорт в PilotDB"
#: mainwindow.cpp:490
msgid "Export to a PilotDB database"
@ -3076,7 +3079,7 @@ msgstr "Экспортировать в базу данных PilotDB"
#: mainwindow.cpp:496
msgid "Export to Alexandria..."
msgstr "Экспорт в Alexandria..."
msgstr "Экспорт в Alexandria"
#: mainwindow.cpp:497
msgid "Export to an Alexandria library"
@ -3084,7 +3087,7 @@ msgstr "Экспорт в библиотеку Alexandria"
#: mainwindow.cpp:503
msgid "Export to Bibtex..."
msgstr "Экспорт в Bibtex..."
msgstr "Экспорт в Bibtex"
#: mainwindow.cpp:504
msgid "Export to a bibtex file"
@ -3092,7 +3095,7 @@ msgstr "Экспорт в файл Bibtex"
#: mainwindow.cpp:510
msgid "Export to Bibtexml..."
msgstr "Экспорт в Bibtexml..."
msgstr "Экспорт в Bibtexml"
#: mainwindow.cpp:511
msgid "Export to a Bibtexml file"
@ -3100,7 +3103,7 @@ msgstr "Экспорт в файл Bibtexml"
#: mainwindow.cpp:517
msgid "Export to ONIX..."
msgstr "Экспорт в ONIX..."
msgstr "Экспорт в ONIX"
#: mainwindow.cpp:518
msgid "Export to an ONIX file"
@ -3108,7 +3111,7 @@ msgstr "Экспорт в файл ONIX"
#: mainwindow.cpp:524
msgid "Export to GCfilms..."
msgstr "Экспорт в GCfilms..."
msgstr "Экспорт в GCfilms"
#: mainwindow.cpp:525
msgid "Export to a GCfilms data file"
@ -3116,7 +3119,7 @@ msgstr "Экспорт в файл GCfilms"
#: mainwindow.cpp:531
msgid "Export to GCstar..."
msgstr "Экспорт в GCStar..."
msgstr "Экспорт в GCStar"
#: mainwindow.cpp:532
msgid "Export to a GCstar data file"
@ -3124,7 +3127,7 @@ msgstr "Экспорт в файл GCfilms"
#: mainwindow.cpp:536
msgid "Export XSL Transform..."
msgstr "Экспорт в XSLT..."
msgstr "Экспорт в XSLT"
#: mainwindow.cpp:537
msgid "Export using an XSL Transform"
@ -3152,15 +3155,15 @@ msgstr "Отменить выделение записей в коллекции
#: mainwindow.cpp:556
msgid "Internet Search..."
msgstr "Поиск в интернете..."
msgstr "Поиск в интернете"
#: mainwindow.cpp:559
msgid "Search the internet..."
msgstr "Повести поиск в интернете для создания новой записи в коллекции..."
msgstr "Повести поиск в интернете для создания новой записи в коллекции"
#: mainwindow.cpp:561
msgid "Advanced &Filter..."
msgstr "Продвинутый &фильтр..."
msgstr "Продвинутый &фильтр"
#: mainwindow.cpp:564 mainwindow.cpp:719
msgid "Filter the collection"
@ -3168,7 +3171,7 @@ msgstr "Фильтр коллекции"
#: mainwindow.cpp:569
msgid "&New Entry..."
msgstr "&Новая запись..."
msgstr "&Новая запись"
#: mainwindow.cpp:572
msgid "Create a new entry"
@ -3176,7 +3179,7 @@ msgstr "Создать новую запись"
#: controller.cpp:620 mainwindow.cpp:573
msgid "&Edit Entry..."
msgstr "&Редактировать запись..."
msgstr "&Редактировать запись"
#: mainwindow.cpp:576
msgid "Edit the selected entries"
@ -3208,7 +3211,7 @@ msgstr "Объединить выделенные записи"
#: mainwindow.cpp:591
msgid "&Generate Reports..."
msgstr "Создать от&чет..."
msgstr "Создать от&чет"
#: mainwindow.cpp:594
msgid "Generate collection reports"
@ -3216,7 +3219,7 @@ msgstr "Создать отчет о коллекции"
#: mainwindow.cpp:595
msgid "Check-&out..."
msgstr "&Отдать в долг..."
msgstr "&Отдать в долг"
#: mainwindow.cpp:598
msgid "Check-out the selected items"
@ -3232,7 +3235,7 @@ msgstr "Вернуть из долга выделенные записи"
#: mainwindow.cpp:604
msgid "&Rename Collection..."
msgstr "&Переименовать коллекцию..."
msgstr "&Переименовать коллекцию"
#: mainwindow.cpp:607
msgid "Rename the collection"
@ -3256,7 +3259,7 @@ msgstr "Конвертировать коллекцию книг в библио
#: mainwindow.cpp:616
msgid "String &Macros..."
msgstr "Строчный &макрос..."
msgstr "Строчный &макрос"
#: mainwindow.cpp:619
msgid "Edit the bibtex string macros"
@ -3357,7 +3360,7 @@ msgstr "Очистить фильтр"
#: mainwindow.cpp:710
msgid "Filter here..."
msgstr "Фильтр..."
msgstr "Фильтр"
#: mainwindow.cpp:768
msgid "Groups"
@ -3399,11 +3402,11 @@ msgstr ""
#: mainwindow.cpp:1066
msgid "Creating new document..."
msgstr "Создание нового документа..."
msgstr "Создание нового документа"
#: mainwindow.cpp:1098 mainwindow.cpp:1117 mainwindow.cpp:1135
msgid "Opening file..."
msgstr "Открытие файла..."
msgstr "Открытие файла"
#: mainwindow.cpp:1108
msgid "Open File"
@ -3411,7 +3414,7 @@ msgstr "Открыть файл"
#: document.cpp:192 mainwindow.cpp:1215
msgid "Saving file..."
msgstr "Сохранение файла...."
msgstr "Сохранение файла."
#: mainwindow.cpp:1226
msgid ""
@ -3435,11 +3438,11 @@ msgstr "Сохранять изображения вместе с файлом"
#: mainwindow.cpp:1265
msgid "Saving file with a new filename..."
msgstr "Сохранение файла под другим именем..."
msgstr "Сохранение файла под другим именем"
#: mainwindow.cpp:1303 mainwindow.cpp:1353
msgid "Printing..."
msgstr "Идёт печать..."
msgstr "Идёт печать"
#: mainwindow.cpp:1312
msgid ""
@ -3451,11 +3454,11 @@ msgstr ""
#: mainwindow.cpp:1337
msgid "Processing document..."
msgstr "Подождите..."
msgstr "Подождите"
#: mainwindow.cpp:1360
msgid "Exiting..."
msgstr "Выход..."
msgstr "Выход"
#: mainwindow.cpp:1498
#, c-format
@ -3490,7 +3493,7 @@ msgstr "Пожалуйста, проверьте свою инсталляцию
#: mainwindow.cpp:1849
msgid "Importing data..."
msgstr "Импорт данных..."
msgstr "Импорт данных"
#: mainwindow.cpp:1858
msgid "Import File"
@ -3502,7 +3505,7 @@ msgstr "Импорт каталога"
#: mainwindow.cpp:1885
msgid "Exporting data..."
msgstr "Экспортирование данных..."
msgstr "Экспортирование данных"
#: mainwindow.cpp:1907
msgid "Export As"
@ -3522,7 +3525,7 @@ msgstr "Строка"
#: mainwindow.cpp:1999
msgid "Creating citations..."
msgstr "Идет создание цитат..."
msgstr "Идет создание цитат"
#: mainwindow.cpp:2104
msgid "Filters"
@ -3598,7 +3601,7 @@ msgstr "Удалить несколько записей"
#: controller.cpp:626
msgid "&Edit Entries..."
msgstr "&Редактировать записи..."
msgstr "&Редактировать записи"
#: controller.cpp:627
msgid "D&uplicate Entries"
@ -3862,7 +3865,7 @@ msgstr "Дополнительные &параметры:"
#: collectionfieldsdialog.cpp:217
msgid "&Set..."
msgstr "&Установить..."
msgstr "&Установить"
#: collectionfieldsdialog.cpp:221
msgid ""
@ -4242,11 +4245,11 @@ msgstr ""
#: configdialog.cpp:380
msgid "&Preview..."
msgstr "&Пред-просмотр..."
msgstr "&Предпросмотр…"
#: configdialog.cpp:381
msgid "Show a preview of the template"
msgstr "Показать пред-просмотр шаблона"
msgstr "Показать предпросмотр шаблона"
#: configdialog.cpp:398
msgid "Font Options"
@ -4294,7 +4297,7 @@ msgstr "Управление шаблонами"
#: configdialog.cpp:475
msgid "Install..."
msgstr "Установить..."
msgstr "Установить"
#: configdialog.cpp:478
msgid "Click to install a new template directly."
@ -4302,7 +4305,7 @@ msgstr "Нажмите для установки шаблона."
#: configdialog.cpp:481 configdialog.cpp:537
msgid "Download..."
msgstr "Загрузить..."
msgstr "Загрузить"
#: configdialog.cpp:484
msgid "Click to download additional templates via the Internet."
@ -4310,7 +4313,7 @@ msgstr "Нажмите для загрузки дополнительных ша
#: configdialog.cpp:487
msgid "Delete..."
msgstr "Удалить..."
msgstr "Удалить"
#: configdialog.cpp:490
msgid "Click to select and remove installed templates."
@ -4346,7 +4349,7 @@ msgstr "&Ниже"
#: configdialog.cpp:528
msgid "&New..."
msgstr "&Новый..."
msgstr "&Новый"
#: configdialog.cpp:530
msgid "Click to add a new data source."
@ -4354,7 +4357,7 @@ msgstr "Нажмите для создания нового источника
#: configdialog.cpp:531
msgid "&Modify..."
msgstr "&Редактировать..."
msgstr "&Редактировать"
#: configdialog.cpp:533
msgid "Click to modify the selected data source."
@ -4390,7 +4393,7 @@ msgstr "Вернуть из долга"
#: loanview.cpp:76
msgid "Modify Loan..."
msgstr "Редактировать долг..."
msgstr "Редактировать долг"
#: loanview.cpp:93
msgid "Borrower (Sort by Count)"
@ -4556,7 +4559,7 @@ msgstr "Если отмечено, будет проведен многокра
#: fetchdialog.cpp:138
msgid "Edit List..."
msgstr "Редактировать список..."
msgstr "Редактировать список"
#: fetchdialog.cpp:140
msgid "Click to open a text edit box for entering or editing multiple ISBN values."
@ -4606,11 +4609,11 @@ msgstr "Очистить все поля поиска и результаты"
#: fetchdialog.cpp:298
msgid "Cancelling the search..."
msgstr "Отмена поиска..."
msgstr "Отмена поиска"
#: fetchdialog.cpp:313 fetchdialog.cpp:472
msgid "Searching..."
msgstr "Поиск..."
msgstr "Поиск"
#: fetchdialog.cpp:368
msgid "The search returned no items."
@ -4631,7 +4634,7 @@ msgstr "Никаких записей не было найдено по след
#: fetchdialog.cpp:443 fetchdialog.cpp:495
msgid "Fetching %1..."
msgstr "Загрузка %1..."
msgstr "Загрузка %1"
#: fetchdialog.cpp:528 fetchdialog.cpp:708
msgid "No Internet sources are available for your current collection type."
@ -4647,7 +4650,7 @@ msgstr "<qt>Введите значения ISBN/UPC, по одному в ст
#: fetchdialog.cpp:604
msgid "&Load From File..."
msgstr "&Загрузить из файла..."
msgstr "&Загрузить из файла"
#: fetchdialog.cpp:605
msgid "<qt>Load the list from a text file.</qt>"
@ -4805,15 +4808,15 @@ msgstr "Калимуллин Артур, Песоцкий Денис"
msgid ""
"_: EMAIL OF TRANSLATORS\n"
"Your emails"
msgstr "kalimullin@gmail.com, St.MPA3b@gmail.com"
msgstr "kalimullin@gmail.com, denis@kde.ru"
#: entrymerger.cpp:35
msgid "Merging entries..."
msgstr "Объединение записей..."
msgstr "Объединение записей"
#: entrymerger.cpp:49
msgid "Total merged/scanned entries: %1/%2"
msgstr "Всего записей объединено/просканировано: %1"
msgstr "Всего записей объединено/просканировано: %1/%2"
#: tips.cpp:3
msgid ""
@ -4823,7 +4826,7 @@ msgid ""
"<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>...что если книга имеет больше, чем одного автора, то вам следует "
"<p>что если книга имеет больше, чем одного автора, то вам следует "
"разделять\n"
"точкой с запятой (;). Таким образом, Tellico будет разделять их имена.</p>\n"
"<p>Любое другое поле также поддерживает эту функцию. Для этого вам следует\n"
@ -4835,7 +4838,7 @@ 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"
"<p>что вы можете выбрать какие поля следует показывать в списке записей,\n"
"кликнув правой кнопкой мыши на заголовке \"таблицы\".\n"
#: tips.cpp:16
@ -4846,7 +4849,7 @@ msgid ""
"position of the field in the list, which affects the placement in the entry\n"
"editor.</p>\n"
msgstr ""
"<p>...что вы можете добавлять, редактировать или удалять поля в коллекции,\n"
"<p>что вы можете добавлять, редактировать или удалять поля в коллекции,\n"
"используя Редактор полей. Кнопки стрелок позволяют вам менять позицию полей "
"в списке,\n"
"которая влияет на расстановку в Редакторе записей.</p>\n"
@ -4861,7 +4864,7 @@ msgid ""
"\"contains\" \"Science Fiction\" (no quotes) and the second rule to\n"
"have \"Read\" \"does not contain\" \"true\" (no quotes).</p>\n"
msgstr ""
"<p>...что если вы хотите отфильтровать записи по полю \"Выбор да/нет\",\n"
"<p>что если вы хотите отфильтровать записи по полю \"Выбор да/нет\",\n"
"то должно использоваться значение \"да\". Например, если вы хотите "
"посмотреть, какие детективы вы ещё не читали,\n"
"нажмите кнопку \"Соответствует всему следующему\",\n"
@ -4876,7 +4879,7 @@ msgid ""
"<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>...что если в быстром фильтре используется символ, не входящий в слова "
"<p>что если в быстром фильтре используется символ, не входящий в слова "
"(напр., ^)\n"
"текст интерпретируется как регулярное выражение.</p>\n"
"<p>Например, чтобы посмотреть только книги, которые написали Пушкин и "
@ -4888,7 +4891,7 @@ 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"
"<p>что за один раз вы можете отредактировать больше, чем одно поле.\n"
"Для этого выделите несколько полей, зажимая клавиши Shift или Ctrl.</p>\n"
#: tips.cpp:45
@ -4896,7 +4899,7 @@ 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"
"<p>что вы можете конвертировать текущую коллекцию книг в библиографию,\n"
"которая может быть экспортирована в формат Bibtex или Bibtexml.</p>\n"
#: tips.cpp:50
@ -4904,7 +4907,7 @@ msgid ""
"<p>...that you can add, edit, and delete string macros for bibliographies.</"
"p>\n"
msgstr ""
"<p>...что вы можете добавлять, редактировать и удалять строковые макросы для "
"<p>что вы можете добавлять, редактировать и удалять строковые макросы для "
"библиографий.</p>\n"
#: tips.cpp:54
@ -4915,7 +4918,7 @@ msgid ""
"editors\n"
"to be sorted or printed together, for example.</p>\n"
msgstr ""
"<p>...что если более чем одно поле форматируется как \"имя\", то в "
"<p>что если более чем одно поле форматируется как \"имя\", то в "
"коллекцию\n"
"добавляется дополнительная группа \"Люди\", например, для сортировки и "
"печати вместе.</p>\n"
@ -4927,7 +4930,7 @@ msgid ""
"CSS\n"
"within the stylesheet governs things like the font, the margins, etc.</p>\n"
msgstr ""
"<p>...что вы можете менять внешний вид, печатаемых отчетов, редактируя\n"
"<p>что вы можете менять внешний вид, печатаемых отчетов, редактируя\n"
"файл <tt>tellico-printing.xsl</tt>. Этот файл создает HTML и CSS\n"
"с такими элементами как шрифт, размер и т.д. </p>\n"
@ -4936,12 +4939,12 @@ msgid ""
"<p>...that you can import using any generic XSL stylesheet which\n"
"outputs a valid Tellico XML file.</p>\n"
msgstr ""
"<p>...что вы можете импортировать, используя стандартный\n"
"<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"
msgstr "<p>что двойной щелчок на записи открывает редактор записей.</p>\n"
#: tips.cpp:75
msgid ""
@ -4949,7 +4952,7 @@ msgid ""
"as\n"
"&lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italic&lt;/i&gt;.</p>\n"
msgstr ""
"<p>...что в любое поле типа \"Большой текст\" вы можете добавлять теги HTML, "
"<p>что в любое поле типа \"Большой текст\" вы можете добавлять теги HTML, "
"такие как \n"
"&lt;b&gt;жирный шрифт&lt;/b&gt; или &lt;i&gt;курсивный&lt;/i&gt;.</p>\n"
@ -4958,7 +4961,7 @@ 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"
"перехода к записи, начинающейся с этой буквы.</p>\n"
#: tips.cpp:85
@ -4973,9 +4976,9 @@ msgid ""
"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"
"<p>что вы можете использовать \"зависимые\" поля для комбинации\n"
"нескольких раздельных полей в одно. Просто выберите тип \"зависимый\" \n"
"и используйте описание вроде \"Значение: %{поле1}%{поле2}\", где %{...}\n"
"и используйте описание вроде \"Значение: %{поле1}%{поле2}\", где %{}\n"
"заменяется на значение поля. Это полезно для использование различных\n"
"полей в одном поле, т.е. для лучшей группировки и для комбинации полей\n"
"различных типов с приоритетом правильной сортировки. Пример -\n"

@ -78,7 +78,7 @@ public:
const TQString& 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(); }
size_t count() const { return m_loans.count(); }
Data::LoanPtr loan(Data::ConstEntryPtr entry);
void addLoan(Data::LoanPtr loan);

@ -25,7 +25,7 @@ BorrowerItem::BorrowerItem(GUI::ListView* parent_, Data::BorrowerPtr borrower_)
setPixmap(0, SmallIcon(TQString::fromLatin1("kaddressbook")));
}
int BorrowerItem::count() const {
size_t BorrowerItem::count() const {
return m_borrower ? m_borrower->count() : GUI::CountedItem::count();
}

@ -29,7 +29,7 @@ public:
virtual bool isBorrowerItem() const { return true; }
Data::BorrowerPtr borrower() { return m_borrower; }
virtual int count() const;
virtual size_t count() const;
virtual Data::EntryVec entries() const;
private:

@ -878,6 +878,9 @@ bool Collection::mergeEntry(EntryPtr e1, EntryPtr e2, bool overwrite_, bool askU
if(ret) {
e1->setField(field, vals1.join(TQString::fromLatin1("; ")));
}
// remove the merging due to use comments
// maybe in the future have a more intelligent way
#if 0
} 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)
@ -894,6 +897,7 @@ bool Collection::mergeEntry(EntryPtr e1, EntryPtr e2, bool overwrite_, bool askU
// items1.sort();
e1->setField(field, items1.join(TQString::fromLatin1("; ")));
ret = true;
#endif
} else if(askUser_ && e1->field(field) != e2->field(field)) {
int ret = Kernel::self()->askAndMerge(e1, e2, field);
if(ret == 0) {

@ -254,7 +254,6 @@ CollectionFieldsDialog::CollectionFieldsDialog(Data::CollPtr coll_, TQWidget* pa
// need to stretch at bottom
vbox->setStretchFactor(new TQWidget(vbox), 1);
TDEAcceleratorManager::manage(vbox);
// keep a default collection
m_defaultCollection = CollectionFactory::collection(m_coll->type(), true);
@ -279,6 +278,9 @@ CollectionFieldsDialog::~CollectionFieldsDialog() {
}
void CollectionFieldsDialog::slotSelectInitial() {
// the accel management is here so that it doesn't cause conflicts with the
// ones explicitly set in the constructor
TDEAcceleratorManager::manage(mainWidget());
m_fieldsBox->setSelected(0, true);
}
@ -405,7 +407,7 @@ void CollectionFieldsDialog::slotNew() {
}
TQString name = TQString::fromLatin1("custom") + TQString::number(m_newFields.count()+1);
int count = m_newFields.count() + 1;
size_t count = m_newFields.count() + 1;
TQString title = i18n("New Field") + TQString::fromLatin1(" %1").arg(count);
while(m_fieldsBox->findItem(title)) {
++count;

@ -102,4 +102,21 @@ Tellico::Data::FieldVec FileCatalog::defaultFields() {
return list;
}
int FileCatalog::sameEntry(Data::EntryPtr entry1_, Data::EntryPtr entry2_) const {
// equal urls are always equal, even if modification time or something is different
if(Entry::compareValues(entry1_, entry2_, TQString::fromLatin1("url"), this) > 0) {
return 100; // good match
}
// if volume or created time is different, it can't be same entry
if(Entry::compareValues(entry1_, entry2_, TQString::fromLatin1("volume"), this) == 0 ||
Entry::compareValues(entry1_, entry2_, TQString::fromLatin1("created"), this) == 0 ||
Entry::compareValues(entry1_, entry2_, TQString::fromLatin1("size"), this) == 0) {
return 0;
}
int res = Entry::compareValues(entry1_, entry2_, TQString::fromLatin1("title"), this);
res += Entry::compareValues(entry1_, entry2_, TQString::fromLatin1("description"), this);
res += Entry::compareValues(entry1_, entry2_, TQString::fromLatin1("mimetype"), this);
return res;
}
#include "filecatalog.moc"

@ -1,5 +1,5 @@
/***************************************************************************
copyright : (C) 2005-2006 by Robby Stephenson
copyright : (C) 2005-2008 by Robby Stephenson
email : robby@periapsis.org
***************************************************************************/
@ -30,6 +30,7 @@ public:
FileCatalog(bool addFields, const TQString& title = TQString());
virtual Type type() const { return File; }
virtual int sameEntry(Data::EntryPtr entry1, Data::EntryPtr entry2) const;
static FieldVec defaultFields();
};

@ -434,6 +434,7 @@ void Controller::slotDeleteSelectedEntries() {
int ret = KMessageBox::warningContinueCancel(Kernel::self()->widget(), str, i18n("Delete Entry"),
KGuiItem(i18n("&Delete"), TQString::fromLatin1("editdelete")), dontAsk);
if(ret != KMessageBox::Continue) {
m_working = false;
return;
}
} else {
@ -448,6 +449,7 @@ void Controller::slotDeleteSelectedEntries() {
i18n("Delete Multiple Entries"),
KGuiItem(i18n("&Delete"), TQString::fromLatin1("editdelete")), dontAsk);
if(ret != KMessageBox::Continue) {
m_working = false;
return;
}
}

@ -17,6 +17,8 @@ drophandler.h drophandler.cpp \
tellico-rename.upd tellico.upd \
tellico-1-3-update.pl
dcopinterface_DCOPIDLNG = ALL
kde_kcfg_DATA = tellico_config.kcfg
updatedir = $(kde_datadir)/tdeconf_update

@ -25,11 +25,11 @@ static const char* const ApplicationInterface_ftable[16][3] = {
{ "bool", "exportHTML(TQString)", "exportHTML(TQString file)" },
{ "bool", "exportCSV(TQString)", "exportCSV(TQString file)" },
{ "bool", "exportPilotDB(TQString)", "exportPilotDB(TQString file)" },
{ "TQValueList<long int>", "selectedEntries()", "selectedEntries()" },
{ "TQValueList<long int>", "filteredEntries()", "filteredEntries()" },
{ "TQValueList<long>", "selectedEntries()", "selectedEntries()" },
{ "TQValueList<long>", "filteredEntries()", "filteredEntries()" },
{ "void", "openFile(TQString)", "openFile(TQString file)" },
{ "void", "setFilter(TQString)", "setFilter(TQString text)" },
{ "bool", "showEntry(long int)", "showEntry(long int id)" },
{ "bool", "showEntry(long)", "showEntry(long id)" },
{ 0, 0, 0 }
};
static const int ApplicationInterface_ftable_hiddens[15] = {
@ -162,12 +162,12 @@ bool ApplicationInterface::process(const TQCString &fun, const TQByteArray &data
TQDataStream _replyStream( replyData, IO_WriteOnly );
_replyStream << exportPilotDB(arg0 );
} break;
case 10: { // TQValueList<long int> selectedEntries()
case 10: { // TQValueList<long> selectedEntries()
replyType = ApplicationInterface_ftable[10][0];
TQDataStream _replyStream( replyData, IO_WriteOnly );
_replyStream << selectedEntries( );
} break;
case 11: { // TQValueList<long int> filteredEntries()
case 11: { // TQValueList<long> filteredEntries()
replyType = ApplicationInterface_ftable[11][0];
TQDataStream _replyStream( replyData, IO_WriteOnly );
_replyStream << filteredEntries( );
@ -188,8 +188,8 @@ bool ApplicationInterface::process(const TQCString &fun, const TQByteArray &data
replyType = ApplicationInterface_ftable[13][0];
setFilter(arg0 );
} break;
case 14: { // bool showEntry(long int)
long int arg0;
case 14: { // bool showEntry(long)
long arg0;
TQDataStream arg( data, IO_ReadOnly );
if (arg.atEnd()) return false;
arg >> arg0;
@ -233,14 +233,14 @@ 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)" },
{ "long", "addEntry()", "addEntry()" },
{ "bool", "removeEntry(long)", "removeEntry(long entryID)" },
{ TQSTRINGLIST_OBJECT_NAME_STRING, "values(TQString)", "values(TQString fieldName)" },
{ TQSTRINGLIST_OBJECT_NAME_STRING, "values(long int,TQString)", "values(long int entryID,TQString fieldName)" },
{ TQSTRINGLIST_OBJECT_NAME_STRING, "values(long,TQString)", "values(long entryID,TQString fieldName)" },
{ TQSTRINGLIST_OBJECT_NAME_STRING, "bibtexKeys()", "bibtexKeys()" },
{ TQSTRING_OBJECT_NAME_STRING, "bibtexKey(long int)", "bibtexKey(long int entryID)" },
{ "bool", "setFieldValue(long int,TQString,TQString)", "setFieldValue(long int entryID,TQString fieldName,TQString value)" },
{ "bool", "addFieldValue(long int,TQString,TQString)", "addFieldValue(long int entryID,TQString fieldName,TQString value)" },
{ TQSTRING_OBJECT_NAME_STRING, "bibtexKey(long)", "bibtexKey(long entryID)" },
{ "bool", "setFieldValue(long,TQString,TQString)", "setFieldValue(long entryID,TQString fieldName,TQString value)" },
{ "bool", "addFieldValue(long,TQString,TQString)", "addFieldValue(long entryID,TQString fieldName,TQString value)" },
{ 0, 0, 0 }
};
static const int CollectionInterface_ftable_hiddens[8] = {
@ -264,13 +264,13 @@ bool CollectionInterface::process(const TQCString &fun, const TQByteArray &data,
}
int* fp = fdict->find( fun );
switch ( fp?*fp:-1) {
case 0: { // long int addEntry()
case 0: { // long addEntry()
replyType = CollectionInterface_ftable[0][0];
TQDataStream _replyStream( replyData, IO_WriteOnly );
_replyStream << addEntry( );
} break;
case 1: { // bool removeEntry(long int)
long int arg0;
case 1: { // bool removeEntry(long)
long arg0;
TQDataStream arg( data, IO_ReadOnly );
if (arg.atEnd()) return false;
arg >> arg0;
@ -287,8 +287,8 @@ bool CollectionInterface::process(const TQCString &fun, const TQByteArray &data,
TQDataStream _replyStream( replyData, IO_WriteOnly );
_replyStream << values(arg0 );
} break;
case 3: { // TQStringList values(long int,TQString)
long int arg0;
case 3: { // TQStringList values(long,TQString)
long arg0;
TQString arg1;
TQDataStream arg( data, IO_ReadOnly );
if (arg.atEnd()) return false;
@ -304,8 +304,8 @@ bool CollectionInterface::process(const TQCString &fun, const TQByteArray &data,
TQDataStream _replyStream( replyData, IO_WriteOnly );
_replyStream << bibtexKeys( );
} break;
case 5: { // TQString bibtexKey(long int)
long int arg0;
case 5: { // TQString bibtexKey(long)
long arg0;
TQDataStream arg( data, IO_ReadOnly );
if (arg.atEnd()) return false;
arg >> arg0;
@ -313,8 +313,8 @@ bool CollectionInterface::process(const TQCString &fun, const TQByteArray &data,
TQDataStream _replyStream( replyData, IO_WriteOnly );
_replyStream << bibtexKey(arg0 );
} break;
case 6: { // bool setFieldValue(long int,TQString,TQString)
long int arg0;
case 6: { // bool setFieldValue(long,TQString,TQString)
long arg0;
TQString arg1;
TQString arg2;
TQDataStream arg( data, IO_ReadOnly );
@ -328,8 +328,8 @@ bool CollectionInterface::process(const TQCString &fun, const TQByteArray &data,
TQDataStream _replyStream( replyData, IO_WriteOnly );
_replyStream << setFieldValue(arg0, arg1, arg2 );
} break;
case 7: { // bool addFieldValue(long int,TQString,TQString)
long int arg0;
case 7: { // bool addFieldValue(long,TQString,TQString)
long arg0;
TQString arg1;
TQString arg2;
TQDataStream arg( data, IO_ReadOnly );

@ -15,9 +15,13 @@
#include "../mainwindow.h"
#include "../tellico_kernel.h"
#include "../tellico_debug.h"
#include "../translators/bibteximporter.h"
#include "../translators/risimporter.h"
#include <kurldrag.h>
#include <kmimetype.h>
#include <tdeio/netaccess.h>
#include <tdeio/job.h>
using Tellico::DropHandler;
@ -62,18 +66,37 @@ 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);
const KURL& url = *it;
KMimeType::Ptr ptr;
// findByURL doesn't work for http, so actually query
// the url itself
if(url.protocol() != TQString::fromLatin1("http")) {
ptr = KMimeType::findByURL(url);
} else {
TDEIO::MimetypeJob* job = TDEIO::mimetype(url, false /*progress*/);
TDEIO::NetAccess::synchronousRun(job, Kernel::self()->widget());
ptr = KMimeType::mimeType(job->mimetype());
}
if(ptr->is(TQString::fromLatin1("application/x-tellico"))) {
tc << *it;
tc << url;
} else if(ptr->is(TQString::fromLatin1("application/pdf"))) {
pdf << *it;
pdf << url;
} else if(ptr->is(TQString::fromLatin1("text/x-bibtex")) ||
ptr->is(TQString::fromLatin1("application/x-bibtex"))) {
bib << *it;
ptr->is(TQString::fromLatin1("application/x-bibtex")) ||
ptr->is(TQString::fromLatin1("application/bibtex"))) {
bib << url;
} else if(ptr->is(TQString::fromLatin1("application/x-research-info-systems"))) {
ris << *it;
ris << url;
} else if(url.fileName().endsWith(TQString::fromLatin1(".bib"))) {
bib << url;
} else if(url.fileName().endsWith(TQString::fromLatin1(".ris"))) {
ris << url;
} else if(ptr->is(TQString::fromLatin1("text/plain")) && Import::BibtexImporter::maybeBibtex(url)) {
bib << url;
} else if(ptr->is(TQString::fromLatin1("text/plain")) && Import::RISImporter::maybeRIS(url)) {
ris << url;
} else {
myDebug() << "DropHandler::handleURL() - unrecognized type: " << ptr->name() << " (" << *it << ")" << endl;
myDebug() << "DropHandler::handleURL() - unrecognized type: " << ptr->name() << " (" << url << ")" << endl;
hasUnknown = true;
}
}

@ -15,6 +15,7 @@
#include "mainwindow.h" // needed for calling fileSave()
#include "collectionfactory.h"
#include "translators/tellicoimporter.h"
#include "translators/tellicosaximporter.h"
#include "translators/tellicozipexporter.h"
#include "translators/tellicoxmlexporter.h"
#include "collection.h"
@ -109,7 +110,12 @@ bool Document::openDocument(const KURL& url_) {
}
delete m_importer;
#ifdef SAX_SUPPORT
myLog() << "Document::openDocument() - using SAX loader" << endl;
m_importer = new Import::TellicoSaxImporter(url_, m_loadAllImages);
#else
m_importer = new Import::TellicoImporter(url_, m_loadAllImages);
#endif
CollPtr coll = m_importer->collection();
// delayed image loading only works for zip files
@ -146,6 +152,8 @@ bool Document::openDocument(const KURL& url_) {
TQTimer::singleShot(500, this, TQT_SLOT(slotLoadAllImages()));
} else {
emit signalCollectionImagesLoaded(m_coll);
m_importer->deleteLater();
m_importer = 0;
}
return true;
}

@ -27,6 +27,7 @@
namespace Tellico {
namespace Import {
class TellicoImporter;
class TellicoSaxImporter;
}
namespace Data {
@ -227,7 +228,11 @@ private:
bool m_loadAllImages : 1;
KURL m_url;
bool m_validFile : 1;
#ifdef SAX_SUPPORT
TQGuardedPtr<Import::TellicoSaxImporter> m_importer;
#else
TQGuardedPtr<Import::TellicoImporter> m_importer;
#endif
bool m_cancelImageWriting : 1;
int m_fileFormat;
bool m_allImagesOnDisk : 1;

@ -252,8 +252,13 @@ bool Entry::setField(const TQString& name_, const TQString& value_) {
}
// the string store is probable only useful for fields with auto-completion or choice/number/bool
bool shareType = f->type() == Field::Choice ||
f->type() == Field::Bool ||
f->type() == Field::Image ||
f->type() == Field::Rating ||
f->type() == Field::Number;
if(!(f->flags() & Field::AllowMultiple) &&
((f->type() == Field::Choice || f->type() == Field::Bool || f->type() == Field::Number) ||
(shareType ||
(f->type() == Field::Line && (f->flags() & Field::AllowCompletion)))) {
m_fields.insert(Tellico::shareString(name_), Tellico::shareString(value_));
} else {
@ -415,6 +420,16 @@ int Entry::compareValues(EntryPtr e1, EntryPtr e2, FieldPtr f) {
if(f->name() == Latin1Literal("lccn") && LCCNValidator::formalize(s1) == LCCNValidator::formalize(s2)) {
return 5;
}
if(f->name() == Latin1Literal("arxiv")) {
// normalize and unVersion arxiv ID
s1.remove(TQRegExp(TQString::fromLatin1("^arxiv:"), false));
s1.remove(TQRegExp(TQString::fromLatin1("v\\d+$")));
s2.remove(TQRegExp(TQString::fromLatin1("^arxiv:"), false));
s2.remove(TQRegExp(TQString::fromLatin1("v\\d+$")));
if(s1 == s2) {
return 5;
}
}
if(f->formatFlag() == Field::FormatName) {
s1 = e1->field(f, true).lower();
s2 = e2->field(f, true).lower();

@ -84,11 +84,6 @@ public:
* 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();
@ -231,6 +226,12 @@ public:
static TQString dependentValue(ConstEntryPtr e, const TQString& formatString, bool formatted);
private:
/**
* 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);
CollPtr m_coll;
long m_id;
StringMap m_fields;

@ -131,7 +131,7 @@ TQString EntryGroupItem::key(int col_, bool) const {
return m_key;
}
int EntryGroupItem::count() const {
size_t EntryGroupItem::count() const {
return m_group ? m_group->count() : GUI::CountedItem::count();
}

@ -51,7 +51,7 @@ public:
*/
virtual TQString key(int col, bool) const;
virtual int count() const;
virtual size_t count() const;
virtual Data::EntryVec entries() const;
private:

@ -26,6 +26,7 @@
#include "document.h"
#include "latin1literal.h"
#include "../core/drophandler.h"
#include "../tellico_debug.h"
#include <kstandarddirs.h>
#include <krun.h>
@ -37,10 +38,22 @@
#include <tdelocale.h>
#include <tqfile.h>
#include <tqclipboard.h>
using Tellico::EntryView;
using Tellico::EntryViewWidget;
EntryView::EntryView(TQWidget* parent_, const char* name_) : TDEHTMLPart(parent_, name_),
EntryViewWidget::EntryViewWidget(TDEHTMLPart* part, TQWidget* parent)
: TDEHTMLView(part, parent) {}
// for the life of me, I could not figure out how to call the actual
// TDEHTMLPartBrowserExtension::copy() slot, so this will have to do
void EntryViewWidget::copy() {
TQString text = part()->selectedText();
TQApplication::clipboard()->setText(text, TQClipboard::Clipboard);
}
EntryView::EntryView(TQWidget* parent_, const char* name_) : TDEHTMLPart(new EntryViewWidget(this, parent_), parent_, name_),
m_entry(0), m_handler(0), m_run(0), m_tempFile(0), m_useGradientImages(true), m_checkCommonFile(true) {
setJScriptEnabled(false);
setJavaEnabled(false);

@ -20,6 +20,7 @@ class KTempFile;
#include "datavectors.h"
#include <tdehtml_part.h>
#include <tdehtmlview.h>
#include <tqguardedptr.h>
@ -103,5 +104,15 @@ private:
bool m_checkCommonFile : 1;
};
// stupid naming on my part, I need to subclass the view to
// add a slot. EntryView is really a part though
class EntryViewWidget : public TDEHTMLView {
Q_OBJECT
public:
EntryViewWidget(TDEHTMLPart* part, TQWidget* parent);
public slots:
void copy();
};
} //end namespace
#endif

@ -10,7 +10,7 @@ libfetch_a_SOURCES = amazonfetcher.cpp animenfofetcher.cpp arxivfetcher.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
z3950fetcher.cpp amazonrequest.cpp hmac_sha2.c sha2.c
####### tdevelop will overwrite this part!!! (end)############
@ -40,6 +40,8 @@ citebasefetcher.h citebasefetcher.cpp \
bibsonomyfetcher.h bibsonomyfetcher.cpp \
googlescholarfetcher.h googlescholarfetcher.cpp \
discogsfetcher.h discogsfetcher.cpp \
amazonrequest.h amazonrequest.cpp \
hmac_sha2.h hmac_sha2.c sha2.h sha2.c \
z3950-servers.cfg
appdir = $(kde_datadir)/tellico

@ -12,6 +12,7 @@
***************************************************************************/
#include "amazonfetcher.h"
#include "amazonrequest.h"
#include "messagehandler.h"
#include "../translators/xslthandler.h"
#include "../translators/tellicoimporter.h"
@ -47,7 +48,6 @@
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");
@ -84,7 +84,6 @@ const AmazonFetcher::SiteData& AmazonFetcher::siteData(int site_) {
AmazonFetcher::AmazonFetcher(Site site_, TQObject* parent_, const char* name_)
: Fetcher(parent_, name_), m_xsltHandler(0), m_site(site_), m_imageSize(MediumImage),
m_access(TQString::fromLatin1(AMAZON_ACCESS_KEY)),
m_assoc(TQString::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;
@ -109,7 +108,8 @@ bool AmazonFetcher::canFetch(int type) const {
|| type == Data::Collection::Bibtex
|| type == Data::Collection::Album
|| type == Data::Collection::Video
|| type == Data::Collection::Game;
|| type == Data::Collection::Game
|| type == Data::Collection::BoardGame;
}
void AmazonFetcher::readConfigHook(const TDEConfigGroup& config_) {
@ -117,6 +117,10 @@ void AmazonFetcher::readConfigHook(const TDEConfigGroup& config_) {
if(!s.isEmpty()) {
m_access = s;
}
s = config_.readEntry("SecretKey");
if(!s.isEmpty()) {
m_amazonKey = s;
}
s = config_.readEntry("AssocToken");
if(!s.isEmpty()) {
m_assoc = s;
@ -152,35 +156,41 @@ void AmazonFetcher::doSearch() {
// myDebug() << "AmazonFetcher::doSearch() - getting page " << m_page << endl;
const SiteData& data = siteData(m_site);
KURL u = data.url;
u.addQueryItem(TQString::fromLatin1("Service"), TQString::fromLatin1("AWSECommerceService"));
u.addQueryItem(TQString::fromLatin1("AssociateTag"), m_assoc);
u.addQueryItem(TQString::fromLatin1("AWSAccessKeyId"), m_access);
u.addQueryItem(TQString::fromLatin1("Operation"), TQString::fromLatin1("ItemSearch"));
u.addQueryItem(TQString::fromLatin1("ResponseGroup"), TQString::fromLatin1("Large"));
u.addQueryItem(TQString::fromLatin1("ItemPage"), TQString::number(m_page));
u.addQueryItem(TQString::fromLatin1("Version"), TQString::fromLatin1("2007-10-29"));
TQMap<TQString, TQString> params;
params.insert(TQString::fromLatin1("Service"), TQString::fromLatin1("AWSECommerceService"));
params.insert(TQString::fromLatin1("AssociateTag"), m_assoc);
params.insert(TQString::fromLatin1("AWSAccessKeyId"), m_access);
params.insert(TQString::fromLatin1("Operation"), TQString::fromLatin1("ItemSearch"));
params.insert(TQString::fromLatin1("ResponseGroup"), TQString::fromLatin1("Large"));
params.insert(TQString::fromLatin1("ItemPage"), TQString::number(m_page));
params.insert(TQString::fromLatin1("Version"), TQString::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(TQString::fromLatin1("SearchIndex"), TQString::fromLatin1("Books"));
u.addQueryItem(TQString::fromLatin1("SortIndex"), TQString::fromLatin1("relevancerank"));
params.insert(TQString::fromLatin1("SearchIndex"), TQString::fromLatin1("Books"));
params.insert(TQString::fromLatin1("SortIndex"), TQString::fromLatin1("relevancerank"));
break;
case Data::Collection::Album:
u.addQueryItem(TQString::fromLatin1("SearchIndex"), TQString::fromLatin1("Music"));
params.insert(TQString::fromLatin1("SearchIndex"), TQString::fromLatin1("Music"));
break;
case Data::Collection::Video:
u.addQueryItem(TQString::fromLatin1("SearchIndex"), TQString::fromLatin1("Video"));
u.addQueryItem(TQString::fromLatin1("SortIndex"), TQString::fromLatin1("relevancerank"));
params.insert(TQString::fromLatin1("SearchIndex"), TQString::fromLatin1("Video"));
params.insert(TQString::fromLatin1("SortIndex"), TQString::fromLatin1("relevancerank"));
break;
case Data::Collection::Game:
u.addQueryItem(TQString::fromLatin1("SearchIndex"), TQString::fromLatin1("VideoGames"));
params.insert(TQString::fromLatin1("SearchIndex"), TQString::fromLatin1("VideoGames"));
break;
case Data::Collection::BoardGame:
params.insert(TQString::fromLatin1("SearchIndex"), TQString::fromLatin1("Toys"));
params.insert(TQString::fromLatin1("SortIndex"), TQString::fromLatin1("relevancerank"));
break;
case Data::Collection::Coin:
@ -188,7 +198,6 @@ void AmazonFetcher::doSearch() {
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;
@ -207,29 +216,28 @@ void AmazonFetcher::doSearch() {
switch(m_key) {
case Title:
u.addQueryItem(TQString::fromLatin1("Title"), value, mib);
params.insert(TQString::fromLatin1("Title"), value);
break;
case Person:
if(type == Data::Collection::Video) {
u.addQueryItem(TQString::fromLatin1("Actor"), value, mib);
u.addQueryItem(TQString::fromLatin1("Director"), value, mib);
params.insert(TQString::fromLatin1("Actor"), value);
params.insert(TQString::fromLatin1("Director"), value);
} else if(type == Data::Collection::Album) {
u.addQueryItem(TQString::fromLatin1("Artist"), value, mib);
params.insert(TQString::fromLatin1("Artist"), value);
} else if(type == Data::Collection::Game) {
u.addQueryItem(TQString::fromLatin1("Manufacturer"), value, mib);
params.insert(TQString::fromLatin1("Manufacturer"), value);
} else { // books and bibtex
TQString s = TQString::fromLatin1("author:%1 or publisher:%2").arg(value, value);
// u.addQueryItem(TQString::fromLatin1("Author"), value, mib);
// u.addQueryItem(TQString::fromLatin1("Publisher"), value, mib);
u.addQueryItem(TQString::fromLatin1("Power"), s, mib);
// params.insert(TQString::fromLatin1("Author"), value, mib);
// params.insert(TQString::fromLatin1("Publisher"), value, mib);
params.insert(TQString::fromLatin1("Power"), s);
}
break;
case ISBN:
{
u.removeQueryItem(TQString::fromLatin1("Operation"));
u.addQueryItem(TQString::fromLatin1("Operation"), TQString::fromLatin1("ItemLookup"));
params.insert(TQString::fromLatin1("Operation"), TQString::fromLatin1("ItemLookup"));
TQString s = m_value; // not encValue!!!
s.remove('-');
@ -260,47 +268,46 @@ void AmazonFetcher::doSearch() {
}
}
// the default search is by ASIN, which prohibits SearchIndex
u.removeQueryItem(TQString::fromLatin1("SearchIndex"));
params.remove(TQString::fromLatin1("SearchIndex"));
}
// limit to first 10
while(isbns.size() > 10) {
isbns.pop_back();
}
u.addQueryItem(TQString::fromLatin1("ItemId"), isbns.join(TQString::fromLatin1(",")));
params.insert(TQString::fromLatin1("ItemId"), isbns.join(TQString::fromLatin1(",")));
if(isbn13) {
u.addQueryItem(TQString::fromLatin1("IdType"), TQString::fromLatin1("EAN"));
params.insert(TQString::fromLatin1("IdType"), TQString::fromLatin1("EAN"));
}
}
break;
case UPC:
{
u.removeQueryItem(TQString::fromLatin1("Operation"));
u.addQueryItem(TQString::fromLatin1("Operation"), TQString::fromLatin1("ItemLookup"));
params.insert(TQString::fromLatin1("Operation"), TQString::fromLatin1("ItemLookup"));
// US allows UPC, all others are EAN
if(m_site == US) {
u.addQueryItem(TQString::fromLatin1("IdType"), TQString::fromLatin1("UPC"));
params.insert(TQString::fromLatin1("IdType"), TQString::fromLatin1("UPC"));
} else {
u.addQueryItem(TQString::fromLatin1("IdType"), TQString::fromLatin1("EAN"));
params.insert(TQString::fromLatin1("IdType"), TQString::fromLatin1("EAN"));
}
TQString s = m_value; // not encValue!!!
s.remove('-');
// limit to first 10
s.replace(TQString::fromLatin1("; "), TQString::fromLatin1(","));
s = s.section(',', 0, 9);
u.addQueryItem(TQString::fromLatin1("ItemId"), s);
params.insert(TQString::fromLatin1("ItemId"), s);
}
break;
case Keyword:
u.addQueryItem(TQString::fromLatin1("Keywords"), m_value, mib);
params.insert(TQString::fromLatin1("Keywords"), value);
break;
case Raw:
{
TQString key = value.section('=', 0, 0).stripWhiteSpace();
TQString str = value.section('=', 1).stripWhiteSpace();
u.addQueryItem(key, str, mib);
params.insert(key, str);
}
break;
@ -309,9 +316,11 @@ void AmazonFetcher::doSearch() {
stop();
return;
}
// myDebug() << "AmazonFetcher::search() - url: " << u.url() << endl;
AmazonRequest request(siteData(m_site).url, m_amazonKey);
KURL newUrl = request.signedRequest(params);
// myDebug() << "AmazonFetcher::search() - url: " << newUrl.url() << endl;
m_job = TDEIO::get(u, false, false);
m_job = TDEIO::get(newUrl, false, false);
connect(m_job, TQT_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
TQT_SLOT(slotData(TDEIO::Job*, const TQByteArray&)));
connect(m_job, TQT_SIGNAL(result(TDEIO::Job*)),
@ -520,6 +529,12 @@ void AmazonFetcher::slotComplete(TDEIO::Job* job_) {
+ entry->field(TQString::fromLatin1("year"));
break;
case Data::Collection::BoardGame:
desc = entry->field(TQString::fromLatin1("publisher"))
+ TQChar('/')
+ entry->field(TQString::fromLatin1("year"));
break;
default:
break;
}
@ -889,11 +904,25 @@ AmazonFetcher::ConfigWidget::ConfigWidget(TQWidget* parent_, const AmazonFetcher
TQWhatsThis::add(m_assocEdit, w);
label->setBuddy(m_assocEdit);
label = new TQLabel(i18n("Access key: "), optionsWidget());
l->addWidget(label, ++row, 0);
m_accessEdit = new KLineEdit(optionsWidget());
connect(m_accessEdit, SIGNAL(textChanged(const TQString&)), SLOT(slotSetModified()));
l->addWidget(m_accessEdit, row, 1);
label = new TQLabel(i18n("Secret Key: "), optionsWidget());
l->addWidget(label, ++row, 0);
m_secretKeyEdit = new KLineEdit(optionsWidget());
connect(m_secretKeyEdit, SIGNAL(textChanged(const TQString&)), SLOT(slotSetModified()));
l->addWidget(m_secretKeyEdit, row, 1);
l->setRowStretch(++row, 10);
if(fetcher_) {
m_siteCombo->setCurrentData(fetcher_->m_site);
m_assocEdit->setText(fetcher_->m_assoc);
m_accessEdit->setText(fetcher_->m_access);
m_secretKeyEdit->setText(fetcher_->m_amazonKey);
m_imageCombo->setCurrentData(fetcher_->m_imageSize);
} else { // defaults
m_assocEdit->setText(TQString::fromLatin1(AMAZON_ASSOC_TOKEN));
@ -912,6 +941,14 @@ void AmazonFetcher::ConfigWidget::saveConfig(TDEConfigGroup& config_) {
if(!s.isEmpty()) {
config_.writeEntry("AssocToken", s);
}
s = m_accessEdit->text().stripWhiteSpace();
if(!s.isEmpty()) {
config_.writeEntry("AccessKey", s);
}
s = m_secretKeyEdit->text().stripWhiteSpace();
if(!s.isEmpty()) {
config_.writeEntry("SecretKey", s);
}
n = m_imageCombo->currentData().toInt();
config_.writeEntry("Image Size", n);

@ -118,6 +118,7 @@ private:
ImageSize m_imageSize;
TQString m_access;
TQString m_amazonKey;
TQString m_assoc;
bool m_addLinkField;
int m_limit;
@ -151,6 +152,8 @@ private slots:
private:
KLineEdit* m_assocEdit;
KLineEdit* m_accessEdit;
KLineEdit* m_secretKeyEdit;
GUI::ComboBox* m_siteCombo;
GUI::ComboBox* m_imageCombo;
};

@ -0,0 +1,72 @@
/***************************************************************************
Copyright (C) 2007-2009 Robby Stephenson <robby@periapsis.org>
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License or (at your option) version 3 or any later version *
* accepted by the membership of KDE e.V. (or its successor approved *
* by the membership of KDE e.V.), which shall act as a proxy *
* defined in Section 14 of version 3 of the license. *
* *
* 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, see <http://www.gnu.org/licenses/>. *
* *
***************************************************************************/
#include "amazonrequest.h"
#include "hmac_sha2.h"
#include "../tellico_debug.h"
#include <kmdcodec.h>
#include <tqdatetime.h>
using Tellico::Fetch::AmazonRequest;
AmazonRequest::AmazonRequest(const KURL& site_, const TQString& key_) : m_siteUrl(site_), m_key(key_) {
}
KURL AmazonRequest::signedRequest(const TQMap<TQString, TQString>& params_) const {
TQMap<TQString, TQString> allParams = params_;
allParams.insert(TQString::fromLatin1("Timestamp"),
TQDateTime::currentDateTime(TQt::UTC).toString(TQt::ISODate));
TQString query;
// has to be a map so that the query elements are sorted
TQMap<TQString, TQString>::Iterator it;
for ( it = allParams.begin(); it != allParams.end(); ++it ) {
query += KURL::encode_string(it.key());
query += '=';
query += KURL::encode_string(it.data());
query += '&';
}
// remove last '&'
query.truncate(query.length()-1);
const TQCString toSign = "GET\n"
+ m_siteUrl.host().utf8() + '\n'
+ m_siteUrl.path().utf8() + '\n'
+ query.latin1();
TQByteArray hmac_buffer;
hmac_buffer.fill('\0', SHA256_DIGEST_SIZE);
// subtract one from string size for toSign, not exactly sure why
hmac_sha256(reinterpret_cast<unsigned char*>(const_cast<char*>(m_key.latin1())), m_key.length(),
reinterpret_cast<unsigned char*>(toSign.data()), toSign.size()-1,
reinterpret_cast<unsigned char*>(hmac_buffer.data()), hmac_buffer.size());
const TQString sig = KURL::encode_string(KCodecs::base64Encode(hmac_buffer));
// myDebug() << sig << endl;
KURL url = m_siteUrl;
url.setQuery(query + "&Signature=" + sig);
return url;
}

@ -0,0 +1,52 @@
/***************************************************************************
Copyright (C) 2007-2009 Robby Stephenson <robby@periapsis.org>
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License or (at your option) version 3 or any later version *
* accepted by the membership of KDE e.V. (or its successor approved *
* by the membership of KDE e.V.), which shall act as a proxy *
* defined in Section 14 of version 3 of the license. *
* *
* 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, see <http://www.gnu.org/licenses/>. *
* *
***************************************************************************/
#ifndef TELLICO_FETCH_AMAZONREQUEST_H
#define TELLICO_FETCH_AMAZONREQUEST_H
#include <kurl.h>
#include <tqmap.h>
namespace Tellico {
namespace Fetch {
/**
* @author Robby Stephenson
*/
class AmazonRequest {
public:
AmazonRequest(const KURL& site, const TQString& key);
KURL signedRequest(const TQMap<TQString, TQString>& params) const;
private:
KURL m_siteUrl;
TQString m_key;
};
} // end Fetch namespace
} // end Tellico namespace
#endif

@ -226,6 +226,13 @@ Tellico::Data::EntryPtr ArxivFetcher::fetchEntry(uint uid_) {
}
}
}
TQRegExp versionRx(TQString::fromLatin1("v\\d+$"));
// if the original search was not for a versioned ID, remove it
if(m_key != ArxivID || !m_value.contains(versionRx)) {
TQString arxiv = entry->field(TQString::fromLatin1("arxiv"));
arxiv.remove(versionRx);
entry->setField(TQString::fromLatin1("arxiv"), arxiv);
}
return entry;
}

@ -163,7 +163,15 @@ void CitebaseFetcher::slotComplete(TDEIO::Job* job_) {
}
Tellico::Data::EntryPtr CitebaseFetcher::fetchEntry(uint uid_) {
return m_entries[uid_];
Data::EntryPtr entry = m_entries[uid_];
TQRegExp versionRx(TQString::fromLatin1("v\\d+$"));
// if the original search was not for a versioned ID, remove it
if(m_key != ArxivID || !m_value.contains(versionRx)) {
TQString arxiv = entry->field(TQString::fromLatin1("arxiv"));
arxiv.remove(versionRx);
entry->setField(TQString::fromLatin1("arxiv"), arxiv);
}
return entry;
}
KURL CitebaseFetcher::searchURL(FetchKey key_, const TQString& value_) const {

@ -34,7 +34,7 @@
//#define ENTREZ_TEST
namespace {
static const int ENTREZ_MAX_RETURNS_TOTAL = 25;
static const size_t 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";

@ -92,8 +92,8 @@ private:
XSLTHandler* m_xsltHandler;
TQString m_dbname;
int m_start;
int m_total;
size_t m_start;
size_t m_total;
TQByteArray m_data;
TQMap<int, Data::EntryPtr> m_entries; // map from search result id to entry

@ -28,7 +28,7 @@
#include <tqlayout.h>
namespace {
static const int GOOGLE_MAX_RETURNS_TOTAL = 20;
static const size_t GOOGLE_MAX_RETURNS_TOTAL = 20;
static const char* SCHOLAR_BASE_URL = "http://scholar.google.com/scholar";
}
@ -157,7 +157,7 @@ void GoogleScholarFetcher::slotComplete(TDEIO::Job* job_) {
TQString text = TQString::fromUtf8(m_data, m_data.size());
TQString bibtex;
int count = 0;
size_t 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(TQString::fromLatin1(SCHOLAR_BASE_URL), m_bibtexRx.cap(1));
// myDebug() << bibtexUrl << endl;

@ -83,9 +83,9 @@ private slots:
private:
void doSearch();
int m_limit;
int m_start;
int m_total;
size_t m_limit;
size_t m_start;
size_t m_total;
TQByteArray m_data;
TQMap<int, Data::EntryPtr> m_entries;

@ -0,0 +1,544 @@
/*-
* HMAC-SHA-224/256/384/512 implementation
* Last update: 06/15/2005
* Issue date: 06/15/2005
*
* Copyright (C) 2005 Olivier Gay <olivier.gay@a3.epfl.ch>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <string.h>
#include "hmac_sha2.h"
/* HMAC-SHA-224 functions */
void hmac_sha224_init(hmac_sha224_ctx *ctx, unsigned char *key,
unsigned int key_size)
{
unsigned int fill;
unsigned int num;
unsigned char *key_used;
unsigned char key_temp[SHA224_DIGEST_SIZE];
int i;
if (key_size == SHA224_BLOCK_SIZE) {
key_used = key;
num = SHA224_BLOCK_SIZE;
} else {
if (key_size > SHA224_BLOCK_SIZE){
key_used = key_temp;
num = SHA224_DIGEST_SIZE;
sha224(key, key_size, key_used);
} else { /* key_size > SHA224_BLOCK_SIZE */
key_used = key;
num = key_size;
}
fill = SHA224_BLOCK_SIZE - num;
memset(ctx->block_ipad + num, 0x36, fill);
memset(ctx->block_opad + num, 0x5c, fill);
}
for (i = 0; i < num; i++) {
ctx->block_ipad[i] = key_used[i] ^ 0x36;
ctx->block_opad[i] = key_used[i] ^ 0x5c;
}
sha224_init(&ctx->ctx_inside);
sha224_update(&ctx->ctx_inside, ctx->block_ipad, SHA224_BLOCK_SIZE);
sha224_init(&ctx->ctx_outside);
sha224_update(&ctx->ctx_outside, ctx->block_opad,
SHA224_BLOCK_SIZE);
/* for hmac_reinit */
memcpy(&ctx->ctx_inside_reinit, &ctx->ctx_inside,
sizeof(sha224_ctx));
memcpy(&ctx->ctx_outside_reinit, &ctx->ctx_outside,
sizeof(sha224_ctx));
}
void hmac_sha224_reinit(hmac_sha224_ctx *ctx)
{
memcpy(&ctx->ctx_inside, &ctx->ctx_inside_reinit,
sizeof(sha224_ctx));
memcpy(&ctx->ctx_outside, &ctx->ctx_outside_reinit,
sizeof(sha224_ctx));
}
void hmac_sha224_update(hmac_sha224_ctx *ctx, unsigned char *message,
unsigned int message_len)
{
sha224_update(&ctx->ctx_inside, message, message_len);
}
void hmac_sha224_final(hmac_sha224_ctx *ctx, unsigned char *mac,
unsigned int mac_size)
{
unsigned char digest_inside[SHA224_DIGEST_SIZE];
unsigned char mac_temp[SHA224_DIGEST_SIZE];
sha224_final(&ctx->ctx_inside, digest_inside);
sha224_update(&ctx->ctx_outside, digest_inside, SHA224_DIGEST_SIZE);
sha224_final(&ctx->ctx_outside, mac_temp);
memcpy(mac, mac_temp, mac_size);
}
void hmac_sha224(unsigned char *key, unsigned int key_size,
unsigned char *message, unsigned int message_len,
unsigned char *mac, unsigned mac_size)
{
hmac_sha224_ctx ctx;
hmac_sha224_init(&ctx, key, key_size);
hmac_sha224_update(&ctx, message, message_len);
hmac_sha224_final(&ctx, mac, mac_size);
}
/* HMAC-SHA-256 functions */
void hmac_sha256_init(hmac_sha256_ctx *ctx, unsigned char *key,
unsigned int key_size)
{
unsigned int fill;
unsigned int num;
unsigned char *key_used;
unsigned char key_temp[SHA256_DIGEST_SIZE];
int i;
if (key_size == SHA256_BLOCK_SIZE) {
key_used = key;
num = SHA256_BLOCK_SIZE;
} else {
if (key_size > SHA256_BLOCK_SIZE){
key_used = key_temp;
num = SHA256_DIGEST_SIZE;
sha256(key, key_size, key_used);
} else { /* key_size > SHA256_BLOCK_SIZE */
key_used = key;
num = key_size;
}
fill = SHA256_BLOCK_SIZE - num;
memset(ctx->block_ipad + num, 0x36, fill);
memset(ctx->block_opad + num, 0x5c, fill);
}
for (i = 0; i < num; i++) {
ctx->block_ipad[i] = key_used[i] ^ 0x36;
ctx->block_opad[i] = key_used[i] ^ 0x5c;
}
sha256_init(&ctx->ctx_inside);
sha256_update(&ctx->ctx_inside, ctx->block_ipad, SHA256_BLOCK_SIZE);
sha256_init(&ctx->ctx_outside);
sha256_update(&ctx->ctx_outside, ctx->block_opad,
SHA256_BLOCK_SIZE);
/* for hmac_reinit */
memcpy(&ctx->ctx_inside_reinit, &ctx->ctx_inside,
sizeof(sha256_ctx));
memcpy(&ctx->ctx_outside_reinit, &ctx->ctx_outside,
sizeof(sha256_ctx));
}
void hmac_sha256_reinit(hmac_sha256_ctx *ctx)
{
memcpy(&ctx->ctx_inside, &ctx->ctx_inside_reinit,
sizeof(sha256_ctx));
memcpy(&ctx->ctx_outside, &ctx->ctx_outside_reinit,
sizeof(sha256_ctx));
}
void hmac_sha256_update(hmac_sha256_ctx *ctx, unsigned char *message,
unsigned int message_len)
{
sha256_update(&ctx->ctx_inside, message, message_len);
}
void hmac_sha256_final(hmac_sha256_ctx *ctx, unsigned char *mac,
unsigned int mac_size)
{
unsigned char digest_inside[SHA256_DIGEST_SIZE];
unsigned char mac_temp[SHA256_DIGEST_SIZE];
sha256_final(&ctx->ctx_inside, digest_inside);
sha256_update(&ctx->ctx_outside, digest_inside, SHA256_DIGEST_SIZE);
sha256_final(&ctx->ctx_outside, mac_temp);
memcpy(mac, mac_temp, mac_size);
}
void hmac_sha256(unsigned char *key, unsigned int key_size,
unsigned char *message, unsigned int message_len,
unsigned char *mac, unsigned mac_size)
{
hmac_sha256_ctx ctx;
hmac_sha256_init(&ctx, key, key_size);
hmac_sha256_update(&ctx, message, message_len);
hmac_sha256_final(&ctx, mac, mac_size);
}
/* HMAC-SHA-384 functions */
void hmac_sha384_init(hmac_sha384_ctx *ctx, unsigned char *key,
unsigned int key_size)
{
unsigned int fill;
unsigned int num;
unsigned char *key_used;
unsigned char key_temp[SHA384_DIGEST_SIZE];
int i;
if (key_size == SHA384_BLOCK_SIZE) {
key_used = key;
num = SHA384_BLOCK_SIZE;
} else {
if (key_size > SHA384_BLOCK_SIZE){
key_used = key_temp;
num = SHA384_DIGEST_SIZE;
sha384(key, key_size, key_used);
} else { /* key_size > SHA384_BLOCK_SIZE */
key_used = key;
num = key_size;
}
fill = SHA384_BLOCK_SIZE - num;
memset(ctx->block_ipad + num, 0x36, fill);
memset(ctx->block_opad + num, 0x5c, fill);
}
for (i = 0; i < num; i++) {
ctx->block_ipad[i] = key_used[i] ^ 0x36;
ctx->block_opad[i] = key_used[i] ^ 0x5c;
}
sha384_init(&ctx->ctx_inside);
sha384_update(&ctx->ctx_inside, ctx->block_ipad, SHA384_BLOCK_SIZE);
sha384_init(&ctx->ctx_outside);
sha384_update(&ctx->ctx_outside, ctx->block_opad,
SHA384_BLOCK_SIZE);
/* for hmac_reinit */
memcpy(&ctx->ctx_inside_reinit, &ctx->ctx_inside,
sizeof(sha384_ctx));
memcpy(&ctx->ctx_outside_reinit, &ctx->ctx_outside,
sizeof(sha384_ctx));
}
void hmac_sha384_reinit(hmac_sha384_ctx *ctx)
{
memcpy(&ctx->ctx_inside, &ctx->ctx_inside_reinit,
sizeof(sha384_ctx));
memcpy(&ctx->ctx_outside, &ctx->ctx_outside_reinit,
sizeof(sha384_ctx));
}
void hmac_sha384_update(hmac_sha384_ctx *ctx, unsigned char *message,
unsigned int message_len)
{
sha384_update(&ctx->ctx_inside, message, message_len);
}
void hmac_sha384_final(hmac_sha384_ctx *ctx, unsigned char *mac,
unsigned int mac_size)
{
unsigned char digest_inside[SHA384_DIGEST_SIZE];
unsigned char mac_temp[SHA384_DIGEST_SIZE];
sha384_final(&ctx->ctx_inside, digest_inside);
sha384_update(&ctx->ctx_outside, digest_inside, SHA384_DIGEST_SIZE);
sha384_final(&ctx->ctx_outside, mac_temp);
memcpy(mac, mac_temp, mac_size);
}
void hmac_sha384(unsigned char *key, unsigned int key_size,
unsigned char *message, unsigned int message_len,
unsigned char *mac, unsigned mac_size)
{
hmac_sha384_ctx ctx;
hmac_sha384_init(&ctx, key, key_size);
hmac_sha384_update(&ctx, message, message_len);
hmac_sha384_final(&ctx, mac, mac_size);
}
/* HMAC-SHA-512 functions */
void hmac_sha512_init(hmac_sha512_ctx *ctx, unsigned char *key,
unsigned int key_size)
{
unsigned int fill;
unsigned int num;
unsigned char *key_used;
unsigned char key_temp[SHA512_DIGEST_SIZE];
int i;
if (key_size == SHA512_BLOCK_SIZE) {
key_used = key;
num = SHA512_BLOCK_SIZE;
} else {
if (key_size > SHA512_BLOCK_SIZE){
key_used = key_temp;
num = SHA512_DIGEST_SIZE;
sha512(key, key_size, key_used);
} else { /* key_size > SHA512_BLOCK_SIZE */
key_used = key;
num = key_size;
}
fill = SHA512_BLOCK_SIZE - num;
memset(ctx->block_ipad + num, 0x36, fill);
memset(ctx->block_opad + num, 0x5c, fill);
}
for (i = 0; i < num; i++) {
ctx->block_ipad[i] = key_used[i] ^ 0x36;
ctx->block_opad[i] = key_used[i] ^ 0x5c;
}
sha512_init(&ctx->ctx_inside);
sha512_update(&ctx->ctx_inside, ctx->block_ipad, SHA512_BLOCK_SIZE);
sha512_init(&ctx->ctx_outside);
sha512_update(&ctx->ctx_outside, ctx->block_opad,
SHA512_BLOCK_SIZE);
/* for hmac_reinit */
memcpy(&ctx->ctx_inside_reinit, &ctx->ctx_inside,
sizeof(sha512_ctx));
memcpy(&ctx->ctx_outside_reinit, &ctx->ctx_outside,
sizeof(sha512_ctx));
}
void hmac_sha512_reinit(hmac_sha512_ctx *ctx)
{
memcpy(&ctx->ctx_inside, &ctx->ctx_inside_reinit,
sizeof(sha512_ctx));
memcpy(&ctx->ctx_outside, &ctx->ctx_outside_reinit,
sizeof(sha512_ctx));
}
void hmac_sha512_update(hmac_sha512_ctx *ctx, unsigned char *message,
unsigned int message_len)
{
sha512_update(&ctx->ctx_inside, message, message_len);
}
void hmac_sha512_final(hmac_sha512_ctx *ctx, unsigned char *mac,
unsigned int mac_size)
{
unsigned char digest_inside[SHA512_DIGEST_SIZE];
unsigned char mac_temp[SHA512_DIGEST_SIZE];
sha512_final(&ctx->ctx_inside, digest_inside);
sha512_update(&ctx->ctx_outside, digest_inside, SHA512_DIGEST_SIZE);
sha512_final(&ctx->ctx_outside, mac_temp);
memcpy(mac, mac_temp, mac_size);
}
void hmac_sha512(unsigned char *key, unsigned int key_size,
unsigned char *message, unsigned int message_len,
unsigned char *mac, unsigned mac_size)
{
hmac_sha512_ctx ctx;
hmac_sha512_init(&ctx, key, key_size);
hmac_sha512_update(&ctx, message, message_len);
hmac_sha512_final(&ctx, mac, mac_size);
}
#ifdef TEST_VECTORS
/* IETF Validation tests */
#include <stdio.h>
#include <stdlib.h>
void test(unsigned char *vector, unsigned char *digest,
unsigned int digest_size)
{
unsigned char output[2 * SHA512_DIGEST_SIZE + 1];
int i;
output[2 * digest_size] = '\0';
for (i = 0; i < digest_size ; i++) {
sprintf((char *) output + 2*i, "%02x", digest[i]);
}
printf("H: %s\n", output);
if (strcmp((char *) vector, (char *) output)) {
fprintf(stderr, "Test failed.\n");
exit(1);
}
}
int main()
{
static unsigned char *vectors[] =
{
/* HMAC-SHA-224 */
"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22",
"a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44",
"7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea",
"6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a",
"0e2aea68a90c8d37c988bcdb9fca6fa8",
"95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e",
"3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1",
/* HMAC-SHA-256 */
"b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7",
"5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843",
"773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe",
"82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b",
"a3b6167473100ee06e0c796c2955552b",
"60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54",
"9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2",
/* HMAC-SHA-384 */
"afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59c"
"faea9ea9076ede7f4af152e8b2fa9cb6",
"af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e"
"8e2240ca5e69e2c78b3239ecfab21649",
"88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b"
"2a5ab39dc13814b94e3ab6e101a34f27",
"3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e"
"6801dd23c4a7d679ccf8a386c674cffb",
"3abf34c3503b2a23a46efc619baef897",
"4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c6"
"0c2ef6ab4030fe8296248df163f44952",
"6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5"
"a678cc31e799176d3860e6110c46523e",
/* HMAC-SHA-512 */
"87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cde"
"daa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854",
"164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea250554"
"9758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737",
"fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39"
"bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb",
"b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3db"
"a91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd",
"415fad6271580a531d4179bc891d87a6",
"80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f352"
"6b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598",
"e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944"
"b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58"
};
static unsigned char *messages[] =
{
"Hi There",
"what do ya want for nothing?",
NULL,
NULL,
"Test With Truncation",
"Test Using Larger Than Block-Size Key - Hash Key First",
"This is a test using a larger than block-size key "
"and a larger than block-size data. The key needs"
" to be hashed before being used by the HMAC algorithm."
};
unsigned char mac[SHA512_DIGEST_SIZE];
unsigned char *keys[7];
unsigned int keys_len[7] = {20, 4, 20, 25, 20, 131, 131};
unsigned int messages2and3_len = 50;
unsigned int mac_224_size, mac_256_size, mac_384_size, mac_512_size;
int i;
for (i = 0; i < 7; i++) {
keys[i] = malloc(keys_len[i]);
if (keys[i] == NULL) {
fprintf(stderr, "Can't allocate memory\n");
return 1;
}
}
memset(keys[0], 0x0b, keys_len[0]);
strcpy(keys[1], "Jefe");
memset(keys[2], 0xaa, keys_len[2]);
for (i = 0; i < keys_len[3]; i++)
keys[3][i] = (unsigned char) i + 1;
memset(keys[4], 0x0c, keys_len[4]);
memset(keys[5], 0xaa, keys_len[5]);
memset(keys[6], 0xaa, keys_len[6]);
messages[2] = malloc(messages2and3_len + 1);
messages[3] = malloc(messages2and3_len + 1);
if (messages[2] == NULL || messages[3] == NULL) {
fprintf(stderr, "Can't allocate memory\n");
return 1;
}
messages[2][messages2and3_len] = '\0';
messages[3][messages2and3_len] = '\0';
memset(messages[2], 0xdd, messages2and3_len);
memset(messages[3], 0xcd, messages2and3_len);
printf("HMAC-SHA-2 IETF Validation tests\n\n");
for (i = 0; i < 7; i++) {
if (i != 4) {
mac_224_size = SHA224_DIGEST_SIZE;
mac_256_size = SHA256_DIGEST_SIZE;
mac_384_size = SHA384_DIGEST_SIZE;
mac_512_size = SHA512_DIGEST_SIZE;
} else {
mac_224_size = 128 / 8; mac_256_size = 128 / 8;
mac_384_size = 128 / 8; mac_512_size = 128 / 8;
}
printf("Test %d:\n", i + 1);
hmac_sha224(keys[i], keys_len[i], messages[i], strlen(messages[i]),
mac, mac_224_size);
test(vectors[i], mac, mac_224_size );
hmac_sha256(keys[i], keys_len[i], messages[i], strlen(messages[i]),
mac, mac_256_size);
test(vectors[7 + i], mac, mac_256_size);
hmac_sha384(keys[i], keys_len[i], messages[i], strlen(messages[i]),
mac, mac_384_size);
test(vectors[14 + i], mac, mac_384_size);
hmac_sha512(keys[i], keys_len[i], messages[i], strlen(messages[i]),
mac, mac_512_size);
test(vectors[21 + i], mac, mac_512_size);
}
printf("All tests passed.\n");
return 0;
}
#endif /* TEST_VECTORS */

@ -0,0 +1,140 @@
/*-
* HMAC-SHA-224/256/384/512 implementation
* Last update: 06/15/2005
* Issue date: 06/15/2005
*
* Copyright (C) 2005 Olivier Gay <olivier.gay@a3.epfl.ch>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _HMAC_SHA2_H
#define _HMAC_SHA2_H
#include "sha2.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
sha224_ctx ctx_inside;
sha224_ctx ctx_outside;
/* for hmac_reinit */
sha224_ctx ctx_inside_reinit;
sha224_ctx ctx_outside_reinit;
unsigned char block_ipad[SHA224_BLOCK_SIZE];
unsigned char block_opad[SHA224_BLOCK_SIZE];
} hmac_sha224_ctx;
typedef struct {
sha256_ctx ctx_inside;
sha256_ctx ctx_outside;
/* for hmac_reinit */
sha256_ctx ctx_inside_reinit;
sha256_ctx ctx_outside_reinit;
unsigned char block_ipad[SHA256_BLOCK_SIZE];
unsigned char block_opad[SHA256_BLOCK_SIZE];
} hmac_sha256_ctx;
typedef struct {
sha384_ctx ctx_inside;
sha384_ctx ctx_outside;
/* for hmac_reinit */
sha384_ctx ctx_inside_reinit;
sha384_ctx ctx_outside_reinit;
unsigned char block_ipad[SHA384_BLOCK_SIZE];
unsigned char block_opad[SHA384_BLOCK_SIZE];
} hmac_sha384_ctx;
typedef struct {
sha512_ctx ctx_inside;
sha512_ctx ctx_outside;
/* for hmac_reinit */
sha512_ctx ctx_inside_reinit;
sha512_ctx ctx_outside_reinit;
unsigned char block_ipad[SHA512_BLOCK_SIZE];
unsigned char block_opad[SHA512_BLOCK_SIZE];
} hmac_sha512_ctx;
void hmac_sha224_init(hmac_sha224_ctx *ctx, unsigned char *key,
unsigned int key_size);
void hmac_sha224_reinit(hmac_sha224_ctx *ctx);
void hmac_sha224_update(hmac_sha224_ctx *ctx, unsigned char *message,
unsigned int message_len);
void hmac_sha224_final(hmac_sha224_ctx *ctx, unsigned char *mac,
unsigned int mac_size);
void hmac_sha224(unsigned char *key, unsigned int key_size,
unsigned char *message, unsigned int message_len,
unsigned char *mac, unsigned mac_size);
void hmac_sha256_init(hmac_sha256_ctx *ctx, unsigned char *key,
unsigned int key_size);
void hmac_sha256_reinit(hmac_sha256_ctx *ctx);
void hmac_sha256_update(hmac_sha256_ctx *ctx, unsigned char *message,
unsigned int message_len);
void hmac_sha256_final(hmac_sha256_ctx *ctx, unsigned char *mac,
unsigned int mac_size);
void hmac_sha256(unsigned char *key, unsigned int key_size,
unsigned char *message, unsigned int message_len,
unsigned char *mac, unsigned mac_size);
void hmac_sha384_init(hmac_sha384_ctx *ctx, unsigned char *key,
unsigned int key_size);
void hmac_sha384_reinit(hmac_sha384_ctx *ctx);
void hmac_sha384_update(hmac_sha384_ctx *ctx, unsigned char *message,
unsigned int message_len);
void hmac_sha384_final(hmac_sha384_ctx *ctx, unsigned char *mac,
unsigned int mac_size);
void hmac_sha384(unsigned char *key, unsigned int key_size,
unsigned char *message, unsigned int message_len,
unsigned char *mac, unsigned mac_size);
void hmac_sha512_init(hmac_sha512_ctx *ctx, unsigned char *key,
unsigned int key_size);
void hmac_sha512_reinit(hmac_sha512_ctx *ctx);
void hmac_sha512_update(hmac_sha512_ctx *ctx, unsigned char *message,
unsigned int message_len);
void hmac_sha512_final(hmac_sha512_ctx *ctx, unsigned char *mac,
unsigned int mac_size);
void hmac_sha512(unsigned char *key, unsigned int key_size,
unsigned char *message, unsigned int message_len,
unsigned char *mac, unsigned mac_size);
#ifdef __cplusplus
}
#endif
#endif /* ! _HMAC_SHA2_H */

@ -156,7 +156,8 @@ void IBSFetcher::slotComplete(TDEIO::Job* job_) {
TQString s = Tellico::decodeHTML(TQString(m_data));
// really specific regexp
TQString pat = TQString::fromLatin1("http://www.internetbookshop.it/code/");
//TQString pat = TQString::fromLatin1("http://www.internetbookshop.it/code/");
TQString pat = TQString::fromLatin1("http://www.ibs.it/code/");
TQRegExp anchorRx(TQString::fromLatin1("<a\\s+[^>]*href\\s*=\\s*[\"'](") +
TQRegExp::escape(pat) +
TQString::fromLatin1("[^\"]*)\"[^>]*><b>([^<]+)<"), false);

@ -799,7 +799,7 @@ void IMDBFetcher::doPlot(const TQString& str_, Data::EntryPtr entry_, const KURL
TQString thisPlot;
// match until next opening tag
TQRegExp plotRx(TQString::fromLatin1("plot (?:outline|summary):(.*)<[^/].*</"), false);
TQRegExp plotRx(TQString::fromLatin1("plot\\s*(?:outline|summary)?:(.*)<[^/].*</"), false);
plotRx.setMinimal(true);
TQRegExp plotURLRx(TQString::fromLatin1("<a\\s+.*href\\s*=\\s*\".*/title/.*/plotsummary\""), false);
plotURLRx.setMinimal(true);
@ -828,6 +828,8 @@ void IMDBFetcher::doPlot(const TQString& str_, Data::EntryPtr entry_, const KURL
if(plotRx.search(plotPage) > -1) {
TQString userPlot = plotRx.cap(1);
userPlot.remove(*s_tagRx); // remove HTML tags
// remove last little "written by", if there
userPlot.remove(TQRegExp(TQString::fromLatin1("\\s*written by.*$"), false));
entry_->setField(TQString::fromLatin1("plot"), Tellico::decodeHTML(userPlot));
}
}

@ -0,0 +1,950 @@
/*
* FIPS 180-2 SHA-224/256/384/512 implementation
* Last update: 02/02/2007
* Issue date: 04/30/2005
*
* Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#define UNROLL_LOOPS /* Enable loops unrolling */
#endif
#include <string.h>
#include "sha2.h"
#define SHFR(x, n) (x >> n)
#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
#define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
#define CH(x, y, z) ((x & y) ^ (~x & z))
#define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
#define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
#define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
#define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3))
#define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))
#define SHA512_F1(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
#define SHA512_F2(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
#define SHA512_F3(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHFR(x, 7))
#define SHA512_F4(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHFR(x, 6))
#define UNPACK32(x, str) \
{ \
*((str) + 3) = (uint8) ((x) ); \
*((str) + 2) = (uint8) ((x) >> 8); \
*((str) + 1) = (uint8) ((x) >> 16); \
*((str) + 0) = (uint8) ((x) >> 24); \
}
#define PACK32(str, x) \
{ \
*(x) = ((uint32) *((str) + 3) ) \
| ((uint32) *((str) + 2) << 8) \
| ((uint32) *((str) + 1) << 16) \
| ((uint32) *((str) + 0) << 24); \
}
#define UNPACK64(x, str) \
{ \
*((str) + 7) = (uint8) ((x) ); \
*((str) + 6) = (uint8) ((x) >> 8); \
*((str) + 5) = (uint8) ((x) >> 16); \
*((str) + 4) = (uint8) ((x) >> 24); \
*((str) + 3) = (uint8) ((x) >> 32); \
*((str) + 2) = (uint8) ((x) >> 40); \
*((str) + 1) = (uint8) ((x) >> 48); \
*((str) + 0) = (uint8) ((x) >> 56); \
}
#define PACK64(str, x) \
{ \
*(x) = ((uint64) *((str) + 7) ) \
| ((uint64) *((str) + 6) << 8) \
| ((uint64) *((str) + 5) << 16) \
| ((uint64) *((str) + 4) << 24) \
| ((uint64) *((str) + 3) << 32) \
| ((uint64) *((str) + 2) << 40) \
| ((uint64) *((str) + 1) << 48) \
| ((uint64) *((str) + 0) << 56); \
}
/* Macros used for loops unrolling */
#define SHA256_SCR(i) \
{ \
w[i] = SHA256_F4(w[i - 2]) + w[i - 7] \
+ SHA256_F3(w[i - 15]) + w[i - 16]; \
}
#define SHA512_SCR(i) \
{ \
w[i] = SHA512_F4(w[i - 2]) + w[i - 7] \
+ SHA512_F3(w[i - 15]) + w[i - 16]; \
}
#define SHA256_EXP(a, b, c, d, e, f, g, h, j) \
{ \
t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \
+ sha256_k[j] + w[j]; \
t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \
wv[d] += t1; \
wv[h] = t1 + t2; \
}
#define SHA512_EXP(a, b, c, d, e, f, g ,h, j) \
{ \
t1 = wv[h] + SHA512_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \
+ sha512_k[j] + w[j]; \
t2 = SHA512_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \
wv[d] += t1; \
wv[h] = t1 + t2; \
}
uint32 sha224_h0[8] =
{0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
uint32 sha256_h0[8] =
{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
uint64 sha384_h0[8] =
{0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL,
0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL,
0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL};
uint64 sha512_h0[8] =
{0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};
uint32 sha256_k[64] =
{0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
uint64 sha512_k[80] =
{0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};
/* SHA-256 functions */
void sha256_transf(sha256_ctx *ctx, const unsigned char *message,
unsigned int block_nb)
{
uint32 w[64];
uint32 wv[8];
uint32 t1, t2;
const unsigned char *sub_block;
int i;
#ifndef UNROLL_LOOPS
int j;
#endif
for (i = 0; i < (int) block_nb; i++) {
sub_block = message + (i << 6);
#ifndef UNROLL_LOOPS
for (j = 0; j < 16; j++) {
PACK32(&sub_block[j << 2], &w[j]);
}
for (j = 16; j < 64; j++) {
SHA256_SCR(j);
}
for (j = 0; j < 8; j++) {
wv[j] = ctx->h[j];
}
for (j = 0; j < 64; j++) {
t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6])
+ sha256_k[j] + w[j];
t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
wv[7] = wv[6];
wv[6] = wv[5];
wv[5] = wv[4];
wv[4] = wv[3] + t1;
wv[3] = wv[2];
wv[2] = wv[1];
wv[1] = wv[0];
wv[0] = t1 + t2;
}
for (j = 0; j < 8; j++) {
ctx->h[j] += wv[j];
}
#else
PACK32(&sub_block[ 0], &w[ 0]); PACK32(&sub_block[ 4], &w[ 1]);
PACK32(&sub_block[ 8], &w[ 2]); PACK32(&sub_block[12], &w[ 3]);
PACK32(&sub_block[16], &w[ 4]); PACK32(&sub_block[20], &w[ 5]);
PACK32(&sub_block[24], &w[ 6]); PACK32(&sub_block[28], &w[ 7]);
PACK32(&sub_block[32], &w[ 8]); PACK32(&sub_block[36], &w[ 9]);
PACK32(&sub_block[40], &w[10]); PACK32(&sub_block[44], &w[11]);
PACK32(&sub_block[48], &w[12]); PACK32(&sub_block[52], &w[13]);
PACK32(&sub_block[56], &w[14]); PACK32(&sub_block[60], &w[15]);
SHA256_SCR(16); SHA256_SCR(17); SHA256_SCR(18); SHA256_SCR(19);
SHA256_SCR(20); SHA256_SCR(21); SHA256_SCR(22); SHA256_SCR(23);
SHA256_SCR(24); SHA256_SCR(25); SHA256_SCR(26); SHA256_SCR(27);
SHA256_SCR(28); SHA256_SCR(29); SHA256_SCR(30); SHA256_SCR(31);
SHA256_SCR(32); SHA256_SCR(33); SHA256_SCR(34); SHA256_SCR(35);
SHA256_SCR(36); SHA256_SCR(37); SHA256_SCR(38); SHA256_SCR(39);
SHA256_SCR(40); SHA256_SCR(41); SHA256_SCR(42); SHA256_SCR(43);
SHA256_SCR(44); SHA256_SCR(45); SHA256_SCR(46); SHA256_SCR(47);
SHA256_SCR(48); SHA256_SCR(49); SHA256_SCR(50); SHA256_SCR(51);
SHA256_SCR(52); SHA256_SCR(53); SHA256_SCR(54); SHA256_SCR(55);
SHA256_SCR(56); SHA256_SCR(57); SHA256_SCR(58); SHA256_SCR(59);
SHA256_SCR(60); SHA256_SCR(61); SHA256_SCR(62); SHA256_SCR(63);
wv[0] = ctx->h[0]; wv[1] = ctx->h[1];
wv[2] = ctx->h[2]; wv[3] = ctx->h[3];
wv[4] = ctx->h[4]; wv[5] = ctx->h[5];
wv[6] = ctx->h[6]; wv[7] = ctx->h[7];
SHA256_EXP(0,1,2,3,4,5,6,7, 0); SHA256_EXP(7,0,1,2,3,4,5,6, 1);
SHA256_EXP(6,7,0,1,2,3,4,5, 2); SHA256_EXP(5,6,7,0,1,2,3,4, 3);
SHA256_EXP(4,5,6,7,0,1,2,3, 4); SHA256_EXP(3,4,5,6,7,0,1,2, 5);
SHA256_EXP(2,3,4,5,6,7,0,1, 6); SHA256_EXP(1,2,3,4,5,6,7,0, 7);
SHA256_EXP(0,1,2,3,4,5,6,7, 8); SHA256_EXP(7,0,1,2,3,4,5,6, 9);
SHA256_EXP(6,7,0,1,2,3,4,5,10); SHA256_EXP(5,6,7,0,1,2,3,4,11);
SHA256_EXP(4,5,6,7,0,1,2,3,12); SHA256_EXP(3,4,5,6,7,0,1,2,13);
SHA256_EXP(2,3,4,5,6,7,0,1,14); SHA256_EXP(1,2,3,4,5,6,7,0,15);
SHA256_EXP(0,1,2,3,4,5,6,7,16); SHA256_EXP(7,0,1,2,3,4,5,6,17);
SHA256_EXP(6,7,0,1,2,3,4,5,18); SHA256_EXP(5,6,7,0,1,2,3,4,19);
SHA256_EXP(4,5,6,7,0,1,2,3,20); SHA256_EXP(3,4,5,6,7,0,1,2,21);
SHA256_EXP(2,3,4,5,6,7,0,1,22); SHA256_EXP(1,2,3,4,5,6,7,0,23);
SHA256_EXP(0,1,2,3,4,5,6,7,24); SHA256_EXP(7,0,1,2,3,4,5,6,25);
SHA256_EXP(6,7,0,1,2,3,4,5,26); SHA256_EXP(5,6,7,0,1,2,3,4,27);
SHA256_EXP(4,5,6,7,0,1,2,3,28); SHA256_EXP(3,4,5,6,7,0,1,2,29);
SHA256_EXP(2,3,4,5,6,7,0,1,30); SHA256_EXP(1,2,3,4,5,6,7,0,31);
SHA256_EXP(0,1,2,3,4,5,6,7,32); SHA256_EXP(7,0,1,2,3,4,5,6,33);
SHA256_EXP(6,7,0,1,2,3,4,5,34); SHA256_EXP(5,6,7,0,1,2,3,4,35);
SHA256_EXP(4,5,6,7,0,1,2,3,36); SHA256_EXP(3,4,5,6,7,0,1,2,37);
SHA256_EXP(2,3,4,5,6,7,0,1,38); SHA256_EXP(1,2,3,4,5,6,7,0,39);
SHA256_EXP(0,1,2,3,4,5,6,7,40); SHA256_EXP(7,0,1,2,3,4,5,6,41);
SHA256_EXP(6,7,0,1,2,3,4,5,42); SHA256_EXP(5,6,7,0,1,2,3,4,43);
SHA256_EXP(4,5,6,7,0,1,2,3,44); SHA256_EXP(3,4,5,6,7,0,1,2,45);
SHA256_EXP(2,3,4,5,6,7,0,1,46); SHA256_EXP(1,2,3,4,5,6,7,0,47);
SHA256_EXP(0,1,2,3,4,5,6,7,48); SHA256_EXP(7,0,1,2,3,4,5,6,49);
SHA256_EXP(6,7,0,1,2,3,4,5,50); SHA256_EXP(5,6,7,0,1,2,3,4,51);
SHA256_EXP(4,5,6,7,0,1,2,3,52); SHA256_EXP(3,4,5,6,7,0,1,2,53);
SHA256_EXP(2,3,4,5,6,7,0,1,54); SHA256_EXP(1,2,3,4,5,6,7,0,55);
SHA256_EXP(0,1,2,3,4,5,6,7,56); SHA256_EXP(7,0,1,2,3,4,5,6,57);
SHA256_EXP(6,7,0,1,2,3,4,5,58); SHA256_EXP(5,6,7,0,1,2,3,4,59);
SHA256_EXP(4,5,6,7,0,1,2,3,60); SHA256_EXP(3,4,5,6,7,0,1,2,61);
SHA256_EXP(2,3,4,5,6,7,0,1,62); SHA256_EXP(1,2,3,4,5,6,7,0,63);
ctx->h[0] += wv[0]; ctx->h[1] += wv[1];
ctx->h[2] += wv[2]; ctx->h[3] += wv[3];
ctx->h[4] += wv[4]; ctx->h[5] += wv[5];
ctx->h[6] += wv[6]; ctx->h[7] += wv[7];
#endif /* !UNROLL_LOOPS */
}
}
void sha256(const unsigned char *message, unsigned int len, unsigned char *digest)
{
sha256_ctx ctx;
sha256_init(&ctx);
sha256_update(&ctx, message, len);
sha256_final(&ctx, digest);
}
void sha256_init(sha256_ctx *ctx)
{
#ifndef UNROLL_LOOPS
int i;
for (i = 0; i < 8; i++) {
ctx->h[i] = sha256_h0[i];
}
#else
ctx->h[0] = sha256_h0[0]; ctx->h[1] = sha256_h0[1];
ctx->h[2] = sha256_h0[2]; ctx->h[3] = sha256_h0[3];
ctx->h[4] = sha256_h0[4]; ctx->h[5] = sha256_h0[5];
ctx->h[6] = sha256_h0[6]; ctx->h[7] = sha256_h0[7];
#endif /* !UNROLL_LOOPS */
ctx->len = 0;
ctx->tot_len = 0;
}
void sha256_update(sha256_ctx *ctx, const unsigned char *message,
unsigned int len)
{
unsigned int block_nb;
unsigned int new_len, rem_len, tmp_len;
const unsigned char *shifted_message;
tmp_len = SHA256_BLOCK_SIZE - ctx->len;
rem_len = len < tmp_len ? len : tmp_len;
memcpy(&ctx->block[ctx->len], message, rem_len);
if (ctx->len + len < SHA256_BLOCK_SIZE) {
ctx->len += len;
return;
}
new_len = len - rem_len;
block_nb = new_len / SHA256_BLOCK_SIZE;
shifted_message = message + rem_len;
sha256_transf(ctx, ctx->block, 1);
sha256_transf(ctx, shifted_message, block_nb);
rem_len = new_len % SHA256_BLOCK_SIZE;
memcpy(ctx->block, &shifted_message[block_nb << 6],
rem_len);
ctx->len = rem_len;
ctx->tot_len += (block_nb + 1) << 6;
}
void sha256_final(sha256_ctx *ctx, unsigned char *digest)
{
unsigned int block_nb;
unsigned int pm_len;
unsigned int len_b;
#ifndef UNROLL_LOOPS
int i;
#endif
block_nb = (1 + ((SHA256_BLOCK_SIZE - 9)
< (ctx->len % SHA256_BLOCK_SIZE)));
len_b = (ctx->tot_len + ctx->len) << 3;
pm_len = block_nb << 6;
memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
ctx->block[ctx->len] = 0x80;
UNPACK32(len_b, ctx->block + pm_len - 4);
sha256_transf(ctx, ctx->block, block_nb);
#ifndef UNROLL_LOOPS
for (i = 0 ; i < 8; i++) {
UNPACK32(ctx->h[i], &digest[i << 2]);
}
#else
UNPACK32(ctx->h[0], &digest[ 0]);
UNPACK32(ctx->h[1], &digest[ 4]);
UNPACK32(ctx->h[2], &digest[ 8]);
UNPACK32(ctx->h[3], &digest[12]);
UNPACK32(ctx->h[4], &digest[16]);
UNPACK32(ctx->h[5], &digest[20]);
UNPACK32(ctx->h[6], &digest[24]);
UNPACK32(ctx->h[7], &digest[28]);
#endif /* !UNROLL_LOOPS */
}
/* SHA-512 functions */
void sha512_transf(sha512_ctx *ctx, const unsigned char *message,
unsigned int block_nb)
{
uint64 w[80];
uint64 wv[8];
uint64 t1, t2;
const unsigned char *sub_block;
int i, j;
for (i = 0; i < (int) block_nb; i++) {
sub_block = message + (i << 7);
#ifndef UNROLL_LOOPS
for (j = 0; j < 16; j++) {
PACK64(&sub_block[j << 3], &w[j]);
}
for (j = 16; j < 80; j++) {
SHA512_SCR(j);
}
for (j = 0; j < 8; j++) {
wv[j] = ctx->h[j];
}
for (j = 0; j < 80; j++) {
t1 = wv[7] + SHA512_F2(wv[4]) + CH(wv[4], wv[5], wv[6])
+ sha512_k[j] + w[j];
t2 = SHA512_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
wv[7] = wv[6];
wv[6] = wv[5];
wv[5] = wv[4];
wv[4] = wv[3] + t1;
wv[3] = wv[2];
wv[2] = wv[1];
wv[1] = wv[0];
wv[0] = t1 + t2;
}
for (j = 0; j < 8; j++) {
ctx->h[j] += wv[j];
}
#else
PACK64(&sub_block[ 0], &w[ 0]); PACK64(&sub_block[ 8], &w[ 1]);
PACK64(&sub_block[ 16], &w[ 2]); PACK64(&sub_block[ 24], &w[ 3]);
PACK64(&sub_block[ 32], &w[ 4]); PACK64(&sub_block[ 40], &w[ 5]);
PACK64(&sub_block[ 48], &w[ 6]); PACK64(&sub_block[ 56], &w[ 7]);
PACK64(&sub_block[ 64], &w[ 8]); PACK64(&sub_block[ 72], &w[ 9]);
PACK64(&sub_block[ 80], &w[10]); PACK64(&sub_block[ 88], &w[11]);
PACK64(&sub_block[ 96], &w[12]); PACK64(&sub_block[104], &w[13]);
PACK64(&sub_block[112], &w[14]); PACK64(&sub_block[120], &w[15]);
SHA512_SCR(16); SHA512_SCR(17); SHA512_SCR(18); SHA512_SCR(19);
SHA512_SCR(20); SHA512_SCR(21); SHA512_SCR(22); SHA512_SCR(23);
SHA512_SCR(24); SHA512_SCR(25); SHA512_SCR(26); SHA512_SCR(27);
SHA512_SCR(28); SHA512_SCR(29); SHA512_SCR(30); SHA512_SCR(31);
SHA512_SCR(32); SHA512_SCR(33); SHA512_SCR(34); SHA512_SCR(35);
SHA512_SCR(36); SHA512_SCR(37); SHA512_SCR(38); SHA512_SCR(39);
SHA512_SCR(40); SHA512_SCR(41); SHA512_SCR(42); SHA512_SCR(43);
SHA512_SCR(44); SHA512_SCR(45); SHA512_SCR(46); SHA512_SCR(47);
SHA512_SCR(48); SHA512_SCR(49); SHA512_SCR(50); SHA512_SCR(51);
SHA512_SCR(52); SHA512_SCR(53); SHA512_SCR(54); SHA512_SCR(55);
SHA512_SCR(56); SHA512_SCR(57); SHA512_SCR(58); SHA512_SCR(59);
SHA512_SCR(60); SHA512_SCR(61); SHA512_SCR(62); SHA512_SCR(63);
SHA512_SCR(64); SHA512_SCR(65); SHA512_SCR(66); SHA512_SCR(67);
SHA512_SCR(68); SHA512_SCR(69); SHA512_SCR(70); SHA512_SCR(71);
SHA512_SCR(72); SHA512_SCR(73); SHA512_SCR(74); SHA512_SCR(75);
SHA512_SCR(76); SHA512_SCR(77); SHA512_SCR(78); SHA512_SCR(79);
wv[0] = ctx->h[0]; wv[1] = ctx->h[1];
wv[2] = ctx->h[2]; wv[3] = ctx->h[3];
wv[4] = ctx->h[4]; wv[5] = ctx->h[5];
wv[6] = ctx->h[6]; wv[7] = ctx->h[7];
j = 0;
do {
SHA512_EXP(0,1,2,3,4,5,6,7,j); j++;
SHA512_EXP(7,0,1,2,3,4,5,6,j); j++;
SHA512_EXP(6,7,0,1,2,3,4,5,j); j++;
SHA512_EXP(5,6,7,0,1,2,3,4,j); j++;
SHA512_EXP(4,5,6,7,0,1,2,3,j); j++;
SHA512_EXP(3,4,5,6,7,0,1,2,j); j++;
SHA512_EXP(2,3,4,5,6,7,0,1,j); j++;
SHA512_EXP(1,2,3,4,5,6,7,0,j); j++;
} while (j < 80);
ctx->h[0] += wv[0]; ctx->h[1] += wv[1];
ctx->h[2] += wv[2]; ctx->h[3] += wv[3];
ctx->h[4] += wv[4]; ctx->h[5] += wv[5];
ctx->h[6] += wv[6]; ctx->h[7] += wv[7];
#endif /* !UNROLL_LOOPS */
}
}
void sha512(const unsigned char *message, unsigned int len,
unsigned char *digest)
{
sha512_ctx ctx;
sha512_init(&ctx);
sha512_update(&ctx, message, len);
sha512_final(&ctx, digest);
}
void sha512_init(sha512_ctx *ctx)
{
#ifndef UNROLL_LOOPS
int i;
for (i = 0; i < 8; i++) {
ctx->h[i] = sha512_h0[i];
}
#else
ctx->h[0] = sha512_h0[0]; ctx->h[1] = sha512_h0[1];
ctx->h[2] = sha512_h0[2]; ctx->h[3] = sha512_h0[3];
ctx->h[4] = sha512_h0[4]; ctx->h[5] = sha512_h0[5];
ctx->h[6] = sha512_h0[6]; ctx->h[7] = sha512_h0[7];
#endif /* !UNROLL_LOOPS */
ctx->len = 0;
ctx->tot_len = 0;
}
void sha512_update(sha512_ctx *ctx, const unsigned char *message,
unsigned int len)
{
unsigned int block_nb;
unsigned int new_len, rem_len, tmp_len;
const unsigned char *shifted_message;
tmp_len = SHA512_BLOCK_SIZE - ctx->len;
rem_len = len < tmp_len ? len : tmp_len;
memcpy(&ctx->block[ctx->len], message, rem_len);
if (ctx->len + len < SHA512_BLOCK_SIZE) {
ctx->len += len;
return;
}
new_len = len - rem_len;
block_nb = new_len / SHA512_BLOCK_SIZE;
shifted_message = message + rem_len;
sha512_transf(ctx, ctx->block, 1);
sha512_transf(ctx, shifted_message, block_nb);
rem_len = new_len % SHA512_BLOCK_SIZE;
memcpy(ctx->block, &shifted_message[block_nb << 7],
rem_len);
ctx->len = rem_len;
ctx->tot_len += (block_nb + 1) << 7;
}
void sha512_final(sha512_ctx *ctx, unsigned char *digest)
{
unsigned int block_nb;
unsigned int pm_len;
unsigned int len_b;
#ifndef UNROLL_LOOPS
int i;
#endif
block_nb = 1 + ((SHA512_BLOCK_SIZE - 17)
< (ctx->len % SHA512_BLOCK_SIZE));
len_b = (ctx->tot_len + ctx->len) << 3;
pm_len = block_nb << 7;
memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
ctx->block[ctx->len] = 0x80;
UNPACK32(len_b, ctx->block + pm_len - 4);
sha512_transf(ctx, ctx->block, block_nb);
#ifndef UNROLL_LOOPS
for (i = 0 ; i < 8; i++) {
UNPACK64(ctx->h[i], &digest[i << 3]);
}
#else
UNPACK64(ctx->h[0], &digest[ 0]);
UNPACK64(ctx->h[1], &digest[ 8]);
UNPACK64(ctx->h[2], &digest[16]);
UNPACK64(ctx->h[3], &digest[24]);
UNPACK64(ctx->h[4], &digest[32]);
UNPACK64(ctx->h[5], &digest[40]);
UNPACK64(ctx->h[6], &digest[48]);
UNPACK64(ctx->h[7], &digest[56]);
#endif /* !UNROLL_LOOPS */
}
/* SHA-384 functions */
void sha384(const unsigned char *message, unsigned int len,
unsigned char *digest)
{
sha384_ctx ctx;
sha384_init(&ctx);
sha384_update(&ctx, message, len);
sha384_final(&ctx, digest);
}
void sha384_init(sha384_ctx *ctx)
{
#ifndef UNROLL_LOOPS
int i;
for (i = 0; i < 8; i++) {
ctx->h[i] = sha384_h0[i];
}
#else
ctx->h[0] = sha384_h0[0]; ctx->h[1] = sha384_h0[1];
ctx->h[2] = sha384_h0[2]; ctx->h[3] = sha384_h0[3];
ctx->h[4] = sha384_h0[4]; ctx->h[5] = sha384_h0[5];
ctx->h[6] = sha384_h0[6]; ctx->h[7] = sha384_h0[7];
#endif /* !UNROLL_LOOPS */
ctx->len = 0;
ctx->tot_len = 0;
}
void sha384_update(sha384_ctx *ctx, const unsigned char *message,
unsigned int len)
{
unsigned int block_nb;
unsigned int new_len, rem_len, tmp_len;
const unsigned char *shifted_message;
tmp_len = SHA384_BLOCK_SIZE - ctx->len;
rem_len = len < tmp_len ? len : tmp_len;
memcpy(&ctx->block[ctx->len], message, rem_len);
if (ctx->len + len < SHA384_BLOCK_SIZE) {
ctx->len += len;
return;
}
new_len = len - rem_len;
block_nb = new_len / SHA384_BLOCK_SIZE;
shifted_message = message + rem_len;
sha512_transf(ctx, ctx->block, 1);
sha512_transf(ctx, shifted_message, block_nb);
rem_len = new_len % SHA384_BLOCK_SIZE;
memcpy(ctx->block, &shifted_message[block_nb << 7],
rem_len);
ctx->len = rem_len;
ctx->tot_len += (block_nb + 1) << 7;
}
void sha384_final(sha384_ctx *ctx, unsigned char *digest)
{
unsigned int block_nb;
unsigned int pm_len;
unsigned int len_b;
#ifndef UNROLL_LOOPS
int i;
#endif
block_nb = (1 + ((SHA384_BLOCK_SIZE - 17)
< (ctx->len % SHA384_BLOCK_SIZE)));
len_b = (ctx->tot_len + ctx->len) << 3;
pm_len = block_nb << 7;
memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
ctx->block[ctx->len] = 0x80;
UNPACK32(len_b, ctx->block + pm_len - 4);
sha512_transf(ctx, ctx->block, block_nb);
#ifndef UNROLL_LOOPS
for (i = 0 ; i < 6; i++) {
UNPACK64(ctx->h[i], &digest[i << 3]);
}
#else
UNPACK64(ctx->h[0], &digest[ 0]);
UNPACK64(ctx->h[1], &digest[ 8]);
UNPACK64(ctx->h[2], &digest[16]);
UNPACK64(ctx->h[3], &digest[24]);
UNPACK64(ctx->h[4], &digest[32]);
UNPACK64(ctx->h[5], &digest[40]);
#endif /* !UNROLL_LOOPS */
}
/* SHA-224 functions */
void sha224(const unsigned char *message, unsigned int len,
unsigned char *digest)
{
sha224_ctx ctx;
sha224_init(&ctx);
sha224_update(&ctx, message, len);
sha224_final(&ctx, digest);
}
void sha224_init(sha224_ctx *ctx)
{
#ifndef UNROLL_LOOPS
int i;
for (i = 0; i < 8; i++) {
ctx->h[i] = sha224_h0[i];
}
#else
ctx->h[0] = sha224_h0[0]; ctx->h[1] = sha224_h0[1];
ctx->h[2] = sha224_h0[2]; ctx->h[3] = sha224_h0[3];
ctx->h[4] = sha224_h0[4]; ctx->h[5] = sha224_h0[5];
ctx->h[6] = sha224_h0[6]; ctx->h[7] = sha224_h0[7];
#endif /* !UNROLL_LOOPS */
ctx->len = 0;
ctx->tot_len = 0;
}
void sha224_update(sha224_ctx *ctx, const unsigned char *message,
unsigned int len)
{
unsigned int block_nb;
unsigned int new_len, rem_len, tmp_len;
const unsigned char *shifted_message;
tmp_len = SHA224_BLOCK_SIZE - ctx->len;
rem_len = len < tmp_len ? len : tmp_len;
memcpy(&ctx->block[ctx->len], message, rem_len);
if (ctx->len + len < SHA224_BLOCK_SIZE) {
ctx->len += len;
return;
}
new_len = len - rem_len;
block_nb = new_len / SHA224_BLOCK_SIZE;
shifted_message = message + rem_len;
sha256_transf(ctx, ctx->block, 1);
sha256_transf(ctx, shifted_message, block_nb);
rem_len = new_len % SHA224_BLOCK_SIZE;
memcpy(ctx->block, &shifted_message[block_nb << 6],
rem_len);
ctx->len = rem_len;
ctx->tot_len += (block_nb + 1) << 6;
}
void sha224_final(sha224_ctx *ctx, unsigned char *digest)
{
unsigned int block_nb;
unsigned int pm_len;
unsigned int len_b;
#ifndef UNROLL_LOOPS
int i;
#endif
block_nb = (1 + ((SHA224_BLOCK_SIZE - 9)
< (ctx->len % SHA224_BLOCK_SIZE)));
len_b = (ctx->tot_len + ctx->len) << 3;
pm_len = block_nb << 6;
memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
ctx->block[ctx->len] = 0x80;
UNPACK32(len_b, ctx->block + pm_len - 4);
sha256_transf(ctx, ctx->block, block_nb);
#ifndef UNROLL_LOOPS
for (i = 0 ; i < 7; i++) {
UNPACK32(ctx->h[i], &digest[i << 2]);
}
#else
UNPACK32(ctx->h[0], &digest[ 0]);
UNPACK32(ctx->h[1], &digest[ 4]);
UNPACK32(ctx->h[2], &digest[ 8]);
UNPACK32(ctx->h[3], &digest[12]);
UNPACK32(ctx->h[4], &digest[16]);
UNPACK32(ctx->h[5], &digest[20]);
UNPACK32(ctx->h[6], &digest[24]);
#endif /* !UNROLL_LOOPS */
}
#ifdef TEST_VECTORS
/* FIPS 180-2 Validation tests */
#include <stdio.h>
#include <stdlib.h>
void test(const unsigned char *vector, unsigned char *digest,
unsigned int digest_size)
{
unsigned char output[2 * SHA512_DIGEST_SIZE + 1];
int i;
output[2 * digest_size] = '\0';
for (i = 0; i < (int) digest_size ; i++) {
sprintf((char *) output + 2 * i, "%02x", digest[i]);
}
printf("H: %s\n", output);
if (strcmp((char *) vector, (char *) output)) {
fprintf(stderr, "Test failed.\n");
exit(EXIT_FAILURE);
}
}
int main()
{
static const unsigned char *vectors[4][3] =
{ /* SHA-224 */
{
"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7",
"75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525",
"20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67",
},
/* SHA-256 */
{
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0",
},
/* SHA-384 */
{
"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"
"8086072ba1e7cc2358baeca134c825a7",
"09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"
"fcc7c71a557e2db966c3e9fa91746039",
"9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b"
"07b8b3dc38ecc4ebae97ddd87f3d8985",
},
/* SHA-512 */
{
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
"8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
"501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909",
"e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"
"de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"
}
};
static const unsigned char message1[] = "abc";
static const unsigned char message2a[] = "abcdbcdecdefdefgefghfghighijhi"
"jkijkljklmklmnlmnomnopnopq";
static const unsigned char message2b[] =
"abcdefghbcdefghicdefghijdefghijkefghij"
"klfghijklmghijklmnhijklmnoijklmnopjklm"
"nopqklmnopqrlmnopqrsmnopqrstnopqrstu";
unsigned char *message3;
unsigned int message3_len = 1000000;
unsigned char digest[SHA512_DIGEST_SIZE];
message3 = malloc(message3_len);
if (message3 == NULL) {
fprintf(stderr, "Can't allocate memory\n");
return -1;
}
memset(message3, 'a', message3_len);
printf("SHA-2 FIPS 180-2 Validation tests\n\n");
printf("SHA-224 Test vectors\n");
sha224(message1, strlen((char *) message1), digest);
test(vectors[0][0], digest, SHA224_DIGEST_SIZE);
sha224(message2a, strlen((char *) message2a), digest);
test(vectors[0][1], digest, SHA224_DIGEST_SIZE);
sha224(message3, message3_len, digest);
test(vectors[0][2], digest, SHA224_DIGEST_SIZE);
printf("\n");
printf("SHA-256 Test vectors\n");
sha256(message1, strlen((char *) message1), digest);
test(vectors[1][0], digest, SHA256_DIGEST_SIZE);
sha256(message2a, strlen((char *) message2a), digest);
test(vectors[1][1], digest, SHA256_DIGEST_SIZE);
sha256(message3, message3_len, digest);
test(vectors[1][2], digest, SHA256_DIGEST_SIZE);
printf("\n");
printf("SHA-384 Test vectors\n");
sha384(message1, strlen((char *) message1), digest);
test(vectors[2][0], digest, SHA384_DIGEST_SIZE);
sha384(message2b, strlen((char *) message2b), digest);
test(vectors[2][1], digest, SHA384_DIGEST_SIZE);
sha384(message3, message3_len, digest);
test(vectors[2][2], digest, SHA384_DIGEST_SIZE);
printf("\n");
printf("SHA-512 Test vectors\n");
sha512(message1, strlen((char *) message1), digest);
test(vectors[3][0], digest, SHA512_DIGEST_SIZE);
sha512(message2b, strlen((char *) message2b), digest);
test(vectors[3][1], digest, SHA512_DIGEST_SIZE);
sha512(message3, message3_len, digest);
test(vectors[3][2], digest, SHA512_DIGEST_SIZE);
printf("\n");
printf("All tests passed.\n");
return 0;
}
#endif /* TEST_VECTORS */

@ -0,0 +1,108 @@
/*
* FIPS 180-2 SHA-224/256/384/512 implementation
* Last update: 02/02/2007
* Issue date: 04/30/2005
*
* Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef SHA2_H
#define SHA2_H
#define SHA224_DIGEST_SIZE ( 224 / 8)
#define SHA256_DIGEST_SIZE ( 256 / 8)
#define SHA384_DIGEST_SIZE ( 384 / 8)
#define SHA512_DIGEST_SIZE ( 512 / 8)
#define SHA256_BLOCK_SIZE ( 512 / 8)
#define SHA512_BLOCK_SIZE (1024 / 8)
#define SHA384_BLOCK_SIZE SHA512_BLOCK_SIZE
#define SHA224_BLOCK_SIZE SHA256_BLOCK_SIZE
#ifndef SHA2_TYPES
#define SHA2_TYPES
typedef unsigned char uint8;
typedef unsigned int uint32;
typedef unsigned long long uint64;
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
unsigned int tot_len;
unsigned int len;
unsigned char block[2 * SHA256_BLOCK_SIZE];
uint32 h[8];
} sha256_ctx;
typedef struct {
unsigned int tot_len;
unsigned int len;
unsigned char block[2 * SHA512_BLOCK_SIZE];
uint64 h[8];
} sha512_ctx;
typedef sha512_ctx sha384_ctx;
typedef sha256_ctx sha224_ctx;
void sha224_init(sha224_ctx *ctx);
void sha224_update(sha224_ctx *ctx, const unsigned char *message,
unsigned int len);
void sha224_final(sha224_ctx *ctx, unsigned char *digest);
void sha224(const unsigned char *message, unsigned int len,
unsigned char *digest);
void sha256_init(sha256_ctx * ctx);
void sha256_update(sha256_ctx *ctx, const unsigned char *message,
unsigned int len);
void sha256_final(sha256_ctx *ctx, unsigned char *digest);
void sha256(const unsigned char *message, unsigned int len,
unsigned char *digest);
void sha384_init(sha384_ctx *ctx);
void sha384_update(sha384_ctx *ctx, const unsigned char *message,
unsigned int len);
void sha384_final(sha384_ctx *ctx, unsigned char *digest);
void sha384(const unsigned char *message, unsigned int len,
unsigned char *digest);
void sha512_init(sha512_ctx *ctx);
void sha512_update(sha512_ctx *ctx, const unsigned char *message,
unsigned int len);
void sha512_final(sha512_ctx *ctx, unsigned char *digest);
void sha512(const unsigned char *message, unsigned int len,
unsigned char *digest);
#ifdef __cplusplus
}
#endif
#endif /* !SHA2_H */

@ -43,9 +43,9 @@ Locale=it
Syntax=unimarc
[porbase]
Host=z3950.bn.pt
Host=z3950.porbase.org
Port=210
Database=bnd
Database=Default
Name=Portuguese National Library
Charset=iso-8859-1
Locale=pt

@ -175,13 +175,13 @@ void Z3950Fetcher::search(FetchKey key_, const TQString& value_) {
isbnList.insert(it, isbn10);
}
}
const int count = isbnList.count();
const size_t count = isbnList.count();
if(count > 1) {
m_pqn = TQString::fromLatin1("@or ");
}
for(int i = 0; i < count; ++i) {
for(size_t i = 0; i < count; ++i) {
m_pqn += TQString::fromLatin1(" @attr 1=7 ") + isbnList[i];
if(i < count-2) {
if(count > 1 && i < count-2) {
m_pqn += TQString::fromLatin1(" @or");
}
}

@ -591,6 +591,10 @@ void FetchDialog::slotMultipleISBN(bool toggle_) {
m_valueLineEdit->setText(val);
}
m_editISBN->setEnabled(toggle_);
if(toggle_) {
// if we're editing multiple values, it makes sense to popup the dialog now
slotEditMultipleISBN();
}
}
void FetchDialog::slotEditMultipleISBN() {

@ -32,6 +32,7 @@ namespace {
using Tellico::Data::Field;
//these get overwritten, but are here since they're static
TQStringList Field::s_articles;
TQStringList Field::s_articlesApos;
TQRegExp Field::s_delimiter = TQRegExp(TQString::fromLatin1("\\s*;\\s*"));
@ -171,7 +172,7 @@ const TQString& Field::defaultValue() const {
}
void Field::setDefaultValue(const TQString& value_) {
if(m_type != Choice || m_allowed.findIndex(value_) > -1) {
if(value_.isEmpty() || m_type != Choice || m_allowed.findIndex(value_) > -1) {
setProperty(TQString::fromLatin1("default"), value_);
}
}
@ -260,8 +261,7 @@ TQString Field::formatTitle(const TQString& title_) {
if(Config::autoFormat()) {
const TQString lower = newTitle.lower();
// TODO if the title has ",the" at the end, put it at the front
const TQStringList& articles = Config::articleList();
for(TQStringList::ConstIterator it = articles.begin(); it != articles.end(); ++it) {
for(TQStringList::ConstIterator it = s_articles.constBegin(); it != s_articles.constEnd(); ++it) {
// assume white space is already stripped
// the articles are already in lower-case
if(lower.startsWith(*it + TQChar(' '))) {
@ -415,7 +415,7 @@ TQString Field::capitalize(TQString str_) {
TQString word = str_.mid(0, pos);
// now check to see if words starts with apostrophe list
for(TQStringList::ConstIterator it = s_articlesApos.begin(); it != s_articlesApos.end(); ++it) {
for(TQStringList::ConstIterator it = s_articlesApos.constBegin(); it != s_articlesApos.constEnd(); ++it) {
if(word.lower().startsWith(*it)) {
uint l = (*it).length();
str_.replace(l, 1, str_.at(l).upper());
@ -432,7 +432,7 @@ TQString Field::capitalize(TQString str_) {
word = str_.mid(pos+1, nextPos-pos-1);
bool aposMatch = false;
// now check to see if words starts with apostrophe list
for(TQStringList::ConstIterator it = s_articlesApos.begin(); it != s_articlesApos.end(); ++it) {
for(TQStringList::ConstIterator it = s_articlesApos.constBegin(); it != s_articlesApos.constEnd(); ++it) {
if(word.lower().startsWith(*it)) {
uint l = (*it).length();
str_.replace(pos+l+1, 1, str_.at(pos+l+1).upper());
@ -455,8 +455,7 @@ TQString Field::capitalize(TQString str_) {
TQString Field::sortKeyTitle(const TQString& title_) {
const TQString lower = title_.lower();
const TQStringList& articles = Config::articleList();
for(TQStringList::ConstIterator it = articles.begin(); it != articles.end(); ++it) {
for(TQStringList::ConstIterator it = s_articles.constBegin(); it != s_articles.constEnd(); ++it) {
// assume white space is already stripped
// the articles are already in lower-case
if(lower.startsWith(*it + TQChar(' '))) {
@ -464,7 +463,7 @@ TQString Field::sortKeyTitle(const TQString& title_) {
}
}
// check apostrophes, too
for(TQStringList::ConstIterator it = s_articlesApos.begin(); it != s_articlesApos.end(); ++it) {
for(TQStringList::ConstIterator it = s_articlesApos.constBegin(); it != s_articlesApos.constEnd(); ++it) {
if(lower.startsWith(*it)) {
return title_.mid((*it).length());
}
@ -474,9 +473,9 @@ TQString Field::sortKeyTitle(const TQString& title_) {
// articles should all be in lower-case
void Field::articlesUpdated() {
const TQStringList articles = Config::articleList();
s_articles = Config::articleList();
s_articlesApos.clear();
for(TQStringList::ConstIterator it = articles.begin(); it != articles.end(); ++it) {
for(TQStringList::ConstIterator it = s_articles.constBegin(); it != s_articles.constEnd(); ++it) {
if((*it).endsWith(TQChar('\''))) {
s_articlesApos += (*it);
}
@ -581,11 +580,10 @@ long Field::getID() {
}
void Field::stripArticles(TQString& value) {
const TQStringList articles = Config::articleList();
if(articles.isEmpty()) {
if(s_articles.isEmpty()) {
return;
}
for(TQStringList::ConstIterator it = articles.begin(); it != articles.end(); ++it) {
for(TQStringList::ConstIterator it = s_articles.constBegin(); it != s_articles.constEnd(); ++it) {
TQRegExp rx(TQString::fromLatin1("\\b") + *it + TQString::fromLatin1("\\b"));
value.remove(rx);
}

@ -385,6 +385,7 @@ private:
FormatFlag m_formatFlag;
StringMap m_properties;
static TQStringList s_articles;
// need to remember articles with apostrophes for capitalization
static TQStringList s_articlesApos;
static TQRegExp s_delimiter;

@ -39,8 +39,8 @@ public:
int column, int width, int align);
virtual int width(const TQFontMetrics& fm, const TQListView* lv, int c) const;
virtual int count() const { return childCount(); }
virtual int realChildCount() const { return count(); }
virtual size_t count() const { return childCount(); }
virtual size_t realChildCount() const { return count(); }
};
} // end namespace

@ -139,7 +139,7 @@ public:
ListViewItem(ListViewItem* parent, const TQString& text) : TDEListViewItem(parent, text), m_sortWeight(-1) {}
virtual ~ListViewItem();
virtual int realChildCount() const { return childCount(); }
virtual size_t realChildCount() const { return childCount(); }
virtual void clear();
virtual bool isEntryGroupItem() const { return false; }

@ -29,6 +29,9 @@ TQTabBar* TabControl::tabBar() const {
void TabControl::setFocusToFirstChild() {
TQWidget* page = currentPage();
Q_ASSERT(page);
if(!page) {
return;
}
TQObjectList* list = page->queryList(TQWIDGET_OBJECT_NAME_STRING);
for(TQObjectListIt it(*list); it.current(); ++it) {
TQWidget* w = TQT_TQWIDGET(it.current());

@ -14,6 +14,7 @@
#include "image.h"
#include "imagefactory.h"
#include "tellico_debug.h"
#include "tellico_utils.h"
#include <kmdcodec.h>
#include <kpixmapio.h>
@ -105,7 +106,7 @@ TQByteArray Image::byteArray(const TQImage& img_, const TQCString& outputFormat_
TQString Image::idClean(const TQString& id_) {
static const TQRegExp rx('[' + TQRegExp::escape(TQString::fromLatin1("/@<>#\"&%?={}|^~[]'`\\:+")) + ']');
TQString clean = id_;
return clean.remove(rx);
return shareString(clean.remove(rx));
}
void Image::setID(const TQString& id_) {

@ -316,7 +316,7 @@ bool ImageFactory::writeCachedImage(const TQString& id_, CacheDir dir_, bool for
const Tellico::Data::Image& ImageFactory::imageById(const TQString& id_) {
if(id_.isEmpty()) {
myDebug() << "ImageFactory::imageById() - empty id" << endl;
// myDebug() << "ImageFactory::imageById() - empty id" << endl;
return s_null;
}
// myLog() << "ImageFactory::imageById() - " << id_ << endl;
@ -348,7 +348,7 @@ const Tellico::Data::Image& ImageFactory::imageById(const TQString& id_) {
if((s_imageInfoMap.contains(id_) && s_imageInfoMap[id_].linkOnly) || !KURL::isRelativeURL(id_)) {
KURL u = id_;
if(u.isValid()) {
return addImageImpl(u, false, KURL(), true);
return addImageImpl(u, true, KURL(), true);
}
}
@ -385,43 +385,53 @@ const Tellico::Data::Image& ImageFactory::imageById(const TQString& id_) {
}
}
// 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 = TQFile::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) {
if(Config::imageLocation() == Config::ImagesInLocalDir) {
bool exists = TQFile::exists(localDir() + id_);
if(exists) {
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 local dir" << endl;
return img2;
}
}
// not an else statement, it might be null
if(TQFile::exists(dataDir() + id_)) {
// the img is in the other location
// consider the document to be modified since it needs the image saved
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;
}
}
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;
} else if(Config::imageLocation() == Config::ImagesInAppDir) {
bool exists = TQFile::exists(dataDir() + id_);
if(exists) {
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 = TQFile::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) {
// not an else statement, it might be null
if(TQFile::exists(localDir() + id_)) {
// the img is in the other location
// consider the document to be modified since it needs the image saved
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;
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 local dir" << endl;
return img2;
}
}
}
myDebug() << "***ImageFactory::imageById() - not found: " << id_ << endl;

@ -12,6 +12,7 @@
***************************************************************************/
#include "isbnvalidator.h"
#include "upcvalidator.h"
#include "tellico_debug.h"
using Tellico::ISBNValidator;
@ -58,6 +59,13 @@ ISBNValidator::ISBNValidator(TQObject* parent_, const char* name_/*=0*/)
}
TQValidator::State ISBNValidator::validate(TQString& input_, int& pos_) const {
// check if it's a cuecat first
State catState = CueCat::decode(input_);
if(catState != Invalid) {
pos_ = input_.length();
return catState;
}
if(input_.startsWith(TQString::fromLatin1("978")) ||
input_.startsWith(TQString::fromLatin1("979"))) {
return validate13(input_, pos_);

@ -65,7 +65,7 @@ TQString LCCNValidator::formalize(const TQString& value_) {
// now check for non digits in the serial
pos = 0;
for( ; pos < serial.length() && serial.at(pos).isNumber(); ++pos) { ; }
for( ; pos < static_cast<int>(serial.length()) && serial.at(pos).isNumber(); ++pos) { ; }
TQString suffix = serial.mid(pos);
serial = serial.left(pos);
// serial must be left-padded with zeros to 6 characters

@ -48,6 +48,8 @@ Tellico::ListViewComparison* Tellico::ListViewComparison::create(Data::ConstFiel
return new DependentComparison(field_);
} else if(field_->type() == Data::Field::Date || field_->formatFlag() == Data::Field::FormatDate) {
return new ISODateComparison(field_);
} else if(field_->type() == Data::Field::Choice) {
return new ChoiceComparison(field_);
} else if(field_->formatFlag() == Data::Field::FormatTitle) {
// Dependent could be title, so put this test after
return new TitleComparison(field_);
@ -277,3 +279,11 @@ int Tellico::ISODateComparison::compare(const TQString& str1, const TQString& st
}
return 0;
}
Tellico::ChoiceComparison::ChoiceComparison(Data::ConstFieldPtr field) : ListViewComparison(field) {
m_values = field->allowed();
}
int Tellico::ChoiceComparison::compare(const TQString& str1, const TQString& str2) {
return m_values.findIndex(str1) - m_values.findIndex(str2);
}

@ -112,5 +112,16 @@ protected:
virtual int compare(const TQString& str1, const TQString& str2);
};
class ChoiceComparison : public ListViewComparison {
public:
ChoiceComparison(Data::ConstFieldPtr field);
protected:
virtual int compare(const TQString& str1, const TQString& str2);
private:
TQStringList m_values;
};
}
#endif

@ -336,7 +336,7 @@ void MainWindow::initActions() {
action = new TDEAction(actionCollection(), "file_import_csv");
action->setText(i18n("Import CSV Data..."));
action->setToolTip(i18n("Import a CSV file"));
action->setIcon(MIME_ICON("text/x-csv"));
action->setIcon(MIME_ICON("text/csv"));
importMenu->insert(action);
connect(action, TQT_SIGNAL(activated()), importMapper, TQT_SLOT(map()));
importMapper->setMapping(action, Import::CSV);
@ -506,7 +506,7 @@ void MainWindow::initActions() {
action = new TDEAction(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"));
action->setIcon(MIME_ICON("text/csv"));
exportMenu->insert(action);
connect(action, TQT_SIGNAL(activated()), exportMapper, TQT_SLOT(map()));
exportMapper->setMapping(action, Export::CSV);
@ -750,6 +750,7 @@ void MainWindow::initActions() {
// want to update every time the filter text changes
connect(m_quickFilter, TQT_SIGNAL(textChanged(const TQString&)),
TQT_TQOBJECT(this), TQT_SLOT(slotQueueFilter()));
m_quickFilter->installEventFilter(this); // intercept keyEvents
KWidgetAction* wAction = new KWidgetAction(m_quickFilter, i18n("Filter"), 0, 0, 0,
actionCollection(), "quick_filter");
@ -907,12 +908,12 @@ void MainWindow::saveOptions() {
Config::setGroupViewSortAscending(m_groupView->ascendingSort());
if(m_loanView) {
Config::setLoanViewSortAscending(m_loanView->sortStyle()); // ok to use SortColumn key, save semantics
Config::setLoanViewSortColumn(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::setFilterViewSortColumn(m_filterView->sortStyle()); // ok to use SortColumn key, save semantics
Config::setFilterViewSortAscending(m_filterView->ascendingSort());
}
@ -991,7 +992,7 @@ void MainWindow::saveCollectionOptions(Data::CollPtr coll_) {
configIndex = i;
}
}
uint limit = TQMIN(urls.count(), Config::maxCustomURLSettings());
size_t limit = TQMIN(urls.count(), Config::maxCustomURLSettings());
for(uint i = 0; i < limit; ++i) {
config.writeEntry(TQString::fromLatin1("URL_%1").arg(i), urls[i].url());
config.writeEntry(TQString::fromLatin1("Group By_%1").arg(i), groupBys[i]);
@ -1531,11 +1532,11 @@ void MainWindow::slotEntryCount() {
return;
}
int count = coll->entryCount();
size_t count = coll->entryCount();
TQString text = i18n("Total entries: %1").arg(count);
int selectCount = Controller::self()->selectedEntries().count();
int filterCount = m_detailedView->visibleItems();
size_t selectCount = Controller::self()->selectedEntries().count();
size_t filterCount = m_detailedView->visibleItems();
// if more than one book is selected, add the number of selected books
if(filterCount < count && selectCount > 1) {
text += TQChar(' ');
@ -1847,6 +1848,10 @@ void MainWindow::setFilter(const TQString& text_) {
} else {
// if it isn't valid, hold off on applying the filter
TQRegExp tx(text);
if(!tx.isValid()) {
text = TQRegExp::escape(text);
tx.setPattern(text);
}
if(!tx.isValid()) {
myDebug() << "MainWindow::slotUpdateFilter() - invalid regexp: " << text << endl;
return;
@ -2389,4 +2394,15 @@ void MainWindow::slotURLAction(const KURL& url_) {
}
}
bool MainWindow::eventFilter(TQObject* obj_, TQEvent* ev_) {
if(ev_->type() == TQEvent::KeyPress && obj_ == m_quickFilter) {
switch(static_cast<TQKeyEvent*>(ev_)->key()) {
case TQt::Key_Escape:
m_quickFilter->clear();
return true;
}
}
return false;
}
#include "mainwindow.moc"

@ -123,6 +123,8 @@ public:
virtual void setFilter(const TQString& text);
virtual bool showEntry(long id);
bool eventFilter(TQObject* watched, TQEvent* event);
public slots:
/**
* Initializes some stuff after the object is created.

@ -197,7 +197,7 @@ void ReportDialog::slotSaveAs() {
if(!u.isEmpty() && u.isValid()) {
TDEConfigGroup config(TDEGlobal::config(), "ExportOptions");
bool encode = config.readBoolEntry("EncodeUTF8", true);
int oldOpt = m_exporter->options();
long oldOpt = m_exporter->options();
// turn utf8 off
long options = oldOpt & ~Export::ExportUTF8;

@ -22,7 +22,7 @@
// std::clock_t
#include <ctime>
// linux has __GNUC_PREREQ, NetBSD has __GNUC_PREQ__
// linux has __GNUC_PREREQ, NetBSD has __GNUC_PREREQ__
#if defined(__GNUC_PREREQ) && !defined(__GNUC_PREREQ__)
#define __GNUC_PREREQ__ __GNUC_PREREQ
#endif

@ -16,7 +16,7 @@ METASOURCES = AUTO
DISTCLEANFILES = *~ *.Po $(CLEANFILES)
isbntest_SOURCES = isbntest.cpp
isbntest_LDADD = ../isbnvalidator.o $(LIB_QT) $(LIB_TDECORE) $(LIB_TDEUI)
isbntest_LDADD = ../isbnvalidator.o ../upcvalidator.o $(LIB_QT) $(LIB_TDECORE) $(LIB_TDEUI)
latin1test_SOURCES = latin1test.cpp
latin1test_LDADD = $(LIB_QT) $(LIB_TDECORE)

@ -12,9 +12,9 @@ libtranslators_a_SOURCES = alexandriaexporter.cpp alexandriaimporter.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
risimporter.cpp tellico_xml.cpp tellicoimporter.cpp tellicosaximporter.cpp \
tellicoxmlexporter.cpp tellicoxmlhandler.cpp tellicozipexporter.cpp textimporter.cpp \
xmlimporter.cpp xmlstatehandler.cpp xsltexporter.cpp xslthandler.cpp xsltimporter.cpp
if !USE_LIBBTPARSE
SUBDIR_LIBBTPARSE = btparse
@ -51,7 +51,10 @@ 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
deliciousimporter.h deliciousimporter.cpp \
tellicosaximporter.h tellicosaximporter.cpp \
tellicoxmlhandler.h tellicoxmlhandler.cpp \
xmlstatehandler.h xmlstatehandler.cpp
####### tdevelop will overwrite this part!!! (end)############
@ -68,3 +71,4 @@ KDE_OPTIONS = noautodist
appdir = $(kde_datadir)/tellico
app_DATA = bibtex-translation.xml
app_SCRIPTS = griffith2tellico.py

@ -77,7 +77,7 @@ bool AlexandriaExporter::exec() {
ProgressItem& item = ProgressManager::self()->newProgressItem(this, TQString(), false);
item.setTotalSteps(entries().count());
ProgressItem::Done done(this);
const uint stepSize = TQMIN(1, entries().count()/100);
const uint stepSize = TQMAX(1, entries().count()/100);
const bool showProgress = options() & ExportProgress;
GUI::CursorSaver cs;

@ -308,5 +308,47 @@ TQWidget* BibtexImporter::widget(TQWidget* parent_, const char* name_/*=0*/) {
return m_widget;
}
bool BibtexImporter::maybeBibtex(const KURL& url_) {
TQString text = FileHandler::readTextFile(url_, true /*quiet*/);
if(text.isEmpty()) {
return false;
}
bt_initialize();
TQRegExp rx(TQString::fromLatin1("[{}]"));
ushort bt_options = 0; // ushort is defined in btparse.h
boolean ok; // boolean is defined in btparse.h as an int
bool foundOne = false;
int brace = 0;
int startpos = 0;
int pos = text.find(rx, 0);
while(pos > 0) {
if(text[pos] == '{') {
++brace;
} else if(text[pos] == '}' && brace > 0) {
--brace;
}
if(brace == 0) {
TQString 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) {
foundOne = true;
break;
}
startpos = pos+1;
}
pos = text.find(rx, pos+1);
}
if(foundOne) {
// clean up some structures
bt_parse_entry_s(0, 0, 1, 0, 0);
}
bt_cleanup();
return foundOne;
}
#include "bibteximporter.moc"

@ -67,6 +67,8 @@ public:
virtual TQWidget* widget(TQWidget* parent, const char* name=0);
virtual bool canImport(int type) const;
static bool maybeBibtex(const KURL& url);
public slots:
void slotCancel();

@ -50,15 +50,26 @@ extern "C" {
using Tellico::Import::CSVImporter;
typedef int(*SpaceFunc)(char);
static void writeToken(char* buffer, size_t len, void* data);
static void writeRow(char buffer, void* data);
static int isSpace(char c);
static int isSpaceOrTab(char c);
static int isTab(char c);
class CSVImporter::Parser {
public:
Parser(const TQString& str) : stream(new TQTextIStream(&str)) { csv_init(&parser, 0); }
~Parser() { csv_free(parser); delete stream; stream = 0; }
void setDelimiter(const TQString& s) { Q_ASSERT(s.length() == 1); csv_set_delim(parser, s[0].latin1()); }
void setDelimiter(const TQString& s) {
Q_ASSERT(s.length() == 1);
csv_set_delim(parser, s[0].latin1());
if(s[0] == '\t') csv_set_space_func(parser, isSpace);
else if(s[0] == ' ') csv_set_space_func(parser, isTab);
else csv_set_space_func(parser, isSpaceOrTab);
}
void reset(const TQString& str) { delete stream; stream = new TQTextIStream(&str); };
bool hasNext() { return !stream->atEnd(); }
void skipLine() { stream->readLine(); }
@ -95,6 +106,21 @@ static void writeRow(char c, void* data) {
p->setRowDone(true);
}
static int isSpace(char c) {
if (c == CSV_SPACE) return 1;
return 0;
}
static int isSpaceOrTab(char c) {
if (c == CSV_SPACE || c == CSV_TAB) return 1;
return 0;
}
static int isTab(char c) {
if (c == CSV_TAB) return 1;
return 0;
}
CSVImporter::CSVImporter(const KURL& url_) : Tellico::Import::TextImporter(url_),
m_coll(0),
m_existingCollection(0),

@ -35,7 +35,9 @@ DeliciousImporter::DeliciousImporter(const KURL& url_) : XSLTImporter(url_) {
}
bool DeliciousImporter::canImport(int type) const {
return type == Data::Collection::Book;
return type == Data::Collection::Book ||
type == Data::Collection::Video ||
type == Data::Collection::Game;
}
Tellico::Data::CollPtr DeliciousImporter::collection() {
@ -51,7 +53,18 @@ Tellico::Data::CollPtr DeliciousImporter::collection() {
<< TQString::fromLatin1("Medium Covers/")
<< TQString::fromLatin1("Small Covers/")
<< TQString::fromLatin1("Plain Covers/");
const TQString commField = TQString::fromLatin1("comments");
TQString commField;
switch(coll->type()) {
case Data::Collection::Book:
commField = TQString::fromLatin1("comments"); break;
case Data::Collection::Video:
commField = TQString::fromLatin1("plot"); break;
case Data::Collection::Game:
commField = TQString::fromLatin1("description"); break;
default:
myWarning() << "bad collection type:" << coll->type() << endl;
}
const TQString uuidField = TQString::fromLatin1("uuid");
const TQString coverField = TQString::fromLatin1("cover");
const bool isLocal = url().isLocalFile();

@ -365,7 +365,7 @@ FreeDBImporter::CDText FreeDBImporter::getCDText(const TQCString& drive_) {
}
}
if(cdtext.trackTitles.size() != cdtext.trackArtists.size()) {
int size = TQMAX(cdtext.trackTitles.size(), cdtext.trackArtists.size());
size_t size = TQMAX(cdtext.trackTitles.size(), cdtext.trackArtists.size());
cdtext.trackTitles.resize(size);
cdtext.trackArtists.resize(size);
}

@ -31,6 +31,7 @@
#include <tdeio/netaccess.h>
#include <tdeapplication.h>
#include <tdelocale.h>
#include <kuser.h>
#include <tqdom.h>
#include <tqgroupbox.h>
@ -192,6 +193,9 @@ bool HTMLExporter::loadXSLTFile() {
m_handler = 0;
return false;
}
m_handler->addStringParam("date", TQDate::currentDate().toString(TQt::ISODate).latin1());
m_handler->addStringParam("time", TQTime::currentTime().toString(TQt::ISODate).latin1());
m_handler->addStringParam("user", KUser(KUser::UseRealUserID).loginName().latin1());
if(m_exportEntryFiles) {
// export entries to same place as all the other date files

@ -188,7 +188,7 @@ void RISImporter::readURL(const KURL& url_, int n, const TQDict<Data::Field>& ri
// 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
// also be gracious and allow any amount of space before hyphen
TQRegExp rx(TQString::fromLatin1("^(\\w\\w)\\s+-(.*)$"));
TQString currLine, nextLine;
for(currLine = t.readLine(); !m_cancelled && !currLine.isNull(); currLine = nextLine, j += currLine.length()) {
@ -312,4 +312,25 @@ void RISImporter::slotCancel() {
m_cancelled = true;
}
bool RISImporter::maybeRIS(const KURL& url_) {
TQString text = FileHandler::readTextFile(url_, true /*quiet*/);
if(text.isEmpty()) {
return false;
}
// bare bones check, strip white space at beginning
// and then first text line must be valid RIS
TQTextIStream t(&text);
TQRegExp rx(TQString::fromLatin1("^(\\w\\w)\\s+-(.*)$"));
TQString currLine;
for(currLine = t.readLine(); !currLine.isNull(); currLine = t.readLine()) {
if(currLine.stripWhiteSpace().isEmpty()) {
continue;
}
break;
}
return rx.exactMatch(currLine);
}
#include "risimporter.moc"

@ -50,6 +50,8 @@ public:
virtual TQWidget* widget(TQWidget*, const char*) { return 0; }
virtual bool canImport(int type) const;
static bool maybeRIS(const KURL& url);
public slots:
void slotCancel();

@ -63,6 +63,12 @@ TQString Tellico::XML::dtdTellico(int version) {
return TQString::fromLatin1("http://periapsis.org/tellico/dtd/v%1/tellico.dtd").arg(version);
}
// returns true if the file has to be converted
// version 9 to 10 requires no conversion since it only added board games
bool Tellico::XML::versionConversion(uint from, uint to) {
return from < to && (from != 9 || to != 10);
}
bool Tellico::XML::validXMLElementName(const TQString& name_) {
return xmlValidateNameValue((xmlChar *)name_.utf8().data());
}

@ -28,6 +28,8 @@ namespace Tellico {
TQString pubTellico(int version = syntaxVersion);
TQString dtdTellico(int version = syntaxVersion);
bool versionConversion(uint from, uint to);
extern const TQString nsBookcase;
extern const TQString nsDublinCore;
extern const TQString nsZing;

@ -39,11 +39,6 @@
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) {
@ -157,7 +152,7 @@ void TellicoImporter::loadXMLData(const TQByteArray& data_, bool loadImages_) {
}
m_format = Error;
return;
} else if(versionConversion(syntaxVersion, XML::syntaxVersion)) {
} else if(XML::versionConversion(syntaxVersion, XML::syntaxVersion)) {
// going form version 9 to 10, there's no conversion needed
TQString 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 "
@ -374,7 +369,7 @@ void TellicoImporter::readField(uint syntaxVersion_, const TQDomElement& elem_)
Data::FieldPtr field;
if(type == Data::Field::Choice) {
TQStringList allowed = TQStringList::split(TQString::fromLatin1(";"),
TQStringList allowed = TQStringList::split(TQRegExp(TQString::fromLatin1("\\s*;\\s*")),
elem_.attribute(TQString::fromLatin1("allowed")));
if(isI18n) {
for(TQStringList::Iterator it = allowed.begin(); it != allowed.end(); ++it) {
@ -652,8 +647,9 @@ void TellicoImporter::readEntry(uint syntaxVersion_, const TQDomElement& entryEl
void TellicoImporter::readImage(const TQDomElement& elem_, bool loadImage_) {
TQString format = elem_.attribute(TQString::fromLatin1("format"));
const bool link = elem_.attribute(TQString::fromLatin1("link")) == Latin1Literal("true");
TQString id = shareString(link ? elem_.attribute(TQString::fromLatin1("id"))
: Data::Image::idClean(elem_.attribute(TQString::fromLatin1("id"))));
// idClean() already calls shareString()
TQString id = link ? shareString(elem_.attribute(TQString::fromLatin1("id")))
: Data::Image::idClean(elem_.attribute(TQString::fromLatin1("id")));
bool readInfo = true;
if(loadImage_) {

@ -70,8 +70,6 @@ public slots:
void slotCancel();
private:
static bool versionConversion(uint from, uint to);
void loadXMLData(const TQByteArray& data, bool loadImages);
void loadZipData();

@ -0,0 +1,293 @@
/***************************************************************************
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; *
* *
***************************************************************************/
// before tellicosaxmporter.h because of QT_NO_CAST_ASCII issues
#include "tellicoxmlhandler.h"
#include "tellicosaximporter.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 <tdelocale.h>
#include <kmdcodec.h>
#include <kzip.h>
#include <tdeapplication.h>
#include <tqbuffer.h>
#include <tqfile.h>
#include <tqtimer.h>
using Tellico::Import::TellicoSaxImporter;
TellicoSaxImporter::TellicoSaxImporter(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) {
}
TellicoSaxImporter::TellicoSaxImporter(const TQString& 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) {
}
TellicoSaxImporter::~TellicoSaxImporter() {
if(m_zip) {
m_zip->close();
}
delete m_zip;
m_zip = 0;
delete m_buffer;
m_buffer = 0;
}
Tellico::Data::CollPtr TellicoSaxImporter::collection() {
if(m_coll) {
return m_coll;
}
TQCString s; // read first 5 characters
if(source() == URL) {
if(!fileRef().open()) {
return 0;
}
TQIODevice* 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 = TQCString(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 TellicoSaxImporter::loadXMLData(const TQByteArray& data_, bool loadImages_) {
ProgressItem& item = ProgressManager::self()->newProgressItem(this, progressLabel(), true);
item.setTotalSteps(data_.size());
connect(&item, SIGNAL(signalCancelled(ProgressItem*)), SLOT(slotCancel()));
ProgressItem::Done done(this);
const bool showProgress = options() & ImportProgress;
TellicoXMLHandler handler;
handler.setLoadImages(loadImages_);
TQXmlSimpleReader reader;
reader.setContentHandler(&handler);
TQXmlInputSource source;
bool success = reader.parse(&source, true);
const uint blockSize = data_.size()/100 + 1;
uint pos = 0;
TQByteArray block;
while(success && !m_cancelled && pos < data_.size()) {
uint size = TQMIN(blockSize, data_.size() - pos);
block.setRawData(data_.data() + pos, size);
source.setData(block);
success = reader.parseContinue();
block.resetRawData(data_.data() + pos, size);
pos += blockSize;
if(showProgress) {
ProgressManager::self()->setProgress(this, pos);
kapp->processEvents();
}
}
if(!success) {
m_format = Error;
TQString error;
if(!url().isEmpty()) {
error = i18n(errorLoad).arg(url().fileName()) + TQChar('\n');
}
error += handler.errorString();
myDebug() << error << endl;
setStatusMessage(error);
return;
}
if(!m_cancelled) {
m_hasImages = handler.hasImages();
m_coll = handler.collection();
}
}
void TellicoSaxImporter::loadZipData() {
delete m_buffer;
delete m_zip;
if(source() == URL) {
m_buffer = 0;
m_zip = new KZip(fileRef().fileName());
} else {
m_buffer = new TQBuffer(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) {
TQString str = i18n(errorLoad).arg(url().fileName()) + TQChar('\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(TQString::fromLatin1("tellico.xml"));
if(!entry) {
entry = dir->entry(TQString::fromLatin1("bookcase.xml"));
}
if(!entry || !entry->isFile()) {
TQString str = i18n(errorLoad).arg(url().fileName()) + TQChar('\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 TQByteArray 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(TQString::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() << "TellicoSaxImporter::loadZipData() - delayed loading for " << m_images.count() << " images" << endl;
return;
}
const TQStringList images = static_cast<const KArchiveDirectory*>(imgDirEntry)->entries();
const uint stepSize = TQMAX(s_stepSize, images.count()/100);
uint j = 0;
for(TQStringList::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
TQTimer::singleShot(3000, this, SLOT(deleteLater()));
}
}
bool TellicoSaxImporter::hasImages() const {
return m_hasImages;
}
bool TellicoSaxImporter::loadImage(const TQString& id_) {
// myLog() << "TellicoSaxImporter::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;
}
TQString 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
TQTimer::singleShot(3000, this, SLOT(deleteLater()));
}
return !newID.isEmpty();
}
void TellicoSaxImporter::slotCancel() {
m_cancelled = true;
m_format = Cancel;
}
#include "tellicosaximporter.moc"

@ -0,0 +1,87 @@
/***************************************************************************
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_IMPORT_TELLICOSAXIMPORTER_H
#define TELLICO_IMPORT_TELLICOSAXIMPORTER_H
#include "dataimporter.h"
#include "../datavectors.h"
#include "../stringset.h"
class TQBuffer;
class KZip;
class KArchiveDirectory;
namespace Tellico {
namespace Import {
/**
* @author Robby Stephenson
*/
class TellicoSaxImporter : public DataImporter {
Q_OBJECT
public:
enum Format { Unknown, Error, XML, Zip, Cancel };
/**
* @param url The tellico data file.
*/
TellicoSaxImporter(const KURL& url, bool loadAllImages=true);
/**
* Constructor used to convert arbitrary text to a @ref Collection
*
* @param text The text
*/
TellicoSaxImporter(const TQString& text);
virtual ~TellicoSaxImporter();
/**
* 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;
bool loadImage(const TQString& id_);
static bool loadAllImages(const KURL& url);
public slots:
void slotCancel();
private:
void loadXMLData(const TQByteArray& data, bool loadImages);
void loadZipData();
Data::CollPtr m_coll;
bool m_loadAllImages;
TQString m_namespace;
Format m_format;
bool m_modified : 1;
bool m_cancelled : 1;
bool m_hasImages : 1;
StringSet m_images;
TQBuffer* m_buffer;
KZip* m_zip;
const KArchiveDirectory* m_imgDir;
};
} // end namespace
} // end namespace
#endif

@ -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 "tellicoxmlhandler.h"
#include "../collection.h"
#include "../tellico_debug.h"
using Tellico::Import::TellicoXMLHandler;
TellicoXMLHandler::TellicoXMLHandler() : TQXmlDefaultHandler(), m_data(new SAX::StateData) {
m_handlers.setAutoDelete(true);
m_handlers.push(new SAX::RootHandler(m_data));
}
TellicoXMLHandler::~TellicoXMLHandler() {
delete m_data;
m_data = 0;
}
bool TellicoXMLHandler::startElement(const TQString& nsURI_, const TQString& localName_,
const TQString& qName_, const TQXmlAttributes& atts_) {
SAX::StateHandler* handler = m_handlers.top()->nextHandler(nsURI_, localName_, qName_);
Q_ASSERT(handler);
m_handlers.push(handler);
return handler->start(nsURI_, localName_, qName_, atts_);
}
bool TellicoXMLHandler::endElement(const TQString& nsURI_, const TQString& localName_,
const TQString& qName_) {
m_data->text = m_data->text.stripWhiteSpace();
/*
if(!m_data->text.isEmpty()) {
myDebug() << " text: " << m_text << endl;
}
*/
SAX::StateHandler* handler = m_handlers.pop();
bool res = handler->end(nsURI_, localName_, qName_);
// need to reset character data, too
m_data->text = TQString();
delete handler;
return res;
}
bool TellicoXMLHandler::characters(const TQString& ch_) {
m_data->text += ch_;
return true;
}
TQString TellicoXMLHandler::errorString() {
return m_data->error;
}
Tellico::Data::CollPtr TellicoXMLHandler::collection() const {
return m_data->coll;
}
bool TellicoXMLHandler::hasImages() const {
return m_data->hasImages;
}
void TellicoXMLHandler::setLoadImages(bool loadImages_) {
m_data->loadImages = loadImages_;
}

@ -0,0 +1,49 @@
/***************************************************************************
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_IMPORT_TELLICOXMLHANDLER_H
#define TELLICO_IMPORT_TELLICOXMLHANDLER_H
#include "xmlstatehandler.h"
#include <tqptrstack.h>
namespace Tellico {
namespace Import {
class TellicoXMLHandler : public TQXmlDefaultHandler {
public:
TellicoXMLHandler();
~TellicoXMLHandler();
virtual bool startElement(const TQString& namespaceURI, const TQString& localName,
const TQString& qName, const TQXmlAttributes& atts);
virtual bool endElement(const TQString& namespaceURI, const TQString& localName,
const TQString& qName);
virtual bool characters(const TQString& ch);
virtual TQString errorString();
Data::CollPtr collection() const;
bool hasImages() const;
void setLoadImages(bool loadImages);
private:
TQPtrStack<SAX::StateHandler> m_handlers;
SAX::StateData* m_data;
};
}
}
#endif

@ -0,0 +1,772 @@
/***************************************************************************
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 "xmlstatehandler.h"
#include "tellico_xml.h"
#include "../latin1literal.h"
#include "../collection.h"
#include "../collectionfactory.h"
#include "../collections/bibtexcollection.h"
#include "../image.h"
#include "../imagefactory.h"
#include "../isbnvalidator.h"
#include "../tellico_utils.h"
#include "../tellico_debug.h"
#include <tdelocale.h>
#include <kmdcodec.h>
namespace {
inline
TQString attValue(const TQXmlAttributes& atts, const char* name, const TQString& defaultValue=TQString()) {
int idx = atts.index(TQString::fromLatin1(name));
return idx < 0 ? defaultValue : atts.value(idx);
}
inline
TQString attValue(const TQXmlAttributes& atts, const char* name, const char* defaultValue) {
Q_ASSERT(defaultValue);
return attValue(atts, name, TQString::fromLatin1(defaultValue));
}
}
using Tellico::Import::SAX::StateHandler;
using Tellico::Import::SAX::NullHandler;
using Tellico::Import::SAX::RootHandler;
using Tellico::Import::SAX::DocumentHandler;
using Tellico::Import::SAX::CollectionHandler;
using Tellico::Import::SAX::FieldsHandler;
using Tellico::Import::SAX::FieldHandler;
using Tellico::Import::SAX::FieldPropertyHandler;
using Tellico::Import::SAX::BibtexPreambleHandler;
using Tellico::Import::SAX::BibtexMacrosHandler;
using Tellico::Import::SAX::BibtexMacroHandler;
using Tellico::Import::SAX::EntryHandler;
using Tellico::Import::SAX::FieldValueContainerHandler;
using Tellico::Import::SAX::FieldValueHandler;
using Tellico::Import::SAX::DateValueHandler;
using Tellico::Import::SAX::TableColumnHandler;
using Tellico::Import::SAX::ImagesHandler;
using Tellico::Import::SAX::ImageHandler;
using Tellico::Import::SAX::FiltersHandler;
using Tellico::Import::SAX::FilterHandler;
using Tellico::Import::SAX::FilterRuleHandler;
using Tellico::Import::SAX::BorrowersHandler;
using Tellico::Import::SAX::BorrowerHandler;
using Tellico::Import::SAX::LoanHandler;
StateHandler* StateHandler::nextHandler(const TQString& ns_, const TQString& localName_, const TQString& qName_) {
StateHandler* handler = nextHandlerImpl(ns_, localName_, qName_);
if(!handler) {
myWarning() << "StateHandler::nextHandler() - no handler for " << localName_ << endl;
}
return handler ? handler : new NullHandler(d);
}
StateHandler* RootHandler::nextHandlerImpl(const TQString&, const TQString& localName_, const TQString&) {
if(localName_ == Latin1Literal("tellico") || localName_ == Latin1Literal("bookcase")) {
return new DocumentHandler(d);
}
return new RootHandler(d);
}
StateHandler* DocumentHandler::nextHandlerImpl(const TQString&, const TQString& localName_, const TQString&) {
if(localName_ == Latin1Literal("collection")) {
return new CollectionHandler(d);
} else if(localName_ == Latin1Literal("filters")) {
return new FiltersHandler(d);
} else if(localName_ == Latin1Literal("borrowers")) {
return new BorrowersHandler(d);
}
return 0;
}
bool DocumentHandler::start(const TQString&, const TQString& localName_, const TQString&, const TQXmlAttributes& atts_) {
// the syntax version field name changed from "version" to "syntaxVersion" in version 3
int idx = atts_.index(TQString::fromLatin1("syntaxVersion"));
if(idx < 0) {
idx = atts_.index(TQString::fromLatin1("version"));
}
if(idx < 0) {
myWarning() << "RootHandler::start() - no syntax version" << endl;
return false;
}
d->syntaxVersion = atts_.value(idx).toUInt();
if(d->syntaxVersion > Tellico::XML::syntaxVersion) {
d->error = i18n("It is from a future version of Tellico.");
return false;
} else if(Tellico::XML::versionConversion(d->syntaxVersion, Tellico::XML::syntaxVersion)) {
// going from version 9 to 10, there's no conversion needed
TQString 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;
}
if((d->syntaxVersion > 6 && localName_ != Latin1Literal("tellico")) ||
(d->syntaxVersion < 7 && localName_ != Latin1Literal("bookcase"))) {
// no error message
myWarning() << "RootHandler::start() - bad root element name" << endl;
return false;
}
d->ns = d->syntaxVersion > 6 ? Tellico::XML::nsTellico : Tellico::XML::nsBookcase;
return true;
}
bool DocumentHandler::end(const TQString&, const TQString&, const TQString&) {
return true;
}
StateHandler* CollectionHandler::nextHandlerImpl(const TQString&, const TQString& localName_, const TQString&) {
if((d->syntaxVersion > 3 && localName_ == Latin1Literal("fields")) ||
(d->syntaxVersion < 4 && localName_ == Latin1Literal("attributes"))) {
return new FieldsHandler(d);
} else if(localName_ == Latin1Literal("bibtex-preamble")) {
return new BibtexPreambleHandler(d);
} else if(localName_ == Latin1Literal("macros")) {
return new BibtexMacrosHandler(d);
} else if(localName_ == d->entryName) {
return new EntryHandler(d);
} else if(localName_ == Latin1Literal("images")) {
return new ImagesHandler(d);
}
return 0;
}
bool CollectionHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes& atts_) {
d->collTitle = attValue(atts_, "title");
d->collType = attValue(atts_, "type").toInt();
d->entryName = attValue(atts_, "unit");
Q_ASSERT(d->collType);
return true;
}
bool CollectionHandler::end(const TQString&, const TQString&, const TQString&) {
d->coll->addEntries(d->entries);
// a little hidden capability was to just have a local path as an image file name
// and on reading the xml file, Tellico would load the image file, too
// here, we need to scan all the image values in all the entries and check
// maybe this is too costly, especially since the capability wasn't advertised?
Data::FieldVec fields = d->coll->imageFields();
for(Data::EntryVecIt entry = d->entries.begin(); entry != d->entries.end(); ++entry) {
for(Data::FieldVecIt field = fields.begin(); field != fields.end(); ++field) {
TQString value = entry->field(field, false);
// 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()) {
TQString result = ImageFactory::addImage(u, false /* quiet */);
if(!result.isEmpty()) {
value = result;
}
}
value = Data::Image::idClean(value);
entry->setField(field->name(), value);
}
}
}
return true;
}
StateHandler* FieldsHandler::nextHandlerImpl(const TQString&, const TQString& localName_, const TQString&) {
if((d->syntaxVersion > 3 && localName_ == Latin1Literal("field")) ||
(d->syntaxVersion < 4 && localName_ == Latin1Literal("attribute"))) {
return new FieldHandler(d);
}
return 0;
}
bool FieldsHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&) {
d->defaultFields = false;
return true;
}
bool FieldsHandler::end(const TQString&, const TQString&, const TQString&) {
// add default fields if there was a default field name, or no names at all
const bool addFields = d->defaultFields || d->fields.isEmpty();
// in syntax 4, the element name was changed to "entry", always, rather than depending on
// on the entryName of the collection.
if(d->syntaxVersion > 3) {
d->entryName = TQString::fromLatin1("entry");
Data::Collection::Type type = static_cast<Data::Collection::Type>(d->collType);
d->coll = CollectionFactory::collection(type, addFields);
} else {
d->coll = CollectionFactory::collection(d->entryName, addFields);
}
if(!d->collTitle.isEmpty()) {
d->coll->setTitle(d->collTitle);
}
d->coll->addFields(d->fields);
// as a special case, for old book collections with a bibtex-id field, convert to Bibtex
if(d->syntaxVersion < 4 && d->collType == Data::Collection::Book
&& d->coll->hasField(TQString::fromLatin1("bibtex-id"))) {
d->coll = Data::BibtexCollection::convertBookCollection(d->coll);
}
return true;
}
StateHandler* FieldHandler::nextHandlerImpl(const TQString&, const TQString& localName_, const TQString&) {
if(localName_ == Latin1Literal("prop")) {
return new FieldPropertyHandler(d);
}
return 0;
}
bool FieldHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes& atts_) {
// special case: if the i18n attribute equals true, then translate the title, description, and category
const bool isI18n = attValue(atts_, "i18n") == Latin1Literal("true");
TQString name = attValue(atts_, "name", "unknown");
if(name == Latin1Literal("_default")) {
d->defaultFields = true;
return true;
}
TQString title = attValue(atts_, "title", i18n("Unknown"));
if(isI18n) {
title = i18n(title.utf8());
}
TQString typeStr = attValue(atts_, "type", TQString::number(Data::Field::Line));
Data::Field::Type type = static_cast<Data::Field::Type>(typeStr.toInt());
Data::FieldPtr field;
if(type == Data::Field::Choice) {
TQStringList allowed = TQStringList::split(TQRegExp(TQString::fromLatin1("\\s*;\\s*")),
attValue(atts_, "allowed"));
if(isI18n) {
for(TQStringList::Iterator word = allowed.begin(); word != allowed.end(); ++word) {
(*word) = i18n((*word).utf8());
}
}
field = new Data::Field(name, title, allowed);
} else {
field = new Data::Field(name, title, type);
}
int idx = atts_.index(TQString::fromLatin1("category"));
if(idx > -1) {
// at one point, the categories had keyboard accels
TQString cat = atts_.value(idx);
if(d->syntaxVersion < 9 && cat.find('&') > -1) {
cat.remove('&');
}
if(isI18n) {
cat = i18n(cat.utf8());
}
field->setCategory(cat);
}
idx = atts_.index(TQString::fromLatin1("flags"));
if(idx > -1) {
int flags = atts_.value(idx).toInt();
// I also changed the enum values for syntax 3, but the only custom field
// would have been bibtex-id
if(d->syntaxVersion < 3 && 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(d->syntaxVersion < 4 && name == Latin1Literal("title")) {
flags |= Data::Field::NoDelete;
}
field->setFlags(flags);
}
TQString formatStr = attValue(atts_, "format", TQString::number(Data::Field::FormatNone));
Data::Field::FormatFlag format = static_cast<Data::Field::FormatFlag>(formatStr.toInt());
field->setFormatFlag(format);
idx = atts_.index(TQString::fromLatin1("description"));
if(idx > -1) {
TQString desc = atts_.value(idx);
if(isI18n) {
desc = i18n(desc.utf8());
}
field->setDescription(desc);
}
if(d->syntaxVersion < 5 && atts_.index(TQString::fromLatin1("bibtex-field")) > -1) {
field->setProperty(TQString::fromLatin1("bibtex"), attValue(atts_, "bibtex-field"));
}
// Table2 is deprecated
if(type == Data::Field::Table2) {
field->setType(Data::Field::Table);
field->setProperty(TQString::fromLatin1("columns"), TQChar('2'));
}
// for syntax 8, rating fields got their own type
if(d->syntaxVersion < 8) {
Data::Field::convertOldRating(field); // does all its own checking
}
d->fields.append(field);
return true;
}
bool FieldHandler::end(const TQString&, const TQString&, const TQString&) {
return true;
}
bool FieldPropertyHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes& atts_) {
// there should be at least one field already so we can add properties to it
Q_ASSERT(!d->fields.isEmpty());
Data::FieldPtr field = d->fields.back();
m_propertyName = attValue(atts_, "name");
// all track fields in music collections prior to version 9 get converted to three columns
if(d->syntaxVersion < 9) {
if(d->collType == Data::Collection::Album && field->name() == Latin1Literal("track")) {
field->setProperty(TQString::fromLatin1("columns"), TQChar('3'));
field->setProperty(TQString::fromLatin1("column1"), i18n("Title"));
field->setProperty(TQString::fromLatin1("column2"), i18n("Artist"));
field->setProperty(TQString::fromLatin1("column3"), i18n("Length"));
} else if(d->collType == Data::Collection::Video && field->name() == Latin1Literal("cast")) {
field->setProperty(TQString::fromLatin1("column1"), i18n("Actor/Actress"));
field->setProperty(TQString::fromLatin1("column2"), i18n("Role"));
}
}
return true;
}
bool FieldPropertyHandler::end(const TQString&, const TQString&, const TQString&) {
Q_ASSERT(!m_propertyName.isEmpty());
// add the previous property
Data::FieldPtr field = d->fields.back();
field->setProperty(m_propertyName, d->text);
return true;
}
bool BibtexPreambleHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&) {
return true;
}
bool BibtexPreambleHandler::end(const TQString&, const TQString&, const TQString&) {
Q_ASSERT(d->coll);
if(d->coll && d->collType == Data::Collection::Bibtex && !d->text.isEmpty()) {
Data::BibtexCollection* c = static_cast<Data::BibtexCollection*>(d->coll.data());
c->setPreamble(d->text);
}
return true;
}
StateHandler* BibtexMacrosHandler::nextHandlerImpl(const TQString&, const TQString& localName_, const TQString&) {
if(localName_ == Latin1Literal("macro")) {
return new BibtexMacroHandler(d);
}
return 0;
}
bool BibtexMacrosHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&) {
return true;
}
bool BibtexMacrosHandler::end(const TQString&, const TQString&, const TQString&) {
return true;
}
bool BibtexMacroHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes& atts_) {
m_macroName = attValue(atts_, "name");
return true;
}
bool BibtexMacroHandler::end(const TQString&, const TQString&, const TQString&) {
if(d->coll && d->collType == Data::Collection::Bibtex && !m_macroName.isEmpty() && !d->text.isEmpty()) {
Data::BibtexCollection* c = static_cast<Data::BibtexCollection*>(d->coll.data());
c->addMacro(m_macroName, d->text);
}
return true;
}
StateHandler* EntryHandler::nextHandlerImpl(const TQString&, const TQString& localName_, const TQString&) {
if(d->coll->hasField(localName_)) {
return new FieldValueHandler(d);
}
return new FieldValueContainerHandler(d);
}
bool EntryHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes& atts_) {
// the entries must come after the fields
if(!d->coll || d->coll->fields().isEmpty()) {
myWarning() << "EntryHandler::start() - entries must come after fields are defined" << endl;
// TODO: i18n
d->error = TQString::fromLatin1("File format error: entries must come after fields are defined");
return false;
}
int id = attValue(atts_, "id").toInt();
Data::EntryPtr entry;
if(id > 0) {
entry = new Data::Entry(d->coll, id);
} else {
entry = new Data::Entry(d->coll);
}
d->entries.append(entry);
return true;
}
bool EntryHandler::end(const TQString&, const TQString&, const TQString&) {
return true;
}
StateHandler* FieldValueContainerHandler::nextHandlerImpl(const TQString&, const TQString& localName_, const TQString&) {
if(d->coll->hasField(localName_)) {
return new FieldValueHandler(d);
}
return new FieldValueContainerHandler(d);
}
bool FieldValueContainerHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&) {
return true;
}
bool FieldValueContainerHandler::end(const TQString&, const TQString&, const TQString&) {
return true;
}
StateHandler* FieldValueHandler::nextHandlerImpl(const TQString&, const TQString& localName_, const TQString&) {
if(localName_ == Latin1Literal("year") ||
localName_ == Latin1Literal("month") ||
localName_ == Latin1Literal("day")) {
return new DateValueHandler(d);
} else if(localName_ == Latin1Literal("column")) {
return new TableColumnHandler(d);
}
return 0;
}
bool FieldValueHandler::start(const TQString&, const TQString&, const TQString& localName_, const TQXmlAttributes& atts_) {
d->currentField = d->coll->fieldByName(localName_);
m_i18n = attValue(atts_, "i18n") == Latin1Literal("true");
m_validateISBN = attValue(atts_, "validate") != Latin1Literal("no");
return true;
}
bool FieldValueHandler::end(const TQString&, const TQString& localName_, const TQString&) {
Data::FieldPtr f = d->coll->fieldByName(localName_);
if(!f) {
myWarning() << "FieldValueHandler::end() - no field named " << localName_ << endl;
return true;
}
// if it's a derived value, no field value is added
if(f->type() == Data::Field::Dependent) {
return true;
}
Data::EntryPtr entry = d->entries.back();
Q_ASSERT(entry);
TQString fieldName = localName_;
TQString fieldValue = d->text;
if(d->syntaxVersion < 2 && fieldName == Latin1Literal("keywords")) {
// in version 2, "keywords" changed to "keyword"
fieldName = TQString::fromLatin1("keyword");
} else if(d->syntaxVersion < 4 && f->type() == Data::Field::Bool) {
// in version 3 and prior, checkbox attributes had no text(), set it to "true"
fieldValue = TQString::fromLatin1("true");
} else if(d->syntaxVersion < 8 && f->type() == Data::Field::Rating) {
// in version 8, old rating fields get changed
bool ok;
uint i = Tellico::toUInt(fieldValue, &ok);
if(ok) {
fieldValue = TQString::number(i);
}
} else if(!d->textBuffer.isEmpty()) {
// for dates and tables, the value is built up from child elements
#ifndef NDEBUG
if(!d->text.isEmpty()) {
myWarning() << "FieldValueHandler::end() - ignoring value for field " << localName_ << ": " << d->text << endl;
}
#endif
fieldValue = d->textBuffer;
d->textBuffer = TQString();
}
// this is not an else branch, the data may be in the textBuffer
if(d->syntaxVersion < 9 && d->coll->type() == Data::Collection::Album && fieldName == Latin1Literal("track")) {
// yes, this assumes the artist has already been set
fieldValue += TQString::fromLatin1("::");
fieldValue += entry->field(TQString::fromLatin1("artist"));
}
// special case: if the i18n attribute equals true, then translate the title, description, and category
if(m_i18n) {
fieldValue = i18n(fieldValue.utf8());
}
// special case for isbn fields, go ahead and validate
if(m_validateISBN && fieldName == Latin1Literal("isbn")) {
ISBNValidator val(0);
val.fixup(fieldValue);
}
if(fieldValue.isEmpty()) {
return true;
}
// for fields with multiple values, we need to add on the new value
TQString oldValue = entry->field(fieldName);
if(!oldValue.isEmpty()) {
fieldValue = oldValue + TQString::fromLatin1("; ") + fieldValue;
}
entry->setField(fieldName, fieldValue);
return true;
}
bool DateValueHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&) {
return true;
}
bool DateValueHandler::end(const TQString&, const TQString& localName_, const TQString&) {
// the data value is y-m-d even if there are no date values
if(d->textBuffer.isEmpty()) {
d->textBuffer = TQString::fromLatin1("--");
}
TQStringList tokens = TQStringList::split('-', d->textBuffer, true /* allow empty */);
Q_ASSERT(tokens.size() == 3);
if(localName_ == Latin1Literal("year")) {
tokens[0] = d->text;
} else if(localName_ == Latin1Literal("month")) {
tokens[1] = d->text;
} else if(localName_ == Latin1Literal("day")) {
tokens[2] = d->text;
}
d->textBuffer = tokens.join(TQChar('-'));
return true;
}
bool TableColumnHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&) {
return true;
}
bool TableColumnHandler::end(const TQString&, const TQString&, const TQString&) {
// for old collections, if the second column holds the track length, bump it to next column
if(d->syntaxVersion < 9 &&
d->coll->type() == Data::Collection::Album &&
d->currentField->name() == Latin1Literal("track") &&
!d->textBuffer.isEmpty() &&
d->textBuffer.contains(TQString::fromLatin1("::")) == 0) {
TQRegExp rx(TQString::fromLatin1("\\d+:\\d\\d"));
if(rx.exactMatch(d->text)) {
d->text += TQString::fromLatin1("::");
d->text += d->entries.back()->field(TQString::fromLatin1("artist"));
}
}
if(!d->textBuffer.isEmpty()) {
d->textBuffer += TQString::fromLatin1("::");
}
d->textBuffer += d->text;
return true;
}
StateHandler* ImagesHandler::nextHandlerImpl(const TQString&, const TQString& localName_, const TQString&) {
if(localName_ == Latin1Literal("image")) {
return new ImageHandler(d);
}
return 0;
}
bool ImagesHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&) {
// reset variable that gets updated in the image handler
d->hasImages = false;
return true;
}
bool ImagesHandler::end(const TQString&, const TQString&, const TQString&) {
return true;
}
bool ImageHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes& atts_) {
m_format = attValue(atts_, "format");
m_link = attValue(atts_, "link") == Latin1Literal("true");
// idClean() already calls shareString()
m_imageId = m_link ? shareString(attValue(atts_, "id"))
: Data::Image::idClean(attValue(atts_, "id"));
m_width = attValue(atts_, "width").toInt();
m_height = attValue(atts_, "height").toInt();
return true;
}
bool ImageHandler::end(const TQString&, const TQString&, const TQString&) {
bool readInfo = true;
if(d->loadImages) {
TQByteArray ba;
KCodecs::base64Decode(TQCString(d->text.latin1()), ba);
if(!ba.isEmpty()) {
TQString result = ImageFactory::addImage(ba, m_format, m_imageId);
if(result.isEmpty()) {
myDebug() << "TellicoImporter::readImage(XML) - null image for " << m_imageId << endl;
}
d->hasImages = true;
readInfo = false;
}
}
if(readInfo) {
// a width or height of 0 is ok here
Data::ImageInfo info(m_imageId, m_format.latin1(), m_width, m_height, m_link);
ImageFactory::cacheImageInfo(info);
}
return true;
}
StateHandler* FiltersHandler::nextHandlerImpl(const TQString&, const TQString& localName_, const TQString&) {
if(localName_ == Latin1Literal("filter")) {
return new FilterHandler(d);
}
return 0;
}
bool FiltersHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&) {
return true;
}
bool FiltersHandler::end(const TQString&, const TQString&, const TQString&) {
return true;
}
StateHandler* FilterHandler::nextHandlerImpl(const TQString&, const TQString& localName_, const TQString&) {
if(localName_ == Latin1Literal("rule")) {
return new FilterRuleHandler(d);
}
return 0;
}
bool FilterHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes& atts_) {
d->filter = new Filter(Filter::MatchAny);
d->filter->setName(attValue(atts_, "name"));
if(attValue(atts_, "match") == Latin1Literal("all")) {
d->filter->setMatch(Filter::MatchAll);
}
return true;
}
bool FilterHandler::end(const TQString&, const TQString&, const TQString&) {
if(d->coll && !d->filter->isEmpty()) {
d->coll->addFilter(d->filter);
}
d->filter = FilterPtr();
return true;
}
bool FilterRuleHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes& atts_) {
TQString field = attValue(atts_, "field");
// empty field means match any of them
TQString pattern = attValue(atts_, "pattern");
// empty pattern is bad
if(pattern.isEmpty()) {
myWarning() << "FilterRuleHandler::start() - empty rule!" << endl;
return true;
}
TQString function = attValue(atts_, "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 {
myWarning() << "FilterRuleHandler::start() - invalid rule function: " << function << endl;
return true;
}
d->filter->append(new FilterRule(field, pattern, func));
return true;
}
bool FilterRuleHandler::end(const TQString&, const TQString&, const TQString&) {
return true;
}
StateHandler* BorrowersHandler::nextHandlerImpl(const TQString&, const TQString& localName_, const TQString&) {
if(localName_ == Latin1Literal("borrower")) {
return new BorrowerHandler(d);
}
return 0;
}
bool BorrowersHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&) {
return true;
}
bool BorrowersHandler::end(const TQString&, const TQString&, const TQString&) {
return true;
}
StateHandler* BorrowerHandler::nextHandlerImpl(const TQString&, const TQString& localName_, const TQString&) {
if(localName_ == Latin1Literal("loan")) {
return new LoanHandler(d);
}
return 0;
}
bool BorrowerHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes& atts_) {
TQString name = attValue(atts_, "name");
TQString uid = attValue(atts_, "uid");
d->borrower = new Data::Borrower(name, uid);
return true;
}
bool BorrowerHandler::end(const TQString&, const TQString&, const TQString&) {
if(d->coll && !d->borrower->isEmpty()) {
d->coll->addBorrower(d->borrower);
}
d->borrower = Data::BorrowerPtr();
return true;
}
bool LoanHandler::start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes& atts_) {
m_id = attValue(atts_, "entryRef").toInt();
m_uid = attValue(atts_, "uid");
m_loanDate = attValue(atts_, "loanDate");
m_dueDate = attValue(atts_, "dueDate");
m_inCalendar = attValue(atts_, "calendar") == Latin1Literal("true");
return true;
}
bool LoanHandler::end(const TQString&, const TQString&, const TQString&) {
Data::EntryPtr entry = d->coll->entryById(m_id);
if(!entry) {
myWarning() << "LoanHandler::end() - no entry with id = " << m_id << endl;
return true;
}
TQDate loanDate, dueDate;
if(!m_loanDate.isEmpty()) {
loanDate = TQDate::fromString(m_loanDate, TQt::ISODate);
}
if(!m_dueDate.isEmpty()) {
dueDate = TQDate::fromString(m_dueDate, TQt::ISODate);
}
Data::LoanPtr loan = new Data::Loan(entry, loanDate, dueDate, d->text);
loan->setUID(m_uid);
loan->setInCalendar(m_inCalendar);
d->borrower->addLoan(loan);
return true;
}

@ -0,0 +1,345 @@
/***************************************************************************
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_IMPORT_XMLSTATEHANDLER_H
#define TELLICO_IMPORT_XMLSTATEHANDLER_H
#ifdef QT_NO_CAST_ASCII
#define HAD_QT_NO_CAST_ASCII
#undef QT_NO_CAST_ASCII
#endif
#include <tqxml.h>
#ifdef HAD_QT_NO_CAST_ASCII
#define QT_NO_CAST_ASCII
#undef HAD_QT_NO_CAST_ASCII
#endif
#include "../datavectors.h"
namespace Tellico {
namespace Import {
namespace SAX {
class StateData {
public:
TQString text;
TQString error;
TQString ns; // namespace
TQString textBuffer;
uint syntaxVersion;
TQString collTitle;
int collType;
TQString entryName;
Data::CollPtr coll;
Data::FieldVec fields;
Data::FieldPtr currentField;
Data::EntryVec entries;
FilterPtr filter;
Data::BorrowerPtr borrower;
bool defaultFields;
bool loadImages;
bool hasImages;
};
class StateHandler {
public:
StateHandler(StateData* data) : d(data) {}
virtual ~StateHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&) = 0;
virtual bool end(const TQString&, const TQString&, const TQString&) = 0;
StateHandler* nextHandler(const TQString&, const TQString&, const TQString&);
protected:
StateData* d;
private:
virtual StateHandler* nextHandlerImpl(const TQString&, const TQString&, const TQString&) { return 0; }
};
class NullHandler : public StateHandler {
public:
NullHandler(StateData* data) : StateHandler(data) {}
virtual ~NullHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&) { return true; }
virtual bool end(const TQString&, const TQString&, const TQString&) { return true; }
};
class RootHandler : public StateHandler {
public:
RootHandler(StateData* data) : StateHandler(data) {}
virtual ~RootHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&) { return true; }
virtual bool end(const TQString&, const TQString&, const TQString&) { return true; }
private:
virtual StateHandler* nextHandlerImpl(const TQString&, const TQString&, const TQString&);
};
class DocumentHandler : public StateHandler {
public:
DocumentHandler(StateData* data) : StateHandler(data) {}
virtual ~DocumentHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
virtual StateHandler* nextHandlerImpl(const TQString&, const TQString&, const TQString&);
};
class CollectionHandler : public StateHandler {
public:
CollectionHandler(StateData* data) : StateHandler(data) {}
virtual ~CollectionHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
virtual StateHandler* nextHandlerImpl(const TQString&, const TQString&, const TQString&);
};
class FieldsHandler : public StateHandler {
public:
FieldsHandler(StateData* data) : StateHandler(data) {}
virtual ~FieldsHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
virtual StateHandler* nextHandlerImpl(const TQString&, const TQString&, const TQString&);
};
class FieldHandler : public StateHandler {
public:
FieldHandler(StateData* data) : StateHandler(data) {}
virtual ~FieldHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
virtual StateHandler* nextHandlerImpl(const TQString&, const TQString&, const TQString&);
};
class FieldPropertyHandler : public StateHandler {
public:
FieldPropertyHandler(StateData* data) : StateHandler(data) {}
virtual ~FieldPropertyHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
TQString m_propertyName;
};
class BibtexPreambleHandler : public StateHandler {
public:
BibtexPreambleHandler(StateData* data) : StateHandler(data) {}
virtual ~BibtexPreambleHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
};
class BibtexMacrosHandler : public StateHandler {
public:
BibtexMacrosHandler(StateData* data) : StateHandler(data) {}
virtual ~BibtexMacrosHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
virtual StateHandler* nextHandlerImpl(const TQString&, const TQString&, const TQString&);
};
class BibtexMacroHandler : public StateHandler {
public:
BibtexMacroHandler(StateData* data) : StateHandler(data) {}
virtual ~BibtexMacroHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
TQString m_macroName;
};
class EntryHandler : public StateHandler {
public:
EntryHandler(StateData* data) : StateHandler(data) {}
virtual ~EntryHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
virtual StateHandler* nextHandlerImpl(const TQString&, const TQString&, const TQString&);
};
class FieldValueContainerHandler : public StateHandler {
public:
FieldValueContainerHandler(StateData* data) : StateHandler(data) {}
virtual ~FieldValueContainerHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
virtual StateHandler* nextHandlerImpl(const TQString&, const TQString&, const TQString&);
};
class FieldValueHandler : public StateHandler {
public:
FieldValueHandler(StateData* data) : StateHandler(data) {}
virtual ~FieldValueHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
virtual StateHandler* nextHandlerImpl(const TQString&, const TQString&, const TQString&);
bool m_i18n;
bool m_validateISBN;
};
class DateValueHandler : public StateHandler {
public:
DateValueHandler(StateData* data) : StateHandler(data) {}
virtual ~DateValueHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
};
class TableColumnHandler : public StateHandler {
public:
TableColumnHandler(StateData* data) : StateHandler(data) {}
virtual ~TableColumnHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
};
class ImagesHandler : public StateHandler {
public:
ImagesHandler(StateData* data) : StateHandler(data) {}
virtual ~ImagesHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
virtual StateHandler* nextHandlerImpl(const TQString&, const TQString&, const TQString&);
};
class ImageHandler : public StateHandler {
public:
ImageHandler(StateData* data) : StateHandler(data) {}
virtual ~ImageHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
TQString m_format;
bool m_link;
TQString m_imageId;
int m_width;
int m_height;
};
class FiltersHandler : public StateHandler {
public:
FiltersHandler(StateData* data) : StateHandler(data) {}
virtual ~FiltersHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
virtual StateHandler* nextHandlerImpl(const TQString&, const TQString&, const TQString&);
};
class FilterHandler : public StateHandler {
public:
FilterHandler(StateData* data) : StateHandler(data) {}
virtual ~FilterHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
virtual StateHandler* nextHandlerImpl(const TQString&, const TQString&, const TQString&);
};
class FilterRuleHandler : public StateHandler {
public:
FilterRuleHandler(StateData* data) : StateHandler(data) {}
virtual ~FilterRuleHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
};
class BorrowersHandler : public StateHandler {
public:
BorrowersHandler(StateData* data) : StateHandler(data) {}
virtual ~BorrowersHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
virtual StateHandler* nextHandlerImpl(const TQString&, const TQString&, const TQString&);
};
class BorrowerHandler : public StateHandler {
public:
BorrowerHandler(StateData* data) : StateHandler(data) {}
virtual ~BorrowerHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
virtual StateHandler* nextHandlerImpl(const TQString&, const TQString&, const TQString&);
};
class LoanHandler : public StateHandler {
public:
LoanHandler(StateData* data) : StateHandler(data) {}
virtual ~LoanHandler() {}
virtual bool start(const TQString&, const TQString&, const TQString&, const TQXmlAttributes&);
virtual bool end(const TQString&, const TQString&, const TQString&);
private:
int m_id;
TQString m_uid;
TQString m_loanDate;
TQString m_dueDate;
bool m_inCalendar;
};
}
}
}
#endif

@ -18,6 +18,8 @@
#include <tdelocale.h>
#include <kurlrequester.h>
#include <kuser.h>
#include <tdeconfig.h>
#include <tqlabel.h>
#include <tqgroupbox.h>
@ -49,6 +51,9 @@ bool XSLTExporter::exec() {
}
// XSLTHandler handler(FileHandler::readXMLFile(url));
XSLTHandler handler(u);
handler.addStringParam("date", TQDate::currentDate().toString(TQt::ISODate).latin1());
handler.addStringParam("time", TQTime::currentTime().toString(TQt::ISODate).latin1());
handler.addStringParam("user", KUser(KUser::UseRealUserID).loginName().latin1());
TellicoXMLExporter exporter;
exporter.setEntries(entries());
@ -75,6 +80,25 @@ TQWidget* XSLTExporter::widget(TQWidget* parent_, const char* name_/*=0*/) {
m_URLRequester = new KURLRequester(box);
TQWhatsThis::add(m_URLRequester, i18n("Choose the XSLT file used to transform the Tellico XML data."));
TQString filter = i18n("*.xsl|XSL Files (*.xsl)") + TQChar('\n');
filter += i18n("*|All Files");
m_URLRequester->setFilter(filter);
m_URLRequester->setMode(static_cast<KFile::Mode>(KFile::File | KFile::ExistingOnly));
if(!m_xsltFile.isEmpty()) {
m_URLRequester->setURL(m_xsltFile);
}
l->addStretch(1);
return m_widget;
}
void XSLTExporter::readOptions(TDEConfig* config_) {
TDEConfigGroup group(config_, TQString::fromLatin1("ExportOptions - %1").arg(formatString()));
m_xsltFile = group.readEntry("Last File", TQString());
}
void XSLTExporter::saveOptions(TDEConfig* config_) {
TDEConfigGroup group(config_, TQString::fromLatin1("ExportOptions - %1").arg(formatString()));
m_xsltFile = m_URLRequester->url();
group.writeEntry("Last File", m_xsltFile);
}

@ -34,9 +34,13 @@ public:
virtual TQWidget* widget(TQWidget* parent, const char* name=0);
virtual void readOptions(TDEConfig* cfg);
virtual void saveOptions(TDEConfig* cfg);
private:
TQWidget* m_widget;
KURLRequester* m_URLRequester;
TQString m_xsltFile;
};
} // end namespace

@ -13,6 +13,7 @@
#include "upcvalidator.h"
#include "isbnvalidator.h"
#include "tellico_debug.h"
#include <kmdcodec.h>
@ -24,7 +25,7 @@ UPCValidator::UPCValidator(TQObject* parent_, const char* name_/*=0*/)
TQValidator::State UPCValidator::validate(TQString& input_, int& pos_) const {
// check if it's a cuecat first
State catState = decodeCat(input_);
State catState = CueCat::decode(input_);
if(catState == Acceptable) {
pos_ = input_.length();
return catState;
@ -91,18 +92,18 @@ void UPCValidator::fixup(TQString& input_) const {
}
}
TQValidator::State UPCValidator::decodeCat(TQString& input_) const {
TQValidator::State Tellico::CueCat::decode(TQString& input_) {
if(input_.length() < 3) {
return Intermediate;
return TQValidator::Intermediate;
}
if(!input_.startsWith(TQString::fromLatin1(".C3"))) { // all cuecat codes start with .C3
return Invalid;
return TQValidator::Invalid;
}
const int periods = input_.contains('.');
if(periods < 4) {
return Intermediate; // not enough yet
return TQValidator::Intermediate; // not enough yet
} else if(periods > 4) {
return Invalid;
return TQValidator::Invalid;
}
// ok, let's have a go, take the third token
@ -127,7 +128,7 @@ TQValidator::State UPCValidator::decodeCat(TQString& input_) const {
}
input_ = code;
return Acceptable;
return TQValidator::Acceptable;
}
#include "upcvalidator.moc"

@ -37,11 +37,14 @@ signals:
void signalISBN();
private:
State decodeCat(TQString& str) const;
bool m_checkISBN : 1;
mutable bool m_isbn : 1;
};
class CueCat {
public:
static TQValidator::State decode(TQString& str);
};
} // end namespace
#endif

@ -53,6 +53,9 @@
<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="10">
<collection title="Amazon Import">
@ -71,6 +74,9 @@
<xsl:when test="$mode='VideoGames'">
<xsl:text>11</xsl:text>
</xsl:when>
<xsl:when test="$mode='Toys'">
<xsl:text>13</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:attribute>
<fields>
@ -81,9 +87,19 @@
<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>
<!-- results for board games need to be filtered -->
<xsl:if test="$mode != 'Toys'">
<xsl:for-each select="//aws:Items/aws:Item">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:if>
<xsl:if test="$mode = 'Toys'">
<!-- only grab items in the board games category -->
<xsl:for-each select="//aws:Items/aws:Item[.//aws:BrowseNode/aws:Name='Board Games' or
.//aws:BrowseNode/aws:BrowseNodeId='166225011']">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:if>
</collection>
</tellico>
</xsl:template>
@ -496,6 +512,27 @@
</xsl:choose>
</certification>
</xsl:when>
<xsl:when test="$mode='Toys'">
<publishers>
<publisher>
<xsl:value-of select="(aws:Label|aws:Brand|aws:Publisher|aws:Manufacturer)[1]"/>
</publisher>
</publishers>
<description>
<xsl:value-of select="../aws:EditorialReviews/aws:EditorialReview[1]/aws:Content"/>
<xsl:for-each select="aws:Feature">
<xsl:value-of select="."/>
<!-- if the last character is not punctuation, add a period -->
<xsl:if test="not(contains('.!?,/', substring(., string-length(.))))">
<xsl:text>.</xsl:text>
</xsl:if>
<xsl:text> </xsl:text>
</xsl:for-each>
</description>
</xsl:when>
</xsl:choose>
</xsl:template>

@ -42,6 +42,10 @@
</tellico>
</xsl:template>
<!-- ignore unresolved queries -->
<xsl:template match="cr:query[@status='unresolved']">
</xsl:template>
<xsl:template match="cr:query">
<entry>

@ -21,17 +21,41 @@
doctype-public="-//Robby Stephenson/DTD Tellico V10.0//EN"
doctype-system="http://periapsis.org/tellico/dtd/v10/tellico.dtd"/>
<xsl:param name="item-type"/>
<xsl:template match="/">
<tc:tellico syntaxVersion="10">
<tc:collection title="Delicious Library Import" type="2">
<!-- DL libraries can contain mixed types and right now, there's no way to do that in Tellico -->
<!-- so we're going to limit the export to whatever the type of the first item is -->
<xsl:variable name="item">
<xsl:choose>
<xsl:when test="string-length($item-type) &gt; 0">
<xsl:value-of select="$item-type"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="local-name(library/items/child::*[1])"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:comment><xsl:text>Choosing all items of type </xsl:text><xsl:value-of select="$item"/></xsl:comment>
<xsl:variable name="type">
<xsl:choose>
<xsl:when test="$item='book'">2</xsl:when>
<xsl:when test="$item='movie'">3</xsl:when>
<xsl:when test="$item='game'">11</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<tc:collection title="Delicious Library Import">
<xsl:attribute name="type"><xsl:value-of select="$type"/></xsl:attribute>
<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>
<xsl:apply-templates select="library/items/child::*[local-name()=$item]"/>
</tc:collection>
</tc:tellico>
</xsl:template>
@ -56,7 +80,7 @@
<xsl:otherwise>
<xsl:value-of select="@title"/>
</xsl:otherwise>
</xsl:choose>
</xsl:choose>
</tc:title>
<tc:subtitle>
@ -116,7 +140,7 @@
<tc:rating>
<!-- tellico automatically rounds down -->
<xsl:value-of select="netrating"/>
<xsl:value-of select="@netrating"/>
</tc:rating>
<xsl:call-template name="split">
@ -132,6 +156,219 @@
</tc:entry>
</xsl:template>
<xsl:template match="movie">
<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:call-template name="strip-title">
<xsl:with-param name="title" select="@title"/>
</xsl:call-template>
</tc:title>
<tc:medium>
<xsl:value-of select="@aspect"/>
</tc:medium>
<xsl:call-template name="split">
<xsl:with-param name="name" select="'tc:director'"/>
<xsl:with-param name="value" select="@director"/>
</xsl:call-template>
<xsl:call-template name="split">
<xsl:with-param name="name" select="'tc:cast'"/>
<xsl:with-param name="value" select="@stars"/>
</xsl:call-template>
<xsl:if test="contains(@features, 'Widescreen')">
<tc:widescreen>true</tc:widescreen>
</xsl:if>
<xsl:if test="contains(@features, 'NTSC')">
<tc:format i18n="true">NTSC</tc:format>
</xsl:if>
<xsl:if test="contains(@features, 'PAL')">
<tc:format i18n="true">PAL</tc:format>
</xsl:if>
<xsl:if test="contains(@features, 'SECAM')">
<tc:format i18n="true">SECAM</tc:format>
</xsl:if>
<xsl:if test="contains(@features, 'Color')">
<tc:color i18n="true">Color</tc:color>
</xsl:if>
<xsl:if test="contains(@features, 'Black &amp; White')">
<tc:color i18n="true">Black &amp; White</tc:color>
</xsl:if>
<xsl:if test="contains(@features, '1.33:1')">
<tc:aspect-ratios>
<tc:aspect-ratio>1.33:1</tc:aspect-ratio>
</tc:aspect-ratios>
</xsl:if>
<xsl:if test="contains(@features, '1.85:1')">
<tc:aspect-ratios>
<tc:aspect-ratio>1.85:1</tc:aspect-ratio>
</tc:aspect-ratios>
</xsl:if>
<tc:audio-tracks>
<xsl:if test="contains(@features, 'Dolby')">
<tc:audio-track i18n="true">Dolby</tc:audio-track>
</xsl:if>
<xsl:if test="contains(@features, 'DTS')">
<tc:audio-track i18n="true">DTS</tc:audio-track>
</xsl:if>
</tc:audio-tracks>
<xsl:choose>
<xsl:when test="contains(@genre, 'Region 1')">
<tc:region i18n="true">Region 1</tc:region>
</xsl:when>
<xsl:when test="contains(@genre, 'Region 2')">
<tc:region i18n="true">Region 2</tc:region>
</xsl:when>
<xsl:when test="contains(@genre, 'Region 3')">
<tc:region i18n="true">Region 3</tc:region>
</xsl:when>
<xsl:when test="contains(@genre, 'Region 4')">
<tc:region i18n="true">Region 4</tc:region>
</xsl:when>
<xsl:when test="contains(@genre, 'Region 5')">
<tc:region i18n="true">Region 5</tc:region>
</xsl:when>
<xsl:when test="contains(@genre, 'Region 6')">
<tc:region i18n="true">Region 6</tc:region>
</xsl:when>
<xsl:when test="contains(@genre, 'Region 7')">
<tc:region i18n="true">Region 7</tc:region>
</xsl:when>
<xsl:when test="contains(@genre, 'Region 8')">
<tc:region i18n="true">Region 8</tc:region>
</xsl:when>
</xsl:choose>
<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>
<xsl:call-template name="split">
<xsl:with-param name="name" select="'tc:studio'"/>
<xsl:with-param name="value" select="@publisher"/>
</xsl:call-template>
<tc:running-time>
<xsl:value-of select="@minutes"/>
</tc:running-time>
<tc:certification>
<xsl:value-of select="concat(@mpaarating, ' (US)')"/>
</tc:certification>
<tc:year>
<xsl:call-template name="year">
<xsl:with-param name="value" select="@theatricalDate"/>
</xsl:call-template>
</tc:year>
<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:plot>
<xsl:value-of select="description"/>
</tc:plot>
</tc:entry>
</xsl:template>
<xsl:template match="game">
<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:value-of select="@title"/>
</tc:title>
<tc:platform>
<xsl:value-of select="@platform"/>
</tc:platform>
<tc:certification>
<xsl:value-of select="@esrbrating"/>
</tc:certification>
<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:pur_price>
<xsl:value-of select="@price"/>
</tc:pur_price>
<tc:pur_date>
<xsl:value-of select="@purchaseDate"/>
</tc:pur_date>
<tc:year>
<xsl:call-template name="year">
<xsl:with-param name="value" select="@published"/>
</xsl:call-template>
</tc:year>
<tc:rating>
<!-- tellico automatically rounds down -->
<xsl:value-of select="@netrating"/>
</tc:rating>
<tc:publisher>
<xsl:value-of select="@publisher"/>
</tc:publisher>
<tc:description>
<xsl:value-of select="description"/>
</tc:description>
</tc:entry>
</xsl:template>
<xsl:template name="split">
<xsl:param name="name"/>
<xsl:param name="value"/>
@ -161,4 +398,38 @@
<xsl:value-of select="substring($numbers, string-length($numbers)-3, 4)"/>
</xsl:template>
<xsl:template name="strip-title">
<xsl:param name="title"/>
<xsl:param name="chars" select="'[('"/>
<xsl:choose>
<xsl:when test="string-length($chars) = 0">
<xsl:value-of select="normalize-space($title)"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="strip-title">
<xsl:with-param name="title">
<xsl:call-template name="str-before">
<xsl:with-param name="value1" select="$title"/>
<xsl:with-param name="value2" select="substring($chars,1,1)"/>
</xsl:call-template>
</xsl:with-param>
<xsl:with-param name="chars" select="substring($chars,2)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="str-before">
<xsl:param name="value1"/>
<xsl:param name="value2"/>
<xsl:choose>
<xsl:when test="string-length($value2) &gt; 0 and contains($value1, $value2)">
<xsl:value-of select="substring-before($value1, $value2)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$value1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

@ -79,6 +79,11 @@
<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:when test="@type='GCcoins'">
<!-- gcstar includes way more coin grades than tellico -->
<tc:field flags="2" title="Grade" category="General" format="4" type="3" name="grade"
allowed="Proof-65;Proof-60;Mint State-70;Mint State-69;Mint State-68;Mint State-67;Mint State-66;Mint State-65;Mint State-64;Mint State-63;Mint State-62;Mint State-61;Mint State-60;Almost Uncirculated-58;Almost Uncirculated-55;Almost Uncirculated-53;Almost Uncirculated-50;Extremely Fine-45;Extremely Fine-40;Very Fine-35;Very Fine-30;Very Fine-25;Very Fine-20;Fine-15;Fine-12;Very Good-10;Very Good-8;Good-6;Good-4;Fair"/>
</xsl:when>
</xsl:choose>
</tc:fields>
<xsl:apply-templates select="item"/>
@ -477,6 +482,48 @@
</tc:num-players>
</xsl:template>
<!-- coins -->
<xsl:template match="condition">
<!-- by default, Tellico includes
"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" -->
<!-- GCStar doesn't appear to include proof grades -->
<tc:grade>
<xsl:choose>
<xsl:when test=".='70'">Mint State-70</xsl:when>
<xsl:when test=".='69'">Mint State-69</xsl:when>
<xsl:when test=".='68'">Mint State-68</xsl:when>
<xsl:when test=".='67'">Mint State-67</xsl:when>
<xsl:when test=".='66'">Mint State-66</xsl:when>
<xsl:when test=".='65'">Mint State-65</xsl:when>
<xsl:when test=".='64'">Mint State-64</xsl:when>
<xsl:when test=".='63'">Mint State-63</xsl:when>
<xsl:when test=".='62'">Mint State-62</xsl:when>
<xsl:when test=".='61'">Mint State-61</xsl:when>
<xsl:when test=".='60'">Mint State-60</xsl:when>
<xsl:when test=".='58'">Almost Uncirculated-58</xsl:when>
<xsl:when test=".='55'">Almost Uncirculated-55</xsl:when>
<xsl:when test=".='53'">Almost Uncirculated-53</xsl:when>
<xsl:when test=".='50'">Almost Uncirculated-50</xsl:when>
<xsl:when test=".='45'">Extremely Fine-45</xsl:when>
<xsl:when test=".='40'">Extremely Fine-40</xsl:when>
<xsl:when test=".='35'">Very Fine-35</xsl:when>
<xsl:when test=".='30'">Very Fine-30</xsl:when>
<xsl:when test=".='25'">Very Fine-25</xsl:when>
<xsl:when test=".='20'">Very Fine-20</xsl:when>
<xsl:when test=".='15'">Fine-15</xsl:when>
<xsl:when test=".='12'">Fine-12</xsl:when>
<xsl:when test=".='10'">Very Good-10</xsl:when>
<xsl:when test=".='8'">Very Good-8</xsl:when>
<xsl:when test=".='6'">Good-6</xsl:when>
<xsl:when test=".='4'">Good-4</xsl:when>
<xsl:when test=".&lt;4">Fair</xsl:when>
</xsl:choose>
</tc:grade>
</xsl:template>
<xsl:template name="year">
<xsl:param name="value"/>
<!-- want to find a 4-digit number to treat as the year -->

@ -258,7 +258,10 @@
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="concat($imgdir, .)"/>
<xsl:call-template name="image-link">
<xsl:with-param name="image" select="key('imagesById', .)"/>
<xsl:with-param name="dir" select="$imgdir"/>
</xsl:call-template>
</xsl:attribute>
<xsl:call-template name="image-size">
<xsl:with-param name="limit-width" select="$image-width"/>

@ -117,6 +117,7 @@
margin: 0px 0px 0px 0px;
padding: 0px 10px 0px 4px;
float: left;
min-height: 1em;
}
span.bar {
width: 590px;
@ -178,7 +179,7 @@
<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:with-param name="field" select="."/>
</xsl:call-template>
</xsl:for-each>
@ -189,35 +190,49 @@
<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:param name="field"/>
<xsl:variable name="fieldname" select="$field/@name"/>
<xsl:variable name="value-expr">
<xsl:for-each select="$coll/tc:entry">
<xsl:choose>
<!-- tables -->
<xsl:when test="$field/@type=8">
<xsl:for-each select="./*/*[local-name() = $fieldname]">
<value>
<xsl:value-of select="tc:column[1]"/>
</value>
</xsl:for-each>
</xsl:when>
<!-- multiple values...could also use "./*/*[local-name() = $fieldname]" -->
<xsl:when test="boolean(floor(key('fieldsByName', $fieldname)/@flags mod 2))">
<xsl:for-each select="./*/*[local-name() = $fieldname]">
<value>
<xsl:value-of select="."/>
</value>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<value>
<xsl:call-template name="simple-field-value">
<xsl:with-param name="entry" select="."/>
<xsl:with-param name="field" select="$fieldname"/>
</xsl:call-template>
</value>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="values" select="dyn:evaluate($str)"/>
<xsl:variable name="values" select="exsl:node-set($value-expr)/value"/>
<xsl:variable name="listing">
<xsl:for-each select="$values[not(. = preceding::*)]">
<xsl:for-each select="$values[not(. = preceding-sibling::*)]">
<!-- 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:value-of select="."/>
</xsl:attribute>
<xsl:attribute name="count">
<xsl:value-of select="$c"/>
@ -229,11 +244,11 @@
<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:call-template>
</xsl:variable>
<xsl:if test="$total &gt; 2">
@ -305,17 +320,6 @@
</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 -->

@ -232,7 +232,10 @@
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="concat($imgdir, .)"/>
<xsl:call-template name="image-link">
<xsl:with-param name="image" select="key('imagesById', .)"/>
<xsl:with-param name="dir" select="$imgdir"/>
</xsl:call-template>
</xsl:attribute>
<xsl:call-template name="image-size">
<xsl:with-param name="limit-width" select="$image-width"/>

@ -141,7 +141,10 @@
<xsl:if test="$id">
<img class="float">
<xsl:attribute name="src">
<xsl:value-of select="concat($imgdir, $id)"/>
<xsl:call-template name="image-link">
<xsl:with-param name="image" select="key('imagesById', $id)"/>
<xsl:with-param name="dir" select="$imgdir"/>
</xsl:call-template>
</xsl:attribute>
<xsl:call-template name="image-size">
<xsl:with-param name="limit-width" select="$image-width"/>
@ -150,7 +153,7 @@
</xsl:call-template>
</img>
</xsl:if>
<table>
<thead>
<tr>
@ -163,8 +166,9 @@
<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">
<!-- no other images or paragraphs allowed -->
<xsl:variable name="ftype" select="$entry/../tc:fields/tc:field[@name = current()]/@type"/>
<xsl:if test="$ftype != 10 and $ftype != 2">
<xsl:call-template name="field-output">
<xsl:with-param name="entry" select="$entry"/>
<!-- can't use a key, the context is not the document -->

@ -193,7 +193,10 @@
<xsl:if test="$id">
<img class="float" alt=" ">
<xsl:attribute name="src">
<xsl:value-of select="concat($imgdir, $id)"/>
<xsl:call-template name="image-link">
<xsl:with-param name="image" select="key('imagesById', $id)"/>
<xsl:with-param name="dir" select="$imgdir"/>
</xsl:call-template>
</xsl:attribute>
<xsl:call-template name="image-size">
<xsl:with-param name="limit-width" select="$image-width"/>

@ -329,7 +329,10 @@
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="concat($imgdir, .)"/>
<xsl:call-template name="image-link">
<xsl:with-param name="image" select="key('imagesById', .)"/>
<xsl:with-param name="dir" select="$imgdir"/>
</xsl:call-template>
</xsl:attribute>
<xsl:call-template name="image-size">
<xsl:with-param name="limit-width" select="$image-width"/>

@ -65,6 +65,9 @@
<xsl:when test="tc:tellico/tc:collection/@type=4">
<xsl:text>GCmusics</xsl:text>
</xsl:when>
<xsl:when test="tc:tellico/tc:collection/@type=8">
<xsl:text>GCcoins</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:variable>
<!-- grab all the applicable attributes once -->
@ -80,7 +83,7 @@
<xsl:apply-templates select="tc:collection"/>
</xsl:template>
<xsl:template match="tc:collection[@type&lt;2 or @type&gt;5]">
<xsl:template match="tc:collection[@type&lt;2 or @type&gt;5 and not(@type=8)]">
<xsl:message terminate="yes">
<xsl:text>GCstar export is not supported for this collection type.</xsl:text>
</xsl:message>
@ -147,6 +150,13 @@
</xsl:choose>
</xsl:attribute>
</xsl:if>
<!-- for coin grade, GCstar uses numbers only -->
<xsl:if test="tc:grade">
<xsl:attribute name="condition">
<!-- remove everything but numbers -->
<xsl:value-of select="translate(tc:grade,translate(tc:grade,'0123456789', ''),'')"/>
</xsl:attribute>
</xsl:if>
<!-- for books -->
<comments>

@ -127,8 +127,8 @@ sorttable = {
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)$/;
sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-](\d{4}|\d\d)$/;
sorttable.YYMMDD_RE = /^(\d{4}|\d\d)[\/\.-](\d\d?)[\/\.-](\d\d?)$/;
forEach(document.getElementsByTagName('table'), function(table) {
if (table.className.search(/\bsortable\b/) != -1) {
@ -371,7 +371,8 @@ sorttable = {
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 (y.length == 2)
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;
@ -379,7 +380,8 @@ sorttable = {
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 (y.length == 2)
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;

@ -115,10 +115,7 @@
</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 -->
@ -557,7 +554,10 @@
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="concat($imgdir, .)"/>
<xsl:call-template name="image-link">
<xsl:with-param name="image" select="key('imagesById', .)"/>
<xsl:with-param name="dir" select="$imgdir"/>
</xsl:call-template>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="concat('[', $entry//tc:title[1], ']')"/>

@ -46,9 +46,12 @@
</xsl:template>
<xsl:template match="cr:crossref">
<entry>
<xsl:apply-templates/>
</entry>
<!-- if there's an error, or none found, a crossref element still shows up, with an error element -->
<xsl:if test="not(cr:error)">
<entry>
<xsl:apply-templates/>
</entry>
</xsl:if>
</xsl:template>
<xsl:template match="cr:book">

Loading…
Cancel
Save