Remember subwindow positions.

master
Tomatix 5 years ago
parent 001c9b8690
commit 35a141492c
  1. 2
      IWin/IWin.h
  2. 1
      IWin/IWinStatus.h
  3. 12
      IdealIRC/ConfigMgr.cpp
  4. 2
      IdealIRC/ConfigMgr.h
  5. 38
      IdealIRC/IdealIRC.cpp
  6. 1
      IdealIRC/IdealIRC.h
  7. 110
      IdealIRC/MdiManager.cpp
  8. 7
      IdealIRC/MdiManager.h

@ -56,7 +56,7 @@ public:
protected:
explicit IWin(Type type, IWin* parentWindow = nullptr);
void closeEvent(QCloseEvent *) override;
void closeEvent(QCloseEvent*) override;
private:
Type m_type;

@ -51,6 +51,7 @@ public:
IWin* getActiveWindow();
QList<IWin*> subWindows() const;
IRC& getConnection() { return connection; }
const IRC& getConnection() const { return connection; }
ILineEdit& getInputBox() { return *input; }
private:

@ -146,6 +146,13 @@ QString ConfigMgr::color(const QString& key) const
return QString::fromStdString( ini.read("Color", keystdstr, defaultValue) );
}
QString ConfigMgr::window(const QString& key) const
{
const auto keystdstr = key.toStdString();
const auto& defaultValue = getDefault(defaultColor, keystdstr);
return QString::fromStdString( ini.read("Window", keystdstr, defaultValue) );
}
std::optional<QColor> ConfigMgr::prefixColor(const QChar& prefix) const
{
const std::string key = std::to_string(prefix.toLatin1());
@ -214,6 +221,11 @@ void ConfigMgr::setCommon(const QString& key, const QString& value)
ini.write("Common", key.toStdString(), value.toStdString());
}
void ConfigMgr::setWindow(const QString& key, const QString& value)
{
ini.write("Window", key.toStdString(), value.toStdString());
}
void ConfigMgr::setLogging(const QString& key, const QString& value)
{
ini.write("Logging", key.toStdString(), value.toStdString());

@ -22,6 +22,7 @@ public:
QString connection(const QString& key) const;
QString common(const QString& key) const;
QString color(const QString& key) const;
QString window(const QString& key) const;
std::optional<QColor> prefixColor(const QChar& prefix) const;
QHash<QString,QString> color() const;
QVector<std::pair<QChar,QColor>> prefixColor() const; // QVector of pairs preserves the order.
@ -31,6 +32,7 @@ public:
void setGeometry(const QString& key, const QString& value);
void setConnection(const QString& key, const QString& value);
void setCommon(const QString& key, const QString& value);
void setWindow(const QString& key, const QString& value);
void setLogging(const QString& key, const QString& value);
void setColorPalette(const QHash<QString,QString>& palette);
void setPrefixColorPalette(const QVector<std::pair<QChar,QColor>>& palette);

@ -80,6 +80,43 @@ IdealIRC::~IdealIRC()
delete ui;
}
void IdealIRC::saveSubwindowGeometries()
{
for (auto* mdiwin : mdiManager->mdiChildren()) {
IWin* subwin = dynamic_cast<IWin*>(mdiwin->widget());
if ((subwin->getType() == IWin::Type::Channel || subwin->getType() == IWin::Type::Private)
&& !mdiwin->isMaximized())
{
QString network;
try {
const auto* status = dynamic_cast<IWinStatus*>(subwin->getStatusParent());
network = QString::fromStdString( status->getConnection().isupport().at("NETWORK") );
}
catch (...) {}
QString persistentWindowName;
if (network.isEmpty())
persistentWindowName = subwin->getButtonText();
else
persistentWindowName = QStringLiteral("%1_%2")
.arg(network)
.arg(subwin->getButtonText());
const auto pos = mdiwin->pos();
const auto size = mdiwin->size();
const auto geo = QStringLiteral("%1,%2,%3,%4")
.arg(pos.x())
.arg(pos.y())
.arg(size.width())
.arg(size.height());
auto& conf = ConfigMgr::instance();
conf.setWindow(persistentWindowName, geo);
}
}
}
void IdealIRC::closeEvent(QCloseEvent* evt)
{
ConfigMgr& conf = ConfigMgr::instance();
@ -137,6 +174,7 @@ void IdealIRC::closeEvent(QCloseEvent* evt)
evt->ignore();
}
else {
saveSubwindowGeometries();
ConfigMgr::instance().save();
ScriptManager::event("exit");
ScriptManager::instance()->unloadAllScripts();

@ -53,6 +53,7 @@ private:
Disconnect
};
void saveSubwindowGeometries();
void closeEvent(QCloseEvent* evt);
void startup();
void subwindowSwitched();

@ -118,7 +118,19 @@ IWin* MdiManager::createSubwindow(IWin* parent, const QString& buttonText, IWin:
mdiwin->setAttribute(Qt::WA_DeleteOnClose);
m_bbMgr.addButton(basePtr, mdiwin);
QRect spawnCoord = generateSpawnCoordinates();
QString networkKey, windowKey;
if (windowType == IWin::Type::Channel || windowType == IWin::Type::Private) {
const auto& connection = dynamic_cast<IWinStatus*>(parent)->getConnection();
try {
networkKey = QString::fromStdString(connection.isupport().at("NETWORK"));
}
catch (...) {}
windowKey = buttonText;
}
QRect spawnCoord = generateSpawnCoordinates(networkKey, windowKey);
mdiwin->setGeometry(spawnCoord);
qInfo() << "Created a subwindow of type" << IWin::TypeString[windowType] << "with button text" << buttonText;
@ -209,7 +221,7 @@ int MdiManager::connectionsOnlineCount() const
IWin* subwin = dynamic_cast<IWin*>(mdiwin->widget());
if (subwin->getType() != IWin::Type::Status)
continue;
IWinStatus* status = dynamic_cast<IWinStatus*>(subwin);
auto* status = dynamic_cast<IWinStatus*>(subwin);
if (status->getConnection().isOnline())
++c;
}
@ -220,18 +232,19 @@ void MdiManager::broadcastProgramExit()
{
for (QMdiSubWindow* mdiwin : m_mdiArea.subWindowList()) {
IWin* subwin = dynamic_cast<IWin*>(mdiwin->widget());
if (subwin->getType() != IWin::Type::Status)
continue;
IWinStatus* status = dynamic_cast<IWinStatus*>(subwin);
if (status->getConnection().isOnline()) {
connect(&status->getConnection(), &IRC::readyForExit, [this](){
if (connectionsOnlineCount() == 0)
emit readyForExit();
});
ConfigMgr& conf = ConfigMgr::instance();
status->getConnection().disconnectForExit(conf.common("QuitMessage"));
}
if (subwin->getType() == IWin::Type::Status) {
auto* status = dynamic_cast<IWinStatus*>(subwin);
if (status->getConnection().isOnline()) {
connect(&status->getConnection(), &IRC::readyForExit,
[this]() {
if (connectionsOnlineCount() == 0)
emit readyForExit();
});
ConfigMgr& conf = ConfigMgr::instance();
status->getConnection().disconnectForExit(conf.common("QuitMessage"));
}
}
}
}
@ -321,19 +334,64 @@ void MdiManager::subwinActivated(QMdiSubWindow* window)
emit subwindowSwitched();
}
QRect MdiManager::generateSpawnCoordinates()
QRect MdiManager::generateSpawnCoordinates(const QString& networkKey, const QString& windowKey)
{
QRect rectangle(nextXY, nextXY, WINDOW_DEFAULT_WIDTH, WINDOW_DEFAULT_HEIGHT);
nextXY += WINDOW_STEP;
if (nextXY > WINDOW_STEP_RESET_POSITION) {
nextXYadjust += WINDOW_STEP_RESET_ADJUST;
if (nextXYadjust > WINDOW_STEP_RESET_POSITION)
nextXYadjust = 0;
nextXY = nextXYadjust;
}
auto generate = [this] {
QRect rectangle(nextXY, nextXY, WINDOW_DEFAULT_WIDTH, WINDOW_DEFAULT_HEIGHT);
nextXY += WINDOW_STEP;
if (nextXY > WINDOW_STEP_RESET_POSITION) {
nextXYadjust += WINDOW_STEP_RESET_ADJUST;
if (nextXYadjust > WINDOW_STEP_RESET_POSITION)
nextXYadjust = 0;
nextXY = nextXYadjust;
}
return rectangle;
};
if (windowKey.isEmpty()) {
return generate();
}
else {
auto persistentKey = QStringLiteral("%1_%2")
.arg(networkKey)
.arg(windowKey);
if (networkKey.isEmpty())
persistentKey = windowKey;
const auto& conf = ConfigMgr::instance();
auto geometryString = conf.window(persistentKey);
if (geometryString.isEmpty()) {
/*
* If the key (persistentKey) doesn't exist, check config if any window name that isn't
* tied to any network name exist, and use that.
*/
geometryString = conf.window(windowKey);
if (geometryString.isEmpty())
return generate();
}
QStringList geometry = geometryString.split(',');
if (geometry.count() < 4) {
qWarning() << "Configuration for subwindow geometry '" << persistentKey << "' is invalid, resolving using generic positioning algorithm.";
return generate();
}
const int X = geometry[0].toInt();
const int Y = geometry[1].toInt();
const int W = geometry[2].toInt();
const int H = geometry[3].toInt();
return { X, Y, W, H };
}
}
return rectangle;
QList<QMdiSubWindow*> MdiManager::mdiChildren() const
{
QList<QMdiSubWindow*> ret;
for (QMdiSubWindow* mdiwin : m_mdiArea.subWindowList())
ret << mdiwin;
return ret;
}

@ -50,8 +50,9 @@ public:
IWin* findWindow(IWin* statusParent, const QString& buttonText);
QMdiSubWindow* toMdiwin(IWin* win);
QList<QMdiSubWindow*> mdiChildrenOf(const IWin* statusParent, IWin::Type type = IWin::Type::Undefined) const;
QList<IWin*> childrenOf(const IWin* statusParent, IWin::Type type = IWin::Type::Undefined) const;
void showTrayInfo(const QString& title, const QString& message);
QList<IWin*> childrenOf(const IWin* statusParent, IWin::Type type = IWin::Type::Undefined) const;
QList<QMdiSubWindow*> mdiChildren() const;
void showTrayInfo(const QString& title, const QString& message);
void showTrayWarn(const QString& title, const QString& message);
int connectionsOnlineCount() const;
void broadcastProgramExit();
@ -88,7 +89,7 @@ private:
int nextXY{ 0 };
int nextXYadjust{ 0 };
QRect generateSpawnCoordinates();
QRect generateSpawnCoordinates(const QString& networkKey, const QString& windowKey);
static MdiManager* m_instance;

Loading…
Cancel
Save