|
|
/***************************************************************************
|
|
|
objectnamelist.cpp - description
|
|
|
-------------------
|
|
|
begin : Mon Feb 18 2002
|
|
|
copyright : (C) 2002 by Thomas Kabelmann
|
|
|
email : tk78@gmx.de
|
|
|
***************************************************************************/
|
|
|
|
|
|
/***************************************************************************
|
|
|
* *
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
* (at your option) any later version. *
|
|
|
* *
|
|
|
***************************************************************************/
|
|
|
|
|
|
#include "objectnamelist.h"
|
|
|
#include "skyobjectname.h"
|
|
|
#include "skyobject.h"
|
|
|
#include "starobject.h"
|
|
|
|
|
|
#include <tqstring.h>
|
|
|
#include <kdebug.h>
|
|
|
|
|
|
ObjectNameList::ObjectNameList() {
|
|
|
amount = 0;
|
|
|
language = latin;
|
|
|
mode = allLists;
|
|
|
|
|
|
// delete just objects of local list
|
|
|
for (int i= 0; i< 27; i++) {
|
|
|
list[local][i].setAutoDelete(true);
|
|
|
unsorted[i] = false;
|
|
|
}
|
|
|
|
|
|
constellations.setAutoDelete(true);
|
|
|
}
|
|
|
|
|
|
ObjectNameList::~ObjectNameList(){
|
|
|
}
|
|
|
|
|
|
void ObjectNameList::setLanguage( Language lang ) {
|
|
|
language = lang;
|
|
|
}
|
|
|
|
|
|
void ObjectNameList::setLanguage( bool lang ) {
|
|
|
language = ( Language ) lang;
|
|
|
}
|
|
|
|
|
|
void ObjectNameList::setMode( Mode m ) {
|
|
|
mode = m;
|
|
|
}
|
|
|
|
|
|
void ObjectNameList::append( SkyObject *object, bool useLongName ) {
|
|
|
amount++;
|
|
|
// create name string and init with longname if forced by parameter else default name
|
|
|
TQString name = ( useLongName ) ? object->longname() : object->name();
|
|
|
|
|
|
//if star's name is it's genetive name, make sure we don't use the Greek charcter here
|
|
|
if ( object->type() == 0 && name == ((StarObject*)object)->gname() )
|
|
|
name = ((StarObject*)object)->gname( false );
|
|
|
|
|
|
// create string with translated name
|
|
|
TQString iName;
|
|
|
|
|
|
if ( object->type() == -1 ) { // constellation
|
|
|
iName = i18n( "Constellation name (optional)", name.local8Bit().data() );
|
|
|
}
|
|
|
else { // all other types
|
|
|
iName = i18n( name.local8Bit() );
|
|
|
}
|
|
|
|
|
|
// create SkyObjectName with translated name
|
|
|
SkyObjectName *soName = new SkyObjectName( iName, object );
|
|
|
// append in localized list
|
|
|
currentIndex = getIndex( name );
|
|
|
list[local] [currentIndex].append(soName);
|
|
|
|
|
|
// type == -1 -> constellation
|
|
|
if (object->type() == -1) {
|
|
|
// get latin name (default name)
|
|
|
iName = name;
|
|
|
// create new SkyObject with localized name
|
|
|
soName = new SkyObjectName(iName, object);
|
|
|
// to delete these objects store them in separate list
|
|
|
constellations.append(soName);
|
|
|
}
|
|
|
|
|
|
// append in latin list
|
|
|
currentIndex = getIndex(name);
|
|
|
list[latin][currentIndex].append(soName);
|
|
|
// set list unsorted
|
|
|
unsorted[currentIndex] = true;
|
|
|
}
|
|
|
|
|
|
SkyObjectName* ObjectNameList::first( const TQString &name ) {
|
|
|
sort();
|
|
|
SkyObjectName *soName = 0;
|
|
|
// set mode: string is empty set mode to all lists
|
|
|
name.isEmpty() ? setMode( allLists ) : setMode( oneList );
|
|
|
|
|
|
// start with first list in array
|
|
|
if ( mode == allLists ) {
|
|
|
currentIndex = 0;
|
|
|
} else {
|
|
|
// start with list which contains the first letter
|
|
|
currentIndex = getIndex( name );
|
|
|
}
|
|
|
|
|
|
soName = list[language][currentIndex].first();
|
|
|
|
|
|
//It's possible that there is no object that belongs to currentIndex
|
|
|
//If not, and mode==allLists, try the next index
|
|
|
while ( !soName && mode==allLists && currentIndex < 26 ) {
|
|
|
currentIndex++; // loop through the array
|
|
|
soName = list[language][currentIndex].first();
|
|
|
}
|
|
|
|
|
|
return soName;
|
|
|
}
|
|
|
|
|
|
SkyObjectName* ObjectNameList::next() {
|
|
|
SkyObjectName *soName = 0;
|
|
|
// get next SkyObjectName object
|
|
|
soName = list[ language ] [ currentIndex ].next();
|
|
|
|
|
|
// if all lists must checked and SkyObjectName is NULL
|
|
|
// check next available list in array and set to first element in list
|
|
|
// if currentIndex == 26 -> last index is reached
|
|
|
if ( mode==allLists && soName==0 && currentIndex<26 ) {
|
|
|
do {
|
|
|
currentIndex++; // loop through the array
|
|
|
soName = list[ language ] [ currentIndex ].first();
|
|
|
} while ( currentIndex<26 && soName==0 ); // break if currentIndex == 27 or soName is found
|
|
|
}
|
|
|
|
|
|
return soName;
|
|
|
}
|
|
|
|
|
|
int ObjectNameList::getIndex( const TQString &name ) {
|
|
|
// default index is 0 if object name starts with a number
|
|
|
int index = 0;
|
|
|
|
|
|
// if object name starts with a letter, so get index number between 1 and 26
|
|
|
if ( !name.isEmpty() ) {
|
|
|
TQChar firstLetter = name[0];
|
|
|
if ( firstLetter ) {
|
|
|
if ( firstLetter.isLetter() ) {
|
|
|
const unsigned char letter = (unsigned char) firstLetter.lower();
|
|
|
index = letter % 96; // a == 97 in ASCII code => 97 % 96 = 1
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
*Avoid invalid index due to non ASCII letters like "<22> etc. Add your own letters to put them in
|
|
|
*the right list (due to %96 index can't never get smaller than 0).
|
|
|
*/
|
|
|
if (index > 26) {
|
|
|
switch (index) {
|
|
|
case 41 : index = 5; break; // <20>= e
|
|
|
case 54 : index = 15; break; // <20>= o
|
|
|
default : index = 0; // all other letters
|
|
|
}
|
|
|
kdDebug() << k_funcinfo << "Object: " << name << " starts with non ASCII letter. Put it in list #" << index << endl;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return index;
|
|
|
}
|
|
|
|
|
|
void ObjectNameList::sort() {
|
|
|
for (int i=0; i<27; ++i) {
|
|
|
if (unsorted[i] == true) {
|
|
|
unsorted[i] = false;
|
|
|
list[latin][i].sort();
|
|
|
list[local][i].sort();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void ObjectNameList::remove ( const TQString &name ) {
|
|
|
setMode(oneList);
|
|
|
int index = getIndex(name);
|
|
|
SortedList <SkyObjectName> *l = &(list[language][index]);
|
|
|
|
|
|
SkyObjectName *son = find( name );
|
|
|
if ( son ) l->remove( son );
|
|
|
}
|
|
|
|
|
|
SkyObjectName* ObjectNameList::find(const TQString &name) {
|
|
|
sort();
|
|
|
if (name.isNull()) return 0;
|
|
|
// find works only in one list and not in all lists
|
|
|
setMode(oneList);
|
|
|
|
|
|
// items are stored translated (JH: Why? this whole class is confusing...)
|
|
|
TQString translatedName = i18n(name.utf8());
|
|
|
|
|
|
int index = getIndex(name);
|
|
|
|
|
|
// first item
|
|
|
int lower = 0;
|
|
|
SortedList <SkyObjectName> *l = &(list[language][index]);
|
|
|
// last item
|
|
|
int upper = l->count() - 1;
|
|
|
// break if list is empty
|
|
|
if (upper == -1) return 0;
|
|
|
|
|
|
int next;
|
|
|
|
|
|
// it's the "binary search" algorithm
|
|
|
SkyObjectName *o;
|
|
|
while (upper >= lower) {
|
|
|
next = (lower + upper) / 2;
|
|
|
o = l->at(next);
|
|
|
if (translatedName == o->text()) { return o; }
|
|
|
if (translatedName < o->text())
|
|
|
upper = next - 1;
|
|
|
else
|
|
|
lower = next + 1;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|