diff --git a/src/dialogs/DiffPanel.cpp b/src/dialogs/DiffPanel.cpp index 40ad124c..54ac225e 100644 --- a/src/dialogs/DiffPanel.cpp +++ b/src/dialogs/DiffPanel.cpp @@ -39,8 +39,10 @@ DiffPanel::DiffPanel(const git::Repository &repo, QWidget *parent) connect(context, contextSignal, [this](int value) { mConfig.setValue("diff.context", value); foreach (MainWindow *window, MainWindow::windows()) { - for (int i = 0; i < window->count(); ++i) - window->view(i)->refresh(); + for (int i = 0; i < window->count(); ++i) { + if (auto v = window->view(i)) + v->refresh(); + } } }); @@ -64,8 +66,10 @@ DiffPanel::DiffPanel(const git::Repository &repo, QWidget *parent) } foreach (MainWindow *window, MainWindow::windows()) { - for (int i = 0; i < window->count(); ++i) - window->view(i)->refresh(); + for (int i = 0; i < window->count(); ++i) { + if (auto v = window->view(i)) + v->refresh(); + } } }); diff --git a/src/dialogs/SettingsDialog.cpp b/src/dialogs/SettingsDialog.cpp index 7dfcc3b6..26542dac 100644 --- a/src/dialogs/SettingsDialog.cpp +++ b/src/dialogs/SettingsDialog.cpp @@ -165,8 +165,10 @@ public: connect(mFetch, &QCheckBox::toggled, this, [](bool checked) { Settings::instance()->setValue(Setting::Id::FetchAutomatically, checked); foreach (MainWindow *window, MainWindow::windows()) { - for (int i = 0; i < window->count(); ++i) - window->view(i)->startFetchTimer(); + for (int i = 0; i < window->count(); ++i) { + if (auto v = window->view(i)) + v->startFetchTimer(); + } } }); diff --git a/src/ui/IndexCompleter.cpp b/src/ui/IndexCompleter.cpp index 5b20ca4b..ba222bfa 100644 --- a/src/ui/IndexCompleter.cpp +++ b/src/ui/IndexCompleter.cpp @@ -62,7 +62,7 @@ public: } int rowCount(const QModelIndex &parent = QModelIndex()) const override { - return mWindow->count() ? dict().size() : 0; + return mWindow->repoCount() ? dict().size() : 0; } private: diff --git a/src/ui/MainWindow.cpp b/src/ui/MainWindow.cpp index ad20abc7..18b0f408 100644 --- a/src/ui/MainWindow.cpp +++ b/src/ui/MainWindow.cpp @@ -117,7 +117,8 @@ MainWindow::MainWindow(const git::Repository &repo, QWidget *parent, if (refresh) { for (int i = 0; i < count(); ++i) - view(i)->refresh(); + if (auto v = view(i)) + v->refresh(); } }); @@ -134,6 +135,7 @@ MainWindow::MainWindow(const git::Repository &repo, QWidget *parent, &MainWindow::updateTabNames); setCentralWidget(tabs); + tabs->addWelcomeTab(); if (repo) addTab(repo); @@ -167,7 +169,11 @@ RepoView *MainWindow::addTab(const QString &path) { TabWidget *tabs = tabWidget(); for (int i = 0; i < tabs->count(); i++) { - RepoView *view = static_cast(tabs->widget(i)); + RepoView *view = dynamic_cast(tabs->widget(i)); + if (!view) { + // Tab 0 is the welcome tab + continue; + } if (path == view->repo().dir(false).path()) { tabs->setCurrentIndex(i); return view; @@ -190,7 +196,11 @@ RepoView *MainWindow::addTab(const git::Repository &repo) { TabWidget *tabs = tabWidget(); for (int i = 0; i < tabs->count(); i++) { - RepoView *view = static_cast(tabs->widget(i)); + RepoView *view = dynamic_cast(tabs->widget(i)); + if (!view) { + // Tab 0 is the welcome tab + continue; + } if (dir.path() == view->repo().dir(false).path()) { tabs->setCurrentIndex(i); return view; @@ -223,12 +233,14 @@ RepoView *MainWindow::addTab(const git::Repository &repo) { int MainWindow::count() const { return tabWidget()->count(); } +int MainWindow::repoCount() const { return tabWidget()->count() - 1; } + RepoView *MainWindow::currentView() const { - return static_cast(tabWidget()->currentWidget()); + return dynamic_cast(tabWidget()->currentWidget()); } RepoView *MainWindow::view(int index) const { - return static_cast(tabWidget()->widget(index)); + return dynamic_cast(tabWidget()->widget(index)); } MainWindow *MainWindow::activeWindow() { @@ -428,9 +440,11 @@ void MainWindow::updateTabNames() { QList fullNames; for (int i = 0; i < count(); ++i) { - TabName name(view(i)->repo().dir(false).path()); - names[name.name()].append(i); - fullNames.append(name); + if (auto v = view(i)) { + TabName name(v->repo().dir(false).path()); + names[name.name()].append(i); + fullNames.append(name); + } } QHash>::key_iterator first; @@ -543,8 +557,10 @@ void MainWindow::updateWindowTitle(int ahead, int behind) { QStringList MainWindow::paths() const { QStringList paths; - for (int i = 0; i < count(); ++i) - paths.append(view(i)->repo().dir(false).path()); + for (int i = 0; i < count(); ++i) { + if (auto v = view(i)) + paths.append(v->repo().dir(false).path()); + } return paths; } diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 1634da97..52706cc5 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -36,6 +36,7 @@ public: RepoView *addTab(const git::Repository &repo); int count() const; + int repoCount() const; RepoView *currentView() const; RepoView *view(int index) const; diff --git a/src/ui/MenuBar.cpp b/src/ui/MenuBar.cpp index 77c76dae..a95fdb58 100644 --- a/src/ui/MenuBar.cpp +++ b/src/ui/MenuBar.cpp @@ -56,7 +56,8 @@ void openCloneDialog(CloneDialog::Kind kind) { QObject::connect(dialog, &CloneDialog::accepted, [dialog] { if (MainWindow *window = MainWindow::open(dialog->path())) { RepoView *view = window->currentView(); - view->addLogEntry(dialog->message(), dialog->messageTitle()); + if (view) + view->addLogEntry(dialog->message(), dialog->messageTitle()); } }); @@ -322,8 +323,9 @@ MenuBar::MenuBar(QWidget *parent) : QMenuBar(parent) { return; if (MainWindow *win = qobject_cast(window)) { - if (win->count() > 0) { - win->currentView()->close(); + if (win->count() > 1) { + if (auto c = win->currentView()) + c->close(); return; } } @@ -439,7 +441,8 @@ MenuBar::MenuBar(QWidget *parent) : QMenuBar(parent) { connect(mFind, &QAction::triggered, [] { QWidget *widget = QApplication::activeWindow(); if (MainWindow *window = qobject_cast(widget)) { - window->currentView()->find(); + if (auto c = window->currentView()) + c->find(); } else if (EditorWindow *window = qobject_cast(widget)) { window->widget()->find(); } @@ -450,7 +453,8 @@ MenuBar::MenuBar(QWidget *parent) : QMenuBar(parent) { connect(mFindNext, &QAction::triggered, [] { QWidget *widget = QApplication::activeWindow(); if (MainWindow *window = qobject_cast(widget)) { - window->currentView()->findNext(); + if (auto c = window->currentView()) + c->findNext(); } else if (EditorWindow *window = qobject_cast(widget)) { window->widget()->findNext(); } @@ -461,7 +465,8 @@ MenuBar::MenuBar(QWidget *parent) : QMenuBar(parent) { connect(mFindPrevious, &QAction::triggered, [] { QWidget *widget = QApplication::activeWindow(); if (MainWindow *window = qobject_cast(widget)) { - window->currentView()->findPrevious(); + if (auto c = window->currentView()) + c->findPrevious(); } else if (EditorWindow *window = qobject_cast(widget)) { window->widget()->findPrevious(); } @@ -753,10 +758,12 @@ MenuBar::MenuBar(QWidget *parent) : QMenuBar(parent) { return; RepoView *view = win->currentView(); - foreach (const git::Submodule &submodule, view->repo().submodules()) { - QAction *action = mOpenSubmodule->addAction(submodule.name()); - connect(action, &QAction::triggered, - [view, submodule] { view->openSubmodule(submodule); }); + if (view) { + foreach (const git::Submodule &submodule, view->repo().submodules()) { + QAction *action = mOpenSubmodule->addAction(submodule.name()); + connect(action, &QAction::triggered, + [view, submodule] { view->openSubmodule(submodule); }); + } } }); @@ -893,13 +900,14 @@ MenuBar::MenuBar(QWidget *parent) : QMenuBar(parent) { QAction *diffs = debug->addAction(tr("Load All Diffs")); connect(diffs, &QAction::triggered, [this] { if (MainWindow *win = qobject_cast(window())) { - RepoView *view = win->currentView(); - CommitList *commits = view->commitList(); - QAbstractItemModel *model = commits->model(); - for (int i = 0; i < model->rowCount(); ++i) { - commits->setCurrentIndex(model->index(i, 0)); - view->find(); // Force editors to load. - QCoreApplication::processEvents(); + if (RepoView *view = win->currentView()) { + CommitList *commits = view->commitList(); + QAbstractItemModel *model = commits->model(); + for (int i = 0; i < model->rowCount(); ++i) { + commits->setCurrentIndex(model->index(i, 0)); + view->find(); // Force editors to load. + QCoreApplication::processEvents(); + } } } }); @@ -907,9 +915,11 @@ MenuBar::MenuBar(QWidget *parent) : QMenuBar(parent) { QAction *walk = debug->addAction(tr("Walk Commits")); connect(walk, &QAction::triggered, [this] { if (MainWindow *win = qobject_cast(window())) { - git::RevWalk walker = win->currentView()->repo().walker(); - while (git::Commit commit = walker.next()) - (void)commit; + if (auto c = win->currentView()) { + git::RevWalk walker = c->repo().walker(); + while (git::Commit commit = walker.next()) + (void)commit; + } } }); } @@ -1132,8 +1142,9 @@ void MenuBar::updateHistory() { void MenuBar::updateWindow() { MainWindow *win = qobject_cast(window()); - mPrevTab->setEnabled(win && win->count() > 1); - mNextTab->setEnabled(win && win->count() > 1); + // First tab is the welcome tab + mPrevTab->setEnabled(win && win->count() > 2); + mNextTab->setEnabled(win && win->count() > 2); } QWidget *MenuBar::window() const { @@ -1150,7 +1161,10 @@ QList MenuBar::views() const { QList repos; for (int i = 0; i < win->count(); i++) { - repos.append(win->view(i)); + auto* view = win->view(i); + if (view) { + repos.append(view); + } } return repos; } diff --git a/src/ui/SideBar.cpp b/src/ui/SideBar.cpp index 39652bcf..f6861aac 100644 --- a/src/ui/SideBar.cpp +++ b/src/ui/SideBar.cpp @@ -351,7 +351,9 @@ public: if (!mShowFullPath) return mTabs->tabText(row); - RepoView *view = static_cast(mTabs->widget(row)); + RepoView *view = dynamic_cast(mTabs->widget(row)); + if (!view) + return QStringLiteral(""); return view->repo().dir(false).path(); } @@ -445,7 +447,10 @@ public: if (!mTabs->count()) return QVariant(); QWidget *widget = mTabs->widget(row); - RepoView *view = static_cast(widget); + RepoView *view = dynamic_cast(widget); + if (!view) { + return QStringLiteral(""); + } return view->repo().dir(false).path(); } @@ -492,7 +497,10 @@ public: switch (parent.row()) { case Repo: if (mTabs->count()) { - RepoView *view = static_cast(mTabs->widget(row)); + RepoView *view = dynamic_cast(mTabs->widget(row)); + if (!view) { + return QStringLiteral(""); + } return view->repo().dir(false).path(); } diff --git a/src/ui/TabBar.cpp b/src/ui/TabBar.cpp index 796a7d00..88790c8d 100644 --- a/src/ui/TabBar.cpp +++ b/src/ui/TabBar.cpp @@ -8,17 +8,47 @@ // #include "TabBar.h" +#include +#include + +namespace { +constexpr auto home_tab_width = 50; +} TabBar::TabBar(QWidget *parent) : QTabBar(parent) { setAutoHide(true); setDocumentMode(true); } +void TabBar::mousePressEvent(QMouseEvent* event) { + mClickedTabIndex = tabAt(event->pos()); + QTabBar::mousePressEvent(event); +} + +void TabBar::mouseMoveEvent(QMouseEvent* event) { + qDebug() << event->pos(); + // if (mClickedTabIndex == 0/*event->pos().x() <= home_tab_width || tabAt(event->pos()) == 0*/) { // + // // Ignoring first tab because this is the welcome tab + // return; + // } + + // QTabBar::mouseMoveEvent(event); + return; +} + +void TabBar::mouseReleaseEvent(QMouseEvent* event) { + mClickedTabIndex = -1; + QTabBar::mouseMoveEvent(event); +} + QSize TabBar::minimumTabSizeHint(int index) const { mCalculatingMinimumSize = true; QSize size = QTabBar::minimumTabSizeHint(index); mCalculatingMinimumSize = false; + if (index == 0) + size.setWidth(home_tab_width); + // Default Tab just a small tab size on the left return size; } @@ -28,7 +58,9 @@ QSize TabBar::tabSizeHint(int index) const { return QTabBar::tabSizeHint(index); int height = fontMetrics().lineSpacing() + 12; - return QSize(parentWidget()->width() / count() + 1, height); + if (index == 0) + return QSize(home_tab_width, height); + return QSize(parentWidget()->width() / (count() - 1) + 1 - home_tab_width, height); // Default Tab just a small tab size on the left } diff --git a/src/ui/TabBar.h b/src/ui/TabBar.h index 7088e37e..337e7c51 100644 --- a/src/ui/TabBar.h +++ b/src/ui/TabBar.h @@ -19,10 +19,14 @@ public: TabBar(QWidget *parent = nullptr); protected: + void mousePressEvent(QMouseEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; QSize minimumTabSizeHint(int index) const override; QSize tabSizeHint(int index) const override; private: + int mClickedTabIndex = -1; mutable bool mCalculatingMinimumSize = false; }; diff --git a/src/ui/TabWidget.cpp b/src/ui/TabWidget.cpp index 928246f2..1c2bd007 100644 --- a/src/ui/TabWidget.cpp +++ b/src/ui/TabWidget.cpp @@ -43,9 +43,10 @@ public: connect(clone, &QPushButton::clicked, [this] { CloneDialog *dialog = new CloneDialog(CloneDialog::Clone, this); connect(dialog, &CloneDialog::accepted, [dialog] { - if (MainWindow *window = MainWindow::open(dialog->path())) - window->currentView()->addLogEntry(dialog->message(), - dialog->messageTitle()); + if (MainWindow *window = MainWindow::open(dialog->path())) { + if (auto c = window->currentView()) + c->addLogEntry(dialog->message(), dialog->messageTitle()); + } }); dialog->open(); }); @@ -70,8 +71,8 @@ public: CloneDialog *dialog = new CloneDialog(CloneDialog::Init, this); connect(dialog, &CloneDialog::accepted, [dialog] { if (MainWindow *window = MainWindow::open(dialog->path())) - window->currentView()->addLogEntry(dialog->message(), - dialog->messageTitle()); + if (auto c = window->currentView()) + c->addLogEntry(dialog->message(), dialog->messageTitle()); }); dialog->open(); }); @@ -140,13 +141,10 @@ private: TabWidget::TabWidget(QWidget *parent) : QTabWidget(parent) { TabBar *bar = new TabBar(this); - bar->setMovable(true); + bar->setMovable(false); bar->setTabsClosable(true); setTabBar(bar); - // Create default widget. - addTab(new DefaultWidget(this), tr("Home")); - // Handle tab close. connect(this, &TabWidget::tabCloseRequested, [this](int index) { emit tabAboutToBeRemoved(); @@ -154,6 +152,13 @@ TabWidget::TabWidget(QWidget *parent) : QTabWidget(parent) { }); } +void TabWidget::addWelcomeTab() { + // Create default widget. + addTab(new DefaultWidget(this), tr("Home")); + Q_ASSERT(count() == 1); + tabBar()->setTabButton(0, QTabBar::RightSide, nullptr); +} + void TabWidget::resizeEvent(QResizeEvent *event) { QTabWidget::resizeEvent(event); } diff --git a/src/ui/TabWidget.h b/src/ui/TabWidget.h index da77fbfa..340ef389 100644 --- a/src/ui/TabWidget.h +++ b/src/ui/TabWidget.h @@ -17,6 +17,7 @@ class TabWidget : public QTabWidget { public: TabWidget(QWidget *parent = nullptr); + void addWelcomeTab(); signals: void tabAboutToBeInserted();