[dtrag-cvs] CVS: qanagram/src .cvsignore,NONE,1.1 Makefile.am,NONE,1.1 anagr.cpp,NONE,1.1 anagr.h,NO
Status: Beta
Brought to you by:
cstim
Update of /cvsroot/dtrag/qanagram/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5179/src Added Files: .cvsignore Makefile.am anagr.cpp anagr.h ancallback.h anlistview.cpp anlistview.h anlistviewitem.cpp anlistviewitem.h anstring.cpp anstring.h antmpstring.cpp antmpstring.h generalpage.cpp generalpage.h langstring.cpp langstring.h langstringabstract.cpp langstringabstract.h main.cpp myconfig.h qanagram.cpp qanagram.h qanagramwidget.cpp qanagramwidget.h wordlistview.cpp wordlistview.h wordlistviewitem.cpp wordlistviewitem.h xpms.h Log Message: Again import, now correctly --- NEW FILE: .cvsignore --- *.moc.cpp qanagram --- NEW FILE: Makefile.am --- # this 10 paths are KDE specific. Use them: # kde_htmldir Where your docs should go to. (contains lang subdirs) # kde_appsdir Where your application file (.kdelnk) should go to. # kde_icondir Where your icon should go to. # kde_sounddir Where system sounds should go to. # kde_datadir Where you install application data. (Use a subdir) # kde_locale Where translation files should go to.(contains lang subdirs) # kde_cgidir Where cgi-bin executables should go to. # kde_confdir Where config files should go to. # kde_mimedir Where mimetypes should go to. # kde_toolbardir Where general toolbar icons should go to. # kde_wallpaperdir Where general wallpapers should go to. # this is where the kdelnk file will go APPSDIR = $(kde_appsdir)/Utilities # set the include path for X, qt and KDE INCLUDES = $(qt3_includes) # this has all of the subdirectories that make will recurse into. if # there are none, comment this out SUBDIRS = doc pics # this is where the source documentation will be installed ### changed by chs SRCDOC_DEST=doc/src ####### This part is very qanagram specific # this is the program that gets installed bin_PROGRAMS = qanagram # Which sources should be compiled for qanagram. qanagram_SOURCES = qanagram.cpp qanagramwidget.cpp main.cpp \ anstring.cpp antmpstring.cpp anagr.cpp anlistview.cpp anlistviewitem.cpp \ wordlistview.cpp wordlistviewitem.cpp generalpage.cpp \ langstringabstract.cpp langstring.cpp # let automoc handle all of the meta source files (moc) qanagram_METASOURCES = USE_AUTOMOC ### changed by chs # the library search path. qanagram_LDFLAGS = $(all_libraries) $(QT_LDFLAGS) ### changed by chs # the libraries to link against. Be aware of the order. First the libraries, # that depend on the following ones. qanagram_LDADD = $(qt3_libs) # these are the headers for your project noinst_HEADERS = qanagram.h qanagramwidget.h anstring.h antmpstring.h anagr.h \ anlistview.h anlistviewitem.h wordlistview.h \ wordlistviewitem.h generalpage.h ancallback.h \ langstringabstract.h langstring.h myconfig.h xpms.h nodist_qanagram_SOURCES = anlistview.moc.cpp \ anlistviewitem.moc.cpp \ generalpage.moc.cpp \ qanagram.moc.cpp \ qanagramwidget.moc.cpp \ wordlistview.moc.cpp \ wordlistviewitem.moc.cpp %.moc.cpp: %.h $(qt3_moc) -o $@ $< SUFFIXES = .moc.cpp # if you "make distclean", this files get removed. If you want to remove # them while "make clean", use CLEANFILES CLEANFILES = $(qanagram_METASOURCES) $(nodist_qanagram_SOURCES) # make messages.po. Move this one to ../po/ and "make merge" in po # the -x is for skipping messages already translated in kdelibs messages: $(XGETTEXT) -C -ki18n -x $(includedir)/kde.pot $(qanagram_SOURCES) && mv messages.po ../po/qanagram.pot # generate source documentation srcdoc: $(mkinstalldirs) $(SRCDOC_DEST) kdoc -H -d $(SRCDOC_DEST) qanagram $(noinst_HEADERS) -lqt # just install datas here. Use install-exec-local for scripts and etc. # the binary itself is already installed from automake # use mkinstalldirs, not "install -d" # don't install a list of file. Just one file per install. # if you have more of them, create a subdirectory with an extra Makefile install-data-local: $(mkinstalldirs) $(APPSDIR) $(INSTALL_DATA) qanagram.kdelnk $(APPSDIR) $(mkinstalldirs) $(kde_icondir) $(INSTALL_DATA) qanagram.xpm $(kde_icondir) $(mkinstalldirs) $(kde_minidir) $(INSTALL_DATA) mini-qanagram.xpm $(kde_minidir)/qanagram.xpm # remove ALL you have installed in install-data-local or install-exec-local uninstall-local: -rm -f $(APPSDIR)/qanagram.kdelnk -rm -f $(kde_icondir)/qanagram.xpm -rm -f $(kde_minidir)/qanagram.xpm --- NEW FILE: anagr.cpp --- /* anagr.cpp QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ #include <anagr.h> Anagr::Anagr() : LangStringAbstractList() { unread=TRUE; marked=FALSE; } Anagr::Anagr(LangStringAbstract *s) : LangStringAbstractList() { push_back(s); unread=TRUE; marked=FALSE; } Anagr::~Anagr() {} QTextStream & operator<< (QTextStream & s, Anagr & a) { // simply write each word in latin-1-characters, delimit each word // by a whitespace, force an end-of-line afterwards const char *c; for( LangStringAbstractListIter iter = a.begin(); iter != a.end() ; iter++ ) { c = (*iter)->latin1(); s << c << " "; }; return s << endl; }; int Anagr::getWorth() { int i=0; for(LangStringAbstractListIter str = begin(); str != end(); str++ ) i += (*str)->getWorth() * (*str)->length(); return i; }; void Anagr::setUnread(bool b) { unread=b; } void Anagr::setMarked(bool b) { marked=b; } --- NEW FILE: anagr.h --- #ifndef ANAGR_H #define ANAGR_H #ifdef HAVE_CONFIG_H #include <config.h> #endif /* anagr.h QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ class Anagr; #include <qtextstream.h> #include "langstringabstract.h" /** A class that represents an anagram. It is a list of words, a list of AnString's. */ class Anagr : public LangStringAbstractList { /** Writes an anagram to a text stream. */ friend QTextStream & operator<< (QTextStream & s, Anagr & a); public: /** default constructor */ Anagr(); /** Constructor which takes the first AnString which belongs to the anagram. */ Anagr(LangStringAbstract *); /** Default destructor. */ virtual ~Anagr(); /** True, if this anagram hasn't been read. */ bool getUnread() { return unread; }; /** True, if the user has marked this anagram. */ bool getMarked() { return marked; }; /** Allows to set the value of getUnread(). */ void setUnread(bool b); /** Allows to set the value of getMarked(). */ void setMarked(bool b); /** Returns the worth which was calculated from the word's values. This value is calculated on-the-fly. */ int getWorth(); inline void append( LangStringAbstract *a) { push_back( a ); }; inline LangStringAbstract * at( uint i ) { return operator[]( i ); }; inline uint count() { return size(); }; private: bool marked; bool unread; }; #endif // ANAGR_H --- NEW FILE: ancallback.h --- #ifndef ANCALLBACK_H #define ANCALLBACK_H #ifdef HAVE_CONFIG_H #include <config.h> #endif /* ancallback.h QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ #include "anagr.h" /** @short Callback function interface for a new anagram This is the interface which contains the callback function which is to be called each time a new anagram is found. */ class AnCallback { public: /** This abstract function is called from within AnString each time a new anagram is found. */ virtual void newAnagr( Anagr *a ) = 0; }; #endif // ANCALLBACK_H --- NEW FILE: anlistview.cpp --- /* anlistview.cpp QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ #include <anlistview.h> #include "xpms.h" const int AnListView::worthZeroIndex=100; AnListView::AnListView(QWidget *parent, int numberWordColumns, const char *name) : QListView(parent, name) { pm_read = new QPixmap(read_xpm); pm_unread = new QPixmap(unread_xpm); pm_unmarked = pm_read; pm_marked = new QPixmap(marked_xpm); // watch out that the column order fits with the column constants // in AnListView!!!! addColumn(*pm_unread, ""); addColumn("Wert"); addColumn(*pm_marked, ""); for (int i=0; i<numberWordColumns; i++) addColumn("Wort"); setSorting(AnListViewItem::worthColumn, TRUE); // focus is shown in all columns setAllColumnsShowFocus(TRUE); // if the focus in the list view has changed, our appropriate slot // should be called. connect(this, SIGNAL(currentChanged(QListViewItem *)), SLOT(mySelection(QListViewItem *)) ); connect(this, SIGNAL(returnPressed(QListViewItem *)), SLOT(returnPressed(QListViewItem *)) ); connect(this, SIGNAL(rightButtonPressed(QListViewItem *, const QPoint &, int)), SLOT(rightClickOnItem(QListViewItem *, const QPoint &, int)) ); valuePopupMenu = new QPopupMenu(this); valuePopupMenu->insertItem( "5", worthZeroIndex+5 ); valuePopupMenu->insertItem( "4", worthZeroIndex+4 ); valuePopupMenu->insertItem( "3", worthZeroIndex+3 ); valuePopupMenu->insertItem( "2", worthZeroIndex+2 ); valuePopupMenu->insertItem( "1", worthZeroIndex+1 ); valuePopupMenu->insertItem( "0", worthZeroIndex ); valuePopupMenu->insertItem( "-1", worthZeroIndex-1 ); valuePopupMenu->insertItem( "-2", worthZeroIndex-2 ); valuePopupMenu->insertItem( "-3", worthZeroIndex-3 ); valuePopupMenu->insertItem( "-4", worthZeroIndex-4 ); valuePopupMenu->insertItem( "-5", worthZeroIndex-5 ); } AnListView::~AnListView() { } void AnListView::disableSorting() { setSorting(-1); } void AnListView::enableSorting() { // sort after the last set column. setSorting(sortColumn, TRUE); } void AnListView::newAnagr(Anagr *a) { new AnListViewItem( a, this); } void AnListView::mySelection(QListViewItem *i) { if (i!=0l) ((AnListViewItem *)i)->anagr->setUnread(FALSE); } void AnListView::deleteAnList() { this->clear(); } void AnListView::rightClickOnItem(QListViewItem *it, const QPoint &p, int col) { if (!it) return; setSelected(it, TRUE); AnListViewItem *item= (AnListViewItem *)it; if ( (col >= AnListViewItem::firstWordColumn) && (col < AnListViewItem::firstWordColumn + (int)item->anagr->count() ) ) { QRect myrect = itemRect(item); QHeader *h = header(); int colPos=0; for ( int i=0; i<h->mapToActual(col); i++) colPos+=h->cellSize(i); int result = valuePopupMenu-> exec(mapToGlobal(myrect.bottomLeft() + QPoint(colPos,0)), valuePopupMenu-> indexOf( worthZeroIndex + item->anagr-> at(col - AnListViewItem::firstWordColumn)->getWorth() ) ); if (result>0) item->anagr-> at(col - AnListViewItem::firstWordColumn)-> setWorth(result - worthZeroIndex); triggerUpdate(); }; } void AnListView::returnPressed(QListViewItem *it) { if (!it) return; AnListViewItem *i= (AnListViewItem *)it; // return pressed on any item? toggle the marker. i->anagr->setMarked( !i->anagr->getMarked() ); triggerUpdate(); } void AnListView::setSorting ( int column, bool increasing ) { sortColumn = column; QListView::setSorting( column, increasing ); } void AnListView::contentsMousePressEvent( QMouseEvent * e ) { // all copied from qlistview.cpp, lines 2552 following if (!e) return; QPoint vp = contentsToViewport(e->pos()); QHeader *h = header(); AnListViewItem * i; if ( viewport()->rect().contains( vp ) ) i = (AnListViewItem *) itemAt( vp ); else i = (AnListViewItem *) selectedItem(); if (i) { int c = h->mapToLogical( h->cellAt( vp.x() ) ); if (c==AnListViewItem::unreadColumn) { // any button pressed on unread column? toggle the marker. i->anagr->setUnread( !i->anagr->getUnread() ); triggerUpdate(); } else if (c==AnListViewItem::markedColumn) { // any button pressed on mark column? toggle the marker. i->anagr->setMarked( !i->anagr->getMarked() ); triggerUpdate(); }; }; QListView::contentsMousePressEvent( e ); } --- NEW FILE: anlistview.h --- #ifndef ANLISTVIEW_H #define ANLISTVIEW_H #ifdef HAVE_CONFIG_H #include <config.h> #endif /* anlistview.h QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ class AnListView; //#include <kapp.h> #include <qwidget.h> #include <qlistview.h> #include <qfile.h> #include <qdatastream.h> #include <qmessagebox.h> #include <qpopupmenu.h> #include <qheader.h> //#include <qmouseevent.h> #include "anlistviewitem.h" #include "ancallback.h" /** Shows the list of all resulted anagrams. Derived from Qt's QListView. Each anagram is shown by an AnListViewItem object. */ class AnListView : public QListView, public AnCallback { Q_OBJECT friend class AnListViewItem; public: /** Default constructor */ AnListView(QWidget *parent = 0, int numberWordColumns = 4, const char *name = 0); /** Default destructor */ virtual ~AnListView(); /** Set the list view to be sorted by column. Different from the original implementation the bool parameter is simply ignored! Sorting happens only ascending. If column is -1, sorting is disabled. */ virtual void setSorting ( int column, bool increasing = TRUE ); /** Inserts a new anagram. A new AnListViewItem will be created each time this method is called. This is the implementation for the method defined in the interface AnCallback. */ virtual void newAnagr(Anagr *a); public slots: /** Ought to be called each time a new item is selected. It (the given item) will then be marked as *read*. */ void mySelection(QListViewItem *); /** Cleans this anagram list, i.e. calls clean(), i.e. deletes all the items. */ void deleteAnList(); /** Guess what this one does. */ void disableSorting(); void enableSorting(); /** This is to be called when the right button is pressed. The arguments are the relevant QListViewItem (may be 0), the point in global coordinates and the relevant column. */ void rightClickOnItem(QListViewItem *, const QPoint &, int); /** To be called when return was pressed during an item was selected. */ void returnPressed(QListViewItem *); protected: /** Processes mouse move events on behalf of the viewed widget. Reimplemented from @ref QListView. */ virtual void contentsMousePressEvent ( QMouseEvent * e ); private: /** These are the pixmaps which are to appear in the items, for the corresponding states... */ QPixmap *pm_read; QPixmap *pm_unread; QPixmap *pm_marked; QPixmap *pm_unmarked; /** The popup menu which is used to change one word's worthvalue. */ QPopupMenu *valuePopupMenu; /** Needed for the implementation of the popup menu. */ static const int worthZeroIndex; /** The column number this list is sorted after. */ int sortColumn; }; #endif // ANLISTVIEW_H --- NEW FILE: anlistviewitem.cpp --- /* anlistviewitem.cpp QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ #include <anlistviewitem.h> const int AnListViewItem::unreadColumn=0; const int AnListViewItem::worthColumn=1; const int AnListViewItem::markedColumn=2; const int AnListViewItem::firstWordColumn=3; AnListViewItem::AnListViewItem(AnListView * parent) : QListViewItem(parent) {} AnListViewItem::AnListViewItem(Anagr * a, AnListView * parent) : QListViewItem(parent) { anagr=a; pm_unread=parent->pm_unread; pm_read=parent->pm_read; pm_unmarked=parent->pm_unmarked; pm_marked=parent->pm_marked; } AnListViewItem::~AnListViewItem() { delete anagr; } QString AnListViewItem::key(int column, bool ascending) const { switch (column) { case unreadColumn : // unread anagrams to be shown before read ones return anagr->getUnread() ? QString("a") : QString("b"); case worthColumn : { return QString( QChar(128 - anagr->getWorth()) ); case markedColumn : // marked anagrams to be shown before unmarked ones return anagr->getMarked() ? QString("a") : QString("b"); } default: tmpString.setNum(anagr->count() ); tmpString.append( (char)(128 - anagr->getWorth()) ); tmpString.append(text(column)); return tmpString; }; }; QString AnListViewItem::tmpString=QString(); QString AnListViewItem::text(int column) const { if (anagr!=0l) switch (column) { case unreadColumn : return ""; case worthColumn : { tmpString.setNum(anagr->getWorth() ); return tmpString; } case markedColumn : return ""; default: if ( (int)anagr->count() > column - firstWordColumn) return *(anagr->at(column - firstWordColumn)); else return ""; } else return QString(); }; const QPixmap * AnListViewItem::pixmap( int col ) const { if (anagr!=0l) switch (col) { case unreadColumn : return (anagr->getUnread() ) ? pm_unread : pm_read; case markedColumn : return (anagr->getMarked() ) ? pm_marked : pm_unmarked; default: return 0l; } else return 0l; } // void // AnListViewItem::startDragging() // { // QString result; // for (LangStringAbstractListIter i = anagr->begin(); // i != anagr->end() ; i++ ) // result+=" "+*(*i); // QDragObject *d = new QTextDrag( result ); // d->dragCopy(); // // do NOT delete d. // } --- NEW FILE: anlistviewitem.h --- #ifndef ANLISTVIEWITEM_H #define ANLISTVIEWITEM_H #ifdef HAVE_CONFIG_H #include <config.h> #endif /* anlistviewitem.h QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ #include <qlistview.h> #include <qmessagebox.h> #include <qpixmap.h> //#include <qdragobject.h> #include "anlistview.h" #include "anagr.h" /** The items which show a single anagram in the AnListView. Here it is defined how they are shown... */ class AnListViewItem : public QListViewItem { //Q_OBJECT friend class AnListView; public: /** Default Constructor */ AnListViewItem(AnListView *parent = 0); /** Constructor which already gets the anagram which this item should show. */ AnListViewItem(Anagr *a, AnListView *parent = 0); /** default destructor */ virtual ~AnListViewItem(); /** Returns a key that can be used for sorting by column column. Overrides the default implementation...*/ virtual QString key( int column, bool ascending=FALSE ) const; /** Returns the text which belongs to column column - this is not necessarily an existing QString, e.g. the worth-value will be converted on-the-fly to a string. */ virtual QString text( int column ) const; /** Returns a pointer to the pixmap for column, or a null pointer if there is no pixmap for column. */ virtual const QPixmap * pixmap( int ) const; /** Is this anagram marked? */ bool getMarked() { return anagr->getMarked(); }; /** Returns a pointer to the anagram this Item shows. */ Anagr * getAnagr() { return anagr; }; // public slots: //void startDragging(); private: /** The anagram this item should show. */ Anagr *anagr; /** This constant is the index of the column which shows the first word. The other constants are the indexes of the corresponding columns. */ static const int firstWordColumn; static const int unreadColumn; static const int worthColumn; static const int markedColumn; /** a temporary string when a numeric value is returned by key(). */ static QString tmpString; const QPixmap *pm_unread; const QPixmap *pm_read; const QPixmap *pm_unmarked; const QPixmap *pm_marked; }; #endif // ANLISTVIEWITEM_H --- NEW FILE: anstring.cpp --- /* anstring.cpp QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ #include <anstring.h> AnString::AnString() : LangString() { myCharString = new AnTmpString(); } AnString::AnString( const QString s ): LangString(s) { myCharString = new AnTmpString( charString ); } AnString::~AnString() { delete myCharString; } void AnString::runAnagrs( LangStringList *dict, AnCallback *p, int recursLeft, int minRecurs, long int linesLeft) { // build one of these temporary strings from the 8bit representation // call the derived method from AnAbstract myCharString->anagrs( dict->begin(), dict->end(), p, recursLeft, minRecurs, linesLeft); }; bool AnString::inString( const LangString * check ) { return myCharString->inString( check ); }; --- NEW FILE: anstring.h --- #ifndef ANSTRING_H #define ANSTRING_H #ifdef HAVE_CONFIG_H #include <config.h> #endif /* anstring.h QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ #include <qlist.h> #include "langstring.h" #include "ancallback.h" #include "antmpstring.h" /** @short The representation of the search word The Searchword is one single real language's word, so it *is* an LangWord which lead me to deriving it from LangWord. The only addition is that it provides the method runAnagrs() which invokes the anagram search for this word. */ class AnString : public LangString { // for access to the charString; friend class AnTmpString; public: /** Constructs a null string. */ AnString(); /** Constructs an implicitly-shared copy of s. */ AnString( const QString s ); virtual ~AnString(); /** Searches for all the anagrams which can be built from this string. This ought to be called in a seperate thread. Each new Anagram calls the function newAnagr() in the AnCallback object *p. It recursivly calls the method @ref anagrs () which is derived from class AnAbstract. @param dict Iterator for the Wordlist from the dictionary. The iterator is left unchanged. @param p The callback object in which the method newAnagr() is to be called. @param recursLeft That many words may appear in the anagram as maximum. @param minRecurs That many word should appear in the anagram as minimum. @param linesLeft Go on only for that many anagrams in total. */ void runAnagrs( LangStringList *dict, AnCallback *p, int recursLeft=0, int minRecurs=0, long int linesLeft=0); /** checks the characters of *check whether they can be found in this object. Returns FALSE if not all letters in *check appear in this object. */ bool inString( const LangString * check); protected: AnTmpString * myCharString; }; #endif // ANSTRING_H --- NEW FILE: antmpstring.cpp --- /* antmpstring.cpp QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ #include "antmpstring.h" #include <time.h> long int AnTmpString::prof1=0; long int AnTmpString::prof2=0; long int AnTmpString::prof3=0; long int AnTmpString::prof4=0; long int AnTmpString::prof5=0; long int AnTmpString::prof6=0; long int AnTmpString::prof7=0; long int AnTmpString::prof8=0; long int AnTmpString::prof9=0; long int AnTmpString::prof10=0; char * AnTmpString::profileInfo() { QCString a(255); // a.sprintf("1:%ld; 2:%ld; 3:%ld; 4:%ld; 5:%ld; 6:%ld; 7:%ld; 8:%ld; 9:%ld; 10:%ld;", // prof1, prof2, prof3, prof4, prof5, prof6, prof7, prof8, // prof9, prof10); a.sprintf("1:%ld; 2:%ld; 3:%ld; 8: %ld; 9:%ld; 10:%ld; 4:%.2lf; 5:%.2lf; 6:%.2lf; 7:%.2lf;", prof1, prof2, prof3, prof8, prof9, prof10, ((double)prof4)/CLOCKS_PER_SEC, ((double)prof5)/CLOCKS_PER_SEC, ((double)prof6)/CLOCKS_PER_SEC, ((double)prof7)/CLOCKS_PER_SEC); return a.data(); }; char AnTmpString::rest_CharBuf[128]; AnTmpString::AnTmpString() : QCString() { // AFAIK this one is not used } AnTmpString::AnTmpString( const QString s ): QCString(s.latin1()) { // AFAIK this one is not used buildMyIntMask(); } AnTmpString::AnTmpString( const QCString &s ): QCString(s) { // AFAIK this one is not used buildMyIntMask(); } AnTmpString::AnTmpString( const char *str ): QCString(str) { buildMyIntMask(); } inline AnTmpString & AnTmpString::operator=( const char *str ) { return (AnTmpString&)duplicate( str, strlen(str)+1 ); } AnTmpString::~AnTmpString() { } long int AnTmpString::anagrs( const LangStringListIter & dictS, const LangStringListIter & dictE, AnCallback *p, int recursLeft, int minRecurs, long int linesLeft) { // the computing time is consumed approximately // * 20% in the inString()-calls // * 20% in the rest()-calls clock_t start4C = clock(), end4C; long int linesFound=0; callbackPointer = p; AnTmpString *restchars = 0l; // new iterator for the one given as parameter; this means that the // given one is left unchanged LangStringListIter it = dictS; LangString * myLookup; // march through dict for ( ; ( it != dictE ) && (linesLeft>0) ; it++ ) { myLookup = *it; // found one matching word? if ( ( (myLookup->bitmask & bitmask) == myLookup->bitmask ) && inString( myLookup ) ) { // any more chars left? restchars = rest( myLookup, restchars ); if ( restchars->isEmpty() ) { // if not, emit this "signal" that we found an anagram. // but only if we want an anagram with a single word if (minRecurs<=1) { p->newAnagr( new Anagr(myLookup) ); linesLeft--; linesFound++; }; } else if ( recursLeft>1 ) { // if yes, continue the search recursivly lookup = myLookup; end4C = clock(); long int i= restchars->anagrs(it, dictE, this, recursLeft-1, minRecurs-1, linesLeft); start4C += clock() - end4C; linesLeft -= i; linesFound += i; }; // recursLeft>1 //restchars->isEmpty() } // inString(lookup) } // iteration through dict AND linesLeft>0 clock_t start5C = clock(); delete(restchars); prof5 += clock() - start5C; prof4 += (clock() - start4C); return linesFound; } // anagrs() void AnTmpString::newAnagr( Anagr *a ) { a->push_back( lookup ); callbackPointer->newAnagr( a ); }; bool AnTmpString::inString( const LangString * check ) { if ( (check->bitmask & bitmask) != check->bitmask ) return FALSE; char *thisCnt = data(), *checkCnt = check->charString.data(); const char *stopThisCnt = thisCnt + length(), *stopCheckCnt = checkCnt + check->charString.length(); if ( stopCheckCnt-checkCnt > stopThisCnt-thisCnt ) return FALSE; char checkChar, thisChar; // search every char out of *check* in *this* do { checkChar = *checkCnt; thisChar = *thisCnt; if ( checkChar == thisChar ) { checkCnt++; thisCnt++; } else if ( checkChar > thisChar ) { thisCnt++; } else { // *check has a letter which is not in *this return( FALSE ); } } while ( ( thisCnt < stopThisCnt ) && ( checkCnt < stopCheckCnt ) ); // if we checked all letters in *check then all letters have been // in *this ! return( checkCnt == stopCheckCnt ); }; AnTmpString * AnTmpString::rest( const LangString *check, AnTmpString * res ) { // The returned String is empty (isEmpty()==true), if and only if // *check and *this consist of the same letters // If, on the other hand, *check has a letter which is not in // *this, then the result is undefined!! Be careful to call // inString() before! char *thisCnt = data(), *checkCnt = check->charString.data(); const char *stopThisCnt = thisCnt + length(), *stopCheckCnt = checkCnt + check->charString.length(); char thisChar, checkChar, *storedChars = rest_CharBuf; do { checkChar = *checkCnt; thisChar = *thisCnt; if ( checkChar == thisChar ) { // This *checkChar seems to exist in *this, so don't store // it in the rest. // approx. 60% of all cases checkCnt++; } else if ( checkChar > thisChar ) { // this *checkChar is not in *this because in *check there // is a greater letter. Store it as rest. // approx. 40% of all cases *storedChars = thisChar; storedChars++; }; thisCnt++; } while ( ( thisCnt < stopThisCnt ) && ( checkCnt < stopCheckCnt ) ); if ( checkCnt == stopCheckCnt ) { // 70% of all while ( thisCnt < stopThisCnt ) { *storedChars = *thisCnt; storedChars++; thisCnt++; } }; *storedChars='\0'; if ( res == 0l ) { res = new AnTmpString( rest_CharBuf ); } else { *res = rest_CharBuf; res->buildMyIntMask(); }; return res; }; void AnTmpString::buildMyIntMask() { char chr; const char *cnt=0, *thislength=data()+length(); FOURBYTE mask=0; for (cnt=data(); cnt<thislength ; cnt++) { chr=*cnt; if ((chr >= 'a') && (chr <= 'z')) mask |= 1 << (FOURBYTE) (chr - 'a'); }; bitmask=mask; }; --- NEW FILE: antmpstring.h --- #ifndef ANTMPSTRING_H #define ANTMPSTRING_H #ifdef HAVE_CONFIG_H #include <config.h> #endif /* antmpstring.h QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ class AnTmpString; #include <qstring.h> #include <qregexp.h> #include <qcstring.h> #include "myconfig.h" #include "ancallback.h" #include "langstring.h" /** @short The representation of temporary words The representation of the temporary words, e.g., collations of those letters which remain when one language's word was found in the searchword. This contains all anagram-relevant functions as members. */ class AnTmpString : public QCString, public AnCallback { friend class LangString; public: /** Constructs a null string. */ AnTmpString(); /** Constructs a shared (?) copy of s. */ AnTmpString( const QString s ); AnTmpString( const QCString &s ); AnTmpString( const char * str ); AnTmpString &operator=( const char *str ); // deep copy virtual ~AnTmpString(); /** This invokes the recursive search for anagrams. It returns *only* the number of found anagrams. The anagrams itself are returned via the newAnagr() method of the AnCallback interface. According to the values of recursLeft and linesLeft, this can really take a *long* time. @param dictS Iterator for the Wordlist from the dictionary, pointing to the start of it. The iterator is left unchanged. @param dictE Iterator for the Wordlist from the dictionary, pointing to the end of it. The iterator is left unchanged. @param p The pointer to the object which wants to be notified that I found a new anagram @param recursLeft That many words may appear in the anagram as maximum. @param minRecurs That many word should appear in the anagram as minimum. @param linesLeft Go on only for that many anagrams in total. */ long int anagrs( const LangStringListIter & dictS, const LangStringListIter & dictE, AnCallback *p, int recursLeft=0, int minRecurs=0, long int linesLeft=0); /** checks the characters of *check whether they can be found in this object. Returns FALSE if not all letters in *check appear in this object. */ bool inString( const LangString * check); /** Returns a new AnTmpString which consists of the letters of this object minus the ones of *check. If not all letters of *check appear in this string, the result is not exactly defined, so use it only if inString() returns TRUE! If all letters of *check appear in this one it returns a string of zero length. If any char of *check does NOT appear in *this, it returns NULL - so be aware to catch this exceptional case. @param check The String whose characters should be "subtracted" from this object. @param res If you already have an AnTmpString object which may be overridden, then we could save really a lot of time in using this instead of creating a new one. */ AnTmpString *rest( const LangString * check, AnTmpString * res = 0l ); /** This is the callback function which is called by the recursivly invoked anagram search. To be implemented in the derived classes */ virtual void newAnagr( Anagr *a ); static long int prof1; static long int prof2; static long int prof3; static long int prof4; static long int prof5; static long int prof6; static long int prof7; static long int prof8; static long int prof9; static long int prof10; static char * profileInfo(); protected: /** The language's word which, in case there was recursivly found any anagram, is added to this anagram. */ LangString *lookup; /** The pointer to the object which wants to get notified whether I found a new angram. */ AnCallback *callbackPointer; /** Taken from wordplay-7.22 by Evans A Criswell Builds a bitmask; a 1 for each character of the alphabet found in the word. Builds this for the actual object. */ void buildMyIntMask(); FOURBYTE bitmask; private: // the buffer for the rest() method static char rest_CharBuf[]; }; #endif // ANTMPSTRING_H --- NEW FILE: generalpage.cpp --- /* generalpage.cpp QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ #include <generalpage.h> //#include <generalpage.moc> GeneralPage::GeneralPage(QWidget *parent, const char *name) : QWidget(parent, name) { // no edits yet wasEdited=FALSE; // 8 Rows, 3 Columns, Border=16 Pixel QGridLayout *grid = new QGridLayout(this,8,3,16); // a label for the title QLabel *l = new QLabel("Anagramm-Suchmaschine", this); l->setMinimumSize(l->sizeHint()); // void addMultiCellWidget ( QWidget *, int fromRow, int toRow, int // fromCol, int toCol, int align = 0 ) grid->addMultiCellWidget(l,0,0,0,2,AlignCenter); QFrame *sep = new QFrame(this); sep->setFrameStyle(QFrame::HLine | QFrame::Raised); grid->addMultiCellWidget(sep,1,1,0,2); // create a line edit field, add it to this page searchEdit = new QLineEdit(this); // addWidget(QWidget *, int row, int col, int align = 0) grid->addWidget(searchEdit, 2, 1); l = new QLabel(searchEdit, "Suchwort:", this); l->setMinimumSize(l->sizeHint()); grid->addWidget(l,2,0); sep = new QFrame(this); sep->setFrameStyle(QFrame::HLine | QFrame::Raised); grid->addMultiCellWidget(sep,3,3,0,2); // The maximum amount of words in one anagram // int minValue, int maxValue, int step = 1, QWidget * parent QSpinBox *mWords = new QSpinBox(1, 4, 1, this); mWords->setValue(3); maxWords = mWords; grid->addWidget(mWords, 4, 1); l = new QLabel(mWords, "Max. Worte", this); l->setMinimumSize(l->sizeHint()); grid->addWidget(l,4,0); connect(mWords, SIGNAL(valueChanged( int )), SLOT(valueChanged( int )) ); // The maximum amount of words in one anagram QSpinBox *mAnagrs = new QSpinBox(1, 1000000, 500, this); mAnagrs->setValue(10000); maxAnagrs = mAnagrs; grid->addWidget(mAnagrs, 5, 1); l = new QLabel(mAnagrs, "Max. Anagramme", this); l->setMinimumSize(l->sizeHint()); grid->addWidget(l,5,0); connect(mAnagrs, SIGNAL(valueChanged( int )), SLOT(valueChanged( int )) ); grid->setColStretch(0,1); grid->setColStretch(1,2); grid->setColStretch(2,1); grid->setRowStretch(7,1); grid->activate(); } GeneralPage::~GeneralPage() { } bool GeneralPage::edited() { return wasEdited || searchEdit->edited(); } void GeneralPage::valueChanged(int value) { wasEdited=TRUE; }; void GeneralPage::setEdited(bool b) { wasEdited=b; searchEdit->setEdited(b); } --- NEW FILE: generalpage.h --- #ifndef GENERALPAGE_H #define GENERALPAGE_H #ifdef HAVE_CONFIG_H #include <config.h> #endif /* generalpage.h QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ class GeneralPage; #include <qwidget.h> #include <qlayout.h> #include <qlineedit.h> #include <qlabel.h> #include <qspinbox.h> #include <qframe.h> /** Contains the main dialog, where the searchword is entered and the options (how many anagrams) are set. */ class GeneralPage : public QWidget { Q_OBJECT public: /** Default constructor */ GeneralPage(QWidget *parent = 0, const char *name = 0); /** Default destructor */ virtual ~GeneralPage(); /** The edit field for the searchword */ QLineEdit *searchEdit; /** Maximum number of words in one anagram */ QRangeControl *maxWords; /** Number of maximum anagrams */ QRangeControl *maxAnagrs; /** True, if anything in this widget has been edited */ bool edited(); void setEdited( bool b ); public slots: void valueChanged( int value ); private: bool wasEdited; }; #endif // GENERALPAGE_H --- NEW FILE: langstring.cpp --- /* langstring.cpp QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ #include "langstring.h" LangString::LangString() : LangStringAbstract() { worthValue = 0; bitmask = 0; charString = QCString(); } LangString::LangString( const QString s, int w ): LangStringAbstract(s) { worthValue=w; buildCharString(); } LangString::LangString( const QCString &s, int w ): LangStringAbstract(s) { worthValue=w; buildCharString(); } LangString::~LangString() {} LangStringList * LangString::expand() { LangStringList *x=new LangStringList; x->push_back(this); return x; }; QDataStream & operator<< (QDataStream & s, const LangString & str) { // write this string. Format: [ int worthValue, int length(), // (Q_INT32) data... ] return s << str.getWorth() << QString(str); }; QTextStream & operator<< (QTextStream & s, const LangString & str) { // simply write the word in latin-1-characters, force an // end-of-line afterwards. The worthValue is silently discarded! const char *c = str.latin1(); //char i = (char) str.getWorth(); //i+='A'; return s << c << endl; //return s << i << c << endl; }; LangString * LangString::readDataStream( QDataStream &s ) { QString tmp = ""; int i; s >> i; s >> tmp; LangString * result = new LangString( tmp, i ); return result; }; LangString * LangString::readTextStream( QTextStream &s ) { //char i; //s >> i; //i -= 'A'; //LangString * result = new LangString( s.readLine(), i ); LangString * result = new LangString( s.readLine() ); result->lower(). replace( QRegExp("\\s+"), "" ). replace( QRegExp("ä"), "ae" ). replace( QRegExp("ö"), "oe" ). replace( QRegExp("ü"), "ue" ). replace( QRegExp("ß"), "ss" ); return result; }; void LangString::buildCharString() { QCString tmp = local8Bit(); sort_QCString( tmp ); charString = tmp; buildMyIntMask(); } void LangString::buildMyIntMask() { char chr; const char *cnt=0, *thislength=charString.data()+charString.length();; FOURBYTE mask=0; for (cnt=charString.data(); cnt<thislength ; cnt++) { chr=*cnt; if ((chr >= 'a') && (chr <= 'z')) mask |= 1 << (FOURBYTE) (chr - 'a'); }; bitmask=mask; }; void LangString::sort_QCString( QCString & c ) { int n = c.length(); for( int i = n/2 - 1; i>=0; i-- ) sort_QCString_reheap( c, i, n-1 ); for( int i = n-1; i>0; i-- ) { char swap = c.at(0); c.at(0) = c.at(i); c.at(i) = swap; sort_QCString_reheap( c, 0, i-1 ); }; }; void LangString::sort_QCString_reheap( QCString & c, int i, int k ) { int j = i; bool done = FALSE; while (!done) { int son =0; if ( 2*j+1 > k) done = TRUE; if (!done) { if (2*j+2 <= k ) if ( c.at(2*j+1) < c.at(2*j+2) ) son = 2*j+2; else son = 2*j+1; else son = 2*j+1; // swap with c.at(son) if ( c.at(j) < c.at(son) ) { char swap = c.at(j); c.at(j) = c.at(son); c.at(son) = swap; j = son; } else done = TRUE; } } }; --- NEW FILE: langstring.h --- #ifndef LANGSTRING_H #define LANGSTRING_H #ifdef HAVE_CONFIG_H #include <config.h> #endif /* anstring.h QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ class LangString; //#include <pthread.h> #include <qstring.h> #include <qcstring.h> #include <qdatastream.h> #include <qtextstream.h> #include <qregexp.h> #include <vector> using namespace std; //#include <qmessagebox.h> #include "myconfig.h" #include "langstringabstract.h" #include "anagr.h" //#include "anabstract.h" //#include "ancallback.h" //#include "antmpstring.h" typedef vector<LangString*> LangStringList; typedef LangStringList::iterator LangStringListIter; /** @short The representation of the dictionary words The representation of the dictionary words. The interface is given in LangStringAbstract so this is the corresponding implementation. */ class LangString : public LangStringAbstract { // for access to the charString; friend class AnTmpString; /** Writes a string to a data stream. */ friend QDataStream & operator<< (QDataStream & s, const LangString & str); /** Writes a string to a text stream. */ friend QTextStream & operator<< (QTextStream & s, const LangString & str); public: /** Constructs a null string. */ LangString(); /** Constructs an implicitly-shared copy of s. @param w The worth value @param sorted TRUE, if this word's letters are already alphabetically sorted. */ LangString( const QString s, int w=0 ); LangString( const QCString &s, int w=0 ); virtual ~LangString(); /** Reads a new LangString from a DataStream and returns the reference to it. */ static LangString * readDataStream( QDataStream & s); /** Reads a new LangString from a TextStream and returns the reference to it. */ static LangString * readTextStream( QTextStream & s); /** True, if this word can be expanded via ispell-macros. Not yet implemented. */ virtual bool isExpandable() { return FALSE; }; /** Return a List of all Strings this one can be expanded to. Not yet implemented. */ virtual LangStringList *expand(); /** True, if this word matches the given one (e.g., female noun to female adjective). Not yet implemented. @param a the word to check against the current object. */ virtual bool matchWith( LangString *a ) { return TRUE; }; /** True, if this word matches all given ones (e.g., female noun to female adjective). Not yet implemented. @param a the wordlist to check against the current object. */ virtual bool matchAll( LangStringList * a) { return TRUE; }; /** True, if this word matches at least one of the given ones. (e.g., female noun to female adjective). Not yet implemented. @param a the wordlist to check against the current object. */ virtual bool matchOne( LangStringList * a) { return TRUE; }; protected: /** For the inString() function, consideration of the unicode characters is far too slow. So we built a 8 bit representation via this function. This method also calls buildMyIntMask(). */ void buildCharString(); /** The above mentioned 8 bit representation. */ QCString charString; /** Taken from wordplay-7.22 by Evans A Criswell Builds a bitmask; a 1 for each character of the alphabet found in the word. Builds this for the actual object. */ void buildMyIntMask(); FOURBYTE bitmask; /** A heapsort implementation, working only on QCString's. */ static void sort_QCString( QCString & c ); static void sort_QCString_reheap( QCString & c, int i, int k); }; #endif // LANGSTRING_H --- NEW FILE: langstringabstract.cpp --- /* langstringabstract.cpp QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ #include "langstringabstract.h" LangStringAbstract::LangStringAbstract() {}; LangStringAbstract::LangStringAbstract( const QString s ) : QString(s) {}; LangStringAbstract::~LangStringAbstract() {}; --- NEW FILE: langstringabstract.h --- #ifndef LANGSTRINGABSTRACT_H #define LANGSTRINGABSTRACT_H #ifdef HAVE_CONFIG_H #include <config.h> #endif /* langstringabstract.h QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ #include <qstring.h> #include <qdatastream.h> #include <qtextstream.h> #include <vector> using namespace std; /** @short The interface of the dictionary words The interface part of the dictionary words which represent that they are a real language's word. For usage this class is derived together with the one that contains the methods needed for anagram search. */ class LangStringAbstract : public QString { public: /** Constructs a null string. */ LangStringAbstract(); LangStringAbstract( const QString s ); virtual ~LangStringAbstract(); /** Reads a new AnString from a DataStream and returns the reference to it. */ static LangStringAbstract * readDataStream( QDataStream & s); /** Reads a new AnString from a TextStream and returns the reference to it. */ static LangStringAbstract * readTextStream( QTextStream & s); /** Returns the value which indicates the good words */ int getWorth() const { return worthValue; }; /** sets the value which indicates the good words. @param i the new value */ void setWorth( int i ) { worthValue=i; }; protected: int worthValue; }; typedef vector<LangStringAbstract*> LangStringAbstractList; typedef LangStringAbstractList::iterator LangStringAbstractListIter; #endif // LANGSTRINGABSTRACT_H --- NEW FILE: main.cpp --- /* main.cpp QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ #include"qanagram.h" #include<qapp.h> int main(int argc, char *argv[]) { // verify FOURBYTE-length used for charmask if ( (8*sizeof(FOURBYTE)) < 32) { fprintf( stderr, "Compilerfehler! Sizeof(FOURBYTE)=%d ist zu klein.\n", sizeof(FOURBYTE)); exit(1); }; QApplication app(argc, argv); QAnagram widget; app.setMainWidget(&widget); //app.setTopWidget(&widget); widget.show(); return app.exec(); } --- NEW FILE: myconfig.h --- /** All the global definitions */ #ifndef __MYCONFIG_H__ #define __MYCONFIG_H__ /** This type has to have at least 4 bytes, otherwise this programm will refuse to work. */ #define FOURBYTE long int #endif --- NEW FILE: qanagram.cpp --- /* qanagram.cpp QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ #include "qanagram.h" //#include "qanagram.moc" #include <qkeycode.h> //#include <kfm.h> //#include <kiconloader.h> QAnagram::QAnagram() : QMainWindow() { QAnagramWidget * view=new QAnagramWidget(this); // tell the KTMainWindow that this is indeed the main widget //setView(view); setCentralWidget(view); //setGeometry(400, 600, 0, 0); // create a DropZone over the entire window and connect it // to the slotDropEvent //connect(new KDNDDropZone(this, DndURL), // SIGNAL(dropAction(KDNDDropZone *)), // SLOT(slotDropEvent(KDNDDropZone *))); // create a popup menu -- in this case, the File menu QPopupMenu* p = new QPopupMenu(this); p->insertItem("Wortliste öffnen", view, SLOT(loadWordListDialog()), CTRL+Key_O); p->insertItem("Wortliste speichern", view, SLOT(saveWordListDialog()) ); p->insertItem("Markierte Anagramme speichern", view, SLOT(saveAnListDialog()), CTRL+Key_S); p->insertItem("Alle Anagramme speichern", view, SLOT(saveAllAnListDialog()) ); p->insertSeparator(); p->insertItem("Schließen", qApp, SLOT(quit()), CTRL+Key_Q); // put our newly created menu into the main menu bar menuBar()->insertItem("Datei", p); menuBar()->insertSeparator(); // KDE will generate a short help menu automagically //p = kapp->getHelpMenu(TRUE, // tr("QAnagram --- Short Description\n\n" // "(c) 1999 Christian Stimming \n" // "Long Description")); //menuBar()->insertItem(i18n("&Help"), p); // insert a quit button. the icon is the standard one in KDE // toolBar()->insertButton(Icon("exit.xpm"), // icon // 0, // button id // SIGNAL(clicked()), // action // kapp, SLOT(quit()), // result // i18n("Exit")); // tooltip text // we do want a status bar //enableStatusBar(); statusBar(); } QAnagram::~QAnagram() { } /*void QAnagram::slotDropEvent(KDNDDropZone *zone) { // the user dropped something on our window. QString url, temp_file; // get the URL pointing to the dropped file url = zone->getURLList().first(); // let KFM grab the file if (KFM::download(url, temp_file)) { // 'temp_file' now contains the absolute path to a temp file // with the contents of the the dropped file. You would presumably // handle it right now. // after you are done handling it, let KFM delete the temp file KFM::removeTempFile(temp_file); } } void QAnagram::saveProperties(KConfig *config) { // the 'config' object points to the session managed // config file. anything you write here will be available // later when this app is restored // e.g., config->writeEntry("key", var); } void QAnagram::readProperties(KConfig *config) { // the 'config' object points to the session managed // config file. this function is automatically called whenever // the app is being restored. read in here whatever you wrote // in 'saveProperties' // e.g., var = config->readEntry("key"); }*/ --- NEW FILE: qanagram.h --- #ifndef QANAGRAM_H #define QANAGRAM_H #ifdef HAVE_CONFIG_H #include <config.h> #endif /* qanagram.h QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ //#include <kapp.h> //#include <ktmainwindow.h> #include <qapplication.h> #include <qmainwindow.h> #include <qmenubar.h> #include "qanagramwidget.h" /** * This class serves as the main window for QAnagram. It handles the * menus, toolbars, and status bars. * * @short Main window class * @author Christian Stimming <sti...@tu...> * @version 0.2 */ class QAnagram : public QMainWindow { Q_OBJECT public: /** * Default Constructor */ QAnagram(); /** * Default Destructor */ virtual ~QAnagram(); private: QAnagramWidget *view; }; #endif // QANAGRAM_H --- NEW FILE: qanagramwidget.cpp --- /* qanagramwidget.cpp QAnagram - an anagram seach engine Copyright (C) 1999 Christian Stimming <sti...@tu...> See file COPYING for copyright information. */ #include <qanagramwidget.h> //#include <qanagramwidget.moc> int QAnagramWidget::maxWordsInAnagr=6; // Use this as filename for the wordlist. QString QAnagramWidget::wordListFileName=QString("./words.awl"); QAnagramWidget::QAnagramWidget(QWidget *parent, const char *name) : QWidget(parent, name) { // main layoutmanager is a vertical box layout QVBoxLayout * mainLayout = new QVBoxLayout(this); // main content is a stack of widgets widgetStack = new QWidgetStack(this); mainLayout->addWidget(widgetStack, 100); // create the view of anagrams, add it to widget stack anagrList = new AnListView(widgetStack, maxWordsInAnagr); widgetStack->addWidget(anagrList, anagrID); connect(this, SIGNAL(cleanAnList()), anagrList, SLOT(deleteAnList()) ); // create the view of words, add it to the widget stack WordListView *wordList = new WordListView(widgetStack); widgetStack->addWidget(wordList, wordID); connect(this, SIGNAL(cleanWordList()), wordList, SLOT(deleteWordList()) ); connect(this, SIGNAL(appendWordList(LangStringAbstract *)), wordList, SLOT(appendWordList(LangStringAbstract *)) ); // create a new widget from our own page widget and add it to the // widget stack generalPage = new GeneralPage(this); widgetStack->addWidget(generalPage, editID); widgetStack->raiseWidget(editID); connect(generalPage->searchEdit, SIGNAL(returnPressed()), SLOT(editFinished()) ); // Adjust the maximum number of anagrams generalPage->maxWords->setRange(1, maxWordsInAnagr); // the lower part of the main window should be a horizontal box layout mainLayout->addSpacing(3); mainLayout->addStretch(5); QHBoxLayout * bLayout = new QHBoxLayout(mainLayout); // for each action, add an appropriate button in the horizontal layout QPushButton * bSearch = new QPushButton("Suchwort", this); bLayout->addWidget(bSearch); bLayout->addSpacing(5); connect(bSearch, SIGNAL(pressed()), SLOT(editPressed()) ); QPushButton * bWList = new QPushButton("Wortliste", this); connect(bWList, SIGNAL(pressed()), SLOT(wListPressed()) ); bLayout->addWidget(bWList); bLayout->addSpacing(5); QPushButton * bAnagr = new QPushButton("Anagramme", this); connect(bAnagr, SIGNAL(pressed()), SLOT(anagrPressed()) ); bLayout->addWidget(bAnagr); // activate the main layout manager. mainLayout->activate(); connect(this, SIGNAL(raiseWidget(int)), widgetStack, SLOT(raiseWidget(int)) ); connect(this, SIGNAL(raiseWidget(int)), SLOT(widgetRaised(int)) ); // No searchword yet. searchword=0l; // load the word list loadWordList(wordListFileName); parent->adjustSize(); } QAnagramWidget::~QAnagramWidget() { if (!allDict.empty()) { for(LangStringListIter j = allDict.begin(); j != allDict.end(); j++) delete *j; }; } void QAnagramWidget::loadWordListDialog() { QString s( QFileDialog::getOpenFileName(wordListFileName) ); if ( s.isNull() ) return; wordListFileName = s; loadWordList(wordListFileName); } void QAnagramWidget::loadWordList(const QString &s) { if (!allDict.empty()) { emit(raiseWidget(editID)); emit(cleanAnList()); emit(cleanWordList()); generalPage->setEdited(TRUE); //allDict.clear(); for(LangStringListIter j = allDict.begin(); j != allDict.end(); j++) delete *j; }; // read the dictionary from disk QFile f( s ); if (! f.open( IO_ReadOnly ) ) { //return TRUE if successful QMessageBox::information( this, "QAnagram", "Unable to find the file \"" + s + "\".\n" "Nothing will happen." ); } else { // open file for reading if ( s.find( QRegExp("\\.awl$") ) != -1 ) { // our anagram-word-list format? yes, use data stream QDataStream stream( &f ); while( !stream.atEnd() ) { allDict.push_back( LangString::readDataStream(stream) ); }; } else { // no, only ascii-text, use text stream QTextStream stream( &f ); while( !stream.atEnd() ) { allDict.push_back( LangString::readTextStream(stream) ); }; } f.close(); } } void QAnagramWidget::saveWordListDialog() { QString s( QFileDialog::getSaveFileName(wordListFileName) ); if ( s.isNull() ) return; saveWordList( s ); } void QAnagramWidget::saveWordList(const QString &s) { if ( allDict.empty() ) return; // save the dictionary to disk QFile f( s ); if (! f.open( IO_WriteOnly ) ) { //return TRUE if successful QMessageBox::information( this, "QAnagram", "Couldn't open the file \"" + s + "\" for writing.\nNothing will happen." ); } else { // open file for reading if ( s.find( QRegExp("\\.awl$") ) != -1 ) { // our anagram-word-list format? yes, use data stream QDataStream stream( &f ); // march through dict for ( LangStringListIter it = allDict.begin(); it != allDict.end() ; it++ ) stream << *(*it); } else { // no, only ascii-text, use text stream QTextStream stream( &f ); // march through dict for ( LangStringListIter it = allDict.begin(); it != allDict.end() ; it++ ) stream << *(*it); } f.close(); } } void QAnagramWidget::saveAnListDialog() { QString s( QFileDialog::getSaveFileName() ); if ( s.isNull() ) return; saveAnList( s ); } void QAnagramWidget::saveAllAnListDialog() { QString s( QFileDialog::getSaveFileName() ); if ( s.isNull() ) return; saveAnList( s, FALSE ); } void QAnagramWidget::saveAnList(const QString &s, bool onlyMarked) { if ( (!anagrList) || (anagrList->childCount()==0) ) return; QFile f( s ); if (! f.open( IO_WriteOnly ) ) { //return TRUE if successful QMessageBox::information( this, "QAnagram", "Couldn't open the file \"" + s + "\" for writing.\nNothing will happen." ); } else { // open file for writing QTextStream stream( &f ); // serialize using f stream << "Anagramme für: " << *searchword << endl; // Create an iterator and give the listview as argument QListViewItemIterator it( anagrList ); // iterate through all items of the listview for ( ; it.current(); ++it ) if ( (!onlyMarked) || ((AnListViewItem*) it.current())->getMarked() ) stream << *( (AnListViewItem*) it.current())->getAnagr(); f.close(); } } void QAnagramWidget::statusMessage(const QString &s) { ((QAnagram *)parent())->statusBar()->message(s); } void QAnagramWidget::editFinished() { if (generalPage->edited()) { newSearch(); generalPage->setEdited(FALSE); } emit(raiseWidget(anagrID)); } void QAnagramWidget::wListPressed() { if ( generalPage->edited()) editFinished(); emit(raiseWidget(wordID)); } void QAnagramWidget::editPressed() { emit(raiseWidget(editID)); } void QAnagramWidget::anagrPressed() { if ( generalPage->edited()) editFinished(); else emit(raiseWidget(anagrID)); } void QAnagramWidget::widgetRaised(int id) { switch (id) { case wordID: { QString tmp; tmp.setNum(wordDict.size()); if (searchword!=0l) statusMessage(*searchword + " - "+tmp+" Wort... [truncated message content] |