Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ SET(ENV{LC_ALL} "C")
# Project properties
PROJECT(gimagereader C CXX)
SET(PACKAGE_NAME gImageReader)
SET(PACKAGE_DESCRIPTION "A GTK/Qt frontend to tesseract OCR")
SET(PACKAGE_VERSION 3.4.3)
SET(PACKAGE_LOCALE_DIR "${CMAKE_INSTALL_PREFIX}/share/locale")

Expand Down Expand Up @@ -44,6 +45,7 @@ ENDFOREACH()

# Definitions
ADD_DEFINITIONS(-DPACKAGE_NAME=\"${PACKAGE_NAME}\")
ADD_DEFINITIONS(-DPACKAGE_DESCRIPTION=\"${PACKAGE_DESCRIPTION}\")
ADD_DEFINITIONS(-DPACKAGE_VERSION=\"${PACKAGE_VERSION}\")
ADD_DEFINITIONS(-DPACKAGE_REVISION=\"${PACKAGE_REVISION}\")
ADD_DEFINITIONS(-DGETTEXT_PACKAGE=\"${CMAKE_PROJECT_NAME}\")
Expand All @@ -61,12 +63,12 @@ PKG_CHECK_MODULES(ddjvuapi REQUIRED ddjvuapi)
PKG_CHECK_MODULES(PODOFO libpodofo)
IF(NOT TESSERACT_FOUND)
MESSAGE(WARNING "Using hardcoded cflags and ldflags for tesseract")
SET(TESSERACT_INCLUDE_DIRS /usr/include/tesseract)
SET(TESSERACT_INCLUDE_DIRS /var/empty/include/tesseract)
SET(TESSERACT_LDFLAGS -ltesseract)
ENDIF(NOT TESSERACT_FOUND)
IF(NOT PODOFO_FOUND)
MESSAGE(WARNING "Using hardcoded cflags and ldflags for podofo")
SET(PODOFO_INCLUDE_DIRS /usr/include/)
SET(PODOFO_INCLUDE_DIRS /var/empty/include/)
SET(PODOFO_LDFLAGS -lpodofo)
ENDIF(NOT PODOFO_FOUND)
IF(UNIX)
Expand Down
10 changes: 8 additions & 2 deletions gtk/src/MainWindow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,10 @@ void MainWindow::openFiles(const std::vector<Glib::RefPtr<Gio::File >> & files)
std::vector<Glib::RefPtr<Gio::File >> otherFiles;
for (const Glib::RefPtr<Gio::File>& file : files) {
std::string filename = file->get_path();
if (Glib::ustring(filename.substr(filename.length() - 5)).lowercase() == ".html") {
if (
Glib::ustring(filename.substr(filename.length() - 5)).lowercase() == ".html" ||
Glib::ustring(filename.substr(filename.length() - 5)).lowercase() == ".hocr"
) {
hocrFiles.push_back(file);
} else {
otherFiles.push_back(file);
Expand All @@ -243,7 +246,10 @@ void MainWindow::openOutput(const std::string& filename) {
if (setOutputMode(OutputModeText)) {
m_outputEditor->open(filename);
}
} else if (Utils::string_endswith(Glib::ustring(filename).lowercase(), ".html")) {
} else if (
Utils::string_endswith(Glib::ustring(filename).lowercase(), ".html") ||
Utils::string_endswith(Glib::ustring(filename).lowercase(), ".hocr")
) {
if (setOutputMode(OutputModeHOCR)) {
m_outputEditor->open(filename);
}
Expand Down
22 changes: 19 additions & 3 deletions gtk/src/SourceManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,11 @@ int SourceManager::addSources(const std::vector<Glib::RefPtr<Gio::File >> & file
m_watchedDirectories[dir].first += 1;
}
std::string base = Utils::split_filename(filename).first;
if (Glib::file_test(base + ".txt", Glib::FILE_TEST_EXISTS) || Glib::file_test(base + ".html", Glib::FILE_TEST_EXISTS)) {
if (
Glib::file_test(base + ".txt", Glib::FILE_TEST_EXISTS) ||
Glib::file_test(base + ".html", Glib::FILE_TEST_EXISTS) ||
Glib::file_test(base + ".hocr", Glib::FILE_TEST_EXISTS)
) {
m_fileTreeModel->setFileEditable(index, true);
}
selectIters.push_back(index);
Expand Down Expand Up @@ -437,6 +441,8 @@ void SourceManager::indexClicked(const Gtk::TreePath& path, Gtk::TreeViewColumn*
std::string base = Utils::split_filename(source->file->get_path()).first;
bool hasTxt = Glib::file_test(base + ".txt", Glib::FILE_TEST_EXISTS);
bool hasHtml = Glib::file_test(base + ".html", Glib::FILE_TEST_EXISTS);
bool hasHocr = Glib::file_test(base + ".hocr", Glib::FILE_TEST_EXISTS);
// FIXME handle all cases...
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs refactoring

if (hasTxt && hasHtml) {
Utils::Button::Type response = Utils::messageBox(Gtk::MESSAGE_QUESTION, _("Open output"), _("Both a text and a hOCR output were found. Which one do you want to open?"), "", Utils::Button::Text | Utils::Button::HOCR | Utils::Button::Cancel);
if (response == Utils::Button::Text) {
Expand All @@ -448,6 +454,8 @@ void SourceManager::indexClicked(const Gtk::TreePath& path, Gtk::TreeViewColumn*
MAIN->openOutput(base + ".txt");
} else if (hasHtml) {
MAIN->openOutput(base + ".html");
} else if (hasHocr) {
MAIN->openOutput(base + ".hocr");
}
}
}
Expand Down Expand Up @@ -517,7 +525,11 @@ void SourceManager::fileChanged(const Glib::RefPtr<Gio::File>& file, const Glib:
m_watchedDirectories[dir].first += 1;
}
std::string base = Utils::split_filename(otherFile->get_path()).first;
m_fileTreeModel->setFileEditable(it, Glib::file_test(base + ".txt", Glib::FILE_TEST_EXISTS) || Glib::file_test(base + ".html", Glib::FILE_TEST_EXISTS));
m_fileTreeModel->setFileEditable(it, (
Glib::file_test(base + ".txt", Glib::FILE_TEST_EXISTS) ||
Glib::file_test(base + ".html", Glib::FILE_TEST_EXISTS ||
Glib::file_test(base + ".hocr", Glib::FILE_TEST_EXISTS
)));
} else if (event == Gio::FILE_MONITOR_EVENT_DELETED) {
Utils::messageBox(Gtk::MESSAGE_ERROR, _("Missing File"), Glib::ustring::compose(_("The following file has been deleted or moved:\n%1"), file->get_path()));
m_fileTreeModel->removeIndex(it);
Expand All @@ -544,7 +556,11 @@ void SourceManager::dirChanged(const Glib::RefPtr<Gio::File>& file, const Glib::
Source* source = m_fileTreeModel->fileData<Source*> (child);
if (source) {
std::string base = Utils::split_filename(source->file->get_path()).first;
m_fileTreeModel->setFileEditable(child, Glib::file_test(base + ".txt", Glib::FILE_TEST_EXISTS) || Glib::file_test(base + ".html", Glib::FILE_TEST_EXISTS));
m_fileTreeModel->setFileEditable(child, (
Glib::file_test(base + ".txt", Glib::FILE_TEST_EXISTS) ||
Glib::file_test(base + ".html", Glib::FILE_TEST_EXISTS) ||
Glib::file_test(base + ".hocr", Glib::FILE_TEST_EXISTS)
));
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion gtk/src/hocr/HOCRBatchExportDialog.cc
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,10 @@ void HOCRBatchExportDialog::scanSourceDir(const std::string& dir, std::vector<st
while (Glib::RefPtr<Gio::FileInfo> file = it->next_file()) {
if (file->get_file_type() == Gio::FILE_TYPE_DIRECTORY) {
scanSourceDir(Glib::build_filename(dir, file->get_name()), files);
} else if (Utils::string_endswith(file->get_name(), ".html")) {
} else if (
Utils::string_endswith(file->get_name(), ".html") ||
Utils::string_endswith(file->get_name(), ".hocr")
) {
files.push_back(Glib::build_filename(dir, file->get_name()));
}
}
Expand Down
7 changes: 5 additions & 2 deletions gtk/src/hocr/OutputEditorHOCR.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1017,7 +1017,7 @@ bool OutputEditorHOCR::open(InsertMode mode, std::vector<Glib::RefPtr<Gio::File
return false;
}
if (files.empty()) {
FileDialogs::FileFilter filter = {_("hOCR HTML Files"), {"text/html", "text/xml", "text/plain"}, {"*.html"}};
FileDialogs::FileFilter filter = {_("hOCR HTML Files"), {"text/html", "text/xml", "text/plain"}, {"*.html", "*.hocr"}};
files = FileDialogs::open_dialog(_("Open hOCR File"), "", "outputdir", filter, true);
}
if (files.empty()) {
Expand Down Expand Up @@ -1100,7 +1100,8 @@ bool OutputEditorHOCR::save(const std::string& filename) {
suggestion = _("output");
}
}
FileDialogs::FileFilter filter = {_("hOCR HTML Files"), {"text/html"}, {"*.html"}};
FileDialogs::FileFilter filter = {_("hOCR HTML Files"), {"text/html"}, {"*.html", "*.hocr"}};
// TODO use .hocr by default?
outname = FileDialogs::save_dialog(_("Save hOCR Output..."), suggestion + ".html", "outputdir", filter);
if (outname.empty()) {
return false;
Expand Down Expand Up @@ -1137,6 +1138,7 @@ bool OutputEditorHOCR::save(const std::string& filename) {
}

std::string OutputEditorHOCR::crashSave(const std::string& filename) const {
// TODO use .hocr by default?
std::ofstream file(filename + ".html");
if (file.is_open()) {
Glib::ustring header = Glib::ustring::compose(
Expand All @@ -1154,6 +1156,7 @@ std::string OutputEditorHOCR::crashSave(const std::string& filename) const {
file.write(header.data(), header.bytes());
file.write(body.data(), body.bytes());
file.write(footer.data(), footer.bytes());
// TODO use .hocr by default?
return filename + ".html";
}
return "";
Expand Down
1 change: 1 addition & 0 deletions gtk/src/hocr/OutputEditorHOCR.hh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class OutputEditorHOCR : public OutputEditor {
public:
class HOCRBatchProcessor : public BatchProcessor {
public:
// TODO use .hocr by default?
std::string fileSuffix() const override { return std::string(".html"); }
void writeHeader(std::ostream& dev, tesseract::TessBaseAPI* tess, const PageInfo& pageInfo) const override;
void writeFooter(std::ostream& dev) const override;
Expand Down
10 changes: 8 additions & 2 deletions qt/src/MainWindow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,10 @@ MainWindow::MainWindow(const QStringList& files)
QStringList hocrFiles;
QStringList otherFiles;
for (const QString& file : files) {
if (file.endsWith(".html", Qt::CaseInsensitive)) {
if (
file.endsWith(".html", Qt::CaseInsensitive) ||
file.endsWith(".hocr", Qt::CaseInsensitive)
) {
hocrFiles.append(file);
} else {
otherFiles.append(file);
Expand Down Expand Up @@ -277,7 +280,10 @@ void MainWindow::openOutput(const QString& filename) {
if (setOutputMode(OutputModeText)) {
m_outputEditor->open(filename);
}
} else if (filename.endsWith(".html", Qt::CaseInsensitive)) {
} else if (
filename.endsWith(".html", Qt::CaseInsensitive) ||
filename.endsWith(".hocr", Qt::CaseInsensitive)
) {
if (setOutputMode(OutputModeHOCR)) {
m_outputEditor->open(filename);
}
Expand Down
17 changes: 15 additions & 2 deletions qt/src/SourceManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,11 @@ int SourceManager::addSources(const QStringList& files, bool suppressWarnings) {
if (m_watchedDirectories[finfo.absolutePath()] == 1) {
m_fsWatcher.addPath(finfo.absolutePath());
}
if (QFile(base + ".txt").exists() || QFile(base + ".html").exists()) {
if (
QFile(base + ".txt").exists() ||
QFile(base + ".html").exists() ||
QFile(base + ".hocr").exists()
) {
m_fileTreeModel->setFileEditable(index, true);
}
sel.select(index, index);
Expand Down Expand Up @@ -473,17 +477,22 @@ void SourceManager::indexClicked(const QModelIndex& index) {
QString base = finfo.absoluteDir().absoluteFilePath(finfo.baseName());
bool hasTxt = QFile(base + ".txt").exists();
bool hasHtml = QFile(base + ".html").exists();
bool hasHocr = QFile(base + ".hocr").exists();
// FIXME handle all cases...
if (hasTxt && hasHtml) {
QMessageBox box(QMessageBox::Question, _("Open output"), _("Both a text and a hOCR output were found. Which one do you want to open?"), QMessageBox::Cancel);
QAbstractButton* textButton = box.addButton(_("Text"), QMessageBox::AcceptRole);
QAbstractButton* hocrButton = box.addButton(_("hOCR"), QMessageBox::AcceptRole);
connect(textButton, &QAbstractButton::clicked, this, [base] { MAIN->openOutput(base + ".txt"); });
// TODO use .hocr by default?
connect(hocrButton, &QAbstractButton::clicked, this, [base] { MAIN->openOutput(base + ".html"); });
box.exec();
} else if (hasTxt) {
MAIN->openOutput(base + ".txt");
} else if (hasHtml) {
MAIN->openOutput(base + ".html");
} else if (hasHocr) {
MAIN->openOutput(base + ".hocr");
}
}
}
Expand Down Expand Up @@ -519,7 +528,11 @@ void SourceManager::directoryChanged(const QString& dir) {
if (source) {
QFileInfo finfo(source->path);
QString base = finfo.absoluteDir().absoluteFilePath(finfo.baseName());
m_fileTreeModel->setFileEditable(child, QFile(base + ".txt").exists() || QFile(base + ".html").exists());
m_fileTreeModel->setFileEditable(child, (
QFile(base + ".txt").exists() ||
QFile(base + ".html").exists() ||
QFile(base + ".hocr").exists()
));
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion qt/src/hocr/OutputEditorHOCR.cc
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,7 @@ bool OutputEditorHOCR::open(InsertMode mode, QStringList files) {
return false;
}
if (files.isEmpty()) {
files = FileDialogs::openDialog(_("Open hOCR File"), "", "outputdir", QString("%1 (*.html)").arg(_("hOCR HTML Files")), true);
files = FileDialogs::openDialog(_("Open hOCR File"), "", "outputdir", QString("%1 (*.html *.hocr)").arg(_("hOCR HTML Files")), true);
}
if (files.isEmpty()) {
return false;
Expand Down Expand Up @@ -996,6 +996,7 @@ bool OutputEditorHOCR::save(const QString& filename) {
suggestion = _("output");
}
}
// TODO use .hocr by default?
outname = FileDialogs::saveDialog(_("Save hOCR Output..."), suggestion + ".html", "outputdir", QString("%1 (*.html)").arg(_("hOCR HTML Files")));
if (outname.isEmpty()) {
return false;
Expand Down Expand Up @@ -1031,6 +1032,7 @@ bool OutputEditorHOCR::save(const QString& filename) {
}

QString OutputEditorHOCR::crashSave(const QString& filename) const {
// TODO use .hocr by default?
QFile file(filename + ".html");
if (file.open(QIODevice::WriteOnly)) {
QString header = QString(
Expand All @@ -1046,6 +1048,7 @@ QString OutputEditorHOCR::crashSave(const QString& filename) const {
file.write(m_document->toHTML().toUtf8());
m_document->convertSourcePaths(QFileInfo(filename).absolutePath(), true);
file.write("</html>\n");
// TODO use .hocr by default?
return filename + ".html";
}
return "";
Expand Down
1 change: 1 addition & 0 deletions qt/src/hocr/OutputEditorHOCR.hh
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class OutputEditorHOCR : public OutputEditor {
public:
class HOCRBatchProcessor : public BatchProcessor {
public:
// TODO use .hocr by default?
QString fileSuffix() const override { return QString(".html"); }
void writeHeader(QIODevice* dev, tesseract::TessBaseAPI* tess, const PageInfo& pageInfo) const override;
void writeFooter(QIODevice* dev) const override;
Expand Down
34 changes: 31 additions & 3 deletions qt/src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <QLocale>
#include <QTextCodec>
#include <QTranslator>
#include <QCommandLineParser>
#include <libintl.h>
#include <cstring>

Expand All @@ -40,6 +41,8 @@ int main(int argc, char* argv[]) {

QApplication::setOrganizationName(PACKAGE_NAME);
QApplication::setApplicationName(PACKAGE_NAME);
QApplication::setApplicationVersion(QString("%1 (%2)").arg(PACKAGE_VERSION, QString(PACKAGE_REVISION).left(6)));

QIcon::setFallbackSearchPaths(QIcon::fallbackSearchPaths() << ":/extra-theme-icons");

#ifdef Q_OS_WIN
Expand Down Expand Up @@ -89,12 +92,37 @@ int main(int argc, char* argv[]) {
qputenv("TWAINDSM_LOG", packageDir.absoluteFilePath("twain.log").toLocal8Bit());
std::freopen(packageDir.absoluteFilePath("gimagereader.log").toLocal8Bit().data(), "w", stderr);
#endif

QCommandLineParser parser;
parser.setApplicationDescription(PACKAGE_DESCRIPTION);
parser.addHelpOption();
parser.addVersionOption();

parser.addPositionalArgument(
"files",
QCoreApplication::translate(
"main",
"Files to open, optionally."
" These can be image files or hocr files."
" Every image file is seen as one page."
// TODO verify: these image paths are relative to the hocr dirname
" Hocr files can reference image files for pages or graphics."
),
"[files...]"
);
parser.process(app);

QStringList files;
for (int i = 1; i < argc; ++i) {
if (QFile(argv[i]).exists()) {
files.append(argv[i]);
for (const QString arg : parser.positionalArguments()) {
if (QFile(arg).exists()) {
qDebug("adding file: %s", arg.toUtf8().data());
files.append(arg);
}
else {
qInfo("ignoring non-file argument: %s", arg.toUtf8().data());
}
}

window = new MainWindow(files);
}
window->show();
Expand Down