From 6156b1f430dfe02f7443082e92c4f06686e6ef89 Mon Sep 17 00:00:00 2001 From: fourtf Date: Mon, 28 May 2018 08:34:54 +0200 Subject: [PATCH] added categories to the accountspage --- chatterino.pro | 6 +-- src/controllers/accounts/account.cpp | 18 ++++++++- src/controllers/accounts/account.hpp | 7 +++- .../accounts/accountcontroller.cpp | 36 +++++++++++++++++- src/controllers/accounts/accountmodel.cpp | 37 +++++++++++++++++++ src/controllers/accounts/accountmodel.hpp | 12 ++++++ src/main.cpp | 6 +-- src/messages/message.cpp | 3 +- src/providers/twitch/twitchaccount.cpp | 2 +- src/providers/twitch/twitchaccountmanager.cpp | 36 +++++++++++------- src/providers/twitch/twitchaccountmanager.hpp | 2 +- src/providers/twitch/twitchchannel.hpp | 2 +- src/providers/twitch/twitchserver.hpp | 2 +- src/singletons/nativemessagingmanager.cpp | 7 ++-- src/util/{mutexvalue.h => mutexvalue.hpp} | 0 src/util/qstringhash.hpp | 14 +++++++ src/util/signalvectormodel.cpp | 1 - src/util/signalvectormodel.hpp | 31 ++++++++++------ src/widgets/attachedwindow.cpp | 7 ++-- src/widgets/helper/channelview.cpp | 2 +- src/widgets/settingspages/accountspage.cpp | 5 ++- src/widgets/settingspages/ignoreuserspage.cpp | 2 +- 22 files changed, 187 insertions(+), 51 deletions(-) rename src/util/{mutexvalue.h => mutexvalue.hpp} (100%) create mode 100644 src/util/qstringhash.hpp delete mode 100644 src/util/signalvectormodel.cpp diff --git a/chatterino.pro b/chatterino.pro index c55313f52..d0e852c7e 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -193,7 +193,6 @@ SOURCES += \ src/widgets/attachedwindow.cpp \ src/widgets/settingspages/externaltoolspage.cpp \ src/widgets/helper/comboboxitemdelegate.cpp \ - src/util/signalvectormodel.cpp \ src/controllers/commands/command.cpp \ src/controllers/commands/commandmodel.cpp \ src/controllers/commands/commandcontroller.cpp \ @@ -360,11 +359,12 @@ HEADERS += \ src/widgets/helper/dropoverlay.hpp \ src/widgets/helper/splitnode.hpp \ src/widgets/notificationpopup.hpp \ - src/util/mutexvalue.h \ src/controllers/taggedusers/taggeduserscontroller.hpp \ src/controllers/taggedusers/taggeduser.hpp \ src/providerid.hpp \ - src/controllers/taggedusers/taggedusersmodel.hpp + src/controllers/taggedusers/taggedusersmodel.hpp \ + src/util/qstringhash.hpp \ + src/util/mutexvalue.hpp RESOURCES += \ resources/resources.qrc diff --git a/src/controllers/accounts/account.cpp b/src/controllers/accounts/account.cpp index bbf42ed0b..e9ef921ed 100644 --- a/src/controllers/accounts/account.cpp +++ b/src/controllers/accounts/account.cpp @@ -6,9 +6,18 @@ namespace chatterino { namespace controllers { namespace accounts { -Account::Account(const QString &_category) - : category(_category) +Account::Account(ProviderId _providerId) + : providerId(_providerId) { + static QString twitch("Twitch"); + + this->category = [&]() { + switch (_providerId) { + case ProviderId::Twitch: + return twitch; + } + return QString("Unknown ProviderId"); + }(); } const QString &Account::getCategory() const @@ -16,6 +25,11 @@ const QString &Account::getCategory() const return this->category; } +ProviderId Account::getProviderId() const +{ + return this->providerId; +} + bool Account::operator<(const Account &other) const { QString a = this->toString(); diff --git a/src/controllers/accounts/account.hpp b/src/controllers/accounts/account.hpp index 81b2652e0..bab75c5dd 100644 --- a/src/controllers/accounts/account.hpp +++ b/src/controllers/accounts/account.hpp @@ -1,5 +1,7 @@ #pragma once +#include "providerid.hpp" + #include namespace chatterino { @@ -9,14 +11,17 @@ namespace accounts { class Account { public: - Account(const QString &category); + Account(ProviderId providerId); + virtual ~Account() = default; virtual QString toString() const = 0; const QString &getCategory() const; + ProviderId getProviderId() const; bool operator<(const Account &other) const; private: + ProviderId providerId; QString category; }; diff --git a/src/controllers/accounts/accountcontroller.cpp b/src/controllers/accounts/accountcontroller.cpp index c07d28628..3a3fc64af 100644 --- a/src/controllers/accounts/accountcontroller.cpp +++ b/src/controllers/accounts/accountcontroller.cpp @@ -9,7 +9,29 @@ namespace accounts { AccountController::AccountController() { this->twitch.accounts.itemInserted.connect([this](const auto &args) { - accounts.insertItem(std::dynamic_pointer_cast(args.item)); + this->accounts.insertItem(std::dynamic_pointer_cast(args.item)); + }); + + this->twitch.accounts.itemRemoved.connect([this](const auto &args) { + if (args.caller != this) { + auto &accs = this->twitch.accounts.getVector(); + auto it = std::find(accs.begin(), accs.end(), args.item); + assert(it != accs.end()); + + this->accounts.removeItem(it - accs.begin()); + } + }); + + this->accounts.itemRemoved.connect([this](const auto &args) { + switch (args.item->getProviderId()) { + case ProviderId::Twitch: { + auto &accs = this->twitch.accounts.getVector(); + auto it = std::find(accs.begin(), accs.end(), args.item); + assert(it != accs.end()); + + this->twitch.accounts.removeItem(it - accs.begin(), this); + } break; + } }); } @@ -21,8 +43,18 @@ void AccountController::load() AccountModel *AccountController::createModel(QObject *parent) { AccountModel *model = new AccountModel(parent); + // model->accountRemoved.connect([this](const auto &account) { + // switch (account->getProviderId()) { + // case ProviderId::Twitch: { + // auto &accs = this->twitch.accounts.getVector(); + // auto it = std::find(accs.begin(), accs.end(), account); + // assert(it != accs.end()); + + // this->twitch.accounts.removeItem(it - accs.begin()); + // } break; + // } + // }); - //(util::BaseSignalVector *) model->init(&this->accounts); return model; } diff --git a/src/controllers/accounts/accountmodel.cpp b/src/controllers/accounts/accountmodel.cpp index 88cce7ddb..635474479 100644 --- a/src/controllers/accounts/accountmodel.cpp +++ b/src/controllers/accounts/accountmodel.cpp @@ -1,5 +1,7 @@ #include "accountmodel.hpp" +#include "util/standarditemhelper.hpp" + namespace chatterino { namespace controllers { namespace accounts { @@ -21,6 +23,41 @@ void AccountModel::getRowFromItem(const std::shared_ptr &item, std::vector &row) { row[0]->setData(item->toString(), Qt::DisplayRole); + row[0]->setData(QFont("Segoe UI", 10), Qt::FontRole); + // row[0]->setData(QColor(255, 255, 255), Qt::BackgroundRole); +} + +int AccountModel::beforeInsert(const std::shared_ptr &item, + std::vector &row, int proposedIndex) +{ + if (this->categoryCount[item->getCategory()]++ == 0) { + auto row = this->createRow(); + + util::setStringItem(row[0], item->getCategory(), false, false); + // row[0]->setData(QColor(142, 36, 170), Qt::ForegroundRole); + // row[0]->setData(QColor(255, 255, 255), Qt::BackgroundRole); + row[0]->setData(QFont("Segoe UI Light", 16), Qt::FontRole); + + this->insertCustomRow(std::move(row), proposedIndex); + + return proposedIndex + 1; + } + + return proposedIndex; +} + +void AccountModel::afterRemoved(const std::shared_ptr &item, + std::vector &row, int index) +{ + auto it = this->categoryCount.find(item->getCategory()); + assert(it != this->categoryCount.end()); + + if (it->second <= 1) { + this->categoryCount.erase(it); + this->removeCustomRow(index - 1); + } else { + it->second--; + } } } // namespace accounts diff --git a/src/controllers/accounts/accountmodel.hpp b/src/controllers/accounts/accountmodel.hpp index 5eaa77662..0d2e1c787 100644 --- a/src/controllers/accounts/accountmodel.hpp +++ b/src/controllers/accounts/accountmodel.hpp @@ -1,8 +1,11 @@ #pragma once #include "controllers/accounts/account.hpp" +#include "util/qstringhash.hpp" #include "util/signalvectormodel.hpp" +#include + namespace chatterino { namespace controllers { namespace accounts { @@ -23,7 +26,16 @@ protected: virtual void getRowFromItem(const std::shared_ptr &item, std::vector &row) override; + virtual int beforeInsert(const std::shared_ptr &item, + std::vector &row, int proposedIndex) override; + + virtual void afterRemoved(const std::shared_ptr &item, + std::vector &row, int index) override; + friend class AccountController; + +private: + std::unordered_map categoryCount; }; } // namespace accounts diff --git a/src/main.cpp b/src/main.cpp index 6872b6f01..5c3607016 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -58,12 +58,12 @@ int runGui(int argc, char *argv[]) // https://stackoverflow.com/questions/15035767/is-the-qt-5-dark-fusion-theme-available-for-windows QPalette darkPalette = a.palette(); - darkPalette.setColor(QPalette::Window, QColor(33, 33, 33)); + darkPalette.setColor(QPalette::Window, QColor(22, 22, 22)); darkPalette.setColor(QPalette::WindowText, Qt::white); darkPalette.setColor(QPalette::Text, Qt::white); darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, QColor(127, 127, 127)); - darkPalette.setColor(QPalette::Base, QColor(90, 90, 90)); - darkPalette.setColor(QPalette::AlternateBase, QColor(66, 66, 66)); + darkPalette.setColor(QPalette::Base, QColor("#333")); + darkPalette.setColor(QPalette::AlternateBase, QColor("#444")); darkPalette.setColor(QPalette::ToolTipBase, Qt::white); darkPalette.setColor(QPalette::ToolTipText, Qt::white); darkPalette.setColor(QPalette::Disabled, QPalette::Text, QColor(127, 127, 127)); diff --git a/src/messages/message.cpp b/src/messages/message.cpp index 4b0e9f3cc..3b91f583d 100644 --- a/src/messages/message.cpp +++ b/src/messages/message.cpp @@ -32,7 +32,8 @@ MessagePtr Message::createSystemMessage(const QString &text) message->addElement(new TimestampElement(QTime::currentTime())); message->addElement(new TextElement(text, MessageElement::Text, MessageColor::System)); - message->flags.EnableFlag(MessageFlags::System); + message->flags |= MessageFlags::System; + message->flags |= MessageFlags::DoNotTriggerNotification; message->searchText = text; return message; diff --git a/src/providers/twitch/twitchaccount.cpp b/src/providers/twitch/twitchaccount.cpp index c089a7c22..4e893fe21 100644 --- a/src/providers/twitch/twitchaccount.cpp +++ b/src/providers/twitch/twitchaccount.cpp @@ -12,7 +12,7 @@ namespace twitch { TwitchAccount::TwitchAccount(const QString &_username, const QString &_oauthToken, const QString &_oauthClient, const QString &_userID) - : controllers::accounts::Account("Twitch") + : controllers::accounts::Account(ProviderId::Twitch) , oauthClient(_oauthClient) , oauthToken(_oauthToken) , userName(_username) diff --git a/src/providers/twitch/twitchaccountmanager.cpp b/src/providers/twitch/twitchaccountmanager.cpp index dcfd9bb4d..f86f75bf7 100644 --- a/src/providers/twitch/twitchaccountmanager.cpp +++ b/src/providers/twitch/twitchaccountmanager.cpp @@ -32,7 +32,7 @@ std::vector TwitchAccountManager::getUsernames() const std::lock_guard lock(this->mutex); - for (const auto &user : this->users) { + for (const auto &user : this->accounts.getVector()) { userNames.push_back(user->getUserName()); } @@ -44,7 +44,7 @@ std::shared_ptr TwitchAccountManager::findUserByUsername( { std::lock_guard lock(this->mutex); - for (const auto &user : this->users) { + for (const auto &user : this->accounts.getVector()) { if (username.compare(user->getUserName(), Qt::CaseInsensitive) == 0) { return user; } @@ -140,17 +140,27 @@ bool TwitchAccountManager::removeUser(const QString &username) return false; } - this->mutex.lock(); - this->users.erase(std::remove_if(this->users.begin(), this->users.end(), [username](auto user) { - if (user->getUserName() == username) { - std::string userID(user->getUserId().toStdString()); - assert(!userID.empty()); - pajlada::Settings::SettingManager::removeSetting("/accounts/uid" + userID); - return true; + { + std::lock_guard guard(this->mutex); + + const auto &accs = this->accounts.getVector(); + + while (true) { + auto it = std::find_if(accs.begin(), accs.end(), + [&](const auto &acc) { return acc->getUserName() == username; }); + + if (it == accs.end()) { + break; + } + + std::string userID(it->get()->getUserId().toStdString()); + if (!userID.empty()) { + pajlada::Settings::SettingManager::removeSetting("/accounts/uid" + userID); + } + + this->accounts.removeItem(int(it - accs.begin())); } - return false; - })); - this->mutex.unlock(); + } if (username == qS(this->currentUsername.getValue())) { // The user that was removed is the current user, log into the anonymous user @@ -189,7 +199,7 @@ TwitchAccountManager::AddUserResponse TwitchAccountManager::addUser( std::lock_guard lock(this->mutex); - this->users.push_back(newUser); + this->accounts.insertItem(newUser); return AddUserResponse::UserAdded; } diff --git a/src/providers/twitch/twitchaccountmanager.hpp b/src/providers/twitch/twitchaccountmanager.hpp index 973d3d700..b4e785934 100644 --- a/src/providers/twitch/twitchaccountmanager.hpp +++ b/src/providers/twitch/twitchaccountmanager.hpp @@ -68,7 +68,7 @@ private: std::shared_ptr currentUser; std::shared_ptr anonymousUser; - std::vector> users; + // std::vector> users; mutable std::mutex mutex; friend class chatterino::controllers::accounts::AccountController; diff --git a/src/providers/twitch/twitchchannel.hpp b/src/providers/twitch/twitchchannel.hpp index 60fe88336..d1637b859 100644 --- a/src/providers/twitch/twitchchannel.hpp +++ b/src/providers/twitch/twitchchannel.hpp @@ -7,7 +7,7 @@ #include "singletons/emotemanager.hpp" #include "singletons/ircmanager.hpp" #include "util/concurrentmap.hpp" -#include "util/mutexvalue.h" +#include "util/mutexvalue.hpp" #include diff --git a/src/providers/twitch/twitchserver.hpp b/src/providers/twitch/twitchserver.hpp index d143856ea..070c9b4cf 100644 --- a/src/providers/twitch/twitchserver.hpp +++ b/src/providers/twitch/twitchserver.hpp @@ -3,7 +3,7 @@ #include "providers/irc/abstractircserver.hpp" #include "providers/twitch/twitchaccount.hpp" #include "providers/twitch/twitchchannel.hpp" -#include "util/mutexvalue.h" +#include "util/mutexvalue.hpp" #include diff --git a/src/singletons/nativemessagingmanager.cpp b/src/singletons/nativemessagingmanager.cpp index fcccec231..6e371d233 100644 --- a/src/singletons/nativemessagingmanager.cpp +++ b/src/singletons/nativemessagingmanager.cpp @@ -113,13 +113,14 @@ void NativeMessagingManager::ReceiverThread::run() while (true) { try { - char *buf = (char *)malloc(MESSAGE_SIZE); + std::unique_ptr buf(static_cast(malloc(MESSAGE_SIZE))); ipc::message_queue::size_type retSize; unsigned int priority; - messageQueue.receive(buf, MESSAGE_SIZE, retSize, priority); + messageQueue.receive(buf.get(), MESSAGE_SIZE, retSize, priority); - QJsonDocument document = QJsonDocument::fromJson(QByteArray(buf, retSize)); + QJsonDocument document = + QJsonDocument::fromJson(QByteArray::fromRawData(buf.get(), retSize)); this->handleMessage(document.object()); } catch (ipc::interprocess_exception &ex) { diff --git a/src/util/mutexvalue.h b/src/util/mutexvalue.hpp similarity index 100% rename from src/util/mutexvalue.h rename to src/util/mutexvalue.hpp diff --git a/src/util/qstringhash.hpp b/src/util/qstringhash.hpp new file mode 100644 index 000000000..d108de7cc --- /dev/null +++ b/src/util/qstringhash.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include +#include + +namespace std { +template <> +struct hash { + std::size_t operator()(const QString &s) const + { + return qHash(s); + } +}; +} // namespace std diff --git a/src/util/signalvectormodel.cpp b/src/util/signalvectormodel.cpp deleted file mode 100644 index 7b74a3639..000000000 --- a/src/util/signalvectormodel.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "signalvectormodel.hpp" diff --git a/src/util/signalvectormodel.hpp b/src/util/signalvectormodel.hpp index 6548a60f4..3ab94a26a 100644 --- a/src/util/signalvectormodel.hpp +++ b/src/util/signalvectormodel.hpp @@ -28,10 +28,6 @@ public: this->vector = vec; auto insert = [this](const SignalVectorItemArgs &args) { - if (args.caller == this) { - return; - } - // get row index int index = this->getModelIndexFromVectorIndex(args.index); assert(index >= 0 && index <= this->rows.size()); @@ -58,20 +54,21 @@ public: this->managedConnect(vec->itemInserted, insert); this->managedConnect(vec->itemRemoved, [this](auto args) { - if (args.caller == this) { - return; - } - int row = this->getModelIndexFromVectorIndex(args.index); assert(row >= 0 && row <= this->rows.size()); // remove row + std::vector items = std::move(this->rows[row].items); + this->beginRemoveRows(QModelIndex(), row, row); - for (QStandardItem *item : this->rows[row].items) { - delete item; - } this->rows.erase(this->rows.begin() + row); this->endRemoveRows(); + + this->afterRemoved(args.item, items, row); + + for (QStandardItem *item : items) { + delete item; + } }); this->afterInit(); @@ -185,7 +182,7 @@ public: assert(row >= 0 && row < this->rows.size()); int signalVectorRow = this->getVectorIndexFromModelIndex(row); - this->vector->removeItem(signalVectorRow); + this->vector->removeItem(signalVectorRow, this); return true; } @@ -226,6 +223,16 @@ protected: this->endInsertRows(); } + void removeCustomRow(int index) + { + assert(index >= 0 && index <= this->rows.size()); + assert(this->rows[index].isCustomRow); + + this->beginRemoveRows(QModelIndex(), index, index); + this->rows.erase(this->rows.begin() + index); + this->endRemoveRows(); + } + std::vector createRow() { std::vector row; diff --git a/src/widgets/attachedwindow.cpp b/src/widgets/attachedwindow.cpp index e8668e2df..9de85b9fd 100644 --- a/src/widgets/attachedwindow.cpp +++ b/src/widgets/attachedwindow.cpp @@ -78,8 +78,8 @@ void AttachedWindow::attachToHwnd(void *_hwnd) QTimer *timer = new QTimer(this); timer->setInterval(1); - HWND hwnd = (HWND)this->winId(); - HWND attached = (HWND)_hwnd; + HWND hwnd = HWND(this->winId()); + HWND attached = HWND(_hwnd); QObject::connect(timer, &QTimer::timeout, [this, hwnd, attached, timer] { ::SetLastError(0); RECT xD; @@ -93,7 +93,8 @@ void AttachedWindow::attachToHwnd(void *_hwnd) HWND next = ::GetNextWindow(attached, GW_HWNDPREV); - ::SetWindowPos(hwnd, next ? next : HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + ::SetWindowPos(hwnd, next ? next : HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); ::MoveWindow(hwnd, xD.right - 360, xD.top + this->yOffset - 8, 360 - 8, xD.bottom - xD.top - this->yOffset, false); // ::MoveWindow(hwnd, xD.right - 360, xD.top + 82, 360 - 8, xD.bottom - xD.top - 82 - diff --git a/src/widgets/helper/channelview.cpp b/src/widgets/helper/channelview.cpp index 1b85ac8ec..3172fc1ce 100644 --- a/src/widgets/helper/channelview.cpp +++ b/src/widgets/helper/channelview.cpp @@ -579,7 +579,7 @@ bool ChannelView::isPaused() void ChannelView::paintEvent(QPaintEvent * /*event*/) { - BenchmarkGuard benchmark("paint event"); + // BenchmarkGuard benchmark("paint event"); QPainter painter(this); diff --git a/src/widgets/settingspages/accountspage.cpp b/src/widgets/settingspages/accountspage.cpp index 91acbd2d1..0ee2266e2 100644 --- a/src/widgets/settingspages/accountspage.cpp +++ b/src/widgets/settingspages/accountspage.cpp @@ -30,14 +30,17 @@ AccountsPage::AccountsPage() helper::EditableModelView *view = *layout.emplace(app->accounts->createModel(nullptr)); - view->setTitles({"Name"}); + view->getTableView()->horizontalHeader()->setVisible(false); view->getTableView()->horizontalHeader()->setStretchLastSection(true); view->addButtonPressed.connect([] { static auto loginWidget = new LoginWidget(); + loginWidget->show(); }); + view->getTableView()->setStyleSheet("background: #333"); + // auto buttons = layout.emplace(); // { // this->addButton = buttons->addButton("Add", QDialogButtonBox::YesRole); diff --git a/src/widgets/settingspages/ignoreuserspage.cpp b/src/widgets/settingspages/ignoreuserspage.cpp index 477c38471..ef901e3b2 100644 --- a/src/widgets/settingspages/ignoreuserspage.cpp +++ b/src/widgets/settingspages/ignoreuserspage.cpp @@ -34,7 +34,7 @@ IgnoreUsersPage::IgnoreUsersPage() // auto group = layout.emplace("Ignored users").setLayoutType(); auto tabs = layout.emplace(); - tabs->setStyleSheet("color: #000"); + // tabs->setStyleSheet("color: #000"); // users auto users = tabs.appendTab(new QVBoxLayout, "Users");