Commit 83430ff8 authored by Robert Lancaster's avatar Robert Lancaster Committed by Jasem Mutlaq

Here are some more improvements to the Whats Interesting panel.

This will download wikipedia info text box in addition to the description.
It can dynamically display the content in a tabbed pane or right next to each other depending on the width of the page. Both the descriptions and the info text are now saved after loaded the first time for easier loading later.
I also captured the wikipedia image from the info text box and added that to the list of images available in the thumbnail picker.  I also improved some of the layouts in whats interesting
parent 9c6c0c85
......@@ -10,7 +10,7 @@
***************************************************************************/
import QtQuick 2.5
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.2
import QtQuick.Controls 1.4
Rectangle {
id: container
......@@ -380,6 +380,7 @@ Rectangle {
id: dispSummary
objectName: dispObjSummary
text: dispObjSummary
textFormat: Text.RichText
x: image.width + 5
width: parent.width - image.width - 30
color: "#187988"
......@@ -462,20 +463,6 @@ Rectangle {
color: "#000000"
}
Image {
id: detailImg
height: 300
width:parent.width - 200
anchors{
right: parent.right
}
objectName: "detailImage"
property string refreshableSource
fillMode: Image.PreserveAspectFit
source: refreshableSource
}
Text {
id: soname
......@@ -499,7 +486,7 @@ Rectangle {
Text {
id: posText
objectName: "posTextObj"
y: 300
y: parent.height - 50
anchors{
right: parent.right
rightMargin: 10
......@@ -516,19 +503,27 @@ Rectangle {
}
}
TabView {
id: tabbedView
y: 170
width: parent.width
height: parent.height - 170 - 50
Tab {
title: "Object Information"
Rectangle {
id: descTextBox
y: 347
height: 200
height: parent.height
width: parent.width
color: "#010a14"
radius: 10
border.width: 0
anchors{
right: parent.right
rightMargin: 4
top: parent.top
left: parent.left
leftMargin: 4
right: parent.right
rightMargin: 4
}
border.color: "#585454"
......@@ -537,29 +532,34 @@ Rectangle {
clip: true
flickableDirection: Flickable.VerticalFlick
width: parent.width
height: parent.height
height: parent.height - 10
anchors{
top: parent.top
topMargin: 3
topMargin: 10
bottom: parent.bottom
bottomMargin: 4
left: parent.left
right: parent.right
}
contentWidth: parent.width
contentHeight: col.height + 4
Item {
id: descTextItem
anchors{
top: parent.top
topMargin: 3
left: parent.left
leftMargin: 6
right: parent.right
}
anchors.fill: parent
Column {
id: col
width: parent.width
Image {
id: detailImg
width:parent.width
anchors{
right: parent.right
}
objectName: "detailImage"
property string refreshableSource
fillMode: Image.PreserveAspectFit
source: refreshableSource
}
Text {
id: descText
objectName: "descTextObj"
......@@ -583,17 +583,118 @@ Rectangle {
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
width: parent.width
onLinkActivated: Qt.openUrlExternally(link)
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton // we don't want to eat clicks on the Text
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
font{
family: "Cantarell"
pixelSize: 13
italic: true
} //font
} //text
} //column
} //item
} //flickable
} //rectangle
} //tab
Tab {
id: infoBoxTab
title: "Wikipedia Infotext"
active: true
Rectangle {
id: descTextBox2
width: parent.width
height: (detailsViewContainer.width >= 600) ? parent.height - 10 - 50 : parent.height
color: "#010a14"
radius: 10
border.width: 0
states: [
State {
name: "outOfTab"
ParentChange { target: descTextBox2; parent: detailsView; x: detailsView.width/2; y: 10 }
PropertyChanges{target:tabbedView; currentIndex: 0}
PropertyChanges{target:tabbedView; tabsVisible: false}
PropertyChanges{target:tabbedView; width: detailsView.width / 2}
PropertyChanges{target:descTextBox2; width: detailsView.width / 2}
},
State {
name: "inTab"
ParentChange { target: descTextBox2; parent: infoBoxTab; x: 0; y: 0 }
}
]
onWidthChanged: (detailsViewContainer.width >= 600) ? descTextBox2.state = "outOfTab" : descTextBox2.state = "inTab"
anchors{
right: parent.right
rightMargin: 4
left: (detailsViewContainer.width >= 600) ? parent.horizontalCenter : parent.left
leftMargin: 4
}
border.color: "#585454"
Flickable {
id: flickableInfoText
clip: true
flickableDirection: Flickable.VerticalFlick
width: parent.width
height: parent.height - 10
anchors{
top: parent.top
topMargin: 10
bottom: parent.bottom
bottomMargin: 4
left: parent.left
right: parent.right
}
contentWidth: parent.width
contentHeight: col2.height + 4
Item {
id: descInfoTextItem
anchors{
top: parent.top
topMargin: 0
left: parent.left
leftMargin: 4
right: parent.right
rightMargin: 4
}
}
Column {
id: col2
width: parent.width
Text {
id: infoText
objectName: "infoBoxText"
textFormat: Text.RichText
color: "white"
onLinkActivated: Qt.openUrlExternally(link)
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton // we don't want to eat clicks on the Text
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
text: xi18n("\ntrying to Load from Wikipedia. . .")
clip: true
width: parent.width
font{
family: "Cantarell"
pixelSize: 13
} //font
} //text
} //column
} //item
} //flickable
} //rectangle
} //tab
} //tabview
Item {
id: nextObjRect
objectName: "nextObj"
......@@ -603,7 +704,7 @@ Rectangle {
right: parent.right
rightMargin: 10
bottom: parent.bottom
bottomMargin: 10
bottomMargin: 0
}
signal nextObjClicked
......@@ -677,7 +778,7 @@ Rectangle {
left: parent.left
leftMargin: 10
bottom: parent.bottom
bottomMargin: 10
bottomMargin: 0
}
signal prevObjClicked
......@@ -738,14 +839,15 @@ Rectangle {
Column {
id: detailItemsCol
x: 0
y: 100
x: 150
y: 80
width: parent.width
height: 93
spacing: 14
DetailsItem {
id: detailsText
textFormat: Text.RichText
objectName: "detailsTextObj"
}
......@@ -754,7 +856,7 @@ Rectangle {
Column {
id: detailsViewButtonsCol
y: 200
y: 50
anchors {
left: parent.left
leftMargin: 10
......@@ -768,7 +870,7 @@ Rectangle {
verticalAlignment: Text.AlignVCenter
color: "white"
text: xi18n("More object details")
text: xi18n("More Details")
font {
underline: true
family: "Cantarell"
......@@ -794,7 +896,7 @@ Rectangle {
verticalAlignment: Text.AlignVCenter
color: "white"
text: xi18n("Slew map to object")
text: xi18n("Center in Map")
font {
underline: true
family: "Cantarell"
......@@ -820,7 +922,7 @@ Rectangle {
verticalAlignment: Text.AlignVCenter
color: "white"
text: xi18n("Slew telescope to object")
text: xi18n("Slew Telescope")
font {
underline: true
family: "Cantarell"
......
......@@ -73,9 +73,9 @@ QVariant SkyObjItem::data(int role)
case DispNameRole:
return getLongName();
case DispImageRole:
return getImageURL();
return getImageURL(true);
case DispSummaryRole:
return getSummary();
return getSummary(true);
case CategoryRole:
return getType();
case CategoryNameRole:
......@@ -110,14 +110,23 @@ void SkyObjItem::setPosition(SkyObject * so)
m_Position = xi18n("Now visible: About %1 degrees above the %2 horizon", rounded_altitude, KSUtils::toDirectionString( sp.az() ) );
}
QString SkyObjItem::getImageURL() const
QString SkyObjItem::getImageURL(bool preferThumb) const
{
if ( m_Type==Star )
{
return "";
}
QString thumbName = KSPaths::locate(QStandardPaths::GenericDataLocation, "thumb-" + m_So->name().toLower().remove( ' ' ) + ".png" ) ;
QString fullSizeName = KSPaths::locate(QStandardPaths::GenericDataLocation, "Image_" + m_So->name().toLower().remove( ' ' ) + ".png" ) ;
QString fname = KSPaths::locate(QStandardPaths::GenericDataLocation, "image_" + m_So->name().toLower().remove( ' ' ) + ".png" ) ;
//First try to return the preferred file
if(thumbName!=""&&preferThumb)
return thumbName;
if(fullSizeName!=""&&(!preferThumb))
return fullSizeName;
//If that fails, try to return the large image first, then the thumb and then if it is a planet, the xplanet image.
QString fname = KSPaths::locate(QStandardPaths::GenericDataLocation, "Image_" + m_So->name().toLower().remove( ' ' ) + ".png" ) ;
if(fname=="")
fname = KSPaths::locate(QStandardPaths::GenericDataLocation, "thumb-" + m_So->name().toLower().remove( ' ' ) + ".png" ) ;
if(fname=="" && m_Type==Planet){
......@@ -128,9 +137,12 @@ QString SkyObjItem::getImageURL() const
}
QString SkyObjItem::getSummary() const
QString SkyObjItem::getSummary(bool includeDescription) const
{
return m_So->typeName()+"\n"+getRADE()+"\n"+getAltAz()+"\n";
if(includeDescription)
return m_So->typeName() + "<BR>" + getRADE() + "<BR>" + getAltAz()+"<BR><BR>" + loadObjectDescription();
else
return m_So->typeName() + "<BR>" + getRADE() + "<BR>" + getAltAz();
}
QString SkyObjItem::getDesc() const
......@@ -222,3 +234,22 @@ QString SkyObjItem::getSize() const
return QString(" --");
}
}
inline QString SkyObjItem::loadObjectDescription() const{
QFile file;
QString fname = "description-" + getName().toLower().remove( ' ' ) + ".html";
file.setFileName( KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + "descriptions/" + fname ) ; //determine filename in local user KDE directory tree.
if(file.exists())
{
if(file.open(QIODevice::ReadOnly))
{
QTextStream in(&file);
QString line;
line = in.readAll();
file.close();
return line;
}
}
return "";
}
......@@ -114,7 +114,7 @@ class SkyObjItem
*/
inline QString getRADE() const
{
return "RA: "+ m_So->ra().toHMSString() + "\nDE: " + m_So->ra().toDMSString();
return "RA: "+ m_So->ra().toHMSString() + "<BR>DE: " + m_So->ra().toDMSString();
}
/**
......@@ -135,14 +135,16 @@ class SkyObjItem
return m_So;
}
QString getImageURL() const;
QString getImageURL(bool preferThumb) const;
inline QString loadObjectDescription() const;
/**
* \brief Get Summary Description for the SkyObjItem.
* \return Summary Description for the SkyObjItem as a QString.
*/
QString getSummary() const;
QString getSummary(bool includeDescription) const;
/**
......@@ -194,6 +196,7 @@ class SkyObjItem
Type m_Type; ///Category of sky-object of type SkyObjItem::Type
SkyObject * m_So; ///Pointer to SkyObject represented by SkyObjItem
SkyObjDescription * skd; /// pointer to SkyObjDescription
};
#endif
......@@ -263,17 +263,21 @@ void WIView::loadDetailsView(SkyObjItem * soitem, int index)
QObject * detailImage = m_DetailsViewObj->findChild<QObject *>("detailImage");
QObject * descTextObj = m_DetailsViewObj->findChild<QObject *>("descTextObj");
QObject * descSrcTextObj = m_DetailsViewObj->findChild<QObject *>("descSrcTextObj");
QObject * infoBoxTextObj = m_DetailsViewObj->findChild<QObject *>("infoBoxText");
QObject * detailsTextObj = m_DetailsViewObj->findChild<QObject *>("detailsTextObj");
sonameObj->setProperty("text", soitem->getLongName());
posTextObj->setProperty("text", soitem->getPosition());
detailImage->setProperty("refreshableSource", soitem->getImageURL());
detailImage->setProperty("refreshableSource", soitem->getImageURL(false));
descTextObj->setProperty("text", soitem->getDesc());
if(soitem->getType() != SkyObjItem::Planet)
tryToLoadFromWikipedia(descTextObj, descSrcTextObj, soitem);
loadObjectDescription(descTextObj, descSrcTextObj, soitem);
infoBoxTextObj->setProperty("text", "trying to Load infoText box from Wikipedia. . .");
loadObjectInfoBox(infoBoxTextObj, soitem);
descSrcTextObj->setProperty("text", soitem->getDescSource());
QString summary=soitem->getSummary();
QString summary=soitem->getSummary(false);
QString magText;
if (soitem->getType() == SkyObjItem::Constellation)
......@@ -285,13 +289,13 @@ void WIView::loadDetailsView(SkyObjItem * soitem, int index)
QString sizeText = xi18n("Size: %1", soitem->getSize());
QString details = summary + "\n" + sbText + "\n" + magText + "\n" + sizeText;
QString details = summary + "<BR>" + sbText + "<BR>" + magText + "<BR>" + sizeText;
detailsTextObj->setProperty("text", details);
}
void WIView::tryToLoadFromWikipedia(QObject * descTextObj, QObject * descSrcTextObj, SkyObjItem * soitem)
void WIView::tryToLoadDescFromWikipedia(QObject * descTextObj, QObject * descSrcTextObj, SkyObjItem * soitem)
{
QString name;
if(soitem->getName().startsWith("M "))
......@@ -311,7 +315,7 @@ void WIView::tryToLoadFromWikipedia(QObject * descTextObj, QObject * descSrcText
QNetworkAccessManager * manager = new QNetworkAccessManager();
QNetworkReply * response = manager->get(QNetworkRequest(url));
connect(manager, &QNetworkAccessManager::finished, this, [descTextObj, descSrcTextObj, manager, response]{
connect(manager, &QNetworkAccessManager::finished, this, [soitem, this, descTextObj, descSrcTextObj, manager, response]{
response->deleteLater();
manager->deleteLater();
if (response->error() != QNetworkReply::NoError) return;
......@@ -333,7 +337,207 @@ void WIView::tryToLoadFromWikipedia(QObject * descTextObj, QObject * descSrcText
QString html="<HTML>" + result.mid(leftPos,rightPos) + "</HTML>";
QString srchtml="<HTML>Source: Wikipedia (<a href='" + result.mid(leftURL,rightURL) + "'>" + result.mid(leftURL,rightURL) + "</a>)</HTML>";
saveObjectText( soitem, "description", html);
descTextObj->setProperty("text", html);
descSrcTextObj->setProperty("text", srchtml);
});
}
void WIView::loadObjectDescription(QObject * descTextObj, QObject * descSrcTextObj, SkyObjItem * soitem){
QFile file;
QString fname = "description-" + soitem->getName().toLower().remove( ' ' ) + ".html";
file.setFileName( KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + "descriptions/" + fname ) ; //determine filename in local user KDE directory tree.
if(file.exists()){
if(file.open(QIODevice::ReadOnly)){
QTextStream in(&file);
QString line;
while ( !in.atEnd() )
{
line = in.readLine();
descTextObj->setProperty("text", line);
}
file.close();
}
}
else{
tryToLoadDescFromWikipedia(descTextObj, descSrcTextObj, soitem);
}
}
void WIView::loadObjectInfoBox(QObject * infoBoxText, SkyObjItem * soitem)
{
QFile file;
QString fname = "infoText-" + soitem->getName().toLower().remove( ' ' ) + ".html";
file.setFileName( KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + "descriptions/" + fname ) ; //determine filename in local user KDE directory tree.
if(file.exists())
{
if(file.open(QIODevice::ReadOnly))
{
QTextStream in(&file);
QString line;
while ( !in.atEnd() )
{
line = in.readAll();
infoBoxText->setProperty("text", line);
QTimer::singleShot(500, infoBoxText, SLOT(doLayout()));
}
file.close();
}
}
else
{
tryToLoadInfoBoxFromWikipedia(infoBoxText, soitem);
}
}
void WIView::tryToLoadInfoBoxFromWikipedia(QObject * infoBoxText, SkyObjItem * soitem)
{
QString name;
if(soitem->getName().toLower().startsWith("m "))
name = soitem->getName().replace("M ","Messier_").remove( ' ' );
else if(soitem->getName().toLower().startsWith("ngc"))
name = soitem->getName().toLower().replace("ngc","NGC_").remove( ' ' );
else if(soitem->getName().toLower().startsWith("ic"))
name = soitem->getName().toLower().replace("ic","IC_").remove( ' ' );
else if(soitem->getType() == SkyObjItem::Constellation)
name = soitem->getName().toLower().replace( " ", "+" ) + "_constellation";
else if(soitem->getType() == SkyObjItem::Star){
StarObject *star=dynamic_cast<StarObject*>(soitem->getSkyObject());
if(star)
name = star->gname().toLower().remove( ' ' ); //the greek name seems to give the most consistent search results.
else
name = soitem->getName().toLower().remove( ' ' );
}else
name = soitem->getName().toLower().remove( ' ' );
QUrl url("https://en.wikipedia.org/w/index.php?action=render&title="+ name + "&redirects");
QNetworkAccessManager * manager = new QNetworkAccessManager();
QNetworkReply * response = manager->get(QNetworkRequest(url));
connect(manager, &QNetworkAccessManager::finished, this, [infoBoxText, url, manager, response, soitem, this]{
if (response->error() != QNetworkReply::NoError) return;
QString result = QString::fromUtf8(response->readAll());
int leftPos=result.indexOf("<table class=\"infobox\"");
int rightPos=result.indexOf("</table>")-leftPos;
QString infoText=result.mid(leftPos,rightPos).replace("href=\"//","href=\"http://").replace("src=\"//","src=\"http://").replace("background:","color:black;background:").replace("background-color:","color:black;background:");
infoText.replace("style=\"width:22em\"","style=\"width:100%;border: 1px solid #a2a9b1;border-spacing: 3px;background-color: black;color: white;margin: 0.5em 0 0.5em 1em;padding: 0.2em;line-height: 1.5em;\"");
infoText=infoText + "<BR>(Source: <a href=" + url.url() + ">Wikipedia</a>)";
int leftImg=infoText.indexOf("src=\"")+5;
int rightImg=infoText.indexOf("\"",leftImg)-leftImg;
QString imgURL=infoText.mid(leftImg,rightImg);
saveImageURL( soitem, imgURL);
downloadWikipediaImage(soitem, imgURL);
QString html="<HTML><style type=text/css>a {text-decoration: none;color: yellow}</style><body><CENTER>" + infoText + "</CENTER></body></HTML>";
infoBoxText->setProperty("text", html);
saveObjectText( soitem, "infoText", html);
QTimer::singleShot(500, infoBoxText, SLOT(doLayout())); //This should make the image load after the html loads
response->deleteLater();
manager->deleteLater();
});
}
void WIView::saveObjectText(SkyObjItem * soitem, QString type, QString text){
QFile file;
QString fname = type + "-" + soitem->getName().toLower().remove( ' ' ) + ".html";
QDir writableDir;
QString filePath=KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + "descriptions";
writableDir.mkpath(filePath);
file.setFileName( filePath + "/" + fname ) ; //determine filename in local user KDE directory tree.
if(file.exists())
return;
if (file.open(QIODevice::WriteOnly) == false)
{
qDebug()<<"Image text cannot be saved for later. file save error";
return;
}
else
{
QTextStream stream( &file );
stream << text;
file.close();
}
}
void WIView::saveImageURL(SkyObjItem * soitem, QString imageURL){
QFile file;
file.setFileName( KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + "image_url.dat" ) ; //determine filename in local user KDE directory tree.
QString entry = soitem->getName() + ':' + "Show Wikipedia Image" + ':' + imageURL;
if(file.open(QIODevice::ReadOnly)){
QTextStream in(&file);
QString line;
while ( !in.atEnd() )