2017-06-11 09:31:45 +02:00
|
|
|
#include "windowmanager.hpp"
|
2018-01-05 02:56:18 +01:00
|
|
|
#include "debug/log.hpp"
|
2018-04-06 23:31:34 +02:00
|
|
|
#include "providers/twitch/twitchserver.hpp"
|
2017-12-31 22:58:35 +01:00
|
|
|
#include "singletons/fontmanager.hpp"
|
2018-04-06 23:31:34 +02:00
|
|
|
#include "singletons/pathmanager.hpp"
|
2017-12-31 00:50:07 +01:00
|
|
|
#include "singletons/thememanager.hpp"
|
2018-01-24 15:08:22 +01:00
|
|
|
#include "widgets/accountswitchpopupwidget.hpp"
|
|
|
|
#include "widgets/settingsdialog.hpp"
|
2017-01-15 16:38:30 +01:00
|
|
|
|
2018-04-06 23:31:34 +02:00
|
|
|
#include <QJsonDocument>
|
|
|
|
#include <QJsonObject>
|
|
|
|
|
2017-01-28 22:35:23 +01:00
|
|
|
#include <QDebug>
|
|
|
|
|
2018-04-06 23:31:34 +02:00
|
|
|
#define SETTINGS_FILENAME "/layout.json"
|
|
|
|
|
2017-01-18 21:30:23 +01:00
|
|
|
namespace chatterino {
|
2017-12-31 22:58:35 +01:00
|
|
|
namespace singletons {
|
2018-01-05 02:56:18 +01:00
|
|
|
|
2017-12-31 00:50:07 +01:00
|
|
|
WindowManager &WindowManager::getInstance()
|
|
|
|
{
|
|
|
|
static WindowManager instance(ThemeManager::getInstance());
|
|
|
|
return instance;
|
|
|
|
}
|
2017-04-13 19:25:33 +02:00
|
|
|
|
2018-01-24 15:08:22 +01:00
|
|
|
void WindowManager::showSettingsDialog()
|
|
|
|
{
|
|
|
|
QTimer::singleShot(80, [] { widgets::SettingsDialog::showDialog(); });
|
|
|
|
}
|
|
|
|
|
|
|
|
void WindowManager::showAccountSelectPopup(QPoint point)
|
|
|
|
{
|
|
|
|
// static QWidget *lastFocusedWidget = nullptr;
|
|
|
|
static widgets::AccountSwitchPopupWidget *w = new widgets::AccountSwitchPopupWidget();
|
|
|
|
|
|
|
|
if (w->hasFocus()) {
|
|
|
|
w->hide();
|
|
|
|
// if (lastFocusedWidget) {
|
|
|
|
// lastFocusedWidget->setFocus();
|
|
|
|
// }
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// lastFocusedWidget = this->focusWidget();
|
|
|
|
|
|
|
|
w->refresh();
|
|
|
|
|
|
|
|
QPoint buttonPos = point;
|
|
|
|
w->move(buttonPos.x(), buttonPos.y());
|
|
|
|
|
|
|
|
w->show();
|
|
|
|
w->setFocus();
|
|
|
|
}
|
|
|
|
|
2017-12-31 00:50:07 +01:00
|
|
|
WindowManager::WindowManager(ThemeManager &_themeManager)
|
|
|
|
: themeManager(_themeManager)
|
2017-04-13 19:25:33 +02:00
|
|
|
{
|
2017-12-31 00:50:07 +01:00
|
|
|
_themeManager.repaintVisibleChatWidgets.connect([this] { this->repaintVisibleChatWidgets(); });
|
2017-04-13 19:25:33 +02:00
|
|
|
}
|
2017-01-18 21:30:23 +01:00
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
void WindowManager::layoutVisibleChatWidgets(Channel *channel)
|
2017-01-15 16:38:30 +01:00
|
|
|
{
|
2018-04-03 02:55:32 +02:00
|
|
|
this->layout.invoke(channel);
|
2017-01-16 03:15:07 +01:00
|
|
|
}
|
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
void WindowManager::repaintVisibleChatWidgets(Channel *channel)
|
2017-01-16 03:15:07 +01:00
|
|
|
{
|
2017-06-13 21:13:58 +02:00
|
|
|
if (this->mainWindow != nullptr) {
|
|
|
|
this->mainWindow->repaintVisibleChatWidgets(channel);
|
2017-01-26 04:26:40 +01:00
|
|
|
}
|
2017-01-15 16:38:30 +01:00
|
|
|
}
|
2017-01-26 21:04:01 +01:00
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
void WindowManager::repaintGifEmotes()
|
2017-02-07 00:03:15 +01:00
|
|
|
{
|
2018-04-03 02:55:32 +02:00
|
|
|
this->repaintGifs.invoke();
|
2017-02-07 00:03:15 +01:00
|
|
|
}
|
|
|
|
|
2017-09-16 00:05:06 +02:00
|
|
|
// void WindowManager::updateAll()
|
|
|
|
//{
|
|
|
|
// if (this->mainWindow != nullptr) {
|
|
|
|
// this->mainWindow->update();
|
|
|
|
// }
|
|
|
|
//}
|
2017-02-02 01:23:26 +01:00
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
widgets::Window &WindowManager::getMainWindow()
|
2017-04-13 19:25:33 +02:00
|
|
|
{
|
2017-06-13 21:13:58 +02:00
|
|
|
return *this->mainWindow;
|
2017-04-13 19:25:33 +02:00
|
|
|
}
|
|
|
|
|
2017-12-14 00:25:06 +01:00
|
|
|
widgets::Window &WindowManager::getSelectedWindow()
|
2017-11-12 17:21:50 +01:00
|
|
|
{
|
2017-12-14 00:25:06 +01:00
|
|
|
return *this->selectedWindow;
|
2017-11-12 17:21:50 +01:00
|
|
|
}
|
|
|
|
|
2018-04-06 23:31:34 +02:00
|
|
|
widgets::Window &WindowManager::createWindow(widgets::Window::WindowType type)
|
2017-11-12 17:21:50 +01:00
|
|
|
{
|
2018-04-06 23:31:34 +02:00
|
|
|
auto *window = new widgets::Window(this->themeManager, type);
|
2017-11-12 17:21:50 +01:00
|
|
|
this->windows.push_back(window);
|
2018-04-06 23:31:34 +02:00
|
|
|
window->show();
|
2017-11-12 17:21:50 +01:00
|
|
|
|
2018-04-08 14:13:48 +02:00
|
|
|
if (type != widgets::Window::Main) {
|
|
|
|
window->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
|
|
|
|
QObject::connect(window, &QWidget::destroyed, [this, window] {
|
|
|
|
for (auto it = this->windows.begin(); it != this->windows.end(); it++) {
|
|
|
|
if (*it == window) {
|
|
|
|
this->windows.erase(it);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
return *window;
|
|
|
|
}
|
|
|
|
|
2017-12-14 00:25:06 +01:00
|
|
|
int WindowManager::windowCount()
|
|
|
|
{
|
|
|
|
return this->windows.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
widgets::Window *WindowManager::windowAt(int index)
|
|
|
|
{
|
2017-12-23 23:24:35 +01:00
|
|
|
if (index < 0 || (size_t)index >= this->windows.size()) {
|
2017-12-14 00:25:06 +01:00
|
|
|
return nullptr;
|
|
|
|
}
|
2018-01-05 02:56:18 +01:00
|
|
|
debug::Log("getting window at bad index {}", index);
|
2017-12-14 00:25:06 +01:00
|
|
|
|
|
|
|
return this->windows.at(index);
|
|
|
|
}
|
|
|
|
|
2018-04-06 23:31:34 +02:00
|
|
|
void WindowManager::initialize()
|
2017-01-26 21:04:01 +01:00
|
|
|
{
|
2018-04-06 23:31:34 +02:00
|
|
|
assert(!this->initialized);
|
|
|
|
|
|
|
|
// load file
|
|
|
|
QString settingsPath = PathManager::getInstance().settingsFolderPath + SETTINGS_FILENAME;
|
|
|
|
QFile file(settingsPath);
|
|
|
|
file.open(QIODevice::ReadOnly);
|
|
|
|
QByteArray data = file.readAll();
|
|
|
|
QJsonDocument document = QJsonDocument::fromJson(data);
|
|
|
|
QJsonArray windows_arr = document.object().value("windows").toArray();
|
|
|
|
|
|
|
|
// "deserialize"
|
|
|
|
for (QJsonValue window_val : windows_arr) {
|
|
|
|
QJsonObject window_obj = window_val.toObject();
|
|
|
|
|
|
|
|
// get type
|
|
|
|
QString type_val = window_obj.value("type").toString();
|
|
|
|
widgets::Window::WindowType type =
|
|
|
|
type_val == "main" ? widgets::Window::Main : widgets::Window::Popup;
|
|
|
|
|
|
|
|
if (type == widgets::Window::Main && mainWindow != nullptr) {
|
|
|
|
type = widgets::Window::Popup;
|
|
|
|
}
|
|
|
|
|
|
|
|
widgets::Window &window = createWindow(type);
|
|
|
|
|
|
|
|
if (type == widgets::Window::Main) {
|
|
|
|
mainWindow = &window;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get geometry
|
|
|
|
{
|
|
|
|
int x = window_obj.value("x").toInt(-1);
|
|
|
|
int y = window_obj.value("y").toInt(-1);
|
|
|
|
int width = window_obj.value("width").toInt(-1);
|
|
|
|
int height = window_obj.value("height").toInt(-1);
|
|
|
|
|
|
|
|
if (x != -1 && y != -1 && width != -1 && height != -1) {
|
|
|
|
window.setGeometry(x, y, width, height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// load tabs
|
|
|
|
QJsonArray tabs = window_obj.value("tabs").toArray();
|
|
|
|
for (QJsonValue tab_val : tabs) {
|
|
|
|
widgets::SplitContainer *tab = window.getNotebook().addNewPage();
|
|
|
|
|
|
|
|
QJsonObject tab_obj = tab_val.toObject();
|
|
|
|
|
|
|
|
// set custom title
|
|
|
|
QJsonValue title_val = tab_obj.value("title");
|
|
|
|
if (title_val.isString()) {
|
|
|
|
tab->getTab()->setTitle(title_val.toString());
|
|
|
|
tab->getTab()->useDefaultTitle = false;
|
|
|
|
}
|
|
|
|
|
2018-04-10 15:59:53 +02:00
|
|
|
// selected
|
|
|
|
if (tab_obj.value("selected").toBool(false)) {
|
|
|
|
window.getNotebook().select(tab);
|
|
|
|
}
|
|
|
|
|
2018-04-06 23:31:34 +02:00
|
|
|
// load splits
|
|
|
|
int colNr = 0;
|
|
|
|
for (QJsonValue column_val : tab_obj.value("splits").toArray()) {
|
|
|
|
for (QJsonValue split_val : column_val.toArray()) {
|
|
|
|
widgets::Split *split = new widgets::Split(tab);
|
|
|
|
|
|
|
|
QJsonObject split_obj = split_val.toObject();
|
2018-04-20 22:33:28 +02:00
|
|
|
split->setChannel(this->decodeChannel(split_obj));
|
2018-04-06 23:31:34 +02:00
|
|
|
|
2018-04-10 17:14:13 +02:00
|
|
|
tab->addToLayout(split, std::make_pair(colNr, 10000000));
|
2018-04-06 23:31:34 +02:00
|
|
|
}
|
|
|
|
colNr++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mainWindow == nullptr) {
|
|
|
|
mainWindow = &createWindow(widgets::Window::Main);
|
|
|
|
mainWindow->getNotebook().addNewPage(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
this->initialized = true;
|
|
|
|
}
|
2017-01-28 22:35:23 +01:00
|
|
|
|
2018-04-06 23:31:34 +02:00
|
|
|
void WindowManager::save()
|
|
|
|
{
|
|
|
|
QJsonDocument document;
|
2017-01-28 22:35:23 +01:00
|
|
|
|
2018-04-06 23:31:34 +02:00
|
|
|
// "serialize"
|
|
|
|
QJsonArray window_arr;
|
2017-12-22 14:44:31 +01:00
|
|
|
for (widgets::Window *window : this->windows) {
|
2018-04-06 23:31:34 +02:00
|
|
|
QJsonObject window_obj;
|
|
|
|
|
|
|
|
// window type
|
|
|
|
switch (window->getType()) {
|
|
|
|
case widgets::Window::Main:
|
|
|
|
window_obj.insert("type", "main");
|
|
|
|
break;
|
|
|
|
case widgets::Window::Popup:
|
|
|
|
window_obj.insert("type", "popup");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// window geometry
|
|
|
|
window_obj.insert("x", window->x());
|
|
|
|
window_obj.insert("y", window->y());
|
|
|
|
window_obj.insert("width", window->width());
|
|
|
|
window_obj.insert("height", window->height());
|
|
|
|
|
|
|
|
// window tabs
|
|
|
|
QJsonArray tabs_arr;
|
|
|
|
|
|
|
|
for (int tab_i = 0; tab_i < window->getNotebook().tabCount(); tab_i++) {
|
|
|
|
QJsonObject tab_obj;
|
|
|
|
widgets::SplitContainer *tab = window->getNotebook().tabAt(tab_i);
|
|
|
|
|
|
|
|
// custom tab title
|
|
|
|
if (!tab->getTab()->useDefaultTitle) {
|
|
|
|
tab_obj.insert("title", tab->getTab()->getTitle());
|
|
|
|
}
|
|
|
|
|
2018-04-10 15:59:53 +02:00
|
|
|
// selected
|
|
|
|
if (window->getNotebook().getSelectedPage() == tab) {
|
|
|
|
tab_obj.insert("selected", true);
|
|
|
|
}
|
|
|
|
|
2018-04-06 23:31:34 +02:00
|
|
|
// splits
|
|
|
|
QJsonArray columns_arr;
|
|
|
|
std::vector<std::vector<widgets::Split *>> columns = tab->getColumns();
|
|
|
|
|
|
|
|
for (std::vector<widgets::Split *> &cells : columns) {
|
|
|
|
QJsonArray cells_arr;
|
|
|
|
|
|
|
|
for (widgets::Split *cell : cells) {
|
|
|
|
QJsonObject cell_obj;
|
2018-04-20 22:33:28 +02:00
|
|
|
|
|
|
|
this->encodeChannel(cell->getIndirectChannel(), cell_obj);
|
2018-04-06 23:31:34 +02:00
|
|
|
|
|
|
|
cells_arr.append(cell_obj);
|
|
|
|
}
|
|
|
|
columns_arr.append(cells_arr);
|
|
|
|
}
|
|
|
|
|
|
|
|
tab_obj.insert("splits", columns_arr);
|
|
|
|
tabs_arr.append(tab_obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
window_obj.insert("tabs", tabs_arr);
|
|
|
|
window_arr.append(window_obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
QJsonObject obj;
|
|
|
|
obj.insert("windows", window_arr);
|
|
|
|
document.setObject(obj);
|
|
|
|
|
|
|
|
// save file
|
|
|
|
QString settingsPath = PathManager::getInstance().settingsFolderPath + SETTINGS_FILENAME;
|
|
|
|
QFile file(settingsPath);
|
|
|
|
file.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
|
|
|
file.write(document.toJson());
|
|
|
|
file.flush();
|
|
|
|
}
|
|
|
|
|
2018-04-20 22:33:28 +02:00
|
|
|
void WindowManager::encodeChannel(IndirectChannel channel, QJsonObject &obj)
|
|
|
|
{
|
|
|
|
switch (channel.getType()) {
|
|
|
|
case Channel::Twitch: {
|
|
|
|
obj.insert("type", "twitch");
|
|
|
|
obj.insert("name", channel.get()->name);
|
|
|
|
} break;
|
|
|
|
case Channel::TwitchMentions: {
|
|
|
|
obj.insert("type", "mentions");
|
|
|
|
} break;
|
|
|
|
case Channel::TwitchWatching: {
|
|
|
|
obj.insert("type", "watching");
|
|
|
|
} break;
|
|
|
|
case Channel::TwitchWhispers: {
|
|
|
|
obj.insert("type", "whispers");
|
|
|
|
} break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IndirectChannel WindowManager::decodeChannel(const QJsonObject &obj)
|
|
|
|
{
|
|
|
|
QString type = obj.value("type").toString();
|
|
|
|
if (type == "twitch") {
|
|
|
|
return providers::twitch::TwitchServer::getInstance().addChannel(
|
|
|
|
obj.value("name").toString());
|
|
|
|
} else if (type == "mentions") {
|
|
|
|
return providers::twitch::TwitchServer::getInstance().mentionsChannel;
|
|
|
|
} else if (type == "watching") {
|
|
|
|
return providers::twitch::TwitchServer::getInstance().watchingChannel;
|
|
|
|
} else if (type == "whispers") {
|
|
|
|
return providers::twitch::TwitchServer::getInstance().whispersChannel;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Channel::getEmpty();
|
|
|
|
}
|
|
|
|
|
2018-04-06 23:31:34 +02:00
|
|
|
void WindowManager::closeAll()
|
|
|
|
{
|
|
|
|
for (widgets::Window *window : windows) {
|
|
|
|
window->close();
|
2017-01-28 22:35:23 +01:00
|
|
|
}
|
2017-01-26 21:04:01 +01:00
|
|
|
}
|
2017-01-28 22:35:23 +01:00
|
|
|
|
2018-01-05 02:56:18 +01:00
|
|
|
} // namespace singletons
|
2017-04-14 17:52:22 +02:00
|
|
|
} // namespace chatterino
|