Skip to content
Merged
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
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,23 @@ Rules:
`Unreleased`.
- Add the date and the compare link once the version tag exists.

## [Unreleased]

### Added

- The search shows which hit is selected and how many there are.

### Changed

- The engine is odrcore 7.6.0, up from 7.5.2. Long text files, PDFs, sheets
and presentations open faster.
- A cell of an array formula says why it cannot be edited.

### Fixed

- Words in a Word document no longer run together where the formatting changes.
- A font that is not installed falls back to one of the same kind.

## [1.49]

### Added
Expand Down
2 changes: 1 addition & 1 deletion OpenDocumentReader.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@
repositoryURL = "https://github.com/opendocument-app/OpenDocument.core.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 7.5.2;
minimumVersion = 7.6.0;
};
};
AD584FCD41577C8CDEE974AA /* XCRemoteSwiftPackageReference "swift-package-manager-google-mobile-ads" */ = {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 48 additions & 0 deletions OpenDocumentReader/DocumentViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ class DocumentViewController: UIViewController, DocumentDelegate, UISearchBarDel
return slot
}()

/// The place of the selected hit and the number of hits, below the search bar.
let searchCountLabel = UILabel()
private let searchCountPill = UIView()

private var searchBarHeightWhenShown: NSLayoutConstraint?
private var searchBarHeightWhenHidden: NSLayoutConstraint?
private lazy var pageTabBarHeight = pageTabBar.heightAnchor.constraint(equalToConstant: 0)
Expand Down Expand Up @@ -197,6 +201,7 @@ class DocumentViewController: UIViewController, DocumentDelegate, UISearchBarDel
searchBar.showsCancelButton = true
searchBarHeightWhenShown = searchBar.heightAnchor.constraint(equalToConstant: 56)
searchBarHeightWhenHidden = searchBar.heightAnchor.constraint(equalToConstant: 0)
setUpSearchCount()

setUpEditToolBar()
setUpPageMessages()
Expand Down Expand Up @@ -744,6 +749,11 @@ class DocumentViewController: UIViewController, DocumentDelegate, UISearchBarDel
}
staleCells = count

case "searchChange":
showSearchCount(
detail["count"] as? Int ?? 0, current: detail["current"] as? Int ?? -1,
complete: detail["complete"] as? Bool ?? true)

case "editRefused":
editRefused(reason: detail["reason"] as? String ?? "")

Expand Down Expand Up @@ -965,6 +975,7 @@ class DocumentViewController: UIViewController, DocumentDelegate, UISearchBarDel
case "newLine": key = "edit_refused_new_line"
case "formula": key = "edit_refused_formula"
case "formulaInput": key = "edit_refused_formula_input"
case "array": key = "edit_refused_array"
case "rich", "shapes": key = "edit_refused_rich"
case "readOnly": key = "edit_refused_read_only"
case "range": key = "edit_refused_range"
Expand Down Expand Up @@ -1150,9 +1161,46 @@ class DocumentViewController: UIViewController, DocumentDelegate, UISearchBarDel
searchBar.becomeFirstResponder()
}

private func setUpSearchCount() {
searchCountLabel.font = .monospacedDigitSystemFont(ofSize: UIFont.smallSystemFontSize, weight: .medium)
searchCountLabel.textColor = .secondaryLabel
searchCountLabel.translatesAutoresizingMaskIntoConstraints = false

// over the document, because the search field does not show a right view
searchCountPill.backgroundColor = .secondarySystemBackground
searchCountPill.layer.cornerRadius = 12
searchCountPill.isUserInteractionEnabled = false
searchCountPill.translatesAutoresizingMaskIntoConstraints = false
searchCountPill.addSubview(searchCountLabel)
view.addSubview(searchCountPill)

NSLayoutConstraint.activate([
searchCountLabel.leadingAnchor.constraint(equalTo: searchCountPill.leadingAnchor, constant: 10),
searchCountLabel.trailingAnchor.constraint(equalTo: searchCountPill.trailingAnchor, constant: -10),
searchCountLabel.topAnchor.constraint(equalTo: searchCountPill.topAnchor, constant: 4),
searchCountLabel.bottomAnchor.constraint(equalTo: searchCountPill.bottomAnchor, constant: -4),
searchCountPill.topAnchor.constraint(equalTo: searchBar.bottomAnchor, constant: 8),
searchCountPill.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16),
])
showSearchCount(0, current: -1, complete: true)
}

/// `current` counts from 0, and is -1 where no hit is selected. Hits that
/// are still being counted show as a "+".
private func showSearchCount(_ count: Int, current: Int, complete: Bool) {
if searchBar.isHidden || searchBar.text?.isEmpty ?? true {
searchCountLabel.text = nil
} else {
let total = "\(count)\(complete ? "" : "+")"
searchCountLabel.text = current >= 0 ? "\(current + 1)/\(total)" : total
}
searchCountPill.isHidden = searchCountLabel.text == nil
}

private func hideSearchBar() {
searchBar.text = ""
searchBar.isHidden = true
showSearchCount(0, current: -1, complete: true)
searchBarHeightWhenHidden?.isActive = true
searchBarHeightWhenShown?.isActive = false

Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/ca.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "Aquesta cel·la conté una fórmula i es queda com està.";
"edit_refused_formula_input" = "Escriure una fórmula encara no és compatible.";
"edit_refused_array" = "Aquesta cel·la forma part d’una fórmula matricial i es queda com està.";
"edit_refused_rich" = "Aquesta cel·la conté més que text simple i es queda com està.";
"edit_refused_generic" = "Aquesta edició no és possible aquí.";
"edit_refused_new_line" = "Un salt de línia dins d’un paràgraf no es pot desar. Prem Retorn per a un paràgraf nou.";
Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/cs.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "Tato buňka obsahuje vzorec a zůstává beze změny.";
"edit_refused_formula_input" = "Zadávání vzorců zatím není podporováno.";
"edit_refused_array" = "Tato buňka je součástí maticového vzorce a zůstane beze změny.";
"edit_refused_rich" = "Tato buňka obsahuje víc než prostý text a zůstává beze změny.";
"edit_refused_generic" = "Tato úprava tu není možná.";
"edit_refused_new_line" = "Zalomení řádku uvnitř odstavce nelze uložit. Stiskněte Enter pro nový odstavec.";
Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/da.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "Den celle indeholder en formel og forbliver, som den er.";
"edit_refused_formula_input" = "Indtastning af formler understøttes ikke endnu.";
"edit_refused_array" = "Cellen er en del af en matrixformel og forbliver uændret.";
"edit_refused_rich" = "Den celle indeholder mere end ren tekst og forbliver, som den er.";
"edit_refused_generic" = "Den redigering er ikke mulig her.";
"edit_refused_new_line" = "Et linjeskift inde i et afsnit kan ikke gemmes. Tryk på Enter for et nyt afsnit.";
Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "Diese Zelle enthält eine Formel und bleibt, wie sie ist.";
"edit_refused_formula_input" = "Formeln eingeben wird noch nicht unterstützt.";
"edit_refused_array" = "Diese Zelle gehört zu einer Matrixformel und bleibt, wie sie ist.";
"edit_refused_rich" = "Diese Zelle enthält mehr als reinen Text und bleibt, wie sie ist.";
"edit_refused_generic" = "Diese Änderung ist hier nicht möglich.";
"edit_refused_new_line" = "Ein Zeilenumbruch innerhalb eines Absatzes kann nicht gespeichert werden. Drücke die Eingabetaste für einen neuen Absatz.";
Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "That cell holds a formula and stays as it is.";
"edit_refused_formula_input" = "Typing a formula is not supported yet.";
"edit_refused_array" = "That cell is part of an array formula and stays as it is.";
"edit_refused_rich" = "That cell holds more than plain text and stays as it is.";
"edit_refused_generic" = "That edit is not possible here.";
"edit_refused_new_line" = "A line break inside a paragraph cannot be saved. Press Return for a new paragraph.";
Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/es.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "Esa celda contiene una fórmula y se queda como está.";
"edit_refused_formula_input" = "Escribir una fórmula aún no es compatible.";
"edit_refused_array" = "Esa celda forma parte de una fórmula matricial y se queda como está.";
"edit_refused_rich" = "Esa celda contiene más que texto sin formato y se queda como está.";
"edit_refused_generic" = "Esa edición no es posible aquí.";
"edit_refused_new_line" = "Un salto de línea dentro de un párrafo no se puede guardar. Pulsa Intro para un párrafo nuevo.";
Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/fr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "Cette cellule contient une formule et reste telle quelle.";
"edit_refused_formula_input" = "La saisie d’une formule n’est pas encore prise en charge.";
"edit_refused_array" = "Cette cellule fait partie d’une formule matricielle et reste telle quelle.";
"edit_refused_rich" = "Cette cellule contient plus que du texte brut et reste telle quelle.";
"edit_refused_generic" = "Cette modification n’est pas possible ici.";
"edit_refused_new_line" = "Un saut de ligne à l’intérieur d’un paragraphe ne peut pas être enregistré. Appuyez sur Entrée pour un nouveau paragraphe.";
Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/ga.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "Tá foirmle sa chill sin agus fanann sí mar atá.";
"edit_refused_formula_input" = "Ní thacaítear le foirmlí a chlóscríobh go fóill.";
"edit_refused_array" = "Is cuid d’fhoirmle eagair an cill sin agus fanann sí mar atá.";
"edit_refused_rich" = "Tá níos mó ná gnáth-théacs sa chill sin agus fanann sí mar atá.";
"edit_refused_generic" = "Ní féidir an t-athrú sin a dhéanamh anseo.";
"edit_refused_new_line" = "Ní féidir briseadh líne laistigh d’alt a shábháil. Brúigh Iontráil le haghaidh alt nua.";
Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/it.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "Quella cella contiene una formula e resta com’è.";
"edit_refused_formula_input" = "Digitare una formula non è ancora supportato.";
"edit_refused_array" = "Quella cella fa parte di una formula matrice e resta com’è.";
"edit_refused_rich" = "Quella cella contiene più di testo semplice e resta com’è.";
"edit_refused_generic" = "Questa modifica non è possibile qui.";
"edit_refused_new_line" = "Un’interruzione di riga dentro un paragrafo non può essere salvata. Premi Invio per un nuovo paragrafo.";
Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/ja.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "そのセルには数式が入っているため、そのままになります。";
"edit_refused_formula_input" = "数式の入力はまだ対応していません。";
"edit_refused_array" = "このセルは配列数式の一部のため、変更できません。";
"edit_refused_rich" = "そのセルには書式付きの内容が入っているため、そのままになります。";
"edit_refused_generic" = "この編集はここではできません。";
"edit_refused_new_line" = "段落内の改行は保存できません。新しい段落にはReturnキーを押してください。";
Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/pl.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "Ta komórka zawiera formułę i pozostaje bez zmian.";
"edit_refused_formula_input" = "Wpisywanie formuł nie jest jeszcze obsługiwane.";
"edit_refused_array" = "Ta komórka należy do formuły tablicowej i pozostaje bez zmian.";
"edit_refused_rich" = "Ta komórka zawiera więcej niż zwykły tekst i pozostaje bez zmian.";
"edit_refused_generic" = "Ta zmiana nie jest tu możliwa.";
"edit_refused_new_line" = "Podziału wiersza wewnątrz akapitu nie można zapisać. Naciśnij Enter, aby zacząć nowy akapit.";
Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/pt-BR.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "Essa célula contém uma fórmula e fica como está.";
"edit_refused_formula_input" = "Digitar uma fórmula ainda não é possível.";
"edit_refused_array" = "Essa célula faz parte de uma fórmula matricial e fica como está.";
"edit_refused_rich" = "Essa célula contém mais do que texto simples e fica como está.";
"edit_refused_generic" = "Essa edição não é possível aqui.";
"edit_refused_new_line" = "Uma quebra de linha dentro de um parágrafo não pode ser salva. Pressione Enter para um novo parágrafo.";
Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/ru.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "В этой ячейке формула, она остаётся как есть.";
"edit_refused_formula_input" = "Ввод формул пока не поддерживается.";
"edit_refused_array" = "Эта ячейка входит в формулу массива и остаётся без изменений.";
"edit_refused_rich" = "В этой ячейке не только простой текст, она остаётся как есть.";
"edit_refused_generic" = "Такое изменение здесь невозможно.";
"edit_refused_new_line" = "Перенос строки внутри абзаца нельзя сохранить. Нажмите Ввод, чтобы начать новый абзац.";
Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/sl.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "Ta celica vsebuje formulo in ostane, kot je.";
"edit_refused_formula_input" = "Vnos formul še ni podprt.";
"edit_refused_array" = "Ta celica je del matrične formule in ostane nespremenjena.";
"edit_refused_rich" = "Ta celica vsebuje več kot navadno besedilo in ostane, kot je.";
"edit_refused_generic" = "To urejanje tu ni mogoče.";
"edit_refused_new_line" = "Preloma vrstice znotraj odstavka ni mogoče shraniti. Pritisnite Enter za nov odstavek.";
Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/tr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "Bu hücrede bir formül var ve olduğu gibi kalır.";
"edit_refused_formula_input" = "Formül yazma henüz desteklenmiyor.";
"edit_refused_array" = "Bu hücre bir dizi formülünün parçasıdır ve olduğu gibi kalır.";
"edit_refused_rich" = "Bu hücrede düz metinden fazlası var ve olduğu gibi kalır.";
"edit_refused_generic" = "Bu düzenleme burada yapılamaz.";
"edit_refused_new_line" = "Paragraf içindeki satır sonu kaydedilemez. Yeni paragraf için Enter’a basın.";
Expand Down
1 change: 1 addition & 0 deletions OpenDocumentReader/zh-Hans.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
/* Why an edit was not taken */
"edit_refused_formula" = "该单元格包含公式,保持不变。";
"edit_refused_formula_input" = "暂不支持输入公式。";
"edit_refused_array" = "该单元格属于数组公式,保持不变。";
"edit_refused_rich" = "该单元格包含的不只是纯文本,保持不变。";
"edit_refused_generic" = "此处无法进行该编辑。";
"edit_refused_new_line" = "段落内的换行无法保存。请按回车键开始新段落。";
Expand Down
14 changes: 14 additions & 0 deletions OpenDocumentReaderTests/EditWorkflowTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ class EditWorkflowTests: XCTestCase {
XCTAssertEqual(evaluate("window.lastQuery") as? String, query)
}

func testSearchShowsTheSelectedHitAndTheCount() throws {
openDocument()
controller.searchButton(controller.searchButton)
controller.searchBar.text = "simple"

controller.searchBar(controller.searchBar, textDidChange: "simple")
waitUntil { self.controller.searchCountLabel.text?.hasPrefix("1/") == true }
let count = try XCTUnwrap(controller.searchCountLabel.text?.dropFirst(2))
XCTAssertGreaterThan(Int(count) ?? 0, 1)

controller.searchBarResultsListButtonClicked(controller.searchBar)
waitUntil { self.controller.searchCountLabel.text == "2/\(count)" }
}

func testCoveringTheReaderKeepsTheDocumentAndEdits() throws {
openDocument()
controller.editDocument()
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ Security blocks plain HTTP.
one and then moves it into place.
- The page talks to the app through one `WKScriptMessageHandler`.

## Search

The search bar calls `odr.search`, and the page sends the count back as
`searchChange`. Do not use the find of the web view. odrcore lays out only the
part near the viewport, and that find does not reach the rest.

The count sits in a pill below the bar, because the search field does not show
a right view. Lazy loading stays off, because a print from the web view leaves
a part that has not loaded empty.

## Formatting

`scripts/format.sh` runs `swift-format` from the active Xcode toolchain, with
Expand Down
Loading