[Kstars-devel] [kstars] kstars: Geo data is now migrated to SQLite database and the UI was reworked to enable removal and updating of custom cities. Please test and check if this works.

Jasem Mutlaq mutlaqja at ikarustech.com
Mon Dec 15 16:28:11 UTC 2014


Git commit abd3167330d3acd7994ee24a61290936328dde09 by Jasem Mutlaq.
Committed on 15/12/2014 at 16:25.
Pushed by mutlaqja into branch 'master'.

Geo data is now migrated to SQLite database and the UI was reworked to enable removal and updating of custom cities. Please test and check if this works.
BUGS:341837
FIXED-IN:15.04
CCMAIL:kstars-devel at kde.org

M  +-    --    kstars/data/citydb.sqlite
M  +146  -51   kstars/dialogs/locationdialog.cpp
M  +10   -1    kstars/dialogs/locationdialog.ui
M  +8    -0    kstars/geolocation.h
M  +27   -23   kstars/kstarsdata.cpp
M  +1    -1    kstars/kstarsdata.h

http://commits.kde.org/kstars/abd3167330d3acd7994ee24a61290936328dde09

diff --git a/kstars/data/citydb.sqlite b/kstars/data/citydb.sqlite
index d3defbb..c75bdf2 100644
Binary files a/kstars/data/citydb.sqlite and b/kstars/data/citydb.sqlite differ
diff --git a/kstars/dialogs/locationdialog.cpp b/kstars/dialogs/locationdialog.cpp
index 7622372..b55dde0 100644
--- a/kstars/dialogs/locationdialog.cpp
+++ b/kstars/dialogs/locationdialog.cpp
@@ -42,6 +42,7 @@ LocationDialog::LocationDialog( QWidget* parent ) :
 {
     KStarsData* data = KStarsData::Instance();
 
+    SelectedCity = NULL;
     ld = new LocationDialogUI(this);
 
     QVBoxLayout *mainLayout = new QVBoxLayout;
@@ -66,6 +67,7 @@ LocationDialog::LocationDialog( QWidget* parent ) :
             ld->DSTRuleBox->addItem( key );
     }
 
+    ld->AddCityButton->setIcon(QIcon::fromTheme("list-add"));
     ld->RemoveButton->setIcon(QIcon::fromTheme("list-remove"));
     ld->UpdateButton->setIcon(QIcon::fromTheme("svn-update"));
 
@@ -286,69 +288,158 @@ bool LocationDialog::updateCity(CityOperation operation)
         KMessageBox::sorry( 0, message, xi18n( "Bad Coordinates" ) );
         return false;
     }
-    else
-    {
-        if ( !nameModified )
+
+    // If name is still the same then it's an update operation
+    if ( operation == CITY_ADD && !nameModified )
+        operation = CITY_UPDATE;
+
+        /*if ( !nameModified )
         {
             QString message = xi18n( "Really override original data for this city?" );
             if ( KMessageBox::questionYesNo( 0, message, xi18n( "Override Existing Data?" ), KGuiItem(xi18n("Override Data")), KGuiItem(xi18n("Do Not Override"))) == KMessageBox::No )
                 return false; //user answered No.
-        }
+        }*/
 
-        QString entry;
-        QFile file;
+        QSqlDatabase mycitydb = QSqlDatabase::database("mycitydb");
+        QString dbfile = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/"  +  "mycitydb.sqlite";
+
+        // If it doesn't exist, create it
+        if (QFile::exists(dbfile) == false)
+        {
+            mycitydb.setDatabaseName(dbfile);
+            mycitydb.open();
+            QSqlQuery create_query(mycitydb);
+            QString query("CREATE TABLE city ( "
+                          "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
+                          "Name TEXT DEFAULT NULL, "
+                          "Province TEXT DEFAULT NULL, "
+                          "Country TEXT DEFAULT NULL, "
+                          "Latitude TEXT DEFAULT NULL, "
+                          "Longitude TEXT DEFAULT NULL, "
+                          "TZ REAL DEFAULT NULL, "
+                          "TZRule TEXT DEFAULT NULL)");
+            if (create_query.exec(query) == false)
+            {
+                qWarning() << create_query.lastError() << endl;
+                return false;
+            }
+        }
+        else if (mycitydb.open() == false)
+        {
+            qWarning() << mycitydb.lastError() << endl;
+            return false;
+        }
 
         //Strip off white space
         QString name = ld->NewCityName->text().trimmed();
         QString province = ld->NewProvinceName->text().trimmed();
         QString country = ld->NewCountryName->text().trimmed();
+        QString TZrule = ld->DSTRuleBox->currentText();
+        GeoLocation *g = NULL;
 
-        //check for user's city database.  If it doesn't exist, create it.
-        file.setFileName( QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') + "mycities.dat" ) ; //determine filename in local user KDE directory tree.
+        switch (operation)
+        {
+            case CITY_ADD:
+            {
+                QSqlQuery add_query(mycitydb);
+                add_query.prepare("INSERT INTO city(Name, Province, Country, Latitude, Longitude, TZ, TZRule) VALUES(:Name, :Province, :Country, :Latitude, :Longitude, :TZ, :TZRule)");
+                add_query.bindValue(":Name", name);
+                add_query.bindValue(":Province", province);
+                add_query.bindValue(":Country", country);
+                add_query.bindValue(":Latitude", lat.toDMSString());
+                add_query.bindValue(":Longitude", lng.toDMSString());
+                add_query.bindValue(":TZ", TZ);
+                add_query.bindValue(":TZRule", TZrule);
+                if (add_query.exec() == false)
+                {
+                    qWarning() << add_query.lastError() << endl;
+                    return false;
+                }
 
-        if ( !file.open( QIODevice::ReadWrite | QIODevice::Append ) ) {
-            QString message = xi18n( "Local cities database could not be opened.\nLocation will not be recorded." );
-            KMessageBox::sorry( 0, message, xi18n( "Could Not Open File" ) );
-            return false;
-        } else {
-            char ltsgn = 'N'; if ( lat.degree()<0 ) ltsgn = 'S';
-            char lgsgn = 'E'; if ( lng.degree()<0 ) lgsgn = 'W';
-            QString TZrule = ld->DSTRuleBox->currentText();
-
-            entry = entry.sprintf( "%-32s : %-21s : %-21s : %2d : %2d : %2d : %c : %3d : %2d : %2d : %c : %5.1f : %2s\n",
-                                   name.toLocal8Bit().data(), province.toLocal8Bit().data(), country.toLocal8Bit().data(),
-                                   abs(lat.degree()), lat.arcmin(), lat.arcsec(), ltsgn,
-                                   abs(lng.degree()), lng.arcmin(), lat.arcsec(), lgsgn,
-                                   TZ, TZrule.toLocal8Bit().data() );
-
-            QTextStream stream( &file );
-            stream << entry;
-            file.close();
-
-            //Add city to geoList...don't need to insert it alphabetically, since we always sort GeoList
-            GeoLocation *g = new GeoLocation( lng, lat,
-                                              ld->NewCityName->text(), ld->NewProvinceName->text(), ld->NewCountryName->text(),
-                                              TZ, & KStarsData::Instance()->Rulebook[ TZrule ] );
-            // FIXME: Uses friendship
-            KStarsData::Instance()->getGeoList().append( g );
-
-            //(possibly) insert new city into GeoBox by running filterCity()
-            filterCity();
-
-            //Attempt to highlight new city in list
-            ld->GeoBox->setCurrentItem( 0 );
-            if ( ld->GeoBox->count() ) {
-                for ( int i=0; i<ld->GeoBox->count(); i++ ) {
-                    if ( ld->GeoBox->item(i)->text() == g->fullName() ) {
-                        ld->GeoBox->setCurrentRow( i );
-                        break;
-                    }
+                //Add city to geoList...don't need to insert it alphabetically, since we always sort GeoList
+                g = new GeoLocation( lng, lat, name, province, country, TZ, & KStarsData::Instance()->Rulebook[ TZrule ] );
+                KStarsData::Instance()->getGeoList().append(g);
+            }
+            break;
+
+            case CITY_UPDATE:
+            {
+
+                g = SelectedCity;
+
+                QSqlQuery update_query(mycitydb);
+                update_query.prepare("UPDATE city SET Name = :newName, Province = :newProvince, Country = :newCountry, Latitude = :Latitude, Longitude = :Longitude, TZ = :TZ, TZRule = :TZRule WHERE "
+                                  "Name = :Name AND Province = :Province AND Country = :Country");
+                update_query.bindValue(":newName", name);
+                update_query.bindValue(":newProvince", province);
+                update_query.bindValue(":newCountry", country);
+                update_query.bindValue(":Name", SelectedCity->name());
+                update_query.bindValue(":Province", SelectedCity->province());
+                update_query.bindValue(":Country", SelectedCity->country());
+                update_query.bindValue(":Latitude", lat.toDMSString());
+                update_query.bindValue(":Longitude", lng.toDMSString());
+                update_query.bindValue(":TZ", TZ);
+                update_query.bindValue(":TZRule", TZrule);
+                if (update_query.exec() == false)
+                {
+                    qWarning() << update_query.lastError() << endl;
+                    return false;
                 }
+
+                g->setName(name);
+                g->setProvince(province);
+                g->setCountry(country);
+                g->setLat(lat);
+                g->setLong(lng);
+                g->setTZ(TZ);
+                g->setTZRule(& KStarsData::Instance()->Rulebook[ TZrule ]);
+
             }
+            break;
+
+            case CITY_REMOVE:
+            {
+                g = SelectedCity;
+                QSqlQuery delete_query(mycitydb);
+                delete_query.prepare("DELETE FROM city WHERE Name = :Name AND Province = :Province AND Country = :Country");
+                delete_query.bindValue(":Name", name);
+                delete_query.bindValue(":Province", province);
+                delete_query.bindValue(":Country", country);
+                if (delete_query.exec() == false)
+                {
+                    qWarning() << delete_query.lastError() << endl;
+                    return false;
+                }
 
+                filteredCityList.removeOne(g);
+                KStarsData::Instance()->getGeoList().removeOne(g);
+                delete(g);
+                g=NULL;
+            }
+            break;
         }
-    }
-    return true;
+
+        //(possibly) insert new city into GeoBox by running filterCity()
+        filterCity();
+
+        //Attempt to highlight new city in list
+        ld->GeoBox->setCurrentItem( 0 );
+        if (g && ld->GeoBox->count() )
+        {
+            for ( int i=0; i<ld->GeoBox->count(); i++ )
+            {
+                if ( ld->GeoBox->item(i)->text() == g->fullName() )
+                {
+                    ld->GeoBox->setCurrentRow( i );
+                    break;
+                }
+            }
+        }
+
+        mycitydb.commit();
+        mycitydb.close();
+
+        return true;
 }
 
 void LocationDialog::findCitiesNear( int lng, int lat ) {
@@ -394,7 +485,8 @@ bool LocationDialog::checkLongLat() {
     return true;
 }
 
-void LocationDialog::clearFields() {
+void LocationDialog::clearFields()
+{
     ld->CityFilter->clear();
     ld->ProvinceFilter->clear();
     ld->CountryFilter->clear();
@@ -410,6 +502,7 @@ void LocationDialog::clearFields() {
     ld->AddCityButton->setEnabled( false );
     ld->UpdateButton->setEnabled( false );
     ld->NewCityName->setFocus();
+
 }
 
 void LocationDialog::showTZRules() {
@@ -479,12 +572,14 @@ void LocationDialog::nameChanged() {
 //do not enable Add button until all data are present and valid.
 void LocationDialog::dataChanged() {
     dataModified = true;
-    ld->AddCityButton->setEnabled( !ld->NewCityName->text().isEmpty() &&
+    ld->AddCityButton->setEnabled( nameModified && !ld->NewCityName->text().isEmpty() &&
                                    !ld->NewCountryName->text().isEmpty() &&
                                    checkLongLat() );
 
-    ld->UpdateButton->setEnabled(!ld->NewCityName->text().isEmpty() &&
-                                 !ld->NewCountryName->text().isEmpty() &&
+
+    if (SelectedCity)
+        ld->UpdateButton->setEnabled(SelectedCity->isReadOnly() == false && !ld->NewCityName->text().isEmpty()
+                                 && !ld->NewCountryName->text().isEmpty() &&
                                  checkLongLat());
 }
 
diff --git a/kstars/dialogs/locationdialog.ui b/kstars/dialogs/locationdialog.ui
index afcd5f6..1c2fee1 100644
--- a/kstars/dialogs/locationdialog.ui
+++ b/kstars/dialogs/locationdialog.ui
@@ -488,8 +488,17 @@
             <property name="enabled">
              <bool>false</bool>
             </property>
+            <property name="minimumSize">
+             <size>
+              <width>16</width>
+              <height>16</height>
+             </size>
+            </property>
+            <property name="toolTip">
+             <string>Add City</string>
+            </property>
             <property name="text">
-             <string>Add City to List</string>
+             <string/>
             </property>
            </widget>
           </item>
diff --git a/kstars/geolocation.h b/kstars/geolocation.h
index 0649e37..0f3d904 100644
--- a/kstars/geolocation.h
+++ b/kstars/geolocation.h
@@ -125,6 +125,14 @@ public:
     /**@return pointer to time zone rule object */
     TimeZoneRule* tzrule() { return TZrule; }
 
+    /**Set Time zone.
+     * @param value the new time zone */
+    void setTZ(double value)  { TimeZone = value;}
+
+    /**Set Time zone rule.
+     * @param value pointer to the new time zone rule */
+    void setTZRule(TimeZoneRule* value) { TZrule = value; }
+
     /**Set longitude according to dms argument.
      * @param l the new longitude */
     void setLong( dms l ) {
diff --git a/kstars/kstarsdata.cpp b/kstars/kstarsdata.cpp
index da231bf..ea6c190 100644
--- a/kstars/kstarsdata.cpp
+++ b/kstars/kstarsdata.cpp
@@ -378,32 +378,36 @@ bool KStarsData::readCityData()
 
     // Reading local database
     QSqlDatabase mycitydb = QSqlDatabase::addDatabase("QSQLITE", "mycitydb");
-    dbfile = QStandardPaths::locate(QStandardPaths::DataLocation, "mycitydb.sqlite");
-    mycitydb.setDatabaseName(dbfile);
-    if (mycitydb.open())
-    {
-        QSqlQuery get_query(mycitydb);
+    dbfile = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/"  +  "mycitydb.sqlite";
 
-        if (!get_query.exec("SELECT * FROM city"))
-        {
-            qDebug() << get_query.lastError();
-            return false;
-        }
-        while (get_query.next())
+    if (QFile::exists(dbfile))
+    {
+        mycitydb.setDatabaseName(dbfile);
+        if (mycitydb.open())
         {
-            QString name         = get_query.value(1).toString();
-            QString province     = get_query.value(2).toString();
-            QString country      = get_query.value(3).toString();
-            dms lat              = dms(get_query.value(4).toString());
-            dms lng              = dms(get_query.value(5).toString());
-            double TZ            = get_query.value(6).toDouble();
-            TimeZoneRule *TZrule = &( Rulebook[ get_query.value(7).toString() ] );
-
-            // appends city names to list
-            geoList.append ( new GeoLocation( lng, lat, name, province, country, TZ, TZrule, false));
-        }
-       mycitydb.close();
+            QSqlQuery get_query(mycitydb);
+
+            if (!get_query.exec("SELECT * FROM city"))
+            {
+                qDebug() << get_query.lastError();
+                return false;
+            }
+            while (get_query.next())
+            {
+                QString name         = get_query.value(1).toString();
+                QString province     = get_query.value(2).toString();
+                QString country      = get_query.value(3).toString();
+                dms lat              = dms(get_query.value(4).toString());
+                dms lng              = dms(get_query.value(5).toString());
+                double TZ            = get_query.value(6).toDouble();
+                TimeZoneRule *TZrule = &( Rulebook[ get_query.value(7).toString() ] );
+
+                // appends city names to list
+                geoList.append ( new GeoLocation( lng, lat, name, province, country, TZ, TZrule, false));
+            }
+           mycitydb.close();
 
+        }
     }
 
     return citiesFound;
diff --git a/kstars/kstarsdata.h b/kstars/kstarsdata.h
index 1564e7f..387b002 100644
--- a/kstars/kstarsdata.h
+++ b/kstars/kstarsdata.h
@@ -157,7 +157,7 @@ public:
     GeoLocation *geo() { return &m_Geo; }
 
     /** @return list of all geographic locations */
-    QList<GeoLocation*> getGeoList() { return geoList; }
+    QList<GeoLocation*> & getGeoList() { return geoList; }
 
     GeoLocation *locationNamed( const QString &city, const QString &province=QString(), const QString &country= QString() );
 


More information about the Kstars-devel mailing list