X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=gui%2Fmainwin.cpp;h=5beefdf2db90ccf3877541348e6975dd85a8dbbe;hp=3fefe4d77f78ce9b7b42f77bc9365e8bb8fe2a43;hb=2a068c11e76c7b34afb64d443dbb1afd2e208aaa;hpb=1c7d9f13b744cd517c0769f453fd8dc3106cd94c diff --git a/gui/mainwin.cpp b/gui/mainwin.cpp index 3fefe4d7..5beefdf2 100644 --- a/gui/mainwin.cpp +++ b/gui/mainwin.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005 by The Quassel Team * + * Copyright (C) 2005-07 by The Quassel Team * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -20,99 +20,190 @@ #include #include +#include +#include "util.h" #include "global.h" +#include "message.h" +#include "guiproxy.h" #include "mainwin.h" -#include "channelwidget.h" +#include "buffer.h" +#include "networkview.h" #include "serverlist.h" #include "coreconnectdlg.h" +#include "settingsdlg.h" +#include "settingspages.h" -MainWin::MainWin() : QMainWindow() { +LayoutThread *layoutThread; +MainWin::MainWin() : QMainWindow() { + ui.setupUi(this); + //widget = 0; + qDebug() << "Available DB drivers: " << QSqlDatabase::drivers (); setWindowTitle("Quassel IRC"); setWindowIcon(QIcon(":/qirc-icon.png")); setWindowIconText("Quassel IRC"); - QSettings s; - s.beginGroup("Geometry"); - resize(s.value("MainWinSize", QSize(500, 400)).toSize()); - move(s.value("MainWinPos", QPoint(50, 50)).toPoint()); - s.endGroup(); - //workspace = new QWorkspace(this); //setCentralWidget(workspace); statusBar()->showMessage(tr("Waiting for core...")); - setEnabled(false); +} + +void MainWin::init() { + + connect(guiProxy, SIGNAL(csServerState(QString, QVariant)), this, SLOT(recvNetworkState(QString, QVariant))); + connect(guiProxy, SIGNAL(csServerConnected(QString)), this, SLOT(networkConnected(QString))); + connect(guiProxy, SIGNAL(csServerDisconnected(QString)), this, SLOT(networkDisconnected(QString))); + connect(guiProxy, SIGNAL(csDisplayMsg(QString, Message)), this, SLOT(recvMessage(QString, Message))); + connect(guiProxy, SIGNAL(csDisplayStatusMsg(QString, QString)), this, SLOT(recvStatusMsg(QString, QString))); + connect(guiProxy, SIGNAL(csTopicSet(QString, QString, QString)), this, SLOT(setTopic(QString, QString, QString))); + connect(guiProxy, SIGNAL(csSetNicks(QString, QString, QStringList)), this, SLOT(setNicks(QString, QString, QStringList))); + connect(guiProxy, SIGNAL(csNickAdded(QString, QString, VarMap)), this, SLOT(addNick(QString, QString, VarMap))); + connect(guiProxy, SIGNAL(csNickRemoved(QString, QString)), this, SLOT(removeNick(QString, QString))); + connect(guiProxy, SIGNAL(csNickRenamed(QString, QString, QString)), this, SLOT(renameNick(QString, QString, QString))); + connect(guiProxy, SIGNAL(csNickUpdated(QString, QString, VarMap)), this, SLOT(updateNick(QString, QString, VarMap))); + connect(guiProxy, SIGNAL(csOwnNickSet(QString, QString)), this, SLOT(setOwnNick(QString, QString))); + connect(this, SIGNAL(sendInput( QString, QString, QString )), guiProxy, SLOT(gsUserInput(QString, QString, QString))); + + layoutThread = new LayoutThread(); + layoutThread->start(); + while(!layoutThread->isRunning()) {}; + ui.bufferWidget->init(); + show(); syncToCore(); - setEnabled(true); + statusBar()->showMessage(tr("Ready.")); + systray = new QSystemTrayIcon(this); + systray->setIcon(QIcon(":/qirc-icon.png")); + systray->show(); + serverListDlg = new ServerListDlg(this); serverListDlg->setVisible(serverListDlg->showOnStartup()); + + setupSettingsDlg(); + + //Buffer::init(); setupMenus(); - //identitiesAct = settingsMenu->addAction(QIcon(":/default/identity.png"), tr("&Identities..."), serverListDlg, SLOT(editIdentities())); - //showServerList(); - IrcWidget *cw = new IrcWidget(this); - setCentralWidget(cw); - //workspace->addWindow(cw); - //cw->showMaximized(); - statusBar()->showMessage(tr("Ready.")); - cw->setFocus(); -} + setupViews(); + + //bufferWidget = 0; + + QSettings s; + s.beginGroup("Geometry"); + //resize(s.value("MainWinSize", QSize(500, 400)).toSize()); + //move(s.value("MainWinPos", QPoint(50, 50)).toPoint()); + if(s.contains("MainWinState")) restoreState(s.value("MainWinState").toByteArray()); + s.endGroup(); -void MainWin::syncToCore() { - if(global->getData("CoreReady").toBool()) return; - // ok, apparently we are running as standalone GUI - coreConnectDlg = new CoreConnectDlg(this); - if(coreConnectDlg->exec() != QDialog::Accepted) { - //qApp->quit(); - exit(1); + // replay backlog + // FIXME do this right + QHash > hash; + Buffer *b; + + foreach(QString net, coreBackLog.keys()) { + //if(net != "MoepNet") continue; + while(coreBackLog[net].count()) { + //recvMessage(net, coreBackLog[net].takeFirst()); + Message msg = coreBackLog[net].takeLast(); + if(msg.flags & Message::PrivMsg) { + // query + if(msg.flags & Message::Self) b = getBuffer(net, msg.target); + else b = getBuffer(net, nickFromMask(msg.sender)); + } else { + b = getBuffer(net, msg.target); + } + hash[b].prepend(msg); + if(hash[b].count() >= 5) { + ui.bufferWidget->prependMessages(b, hash.take(b)); + } + } } - VarMap state = coreConnectDlg->getCoreState().toMap()["CoreData"].toMap(); - delete coreConnectDlg; - QString key; - foreach(key, state.keys()) { - global->updateData(key, state[key]); + foreach(Buffer *buf, hash.keys()) { + ui.bufferWidget->prependMessages(buf, hash.take(buf)); } - if(!global->getData("CoreReady").toBool()) { - QMessageBox::critical(this, tr("Fatal Error"), tr("Could not synchronize with Quassel Core!
Quassel GUI will be aborted."), QMessageBox::Abort); - //qApp->quit(); - exit(1); + +/* + foreach(QString key, buffers.keys()) { + foreach(Buffer *b, buffers[key].values()) { + QWidget *widget = b->showWidget(this); + workspace->addWindow(widget); + widget->show(); + } } -} +*/ -void MainWin::setupMenus() { - fileMenu = menuBar()->addMenu(tr("&File")); - serverListAct = fileMenu->addAction(QIcon(":/default/server.png"), tr("&Server List..."), this, SLOT(showServerList()), tr("F7")); - fileMenu->addSeparator(); - quitAct = fileMenu->addAction(QIcon(":/default/exit.png"), tr("&Quit"), qApp, SLOT(quit()), tr("CTRL+Q")); + s.beginGroup("Buffers"); + QString net = s.value("CurrentNetwork", "").toString(); + QString buf = s.value("CurrentBuffer", "").toString(); + s.endGroup(); + if(!net.isEmpty()) { + if(buffers.contains(net)) { + if(buffers[net].contains(buf)) { + showBuffer(net, buf); + } else { + showBuffer(net, ""); + } + } + } +} - editMenu = menuBar()->addMenu(tr("&Edit")); - editMenu->setEnabled(0); +MainWin::~MainWin() { + typedef QHash BufHash; + foreach(BufHash h, buffers.values()) { + foreach(Buffer *b, h.values()) { + delete b; + } + } +} - ircMenu = menuBar()->addMenu(tr("&IRC")); - ircMenu->setEnabled(0); +/* This is implemented in settingspages.cpp */ +/* +void MainWin::setupSettingsDlg() { - serverMenu = menuBar()->addMenu(tr("Ser&ver")); - serverMenu->setEnabled(0); +} +*/ - windowMenu = menuBar()->addMenu(tr("&Window")); - windowMenu->setEnabled(0); +void MainWin::setupMenus() { + connect(ui.actionNetworkList, SIGNAL(triggered()), this, SLOT(showServerList())); + connect(ui.actionEditIdentities, SIGNAL(triggered()), serverListDlg, SLOT(editIdentities())); + connect(ui.actionSettingsDlg, SIGNAL(triggered()), this, SLOT(showSettingsDlg())); + //ui.actionSettingsDlg->setEnabled(false); + connect(ui.actionAboutQt, SIGNAL(triggered()), QApplication::instance(), SLOT(aboutQt())); +} - settingsMenu = menuBar()->addMenu(tr("&Settings")); - identitiesAct = settingsMenu->addAction(QIcon(":/default/identity.png"), tr("&Identities..."), serverListDlg, SLOT(editIdentities())); - settingsMenu->addSeparator(); - configAct = settingsMenu->addAction(QIcon(":/default/configure.png"), tr("&Configure Quassel...")); - configAct->setEnabled(0); +void MainWin::setupViews() { + NetworkView *all = new NetworkView(tr("All Buffers"), NetworkView::AllNets); + registerNetView(all); + addDockWidget(Qt::LeftDockWidgetArea, all); + NetworkView *allchans = new NetworkView(tr("All Channels"), NetworkView::AllNets|NetworkView::NoQueries|NetworkView::NoServers); + registerNetView(allchans); + addDockWidget(Qt::LeftDockWidgetArea, allchans); + NetworkView *allqrys = new NetworkView(tr("All Queries"), NetworkView::AllNets|NetworkView::NoChannels|NetworkView::NoServers); + registerNetView(allqrys); + addDockWidget(Qt::RightDockWidgetArea, allqrys); + NetworkView *allnets = new NetworkView(tr("All Networks"), NetworkView::AllNets|NetworkView::NoChannels|NetworkView::NoQueries); + registerNetView(allnets); + addDockWidget(Qt::RightDockWidgetArea, allnets); - helpMenu = menuBar()->addMenu(tr("&Help")); - aboutAct = helpMenu->addAction(tr("&About")); - aboutAct->setEnabled(0); - aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, SLOT(aboutQt())); + ui.menuViews->addSeparator(); +} - //toolBar = new QToolBar("Test", this); - //toolBar->addAction(identitiesAct); - //addToolBar(Qt::TopToolBarArea, toolBar); +void MainWin::registerNetView(NetworkView *view) { + connect(this, SIGNAL(bufferSelected(Buffer *)), view, SLOT(selectBuffer(Buffer *))); + connect(this, SIGNAL(bufferUpdated(Buffer *)), view, SLOT(bufferUpdated(Buffer *))); + connect(this, SIGNAL(bufferDestroyed(Buffer *)), view, SLOT(bufferDestroyed(Buffer *))); + connect(view, SIGNAL(bufferSelected(Buffer *)), this, SLOT(showBuffer(Buffer *))); + QList bufs; + typedef QHash bufhash; + QList foo = buffers.values(); + foreach(bufhash h, foo) { + bufs += h.values(); + } + view->setBuffers(bufs); + view->setAllowedAreas(Qt::RightDockWidgetArea|Qt::LeftDockWidgetArea); + netViews.append(view); + ui.menuViews->addAction(view->toggleViewAction()); } void MainWin::showServerList() { @@ -122,16 +213,172 @@ void MainWin::showServerList() { serverListDlg->show(); } +void MainWin::showSettingsDlg() { + settingsDlg->show(); +} + void MainWin::closeEvent(QCloseEvent *event) { //if (userReallyWantsToQuit()) { + ui.bufferWidget->saveState(); QSettings s; s.beginGroup("Geometry"); s.setValue("MainWinSize", size()); s.setValue("MainWinPos", pos()); + s.setValue("MainWinState", saveState()); s.endGroup(); + s.beginGroup("Buffers"); + s.setValue("CurrentNetwork", currentNetwork); + s.setValue("CurrentBuffer", currentBuffer); + s.endGroup(); + delete systray; event->accept(); //} else { //event->ignore(); //} } + +void MainWin::showBuffer(QString net, QString buf) { + showBuffer(getBuffer(net, buf)); +} + +void MainWin::showBuffer(Buffer *b) { + currentBuffer = b->bufferName(); currentNetwork = b->networkName(); + //emit bufferSelected(b); + //qApp->processEvents(); + ui.bufferWidget->setBuffer(b); + emit bufferSelected(b); +} + +void MainWin::networkConnected(QString net) { + connected[net] = true; + Buffer *b = getBuffer(net, ""); + b->setActive(true); + b->displayMsg(Message::server("", tr("Connected."))); + // TODO buffersUpdated(); +} + +void MainWin::networkDisconnected(QString net) { + //getBuffer(net, "")->setActive(false); + foreach(QString buf, buffers[net].keys()) { + Buffer *b = getBuffer(net, buf); + b->displayMsg(Message::server(buf, tr("Server disconnected."))); + b->setActive(false); + + } + connected[net] = false; +} + +Buffer * MainWin::getBuffer(QString net, QString buf) { + if(!buffers[net].contains(buf)) { + Buffer *b = new Buffer(net, buf); + b->setOwnNick(ownNick[net]); + connect(b, SIGNAL(userInput(QString, QString, QString)), this, SLOT(userInput(QString, QString, QString))); + connect(b, SIGNAL(bufferUpdated(Buffer *)), this, SIGNAL(bufferUpdated(Buffer *))); + connect(b, SIGNAL(bufferDestroyed(Buffer *)), this, SIGNAL(bufferDestroyed(Buffer *))); + buffers[net][buf] = b; + emit bufferUpdated(b); + } + return buffers[net][buf]; +} + +void MainWin::recvNetworkState(QString net, QVariant state) { + connected[net] = true; + setOwnNick(net, state.toMap()["OwnNick"].toString()); + getBuffer(net, "")->setActive(true); + VarMap t = state.toMap()["Topics"].toMap(); + VarMap n = state.toMap()["Nicks"].toMap(); + foreach(QString buf, t.keys()) { + getBuffer(net, buf)->setActive(true); + setTopic(net, buf, t[buf].toString()); + } + foreach(QString nick, n.keys()) { + addNick(net, nick, n[nick].toMap()); + } +} + +void MainWin::recvMessage(QString net, Message msg) { + Buffer *b; + if(msg.flags & Message::PrivMsg) { + // query + if(msg.flags & Message::Self) b = getBuffer(net, msg.target); + else b = getBuffer(net, nickFromMask(msg.sender)); + } else { + b = getBuffer(net, msg.target); + } + b->displayMsg(msg); +} + +void MainWin::recvStatusMsg(QString net, QString msg) { + recvMessage(net, Message::server("", QString("[STATUS] %1").arg(msg))); + +} + +void MainWin::userInput(QString net, QString buf, QString msg) { + emit sendInput(net, buf, msg); +} + +void MainWin::setTopic(QString net, QString buf, QString topic) { + if(!connected[net]) return; + Buffer *b = getBuffer(net, buf); + b->setTopic(topic); + //if(!b->isActive()) { + // b->setActive(true); + // buffersUpdated(); + //} +} + +void MainWin::setNicks(QString net, QString buf, QStringList nicks) { + Q_ASSERT(false); +} + +void MainWin::addNick(QString net, QString nick, VarMap props) { + if(!connected[net]) return; + nicks[net][nick] = props; + VarMap chans = props["Channels"].toMap(); + QStringList c = chans.keys(); + foreach(QString bufname, c) { + getBuffer(net, bufname)->addNick(nick, props); + } +} + +void MainWin::renameNick(QString net, QString oldnick, QString newnick) { + if(!connected[net]) return; + QStringList chans = nicks[net][oldnick]["Channels"].toMap().keys(); + foreach(QString c, chans) { + getBuffer(net, c)->renameNick(oldnick, newnick); + } + nicks[net][newnick] = nicks[net].take(oldnick); +} + +void MainWin::updateNick(QString net, QString nick, VarMap props) { + if(!connected[net]) return; + QStringList oldchans = nicks[net][nick]["Channels"].toMap().keys(); + QStringList newchans = props["Channels"].toMap().keys(); + foreach(QString c, newchans) { + if(oldchans.contains(c)) getBuffer(net, c)->updateNick(nick, props); + else getBuffer(net, c)->addNick(nick, props); + } + foreach(QString c, oldchans) { + if(!newchans.contains(c)) getBuffer(net, c)->removeNick(nick); + } + nicks[net][nick] = props; +} + +void MainWin::removeNick(QString net, QString nick) { + if(!connected[net]) return; + VarMap chans = nicks[net][nick]["Channels"].toMap(); + foreach(QString bufname, chans.keys()) { + getBuffer(net, bufname)->removeNick(nick); + } + nicks[net].remove(nick); +} + +void MainWin::setOwnNick(QString net, QString nick) { + if(!connected[net]) return; + ownNick[net] = nick; + foreach(Buffer *b, buffers[net].values()) { + b->setOwnNick(nick); + } +} +