This replaces #ifdefs mostly by OO stuff, i.e. we now have a class hierarchy in place
for initializing the application. Also, namespace Global:: is gone[1]; most of its functionality
is part of the new Quassel object now which encapsulates common app stuff.
You should clean (rm -rf) your build dir, as these changes are quite invasive.
[1] Some remnants are still there until I get around to redesigning genversion, and actually
fill Quassel::buildInfo() with data.
# Now we have everything, so just glue the right pieces together :)
if(WANT_CORE)
setup_qt4_variables(NETWORK SCRIPT SQL)
- add_executable(quasselcore ${CMAKE_SOURCE_DIR}/src/common/main.cpp
+ add_executable(quasselcore src/common/main.cpp
${RC_SQL} ${RC_I18N} ${WIN32_RC})
set_target_properties(quasselcore PROPERTIES
COMPILE_FLAGS "-DQT_NETWORK_LIB -DQT_SCRIPT_LIB -DQT_SQL_LIB -DBUILD_CORE")
if(WANT_QTCLIENT)
setup_qt4_variables(${LINK_DBUS} GUI NETWORK)
- add_executable(quasselclient WIN32 ${CMAKE_SOURCE_DIR}/src/common/main.cpp
+ add_executable(quasselclient WIN32 src/common/main.cpp
${RC_ICONS} ${RC_QUASSEL_ICONS} ${RC_I18N} ${WIN32_RC})
set_target_properties(quasselclient PROPERTIES
COMPILE_FLAGS "-DQT_GUI_LIB -DQT_NETWORK_LIB -DBUILD_QTUI")
if(WANT_MONO)
setup_qt4_variables(${LINK_DBUS} GUI NETWORK SCRIPT SQL)
- add_executable(quassel WIN32 ${CMAKE_SOURCE_DIR}/src/common/main.cpp
+ add_executable(quassel WIN32 src/common/main.cpp src/qtui/monoapplication.cpp
${RC_ICONS} ${RC_QUASSEL_ICONS} ${RC_SQL} ${RC_I18N} ${WIN32_RC})
set_target_properties(quassel PROPERTIES
COMPILE_FLAGS "-DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_SCRIPT_LIB -DQT_SQL_LIB -DBUILD_MONO")
#include "buffermodel.h"
+#include <QAbstractItemView>
+
#include "client.h"
-#include "global.h"
#include "mappedselectionmodel.h"
#include "networkmodel.h"
-
-#include <QAbstractItemView>
+#include "quassel.h"
BufferModel::BufferModel(NetworkModel *parent)
: QSortFilterProxyModel(parent),
_selectionModelSynchronizer(this)
{
setSourceModel(parent);
- if(Global::parser.isSet("debugbufferswitches")) {
+ if(Quassel::isOptionSet("debugbufferswitches")) {
connect(_selectionModelSynchronizer.selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
this, SLOT(debug_currentChanged(const QModelIndex &, const QModelIndex &)));
}
#include "bufferviewmanager.h"
#include "clientbacklogmanager.h"
#include "clientirclisthelper.h"
-#include "global.h"
#include "identity.h"
#include "ircchannel.h"
#include "ircuser.h"
}
void Client::destroy() {
- //delete instanceptr;
- instanceptr->deleteLater();
+ if(instanceptr) {
+ delete instanceptr->mainUi;
+ instanceptr->deleteLater();
+ instanceptr = 0;
+ }
}
void Client::init(AbstractUi *ui) {
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#include <QStringList>
+
#include "client.h"
#include "clientsettings.h"
-#include "global.h"
-
-#include <QStringList>
+#include "quassel.h"
-ClientSettings::ClientSettings(QString g) : Settings(g, Global::clientApplicationName) {
+ClientSettings::ClientSettings(QString g) : Settings(g, Quassel::buildInfo().clientApplicationName) {
}
ClientSettings::~ClientSettings() {
#endif
#include "client.h"
-#include "global.h"
#include "identity.h"
#include "ircuser.h"
#include "ircchannel.h"
#include "network.h"
#include "networkmodel.h"
+#include "quassel.h"
#include "signalproxy.h"
-
ClientSyncer::ClientSyncer(QObject *parent)
: QObject(parent)
{
***************************************************************************/
#include "treemodel.h"
-#include "global.h"
-#include <QDebug>
#include <QCoreApplication>
+#include <QDebug>
+
+#include "quassel.h"
class RemoveChildLaterEvent : public QEvent {
public:
bool AbstractTreeItem::newChilds(const QList<AbstractTreeItem *> &items) {
if(items.isEmpty())
return false;
-
+
int nextRow = childCount();
int lastRow = nextRow + items.count() - 1;
emit endRemoveChilds();
checkForDeletion();
-
+
return true;
}
void AbstractTreeItem::removeAllChilds() {
const int numChilds = childCount();
-
+
if(numChilds == 0)
return;
-
+
AbstractTreeItem *child;
QList<AbstractTreeItem *>::iterator childIter;
int oldRow = row();
if(oldRow == -1)
return false;
-
+
emit parent()->beginRemoveChilds(oldRow, oldRow);
parent()->_childItems.removeAt(oldRow);
emit parent()->endRemoveChilds();
qWarning() << "AbstractTreeItem::row():" << this << "has no parent AbstractTreeItem as it's parent! parent is" << QObject::parent();
return -1;
}
-
+
int row_ = parent()->_childItems.indexOf(const_cast<AbstractTreeItem *>(this));
if(row_ == -1)
qWarning() << "AbstractTreeItem::row():" << this << "is not in the child list of" << QObject::parent();
childIter++;
}
}
- qDebug() << "==== End Of Childlist ====";
+ qDebug() << "==== End Of Childlist ====";
}
/*****************************************
PropertyMapItem::~PropertyMapItem() {
}
-
+
QVariant PropertyMapItem::data(int column, int role) const {
if(column >= columnCount())
return QVariant();
default:
return QVariant();
}
-
+
}
bool PropertyMapItem::setData(int column, const QVariant &value, int role) {
int PropertyMapItem::columnCount() const {
return _propertyOrder.count();
}
-
+
void PropertyMapItem::appendProperty(const QString &property) {
_propertyOrder << property;
}
rootItem = new SimpleTreeItem(data, 0);
connectItem(rootItem);
- if(Global::parser.isSet("debugmodel")) {
+ if(Quassel::isOptionSet("debugmodel")) {
connect(this, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)),
this, SLOT(debug_rowsAboutToBeInserted(const QModelIndex &, int, int)));
connect(this, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const {
if(!hasIndex(row, column, parent))
return QModelIndex();
-
+
AbstractTreeItem *parentItem;
-
+
if(!parent.isValid())
parentItem = rootItem;
else
parentItem = static_cast<AbstractTreeItem *>(parent.internalPointer());
-
+
AbstractTreeItem *childItem = parentItem->child(row);
if(childItem)
qWarning() << "TreeModel::indexByItem(AbstractTreeItem *item) received NULL-Pointer";
return QModelIndex();
}
-
+
if(item == rootItem)
return QModelIndex();
else
qWarning() << "TreeModel::parent(): has been asked for the rootItems Parent!";
return QModelIndex();
}
-
+
AbstractTreeItem *childItem = static_cast<AbstractTreeItem *>(index.internalPointer());
AbstractTreeItem *parentItem = childItem->parent();
Q_ASSERT(parentItem);
if(parentItem == rootItem)
return QModelIndex();
-
+
return createIndex(parentItem->row(), 0, parentItem);
}
void TreeModel::connectItem(AbstractTreeItem *item) {
connect(item, SIGNAL(dataChanged(int)),
this, SLOT(itemDataChanged(int)));
-
+
connect(item, SIGNAL(beginAppendChilds(int, int)),
this, SLOT(beginAppendChilds(int, int)));
connect(item, SIGNAL(endAppendChilds()),
this, SLOT(endAppendChilds()));
-
+
connect(item, SIGNAL(beginRemoveChilds(int, int)),
this, SLOT(beginRemoveChilds(int, int)));
connect(item, SIGNAL(endRemoveChilds()),
QModelIndex parent = indexByItem(parentItem);
Q_ASSERT(!_aboutToRemoveOrInsert);
-
+
_aboutToRemoveOrInsert = true;
_childStatus = ChildStatus(parent, rowCount(parent), firstRow, lastRow);
beginInsertRows(parent, firstRow, lastRow);
for(int i = firstRow; i <= lastRow; i++) {
disconnect(parentItem->child(i), 0, this, 0);
}
-
+
// consitency checks
QModelIndex parent = indexByItem(parentItem);
Q_ASSERT(firstRow <= lastRow);
buffersyncer.cpp
bufferviewconfig.cpp
bufferviewmanager.cpp
- global.cpp
+ cliparser.cpp
identity.cpp
+ ircchannel.cpp
+ ircuser.cpp
logger.cpp
message.cpp
+ network.cpp
+ quassel.cpp
settings.cpp
signalproxy.cpp
syncableobject.cpp
- util.cpp
- network.cpp
- ircuser.cpp
- ircchannel.cpp
- cliparser.cpp)
+ util.cpp)
set(MOC_HDRS
aliasmanager.h
set(HEADERS ${MOC_HDRS}
bufferinfo.h
- global.h
+ cliparser.h
logger.h
message.h
types.h
- util.h
- cliparser.h)
+ util.h)
qt4_wrap_cpp(MOC ${MOC_HDRS})
#include <QFileInfo>
#include <QDebug>
-CliParser::CliParser(QStringList arguments)
-{
- argsRaw = arguments;
-}
-
void CliParser::addArgument(const QString &longName, const CliParserArg &arg) {
if(argsHash.contains(longName)) qWarning() << "Warning: Multiple definition of argument" << longName;
if(arg.shortName != 0 && !lnameOfShortArg(arg.shortName).isNull())
return escapedValue;
}
-bool CliParser::parse() {
+bool CliParser::parse(const QStringList &args) {
+ argsRaw = args;
QStringList::const_iterator currentArg;
for (currentArg = argsRaw.constBegin(); currentArg != argsRaw.constEnd(); ++currentArg) {
if(currentArg->startsWith("--")) {
void CliParser::usage() {
qWarning() << "Usage:" << QFileInfo(argsRaw.at(0)).completeBaseName() << "[arguments]";
-
+
// get size of longName field
QStringList keys = argsHash.keys();
uint lnameFieldSize = 0;
size += 8;
if(size > lnameFieldSize) lnameFieldSize = size;
}
-
+
QHash<QString, CliParserArg>::const_iterator arg;
for(arg = argsHash.constBegin(); arg != argsHash.constEnd(); ++arg) {
QString output;
QString lnameField;
-
+
if(arg.value().shortName) {
output.append(" -").append(arg.value().shortName).append(",");
}
class CliParser{
public:
inline CliParser() {};
- CliParser(QStringList arguments);
- bool parse();
+ bool parse(const QStringList &arguments);
QString value(const QString &longName);
bool isSet(const QString &longName);
inline void addSwitch(const QString &longName, const char shortName = 0, const QString &help = QString()) {
def(_def),
value(QString()),
boolValue(false) {};
-
+
CliArgType type;
char shortName;
QString help;
QString value;
bool boolValue;
};
-
+
void addArgument(const QString &longName, const CliParserArg &arg);
bool addLongArg(const CliParserArg::CliArgType type, const QString &name, const QString &value = QString());
bool addShortArg(const CliParserArg::CliArgType type, const char shortName, const QString &value = QString());
QString escapedValue(const QString &value);
QString lnameOfShortArg(const char arg);
+
QStringList argsRaw;
QHash<QString, CliParserArg> argsHash;
};
+++ /dev/null
-/***************************************************************************
- * Copyright (C) 2005-08 by the Quassel Project *
- * devel@quassel-irc.org *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) version 3. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-#include <QDateTime>
-#include <QObject>
-#include <QMetaType>
-
-#include "global.h"
-#include "message.h"
-#include "identity.h"
-#include "network.h"
-#include "bufferinfo.h"
-#include "types.h"
-#include "syncableobject.h"
-
-extern void messageHandler(QtMsgType type, const char *msg);
-
-/* not done yet */
-/*
-void Global::initIconMap() {
-// Do not depend on GUI in core!
- QDomDocument doc("IconMap");
- QFile file("images/iconmap.xml");
- if(!file.open(QIODevice::ReadOnly)) {
- qDebug() << "Error opening iconMap file!";
- return;
- } else if(!doc.setContent(&file)) {
- file.close();
- qDebug() << "Error parsing iconMap file!";
- } else {
- file.close();
-
- }
-}
-*/
-
-/**
- * Retrieves an icon determined by its symbolic name. The mapping shall later
- * be performed by a theme manager or something like that.
- * @param symbol Symbol of requested icon
- * @return Pointer to a newly created QIcon
- */
-//
-//QIcon *Global::getIcon(QString /*symbol*/) {
- //if(symbol == "connect"
-
-// return 0;
-//}
-
-//! Register our custom types with Qt's Meta Object System.
-/** This makes them available for QVariant and in signals/slots, among other things.
- *
- */
-void Global::registerMetaTypes() {
- // Complex types
- qRegisterMetaType<QVariant>("QVariant");
- qRegisterMetaType<Message>("Message");
- qRegisterMetaType<BufferInfo>("BufferInfo");
- qRegisterMetaType<NetworkInfo>("NetworkInfo");
- qRegisterMetaType<Identity>("Identity");
- qRegisterMetaType<Network::ConnectionState>("Network::ConnectionState");
-
- qRegisterMetaTypeStreamOperators<QVariant>("QVariant");
- qRegisterMetaTypeStreamOperators<Message>("Message");
- qRegisterMetaTypeStreamOperators<BufferInfo>("BufferInfo");
- qRegisterMetaTypeStreamOperators<NetworkInfo>("NetworkInfo");
- qRegisterMetaTypeStreamOperators<Identity>("Identity");
- qRegisterMetaTypeStreamOperators<qint8>("Network::ConnectionState");
-
- qRegisterMetaType<IdentityId>("IdentityId");
- qRegisterMetaType<BufferId>("BufferId");
- qRegisterMetaType<NetworkId>("NetworkId");
- qRegisterMetaType<UserId>("UserId");
- qRegisterMetaType<AccountId>("AccountId");
- qRegisterMetaType<MsgId>("MsgId");
-
- qRegisterMetaTypeStreamOperators<IdentityId>("IdentityId");
- qRegisterMetaTypeStreamOperators<BufferId>("BufferId");
- qRegisterMetaTypeStreamOperators<NetworkId>("NetworkId");
- qRegisterMetaTypeStreamOperators<UserId>("UserId");
- qRegisterMetaTypeStreamOperators<AccountId>("AccountId");
- qRegisterMetaTypeStreamOperators<MsgId>("MsgId");
-}
-
-//! This includes version.inc and possibly version.gen and sets up our version numbers.
-void Global::setupVersion() {
-
-# include "version.inc"
-# include "version.gen"
-
- if(quasselGeneratedVersion.isEmpty()) {
- if(quasselCommit.isEmpty())
- quasselVersion = QString("v%1 (unknown rev)").arg(quasselBaseVersion);
- else
- quasselVersion = QString("v%1 (dist-%2, %3)").arg(quasselBaseVersion).arg(quasselCommit.left(7))
- .arg(QDateTime::fromTime_t(quasselArchiveDate).toLocalTime().toString("yyyy-MM-dd"));
- } else {
- QStringList parts = quasselGeneratedVersion.split(':');
- quasselVersion = QString("v%1").arg(parts[0]);
- if(parts.count() >= 2) quasselVersion.append(QString(" (%1)").arg(parts[1]));
- }
- quasselBuildDate = __DATE__;
- quasselBuildTime = __TIME__;
-}
-
-// Static variables
-
-QString Global::quasselVersion;
-QString Global::quasselBaseVersion;
-QString Global::quasselGeneratedVersion;
-QString Global::quasselBuildDate;
-QString Global::quasselBuildTime;
-QString Global::quasselCommit;
-uint Global::quasselArchiveDate;
-uint Global::protocolVersion;
-uint Global::clientNeedsProtocol;
-uint Global::coreNeedsProtocol;
-
-Global::RunMode Global::runMode;
-uint Global::defaultPort;
-
-bool Global::DEBUG;
-CliParser Global::parser;
***************************************************************************/
#include "logger.h"
-#include "global.h"
+#include "quassel.h"
#include <QFile>
#include <QTextStream>
void Logger::log() {
LogLevel lvl;
- if (Global::parser.value("loglevel") == "Debug") lvl = DebugLevel;
- else if (Global::parser.value("loglevel") == "Info") lvl = InfoLevel;
- else if (Global::parser.value("loglevel") == "Warning") lvl = WarningLevel;
- else if (Global::parser.value("loglevel") == "Error") lvl = ErrorLevel;
+ if (Quassel::optionValue("loglevel") == "Debug") lvl = DebugLevel;
+ else if (Quassel::optionValue("loglevel") == "Info") lvl = InfoLevel;
+ else if (Quassel::optionValue("loglevel") == "Warning") lvl = WarningLevel;
+ else if (Quassel::optionValue("loglevel") == "Error") lvl = ErrorLevel;
else lvl = InfoLevel;
if(_logLevel < lvl) return;
// if we can't open logfile we log to stdout
QTextStream out(stdout);
QFile file;
- if(!Global::parser.value("logfile").isEmpty()) {
- file.setFileName(Global::parser.value("logfile"));
+ if(!Quassel::optionValue("logfile").isEmpty()) {
+ file.setFileName(Quassel::optionValue("logfile"));
if (file.open(QIODevice::Append | QIODevice::Text)) {
out.setDevice(&file);
_buffer.remove(QChar('\n'));
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
-#include <QDateTime>
-#include <QString>
-#include <QTimer>
-#include <QTranslator>
-#include <QFile>
-
-#include "global.h"
-#include "logger.h"
-#include "network.h"
-#include "settings.h"
-#include "cliparser.h"
-
-#if defined BUILD_CORE
-#include <QDir>
-#include "core.h"
-#include "message.h"
+#include <cstdlib>
+#ifdef BUILD_CORE
+# include "coreapplication.h"
#elif defined BUILD_QTUI
-#include "client.h"
-#include "qtuiapplication.h"
-#include "qtui.h"
-
+# include "qtuiapplication.h"
#elif defined BUILD_MONO
-#include "client.h"
-#include "core.h"
-#include "coresession.h"
-#include "qtuiapplication.h"
-#include "qtui.h"
+# include "monoapplication.h"
#else
#error "Something is wrong - you need to #define a build mode!"
#endif
-
-#include <signal.h>
-
-#if defined(HAVE_EXECINFO) and not defined(Q_OS_MAC)
-#include <execinfo.h>
-#include <dlfcn.h>
-#include <cxxabi.h>
-#endif
-
-//! Signal handler for graceful shutdown.
-void handle_signal(int sig) {
- qWarning("%s", qPrintable(QString("Caught signal %1 - exiting.").arg(sig)));
- QCoreApplication::quit();
-}
-
-#if defined(HAVE_EXECINFO) and not defined(Q_OS_MAC)
-void handle_crash(int sig) {
- Q_UNUSED(sig)
- void* callstack[128];
- int i, frames = backtrace(callstack, 128);
-
- QFile dumpFile(QString("Quassel-Crash-%1").arg(QDateTime::currentDateTime().toString("yyyyMMdd-hhmm.log")));
- dumpFile.open(QIODevice::WriteOnly);
- QTextStream dumpStream(&dumpFile);
-
- for (i = 0; i < frames; ++i) {
- Dl_info info;
- dladdr (callstack[i], &info);
- // as a reference:
- // typedef struct
- // {
- // __const char *dli_fname; /* File name of defining object. */
- // void *dli_fbase; /* Load address of that object. */
- // __const char *dli_sname; /* Name of nearest symbol. */
- // void *dli_saddr; /* Exact value of nearest symbol. */
- // } Dl_info;
-
-#if __LP64__
- int addrSize = 16;
-#else
- int addrSize = 8;
-#endif
-
- QString funcName;
- if(info.dli_sname) {
- char *func = abi::__cxa_demangle(info.dli_sname, 0, 0, 0);
- if(func) {
- funcName = QString(func);
- free(func);
- } else {
- funcName = QString(info.dli_sname);
- }
- } else {
- funcName = QString("0x%1").arg((long)info.dli_saddr, addrSize, QLatin1Char('0'));
- }
-
- // prettificating the filename
- QString fileName("???");
- if(info.dli_fname) {
- fileName = QString(info.dli_fname);
- int slashPos = fileName.lastIndexOf('/');
- if(slashPos != -1)
- fileName = fileName.mid(slashPos + 1);
- if(fileName.count() < 20)
- fileName += QString(20 - fileName.count(), ' ');
- }
-
- QString debugLine = QString("#%1 %2 0x%3 %4").arg(i, 3, 10)
- .arg(fileName)
- .arg((long)(callstack[i]), addrSize, 16, QLatin1Char('0'))
- .arg(funcName);
-
- dumpStream << debugLine << "\n";
- qDebug() << qPrintable(debugLine);
- }
- dumpFile.close();
- exit(27);
-}
-#endif // #if defined(HAVE_EXECINFO) and not defined(Q_OS_MAC)
-
+#include "quassel.h"
int main(int argc, char **argv) {
- // We catch SIGTERM and SIGINT (caused by Ctrl+C) to graceful shutdown Quassel.
- signal(SIGTERM, handle_signal);
- signal(SIGINT, handle_signal);
-
-#if defined(HAVE_EXECINFO) and not defined(Q_OS_MAC)
- signal(SIGABRT, handle_crash);
- signal(SIGBUS, handle_crash);
- signal(SIGSEGV, handle_crash);
-#endif // #if defined(HAVE_EXECINFO) and not defined(Q_OS_MAC)
-
- Global::registerMetaTypes();
- Global::setupVersion();
-
-#if defined BUILD_CORE
- Global::runMode = Global::CoreOnly;
- QCoreApplication app(argc, argv);
-#elif defined BUILD_QTUI
- Global::runMode = Global::ClientOnly;
- QtUiApplication app(argc, argv);
-#else
- Global::runMode = Global::Monolithic;
- QtUiApplication app(argc, argv);
-#endif
- Global::parser = CliParser(QCoreApplication::arguments());
-
-#ifndef BUILD_QTUI
-// put core-only arguments here
- Global::parser.addOption("port",'p',"The port quasselcore will listen at",QString("4242"));
- Global::parser.addSwitch("norestore", 'n', "Don't restore last core's state");
- Global::parser.addOption("logfile",'l',"Path to logfile");
- Global::parser.addOption("loglevel",'L',"Loglevel Debug|Info|Warning|Error","Info");
- Global::parser.addOption("datadir", 0, "Specify the directory holding datafiles like the Sqlite DB and the SSL Cert");
-#endif // BUILD_QTUI
-#ifndef BUILD_CORE
-// put client-only arguments here
- Global::parser.addSwitch("debugbufferswitches",0,"Enables debugging for bufferswitches");
- Global::parser.addSwitch("debugmodel",0,"Enables debugging for models");
-#endif // BUILD_QTCORE
-// put shared client&core arguments here
- Global::parser.addSwitch("debug",'d',"Enable debug output");
- Global::parser.addSwitch("help",'h', "Display this help and exit");
-
- if(!Global::parser.parse() || Global::parser.isSet("help")) {
- Global::parser.usage();
- return 1;
- }
-
- /*
- This is an initial check if logfile is writable since the warning would spam stdout if done
- in current Logger implementation. Can be dropped whenever the logfile is only opened once.
- */
- if(Global::runMode != Global::ClientOnly) {
- QFile logFile;
- if(!Global::parser.value("logfile").isEmpty()) {
- logFile.setFileName(Global::parser.value("logfile"));
- if(!logFile.open(QIODevice::Append | QIODevice::Text))
- qWarning("Warning: Couldn't open logfile '%s' - will log to stdout instead",qPrintable(logFile.fileName()));
- else logFile.close();
- }
- }
-
- qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
-
- // Set up i18n support
- QLocale locale = QLocale::system();
-
- QTranslator qtTranslator(&app);
- qtTranslator.setObjectName("QtTr");
- qtTranslator.load(QString(":i18n/qt_%1").arg(locale.name()));
- app.installTranslator(&qtTranslator);
-
- QTranslator quasselTranslator(&app);
- quasselTranslator.setObjectName("QuasselTr");
- quasselTranslator.load(QString(":i18n/quassel_%1").arg(locale.name()));
- app.installTranslator(&quasselTranslator);
-
- Network::setDefaultCodecForServer("ISO-8859-1");
- Network::setDefaultCodecForEncoding("UTF-8");
- Network::setDefaultCodecForDecoding("ISO-8859-15");
-
- QCoreApplication::setOrganizationDomain("quassel-irc.org");
- QCoreApplication::setApplicationName("Quassel IRC");
- QCoreApplication::setOrganizationName("Quassel Project");
-
-
-#ifndef BUILD_QTUI
- Core::instance(); // create and init the core
-#endif
-
- //Settings::init();
-
-#ifndef BUILD_CORE
- // session resume
- QtUi *gui = new QtUi();
- Client::init(gui);
- // init gui only after the event loop has started
- QTimer::singleShot(0, gui, SLOT(init()));
- //gui->init();
-#endif
-
-#ifndef BUILD_QTUI
- if(!Global::parser.isSet("norestore")) {
- Core::restoreState();
- }
-#endif
-
-#ifndef BUILD_CORE
- app.resumeSessionIfPossible();
-#endif
-
- int exitCode = app.exec();
-
-#ifndef BUILD_QTUI
- Core::saveState();
-#endif
-
-#ifndef BUILD_CORE
- // the mainWin has to be deleted before the Core
- // if not Quassel will crash on exit under certain conditions since the gui
- // still wants to access clientdata
- delete gui;
- Client::destroy();
-#endif
-#ifndef BUILD_QTUI
- Core::destroy();
-#endif
+# ifdef BUILD_CORE
+ CoreApplication app(argc, argv);
+# elif BUILD_QTUI
+ QtUiApplication app(argc, argv);
+# elif BUILD_MONO
+ MonolithicApplication app(argc, argv);
+# endif
- return exitCode;
+ if(!app.init()) return EXIT_FAILURE;
+ return app.exec();
}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2005-08 by the Quassel IRC Team *
+ * devel@quassel-irc.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) version 3. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include "quassel.h"
+
+#include <signal.h>
+
+#include <QCoreApplication>
+#include <QDateTime>
+#include <QObject>
+#include <QMetaType>
+
+#include "message.h"
+#include "identity.h"
+#include "network.h"
+#include "bufferinfo.h"
+#include "types.h"
+#include "syncableobject.h"
+
+#if defined(HAVE_EXECINFO) and not defined(Q_OS_MAC)
+# include <execinfo.h>
+# include <dlfcn.h>
+# include <cxxabi.h>
+#endif
+
+Quassel::BuildInfo Quassel::_buildInfo;
+CliParser *Quassel::_cliParser = 0;
+Quassel::RunMode Quassel::_runMode;
+bool Quassel::_initialized = false;
+bool Quassel::DEBUG = false;
+
+Quassel::Quassel() {
+ // We catch SIGTERM and SIGINT (caused by Ctrl+C) to graceful shutdown Quassel.
+ signal(SIGTERM, handleSignal);
+ signal(SIGINT, handleSignal);
+
+#if defined(HAVE_EXECINFO) and not defined(Q_OS_MAC)
+ signal(SIGABRT, handleSignal);
+ signal(SIGBUS, handleSignal);
+ signal(SIGSEGV, handleSignal);
+#endif // #if defined(HAVE_EXECINFO) and not defined(Q_OS_MAC)
+
+ _cliParser = new CliParser();
+
+ // put shared client&core arguments here
+ cliParser()->addSwitch("debug",'d', tr("Enable debug output"));
+ cliParser()->addSwitch("help",'h', tr("Display this help and exit"));
+}
+
+Quassel::~Quassel() {
+ delete _cliParser;
+}
+
+bool Quassel::init() {
+ if(_initialized) return true; // allow multiple invocations because of MonolithicApplication
+
+ qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
+
+ registerMetaTypes();
+ setupBuildInfo();
+ Global::setupVersion();
+ setupTranslations();
+
+ QCoreApplication::setApplicationName(buildInfo().applicationName);
+ QCoreApplication::setOrganizationName(buildInfo().organizationName);
+ QCoreApplication::setOrganizationDomain(buildInfo().organizationDomain);
+
+ Network::setDefaultCodecForServer("ISO-8859-1");
+ Network::setDefaultCodecForEncoding("UTF-8");
+ Network::setDefaultCodecForDecoding("ISO-8859-15");
+
+ if(!cliParser()->parse(QCoreApplication::arguments()) || isOptionSet("help")) {
+ cliParser()->usage();
+ return false;
+ }
+ DEBUG = isOptionSet("debug");
+ return true;
+}
+
+//! Register our custom types with Qt's Meta Object System.
+/** This makes them available for QVariant and in signals/slots, among other things.
+*
+*/
+void Quassel::registerMetaTypes() {
+ // Complex types
+ qRegisterMetaType<QVariant>("QVariant");
+ qRegisterMetaType<Message>("Message");
+ qRegisterMetaType<BufferInfo>("BufferInfo");
+ qRegisterMetaType<NetworkInfo>("NetworkInfo");
+ qRegisterMetaType<Identity>("Identity");
+ qRegisterMetaType<Network::ConnectionState>("Network::ConnectionState");
+
+ qRegisterMetaTypeStreamOperators<QVariant>("QVariant");
+ qRegisterMetaTypeStreamOperators<Message>("Message");
+ qRegisterMetaTypeStreamOperators<BufferInfo>("BufferInfo");
+ qRegisterMetaTypeStreamOperators<NetworkInfo>("NetworkInfo");
+ qRegisterMetaTypeStreamOperators<Identity>("Identity");
+ qRegisterMetaTypeStreamOperators<qint8>("Network::ConnectionState");
+
+ qRegisterMetaType<IdentityId>("IdentityId");
+ qRegisterMetaType<BufferId>("BufferId");
+ qRegisterMetaType<NetworkId>("NetworkId");
+ qRegisterMetaType<UserId>("UserId");
+ qRegisterMetaType<AccountId>("AccountId");
+ qRegisterMetaType<MsgId>("MsgId");
+
+ qRegisterMetaTypeStreamOperators<IdentityId>("IdentityId");
+ qRegisterMetaTypeStreamOperators<BufferId>("BufferId");
+ qRegisterMetaTypeStreamOperators<NetworkId>("NetworkId");
+ qRegisterMetaTypeStreamOperators<UserId>("UserId");
+ qRegisterMetaTypeStreamOperators<AccountId>("AccountId");
+ qRegisterMetaTypeStreamOperators<MsgId>("MsgId");
+}
+
+void Quassel::setupTranslations() {
+ // Set up i18n support
+ QLocale locale = QLocale::system();
+
+ QTranslator *qtTranslator = new QTranslator(qApp);
+ qtTranslator->setObjectName("QtTr");
+ qtTranslator->load(QString(":i18n/qt_%1").arg(locale.name()));
+ qApp->installTranslator(qtTranslator);
+
+ QTranslator *quasselTranslator = new QTranslator(qApp);
+ quasselTranslator->setObjectName("QuasselTr");
+ quasselTranslator->load(QString(":i18n/quassel_%1").arg(locale.name()));
+ qApp->installTranslator(quasselTranslator);
+}
+
+void Quassel::setupBuildInfo() {
+ _buildInfo.applicationName = "Quassel IRC";
+ _buildInfo.coreApplicationName = "Quassel Core";
+ _buildInfo.clientApplicationName = "Quassel Client";
+ _buildInfo.organizationName = "Quassel Project";
+ _buildInfo.organizationDomain = "quassel-irc.org";
+/*
+# include "version.inc"
+# include "version.gen"
+
+ if(quasselGeneratedVersion.isEmpty()) {
+ if(quasselCommit.isEmpty())
+ quasselVersion = QString("v%1 (unknown rev)").arg(quasselBaseVersion);
+ else
+ quasselVersion = QString("v%1 (dist-%2, %3)").arg(quasselBaseVersion).arg(quasselCommit.left(7))
+ .arg(QDateTime::fromTime_t(quasselArchiveDate).toLocalTime().toString("yyyy-MM-dd"));
+ } else {
+ QStringList parts = quasselGeneratedVersion.split(':');
+ quasselVersion = QString("v%1").arg(parts[0]);
+ if(parts.count() >= 2) quasselVersion.append(QString(" (%1)").arg(parts[1]));
+ }
+ quasselBuildDate = __DATE__;
+ quasselBuildTime = __TIME__;
+ */
+}
+
+//! Signal handler for graceful shutdown.
+void Quassel::handleSignal(int sig) {
+ switch(sig) {
+ case SIGTERM:
+ case SIGINT:
+ qWarning("%s", qPrintable(QString("Caught signal %1 - exiting.").arg(sig)));
+ QCoreApplication::quit();
+ break;
+
+ case SIGABRT:
+ case SIGBUS:
+ case SIGSEGV:
+ handleCrash();
+ break;
+ default:
+ break;
+ }
+}
+
+void Quassel::handleCrash() {
+#if defined(HAVE_EXECINFO) and not defined(Q_OS_MAC)
+ void* callstack[128];
+ int i, frames = backtrace(callstack, 128);
+
+ QFile dumpFile(QString("Quassel-Crash-%1").arg(QDateTime::currentDateTime().toString("yyyyMMdd-hhmm.log")));
+ dumpFile.open(QIODevice::WriteOnly);
+ QTextStream dumpStream(&dumpFile);
+
+ for (i = 0; i < frames; ++i) {
+ Dl_info info;
+ dladdr (callstack[i], &info);
+ // as a reference:
+ // typedef struct
+ // {
+ // __const char *dli_fname; /* File name of defining object. */
+ // void *dli_fbase; /* Load address of that object. */
+ // __const char *dli_sname; /* Name of nearest symbol. */
+ // void *dli_saddr; /* Exact value of nearest symbol. */
+ // } Dl_info;
+
+ #if __LP64__
+ int addrSize = 16;
+ #else
+ int addrSize = 8;
+ #endif
+
+ QString funcName;
+ if(info.dli_sname) {
+ char *func = abi::__cxa_demangle(info.dli_sname, 0, 0, 0);
+ if(func) {
+ funcName = QString(func);
+ free(func);
+ } else {
+ funcName = QString(info.dli_sname);
+ }
+ } else {
+ funcName = QString("0x%1").arg((long)info.dli_saddr, addrSize, QLatin1Char('0'));
+ }
+
+ // prettificating the filename
+ QString fileName("???");
+ if(info.dli_fname) {
+ fileName = QString(info.dli_fname);
+ int slashPos = fileName.lastIndexOf('/');
+ if(slashPos != -1)
+ fileName = fileName.mid(slashPos + 1);
+ if(fileName.count() < 20)
+ fileName += QString(20 - fileName.count(), ' ');
+ }
+
+ QString debugLine = QString("#%1 %2 0x%3 %4").arg(i, 3, 10)
+ .arg(fileName)
+ .arg((long)(callstack[i]), addrSize, 16, QLatin1Char('0'))
+ .arg(funcName);
+
+ dumpStream << debugLine << "\n";
+ qDebug() << qPrintable(debugLine);
+ }
+ dumpFile.close();
+ exit(27);
+#endif // #if defined(HAVE_EXECINFO) and not defined(Q_OS_MAC)
+}
+
+// FIXME temporary
+
+void Global::setupVersion() {
+
+ # include "version.inc"
+ # include "version.gen"
+
+ if(quasselGeneratedVersion.isEmpty()) {
+ if(quasselCommit.isEmpty())
+ quasselVersion = QString("v%1 (unknown rev)").arg(quasselBaseVersion);
+ else
+ quasselVersion = QString("v%1 (dist-%2, %3)").arg(quasselBaseVersion).arg(quasselCommit.left(7))
+ .arg(QDateTime::fromTime_t(quasselArchiveDate).toLocalTime().toString("yyyy-MM-dd"));
+ } else {
+ QStringList parts = quasselGeneratedVersion.split(':');
+ quasselVersion = QString("v%1").arg(parts[0]);
+ if(parts.count() >= 2) quasselVersion.append(QString(" (%1)").arg(parts[1]));
+ }
+ quasselBuildDate = __DATE__;
+ quasselBuildTime = __TIME__;
+}
+
+QString Global::quasselVersion;
+QString Global::quasselBaseVersion;
+QString Global::quasselGeneratedVersion;
+QString Global::quasselBuildDate;
+QString Global::quasselBuildTime;
+QString Global::quasselCommit;
+uint Global::quasselArchiveDate;
+uint Global::protocolVersion;
+uint Global::clientNeedsProtocol;
+uint Global::coreNeedsProtocol;
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2005-08 by the Quassel IRC Team *
+ * devel@quassel-irc.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) version 3. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef QUASSEL_H_
+#define QUASSEL_H_
+
+#include <QCoreApplication>
+#include <QString>
+
+#include "cliparser.h"
+
+class Quassel {
+ Q_DECLARE_TR_FUNCTIONS(Quassel)
+
+ public:
+ enum RunMode {
+ Monolithic,
+ ClientOnly,
+ CoreOnly
+ };
+
+ struct BuildInfo {
+ QString version;
+ QString baseVersion;
+ QString generatedVersion;
+ QString buildDate;
+ QString buildTime;
+ QString commitHash;
+ uint archiveDate;
+ uint protocolVersion;
+ uint clientNeedsProtocol;
+ uint coreNeedsProtocol;
+
+ QString applicationName;
+ QString coreApplicationName;
+ QString clientApplicationName;
+ QString organizationName;
+ QString organizationDomain;
+ };
+
+ ~Quassel();
+
+ static inline const BuildInfo & buildInfo();
+ static inline RunMode runMode();
+
+ static inline CliParser *cliParser();
+ static inline QString optionValue(const QString &option);
+ static inline bool isOptionSet(const QString &option);
+
+ static bool DEBUG;
+
+ protected:
+ Quassel();
+ virtual bool init();
+
+ inline void setRunMode(RunMode mode);
+
+
+ private:
+ void setupBuildInfo();
+ void setupTranslations();
+ void registerMetaTypes();
+
+ static void handleSignal(int signal);
+ static void handleCrash();
+
+ static BuildInfo _buildInfo;
+ static CliParser *_cliParser;
+ static RunMode _runMode;
+ static bool _initialized;
+};
+
+// FIXME temporary
+namespace Global {
+ extern QString quasselVersion;
+ extern QString quasselBaseVersion;
+ extern QString quasselBuildDate;
+ extern QString quasselBuildTime;
+ extern QString quasselCommit;
+ extern uint quasselArchiveDate;
+ extern uint protocolVersion;
+
+ extern uint clientNeedsProtocol; //< Minimum protocol version the client needs
+ extern uint coreNeedsProtocol; //< Minimum protocol version the core needs
+
+ extern QString quasselGeneratedVersion; //< This is possibly set in version.gen
+
+ void setupVersion();
+};
+
+const Quassel::BuildInfo & Quassel::buildInfo() { return _buildInfo; }
+Quassel::RunMode Quassel::runMode() { return _runMode; }
+void Quassel::setRunMode(Quassel::RunMode mode) { _runMode = mode; }
+
+CliParser *Quassel::cliParser() { return _cliParser; }
+QString Quassel::optionValue(const QString &key) { return cliParser()->value(key); }
+bool Quassel::isOptionSet(const QString &key) { return cliParser()->isSet(key); }
+
+#endif
***************************************************************************/
#include "util.h"
-#include "global.h"
#include <QCoreApplication>
#include <QDebug>
#include <QTextCodec>
#include <QTranslator>
+#include "quassel.h"
+
class QMetaMethod;
QString nickFromMask(QString mask) {
min = deleteChar;
else
min = insertChar;
-
+
if(s1[i-1] == s2[j-1]) {
uint inheritChar = matrix[i-1][j-1];
if(inheritChar < min)
QDir quasselDir() {
QString quasselDir;
- if(Global::parser.isSet("datadir")) {
- quasselDir = Global::parser.value("datadir");
+ if(Quassel::isOptionSet("datadir")) {
+ quasselDir = Quassel::optionValue("datadir");
} else {
+ // FIXME use QDesktopServices
#ifdef Q_OS_WIN32
quasselDir = qgetenv("APPDATA") + "/quassel/";
#elif defined Q_WS_MAC
if(locale.language() == QLocale::C)
return;
-
+
qtTranslator->load(QString(":i18n/qt_%1").arg(locale.name()));
quasselTranslator->load(QString(":i18n/quassel_%1").arg(locale.name()));
basichandler.cpp
core.cpp
corealiasmanager.cpp
+ coreapplication.cpp
corebacklogmanager.cpp
corebufferviewconfig.cpp
corebufferviewmanager.cpp
basichandler.h
core.h
corealiasmanager.h
+ coreapplication.h
corebacklogmanager.h
corebufferviewconfig.h
corebufferviewmanager.h
#include "core.h"
#include "coresession.h"
#include "coresettings.h"
+#include "quassel.h"
#include "signalproxy.h"
#include "sqlitestorage.h"
#include "network.h"
connect(&_server, SIGNAL(newConnection()), this, SLOT(incomingConnection()));
connect(&_v6server, SIGNAL(newConnection()), this, SLOT(incomingConnection()));
- if(!startListening(cs.port())) exit(1); // TODO make this less brutal
+ if(!startListening()) exit(1); // TODO make this less brutal
}
Core::~Core() {
/*** Network Management ***/
-bool Core::startListening(uint port) {
+bool Core::startListening() {
bool success = false;
+ uint port = Quassel::optionValue("port").toUInt();
if(_server.listen(QHostAddress::Any, port)) {
quInfo() << "Listening for GUI clients on IPv6 port" << _server.serverPort() << "using protocol version" << Global::protocolVersion;
if(!success) {
quError() << qPrintable(QString("Could not open GUI client port %1: %2").arg(port).arg(_server.errorString()));
}
-
+
return success;
}
connect(socket, SIGNAL(disconnected()), this, SLOT(clientDisconnected()));
connect(socket, SIGNAL(readyRead()), this, SLOT(clientHasData()));
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
-
+
QVariantMap clientInfo;
blocksizes.insert(socket, (quint32)0);
quInfo() << qPrintable(tr("Client connected from")) << qPrintable(socket->peerAddress().toString());
quDebug() << "Using compression for Client:" << qPrintable(socket->peerAddress().toString());
}
#endif
-
+
} else {
// for the rest, we need an initialized connection
if(!clientInfo.contains(socket)) {
// DO NOT CALL ANY METHODS ON socket!!
socket = static_cast<QTcpSocket *>(sender());
-
+
QHash<QTcpSocket *, quint32>::iterator blockSizeIter = blocksizes.begin();
while(blockSizeIter != blocksizes.end()) {
if(blockSizeIter.key() == socket) {
#include "bufferinfo.h"
#include "message.h"
-#include "global.h"
#include "sessionthread.h"
#include "types.h"
* \param data The Value
*/
static void setUserSetting(UserId userId, const QString &settingName, const QVariant &data);
-
+
//! Retrieve a persistent user setting
/**
* \param userId The users Id
*/
static QVariant getUserSetting(UserId userId, const QString &settingName, const QVariant &data = QVariant());
-
+
//! Create a Network in the Storage and store it's Id in the given NetworkInfo
/** \note This method is thredsafe.
*
* \return true if successfull.
*/
static bool createNetwork(UserId user, NetworkInfo &info);
-
+
//! Apply the changes to NetworkInfo info to the storage engine
/** \note This method is thredsafe.
*
* \return true if successfull.
*/
static bool removeNetwork(UserId user, const NetworkId &networkId);
-
+
//! Returns a list of all NetworkInfos for the given UserId user
/** \note This method is thredsafe.
*
*/
static BufferInfo getBufferInfo(UserId user, const BufferId &bufferId);
-
+
//! Store a Message in the backlog.
/** \note This method is threadsafe.
*
/** \note This method is threadsafe.
*/
void syncStorage();
-
+
signals:
//! Sent when a BufferInfo is updated in storage.
void bufferInfoUpdated(UserId user, const BufferInfo &info);
private slots:
- bool startListening(uint port = Global::parser.value("port").toUInt());
+ bool startListening();
void stopListening();
void incomingConnection();
void clientHasData();
Storage *storage;
QTimer _storageSyncTimer;
-#ifdef HAVE_SSL
+#ifdef HAVE_SSL
SslServer _server, _v6server;
#else
QTcpServer _server, _v6server;
-#endif
+#endif
QHash<QTcpSocket *, quint32> blocksizes;
QHash<QTcpSocket *, QVariantMap> clientInfo;
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2005-08 by the Quassel IRC Team *
+ * devel@quassel-irc.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) version 3. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include "coreapplication.h"
+
+#include "core.h"
+
+CoreApplicationInternal::CoreApplicationInternal() {
+ // put core-only arguments here
+ CliParser *parser = Quassel::cliParser();
+ parser->addOption("port",'p', tr("The port quasselcore will listen at"), QString("4242"));
+ parser->addSwitch("norestore", 'n', tr("Don't restore last core's state"));
+ parser->addOption("logfile", 'l', tr("Path to logfile"));
+ parser->addOption("loglevel", 'L', tr("Loglevel Debug|Info|Warning|Error"), "Info");
+ parser->addOption("datadir", 0, tr("Specify the directory holding datafiles like the Sqlite DB and the SSL Cert"));
+}
+
+CoreApplicationInternal::~CoreApplicationInternal() {
+ Core::saveState();
+ Core::destroy();
+}
+
+bool CoreApplicationInternal::init() {
+ /* FIXME
+ This is an initial check if logfile is writable since the warning would spam stdout if done
+ in current Logger implementation. Can be dropped whenever the logfile is only opened once.
+ */
+ QFile logFile;
+ if(!Quassel::optionValue("logfile").isEmpty()) {
+ logFile.setFileName(Quassel::optionValue("logfile"));
+ if(!logFile.open(QIODevice::Append | QIODevice::Text))
+ qWarning("Warning: Couldn't open logfile '%s' - will log to stdout instead",qPrintable(logFile.fileName()));
+ else logFile.close();
+ }
+
+ Core::instance(); // create and init the core
+
+ if(!Quassel::isOptionSet("norestore")) {
+ Core::restoreState();
+ }
+ return true;
+}
+
+/*****************************************************************************/
+
+CoreApplication::CoreApplication(int &argc, char **argv) : QCoreApplication(argc, argv), Quassel() {
+ setRunMode(Quassel::CoreOnly);
+ _internal = new CoreApplicationInternal();
+}
+
+CoreApplication::~CoreApplication() {
+ delete _internal;
+}
+
+bool CoreApplication::init() {
+ if(Quassel::init())
+ return _internal->init();
+ return false;
+}
/***************************************************************************
- * Copyright (C) 2005-08 by the Quassel Project *
+ * Copyright (C) 2005-08 by the Quassel IRC Team *
* devel@quassel-irc.org *
* *
* This program is free software; you can redistribute it and/or modify *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
-// This file needs probably to go away at some point. Not much left anymore.
+#ifndef COREAPPLICATION_H_
+#define COREAPPLICATION_H_
-#ifndef _GLOBAL_H_
-#define _GLOBAL_H_
+#include <QCoreApplication>
-#include "cliparser.h"
+#include "quassel.h"
-#include <QString>
+/// Encapsulates CoreApplication's logic.
+/** This allows it to be reused within MonolithicApplication as well.
+ */
+class CoreApplicationInternal {
+ Q_DECLARE_TR_FUNCTIONS(CoreApplicationInternal)
-// Enable some shortcuts and stuff
-//#define DEVELMODE
+ public:
+ CoreApplicationInternal();
+ ~CoreApplicationInternal();
-/* Some global stuff */
-
-namespace Global {
-
- extern QString quasselVersion;
- extern QString quasselBaseVersion;
- extern QString quasselBuildDate;
- extern QString quasselBuildTime;
- extern QString quasselCommit;
- extern uint quasselArchiveDate;
- extern uint protocolVersion;
-
- extern uint clientNeedsProtocol; //< Minimum protocol version the client needs
- extern uint coreNeedsProtocol; //< Minimum protocol version the core needs
-
- extern QString quasselGeneratedVersion; //< This is possibly set in version.gen
+ bool init();
+};
- // We need different config (QSettings) files for client and gui, since the core cannot work with GUI types
- // Set these here. They're used in ClientSettings and CoreSettings.
- const QString coreApplicationName = "Quassel Core";
- const QString clientApplicationName = "Quassel Client";
+class CoreApplication : public QCoreApplication, public Quassel {
+ Q_OBJECT
+ public:
+ CoreApplication(int &argc, char **argv);
+ ~CoreApplication();
- enum RunMode { Monolithic, ClientOnly, CoreOnly };
- extern RunMode runMode;
- extern unsigned int defaultPort;
+ bool init();
- extern bool DEBUG;
- extern CliParser parser;
- void registerMetaTypes();
- void setupVersion();
+ private:
+ CoreApplicationInternal *_internal;
};
#endif
#include "core.h"
#include "coresession.h"
-#include "global.h"
+#include "quassel.h"
#include "signalproxy.h"
CoreCoreInfo::CoreCoreInfo(CoreSession *parent)
#include "coresettings.h"
-#include <QStringList>
+#include "quassel.h"
-CoreSettings::CoreSettings(const QString group) : Settings(group, Global::coreApplicationName) {
+CoreSettings::CoreSettings(const QString group) : Settings(group, Quassel::buildInfo().coreApplicationName) {
}
CoreSettings::~CoreSettings() {
return localValue("DatabaseSettings");
}
-void CoreSettings::setPort(const uint &port) {
- setLocalValue("Port", port);
-}
-
-uint CoreSettings::port(const uint &def) {
- return localValue("Port", def).toUInt();
-}
-
void CoreSettings::setCoreState(const QVariant &data) {
setLocalValue("CoreState", data);
}
#ifndef _CORESETTINGS_H_
#define _CORESETTINGS_H_
-#include "global.h"
#include "settings.h"
class CoreSettings : public Settings {
QVariant oldDbSettings(); // FIXME remove
- void setPort(const uint &port);
- uint port(const uint &def = Global::parser.value("port").toUInt());
-
void setCoreState(const QVariant &data);
QVariant coreState(const QVariant &def = QVariant());
***************************************************************************/
#include "ctcphandler.h"
-#include "global.h"
-#include "util.h"
#include "message.h"
#include "network.h"
+#include "quassel.h"
+#include "util.h"
CtcpHandler::CtcpHandler(NetworkConnection *parent)
: BasicHandler(parent),
QByteArray dequotedMessage;
QByteArray messagepart;
QHash<QByteArray, QByteArray>::iterator ctcpquote;
-
+
// copy dequote Message
for(int i = 0; i < message.size(); i++) {
messagepart = message.mid(i,1);
void CtcpHandler::parse(Message::Type messageType, const QString &prefix, const QString &target, const QByteArray &message) {
QByteArray ctcp;
-
+
//lowlevel message dequote
QByteArray dequotedMessage = dequote(message);
CtcpType ctcptype = messageType == Message::Notice
? CtcpReply
: CtcpQuery;
-
+
Message::Flags flags = (messageType == Message::Notice && !network()->isChannelName(target))
? Message::Redirected
: Message::None;
handle(ctcpcmd, Q_ARG(CtcpType, ctcptype), Q_ARG(QString, prefix), Q_ARG(QString, target), Q_ARG(QString, ctcpparam));
}
-
+
if(!dequotedMessage.isEmpty())
displayMsg(messageType, target, userDecode(target, dequotedMessage), prefix, flags);
}
mainwin.cpp
msgprocessorstatuswidget.cpp
nicklistwidget.cpp
- qtuiapplication.cpp
qtui.cpp
+ qtuiapplication.cpp
qtuimessageprocessor.cpp
qtuisettings.cpp
qtuistyle.cpp
***************************************************************************/
#include "aboutdlg.h"
-#include "global.h"
+#include "quassel.h"
AboutDlg::AboutDlg(QWidget *parent) : QDialog(parent) {
ui.setupUi(this);
#include "settings.h"
#include "client.h"
-#include "global.h"
-
#include <QLayout>
BufferWidget::BufferWidget(QWidget *parent)
_chatViewSearchController->setSearchSenders(ui.searchBar->searchSendersBox()->isChecked());
_chatViewSearchController->setSearchMsgs(ui.searchBar->searchMsgsBox()->isChecked());
_chatViewSearchController->setSearchOnlyRegularMsgs(ui.searchBar->searchOnlyRegularMsgsBox()->isChecked());
-
+
connect(ui.searchBar->searchEditLine(), SIGNAL(textChanged(const QString &)),
_chatViewSearchController, SLOT(setSearchString(const QString &)));
connect(ui.searchBar->caseSensitiveBox(), SIGNAL(toggled(bool)),
#include "settingspages/networkssettingspage.h"
#include "settingspages/notificationssettingspage.h"
-#include "global.h"
#include "qtuistyle.h"
MainWin::MainWin(QWidget *parent)
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2005-08 by the Quassel IRC Team *
+ * devel@quassel-irc.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) version 3. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include "monoapplication.h"
+#include "coreapplication.h"
+#include "client.h"
+#include "qtui.h"
+
+MonolithicApplication::MonolithicApplication(int &argc, char **argv) : QtUiApplication(argc, argv) {
+ setRunMode(Monolithic);
+ _internal = new CoreApplicationInternal();
+
+}
+
+bool MonolithicApplication::init() {
+ if(Quassel::init() && _internal->init()) {
+ return QtUiApplication::init();
+ }
+ return false;
+}
+
+MonolithicApplication::~MonolithicApplication() {
+ // Client needs to be destroyed first
+ Client::destroy();
+
+ delete _internal;
+}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2005-08 by the Quassel IRC Team *
+ * devel@quassel-irc.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) version 3. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef MONOAPPLICATION_H_
+#define MONOAPPLICATION_H_
+
+#include "qtuiapplication.h"
+
+class CoreApplicationInternal;
+
+class MonolithicApplication : public QtUiApplication {
+
+ public:
+ MonolithicApplication(int &, char **);
+ ~MonolithicApplication();
+
+ bool init();
+
+ private:
+ CoreApplicationInternal *_internal;
+};
+
+#endif
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#include "qtuiapplication.h"
+
#include <QStringList>
-#include "qtuiapplication.h"
-#include "sessionsettings.h"
#include "client.h"
+#include "cliparser.h"
+#include "qtui.h"
+#include "sessionsettings.h"
-QtUiApplication::QtUiApplication(int &argc, char **argv) : QApplication(argc, argv) {
+QtUiApplication::QtUiApplication(int &argc, char **argv) : QApplication(argc, argv), Quassel() {
+ setRunMode(Quassel::ClientOnly);
+ // put client-only arguments here
+ CliParser *parser = Quassel::cliParser();
+ parser->addSwitch("debugbufferswitches",0,"Enables debugging for bufferswitches");
+ parser->addSwitch("debugmodel",0,"Enables debugging for models");
+}
+
+bool QtUiApplication::init() {
+ if(Quassel::init()) {
+ // session resume
+ QtUi *gui = new QtUi();
+ Client::init(gui);
+ // init gui only after the event loop has started
+ // QTimer::singleShot(0, gui, SLOT(init()));
+ gui->init();
+ resumeSessionIfPossible();
+ return true;
+ }
+ return false;
+}
+
+QtUiApplication::~QtUiApplication() {
+ Client::destroy();
}
void QtUiApplication::saveState(QSessionManager & manager) {
emit saveStateToSessionSettings(s);
}
-QtUiApplication::~ QtUiApplication() {
-}
-
void QtUiApplication::resumeSessionIfPossible() {
// load all sessions
if(isSessionRestored()) {
s.cleanup();
}
}
-
#include <QApplication>
#include <QSessionManager>
+#include "quassel.h"
#include "sessionsettings.h"
-#include "qtui.h"
-class QtUiApplication : public QApplication {
+class QtUi;
+
+class QtUiApplication : public QApplication, public Quassel {
Q_OBJECT
+
public:
- QtUiApplication(int &, char**);
+ QtUiApplication(int &, char **);
~QtUiApplication();
+ virtual bool init();
+
void resumeSessionIfPossible();
virtual void saveState(QSessionManager & manager);
+
signals:
void saveStateToSession(const QString &sessionId);
- void saveStateToSessionSettings(SessionSettings &s);
+ void saveStateToSessionSettings(SessionSettings &s); // FIXME refs in signals won't probably work
void resumeFromSession(const QString sessionId);
void resumeFromSessionSettings(SessionSettings &s);
-
+
};
#endif
#include "networkssettingspage.h"
#include "client.h"
-#include "global.h"
#include "identity.h"
#include "network.h"
#include "uisettings.h"
-#include "global.h"
-
#include <QAction>
#include <QFlags>
#include <QHeaderView>
void BufferView::setModel(QAbstractItemModel *model) {
delete selectionModel();
-
+
QTreeView::setModel(model);
init();
// remove old Actions
connect(showSection, SIGNAL(toggled(bool)), this, SLOT(toggleHeader(bool)));
header()->addAction(showSection);
}
-
+
}
void BufferView::setFilteredModel(QAbstractItemModel *model_, BufferViewConfig *config) {
if(QTreeView::selectionModel())
disconnect(selectionModel, SIGNAL(currentChanged(QModelIndex, QModelIndex)),
model(), SIGNAL(checkPreviousCurrentForRemoval(QModelIndex, QModelIndex)));
-
+
QTreeView::setSelectionModel(selectionModel);
BufferViewFilter *filter = qobject_cast<BufferViewFilter *>(model());
if(filter) {
void BufferView::setConfig(BufferViewConfig *config) {
if(_config == config)
return;
-
+
if(_config) {
disconnect(_config, 0, this, 0);
}
return;
BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>();
-
+
Client::userInput(bufferInfo, QString("/JOIN %1").arg(bufferInfo.bufferName()));
}
continue;
removedRows << bufferId;
-
+
if(permanently)
config()->requestRemoveBufferPermanently(bufferId);
else
// ensure that newly inserted network nodes are expanded per default
if(parent.data(NetworkModel::ItemTypeRole) != NetworkModel::NetworkItemType)
return;
-
+
if(model()->rowCount(parent) == 1 && parent.data(NetworkModel::ItemActiveRole) == true) {
// without updating the parent the expand will have no effect... Qt Bug?
update(parent);
void BufferView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) {
QTreeView::dataChanged(topLeft, bottomRight);
-
+
// determine how many items have been changed and if any of them is a networkitem
// which just swichted from active to inactive or vice versa
if(topLeft.data(NetworkModel::ItemTypeRole) != NetworkModel::NetworkItemType)
connectionStateIcon = QIcon(":/22x22/actions/gear");
}
}
-
+
QMenu contextMenu(this);
NetworkModel::itemType itemType = static_cast<NetworkModel::itemType>(index.data(NetworkModel::ItemTypeRole).toInt());
-
+
switch(itemType) {
case NetworkModel::NetworkItemType:
showChannelList.setData(index.data(NetworkModel::NetworkIdRole));
default:
return;
}
-
+
if(contextMenu.actions().isEmpty())
return;
QAction *result = contextMenu.exec(QCursor::pos());
-
+
// Handle Result
if(network && result == &_connectNetAction) {
network->requestConnect();
Client::instance()->userInput(bufferInfo, QString("/PART"));
return;
}
-
+
if(result == &_hideBufferTemporarilyAction) {
removeSelectedBuffers();
return;
}
selectionModel()->setCurrentIndex( resultingIndex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
selectionModel()->select( resultingIndex, QItemSelectionModel::ClearAndSelect );
-
+
}
QSize BufferView::sizeHint() const {
return QTreeView::sizeHint();
-
+
if(!model())
return QTreeView::sizeHint();
***************************************************************************/
#include <QApplication>
+#include "quassel.h"
#include "uistyle.h"
#include "uisettings.h"
#include "util.h"
// FIXME remove with migration code
#include <QSettings>
-#include "global.h"
UiStyle::UiStyle(const QString &settingsKey) : _settingsKey(settingsKey) {
// register FormatList if that hasn't happened yet
// FIXME remove migration at some point
// We remove old settings if we find them, since they conflict
#ifdef Q_WS_MAC
- QSettings mys(QCoreApplication::organizationDomain(), Global::clientApplicationName);
+ QSettings mys(QCoreApplication::organizationDomain(), Quassel::buildInfo().clientApplicationName);
#else
- QSettings mys(QCoreApplication::organizationName(), Global::clientApplicationName);
+ QSettings mys(QCoreApplication::organizationName(), Quassel::buildInfo().clientApplicationName);
#endif
mys.beginGroup("QtUi");
if(mys.childGroups().contains("Colors")) {