added first brand of chat/msg link creator/editor. Not functional yet

git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-GenericTunneling@6304 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2013-04-13 13:12:13 +00:00
parent d0703df7e3
commit 9e8b9b6c05
8 changed files with 494 additions and 57 deletions

View File

@ -0,0 +1,66 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2008 Robert Fernie
*
* This program is free software; you can redistribute it and/or
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#include <iostream>
#include "CreateMsgLinkDialog.h"
#include <gui/common/FriendSelectionWidget.h>
CreateMsgLinkDialog::CreateMsgLinkDialog(QWidget *parent)
:QDialog(NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint)
{
/* Invoke the Qt Designer generated object setup routine */
setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true);
_info_GB->layout()->addWidget( _gpg_selection = new FriendSelectionWidget(this) ) ;
QObject::connect(_link_type_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(update())) ;
QObject::connect(_create_link_PB,SIGNAL(clicked()),this,SLOT(create())) ;
update() ;
}
void CreateMsgLinkDialog::update()
{
if(_link_type_CB->currentIndex() == 0)
{
QString s ;
s += "A private chat invite allows a specific peer to contact you\nusing encrypted private chat. You need to select a destination peer from your PGP keyring\nbefore creating the link. The link contains the encryption code and your PGP signature, so that the peer can authenticate you." ;
_info_LB->setText(s) ;
_gpg_selection->setHidden(false) ;
}
else
{
QString s ;
s += "A private chat invite allows a specific peer to contact you\nusing encrypted private chat. You need to select a destination peer from your PGP keyring\nbefore creating the link. The link contains the encryption code and your PGP signature, so that the peer can authenticate you." ;
_info_LB->setText(s) ;
_gpg_selection->setHidden(true) ;
}
}
void CreateMsgLinkDialog::createLink()
{
std::cerr << "Creating link!" << std::endl;
}

View File

@ -0,0 +1,49 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2008 Robert Fernie
*
* 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) any later version.
*
* 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., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
******************************************************************/
#pragma once
#include "ui_CreateMsgLinkDialog.h"
class FriendSelectionWidget ;
class CreateMsgLinkDialog : public QDialog, public Ui::CreateMsgLinkDialog
{
Q_OBJECT
public:
CreateMsgLinkDialog(QWidget *parent = NULL);
virtual ~CreateMsgLinkDialog() {}
private slots:
/* actions to take.... */
void createLink();
void update() ;
private:
/** Qt Designer generated object */
FriendSelectionWidget *_gpg_selection ;
};

View File

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CreateMsgLinkDialog</class>
<widget class="QDialog" name="CreateMsgLinkDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>497</width>
<height>174</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Invite type:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="_link_type_CB">
<item>
<property name="text">
<string>Private chat</string>
</property>
</item>
<item>
<property name="text">
<string>Public message</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Valid until:</string>
</property>
</widget>
</item>
<item>
<widget class="QDateTimeEdit" name="dateTimeEdit"/>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="_info_GB">
<property name="title">
<string>Information</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="_info_LB">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="_create_link_PB">
<property name="text">
<string>Create!</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Link:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>CreateMsgLinkDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>CreateMsgLinkDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -55,7 +55,9 @@
#define HOST_MESSAGE "message" #define HOST_MESSAGE "message"
#define HOST_SEARCH "search" #define HOST_SEARCH "search"
#define HOST_CERTIFICATE "certificate" #define HOST_CERTIFICATE "certificate"
#define HOST_REGEXP "file|person|forum|channel|search|message|certificate" #define HOST_PUBLIC_MSG "public_msg"
#define HOST_PRIVATE_CHAT "private_chat"
#define HOST_REGEXP "file|person|forum|channel|search|message|certificate|private_chat|public_msg"
#define FILE_NAME "name" #define FILE_NAME "name"
#define FILE_SIZE "size" #define FILE_SIZE "size"
@ -87,6 +89,13 @@
#define CERTIFICATE_EXT_IPPORT "extipp" #define CERTIFICATE_EXT_IPPORT "extipp"
#define CERTIFICATE_LOC_IPPORT "locipp" #define CERTIFICATE_LOC_IPPORT "locipp"
#define PRIVATE_CHAT_TIME_STAMP "time_stamp"
#define PRIVATE_CHAT_STRING "encrypted_data"
#define PUBLIC_MSG_TIME_STAMP "time_stamp"
#define PUBLIC_MSG_SRC_PGP_ID "gpgid"
#define PUBLIC_MSG_HASH "hash"
RetroShareLink::RetroShareLink(const QUrl& url) RetroShareLink::RetroShareLink(const QUrl& url)
{ {
fromUrl(url); fromUrl(url);
@ -181,6 +190,28 @@ void RetroShareLink::fromUrl(const QUrl& url)
} }
} }
if(url.host() == HOST_PRIVATE_CHAT)
{
bool ok ;
_type = TYPE_PRIVATE_CHAT ;
_time_stamp = url.queryItemValue(PRIVATE_CHAT_TIME_STAMP).toUInt(&ok) ;
_encrypted_chat_info = url.queryItemValue(PRIVATE_CHAT_STRING) ;
check() ;
return;
}
if(url.host() == HOST_PUBLIC_MSG)
{
bool ok ;
_type = TYPE_PUBLIC_MSG ;
_hash = url.queryItemValue(PUBLIC_MSG_HASH) ;
_time_stamp = url.queryItemValue(PUBLIC_MSG_TIME_STAMP).toUInt(&ok) ;
_GPGid = url.queryItemValue(PUBLIC_MSG_SRC_PGP_ID) ;
check() ;
return;
}
if (url.host() == HOST_EXTRAFILE) { if (url.host() == HOST_EXTRAFILE) {
bool ok ; bool ok ;
@ -299,6 +330,29 @@ bool RetroShareLink::createFile(const QString& name, uint64_t size, const QStrin
return valid(); return valid();
} }
bool RetroShareLink::createPrivateChatInvite(time_t time_stamp,const QString& gpg_id,const QString& encrypted_chat_info)
{
clear() ;
_time_stamp = time_stamp ;
_encrypted_chat_info = encrypted_chat_info ;
check() ;
return valid() ;
}
bool RetroShareLink::createPublicMsgInvite(time_t time_stamp,const QString& pgp_id,const QString& hash)
{
clear() ;
_time_stamp = time_stamp ;
_hash = hash ;
_GPGid = pgp_id ;
check() ;
return valid() ;
}
bool RetroShareLink::createPerson(const std::string& id) bool RetroShareLink::createPerson(const std::string& id)
{ {
clear(); clear();
@ -491,78 +545,92 @@ void RetroShareLink::clear()
_hash = "" ; _hash = "" ;
_size = 0 ; _size = 0 ;
_name = "" ; _name = "" ;
_GPGid = "" ;
_time_stamp = 0 ;
_encrypted_chat_info = "" ;
} }
void RetroShareLink::check() void RetroShareLink::check()
{ {
_valid = true; _valid = true;
switch (_type) { switch (_type)
case TYPE_UNKNOWN: {
_valid = false; case TYPE_UNKNOWN:
break;
case TYPE_EXTRAFILE:
if(!checkSSLId(_SSLid))
_valid = false; // no break! We also test file stuff below.
case TYPE_FILE:
if(_size > (((uint64_t)1)<<40)) // 1TB. Who has such large files?
_valid = false; _valid = false;
break;
case TYPE_EXTRAFILE:
if(!checkSSLId(_SSLid))
_valid = false; // no break! We also test file stuff below.
case TYPE_FILE:
if(_size > (((uint64_t)1)<<40)) // 1TB. Who has such large files?
_valid = false;
if(!checkName(_name)) if(!checkName(_name))
_valid = false; _valid = false;
if(!checkHash(_hash)) if(!checkHash(_hash))
_valid = false; _valid = false;
break; break;
case TYPE_PERSON:
if(_size != 0)
_valid = false;
if(_name.isEmpty()) case TYPE_PRIVATE_CHAT:
_valid = false; if(!checkRadix64(_encrypted_chat_info)) _valid = false ;
break ;
if(_hash.isEmpty()) case TYPE_PUBLIC_MSG:
_valid = false; if(!checkHash(_hash)) _valid = false ;
break; if(!checkPGPId(_GPGid)) _valid = false ;
case TYPE_FORUM: break ;
if(_size != 0)
_valid = false;
if(_name.isEmpty()) case TYPE_PERSON:
_valid = false; if(_size != 0)
_valid = false;
if(_hash.isEmpty()) if(_name.isEmpty())
_valid = false; _valid = false;
break;
case TYPE_CHANNEL:
if(_size != 0)
_valid = false;
if(_name.isEmpty()) if(_hash.isEmpty())
_valid = false; _valid = false;
break;
case TYPE_FORUM:
if(_size != 0)
_valid = false;
if(_hash.isEmpty()) if(_name.isEmpty())
_valid = false; _valid = false;
break;
case TYPE_SEARCH:
if(_size != 0)
_valid = false;
if(_name.isEmpty()) if(_hash.isEmpty())
_valid = false; _valid = false;
break;
case TYPE_CHANNEL:
if(_size != 0)
_valid = false;
if(!_hash.isEmpty()) if(_name.isEmpty())
_valid = false; _valid = false;
break;
case TYPE_MESSAGE:
if(_size != 0)
_valid = false;
if(_hash.isEmpty()) if(_hash.isEmpty())
_valid = false; _valid = false;
break; break;
case TYPE_CERTIFICATE: case TYPE_SEARCH:
break; if(_size != 0)
_valid = false;
if(_name.isEmpty())
_valid = false;
if(!_hash.isEmpty())
_valid = false;
break;
case TYPE_MESSAGE:
if(_size != 0)
_valid = false;
if(_hash.isEmpty())
_valid = false;
break;
case TYPE_CERTIFICATE:
break;
} }
if (!_valid) { if (!_valid) {
@ -579,6 +647,22 @@ QString RetroShareLink::title() const
switch (_type) { switch (_type) {
case TYPE_UNKNOWN: case TYPE_UNKNOWN:
break; break;
case TYPE_PUBLIC_MSG:
{
RsPeerDetails detail;
rsPeers->getPeerDetails(_GPGid.toStdString(), detail) ;
return QString("Click to send a private message to %1 (%2).").arg(QString::fromStdString(detail.name)).arg(_GPGid) ;
}
case TYPE_PRIVATE_CHAT:
{
RsPeerDetails detail;
rsPeers->getPeerDetails(_GPGid.toStdString(), detail) ;
if (_GPGid.toStdString() == rsPeers->getGPGOwnId())
return QString("Click to open a private chat canal to %1 (%2).").arg(QString::fromStdString(detail.name)).arg(_GPGid) ;
else
return QString("This is a private chat invite for %1 (%2). You can't use it.").arg(QString::fromStdString(detail.name)).arg(_GPGid) ;
}
case TYPE_EXTRAFILE: case TYPE_EXTRAFILE:
return QString("%1 (%2, Extra - Source included)").arg(hash()).arg(misc::friendlyUnit(size())); return QString("%1 (%2, Extra - Source included)").arg(hash()).arg(misc::friendlyUnit(size()));
case TYPE_FILE: case TYPE_FILE:
@ -619,6 +703,28 @@ QString RetroShareLink::toString() const
return url.toString(); return url.toString();
} }
case TYPE_PRIVATE_CHAT:
{
QUrl url;
url.setScheme(RSLINK_SCHEME) ;
url.setHost(HOST_PRIVATE_CHAT) ;
url.addQueryItem(PRIVATE_CHAT_TIME_STAMP,QString::number(_time_stamp)) ;
url.addQueryItem(PRIVATE_CHAT_STRING,_encrypted_chat_info) ;
return url.toString() ;
}
case TYPE_PUBLIC_MSG:
{
QUrl url;
url.setScheme(RSLINK_SCHEME) ;
url.setHost(HOST_PUBLIC_MSG) ;
url.addQueryItem(PUBLIC_MSG_TIME_STAMP,QString::number(_time_stamp)) ;
url.addQueryItem(PUBLIC_MSG_HASH,_hash) ;
url.addQueryItem(PUBLIC_MSG_SRC_PGP_ID,_GPGid) ;
return url.toString() ;
}
case TYPE_EXTRAFILE: case TYPE_EXTRAFILE:
{ {
QUrl url; QUrl url;
@ -814,6 +920,37 @@ bool RetroShareLink::checkSSLId(const QString& ssl_id)
return true ; return true ;
} }
bool RetroShareLink::checkPGPId(const QString& pgp_id)
{
if(pgp_id.length() != 16)
return false ;
QByteArray qb(pgp_id.toAscii()) ;
for(int i=0;i<qb.length();++i)
{
unsigned char b(qb[i]) ;
if(!((b>47 && b<58) || (b>64 && b<71)))
return false ;
}
return true ;
}
bool RetroShareLink::checkRadix64(const QString& s)
{
QByteArray qb(s.toAscii()) ;
for(int i=0;i<qb.length();++i)
{
unsigned char b(qb[i]) ;
if(!( (b > 46 && b < 58) || (b > 64 && b < 91) || (b > 96 && b < 123) || b=='+'))
return false;
}
return true ;
}
bool RetroShareLink::checkHash(const QString& hash) bool RetroShareLink::checkHash(const QString& hash)
{ {
if(hash.length() != 40) if(hash.length() != 40)
@ -1028,6 +1165,22 @@ static void processList(const QStringList &list, const QString &textSingular, co
} }
break ; break ;
case TYPE_PUBLIC_MSG:
{
std::cerr << "Opening a public msg window " << std::endl;
std::cerr << " time_stamp = " << link._time_stamp << std::endl;
std::cerr << " hash = " << link._hash.toStdString() << std::endl;
std::cerr << " PGP Id = " << link._GPGid.toStdString() << std::endl;
}
break ;
case TYPE_PRIVATE_CHAT:
{
std::cerr << "Opening a private chat window " << std::endl;
std::cerr << " time_stamp = " << link._time_stamp << std::endl;
std::cerr << " enc-string = " << link._encrypted_chat_info.toStdString() << std::endl;
}
break ;
case TYPE_FILE: case TYPE_FILE:
case TYPE_EXTRAFILE: case TYPE_EXTRAFILE:
{ {

View File

@ -52,7 +52,18 @@
class RetroShareLink class RetroShareLink
{ {
public: public:
enum enumType { TYPE_UNKNOWN, TYPE_FILE, TYPE_PERSON, TYPE_FORUM, TYPE_CHANNEL, TYPE_SEARCH, TYPE_MESSAGE, TYPE_CERTIFICATE,TYPE_EXTRAFILE }; enum enumType { TYPE_UNKNOWN = 0x00,
TYPE_FILE = 0x01,
TYPE_PERSON = 0x02,
TYPE_FORUM = 0x03,
TYPE_CHANNEL = 0x04,
TYPE_SEARCH = 0x05,
TYPE_MESSAGE = 0x06,
TYPE_CERTIFICATE = 0x07,
TYPE_EXTRAFILE = 0x08,
TYPE_PRIVATE_CHAT = 0x09,
TYPE_PUBLIC_MSG = 0x0a
};
public: public:
RetroShareLink(); RetroShareLink();
@ -67,6 +78,8 @@ class RetroShareLink
bool createSearch(const QString& keywords); bool createSearch(const QString& keywords);
bool createMessage(const std::string& peerId, const QString& subject); bool createMessage(const std::string& peerId, const QString& subject);
bool createCertificate(const std::string& ssl_or_gpg_id) ; bool createCertificate(const std::string& ssl_or_gpg_id) ;
bool createPrivateChatInvite(time_t time_stamp,const QString& gpg_id,const QString& encrypted_chat_info) ;
bool createPublicMsgInvite(time_t time_stamp,const QString& pgp_id,const QString& hash) ;
bool createUnknwonSslCertificate(const std::string& sslId, const std::string& gpgId = "") ; bool createUnknwonSslCertificate(const std::string& sslId, const std::string& gpgId = "") ;
enumType type() const {return _type; } enumType type() const {return _type; }
@ -83,6 +96,8 @@ class RetroShareLink
const QString& localIPAndPort() const { return _loc_ip_port ; } const QString& localIPAndPort() const { return _loc_ip_port ; }
const QString& externalIPAndPort() const { return _ext_ip_port ; } const QString& externalIPAndPort() const { return _ext_ip_port ; }
const QString& location() const { return _location ; } const QString& location() const { return _location ; }
const time_t timeStamp() const { return _time_stamp ; }
const QString& encryptedPrivateChatInfo() const { return _encrypted_chat_info ; }
QString title() const; QString title() const;
unsigned int subType() const { return _subType; } unsigned int subType() const { return _subType; }
@ -118,8 +133,10 @@ class RetroShareLink
void clear(); void clear();
void check(); void check();
static bool checkHash(const QString& hash); static bool checkHash(const QString& hash);
static bool checkRadix64(const QString& s);
static bool checkName(const QString& name); static bool checkName(const QString& name);
static bool checkSSLId(const QString& name); static bool checkSSLId(const QString& name);
static bool checkPGPId(const QString& name);
bool _valid; bool _valid;
enumType _type; enumType _type;
@ -135,6 +152,9 @@ class RetroShareLink
QString _location ; // location QString _location ; // location
QString _ext_ip_port ; QString _ext_ip_port ;
QString _loc_ip_port ; QString _loc_ip_port ;
QString _encrypted_chat_info ; // encrypted data string for the recipient of a chat invite
time_t _time_stamp ; // time stamp at which the link will expire.
unsigned int _subType; // for general use as sub type for _type (RSLINK_SUBTYPE_...) unsigned int _subType; // for general use as sub type for _type (RSLINK_SUBTYPE_...)
}; };

View File

@ -36,6 +36,7 @@
#include "ui_ChatWidget.h" #include "ui_ChatWidget.h"
#include "gui/notifyqt.h" #include "gui/notifyqt.h"
#include "gui/RetroShareLink.h" #include "gui/RetroShareLink.h"
#include "gui/CreateMsgLinkDialog.h"
#include "gui/settings/rsharesettings.h" #include "gui/settings/rsharesettings.h"
#include "gui/settings/RsharePeerSettings.h" #include "gui/settings/RsharePeerSettings.h"
#include "gui/im_history/ImHistoryBrowser.h" #include "gui/im_history/ImHistoryBrowser.h"
@ -549,11 +550,20 @@ void ChatWidget::contextMenu(QPoint point)
QAction *action = contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Link"), this, SLOT(pasteLink())); QAction *action = contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Link"), this, SLOT(pasteLink()));
action->setDisabled(RSLinkClipboard::empty()); action->setDisabled(RSLinkClipboard::empty());
contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste my certificate link"), this, SLOT(pasteOwnCertificateLink())); contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste my certificate link"), this, SLOT(pasteOwnCertificateLink()));
contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste/Create private chat or Message link..."), this, SLOT(pasteCreateMsgLink()));
contextMnu->exec(QCursor::pos()); contextMnu->exec(QCursor::pos());
delete(contextMnu); delete(contextMnu);
} }
void ChatWidget::pasteCreateMsgLink()
{
CreateMsgLinkDialog dialog ;
dialog.exec() ;
ui->chatTextEdit->insertHtml(RSLinkClipboard::toHtml());
}
void ChatWidget::contextMenuTextBrowser(QPoint point) void ChatWidget::contextMenuTextBrowser(QPoint point)
{ {
QMatrix matrix; QMatrix matrix;

View File

@ -47,7 +47,6 @@ class ChatWidget : public QWidget
public: public:
enum enumChatType { TYPE_NORMAL, TYPE_HISTORY, TYPE_OFFLINE, TYPE_SYSTEM }; enum enumChatType { TYPE_NORMAL, TYPE_HISTORY, TYPE_OFFLINE, TYPE_SYSTEM };
public:
explicit ChatWidget(QWidget *parent = 0); explicit ChatWidget(QWidget *parent = 0);
~ChatWidget(); ~ChatWidget();
@ -81,6 +80,7 @@ public:
void pasteText(const QString&); void pasteText(const QString&);
private slots: private slots:
void pasteCreateMsgLink() ;
void clearChatHistory(); void clearChatHistory();
void deleteChatHistory(); void deleteChatHistory();
void messageHistory(); void messageHistory();

View File

@ -275,6 +275,7 @@ HEADERS += rshare.h \
gui/TurtleRouterStatistics.h \ gui/TurtleRouterStatistics.h \
gui/AboutDialog.h \ gui/AboutDialog.h \
gui/ForumsDialog.h \ gui/ForumsDialog.h \
gui/CreateMsgLinkDialog.h \
gui/forums/ForumDetails.h \ gui/forums/ForumDetails.h \
gui/forums/EditForumDetails.h \ gui/forums/EditForumDetails.h \
gui/forums/CreateForum.h \ gui/forums/CreateForum.h \
@ -471,6 +472,7 @@ FORMS += gui/StartDialog.ui \
gui/MainWindow.ui \ gui/MainWindow.ui \
gui/TurtleRouterDialog.ui \ gui/TurtleRouterDialog.ui \
gui/TurtleRouterStatistics.ui \ gui/TurtleRouterStatistics.ui \
gui/CreateMsgLinkDialog.ui \
gui/forums/CreateForum.ui \ gui/forums/CreateForum.ui \
gui/forums/CreateForumMsg.ui \ gui/forums/CreateForumMsg.ui \
gui/forums/ForumDetails.ui \ gui/forums/ForumDetails.ui \
@ -580,6 +582,7 @@ SOURCES += main.cpp \
gui/TurtleRouterStatistics.cpp \ gui/TurtleRouterStatistics.cpp \
gui/MainWindow.cpp \ gui/MainWindow.cpp \
gui/ForumsDialog.cpp \ gui/ForumsDialog.cpp \
gui/CreateMsgLinkDialog.cpp \
gui/forums/ForumDetails.cpp \ gui/forums/ForumDetails.cpp \
gui/forums/EditForumDetails.cpp \ gui/forums/EditForumDetails.cpp \
gui/forums/CreateForum.cpp \ gui/forums/CreateForum.cpp \