Setting Text from QRC in QML TextArea - qt

I have a Qt Quick QML file with a TextArea that I would like have display text from a QRC resource. Other controls with images have a source member that can be set to load directly from a QRC QURL (see here) but TextArea must set the text directly. What is the most concise way in Qt 5.x to set the text value from a QRC resource? I would like
TextArea
{
text: LoadResource("qrc://messages.txt")
}
Another question here alludes to a simple process but the code is gone and now only shows how to use do it in C++.

You can use XMLHttpRequest to access local file and embedded resources but it requires QML_XHR_ALLOW_FILE_READ environment variable set to 1, e.g.
// in main.cpp
qputenv("QML_XHR_ALLOW_FILE_READ", QString("1").toUtf8());
Here's the XMLHttpRequest code snippet:
import QtQuick
import QtQuick.Controls
Page {
Frame {
width: parent.width
TextArea {
width: parent.width
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
TextLoader {
url: "messages.txt"
}
}
}
}
// TextLoader.qml
import QtQuick
Item {
id: textLoader
property var target: parent
property string property: "text"
property string url
onUrlChanged: Qt.callLater(load)
function load() {
if (!url) return;
let xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onreadystatechange = () => {
if (xhr.readyState !== 4) return;
if (xhr.status !== 0 && (xhr.status < 200 || xhr.status >= 400)) return;
target[property] = xhr.responseText;
}
xhr.send();
}
Component.onCompleted: Qt.callLater(load)
}
// messages.txt
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris scelerisque augue non magna consectetur pretium quis lobortis mi. Sed fermentum, turpis at molestie imperdiet, odio magna elementum libero, quis posuere lorem risus in libero. Nunc ullamcorper massa eget condimentum venenatis. Donec eget tempus leo, id gravida sem. Duis eget libero id lorem fringilla accumsan dictum sed purus. Pellentesque tristique velit at quam pharetra, in porta tortor hendrerit. In tristique imperdiet velit, ac hendrerit metus sagittis a. Fusce suscipit tellus volutpat, accumsan metus non, tempus sem.
You can Try it Online!

Related

How to set elements xy-position relative to selected text in another element?

Im trying to make a simple tooltip element in a textarea. The idea is, that the tooltip should show what is selected. My code so far is:
import React, { useRef, useState } from 'react';
const Contact = () => {
const myref = useRef();
const [tooltip, setTooltip] = useState('');
const handleMouseUp = (e) => {
if (window.getSelection().toString() !== '') {
myref.current.style.display = "inline-block";
myref.current.style.background = "black";
myref.current.style.color = "white";
setTooltip(window.getSelection().toString());
myref.current.style.top = e.clientY + "px";
myref.current.style.left = e.clientX + "px";
}
}
return (
<div className="contact">
<h2>Contact</h2>
<textarea
rows="10" cols="100"
onMouseUp={handleMouseUp}
value="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sit amet vestibulum odio. Morbi porttitor, ante fermentum condimentum porta, elit tellus blandit lorem, eu porttitor turpis lectus sed urna. Morbi semper, velit luctus finibus aliquam, orci orci commodo velit, ut ultrices ligula ex id nulla. Quisque enim leo, mollis a consectetur quis, vestibulum id eros. Integer non vehicula ligula. Nulla eu quam consectetur, elementum felis rutrum, lobortis dolor. Mauris laoreet egestas orci, at posuere odio sagittis sagittis. Sed consequat urna turpis, ut tincidunt nunc posuere sit amet. In dui leo, euismod et tempus sed, sodales vitae nisi. Nam faucibus aliquet condimentum. Curabitur scelerisque, quam in dignissim mattis, erat felis ultrices metus, et sagittis purus magna quis magna."
/>
<div ref={myref} style={{ display: 'none', position: 'absolute' }}>{tooltip}</div>
</div >
)
}
export default Contact;
But I cant make the tooltip position just under the selected text. Any ideas?
getBoundingClientRect seem to do the trick.
import React, { useRef, useState } from 'react';
const Contact = () => {
const myref = useRef();
const myref2 = useRef();
const [tooltip, setTooltip] = useState('');
const handleMouseUp = (e) => {
console.log(e.current);
if (window.getSelection().toString() !== '') {
myref.current.style.display = "inline-block";
myref.current.style.background = "black";
myref.current.style.color = "white";
setTooltip(window.getSelection().toString());
myref.current.style.left = (e.clientX - myref2.current.getBoundingClientRect().left) + "px";
myref.current.style.top = (e.clientY - myref2.current.getBoundingClientRect().top) + "px";
}
}
return (
<div className="contact" ref={myref2}>
<h2>Contact</h2>
<textarea
rows="10" cols="100"
// onMouseUp={handleMouseUp}
onChange={() => { }}
onMouseUp={handleMouseUp}
value="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sit amet vestibulum odio. Morbi porttitor, ante fermentum condimentum porta, elit tellus blandit lorem, eu porttitor turpis lectus sed urna. Morbi semper, velit luctus finibus aliquam, orci orci commodo velit, ut ultrices ligula ex id nulla. Quisque enim leo, mollis a consectetur quis, vestibulum id eros. Integer non vehicula ligula. Nulla eu quam consectetur, elementum felis rutrum, lobortis dolor. Mauris laoreet egestas orci, at posuere odio sagittis sagittis. Sed consequat urna turpis, ut tincidunt nunc posuere sit amet. In dui leo, euismod et tempus sed, sodales vitae nisi. Nam faucibus aliquet condimentum. Curabitur scelerisque, quam in dignissim mattis, erat felis ultrices metus, et sagittis purus magna quis magna."
/>
<div ref={myref} style={{ display: 'none', position: 'absolute' }}>{tooltip}</div>
</div >
)
}
export default Contact;

How would I use CSS to change style of element depending on browser language?

Basically, without changing the html if at all possible, I'd like to be able to write a CSS selector that when the browser language = 'ar-sa' or 'ar' it has direction: rtl otherwise it has direction: ltr?
I've found some stuff about language attributes in html, but I'm trying to do this entirely in CSS so I can avoid a site redeploy (I have a mechanism to dynamically drop in CSS)
You can use the :lang() pseudo-selector!
var html = document.documentElement;
var switcher = document.querySelector('#switch-lang');
html.setAttribute('lang', 'ar');
switcher.addEventListener('click', function(e) {
var languageSet = getLang() == 'ar' ? 'en' : 'ar';
html.removeAttribute('lang');
html.setAttribute('lang', languageSet);
});
function getLang() {
return html.getAttribute('lang');
}
html:lang('ar') {
direction: rtl;
}
<p>Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Sed posuere consectetur est at lobortis. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p>
<button id="switch-lang" type="button">Switch language</button>
You can not identify the browser language purely with CSS.
The lang attribute for the <html> tag and the dir (direction: ltr, rtl) attribute for the <body> tag can be used to configure the direction.
Example:
body[dir="ltr"] { direction: ltr; }
body[dir="rtl"] { direction: rtl; }

Qt5.7 QML QtQuick; How to build a scrollable and editable TextArea for Desktop & Android

Using QtQuick Controls.2, You can make a TextArea scrollable by putting it inside a Flickable, but then you cannot select text (because attempting to select initiates a scroll). However, if you make it selectByMouse, you can select, but then you cannot scroll.
How to do both?
Here is my example code:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQml 2.2
ApplicationWindow
{
visible: true
width: 640
height: 800
function makeText()
{
var s = "click here\n"
for (var i = 0; i < 10; ++i)
{
s +=
"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras at tempus felis. Nulla facilisi. Duis quam purus, posuere eu rutrum vel, blandit quis lorem. Cras vitae orci eget lorem luctus cursus quis nec nibh. Sed luctus ligula urna, vel commodo nisi finibus quis. Donec pretium eu purus a porttitor. Nam vehicula nunc quis dui gravida luctus. Morbi fermentum, elit nec ullamcorper accumsan, ex ligula iaculis nisi, id pretium ipsum metus quis quam. In lobortis dignissim semper. Aenean at neque lorem. Maecenas dapibus, arcu a condimentum consequat, mauris enim vehicula nibh, in fringilla quam nisi eu ipsum.</p>"
}
return s
}
Flickable
{
id: flickable
anchors.fill: parent
flickableDirection: Flickable.VerticalFlick
// place a TextArea inside the flickable, you can edit text
// but you cannot select because click & move mouse flicks the view.
TextArea.flickable: TextArea
{
id: textarea
wrapMode: TextArea.Wrap
font.pointSize: 16
textMargin: 16
textFormat: TextEdit.RichText
// can select but kills scrolling
//selectByMouse: true
text: Qt.platform.os + "\n" + makeText()
// try out links
onLinkActivated: Qt.openUrlExternally(link)
}
ScrollBar.vertical: ScrollBar { }
}
}
What would be the best way to go about this, and is there a stock answer (because there should be!).
I tried to implement an idea where you can perform a selection using PressAndHold. It, sort of, works but is fiddly. Is this a good idea? What would be the best practice here.
The other thing is that there is no popup cut&paste menu now for Controls.2, even for desktops it would appear.
Does this mean i have to implement:
A method to select over scroll
A cut & paste menu for desktop
A cut & paste menu for Android (wont have key shortcuts)
Selection handles for Android
Cursor point handle for Android
I'm rather surprised to discover that none of these are provided in a so-called, EditArea control!
Any recommendations here/reference implementations or suggestions.
BTW, 3,4 & 5 are also absent from Controls.1
project files: https://gist.github.com/anonymous/1ad94c9539fdc51d29258f6164f72487
thanks.
Unfortunately, proper text selection support through the Qt platform abstraction layer was not finished for Android in time for the Qt 5.7.0 release. In this area, iOS and Embedded Linux are better covered. Any progress on the Android side of things can be monitored via https://bugreports.qt.io/browse/QTBUG-34867.

last word of excerpt as a link

Does anybody know how to do this ? I would like to use last word of post excerpt as a link to it (post). Just like in text below:
Curabitur porttitor sem quis ipsum rutrum pharetra. Aliquam molestie justo eget nibh vulputate placerat. Etiam aliquet augue sit
solved :)
function excerpt_read_more_link($output) {
global $post;
$output_array=explode (' ',$output);
$count_words=count ($output_array);
$last_word=$output_array[$count_words-1];
for ($i=0; $i<$count_words-1;$i++)
{ $new_output.=$output_array[$i]." ";}
return $new_output . ''.$last_word.'';
}
add_filter('the_excerpt', 'excerpt_read_more_link');

Setting button text after it's been added to navigation bar in sencha touch 2

I am trying to change the text on a button after it's been added to navigationbar in the initialize method of the view. When debugging with Chrome however, it stops and gives the following message on Connection.js: Uncaught TypeError: Cannot read property 'readyState' of undefined. I thought this should be simple and am a bit confused! Here's my code:
Ext.define('EventsTest.view.NavTest', {
extend: 'Ext.navigation.View',
config: {
navigationBar: {
items: [
{
xtype: 'button',
text: 'Help',
id: 'favoritesHelp',
translate: true,
translationKey: 'navigationbar.helpbutton',
align: 'right'
}
]
},
items: [
{
xtype: 'container',
items: [
{
xtype: 'panel',
html: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vehicula tincidunt purus, a dignissim dui rutrum ut. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam pellentesque quam non orci porta sodales. Nulla laoreet varius libero, ac eleifend velit eleifend et. Proin a odio orci, sed bibendum libero. Maecenas eget nisl nec sapien sollicitudin mollis. Phasellus vel est eget risus ornare facilisis ac sed dui. Aliquam non feugiat sapien. In suscipit libero nec lorem lobortis molestie.'
},
{
xtype: 'button',
id: 'nextPage',
text: 'Next Page'
}
]
}
]
},
initialize: function() {
this.callParent();
this.setDefaultBackButtonText('reverse');
var helpBtn = this.getNavigationBar().query('#favoritesHelp');
helpBtn.text = 'Yello';
}
});
It's because your query is wrong. Try replace this 2 line:
var helpBtn = this.getNavigationBar().query('#favoritesHelp');
helpBtn.text = 'Yello';
with this:
var helpBtn = Ext.getCmp('favoritesHelp');
helpBtn.setText("Yellow");
Hope it helps :)
EDIT:
It's ok to keep your query like that but you need to remember that your query will retrieve an array of elements not a single element.
Besides that, you cannot change your text inside your button by using .text since it will not change the innerHTML of your button. Try using this:
var helpBtn = this.getNavigationBar().query('#favoritesHelp');
helpBtn[0].textElement.dom.innerHTML = "Yellow";
I think this is what you want....
config: {
listeners: {
initialize: function(){
this.down('button').setText('Whatever You Want')
}
}}

Resources