Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Quick PDF-Library: Wie die Position des Annotationfensters ermitteln? (https://www.delphipraxis.net/209154-quick-pdf-library-wie-die-position-des-annotationfensters-ermitteln.html)

Harry Stahl 2. Nov 2021 16:04

Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Nutzt evtl. jemand von Euch die Quick PDF-Librray (ehemals Debenu, jetzt FoxIt), aktuelle Version 18.11?

Da gibt es eine Funktion, da kann man sog. Stick Notes als Anmerkung (Annotation) dem PDF-Dokument hinzufügen (Funktion "AddNoteAnnotation".

Da übergibt man eine left, top position für das Icon, welches eine Anmerkung symbolisiert und dann auch PopupLeft, PopUpTop, PopUp.Width und PopUp.height für das eigentliche Anmerkungsfenster, welches an unterschiedlichen Positionen auf der Seite gezeigt werden kann.

Das funktioniert auch soweit, jedoch habe ich in der Library keine Funktion gefunden, mit der man die Position des PopUp-Fensters später wieder aus der PDF-Datei ermitteln könnte. Die Position des Icon kann ich abfragen, mit "GetAnnotDblProperty". Aber wie die Position des PopUp-Fensters?

Das Quick-PDF-Forum (http://www.quickpdf.org/forum) ist leider seit gestern down, da ist die Seite abgelaufen, da konnte man sonst oft was finden. Habe mit Google das ganze Internet abgesucht, aber außer insoweit nun toten Links nichts gefunden.

Auch wenn die Hoffnung ist groß ist, hat da evtl. jemand eine Lösung?

ULIK 3. Nov 2021 09:03

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Hast Du QuickPDF in der Source-Version? Dann könnte ich Dir die nötigen Erweiterungen schicken um an die benötigten Informationen heran zu kommen.

Das Problem im Allgemeinen ist wie folgt: wenn Du mit AddNoteAnnotation eine Annotation anlegst, dann wird nicht nur eine angelegt, sondern immer zwei Stück:
die erste die das Note-Symbol darstellt und vom Subtype /Text ist und die zweite die vom Subtype /Popup ist. Die erste referenziert die zweite mittels der Eigenschaft /Popup und die zweite hat in der Eigenschaft /Parent die erste stehen. In PDF schaut das so aus:

Code:
AddNoteAnnotation(100, 100, 0, 100, 100, 100, 100, 'Murks', 'Content', 1.0, 0,0,0);
wird zu
Code:
8 0 obj
<<
/Type /Annot
/Subtype /Text
/M (D:20211103093933+01'00')
/Name /Note
/Rect [ 100 76 120 100 ]
/C [ 1 0 0 ]
/T (Murks)
/Contents (Content)
/F 28
/Popup 9 0 R
/AP <<
/N 10 0 R
>>
/P 2 0 R
/Subj (Sticky Note)
/NM (D:20211103093933+01'00')
/CreationDate (D:20211103093933+01'00')
>>
endobj
9 0 obj
<<
/Type /Annot
/Subtype /Popup
/Parent 8 0 R
/Rect [ 100 0 200 100 ]
/F 25
/Open false
>>
endobj
Auf diese Weise sind die beiden Annotations verbunden. Dummerweise kommt man mit der regulären Version von QuickPDF nicht an die Informationen /Popup bzw. /Parent ran. Das hab ich erst extra einbauen müssen.


Grüße,
Uli

Harry Stahl 3. Nov 2021 23:17

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Hey, vielen Dank für die Antwort.

Bin da eben zufälligerweise selbst drauf gekommen, als mir auffiel, dass nach der eigentlichen Annotation vom Type "Text" immer ein Element namens "Popup" folgt, welches die Koordinaten enthält (also einfach Index um 1 erhöhen).

Jetzt stehe ich gerade vor dem Problem, herauszufinden, ob ein Popup beim Laden der PDF geschlossen ist oder offen.

Hast Du da zufälligerweise auch noch einen Tipp?

Habe nur die "normale" Version, also ohne Source...

ULIK 4. Nov 2021 06:32

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Servus,

leider kenn ich da keinen Workaround. Das Auswerten von /Open hab ich erst in QuickPDF einbauen müssen.
Was deine Lösung für das Finden des Popups betrifft: das dürfte wohl so klappen. Ich hab bisher noch kein PDF gesehen, wo das Popup nicht sofort nach der Annotation kommt.
Wenn Du die PDFs aber nicht selbst erstellst, sondern beliebige PDFs verarbeiten willst, dann achte auf eines: es gibt Annotations, die ein Reply auf eine andere Annotation sind. Für dieses darfst Du dann das Popup nicht anzeigen sondern es muß in dem Popup der Annotation erscheinen, für das es ein Reply ist. Ich hab Dir ein entsprechendes PDF mal angehängt. Du kannst das aber erkennen, in dem Du mit GetAnnotIntProperty(128) nachschaust, ob dieses einen Index > 0 liefert. In dem Fall wird dann die Annotation nicht angezeigt, aber das zugehörige Popup in das der Referenz eingebettet.

Grüße,
Uli

Harry Stahl 4. Nov 2021 21:18

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hey, danke für den Hinweis auf die Replys, die hatte ich bislang noch gar nicht im Blick.

Sieht jetzt so aus, wie im anliegenden Screenshot (Deine Anmerkung rechts neben der Seite und weitere von mir hinzugefügt).

Na, dann muss ich mal weiter forschen wegen des Open-Status.

Ich bin eigentlich ganz zufrieden mit der Standard-Version, nutze da inzwischen nur die DLL's, die kriege ich fertig für Windows, MacOS und Linux, funktionieren also unabhängig von irgendwelchen Delphi-Updates.

Compiliert denn die Source-Version auch für FMX oder ist das Windows-Only?

ULIK 5. Nov 2021 08:44

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Ob QuickPDF mit FMX kompiliert: ich hab das nie ausprobiert, da ich FMX nicht verwende. Aber eigentlich sollte es, denn die Source-Edition ist ja die Codebasis von allen Versionen und spezieller UI Code wird ja nicht verwendet. Zumindest ist für die DLL Version ein eigenes Projekt dabei.

Edit: hab's grad mal getestet. Out of Box kompiliert das nicht für FMX. Man muß auf alle Fälle die .INC Datei ändern und dann teilweise ein paar Sachen wegen Uneindeutigkeiten bei der Typdeklaration anpassen. Denke aber, daß man das in den Griff kriegt.

Was das Open betrifft: ich kann mir gerade nicht vorstellen, wie man da anders ran kommen sollte. Die Info ist halt nur in den Daten der Popup-Annotation gespeichert.


Grüße,
Uli

Harry Stahl 8. Nov 2021 17:19

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Vielen Dank für's ausprobieren.

Wie gesagt, eigentlich reicht mir die DLL-Variante, aber wenn man sonst nicht an bestimmte Sachen ran kommt, muss ich mir das überlegen. Müsste aber zwingend auch für FMX geeignet sein, da ich das immer Plattform-übergreifend verwende.

Scheint jedenfalls so einiges zu sein, neben dem Offen/geschlossen Status der Annotation habe z.B. auch nichts gefunden, um selber eine Antwort-Annotation zu setzen...

Aber ich werde da einfach mal eine Erweiterung bei Foxit anregen, evtl. machen die das ja...

Harry Stahl 11. Nov 2021 14:59

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Zitat:

Zitat von ULIK (Beitrag 1497000)
Hast Du QuickPDF in der Source-Version? Dann könnte ich Dir die nötigen Erweiterungen schicken um an die benötigten Informationen heran zu kommen.

Das Problem im Allgemeinen ist wie folgt: wenn Du mit AddNoteAnnotation eine Annotation anlegst, dann wird nicht nur eine angelegt, sondern immer zwei Stück:
die erste die das Note-Symbol darstellt und vom Subtype /Text ist und die zweite die vom Subtype /Popup ist. Die erste referenziert die zweite mittels der Eigenschaft /Popup und die zweite hat in der Eigenschaft /Parent die erste stehen. In PDF schaut das so aus:

Code:
AddNoteAnnotation(100, 100, 0, 100, 100, 100, 100, 'Murks', 'Content', 1.0, 0,0,0);
wird zu
Code:
8 0 obj
<<
/Type /Annot
/Subtype /Text
/M (D:20211103093933+01'00')
/Name /Note
/Rect [ 100 76 120 100 ]
/C [ 1 0 0 ]
/T (Murks)
/Contents (Content)
/F 28
/Popup 9 0 R
/AP <<
/N 10 0 R
>>
/P 2 0 R
/Subj (Sticky Note)
/NM (D:20211103093933+01'00')
/CreationDate (D:20211103093933+01'00')
>>
endobj
9 0 obj
<<
/Type /Annot
/Subtype /Popup
/Parent 8 0 R
/Rect [ 100 0 200 100 ]
/F 25
/Open false
>>
endobj
Auf diese Weise sind die beiden Annotations verbunden. Dummerweise kommt man mit der regulären Version von QuickPDF nicht an die Informationen /Popup bzw. /Parent ran. Das hab ich erst extra einbauen müssen.


Grüße,
Uli

Hier könnte ich die Information ja entsprechend auslesen (/Open false). Würde aber ungerne immer auch die PDF-Datei zusätzlich als ganzen Textstream einlesen (was natürlich zur Not ginge). Mit SelectContentSteram und GetContentstream komme ich leider nicht zum Ziel. Gibt es sonst eine alternative Möglichkeit Teile aus der PDF-Datei im oben genannten Format anlassbezogen und partiell einzulesen, so dass ich an Infos im oben genannten Format rankomme?

ULIK 11. Nov 2021 15:17

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Das ist genau das Problem: es gibt nichts passendes dafür. Zwar kann Du mit GetObjectToString die Daten eines PDF Objekts auslesen. Das Problem ist dann aber: wie finde ich heraus, welche Objektnummer meine aktuelle Annotation hat.
Die Funktionen im QuickPDF liefern max. den Index der Annotation auf der Seite. Im Endeffekt bleibt Dir also nichts weiter übrig, als den kompletten Source durchzugehen und Dir zu merken, was davon eine Annotation ist und auf welcher Seite diese liegt.

Harry Stahl 11. Nov 2021 16:40

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Interessanterweise liefert bei mir die GetobjectToString gar nicht die Annotations zurück, sondern irgend einen anderen Kram. Vielversprechender ist dann wohl doch die ganze PDF Datei zu verwenden, da finde ich alle Objekte und kann meine Annotationen anhand der Position (relativ) sicher ermitteln.

Blöd nur, dass andere PDF-Programme anscheinend die PDF-Datei irgendwie komprimiert speichern, dann finde ich nichts, muss also erst die Datei öffnen, dann als (unkomprimierten) Stream speichern und den in eine Textdatei laden.

Na ja, werde ich gleich mal ausprobieren. Aber sieht so aus, als ob man so doch an einige zusätzliche Infos ran kommen könnte.

Edit: Funktioniert hervorrangend!. Ist zwar ein wenig Parser-Gefrickel (aber ich muss gestehen, ich liebe das), aber so kann ich beim Laden der Datei sicher den Zustand der Popups ermitteln. Und als Stream zu speichern, etc. brauch ich auch nicht, da ein einfaches qp.savetostring mir die Daten wie gewünscht liefert.

Nun muss ich mir nur noch überlegen, wie ich Änderungen des geöffnet-Status zurückschreibe. Wahrscheinlich indem ich bei Änderung des Status das Popup lösche und mit dem neuen Status wieder anlege. Umständlich, aber wenn es nicht anders geht...?

Denn eine Quick-PDF-Funktion habe ich nicht gefunden, womit man den Status des Popups ändern könnte.

ULIK 12. Nov 2021 08:20

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Super! :thumb:
Noch ein kleiner Rat (falls für Dich relevant): wenn Du Zugriff auf einen mit einer neueren AutoCAD Version erstellten Plan hast, dann teste dein Programm mal gegen ein daraus generiertes PDF. Der Hintergrund: in diesen Plänen gibt es nämlich gerne mal extrem viele Annotations (hab da Beispiele mit 10000 und mehr Annotations). Einfach weil dort jede Beschriftung als Annotation angelegt wird.
Oder generier mal mit QuickPDF so ein PDF mit >10000 Text-Annotations.


Grüße,
Uli

Harry Stahl 12. Nov 2021 17:16

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Und die 10.000 Annotationen sind alle auf einer Seite?
Ich habe mein Programm so gestrickt, dass immer nur alle Annotationen der gewählten Seite angezeigt wird.
Man kann aber mit Schaltern zur nächsten oder vorherigen Seite mit Annotationen springen.

Edit 1: Sind das alles sinle-Annotations oder ist es eher eine oder einige Annotationen mit vielen Antworten?

Edit2: Jetzt ist es mir auch gelungen, den Status der Annotationen zu setzen und zu speichern (habe hier doch GetobjFromString und SetObjToString verwendet). Mal schauen, ob ich noch das setzen einer Antwort auf eine Annotation hinbekomme, dann wäre ich soweit zufrieden...

ULIK 15. Nov 2021 06:37

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Die waren wirklich auf einer Seite: das war ein riesiger AutoCAD Plan mit Papierformat 2x3 m und alle Beschriftungen auf diesem Plan waren Text Annotations :-D Ist natürlich ein Extrembeispiel aber im Hinterkopf sollte man es halt behalten.

Lies Dir in der PDF Spec die Abschnitte bei den Markup-Annotations für die Eigenschaften IRT und RT durch. Gerade IRT ist das interessante. Dann modifizier deine Annotation entsprechend und schreib es mit SetObjToString in das PDF zurück.

Harry Stahl 15. Nov 2021 10:52

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Danke für den Hinweis. Genau das hatte ich schon selber herausgefunden und konnte damit auch eine Antwort-Annotation setzen.

Was mir dabei auffiel, ist dass nach dem Anfügen von Annotationen diese leider nicht direkt auch über die Objektliste erreichbar sind. Erst nachdem ich die PDF-Datei gespeichert und neu geladen habe, tauchen die in der Objektliste auf (mache ich nicht als Dateispeicherung, sondern speichern in String und laden daraus). Die Anzahl der Objekte wird zwar erhöht, aber wie gesagt, bei Abfrage der Objekte nacheinander tauchen die neu hinzugefügten Annotationen nicht auf.

Allerdings ist das umständlich und unnötig aufwändig. Gibt es nicht eine andere Methode, um sicherzustellen, dass angefügte Annotationen auch direkt danach über die Objectliste verfügbar sind?

Welche Dokumentation zur PDF-Spezifikation kannst Du empfehlen? "/IRT" habe ich durch vergleichen der Annos rausgefunden, aber das ist natürlich aufwendig. Andererseits eröffnet sich ja mit dem direkten Schreiben und lesen der Objekte doch ein weites Anwedungsfeld...

ULIK 15. Nov 2021 14:59

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Ich hab hier die offizielle PDF 1.7 und 2.0 Spezifikation rumliegen. Die gibt's aber glaub ich nur zu kaufen (hat mein Arbeitgeber besorgt, darum weis ich grad nichts genaueres über Bezugsquellen).

Das mit den Objektlisten schau ich mir mal an. Wie genau erstellst Du eine neue Annotation? Mit AddTextMarkupAnnotation?

Edit: Hab das schnell getestet: wenn ich mit
Code:
qp.AddNoteAnnotation(100, 100, 0, 100, 100, 100, 100, 'Murks', 'Content', 1.0, 0,0,0);
eine neue Annotation angelege, dann seh ich die sofort in der Objektliste.

Hier mein Testcode:
Code:
        qp := TDebenuPDFLibrary.Create;
        try
          for i := 1 to qp.GetObjectCount do
          begin
            strObject := qp.GetObjectToString(i);

            memo1.Lines.Add('Obj ' + IntToStr(i) + ' ' + Copy(strObject,1, 60) + #13#10);
          end;

          qp.AddNoteAnnotation(100, 100, 0, 100, 100, 100, 100, 'Murks', 'Content', 1.0, 0,0,0);

          for i := 1 to qp.GetObjectCount do
          begin
            strObject := qp.GetObjectToString(i);

            memo1.Lines.Add('Obj ' + IntToStr(i) + ' ' + Copy(strObject,1, 60) + #13#10);
          end;
        finally
          qp.Free;
        end;

Harry Stahl 15. Nov 2021 15:05

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Nein, ich verwende AddNoteAnnotation.

ULIK 15. Nov 2021 15:12

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Upps. Siehe meine Bearbeitung oben

Harry Stahl 15. Nov 2021 15:42

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Dein "Upps" verstehe ich als Bestätigung des Problems. Oder?

Edit: Mal selber getestet: hier existiert das Object auch nach dem Add.

Das nicht- funktionieren hatte ich auch erst mal festgestellt, bei einer größeren Datei, die ein anderer erzeugt hat...

Harry Stahl 15. Nov 2021 18:16

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Kann das übrigens sein, dass das nachträgliche Hinzufügen eines Outline-Eintrages als Child nicht funktioniert, wenn das Parent-Outline kein Child ist?

Ich wollte einen neuen Untereintrag in einem bestehenden Baum nachträglich hinzufügen (also einem Child ein weiteres Child hinzufügen), das geht wohl nicht, muss ich dafür den ganzen Baum neu erzeugen?

EDit: Das ist wohl nur so ab Level-Ebene 3, ab da funktioniert es nicht mehr, vorher kein Problem. Seltsam...

ULIK 16. Nov 2021 08:39

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Outlines: das wäre mir noch nie aufgefallen. Kannst Du mir da mal deinen Testcode schicken? Hab's grad in unsere Anwendung schnell ausprobiert, da hab ich kein Problem gehabt auch in der 6./7. Ebene

Harry Stahl 16. Nov 2021 16:26

AW: Quick PDF-Library: Wie die Position des Annotationfensters ermitteln?
 
Zitat:

Zitat von ULIK (Beitrag 1497624)
Outlines: das wäre mir noch nie aufgefallen. Kannst Du mir da mal deinen Testcode schicken? Hab's grad in unsere Anwendung schnell ausprobiert, da hab ich kein Problem gehabt auch in der 6./7. Ebene

Danke, Dein Hinweis hat geholfen.
Du hast recht, das Problem war nicht in der Bib, sondern vor dem Bildschirm...


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz