The AppStudio AppFramework contains several components that provide access to standard and well-known system functions. While these components are not required to use these functions in your app, implementing the components should be considered when planning to use these functions.
Clipboard
By default, there is nothing preventing an AppStudio app from accessing the cut, copy, and paste functions of the system clipboard, and you don't need to write any code if this is your intention. For more complex workflows involving the clipboard, including copying items such as colors and JavaScript objects, the Clipboard
component provides more detailed access to the system clipboard.
The Clipboard
component contains multiple properties and methods for returning the contents of the system clipboard, depending on the type of data stored in it. The text
property returns the contents as a plain text string if possible, without formatting and potentially with visible HTML, depending on the clipboard contents.
TextArea {
id: textArea
Layout.fillWidth: true
Layout.fillHeight: true
text: AppFramework.clipboard.text
readOnly: true
}
The html
property, however, is primarily intended to read and display HTML content. This property is also capable of reading and retaining more complex text formatting, which the following code sample uses by attaching the property to a text area with rich text format enabled.
TextArea {
id: htmlTextArea
Layout.fillWidth: true
Layout.fillHeight: true
text: AppFramework.clipboard.html
textFormat: Text.RichText
readOnly: true
}
Color values are stored as an application/x-color MIME type and can only be written or returned by the color
property.
The Clipboard
component has no means to interact with images on the system clipboard (although, depending on the source, the text
property may return a URL). Instead, the Image
component provides the copy
and paste
methods for interaction.
Flow {
Layout.fillWidth: true
ImageObject {
id: imageObject
}
Button {
text: "Clear Image"
enabled: !imageObject.empty
onClicked: {
imageObject.clear();
}
}
Button {
text: "Copy"
enabled: !imageObject.empty
onClicked: {
imageObject.copyToClipboard();
}
}
Button {
text: "Paste"
enabled: imageObject.canPasteFromClipboard
onClicked: {
imageObject.pasteFromClipboard();
}
}
}
Sharing functionality
You can share text, URLs, or files to other apps using sharing functionality provided by AppFramework Clipboard. The Clipboard component's share
method is used to share any input text or URL. If sharing a file, the share
method needs you to provide the file location URL. The following code snippet shows how to use this method, sharing the text entered into a text field.
property url shareURL
TextField {
id: inputText
placeholderText: "Enter something to share"
}
Button {
text: "Share as text"
onClicked: {
AppFramework.clipboard.share(inputText.text)
}
}
Button {
text: "Share as Url"
onClicked: {
shareURL = inputText.text
AppFramework.clipboard.share(shareURL)
}
}
Currently, this functionality is only supported on macOS, iOS, and Android platforms.
For an example of this functionality in use, refer to the sample app available in ArcGIS AppStudio, or in the AppStudio samples GitHub repository.
Locale information
A locale is a standardized value describing a language or dialect, including details such as alphabet used, decimal markers, and date format. By using a valid locale code, you can override your system's default locale and provide a number of important ways information in your app will be displayed.
These locales can be passed on to the app through the use of the Locale
component, which contains properties to define a locale, as well as to map the locale consistently across standards and other sections of your app. In AppStudio, an example is to use Locale
to determine the language of an OAuth sign-in dialog box for ArcGIS Online. To do this, first instantiate Locale
, and inform it of both the initial locale and when the locale changes.
property string localeName
property string oauthUrlFormat: "https://www.arcgis.com/sharing/rest/oauth2/authorize?client_id=arcgisonline&redirect_uri=http://www.arcgis.com&response_type=token&locale=%1"
property url oauthUrl
Component.onCompleted: {
// Get the current Locale from the system's locale settings
localeName = Qt.locale().name;
}
LocaleInfo {
id: localeInfo
name: localeName
// update the properties and the OAuth page when the app Locale is changed
onLocaleChanged: {
localeInfoModel.update(localeInfo);
oauthUrl = oauthUrlFormat.arg(esriName);
if (oauthTab.item) {
oauthTab.item.url = oauthUrl;
}
}
}
To update the app's locale, add a text field to both display and edit the locale.
Text {
text: "Locale search"
}
// locale Name provided by the user for the app e.g. fr-Fr, en-GB, de_DE
TextField {
id: localeField
Layout.fillWidth: true
text: localeName
placeholderText: "Locale"
onEditingFinished: {
localeName = text;
}
function update(name) {
text = name;
editingFinished();
}
}
Since the other properties of Locale
won't be updated during synchronization, a function is needed to update them. For the purposes of this workflow, the function will also be in a list model that can be exposed in the UI.
// Model to list the properties associated with the LocaleInfo
ListModel {
id: localeInfoModel
// function to update the properties when the Locale is changed in the textbox
function update(localeInfo) {
clear();
add("name", localeInfo.name);
add("ietfName", localeInfo.ietfName);
add("esriName", localeInfo.esriName);
add("languageName", localeInfo.languageName);
add("languageCode", localeInfo.languageCode);
add("countryName", localeInfo.countryName);
add("countryCode", localeInfo.countryCode);
add("scriptName", localeInfo.scriptName);
add("scriptCode", localeInfo.scriptCode);
}
function add(name, value) {
append({
name: name,
value: value.toString()
});
}
}
After the list model is set up, you can add a web view to an OAuth sign-in, which will display in the locale declared in the earlier text field. In this case, the web view displays as part of a tab view alongside the list of Locale
properties above.
TabView {
Layout.fillWidth: true
Layout.fillHeight: true
Tab {
id: localeInfoTab
title: "LocaleInfo"
TableView {
model: localeInfoModel
TableViewColumn {
role: "name"
title: "Property"
}
TableViewColumn {
role: "value"
title: "Value"
}
}
}
Tab {
id: oauthTab
title: "Sign In Page"
WebView {
// Load the OAuth url in the webView.
Component.onCompleted: {
url = oauthUrl;
}
}
}
}
Be aware that controlling the locale code and changing your app's presentation depending on it are only part of the localization process. For more information, see Globalize your app.
URLs
To perform complex operations with URLs, the Url
component provides properties and methods for constructing and deconstructing URLs. These properties and methods can be used to dynamically construct a URL or derive individual components of one. The following section of code shows how to use Url
to extract the parameters of a query from a URL, in this case a feature service. Edits made to the extracted query when the sample app is run are then reassembled and presented as a new URL.
Column {
id: cl
width: parent.width
spacing: 5
UrlInfo {
id: urlInfo
}
Text {
text: "Your initial URL:"
wrapMode: Text.WrapAnywhere
width: parent.width
}
TextArea {
id: urlField
selectByMouse: true
cursorPosition: 1
wrapMode: "Wrap"
width: parent.width
font.pixelSize: 10
horizontalAlignment :TextInput.AlignLeft
text:"https://csmgisweb.smgov.net/csmgis01/rest/services/admin_boundaries/zoning/MapServer/0/query?objectIds=99,100&time=&geometry=&geometryType=esriGeometryPoint&inSR=&spatialRel=esriSpatialRelContains&f=html"
onTextChanged: {
urlInfo.fromUserInput(text);
}
}
CheckBox {
text: "<b>Is a query present?</b>"
checked: urlInfo.hasQuery
enabled: false
padding: 0
}
Text {
text: "<b>The query for your URL</b>: "
wrapMode: Text.WrapAnywhere
width: parent.width
}
Text {
text: "Edit the query, and the URL below it will update with your changes."
wrapMode: Text.WrapAnywhere
width: parent.width
}
TextArea {
id: queryField
text: JSON.stringify(urlInfo.queryParameters, undefined, 2)
wrapMode: Text.WrapAnywhere
width: parent.width
onTextChanged: {
urlInfo.queryParameters = JSON.parse(text);
}
}
Text {
text: "<b>Your URL with updated query:<b>"
wrapMode: Text.WrapAnywhere
width: parent.width
}
TextField {
id: reQueried
text: urlInfo.url
wrapMode: Text.WrapAnywhere
width: parent.width
}
}