Annotation Flags
Showcases annotation flags.
/* * Copyright © 2017-2026 PSPDFKit GmbH. All rights reserved. * * The PSPDFKit Sample applications are licensed with a modified BSD license. * Please see License for details. This notice may not be removed from this file. */
package com.pspdfkit.catalog.examples.kotlin
import android.content.Contextimport android.graphics.Colorimport android.graphics.drawable.Drawableimport android.net.Uriimport android.util.Logimport android.view.ContextMenuimport android.view.Menuimport android.view.MenuItemimport android.view.Viewimport androidx.core.content.ContextCompatimport com.pspdfkit.annotations.Annotationimport com.pspdfkit.annotations.AnnotationFlagsimport com.pspdfkit.annotations.AnnotationTypeimport com.pspdfkit.catalog.Rimport com.pspdfkit.catalog.SdkExampleimport com.pspdfkit.catalog.tasks.ExtractAssetTaskimport com.pspdfkit.catalog.ui.CustomAnnotationEditingToolbarGroupingRuleimport com.pspdfkit.configuration.activity.PdfActivityConfigurationimport com.pspdfkit.ui.PdfActivityimport com.pspdfkit.ui.PdfActivityIntentBuilderimport com.pspdfkit.ui.toolbar.AnnotationEditingToolbarimport com.pspdfkit.ui.toolbar.ContextualToolbarimport com.pspdfkit.ui.toolbar.ContextualToolbarMenuItemimport com.pspdfkit.ui.toolbar.ToolbarCoordinatorLayoutimport kotlinx.coroutines.CoroutineScopeimport kotlinx.coroutines.Dispatchersimport kotlinx.coroutines.launchimport java.util.EnumSet
/** * Shows how to use [com.pspdfkit.annotations.AnnotationFlags] to modify annotation * characteristics. */class AnnotationFlagsExample(context: Context) : SdkExample( context, R.string.annotationFlagsExampleTitle, R.string.annotationFlagsExampleDescription, ) { override fun launchExample(context: Context, configuration: PdfActivityConfiguration.Builder) { configuration // Turn off saving, so we have the clean original document every time the example is // launched. .autosaveEnabled(false) // Notes are treated as if they had the NOZOOM flag set by default. // We override this behavior here by enabling NOZOOM flag handling for note // annotations. .setEnableNoteAnnotationNoZoomHandling(true)
// Extract the document from the assets. ExtractAssetTask.extract(ANNOTATIONS_EXAMPLE, title, context) { documentFile -> // To start the AnnotationFlagsActivity create a launch intent using the // builder. val intent = PdfActivityIntentBuilder .fromUri(context, Uri.fromFile(documentFile)) .configuration(configuration.build()) .activityClass(AnnotationFlagsActivity::class.java) .build()
context.startActivity(intent) } }}
/** This example showcases supported [AnnotationFlags]. */class AnnotationFlagsActivity : PdfActivity(), ToolbarCoordinatorLayout.OnContextualToolbarLifecycleListener { override fun onPause() { super.onPause() setOnContextualToolbarLifecycleListener(null) }
override fun onResume() { super.onResume() setOnContextualToolbarLifecycleListener(this) }
override fun onCreateOptionsMenu(menu: Menu): Boolean { super.onCreateOptionsMenu(menu) menu.add(0, R.id.reset_all_flags, 0, "Reset All Flags") return true }
override fun onOptionsItemSelected(item: MenuItem): Boolean { if (item.itemId == R.id.reset_all_flags) { setFlagsOnAllAnnotations(EnumSet.of(AnnotationFlags.PRINT, AnnotationFlags.NOZOOM)) return true } return super.onOptionsItemSelected(item) }
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo?) { super.onCreateContextMenu(menu, v, menuInfo)
// In this example we handle only single annotation selection. val fragment = pdfFragment ?: return if (fragment.selectedAnnotations.size != 1) return val annotation = fragment.selectedAnnotations[0]
// Populate contextual menu. menuInflater.inflate(R.menu.flags_example, menu)
menu.findItem(R.id.toggle_read_only_flag).title = if (!annotation.hasFlag(AnnotationFlags.READONLY)) "Enable Read-Only Flag" else "Disable Read-Only Flag"
menu.findItem(R.id.toggle_hidden_flag).title = if (!annotation.hasFlag(AnnotationFlags.HIDDEN)) "Enable Hidden Flag" else "Disable Hidden Flag"
menu.findItem(R.id.toggle_print_flag).title = if (!annotation.hasFlag(AnnotationFlags.PRINT)) "Enable Print Flag" else "Disable Print Flag"
menu.findItem(R.id.toggle_no_view_flag).title = if (!annotation.hasFlag(AnnotationFlags.NOVIEW)) "Enable No-View Flag" else "Disable No-View Flag"
menu.findItem(R.id.toggle_locked_flag).title = if (!annotation.hasFlag(AnnotationFlags.LOCKED)) "Enable Locked Flag" else "Disable Locked Flag"
menu.findItem(R.id.toggle_locked_contents_flag).title = if (!annotation.hasFlag(AnnotationFlags.LOCKEDCONTENTS)) "Enable Locked-Contents Flag" else "Disable Locked-Contents Flag"
// No-zoom flag is supported only for Note, File and Stamp, and free-text annotations (but not callouts). val noZoomMenuItem = menu.findItem(R.id.toggle_no_zoom_flag) if (annotation.type == AnnotationType.NOTE || annotation.type == AnnotationType.FREETEXT || annotation.type == AnnotationType.FILE || annotation.type == AnnotationType.STAMP ) { noZoomMenuItem.isVisible = true noZoomMenuItem.title = if (!annotation.hasFlag(AnnotationFlags.NOZOOM)) "Enable No-Zoom Flag" else "Disable No-Zoom Flag" } else { noZoomMenuItem.isVisible = false } }
override fun onContextItemSelected(item: MenuItem): Boolean { // In this example we handle only single annotation selection. val fragment = pdfFragment ?: return super.onContextItemSelected(item) if (fragment.selectedAnnotations.size != 1) return super.onContextItemSelected(item) val annotation = fragment.selectedAnnotations[0]
return when (item.itemId) { R.id.reset_all_flags -> { annotation.flags = EnumSet.of(AnnotationFlags.PRINT, AnnotationFlags.NOZOOM) true }
R.id.toggle_read_only_flag -> { toggleAnnotationFlag(annotation, AnnotationFlags.READONLY) true }
R.id.toggle_hidden_flag -> { toggleAnnotationFlag(annotation, AnnotationFlags.HIDDEN) true }
R.id.toggle_print_flag -> { toggleAnnotationFlag(annotation, AnnotationFlags.PRINT) true }
R.id.toggle_no_view_flag -> { toggleAnnotationFlag(annotation, AnnotationFlags.NOVIEW) true }
R.id.toggle_locked_flag -> { toggleAnnotationFlag(annotation, AnnotationFlags.LOCKED) true }
R.id.toggle_locked_contents_flag -> { toggleAnnotationFlag(annotation, AnnotationFlags.LOCKEDCONTENTS) true }
R.id.toggle_no_zoom_flag -> { toggleAnnotationFlag(annotation, AnnotationFlags.NOZOOM) true }
else -> { super.onContextItemSelected(item) } } }
override fun onPrepareContextualToolbar(toolbar: ContextualToolbar<*>) { // Add item to annotation editing toolbar that will show our context menu for toggling flags // on selected annotation. if (toolbar is AnnotationEditingToolbar) { // In this example we handle only single annotation selection. val fragment = pdfFragment ?: return if (fragment.selectedAnnotations.size != 1) return
// Set custom grouping rule for our extended editing toolbar. toolbar.setMenuItemGroupingRule(CustomAnnotationEditingToolbarGroupingRule(this))
// Get the existing menu items so we can add our item later. val menuItems = toolbar.menuItems
// Create our custom menu item. val settingsDrawable: Drawable = ContextCompat.getDrawable(this, R.drawable.ic_settings) ?: return val customItem = ContextualToolbarMenuItem.createSingleItem( this, R.id.pspdf_menu_custom, settingsDrawable, "Annotation flags", Color.MAGENTA, Color.CYAN, ContextualToolbarMenuItem.Position.END, false, ) // Register it to for context menu. registerForContextMenu(customItem)
// Tell the toolbar about our new item. menuItems.add(customItem) toolbar.setMenuItems(menuItems)
// Add a listener so we can handle clicking on our item. toolbar.setOnMenuItemClickListener { _, menuItem -> if (menuItem.id == R.id.pspdf_menu_custom) { menuItem.showContextMenu() true } else { false } } } }
override fun onDisplayContextualToolbar(toolbar: ContextualToolbar<*>) {}
override fun onRemoveContextualToolbar(toolbar: ContextualToolbar<*>) {}
/** Sets/unsets [AnnotationFlags] on single annotation. */ private fun setFlagOnAnnotation(annotation: Annotation, flag: AnnotationFlags, isSet: Boolean) { val flags = annotation.flags if (isSet) { flags.add(flag) } else { flags.remove(flag) } annotation.flags = flags }
/** Set flags on all annotations in document. */ private fun setFlagsOnAllAnnotations(newFlags: EnumSet<AnnotationFlags>) { val doc = document ?: return
CoroutineScope(Dispatchers.Main).launch { try { val annotations = doc.annotationProvider.getAllAnnotationsOfType( EnumSet.allOf(AnnotationType::class.java), ) annotations.forEach { annotation -> annotation.flags = newFlags } } catch (e: Exception) { Log.e(LOG_TAG, "Failed to set flags on annotations", e) } } }
/** Toggles single annotation flag. */ private fun toggleAnnotationFlag(annotation: Annotation, flag: AnnotationFlags) { setFlagOnAnnotation(annotation, flag, !annotation.hasFlag(flag)) }
companion object { private const val LOG_TAG = "AnnotationFlagsActivity" }}This code sample is an example that illustrates how to use our SDK. Please adapt it to your specific use case.