diff --git a/Doxyfile b/Doxyfile index 0486281..0d76dca 100644 --- a/Doxyfile +++ b/Doxyfile @@ -2202,7 +2202,7 @@ PERL_PATH = /usr/bin/perl # powerful graphs. # The default value is: YES. -CLASS_DIAGRAMS = YES +CLASS_DIAGRAMS = NO # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see: @@ -2350,7 +2350,7 @@ INCLUDED_BY_GRAPH = YES # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -CALL_GRAPH = YES +CALL_GRAPH = NO # If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller # dependency graph for every global function or class method. @@ -2362,7 +2362,7 @@ CALL_GRAPH = YES # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -CALLER_GRAPH = YES +CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical # hierarchy of all classes instead of a textual one. diff --git a/cbook.h b/cbook.h index eadc3dc..e3e7d74 100644 --- a/cbook.h +++ b/cbook.h @@ -34,148 +34,148 @@ public: explicit cBook(const QString& szTitle = "", QObject *parent = nullptr); /*! - \brief + \brief Load the main book values from the database. \fn load - \return bool + \return true on success, otherwise false */ bool load(); /*! - \brief + \brief Save the main book values to the database. \fn save - \return bool + \return true on success, otherwise false */ bool save(); /*! - \brief + \brief Set the title of the book. \fn setTitle - \param szTitle + \param szTitle Title of the book */ void setTitle(const QString& szTitle); /*! - \brief + \brief Returns the title of the book. \fn title - \return QString + \return title of the book */ QString title(); /*! - \brief + \brief Set the subtitle of the book. \fn setSubTitle - \param szSubTitle + \param szSubTitle subtitle of the book */ void setSubTitle(const QString& szSubTitle); /*! - \brief + \brief Return the subtitle of the book. \fn subTitle - \return QString + \return subtitle of the book */ QString subTitle(); /*! - \brief + \brief Set the short description of the book. The text may be formatted. \fn setShortDescription - \param lpShortDescription + \param lpShortDescription pointer to a cTextDocument containing the short description */ void setShortDescription(cTextDocument* lpShortDescription); /*! - \brief + \brief Return the short description of the book. \fn shortDescription - \return cTextDocument + \return short description of the book as a cTextDocument */ cTextDocument* shortDescription(); /*! - \brief + \brief Set the description of the book. The text may be formatted. \fn setDescription - \param lpDescription + \param lpDescription pointer to a cTextDocument containing the description */ void setDescription(cTextDocument* lpDescription); /*! - \brief + \brief Return the description of the book. \fn description - \return cTextDocument + \return description of the book as a cTextDocument */ cTextDocument* description(); /*! - \brief + \brief Set the author of the book. \fn setAuthor - \param szAuthor + \param name of the author */ void setAuthor(const QString& szAuthor); /*! - \brief + \brief Return the author of the book. \fn author - \return QString + \return name of the author */ QString author(); /*! - \brief + \brief Set the date and time when the document has been started. \fn setStartedAt - \param startedAt + \param date and time when the document has been started */ void setStartedAt(const QDateTime& startedAt); /*! - \brief + \brief Return the date and time when the document has been started. \fn startedAt - \return QDateTime + \return date and time when the document has been started */ QDateTime startedAt(); /*! - \brief + \brief Set the date and time when the document has been finished. \fn setFinishedAt - \param finishedAt + \param date and time when the document has been finished */ void setFinishedAt(const QDateTime& finishedAt); /*! - \brief + \brief Return the date and time when the document has been finished. \fn finishedAt - \return QDateTime + \return date and time when the document has been finished */ QDateTime finishedAt(); /*! - \brief + \brief Set the date and time when the document should be finished. \fn setTargetDate - \param targetDate + \param date and time when the document should be finished */ void setTargetDate(const QDateTime& targetDate); /*! - \brief + \brief Return the date and time when the document should be finished. \fn targetDate - \return QDateTime + \return date and time when the document should be finished */ QDateTime targetDate(); private: - QString m_szTitle; /*!< TODO: describe */ - QString m_szSubtitle; /*!< TODO: describe */ - cTextDocument* m_lpShortDescription; /*!< TODO: describe */ - cTextDocument* m_lpDescription; /*!< TODO: describe */ - QString m_szAuthor; /*!< TODO: describe */ - QDateTime m_startedAt; /*!< TODO: describe */ - QDateTime m_finishedAt; /*!< TODO: describe */ - QDateTime m_targetDate; /*!< TODO: describe */ + QString m_szTitle; /*!< title of the document */ + QString m_szSubtitle; /*!< subtitle of the document */ + cTextDocument* m_lpShortDescription; /*!< short description of the document. The text may be formatted */ + cTextDocument* m_lpDescription; /*!< description of the document. The text may be formatted */ + QString m_szAuthor; /*!< name of the author of the document */ + QDateTime m_startedAt; /*!< date and time when the document has been startd */ + QDateTime m_finishedAt; /*!< date and time when the document has been finished */ + QDateTime m_targetDate; /*!< date and time when the document should be finished */ }; Q_DECLARE_METATYPE(cBook*) diff --git a/cchapter.cpp b/cchapter.cpp index 8a732ae..1b2e3a5 100644 --- a/cchapter.cpp +++ b/cchapter.cpp @@ -18,7 +18,9 @@ cChapter::cChapter(qint32 iID, QObject *parent) : m_szName(""), m_iSortOrder(-1), m_lpDescription(0), - m_lpText(0) + m_lpText(0), + m_lpItem(0), + m_bDeleted(false) { } @@ -82,6 +84,26 @@ cTextDocument* cChapter::text() return(m_lpText); } +void cChapter::setItem(QStandardItem* lpItem) +{ + m_lpItem = lpItem; +} + +QStandardItem* cChapter::item() +{ + return(m_lpItem); +} + +void cChapter::setDeleted(bool bDeleted) +{ + m_bDeleted = bDeleted; +} + +bool cChapter::deleted() +{ + return(m_bDeleted); +} + cChapter* cChapterList::add(const qint32& iID) { cChapter* lpChapter = find(iID); @@ -118,6 +140,18 @@ QList cChapterList::find(cPart* lpPart) return(chapterList); } +qint32 cChapterList::nextSort(cPart* lpPart) +{ + qint32 iSort = -1; + + for(int x = 0;x < count();x++) + { + if(lpPart == at(x)->part() && iSort < at(x)->sortOrder()) + iSort = at(x)->sortOrder(); + } + return(iSort+1); +} + bool cChapterList::load(cPartList* lpPartList) { QSqlQuery query; @@ -148,16 +182,29 @@ bool cChapterList::save() QSqlQuery queryUpdate; QSqlQuery queryInsert; QSqlQuery querySelect; + QSqlQuery queryDelete; queryUpdate.prepare("UPDATE chapter SET name=:name, partID=:partID, sortOrder=:sortOrder, description=:description, text=:text WHERE id=:id;"); queryInsert.prepare("INSERT INTO chapter (name, partID, sortOrder, description, text) VALUES (:name, :partID, :sortOrder, :description, :text);"); querySelect.prepare("SELECT id FROM chapter WHERE _rowid_=(SELECT MAX(_rowid_) FROM chapter);"); + queryDelete.prepare("DELETE FROM chapter WHERE id=:id;"); for(int x = 0;x < count();x++) { cChapter* lpChapter = at(x); - if(lpChapter->id() != -1) + if(lpChapter->deleted()) + { + queryDelete.bindValue(":id", lpChapter->id()); + + if(!queryDelete.exec()) + { + myDebug << queryDelete.lastError().text(); + return(false); + } + this->removeOne(lpChapter); + } + else if(lpChapter->id() != -1) { queryUpdate.bindValue(":id", lpChapter->id()); queryUpdate.bindValue(":name", lpChapter->name()); diff --git a/cchapter.h b/cchapter.h index ef515fc..5e8f40e 100644 --- a/cchapter.h +++ b/cchapter.h @@ -125,6 +125,36 @@ public: */ cTextDocument* text(); + /*! + \brief + + \fn setItem + \param lpItem + */ + void setItem(QStandardItem* lpItem); + /*! + \brief + + \fn item + \return QStandardItem + */ + QStandardItem* item(); + + /*! + \brief + + \fn setDeleted + \param bDeleted + */ + void setDeleted(bool bDeleted); + /*! + \brief + + \fn deleted + \return bool + */ + bool deleted(); + private: qint32 m_iID; /*!< TODO: describe */ cPart* m_lpPart; /*!< TODO: describe */ @@ -132,6 +162,8 @@ private: qint32 m_iSortOrder; /*!< TODO: describe */ cTextDocument* m_lpDescription; /*!< TODO: describe */ cTextDocument* m_lpText; /*!< TODO: describe */ + QStandardItem* m_lpItem; /*!< TODO: describe */ + bool m_bDeleted; /*!< TODO: describe */ }; Q_DECLARE_METATYPE(cChapter*) @@ -185,6 +217,15 @@ public: \return QList */ QList find(cPart* lpPart); + + /*! + \brief + + \fn nextSort + \param lpPart + \return cPart + */ + qint32 nextSort(cPart* lpPart); }; #endif // CCHAPTER_H diff --git a/cchapterwindow.cpp b/cchapterwindow.cpp index 1f6f4c4..3bdf480 100644 --- a/cchapterwindow.cpp +++ b/cchapterwindow.cpp @@ -95,6 +95,10 @@ void cChapterWindow::onSceneDoubleClicked(const QModelIndex& index) void cChapterWindow::onNameChanged(const QString& szName) { m_lpChapter->setName(szName); + + if(m_lpChapter->item()) + m_lpChapter->item()->setText(szName); + m_lpMainWindow->somethingChanged(); } diff --git a/ccharacter.cpp b/ccharacter.cpp index 1a64169..99923a6 100644 --- a/ccharacter.cpp +++ b/ccharacter.cpp @@ -371,6 +371,9 @@ cCharacter* cCharacterList::add(const qint32& iID) cCharacter* cCharacterList::find(const qint32& iID) { + if(iID == -1) + return(0); + for(int x = 0;x < count();x++) { if(at(x)->id() == iID) @@ -384,7 +387,7 @@ bool cCharacterList::load(cImageList *lpImageList) { QSqlQuery query; - query.prepare("SELECT id, mainCharacter, creature, gender, title, firstName, middleName, lastName, height, weight, dateOfBirth, placeOfBirth, dateOfDeath, placeOfDeath, hairColor, hairCut, hairLength, figure, nature, spokenLanguages, skin, school, job, description FROM character ORDER BY mainCharacter DESC, lastName, middleName, firstName;"); + query.prepare("SELECT id, mainCharacter, creature, gender, title, firstName, middleName, lastName, nickName, height, weight, dateOfBirth, placeOfBirth, dateOfDeath, placeOfDeath, hairColor, hairCut, hairLength, figure, nature, spokenLanguages, skin, school, job, description FROM character ORDER BY mainCharacter DESC, lastName, middleName, firstName;"); if(!query.exec()) { myDebug << query.lastError().text(); @@ -402,6 +405,7 @@ bool cCharacterList::load(cImageList *lpImageList) lpCharacter->setFirstName(query.value("firstName").toString()); lpCharacter->setMiddleName(query.value("middleName").toString()); lpCharacter->setLastName(query.value("lastName").toString()); + lpCharacter->setNickName(query.value("nickName").toString()); lpCharacter->setHeight(query.value("height").toDouble()); lpCharacter->setWeight(query.value("weight").toDouble()); lpCharacter->setDateOfBirth(query.value("dateOfBirth").toDate()); @@ -447,8 +451,8 @@ bool cCharacterList::save() QSqlQuery queryInsert; QSqlQuery querySelect; - queryUpdate.prepare("UPDATE character SET mainCharacter=:mainCharacter, creature=:creature, gender=:gender, title=:title, firstName=:firstName, middleName=:middleName, lastName=:lastName, height=:height, weight=:weight, dateOfBirth=:dateOfBirth, dateOfDeath=:dateOfDeath, placeOfBirth=:placeOfBirth, placeOfDeath=:placeOfDeath, hairColor=:hairColor, hairCut=:hairCut, hairLength=:hairLength, figure=:figure, nature=:nature, spokenLanguages=:spokenLanguages, skin=:skin, school=:school, job=:job, description=:description WHERE id=:id;"); - queryInsert.prepare("INSERT INTO character (mainCharacter, creature, gender, title, firstName, middleName, lastName, height, weight, dateOfBirth, dateOfDeath, placeOfBirth, placeOfDeath, hairColor, hairCut, hairLength, figure, nature, spokenLanguages, skin, school, job, description) VALUES (:mainCharacter, :creature, :gender, :title, :firstName,: middleName, :lastName, :height, :weight,:dateOfBirth, :dateOfDeath, :placeOfBirth, :placeOfDeath, :hairColor, :hairCut, :hairLength, :figure, :nature, :spokenLanguages, :skin, :school, :job, :description);"); + queryUpdate.prepare("UPDATE character SET mainCharacter=:mainCharacter, creature=:creature, gender=:gender, title=:title, firstName=:firstName, middleName=:middleName, lastName=:lastName, nickName=:nickName, height=:height, weight=:weight, dateOfBirth=:dateOfBirth, dateOfDeath=:dateOfDeath, placeOfBirth=:placeOfBirth, placeOfDeath=:placeOfDeath, hairColor=:hairColor, hairCut=:hairCut, hairLength=:hairLength, figure=:figure, nature=:nature, spokenLanguages=:spokenLanguages, skin=:skin, school=:school, job=:job, description=:description WHERE id=:id;"); + queryInsert.prepare("INSERT INTO character (mainCharacter, creature, gender, title, firstName, middleName, lastName, nickName, height, weight, dateOfBirth, dateOfDeath, placeOfBirth, placeOfDeath, hairColor, hairCut, hairLength, figure, nature, spokenLanguages, skin, school, job, description) VALUES (:mainCharacter, :creature, :gender, :title, :firstName, :middleName, :lastName, :nickName, :height, :weight,:dateOfBirth, :dateOfDeath, :placeOfBirth, :placeOfDeath, :hairColor, :hairCut, :hairLength, :figure, :nature, :spokenLanguages, :skin, :school, :job, :description);"); querySelect.prepare("SELECT id FROM character WHERE _rowid_=(SELECT MAX(_rowid_) FROM character);"); QSqlQuery imageDelete; @@ -471,6 +475,7 @@ bool cCharacterList::save() queryUpdate.bindValue(":firstName", lpCharacter->firstName()); queryUpdate.bindValue(":middleName", lpCharacter->middleName()); queryUpdate.bindValue(":lastName", lpCharacter->lastName()); + queryUpdate.bindValue(":nickName", lpCharacter->nickName()); queryUpdate.bindValue(":height", lpCharacter->height()); queryUpdate.bindValue(":weight", lpCharacter->weight()); queryUpdate.bindValue(":dateOfBirth", lpCharacter->dateOfBirth()); @@ -503,6 +508,7 @@ bool cCharacterList::save() queryInsert.bindValue(":firstName", lpCharacter->firstName()); queryInsert.bindValue(":middleName", lpCharacter->middleName()); queryInsert.bindValue(":lastName", lpCharacter->lastName()); + queryInsert.bindValue(":nickName", lpCharacter->nickName()); queryInsert.bindValue(":height", lpCharacter->height()); queryInsert.bindValue(":weight", lpCharacter->weight()); queryInsert.bindValue(":dateOfBirth", lpCharacter->dateOfBirth()); diff --git a/ccharacterwindow.cpp b/ccharacterwindow.cpp index 006c827..9e29cc9 100644 --- a/ccharacterwindow.cpp +++ b/ccharacterwindow.cpp @@ -33,6 +33,9 @@ cCharacterWindow::cCharacterWindow(QWidget *parent) : connect(ui->m_lpLastName, &cLineEdit::gotFocus, (cMainWindow*)parent, &cMainWindow::onLineEditGotFocus); connect(ui->m_lpLastName, &cLineEdit::lostFocus, (cMainWindow*)parent, &cMainWindow::onLineEditLostFocus); + connect(ui->m_lpNickName, &cLineEdit::gotFocus, (cMainWindow*)parent, &cMainWindow::onLineEditGotFocus); + connect(ui->m_lpNickName, &cLineEdit::lostFocus, (cMainWindow*)parent, &cMainWindow::onLineEditLostFocus); + connect(ui->m_lpMainCharacter, &cCheckBox::gotFocus, (cMainWindow*)parent, &cMainWindow::onCheckBoxGotFocus); connect(ui->m_lpMainCharacter, &cCheckBox::lostFocus, (cMainWindow*)parent, &cMainWindow::onCheckBoxLostFocus); @@ -112,6 +115,7 @@ void cCharacterWindow::setCharacter(cCharacter* lpCharacter) ui->m_lpFirstName->setText(lpCharacter->firstName()); ui->m_lpMiddleName->setText(lpCharacter->middleName()); ui->m_lpLastName->setText(lpCharacter->lastName()); + ui->m_lpNickName->setText(lpCharacter->nickName()); ui->m_lpMainCharacter->setChecked(lpCharacter->mainCharacter()); ui->m_lpCreature->setText(lpCharacter->creature()); ui->m_lpTitle->setText(lpCharacter->title()); @@ -163,6 +167,7 @@ void cCharacterWindow::setCharacter(cCharacter* lpCharacter) connect(ui->m_lpFirstName, &cLineEdit::textChanged, this, &cCharacterWindow::onFirstNameChanged); connect(ui->m_lpMiddleName, &cLineEdit::textChanged, this, &cCharacterWindow::onMiddleNameChanged); connect(ui->m_lpLastName, &cLineEdit::textChanged, this, &cCharacterWindow::onLastNameChanged); + connect(ui->m_lpNickName, &cLineEdit::textChanged, this, &cCharacterWindow::onNickNameChanged); connect(ui->m_lpMainCharacter, &cCheckBox::clicked, this, &cCharacterWindow::onMainCharacterClicked); connect(ui->m_lpCreature, &cLineEdit::textChanged, this, &cCharacterWindow::onCreatureChanged); connect(ui->m_lpMale, &cCheckBox::clicked, this, &cCharacterWindow::onGenderMaleClicked); @@ -210,6 +215,12 @@ void cCharacterWindow::onLastNameChanged(const QString& szText) m_lpMainWindow->somethingChanged(); } +void cCharacterWindow::onNickNameChanged(const QString& szText) +{ + m_lpCharacter->setNickName(szText); + m_lpMainWindow->somethingChanged(); +} + void cCharacterWindow::onMainCharacterClicked(bool bChecked) { m_lpCharacter->setMainCharacter(bChecked); diff --git a/ccharacterwindow.h b/ccharacterwindow.h index 74b5453..fda2156 100644 --- a/ccharacterwindow.h +++ b/ccharacterwindow.h @@ -79,6 +79,13 @@ private slots: /*! \brief + \fn onLastNameChanged + \param szText + */ + void onNickNameChanged(const QString& szText); + /*! + \brief + \fn onMainCharacterClicked \param bChecked */ diff --git a/ccharacterwindow.ui b/ccharacterwindow.ui index 75db31f..d8da721 100644 --- a/ccharacterwindow.ui +++ b/ccharacterwindow.ui @@ -93,10 +93,18 @@ - + + + true + + - + + + true + + @@ -145,16 +153,6 @@ - - - - Title: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - @@ -194,9 +192,6 @@ - - - @@ -344,6 +339,32 @@ + + + + + + + Title: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Nick Name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + @@ -427,8 +448,34 @@ + m_lpTab m_lpFirstName + m_lpMiddleName + m_lpLastName + m_lpMainCharacter + m_lpCreature + m_lpNickName + m_lpTitle + m_lpMale + m_lpFemale + m_lpOther + m_lpDayOfBirth + m_lpPlaceOfBirth + m_lpDayOfDeath + m_lpPlaceOfDeath + m_lpHeight + m_lpFigure + m_lpWeight + m_lpSkin + m_lpNature + m_lpHairColor + m_lpHairCut + m_lpHairLength + m_lpSchool + m_lpSpokenLanguages + m_lpJob m_lpDescription + m_lpScrollArea diff --git a/cmainwindow.cpp b/cmainwindow.cpp index ddf36af..52bc883 100644 --- a/cmainwindow.cpp +++ b/cmainwindow.cpp @@ -1234,6 +1234,8 @@ void cMainWindow::onAddPart() } m_lpStoryBook->fillOutlineList(ui->m_lpOutlineList); + m_bSomethingChanged = true; + updateWindowTitle(); } } @@ -1257,6 +1259,49 @@ void cMainWindow::onDeletePart() void cMainWindow::onAddChapter() { + bool bOK; + QString szChapterName = ""; + QStandardItem* lpItem = m_lpOutlineModel->itemFromIndex(ui->m_lpOutlineList->currentIndex()); + if(!lpItem) + return; + + cPart* lpPart = qvariant_cast(lpItem->data()); + if(!lpPart) + { + lpItem = lpItem->parent(); + lpPart = qvariant_cast(lpItem->data()); + + if(!lpPart) + return; + } + + for(;;) + { + szChapterName = QInputDialog::getText(this, tr("New Chapter"), tr("Name:"), QLineEdit::Normal, "", &bOK); + if(!bOK) + return; + + if(szChapterName.isEmpty()) + { + QMessageBox::critical(this, tr("New Chapter"), tr("Chapter Name is empty.")); + bOK = false; + } + else + break; + } + + if(bOK && !szChapterName.isEmpty()) + { + if(!m_lpStoryBook->addChapter(lpPart, szChapterName)) + { + QMessageBox::critical(this, tr("New Chapter"), tr("Chapter could not be created.")); + return; + } + + m_lpStoryBook->fillOutlineList(ui->m_lpOutlineList); + m_bSomethingChanged = true; + updateWindowTitle(); + } } void cMainWindow::onEditChapter() @@ -1275,10 +1320,96 @@ void cMainWindow::onEditChapter() void cMainWindow::onDeleteChapter() { + QStandardItem* lpItem = m_lpOutlineModel->itemFromIndex(ui->m_lpOutlineList->currentIndex()); + if(!lpItem) + return; + + cChapter* lpChapter = qvariant_cast(lpItem->data()); + + if(!lpChapter) + return; + + if(m_lpStoryBook->hasScene(lpChapter)) + { + QMessageBox::critical(this, "Delete Chapter", tr("There are still some scenes in this chapter.\nPlease delete them before deleting the chapter.")); + return; + + } + + if(QMessageBox::question(this, "Delete Chapter", tr("Are you sure you want to delete this chapter:
") + "
" + lpChapter->name() + "
" + tr("
from part
") + "
" + lpChapter->part()->name() + "
") != QMessageBox::Yes) + return; + + lpChapter->setDeleted(true); + m_lpStoryBook->fillOutlineList(ui->m_lpOutlineList); + m_bSomethingChanged = true; + updateWindowTitle(); + + for(int x = 0;x < ui->m_lpMainTab->count();x++) + { + cWidget* lpWidget = (cWidget*)ui->m_lpMainTab->widget(x); + if(lpWidget->type() == cWidget::TYPE_chapter) + { + cChapterWindow* lpChapterWindow = (cChapterWindow*)lpWidget->widget(); + if(lpChapterWindow->chapter() == lpChapter) + { + onMainTabTabCloseRequested(x); + return; + } + } + } } void cMainWindow::onAddScene() { + bool bOK; + QString szSceneName = ""; + QStandardItem* lpItem = m_lpOutlineModel->itemFromIndex(ui->m_lpOutlineList->currentIndex()); + if(!lpItem) + return; + + cChapter* lpChapter = qvariant_cast(lpItem->data()); + if(!lpChapter) + { + lpItem = lpItem->parent(); + lpChapter = qvariant_cast(lpItem->data()); + + if(!lpChapter) + { + lpItem = lpItem->parent(); + lpChapter = qvariant_cast(lpItem->data()); + + if(!lpChapter) + return; + } + } + + for(;;) + { + szSceneName = QInputDialog::getText(this, tr("New Scene"), tr("Name:"), QLineEdit::Normal, "", &bOK); + if(!bOK) + return; + + if(szSceneName.isEmpty()) + { + QMessageBox::critical(this, tr("New Scene"), tr("Scene Name is empty.")); + bOK = false; + } + else + break; + } + + if(bOK && !szSceneName.isEmpty()) + { + if(!m_lpStoryBook->addScene(lpChapter, szSceneName)) + { + QMessageBox::critical(this, tr("New Scene"), tr("Scene could not be created.")); + return; + } + + m_lpStoryBook->fillOutlineList(ui->m_lpOutlineList); + m_bSomethingChanged = true; + updateWindowTitle(); + } } void cMainWindow::onEditScene() @@ -1297,10 +1428,70 @@ void cMainWindow::onEditScene() void cMainWindow::onDeleteScene() { + QStandardItem* lpItem = m_lpOutlineModel->itemFromIndex(ui->m_lpOutlineList->currentIndex()); + if(!lpItem) + return; + + cScene* lpScene = qvariant_cast(lpItem->data()); + + if(!lpScene) + return; + + if(QMessageBox::question(this, "Delete Scene", tr("Are you sure you want to delete this scene:
") + "
" + lpScene->name() + "
" + tr("
from chapter
") + "
" + lpScene->chapter()->name() + "
") != QMessageBox::Yes) + return; + + lpScene->setDeleted(true); + m_lpStoryBook->fillOutlineList(ui->m_lpOutlineList); + m_bSomethingChanged = true; + updateWindowTitle(); + + for(int x = 0;x < ui->m_lpMainTab->count();x++) + { + cWidget* lpWidget = (cWidget*)ui->m_lpMainTab->widget(x); + if(lpWidget->type() == cWidget::TYPE_scene) + { + cSceneWindow* lpSceneWindow = (cSceneWindow*)lpWidget->widget(); + if(lpSceneWindow->scene() == lpScene) + { + onMainTabTabCloseRequested(x); + return; + } + } + } } void cMainWindow::onAddCharacter() { + bool bOK; + QString szCharacterName = ""; + + for(;;) + { + szCharacterName = QInputDialog::getText(this, tr("New Character"), tr("Name:"), QLineEdit::Normal, "", &bOK); + if(!bOK) + return; + + if(szCharacterName.isEmpty()) + { + QMessageBox::critical(this, tr("New Character"), tr("Character Name is empty.")); + bOK = false; + } + else + break; + } + + if(bOK && !szCharacterName.isEmpty()) + { + if(!m_lpStoryBook->addCharacter(szCharacterName)) + { + QMessageBox::critical(this, tr("New Character"), tr("Character could not be created.")); + return; + } + + m_lpStoryBook->fillCharacterList(ui->m_lpCharacterList); + m_bSomethingChanged = true; + updateWindowTitle(); + } } void cMainWindow::onEditCharacter() @@ -1323,6 +1514,36 @@ void cMainWindow::onDeleteCharacter() void cMainWindow::onAddPlace() { + bool bOK; + QString szPlaceName = ""; + + for(;;) + { + szPlaceName = QInputDialog::getText(this, tr("New Place"), tr("Name:"), QLineEdit::Normal, "", &bOK); + if(!bOK) + return; + + if(szPlaceName.isEmpty()) + { + QMessageBox::critical(this, tr("New Place"), tr("Place Name is empty.")); + bOK = false; + } + else + break; + } + + if(bOK && !szPlaceName.isEmpty()) + { + if(!m_lpStoryBook->addPlace(szPlaceName)) + { + QMessageBox::critical(this, tr("New Place"), tr("Place could not be created.")); + return; + } + + m_lpStoryBook->fillPlaceList(ui->m_lpPlaceList); + m_bSomethingChanged = true; + updateWindowTitle(); + } } void cMainWindow::onEditPlace() @@ -1345,6 +1566,36 @@ void cMainWindow::onDeletePlace() void cMainWindow::onAddObject() { + bool bOK; + QString szObjectName = ""; + + for(;;) + { + szObjectName = QInputDialog::getText(this, tr("New Object"), tr("Name:"), QLineEdit::Normal, "", &bOK); + if(!bOK) + return; + + if(szObjectName.isEmpty()) + { + QMessageBox::critical(this, tr("New Object"), tr("Object Name is empty.")); + bOK = false; + } + else + break; + } + + if(bOK && !szObjectName.isEmpty()) + { + if(!m_lpStoryBook->addObject(szObjectName)) + { + QMessageBox::critical(this, tr("New Object"), tr("Object could not be created.")); + return; + } + + m_lpStoryBook->fillObjectList(ui->m_lpObjectList); + m_bSomethingChanged = true; + updateWindowTitle(); + } } void cMainWindow::onEditObject() @@ -1367,6 +1618,36 @@ void cMainWindow::onDeleteObject() void cMainWindow::onAddRecherche() { + bool bOK; + QString szRechercheName = ""; + + for(;;) + { + szRechercheName = QInputDialog::getText(this, tr("New Recherche"), tr("Name:"), QLineEdit::Normal, "", &bOK); + if(!bOK) + return; + + if(szRechercheName.isEmpty()) + { + QMessageBox::critical(this, tr("New Recherche"), tr("Recherche Name is empty.")); + bOK = false; + } + else + break; + } + + if(bOK && !szRechercheName.isEmpty()) + { + if(!m_lpStoryBook->addRecherche(szRechercheName)) + { + QMessageBox::critical(this, tr("New Recherche"), tr("Recherche could not be created.")); + return; + } + + m_lpStoryBook->fillRechercheList(ui->m_lpRechercheList); + m_bSomethingChanged = true; + updateWindowTitle(); + } } void cMainWindow::onEditRecherche() diff --git a/cobject.cpp b/cobject.cpp index c501bf5..ff19809 100644 --- a/cobject.cpp +++ b/cobject.cpp @@ -87,6 +87,9 @@ cObject* cObjectList::add(const qint32& iID) cObject* cObjectList::find(const qint32& iID) { + if(iID == -1) + return(0); + for(int x = 0;x < count();x++) { if(at(x)->id() == iID) diff --git a/cpart.cpp b/cpart.cpp index 7407334..0de952a 100644 --- a/cpart.cpp +++ b/cpart.cpp @@ -17,7 +17,8 @@ cPart::cPart(qint32 iID, QObject *parent) : m_szName(""), m_iSortOrder(-1), m_lpDescription(0), - m_lpText(0) + m_lpText(0), + m_lpItem(0) { } @@ -71,6 +72,16 @@ cTextDocument* cPart::text() return(m_lpText); } +void cPart::setItem(QStandardItem* lpItem) +{ + m_lpItem = lpItem; +} + +QStandardItem* cPart::item() +{ + return(m_lpItem); +} + cPart* cPartList::add(const qint32& iID) { cPart* lpPart = find(iID); diff --git a/cpart.h b/cpart.h index 01bfae8..30ee7d3 100644 --- a/cpart.h +++ b/cpart.h @@ -13,6 +13,7 @@ #include #include #include +#include /*! @@ -108,12 +109,28 @@ public: */ cTextDocument* text(); + /*! + \brief + + \fn setItem + \param lpItem + */ + void setItem(QStandardItem* lpItem); + /*! + \brief + + \fn item + \return QStandardItem + */ + QStandardItem* item(); + private: qint32 m_iID; /*!< TODO: describe */ QString m_szName; /*!< TODO: describe */ qint32 m_iSortOrder; /*!< TODO: describe */ cTextDocument* m_lpDescription; /*!< TODO: describe */ cTextDocument* m_lpText; /*!< TODO: describe */ + QStandardItem* m_lpItem; /*!< TODO: describe */ }; Q_DECLARE_METATYPE(cPart*) @@ -158,6 +175,12 @@ public: */ cPart* find(const qint32& iID); + /*! + \brief + + \fn nextSort + \return cPart + */ qint32 nextSort(); }; diff --git a/cpartwindow.cpp b/cpartwindow.cpp index ccd5b02..80e7127 100644 --- a/cpartwindow.cpp +++ b/cpartwindow.cpp @@ -93,6 +93,10 @@ void cPartWindow::onChapterDoubleClicked(const QModelIndex& index) void cPartWindow::onNameChanged(const QString& szName) { m_lpPart->setName(szName); + + if(m_lpPart->item()) + m_lpPart->item()->setText(szName); + m_lpMainWindow->somethingChanged(); } diff --git a/cplace.cpp b/cplace.cpp index dd13d51..f6b9300 100644 --- a/cplace.cpp +++ b/cplace.cpp @@ -98,6 +98,9 @@ cPlace* cPlaceList::add(const qint32& iID) cPlace* cPlaceList::find(const qint32& iID) { + if(iID == -1) + return(0); + for(int x = 0;x < count();x++) { if(at(x)->id() == iID) diff --git a/crecherche.cpp b/crecherche.cpp index d6d67bc..bb652e2 100644 --- a/crecherche.cpp +++ b/crecherche.cpp @@ -123,6 +123,9 @@ cRecherche* cRechercheList::add(const qint32& iID) cRecherche* cRechercheList::find(const qint32& iID) { + if(iID == -1) + return(0); + for(int x = 0;x < count();x++) { if(at(x)->id() == iID) diff --git a/cscene.cpp b/cscene.cpp index 215d9d2..fa38451 100644 --- a/cscene.cpp +++ b/cscene.cpp @@ -19,7 +19,10 @@ cScene::cScene(qint32 iID, QObject *parent) : m_iSortOrder(-1), m_lpDescription(0), m_state(STATE::STATE_unknown), - m_lpText(0) + m_lpText(0), + m_lpItem(0), + m_lpStateItem(0), + m_bDeleted(false) { } @@ -205,6 +208,36 @@ QColor cScene::stateColor(STATE state) return(Qt::darkRed); } +void cScene::setItem(QStandardItem* lpItem) +{ + m_lpItem = lpItem; +} + +QStandardItem* cScene::item() +{ + return(m_lpItem); +} + +void cScene::setStateItem(QStandardItem* lpItem) +{ + m_lpStateItem = lpItem; +} + +QStandardItem* cScene::stateItem() +{ + return(m_lpStateItem); +} + +void cScene::setDeleted(bool bDeleted) +{ + m_bDeleted = bDeleted; +} + +bool cScene::deleted() +{ + return(m_bDeleted); +} + cScene* cSceneList::add(const qint32& iID) { cScene* lpScene = find(iID); @@ -220,6 +253,9 @@ cScene* cSceneList::add(const qint32& iID) cScene* cSceneList::find(const qint32& iID) { + if(iID == -1) + return(0); + for(int x = 0;x < count();x++) { if(at(x)->id() == iID) @@ -235,12 +271,24 @@ QList cSceneList::find(cChapter* lpChapter) for(int x = 0;x < count();x++) { - if(at(x)->chapter() == lpChapter) + if(at(x)->chapter() == lpChapter && !at(x)->deleted()) sceneList.append(at(x)); } return(sceneList); } +qint32 cSceneList::nextSort(cChapter* lpChapter) +{ + qint32 iSort = -1; + + for(int x = 0;x < count();x++) + { + if(lpChapter == at(x)->chapter() && iSort < at(x)->sortOrder()) + iSort = at(x)->sortOrder(); + } + return(iSort+1); +} + bool cSceneList::load(cChapterList* lpChapterList, cCharacterList *lpCharacterList, cObjectList *lpObjectList, cPlaceList *lpPlaceList) { QSqlQuery query; @@ -329,16 +377,29 @@ bool cSceneList::save() QSqlQuery queryUpdate; QSqlQuery queryInsert; QSqlQuery querySelect; + QSqlQuery queryDelete; queryUpdate.prepare("UPDATE scene SET name=:name, chapterID=:chapterID, sortOrder=:sortOrder, description=:description, state=:state, startedAt=:startedAt, finishedAt=:finishedAt, targetDate=:targetDate, text=:text WHERE id=:id;"); queryInsert.prepare("INSERT INTO scene (name, chapterID, sortOrder, description, state, startedAt, finishedAt, targetDate, text) VALUES (:name, :chapterID, :sortOrder, :description, :state, :startedAt, :finishedAt, :targetDate, :text);"); querySelect.prepare("SELECT id FROM scene WHERE _rowid_=(SELECT MAX(_rowid_) FROM part);"); + queryDelete.prepare("DELETE FROM scene WHERE id=:id;"); for(int x = 0;x < count();x++) { cScene* lpScene = at(x); - if(lpScene->id() != -1) + if(lpScene->deleted()) + { + queryDelete.bindValue(":id", lpScene->id()); + + if(!queryDelete.exec()) + { + myDebug << queryDelete.lastError().text(); + return(false); + } + this->removeOne(lpScene); + } + else if(lpScene->id() != -1) { queryUpdate.bindValue(":id", lpScene->id()); queryUpdate.bindValue(":name", lpScene->name()); diff --git a/cscene.h b/cscene.h index 9691596..2f66cfc 100644 --- a/cscene.h +++ b/cscene.h @@ -279,6 +279,52 @@ public: \return QColor */ static QColor stateColor(STATE state); + + /*! + \brief + + \fn setItem + \param lpItem + */ + void setItem(QStandardItem* lpItem); + /*! + \brief + + \fn item + \return QStandardItem + */ + QStandardItem* item(); + + /*! + \brief + + \fn setStateItem + \param lpItem + */ + void setStateItem(QStandardItem* lpItem); + /*! + \brief + + \fn stateItem + \return QStandardItem + */ + QStandardItem* stateItem(); + + /*! + \brief + + \fn setDeleted + \param bDeleted + */ + void setDeleted(bool bDeleted); + /*! + \brief + + \fn deleted + \return bool + */ + bool deleted(); + private: qint32 m_iID; /*!< TODO: describe */ cChapter* m_lpChapter; /*!< TODO: describe */ @@ -293,6 +339,9 @@ private: QList m_characterList; /*!< TODO: describe */ QList m_objectList; /*!< TODO: describe */ QList m_placeList; /*!< TODO: describe */ + QStandardItem* m_lpItem; /*!< TODO: describe */ + QStandardItem* m_lpStateItem; /*!< TODO: describe */ + bool m_bDeleted; /*!< TODO: describe */ }; Q_DECLARE_METATYPE(cScene*) @@ -349,6 +398,15 @@ public: \return QList */ QList find(cChapter* lpChapter); + + /*! + \brief + + \fn nextSort + \param lpPart + \return cPart + */ + qint32 nextSort(cChapter* lpChapter); }; #endif // CSCENE_H diff --git a/cscenewindow.cpp b/cscenewindow.cpp index 8f3269c..72548a6 100644 --- a/cscenewindow.cpp +++ b/cscenewindow.cpp @@ -253,6 +253,10 @@ void cSceneWindow::onObjectDoubleClicked(const QModelIndex& index) void cSceneWindow::onNameChanged(const QString& szName) { m_lpScene->setName(szName); + + if(m_lpScene->item()) + m_lpScene->item()->setText(szName); + m_lpMainWindow->somethingChanged(); } @@ -286,6 +290,9 @@ void cSceneWindow::onStateChanged(int index) m_lpScene->setState(cScene::STATE_unknown); break; } + m_lpScene->stateItem()->setBackground(QBrush(m_lpScene->stateColor())); + m_lpScene->stateItem()->setText(m_lpScene->stateText()); + m_lpMainWindow->somethingChanged(); } diff --git a/cstorybook.cpp b/cstorybook.cpp index 939203c..a7e35b3 100644 --- a/cstorybook.cpp +++ b/cstorybook.cpp @@ -494,6 +494,90 @@ bool cStoryBook::addPart(const QString& szPartName) return(true); } +bool cStoryBook::addChapter(cPart* lpPart, const QString& szChapterName) +{ + cChapter* lpChapter = m_chapterList.add(-1); + lpChapter->setName(szChapterName); + lpChapter->setPart(lpPart); + lpChapter->setSortOrder(m_chapterList.nextSort(lpPart)); + + return(true); +} + +bool cStoryBook::addScene(cChapter* lpChapter, const QString& szSceneName) +{ + cScene* lpScene = m_sceneList.add(-1); + lpScene->setName(szSceneName); + lpScene->setChapter(lpChapter); + lpScene->setSortOrder(m_sceneList.nextSort(lpChapter)); + + return(true); +} + +bool cStoryBook::addCharacter(const QString& szCharacterName) +{ + QString szFirstName; + QString szMiddleName; + QString szLastName; + QStringList list = szCharacterName.split(" "); + + if(list.count() == 1) + szFirstName = list.at(0); + else if(list.count() == 2) + { + szFirstName = list.at(0); + szLastName = list.at(1); + } + else + { + szFirstName = list.at(0); + szLastName = list.last(); + szMiddleName = list.at(1); + + for(int x = 2;x < list.count()-1;x++) + { + szMiddleName.append(" "); + szMiddleName.append(list.at(x)); + } + } + + cCharacter* lpCharacter = m_characterList.add(-1); + lpCharacter->setFirstName(szFirstName); + lpCharacter->setMiddleName(szMiddleName); + lpCharacter->setLastName(szLastName); + + return(true); +} + +bool cStoryBook::addPlace(const QString& szPlaceName) +{ + cPlace* lpPlace = m_placeList.add(-1); + lpPlace->setName(szPlaceName); + + return(true); +} + +bool cStoryBook::addObject(const QString& szObjectName) +{ + cObject* lpObject = m_objectList.add(-1); + lpObject->setName(szObjectName); + + return(true); +} + +bool cStoryBook::addRecherche(const QString& szRechercheName) +{ + cRecherche* lpRecherche = m_rechercheList.add(-1); + lpRecherche->setName(szRechercheName); + + return(true); +} + +bool cStoryBook::hasScene(cChapter* lpChapter) +{ + return(m_sceneList.find(lpChapter).count() > 0); +} + bool cStoryBook::fillOutlineList(QTreeView* lpView) { QMap part; @@ -524,6 +608,7 @@ bool cStoryBook::fillOutlineList(QTreeView* lpView) lpItem->setToolTip(lpPart->description()->toPlainText()); part.insert(lpPart->id(), lpItem); lpModel->appendRow(lpItem); + lpPart->setItem(lpItem); lpView->setFirstColumnSpanned(lpModel->rowCount()-1, lpModel->invisibleRootItem()->index(), true); } @@ -531,6 +616,10 @@ bool cStoryBook::fillOutlineList(QTreeView* lpView) for(int x = 0;x < m_chapterList.count();x++) { cChapter* lpChapter = m_chapterList.at(x); + + if(lpChapter->deleted()) + continue; + QStandardItem* lpRoot = part.value(lpChapter->part()->id()); if(lpRoot) @@ -540,9 +629,12 @@ bool cStoryBook::fillOutlineList(QTreeView* lpView) lpItem->setFont(fontChapter); lpItem->setForeground(QBrush(Qt::darkBlue)); lpItem->setBackground(QBrush(background)); - lpItem->setToolTip(lpChapter->description()->toPlainText()); + if(lpChapter->description()) + lpItem->setToolTip(lpChapter->description()->toPlainText()); chapter.insert(lpChapter->id(), lpItem); lpRoot->appendRow(lpItem); + lpChapter->setItem(lpItem); + lpView->setFirstColumnSpanned(lpRoot->rowCount()-1, lpRoot->index(), true); } } @@ -550,6 +642,10 @@ bool cStoryBook::fillOutlineList(QTreeView* lpView) for(int x = 0;x < m_sceneList.count();x++) { cScene* lpScene = m_sceneList.at(x); + + if(lpScene->deleted()) + continue; + QStandardItem* lpChapterItem = chapter.value(lpScene->chapter()->id()); if(lpChapterItem) @@ -562,12 +658,16 @@ bool cStoryBook::fillOutlineList(QTreeView* lpView) lpItems[0]->setData(QVariant::fromValue(lpScene)); lpItems[0]->setFont(fontScene); lpItems[0]->setForeground(QBrush(Qt::blue)); - lpItems[0]->setToolTip(lpScene->description()->toPlainText()); + if(lpScene->description()) + lpItems[0]->setToolTip(lpScene->description()->toPlainText()); lpItems[1]->setData(QVariant::fromValue(lpScene)); lpItems[1]->setBackground(QBrush(lpScene->stateColor())); lpItems[1]->setTextAlignment(Qt::AlignCenter); - lpItems[1]->setToolTip(lpScene->description()->toPlainText()); + if(lpScene->description()) + lpItems[1]->setToolTip(lpScene->description()->toPlainText()); + lpScene->setItem(lpItems[0]); + lpScene->setStateItem(lpItems[1]); lpChapterItem->appendRow(lpItems); } @@ -618,7 +718,8 @@ bool cStoryBook::fillCharacterList(QTreeView* lpView) else lpItems[i]->setFont(fontNonMainCharacter); - lpItems[i]->setToolTip(lpCharacter->description()->toPlainText()); + if(lpCharacter->description()) + lpItems[i]->setToolTip(lpCharacter->description()->toPlainText()); } lpModel->appendRow(lpItems); @@ -655,7 +756,8 @@ bool cStoryBook::fillPlaceList(QTreeView* lpView) for(int i = 0;i < headerLabels.count();i++) { lpItems[i]->setData(QVariant::fromValue(lpPlace)); - lpItems[i]->setToolTip(lpPlace->description()->toPlainText()); + if(lpPlace->description()) + lpItems[i]->setToolTip(lpPlace->description()->toPlainText()); } lpModel->appendRow(lpItems); @@ -691,7 +793,8 @@ bool cStoryBook::fillObjectList(QTreeView* lpView) for(int i = 0;i < headerLabels.count();i++) { lpItems[i]->setData(QVariant::fromValue(lpObject)); - lpItems[i]->setToolTip(lpObject->description()->toPlainText()); + if(lpObject->description()) + lpItems[i]->setToolTip(lpObject->description()->toPlainText()); } lpModel->appendRow(lpItems); @@ -727,7 +830,8 @@ bool cStoryBook::fillRechercheList(QTreeView* lpView) for(int i = 0;i < headerLabels.count();i++) { lpItems[i]->setData(QVariant::fromValue(lpRecherche)); - lpItems[i]->setToolTip(lpRecherche->description()->toPlainText()); + if(lpRecherche->description()) + lpItems[i]->setToolTip(lpRecherche->description()->toPlainText()); } lpModel->appendRow(lpItems); diff --git a/cstorybook.h b/cstorybook.h index b8bc536..c084468 100644 --- a/cstorybook.h +++ b/cstorybook.h @@ -146,6 +146,72 @@ public: \return bool */ bool addPart(const QString& szPartName); + + /*! + \brief + + \fn addChapter + \param lpPart + \param szChapterName + \return bool + */ + bool addChapter(cPart* lpPart, const QString& szChapterName); + + /*! + \brief + + \fn addScene + \param lpChapter + \param szSceneName + \return bool + */ + bool addScene(cChapter* lpChapter, const QString& szSceneName); + + /*! + \brief + + \fn addCharacter + \param szCharacterName + \return bool + */ + bool addCharacter(const QString& szCharacterName); + + /*! + \brief + + \fn addPlace + \param szPlaceName + \return bool + */ + bool addPlace(const QString& szPlaceName); + + /*! + \brief + + \fn addObject + \param szObjectName + \return bool + */ + bool addObject(const QString& szObjectName); + + /*! + \brief + + \fn addRecherche + \param szRechercheName + \return bool + */ + bool addRecherche(const QString& szRechercheName); + + /*! + \brief + + \fn addRecherche + \param szRechercheName + \return bool + */ + bool hasScene(cChapter* lpChapter); + private: QString m_szProject; /*!< TODO: describe */ bool m_bIsOpen; /*!< TODO: describe */ @@ -247,6 +313,12 @@ private: */ bool loadImageList(); + /*! + \brief + + \fn saveBook + \return bool + */ bool saveBook(); /*! \brief