From 5ab627b7351378995c2a5f6992832fa266433080 Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Fri, 4 Sep 2015 10:54:37 +0200 Subject: [PATCH] ui: reworked StartScreen and ProjectSettupScreen UI flow * realigned buttons and elements * fixed retina styles for mac * removed MessageLoadSource and subsequent functionality * edit existing project through menu * browsing paths from the line item in QtDirectoryListBox * grow QtDirectoryListBox instead of scroll * take any file or directory as valid path * fixed new project setup screen background * fixed screen handling on cancelation --- bin/app/data/gui/settingwindows/listbox.css | 67 +++++-- .../data/gui/settingwindows/projectsetup.css | 70 ++++--- .../data/gui/startscreen/logo_schriftzug.png | Bin 36778 -> 54976 bytes bin/app/data/gui/startscreen/startscreen.css | 35 ++-- src/app/CMakeLists.txt | 2 + src/app/qt/element/QtDirectoryListBox.cpp | 187 ++++++++++++----- src/app/qt/element/QtDirectoryListBox.h | 54 ++++- src/app/qt/element/QtLineEdit.cpp | 12 ++ src/app/qt/element/QtLineEdit.h | 21 ++ src/app/qt/element/QtMainWindow.cpp | 92 +++++++-- src/app/qt/element/QtMainWindow.h | 11 + src/app/qt/element/QtProjectSetupScreen.cpp | 188 ++++++++++++------ src/app/qt/element/QtProjectSetupScreen.h | 59 ++++-- src/app/qt/element/QtSettingsWindow.cpp | 55 ++--- src/app/qt/element/QtSettingsWindow.h | 21 +- src/app/qt/element/QtStartScreen.cpp | 27 +-- src/app/qt/element/QtStartScreen.h | 9 +- src/lib/Application.cpp | 20 -- src/lib/Application.h | 3 - src/lib/CMakeLists.txt | 1 - src/lib/Project.cpp | 14 -- src/lib/Project.h | 2 - .../controller/UndoRedoController.cpp | 5 - .../component/controller/UndoRedoController.h | 3 - src/lib/data/Storage.cpp | 5 + src/lib/settings/ProjectSettings.cpp | 25 ++- src/lib/settings/ProjectSettings.h | 3 + src/lib/settings/Settings.cpp | 10 +- src/lib/settings/Settings.h | 3 +- .../messaging/type/MessageLoadSource.h | 22 -- 30 files changed, 688 insertions(+), 338 deletions(-) create mode 100644 src/app/qt/element/QtLineEdit.cpp create mode 100644 src/app/qt/element/QtLineEdit.h delete mode 100644 src/lib/utility/messaging/type/MessageLoadSource.h diff --git a/bin/app/data/gui/settingwindows/listbox.css b/bin/app/data/gui/settingwindows/listbox.css index 89782c7a..8b452bbf 100644 --- a/bin/app/data/gui/settingwindows/listbox.css +++ b/bin/app/data/gui/settingwindows/listbox.css @@ -1,27 +1,64 @@ -.QtDirectoryListBox { - border: 1px solid lightgray; - border-radius: 15px; - background-color: rgba(255, 255, 255, 200); +QtDirectoryListBox { + background-color: rgba(255, 255, 255, 200); + border: 1px solid lightgray; + border-radius: 12px; } -.QListWidget { - border: none; - background: transparent; +QListWidget { + background: transparent; + border: none; + margin: 2px 0 2px 0; +} + +QListWidget::item { + border-bottom: 1px solid lightgray; + height: 20px; +} + +QListWidget::item:selected { + background-color: #EEE; +} + + +QtListItemWidget #field { + background-color: transparent; + border: none; + font-size: 12px; + margin-top: 2px; +} + +QtListItemWidget #button { + border: 1px solid lightgray; + border-radius: 8px; + font-size: 12px; + margin-top: 2px; + margin-right: 2px; + width: 20px; +} + +QtListItemWidget #button:hover { + color: white; + background: #2D3F85; +} + +#bar { + border-top: 1px solid lightgray; } #roundedButton { - font-size: 15px; - color: white; - border-radius: 10px; - background: dimgray; - width: 20px; - height: 20px; + background: dimgray; + border-radius: 8px; + color: white; + font-size: 15px; + height: 16px; + margin-right: 3px; + width: 16px; } #roundedButton:hover { - background: lightgray; + background: gray; } #dropInfo { - color: lightgray; + color: lightgray; } diff --git a/bin/app/data/gui/settingwindows/projectsetup.css b/bin/app/data/gui/settingwindows/projectsetup.css index 38a9ffe8..09b1e20b 100644 --- a/bin/app/data/gui/settingwindows/projectsetup.css +++ b/bin/app/data/gui/settingwindows/projectsetup.css @@ -1,39 +1,63 @@ +#titleLabel { + color: black; + font-size: 16pt; + font-weight: bold; +} + QLineEdit { - border-radius: 10px; - border: 1px solid lightgrey; - background-color: rgba(255, 255, 255, 200); + background-color: rgba(255, 255, 255, 200); + border-radius: 10px; + border: 1px solid lightgrey; + padding-left: 5px; + padding-right: 5px; +} + +QLineEdit:disabled { + border: 1px solid lightgrey; +} + +#formArea { + background-color: transparent; + border: none; + border-top: 1px solid lightgrey; + border-bottom: 1px solid lightgrey; } #form { - background-color: rgba(255, 255, 255, 200); - border: none; + background-color: rgba(255, 255, 255, 220); +} + +#form QLabel { + font-weight: bold; } #moreButton { - font-size: 15px; - margin-left: 10px; - color: gray; - border-radius: 10px; - border: 1px solid lightgray; - background: white; - width: 40px; - height: 20px; + background-color: rgba(255, 255, 255, 200); + border: 1px solid lightgray; + border-radius: 10px; + color: gray; + font-size: 15px; + height: 20px; + margin-left: 10px; + width: 28px; } -#moreutton:hover { - background: lightgray; +#moreButton:hover { + color: white; + background: #2D3F85; } #windowButton { - margin-left: 10px; - color: black; - border-radius: 10px; - border: 1px solid lightgray; - background: white; - width: 40px; - height: 20px; + background: white; + border: 1px solid lightgray; + border-radius: 10px; + color: black; + font-size: 17pt; + height: 30px; + width: 140px; } #windowButton:hover { - background: lightgray; + color: white; + background: #2D3F85; } diff --git a/bin/app/data/gui/startscreen/logo_schriftzug.png b/bin/app/data/gui/startscreen/logo_schriftzug.png index 02807313051244ff50fffa7c57be4c0402868796..ac955102c8cba1c3de5da5e82287055bd7f888ac 100755 GIT binary patch literal 54976 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�+UA6|PB84?5dDf-^=DHsAsGpg8su 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 Rf}en&l$g9|weYu}{|9_XNd^D_ literal 36778 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 V*6)};h{Ls0l2el{d-^uue*n=z?kNBO diff --git a/bin/app/data/gui/startscreen/startscreen.css b/bin/app/data/gui/startscreen/startscreen.css index c59555ff..3be3e854 100644 --- a/bin/app/data/gui/startscreen/startscreen.css +++ b/bin/app/data/gui/startscreen/startscreen.css @@ -1,28 +1,35 @@ #projectButton { + background: white; + border: 1px solid lightgray; + border-radius: 10px; font-size: 17pt; - border: 1px solid lightgray; - border-radius: 10px; - background: white; } #projectButton:hover { - color: white; - background: navy; + background: #2D3F85; + color: white; } -#recentButton{ - font-size: 12pt; - color: black; - background: none; - border: none; +#recentButton { + background: none; + border: none; + color: black; + font-size: 12pt; } -#recentButton:hover{ - background: lightgray; - border-radius: 10px; +#recentButton:hover { + background-color: rgba(45, 63, 133, 70); + border-radius: 10px; } #recentLabel { - font-size: 16pt; color: black; + font-size: 16pt; + font-weight: bold; +} + +QToolTip { + background-color: ; + color: ; + font-size: pt; } diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 028d0574..6032b91e 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -17,6 +17,8 @@ add_files( qt/element/QtCodeSnippet.h qt/element/QtDirectoryListBox.cpp qt/element/QtDirectoryListBox.h + qt/element/QtLineEdit.cpp + qt/element/QtLineEdit.h qt/element/QtMainWindow.cpp qt/element/QtMainWindow.h qt/element/QtProjectSetupScreen.cpp diff --git a/src/app/qt/element/QtDirectoryListBox.cpp b/src/app/qt/element/QtDirectoryListBox.cpp index c763aa86..7ea17d0e 100644 --- a/src/app/qt/element/QtDirectoryListBox.cpp +++ b/src/app/qt/element/QtDirectoryListBox.cpp @@ -3,46 +3,113 @@ #include #include #include -#include #include #include "qt/utility/utilityQt.h" +QtListItemWidget::QtListItemWidget(QtDirectoryListBox* list, QListWidgetItem* item, QWidget *parent) + : QWidget(parent) + , m_list(list) + , m_item(item) +{ + QBoxLayout* layout = new QHBoxLayout(); + layout->setSpacing(3); + layout->setContentsMargins(0, 0, 0, 0); + layout->setAlignment(Qt::AlignTop); + + m_data = new QtLineEdit(this); + m_data->setAttribute(Qt::WA_MacShowFocusRect, 0); + m_data->setObjectName("field"); + + m_button = new QPushButton("..."); + m_button->setObjectName("button"); + + layout->addWidget(m_data); + layout->addWidget(m_button); + + setLayout(layout); + + connect(m_button, SIGNAL(clicked()), this, SLOT(handleButtonPress())); + connect(m_data, SIGNAL(focus()), this, SLOT(handleFocus())); +} + +QString QtListItemWidget::getText() +{ + return m_data->text(); +} + +void QtListItemWidget::setText(QString text) +{ + m_data->setText(text); +} + +void QtListItemWidget::setFocus() +{ + m_data->setFocus(Qt::OtherFocusReason); +} + +void QtListItemWidget::handleButtonPress() +{ + QFileDialog dialog(this); + if (dialog.exec()) + { + QStringList list = dialog.selectedFiles(); + for (int i = 0; i < list.size(); i++) + { + setText(list.at(i)); + } + } + + handleFocus(); +} + +void QtListItemWidget::handleFocus() +{ + m_list->selectItem(m_item); +} + + QtDirectoryListBox::QtDirectoryListBox(QWidget *parent) - :QFrame(parent) + :QFrame(parent) { - setObjectName("QtListBox"); - setMinimumHeight(150); QBoxLayout* layout = new QVBoxLayout(); layout->setSpacing(0); - layout->setContentsMargins(10, 10, 10, 10); + layout->setContentsMargins(0, 6, 0, 0); layout->setAlignment(Qt::AlignTop); + m_list = new QListWidget(this); + m_list->setObjectName("list"); + m_list->setAttribute(Qt::WA_MacShowFocusRect, 0); setStyleSheet(utility::getStyleSheet("data/gui/settingwindows/listbox.css").c_str()); layout->addWidget(m_list); QWidget* buttonContainer = new QWidget(this); - QBoxLayout* innerLayout = new QHBoxLayout(); - innerLayout->setContentsMargins(0,0,0,0); + buttonContainer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + buttonContainer->setObjectName("bar"); - m_addButton = new QPushButton("+",this); - m_addButton->resize(20,20); - m_addButton->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); + QHBoxLayout* innerLayout = new QHBoxLayout(); + innerLayout->setContentsMargins(8, 4, 8, 3); + innerLayout->setSpacing(0); + + m_addButton = new QPushButton("+", this); + m_addButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_addButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac m_addButton->setObjectName("roundedButton"); innerLayout->addWidget(m_addButton); - m_removeButton = new QPushButton("-",this); - m_removeButton->resize(20,20); - m_removeButton->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); + m_removeButton = new QPushButton("-", this); + m_removeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_removeButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac m_removeButton->setObjectName("roundedButton"); innerLayout->addWidget(m_removeButton); - QLabel* dropInfoText = new QLabel("You can drop Folders here"); - dropInfoText->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); + QLabel* dropInfoText = new QLabel("Drop Files & Folders"); + dropInfoText->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); dropInfoText->setObjectName("dropInfo"); dropInfoText->setAlignment(Qt::AlignRight); innerLayout->addWidget(dropInfoText); + buttonContainer->setLayout(innerLayout); layout->addWidget(buttonContainer); setLayout(layout); @@ -51,6 +118,7 @@ QtDirectoryListBox::QtDirectoryListBox(QWidget *parent) connect(m_removeButton, SIGNAL(clicked()), this, SLOT(removeListBoxItem())); setAcceptDrops(true); + resize(); } void QtDirectoryListBox::dropEvent(QDropEvent *event) @@ -58,62 +126,79 @@ void QtDirectoryListBox::dropEvent(QDropEvent *event) QFileInfo fileInfo; foreach(QUrl url, event->mimeData()->urls()) { - fileInfo.setFile(url.toLocalFile()); - if(fileInfo.isDir()) - { - QListWidgetItem *item = new QListWidgetItem(m_list); - m_list->addItem(item); - item->setText(url.toLocalFile()); - } + QtListItemWidget* widget = addListBoxItem(); + widget->setText(url.toLocalFile()); } } std::vector QtDirectoryListBox::getList() { std::vector list; - for( int i = 0; i < m_list->count(); ++i) + for (int i = 0; i < m_list->count(); ++i) { - QListWidgetItem* item = m_list->item(i); - list.push_back(item->text().toStdString()); + QtListItemWidget* widget = dynamic_cast(m_list->itemWidget(m_list->item(i))); + list.push_back(widget->getText().toStdString()); } - return list; } -void QtDirectoryListBox::addListBoxItem() +void QtDirectoryListBox::setList(const std::vector& list) { - QFileDialog dialog(this); - dialog.setFileMode(QFileDialog::DirectoryOnly); - dialog.setOption(QFileDialog::ShowDirsOnly, true); - dialog.setOption(QFileDialog::DontUseNativeDialog,true); + m_list->clear(); - // enable multiselection of directories - QListView *l = dialog.findChild("listView"); - if (l) - { - l->setSelectionMode(QAbstractItemView::MultiSelection); - } - QTreeView *t = dialog.findChild(); - if (t) - { - t->setSelectionMode(QAbstractItemView::MultiSelection); - } - - if(dialog.exec()) + for (const FilePath& path : list) { - QStringList list = dialog.selectedFiles(); - for(int i = 0; i < list.size(); i++) - { - QListWidgetItem *item = new QListWidgetItem(m_list); - m_list->addItem(item); - item->setText(list.at(i)); - } + QtListItemWidget* widget = addListBoxItem(); + widget->setText(QString::fromStdString(path.str())); } } +void QtDirectoryListBox::selectItem(QListWidgetItem* item) +{ + for (int i = 0; i < m_list->count(); i++) + { + m_list->item(i)->setSelected(false); + } + + item->setSelected(true); +} + +void QtDirectoryListBox::resize() +{ + int height = 25; + + if (m_list->count() > 0) + { + height += (m_list->itemWidget(m_list->item(0))->height() + 1) * m_list->count() + 8; + } + + if (height < 150) + { + height = 150; + } + + setMinimumHeight(height); +} + +QtListItemWidget* QtDirectoryListBox::addListBoxItem() +{ + QListWidgetItem *item = new QListWidgetItem(m_list); + m_list->addItem(item); + + QtListItemWidget* widget = new QtListItemWidget(this, item); + m_list->setItemWidget(item, widget); + + resize(); + + widget->setFocus(); + + return widget; +} + void QtDirectoryListBox::removeListBoxItem() { qDeleteAll(m_list->selectedItems()); + resize(); } void QtDirectoryListBox::dragEnterEvent(QDragEnterEvent *event) diff --git a/src/app/qt/element/QtDirectoryListBox.h b/src/app/qt/element/QtDirectoryListBox.h index 33f1c732..ca85e431 100644 --- a/src/app/qt/element/QtDirectoryListBox.h +++ b/src/app/qt/element/QtDirectoryListBox.h @@ -1,30 +1,72 @@ -#ifndef QT_DIRECTORYLISTBOX_H -#define QT_DIRECTORYLISTBOX_H +#ifndef QT_DIRECTORY_LIST_BOX_H +#define QT_DIRECTORY_LIST_BOX_H #include +#include #include #include #include #include "utility/file/FilePath.h" -class QtDirectoryListBox : public QFrame +#include "qt/element/QtLineEdit.h" + +class QtDirectoryListBox; + +class QtListItemWidget + : public QWidget { -Q_OBJECT + Q_OBJECT + +public: + QtListItemWidget(QtDirectoryListBox* list, QListWidgetItem* item, QWidget *parent = nullptr); + + QString getText(); + void setText(QString text); + +public slots: + void setFocus(); + +private slots: + void handleButtonPress(); + void handleFocus(); + +private: + QPushButton* m_button; + QtLineEdit* m_data; + + QtDirectoryListBox* m_list; + QListWidgetItem* m_item; +}; + + +class QtDirectoryListBox + : public QFrame +{ + Q_OBJECT + public: QtDirectoryListBox(QWidget *parent); + std::vector getList(); + void setList(const std::vector& list); + + void selectItem(QListWidgetItem* item); + protected: void dropEvent(QDropEvent *event); void dragEnterEvent(QDragEnterEvent* event); + private: + void resize(); + QPushButton* m_addButton; QPushButton* m_removeButton; QListWidget* m_list; private slots: - void addListBoxItem(); + QtListItemWidget* addListBoxItem(); void removeListBoxItem(); }; -#endif //QT_DIRECTORYLISTBOX_H +#endif // QT_DIRECTORY_LIST_BOX_H diff --git a/src/app/qt/element/QtLineEdit.cpp b/src/app/qt/element/QtLineEdit.cpp new file mode 100644 index 00000000..9fe002f1 --- /dev/null +++ b/src/app/qt/element/QtLineEdit.cpp @@ -0,0 +1,12 @@ +#include "qt/element/QtLineEdit.h" + +QtLineEdit::QtLineEdit(QWidget* parent) + : QLineEdit(parent) +{ +} + +void QtLineEdit::focusInEvent(QFocusEvent* event) +{ + emit focus(); + QLineEdit::focusInEvent(event); +} diff --git a/src/app/qt/element/QtLineEdit.h b/src/app/qt/element/QtLineEdit.h new file mode 100644 index 00000000..3d604d9a --- /dev/null +++ b/src/app/qt/element/QtLineEdit.h @@ -0,0 +1,21 @@ +#ifndef QT_LINE_EDIT_H +#define QT_LINE_EDIT_H + +#include + +class QtLineEdit + : public QLineEdit +{ + Q_OBJECT + +public: + QtLineEdit(QWidget* parent = nullptr); + +signals: + void focus(); + +protected: + void focusInEvent(QFocusEvent* event); +}; + +#endif // QT_LINE_EDIT_H diff --git a/src/app/qt/element/QtMainWindow.cpp b/src/app/qt/element/QtMainWindow.cpp index 18ea08bc..ba7faed6 100644 --- a/src/app/qt/element/QtMainWindow.cpp +++ b/src/app/qt/element/QtMainWindow.cpp @@ -16,7 +16,6 @@ #include "utility/messaging/type/MessageFind.h" #include "utility/messaging/type/MessageInterruptTasks.h" #include "utility/messaging/type/MessageLoadProject.h" -#include "utility/messaging/type/MessageLoadSource.h" #include "utility/messaging/type/MessageRedo.h" #include "utility/messaging/type/MessageRefresh.h" #include "utility/messaging/type/MessageSaveProject.h" @@ -26,6 +25,7 @@ #include "utility/messaging/type/MessageZoom.h" QtMainWindow::QtMainWindow() + : m_startScreenWasVisible(false) { setObjectName("QtMainWindow"); setCentralWidget(nullptr); @@ -50,10 +50,7 @@ QtMainWindow::QtMainWindow() void QtMainWindow::init() { - // StartScreen - m_startScreen = std::make_shared(this); - m_startScreen->setup(); - m_startScreen->show(); + showStartScreen(); } @@ -157,10 +154,66 @@ void QtMainWindow::about() ); } +void QtMainWindow::hideScreens() +{ + if (m_startScreen) + { + m_startScreen->hide(); + } + + if (m_newProjectDialog) + { + m_newProjectDialog->hide(); + } +} + +void QtMainWindow::restoreScreens() +{ + hideScreens(); + + if (m_startScreen && m_startScreenWasVisible) + { + m_startScreen->show(); + } + + m_startScreenWasVisible = false; +} + +void QtMainWindow::showStartScreen() +{ + if (!m_startScreen) + { + m_startScreen = std::make_shared(this); + m_startScreen->setup(); + connect(m_startScreen.get(), SIGNAL(finished()), this, SLOT(hideScreens())); + } + + m_startScreen->show(); + m_startScreenWasVisible = true; + + if (m_newProjectDialog) + { + m_newProjectDialog->hide(); + } +} + void QtMainWindow::newProject() { - m_newProjectDialog = std::make_shared(this); - m_newProjectDialog->setup(); + if (m_startScreen) + { + m_startScreen->hide(); + } + + if (!m_newProjectDialog) + { + m_newProjectDialog = std::make_shared(this); + m_newProjectDialog->setup(); + + connect(m_newProjectDialog.get(), SIGNAL(finished()), this, SLOT(hideScreens())); + connect(m_newProjectDialog.get(), SIGNAL(canceled()), this, SLOT(restoreScreens())); + } + + m_newProjectDialog->loadEmpty(); m_newProjectDialog->show(); } @@ -179,6 +232,12 @@ void QtMainWindow::openProject(const QString &path) } } +void QtMainWindow::editProject() +{ + newProject(); + m_newProjectDialog->loadProjectSettings(); +} + void QtMainWindow::find() { MessageFind().dispatch(); @@ -248,14 +307,6 @@ void QtMainWindow::switchColorScheme() void QtMainWindow::handleEscapeShortcut() { - if(m_startScreen) - { - m_startScreen->hide(); - } - if(m_newProjectDialog) - { - m_newProjectDialog->hide(); - } MessageInterruptTasks().dispatch(); } @@ -264,10 +315,13 @@ void QtMainWindow::setupProjectMenu() QMenu *menu = new QMenu(tr("&Project"), this); menuBar()->addMenu(menu); - menu->addAction(tr("Ope&n Source Folder..."), this, SLOT(newProject()), QKeySequence::New); - menu->addAction(tr("&Open Coati Project..."), this, SLOT(openProject()), QKeySequence::Open); - menu->addAction(tr("&Save"), this, SLOT(saveProject()), QKeySequence::Save); - menu->addAction(tr("Save as..."), this, SLOT(saveAsProject()), QKeySequence::SaveAs); + menu->addAction(tr("&New Project..."), this, SLOT(newProject()), QKeySequence::New); + menu->addAction(tr("&Open Project..."), this, SLOT(openProject()), QKeySequence::Open); + menu->addAction(tr("&Edit Project..."), this, SLOT(editProject())); + + menu->addAction(tr("&Save Project"), this, SLOT(saveProject()), QKeySequence::Save); + menu->addAction(tr("Save Project as..."), this, SLOT(saveAsProject()), QKeySequence::SaveAs); + menu->addAction(tr("&Close Window"), this, SLOT(closeWindow()), QKeySequence::Close); menu->addAction(tr("E&xit"), QCoreApplication::instance(), SLOT(quit()), QKeySequence::Quit); } diff --git a/src/app/qt/element/QtMainWindow.h b/src/app/qt/element/QtMainWindow.h index 907fe9b8..deace827 100644 --- a/src/app/qt/element/QtMainWindow.h +++ b/src/app/qt/element/QtMainWindow.h @@ -38,14 +38,23 @@ protected: public slots: void about(); + void hideScreens(); + void restoreScreens(); + void showStartScreen(); + void newProject(); void openProject(const QString &path = QString()); + void editProject(); + void find(); void closeWindow(); void refresh(); + void saveProject(); void saveAsProject(); + void showLicences(); + void undo(); void redo(); void zoomIn(); @@ -70,6 +79,8 @@ private: std::vector> m_dockWidgets; QShortcut* m_escapeShortcut; + + bool m_startScreenWasVisible; }; #endif // QT_MAIN_WINDOW_H diff --git a/src/app/qt/element/QtProjectSetupScreen.cpp b/src/app/qt/element/QtProjectSetupScreen.cpp index 293d2567..724f4680 100644 --- a/src/app/qt/element/QtProjectSetupScreen.cpp +++ b/src/app/qt/element/QtProjectSetupScreen.cpp @@ -4,11 +4,11 @@ #include #include #include +#include #include #include #include - #include "settings/ProjectSettings.h" #include "utility/logging/logging.h" #include "qt/utility/QtDeviceScaledPixmap.h" @@ -16,7 +16,7 @@ #include "qt/utility/utilityQt.h" QtTextLine::QtTextLine(QWidget *parent) - :QWidget(parent) + : QWidget(parent) { QBoxLayout* layout = new QHBoxLayout(); layout->setSpacing(0); @@ -25,14 +25,19 @@ QtTextLine::QtTextLine(QWidget *parent) setLayout(layout); - m_data = new QLineEdit(this); + m_data = new QtLineEdit(this); + m_data->setAttribute(Qt::WA_MacShowFocusRect, 0); + m_data->setObjectName("locationField"); + m_data->setReadOnly(true); + m_button = new QPushButton("..."); - m_button->setMaximumWidth(40); m_button->setObjectName("moreButton"); + layout->addWidget(m_data); layout->addWidget(m_button); connect(m_button, SIGNAL(clicked()), this, SLOT(handleButtonPress())); + connect(m_data, SIGNAL(focus()), this, SLOT(handleButtonPress())); } QString QtTextLine::getText() @@ -47,7 +52,7 @@ void QtTextLine::setText(QString text) void QtTextLine::handleButtonPress() { - QString file = QFileDialog::getExistingDirectory(this, tr("Select File"), ""); + QString file = QFileDialog::getExistingDirectory(this, tr("Select Directory"), ""); if (!file.isEmpty()) { m_data->setText(file); @@ -62,121 +67,180 @@ QtProjectSetupScreen::QtProjectSetupScreen(QWidget *parent) void QtProjectSetupScreen::setup() { + QtDeviceScaledPixmap coati_logo("data/gui/startscreen/logo.png"); + coati_logo.scaleToWidth(400); + QLabel* coatiLogoLabel = new QLabel(m_window); + coatiLogoLabel->setPixmap(coati_logo.pixmap()); + coatiLogoLabel->resize(coati_logo.width(), coati_logo.height()); + coatiLogoLabel->move(100, 100); + setStyleSheet(utility::getStyleSheet("data/gui/settingwindows/projectsetup.css").c_str()); QVBoxLayout* windowLayout = new QVBoxLayout(); - windowLayout->setContentsMargins(20,30,20,20); - QLabel* windowTitleLabel = new QLabel("NEW PROJECT"); - windowLayout->addWidget(windowTitleLabel); + windowLayout->setContentsMargins(25, 30, 25, 20); + + m_title = new QLabel(); + m_title->setObjectName("titleLabel"); + windowLayout->addWidget(m_title); windowLayout->addSpacing(30); QScrollArea* scrollArea = new QScrollArea(); - scrollArea->setObjectName("coatiBackground"); + scrollArea->setObjectName("formArea"); + scrollArea->setFrameShadow(QFrame::Plain); + scrollArea->setWidgetResizable(true); + QWidget* form = new QWidget(); form->setObjectName("form"); scrollArea->setWidget(form); - scrollArea->setFrameShadow(QFrame::Plain); - scrollArea->setWidgetResizable(true); - QFormLayout *layout = new QFormLayout(); - layout->setContentsMargins(20,30,20,20); - //Background Image - QPalette p = palette(); - QPixmap pixmap1("data/gui/startscreen/logo.png"); - QRect rect = scrollArea->rect(); - QSize size(rect.width()-90,rect.height()); - QPixmap pixmap(pixmap1.scaled(size)); - p.setBrush(QPalette::Background, pixmap); - scrollArea->setPalette(p); + QFormLayout *layout = new QFormLayout(); + layout->setContentsMargins(10, 10, 10, 10); + layout->setHorizontalSpacing(20); + + int minimumWidthForSecondCol = 360; QLabel* nameLabel = new QLabel("Name"); m_projectName = new QLineEdit(); + m_projectName->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + m_projectName->setMinimumWidth(minimumWidthForSecondCol); + m_projectName->setAttribute(Qt::WA_MacShowFocusRect, 0); layout->addRow(nameLabel, m_projectName); QLabel* locationLabel = new QLabel("Location"); m_projectFileLocation = new QtTextLine(this); + m_projectFileLocation->setMinimumWidth(minimumWidthForSecondCol); layout->addRow(locationLabel, m_projectFileLocation); - /* QLabel* languageLabel = new QLabel("Language"); QComboBox* language = new QComboBox(); language->insertItem(0, "C++"); layout->addRow(languageLabel, language); - */ - QLabel* sourcePathsLabel = new QLabel("Sourcepaths"); + QLabel* sourcePathsLabel = new QLabel("Source Paths"); m_sourcePaths = new QtDirectoryListBox(this); + m_sourcePaths->setMinimumWidth(minimumWidthForSecondCol); layout->addRow(sourcePathsLabel, m_sourcePaths); - QLabel* includePathsLabel = new QLabel("IncludePaths"); + QLabel* includePathsLabel = new QLabel("Include Paths"); m_includePaths = new QtDirectoryListBox(this); + m_includePaths->setMinimumWidth(minimumWidthForSecondCol); layout->addRow(includePathsLabel, m_includePaths); - if(QSysInfo::macVersion() != QSysInfo::MV_None) + if (QSysInfo::macVersion() != QSysInfo::MV_None) { - QLabel* frameworkPathsLabel = new QLabel("FrameworkPaths"); + QLabel* frameworkPathsLabel = new QLabel("Framework Paths"); m_frameworkPaths = new QtDirectoryListBox(this); + m_frameworkPaths->setMinimumWidth(minimumWidthForSecondCol); layout->addRow(frameworkPathsLabel, m_frameworkPaths); } + form->setLayout(layout); - QPushButton* createButton = new QPushButton("Create"); - createButton->setObjectName("windowButton"); - QPushButton* cancelButton = new QPushButton("Cancel"); - cancelButton->setObjectName("windowButton"); + m_createButton = new QPushButton("Create"); + m_createButton->setObjectName("windowButton"); + m_cancelButton = new QPushButton("Cancel"); + m_cancelButton->setObjectName("windowButton"); + m_updateButton = new QPushButton("Update"); + m_updateButton->setObjectName("windowButton"); - connect(createButton, SIGNAL(clicked()), this, SLOT(handleCreateButtonPress())); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(handleCancelButtonPress())); + connect(m_createButton, SIGNAL(clicked()), this, SLOT(handleCreateButtonPress())); + connect(m_cancelButton, SIGNAL(clicked()), this, SLOT(handleCancelButtonPress())); + connect(m_updateButton, SIGNAL(clicked()), this, SLOT(handleUpdateButtonPress())); QHBoxLayout* buttons = new QHBoxLayout(); - buttons->addSpacing(100); - buttons->addWidget(createButton); - buttons->addWidget(cancelButton); - buttons->addSpacing(30); + buttons->addWidget(m_cancelButton); + buttons->addStretch(); + buttons->addWidget(m_createButton); + buttons->addWidget(m_updateButton); windowLayout->addWidget(scrollArea); windowLayout->addSpacing(20); windowLayout->addLayout(buttons); m_window->setLayout(windowLayout); - resize(QSize(600,600)); + resize(QSize(600, 620)); + + scrollArea->raise(); } -void QtProjectSetupScreen::handleCancelButtonPress() +void QtProjectSetupScreen::loadEmpty() { - hide(); + m_updateButton->hide(); + m_createButton->show(); + + m_title->setText("NEW PROJECT"); +} + +void QtProjectSetupScreen::loadProjectSettings() +{ + m_updateButton->show(); + m_createButton->hide(); + + m_title->setText("EDIT PROJECT"); + + ProjectSettings* projSettings = ProjectSettings::getInstance().get(); + + m_projectName->setText(QString::fromStdString(projSettings->getFilePath().withoutExtension().fileName())); + m_projectFileLocation->setText(QString::fromStdString(projSettings->getFilePath().parentDirectory().str())); + + m_sourcePaths->setList(projSettings->getSourcePaths()); + m_includePaths->setList(projSettings->getHeaderSearchPaths()); + m_frameworkPaths->setList(projSettings->getFrameworkSearchPaths()); } void QtProjectSetupScreen::handleCreateButtonPress() { - bool error = false; - if(m_projectName->text().isEmpty()) + if (m_projectName->text().isEmpty()) { QMessageBox msgBox; - msgBox.setText("Please Enter a Project Name"); + msgBox.setText("Please enter a project name."); msgBox.exec(); - error = true; - } - if(m_projectFileLocation->getText().isEmpty()) - { - QMessageBox msgBox; - msgBox.setText("Location for the ProjectFiles is empty"); - msgBox.exec(); - error = true; + return; } - if(!error) + if (m_projectFileLocation->getText().isEmpty()) { - ProjectSettings::getInstance()->setSourcePaths(m_sourcePaths->getList()); - ProjectSettings::getInstance()->setHeaderSearchPaths(m_includePaths->getList()); - if(m_frameworkPaths) - { - ProjectSettings::getInstance()->setFrameworkSearchPaths(m_frameworkPaths->getList()); - } - std::string projectFile = - m_projectFileLocation->getText().toStdString() + "/" + m_projectName->text().toStdString() + ".xml"; - ProjectSettings::getInstance()->save(projectFile); - MessageLoadProject(projectFile).dispatch(); + QMessageBox msgBox; + msgBox.setText("Please define the location of the project file."); + msgBox.exec(); + return; } + + if (!m_sourcePaths->getList().size()) + { + QMessageBox msgBox; + msgBox.setText("Please add at least one source path to your project."); + msgBox.exec(); + return; + } + + ProjectSettings* projSettings = ProjectSettings::getInstance().get(); + + projSettings->clear(); + + projSettings->setSourcePaths(m_sourcePaths->getList()); + projSettings->setHeaderSearchPaths(m_includePaths->getList()); + + if (m_frameworkPaths) + { + projSettings->setFrameworkSearchPaths(m_frameworkPaths->getList()); + } + + std::string projectFile = + m_projectFileLocation->getText().toStdString() + "/" + m_projectName->text().toStdString() + ".xml"; + projSettings->save(projectFile); + + MessageLoadProject(projectFile).dispatch(); + emit finished(); +} + +void QtProjectSetupScreen::handleCancelButtonPress() +{ + emit canceled(); +} + +void QtProjectSetupScreen::handleUpdateButtonPress() +{ + handleCreateButtonPress(); } QSize QtProjectSetupScreen::sizeHint() const diff --git a/src/app/qt/element/QtProjectSetupScreen.h b/src/app/qt/element/QtProjectSetupScreen.h index bd3b2472..a13006ee 100644 --- a/src/app/qt/element/QtProjectSetupScreen.h +++ b/src/app/qt/element/QtProjectSetupScreen.h @@ -1,51 +1,72 @@ -#ifndef QTPROJECTSETUPSCREEN_H -#define QTPROJECTSETUPSCREEN_H +#ifndef QT_PROJECT_SETUP_SCREEN_H +#define QT_PROJECT_SETUP_SCREEN_H -#include #include #include #include #include "QtSettingsWindow.h" -#include "qt/element/QtDirectoryListBox.h" #include "utility/file/FilePath.h" -class QtTextLine : public QWidget +#include "qt/element/QtDirectoryListBox.h" +#include "qt/element/QtLineEdit.h" + +class QtTextLine + : public QWidget { -Q_OBJECT + Q_OBJECT + public: QtTextLine(QWidget *parent); QString getText(); void setText(QString text); -private: - QPushButton* m_button; - QLineEdit* m_data; + private slots: void handleButtonPress(); + +private: + QPushButton* m_button; + QtLineEdit* m_data; }; -class QtProjectSetupScreen : public QtSettingsWindow + +class QtProjectSetupScreen + : public QtSettingsWindow { -Q_OBJECT + Q_OBJECT + public: QtProjectSetupScreen(QWidget* parent = 0); QSize sizeHint() const Q_DECL_OVERRIDE; + virtual void setup() override; + + void loadEmpty(); + void loadProjectSettings(); + +signals: + void finished(); + void canceled(); + private slots: void handleCreateButtonPress(); void handleCancelButtonPress(); + void handleUpdateButtonPress(); private: QLineEdit* m_projectName; - QtDirectoryListBox *m_includePaths; - QtDirectoryListBox *m_sourcePaths; - QtDirectoryListBox *m_frameworkPaths; QtTextLine* m_projectFileLocation; - std::vector compilerFlags; - std::vector sourceExtensions; - std::vector headerExtensions; + + QLabel* m_title; + + QPushButton* m_createButton; + QPushButton* m_cancelButton; + QPushButton* m_updateButton; + + QtDirectoryListBox* m_includePaths; + QtDirectoryListBox* m_sourcePaths; + QtDirectoryListBox* m_frameworkPaths; }; - -#endif //QTPROJECTSETUPSCREEN_H +#endif //QT_PROJECT_SETUP_SCREEN_H diff --git a/src/app/qt/element/QtSettingsWindow.cpp b/src/app/qt/element/QtSettingsWindow.cpp index b6a3b48e..4dbc8111 100644 --- a/src/app/qt/element/QtSettingsWindow.cpp +++ b/src/app/qt/element/QtSettingsWindow.cpp @@ -1,48 +1,54 @@ #include "qt/element/QtSettingsWindow.h" #include +#include #include "utility/messaging/type/MessageInterruptTasks.h" QtSettingsWindow::QtSettingsWindow(QWidget *parent, int displacement) - : QWidget(parent, Qt::Dialog | Qt::FramelessWindowHint ) + : QWidget(parent, Qt::Dialog | Qt::FramelessWindowHint) , m_mousePressedInWindow(false) { QSize windowSize = sizeHint(); - move(parent->pos().x()+parent->width()/2-250,parent->pos().y()+parent->height()/2-250); + move(parent->pos().x() + parent->width() / 2 - 250, parent->pos().y() + parent->height() / 2 - 250); + setAttribute(Qt::WA_TranslucentBackground, true); m_displacment = displacement; + m_window = new QWidget(this); - windowSize.setHeight(windowSize.height()-displacement-10); - windowSize.setWidth(windowSize.width()-10); - m_window->move(0,displacement); - //m_window->setFixedSize(windowSize); + windowSize.setHeight(windowSize.height() - displacement - 10); + windowSize.setWidth(windowSize.width() - 10); + m_window->move(0, displacement); m_window->resize(windowSize); + std::string frameStyle = - "#SettingWindow {" - "font-size: 17pt; " - "border: 1px solid lightgray;" - "border-radius: 15px; " - "background: white; " - "background-image: url(:/data/gui/icon/logo_1024_1024.png); " - "}"; + "#SettingWindow {" + "font-size: 17pt; " + "border: 1px solid lightgray;" + "border-radius: 15px; " + "background: white; " + "background-image: url(:/data/gui/icon/logo_1024_1024.png); " + "}"; m_window->setStyleSheet(frameStyle.c_str()); m_window->setObjectName("SettingWindow"); - // test with window shadow - QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect; - effect->setBlurRadius(5); - effect->setXOffset(2); - effect->setYOffset(2); - effect->setColor(Qt::darkGray); - m_window->setGraphicsEffect(effect); + // window shadow + if (QSysInfo::macVersion() == QSysInfo::MV_None) + { + QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect; + effect->setBlurRadius(5); + effect->setXOffset(2); + effect->setYOffset(2); + effect->setColor(Qt::darkGray); + m_window->setGraphicsEffect(effect); + } this->raise(); } void QtSettingsWindow::keyPressEvent(QKeyEvent *event) { - if(event->key() == Qt::Key_Escape) + if (event->key() == Qt::Key_Escape) { this->hide(); } @@ -53,10 +59,11 @@ QSize QtSettingsWindow::sizeHint() const return QSize(500, 500); } -void QtSettingsWindow::resizeEvent(QResizeEvent *event) { - QSize windowSize = event->size()-QSize(10,10+m_displacment); +void QtSettingsWindow::resizeEvent(QResizeEvent *event) +{ + QSize windowSize = event->size()-QSize(10, 10 + m_displacment); m_window->resize(windowSize); - m_window->move(0,m_displacment); + m_window->move(0, m_displacment); } void QtSettingsWindow::mouseMoveEvent(QMouseEvent *event) diff --git a/src/app/qt/element/QtSettingsWindow.h b/src/app/qt/element/QtSettingsWindow.h index 642858ee..91e38ee8 100644 --- a/src/app/qt/element/QtSettingsWindow.h +++ b/src/app/qt/element/QtSettingsWindow.h @@ -1,31 +1,34 @@ -#ifndef QTSETTINGSWINDOW_H -#define QTSETTINGSWINDOW_H +#ifndef QT_SETTINGS_WINDOW_H +#define QT_SETTINGS_WINDOW_H -#include #include +#include -class QtSettingsWindow : public QWidget +class QtSettingsWindow + : public QWidget { Q_OBJECT public: QtSettingsWindow(QWidget* parent = 0, int displacement = 0); + QSize sizeHint() const Q_DECL_OVERRIDE; - virtual void setup() = 0; + + virtual void setup() = 0; protected: - QWidget* m_window; - void keyPressEvent(QKeyEvent* event) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent* event) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + + QWidget* m_window; + private: int m_displacment; QPoint m_dragPosition; bool m_mousePressedInWindow; - //void mouse }; -#endif //QTSETTINGSWINDOW_H +#endif //QT_SETTINGS_WINDOW_H diff --git a/src/app/qt/element/QtStartScreen.cpp b/src/app/qt/element/QtStartScreen.cpp index faf32e9b..826ac6c4 100644 --- a/src/app/qt/element/QtStartScreen.cpp +++ b/src/app/qt/element/QtStartScreen.cpp @@ -22,11 +22,10 @@ QtRecentProjectButton::QtRecentProjectButton(const QString &text, QWidget *paren void QtRecentProjectButton::handleButtonClick() { MessageLoadProject(m_projectFile).dispatch(); - parentWidget()->hide(); }; QtStartScreen::QtStartScreen(QWidget *parent) - : QtSettingsWindow(parent, 50) + : QtSettingsWindow(parent, 68) { this->raise(); } @@ -37,7 +36,7 @@ void QtStartScreen::setup() std::vector recentProjects = ApplicationSettings::getInstance()->getRecentProjects(); QtDeviceScaledPixmap coati_logo("data/gui/startscreen/logo_schriftzug.png"); - coati_logo.scaleToWidth(250); + coati_logo.scaleToWidth(200); QLabel* coatiLogoLabel = new QLabel(this); coatiLogoLabel->setPixmap(coati_logo.pixmap()); coatiLogoLabel->resize(coati_logo.width(), coati_logo.height()); @@ -45,28 +44,28 @@ void QtStartScreen::setup() m_newProjectButton = new QPushButton("New Project", this); m_newProjectButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac - m_newProjectButton->setGeometry(30, 375, 140, 30); + m_newProjectButton->setGeometry(30, 495, 140, 30); m_newProjectButton->setObjectName("projectButton"); connect(m_newProjectButton, SIGNAL(clicked()), this, SLOT(handleNewProjectButton())); m_openProjectButton = new QPushButton("Open Project", this); m_openProjectButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac - m_openProjectButton->setGeometry(30, 420, 140, 30); + m_openProjectButton->setGeometry(30, 540, 140, 30); m_openProjectButton->setObjectName("projectButton"); connect(m_openProjectButton, SIGNAL(clicked()), this, SLOT(handleOpenProjectButton())); connect(this, SIGNAL(openOpenProjectDialog()), parent(), SLOT(openProject())); connect(this, SIGNAL(openNewProjectDialog()), parent(), SLOT(newProject())); - QLabel* recentProjectsLabel = new QLabel("RECENT PROJECTS: ", this); - recentProjectsLabel->setGeometry(300, 129, 300, 50); + QLabel* recentProjectsLabel = new QLabel("Recent Projects: ", this); + recentProjectsLabel->setGeometry(300, 234, 300, 50); recentProjectsLabel->setObjectName("recentLabel"); - int position = 200; + int position = 290; QIcon cpp_icon("data/gui/startscreen/Icon_CPP.png"); for (std::string project : recentProjects) { - if(FileSystem::exists(project.c_str())) + if (FileSystem::exists(project.c_str())) { QtRecentProjectButton* button = new QtRecentProjectButton(project.c_str(), this); button->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac @@ -76,11 +75,12 @@ void QtStartScreen::setup() button->minimumSizeHint(); // force font loading button->setGeometry(292, position, button->fontMetrics().width(button->text()) + 45, 40); connect(button, SIGNAL(clicked()), button, SLOT(handleButtonClick())); + connect(button, SIGNAL(clicked()), this, SLOT(handleRecentButton())); position += 40; } } - resize(600,500); + resize(600, 600); } QSize QtStartScreen::sizeHint() const @@ -90,12 +90,15 @@ QSize QtStartScreen::sizeHint() const void QtStartScreen::handleNewProjectButton() { - this->hide(); emit openNewProjectDialog(); } void QtStartScreen::handleOpenProjectButton() { - this->hide(); emit openOpenProjectDialog(); } + +void QtStartScreen::handleRecentButton() +{ + emit finished(); +} diff --git a/src/app/qt/element/QtStartScreen.h b/src/app/qt/element/QtStartScreen.h index 8983717a..82445dbc 100644 --- a/src/app/qt/element/QtStartScreen.h +++ b/src/app/qt/element/QtStartScreen.h @@ -4,7 +4,8 @@ #include #include "QtSettingsWindow.h" -class QtRecentProjectButton : public QPushButton +class QtRecentProjectButton + : public QPushButton { Q_OBJECT public: @@ -15,7 +16,8 @@ private: std::string m_projectFile; }; -class QtStartScreen : public QtSettingsWindow +class QtStartScreen + : public QtSettingsWindow { Q_OBJECT @@ -27,10 +29,13 @@ public: signals: void openOpenProjectDialog(); void openNewProjectDialog(); + void finished(); private slots: void handleNewProjectButton(); void handleOpenProjectButton(); + void handleRecentButton(); + private: QPushButton* m_openProjectButton; QPushButton* m_newProjectButton; diff --git a/src/lib/Application.cpp b/src/lib/Application.cpp index d1822061..1ae8176a 100644 --- a/src/lib/Application.cpp +++ b/src/lib/Application.cpp @@ -67,20 +67,6 @@ void Application::loadProject(const std::string& projectSettingsFilePath) updateRecentProjects(projectSettingsFilePath); } -void Application::loadSource(const std::string& sourceDirectoryPath) -{ - MessageStatus("Loading Source: " + sourceDirectoryPath).dispatch(); - - m_storageCache->clear(); - m_componentManager->refreshViews(); - - m_project = Project::create(m_storageCache.get()); - - m_project->clearProjectSettings(); - m_project->setSourceDirectoryPath(sourceDirectoryPath); - m_project->parseCode(); -} - void Application::reloadProject() { MessageStatus("Refreshing Project").dispatch(); @@ -136,12 +122,6 @@ void Application::handleMessage(MessageLoadProject* message) loadProject(message->projectSettingsFilePath); } -void Application::handleMessage(MessageLoadSource* message) -{ - m_isInitialParse = true; - loadSource(message->sourceDirectoryPath); -} - void Application::handleMessage(MessageRefresh* message) { loadSettings(); diff --git a/src/lib/Application.h b/src/lib/Application.h index 0508ea90..47b78b52 100644 --- a/src/lib/Application.h +++ b/src/lib/Application.h @@ -8,7 +8,6 @@ #include "utility/messaging/MessageListener.h" #include "utility/messaging/type/MessageFinishedParsing.h" #include "utility/messaging/type/MessageLoadProject.h" -#include "utility/messaging/type/MessageLoadSource.h" #include "utility/messaging/type/MessageRefresh.h" #include "utility/messaging/type/MessageSaveProject.h" @@ -19,7 +18,6 @@ class StorageCache; class Application : public MessageListener , public MessageListener - , public MessageListener , public MessageListener , public MessageListener { @@ -39,7 +37,6 @@ private: virtual void handleMessage(MessageFinishedParsing* message); virtual void handleMessage(MessageLoadProject* message); - virtual void handleMessage(MessageLoadSource* message); virtual void handleMessage(MessageRefresh* message); virtual void handleMessage(MessageSaveProject* message); diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 6977759b..166ade22 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -247,7 +247,6 @@ add_files( utility/messaging/type/MessageGraphNodeMove.h utility/messaging/type/MessageInterruptTasks.h utility/messaging/type/MessageLoadProject.h - utility/messaging/type/MessageLoadSource.h utility/messaging/type/MessageRedo.h utility/messaging/type/MessageRefresh.h utility/messaging/type/MessageSaveProject.h diff --git a/src/lib/Project.cpp b/src/lib/Project.cpp index 2bc8d5dc..1747226d 100644 --- a/src/lib/Project.cpp +++ b/src/lib/Project.cpp @@ -70,20 +70,6 @@ void Project::reloadProjectSettings() } } -bool Project::setSourceDirectoryPath(const std::string& sourceDirectoryPath) -{ - m_projectSettingsFilepath = sourceDirectoryPath + "/ProjectSettings.xml"; - bool success = ProjectSettings::getInstance()->setSourcePaths(std::vector(1, sourceDirectoryPath)); - - if (success) - { - m_fileManager.reset(); - updateFileManager(); - } - - return success; -} - void Project::clearStorage() { m_storage = std::make_shared(); diff --git a/src/lib/Project.h b/src/lib/Project.h index 25a09880..ae05fb48 100644 --- a/src/lib/Project.h +++ b/src/lib/Project.h @@ -22,8 +22,6 @@ public: void clearProjectSettings(); void reloadProjectSettings(); - bool setSourceDirectoryPath(const std::string& sourceDirectoryPath); - void clearStorage(); void parseCode(); diff --git a/src/lib/component/controller/UndoRedoController.cpp b/src/lib/component/controller/UndoRedoController.cpp index 072b7e20..9950a274 100644 --- a/src/lib/component/controller/UndoRedoController.cpp +++ b/src/lib/component/controller/UndoRedoController.cpp @@ -84,11 +84,6 @@ void UndoRedoController::handleMessage(MessageLoadProject* message) clear(); } -void UndoRedoController::handleMessage(MessageLoadSource* message) -{ - clear(); -} - void UndoRedoController::handleMessage(MessageRedo* message) { if (!m_redo.empty()) diff --git a/src/lib/component/controller/UndoRedoController.h b/src/lib/component/controller/UndoRedoController.h index c5226fba..b00f2a57 100644 --- a/src/lib/component/controller/UndoRedoController.h +++ b/src/lib/component/controller/UndoRedoController.h @@ -12,7 +12,6 @@ #include "utility/messaging/type/MessageGraphNodeExpand.h" #include "utility/messaging/type/MessageGraphNodeMove.h" #include "utility/messaging/type/MessageLoadProject.h" -#include "utility/messaging/type/MessageLoadSource.h" #include "utility/messaging/type/MessageRedo.h" #include "utility/messaging/type/MessageRefresh.h" #include "utility/messaging/type/MessageSearch.h" @@ -33,7 +32,6 @@ class UndoRedoController , public MessageListener , public MessageListener , public MessageListener - , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -63,7 +61,6 @@ private: virtual void handleMessage(MessageGraphNodeExpand* message); virtual void handleMessage(MessageGraphNodeMove* message); virtual void handleMessage(MessageLoadProject* message); - virtual void handleMessage(MessageLoadSource* message); virtual void handleMessage(MessageRedo* message); virtual void handleMessage(MessageRefresh* message); virtual void handleMessage(MessageSearch* message); diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index dc6a9a98..23b47465 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -809,6 +809,11 @@ std::shared_ptr Storage::getTokenLocationsForLinesInFile( std::shared_ptr ret = std::make_shared(filePath); std::shared_ptr locationFile = m_sqliteStorage.getTokenLocationsForFile(filePath); + if (!locationFile->getTokenLocationLines().size()) + { + return ret; + } + uint endLineNumber = locationFile->getTokenLocationLines().rbegin()->first; std::set addedLocationIds; for (uint i = firstLineNumber; i <= endLineNumber; i++) diff --git a/src/lib/settings/ProjectSettings.cpp b/src/lib/settings/ProjectSettings.cpp index 1d4080d4..486fb561 100644 --- a/src/lib/settings/ProjectSettings.cpp +++ b/src/lib/settings/ProjectSettings.cpp @@ -1,5 +1,22 @@ #include "settings/ProjectSettings.h" +std::vector ProjectSettings::getDefaultHeaderExtensions() +{ + std::vector defaultValues; + defaultValues.push_back(".h"); + defaultValues.push_back(".hpp"); + return defaultValues; +} + +std::vector ProjectSettings::getDefaultSourceExtensions() +{ + std::vector defaultValues; + defaultValues.push_back(".cpp"); + defaultValues.push_back(".cxx"); + defaultValues.push_back(".cc"); + return defaultValues; +} + std::shared_ptr ProjectSettings::s_instance; std::shared_ptr ProjectSettings::getInstance() @@ -67,16 +84,12 @@ std::vector ProjectSettings::getCompilerFlags() const std::vector ProjectSettings::getHeaderExtensions() const { - std::vector defaultValues; - defaultValues.push_back(".h"); - return getValues("source/Extensions/HeaderExtensions", defaultValues); + return getValues("source/Extensions/HeaderExtensions", getDefaultHeaderExtensions()); } std::vector ProjectSettings::getSourceExtensions() const { - std::vector defaultValues; - defaultValues.push_back(".cpp"); - return getValues("source/Extensions/SourceExtensions", defaultValues); + return getValues("source/Extensions/SourceExtensions", getDefaultSourceExtensions()); } bool ProjectSettings::setHeaderExtensions(const std::vector &headerExtensions) diff --git a/src/lib/settings/ProjectSettings.h b/src/lib/settings/ProjectSettings.h index 9b772c7c..5773d75e 100644 --- a/src/lib/settings/ProjectSettings.h +++ b/src/lib/settings/ProjectSettings.h @@ -10,6 +10,9 @@ class ProjectSettings : public Settings { public: + static std::vector getDefaultHeaderExtensions(); + static std::vector getDefaultSourceExtensions(); + static std::shared_ptr getInstance(); ~ProjectSettings(); diff --git a/src/lib/settings/Settings.cpp b/src/lib/settings/Settings.cpp index 833b99ec..7dd09a46 100644 --- a/src/lib/settings/Settings.cpp +++ b/src/lib/settings/Settings.cpp @@ -57,16 +57,16 @@ void Settings::clear() m_filePath = FilePath(); } -Settings::Settings() -{ - clear(); -} - const FilePath& Settings::getFilePath() const { return m_filePath; } +Settings::Settings() +{ + clear(); +} + void Settings::setFilePath(const FilePath& filePath) { m_filePath = filePath; diff --git a/src/lib/settings/Settings.h b/src/lib/settings/Settings.h index e0d42974..c6216025 100644 --- a/src/lib/settings/Settings.h +++ b/src/lib/settings/Settings.h @@ -18,10 +18,11 @@ public: virtual void save(const FilePath& filePath); void clear(); + const FilePath& getFilePath() const; + protected: Settings(); - const FilePath& getFilePath() const; void setFilePath(const FilePath& filePath); template diff --git a/src/lib/utility/messaging/type/MessageLoadSource.h b/src/lib/utility/messaging/type/MessageLoadSource.h deleted file mode 100644 index 1b7260e6..00000000 --- a/src/lib/utility/messaging/type/MessageLoadSource.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef MESSAGE_LOAD_SOURCE_H -#define MESSAGE_LOAD_SOURCE_H - -#include "utility/messaging/Message.h" - -class MessageLoadSource: public Message -{ -public: - MessageLoadSource(const std::string& sourceDir) - : sourceDirectoryPath(sourceDir) - { - } - - static const std::string getStaticType() - { - return "MessageLoadSource"; - } - - const std::string sourceDirectoryPath; -}; - -#endif // MESSAGE_LOAD_SOURCE_H