[PATCH] Merge the old codes to master

27 views
Skip to first unread message

Jianjun Kong

unread,
Apr 19, 2008, 1:12:56 AM4/19/08
to aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, zhaoc...@gmail.com, xiyou...@googlegroups.com, Jianjun Kong
这次变化比较大,把原来的代码合并到了git树。
以后大家的工作都基于这git树开发。如果前期一些还未汇入此树,请及时回复新闻组。

演示界面:(我的主题色调很暗,在赵机子上很漂亮)
http://kongove.cn/down/pigeons.jpg

里边也添加了几个图片,在补丁里现实乱码,大家别介意~

Signed-off-by: Jianjun Kong <kongj...@gmail.com>
---
src/data/QQ.png | Bin 0 -> 7511 bytes
src/data/openimage.png | Bin 0 -> 3076 bytes
src/data/textbold.png | Bin 0 -> 1928 bytes
src/data/textcolor.png | Bin 0 -> 4226 bytes
src/data/textitalic.png | Bin 0 -> 1339 bytes
src/data/textunder.png | Bin 0 -> 1644 bytes
src/data/zh_CN.qm | Bin 0 -> 1767 bytes
src/ipmsg.h | 37 ++++++-
src/main.cpp | 2 +-
src/mainWindow.cpp | 275 +++++++++++++++++++++++++++++++++++++++++++----
src/mainWindow.h | 73 +++++++++++--
src/msgManage.cpp | 22 ++++
src/serve.cpp | 172 +++++++++++++++++++++++++++++
src/serve.h | 38 +++++++
src/subWindow.cpp | 205 +++++++++++++++++++++++++++++++++++
src/subWindow.h | 57 ++++++++++
16 files changed, 844 insertions(+), 37 deletions(-)
create mode 100644 src/data/QQ.png
create mode 100644 src/data/openimage.png
create mode 100644 src/data/textbold.png
create mode 100644 src/data/textcolor.png
create mode 100644 src/data/textitalic.png
create mode 100644 src/data/textunder.png
create mode 100644 src/data/zh_CN.qm
create mode 100644 src/serve.h

diff --git a/src/data/QQ.png b/src/data/QQ.png
new file mode 100644
index 0000000000000000000000000000000000000000..366160f700cf34cc0b4b8362b036bb086dd441c0
GIT binary patch
literal 7511
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

literal 0
Hc$@<O00001

diff --git a/src/data/openimage.png b/src/data/openimage.png
new file mode 100644
index 0000000000000000000000000000000000000000..d75f61b08ef0e65bf9ab4174002589f4a0c3950a
GIT binary patch
literal 3076
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
SjRFAx0000<MNUMnLSTYlGTOKR

literal 0
Hc$@<O00001

diff --git a/src/data/textbold.png b/src/data/textbold.png
new file mode 100644
index 0000000000000000000000000000000000000000..5fff9beaf34811959b751b9422313e63285e1413
GIT binary patch
literal 1928
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
O0000<MNUMnLSTYdP>b{c

literal 0
Hc$@<O00001

diff --git a/src/data/textcolor.png b/src/data/textcolor.png
new file mode 100644
index 0000000000000000000000000000000000000000..4be4e3501f84717ce89d93e49e53120cea75e092
GIT binary patch
literal 4226
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
YA4j6z0f?l-vj6}907*qoM6N<$g0HbDBLDyZ

literal 0
Hc$@<O00001

diff --git a/src/data/textitalic.png b/src/data/textitalic.png
new file mode 100644
index 0000000000000000000000000000000000000000..728ee488d239d7da4a213db79918ec104a2c5c96
GIT binary patch
literal 1339
zc$@({1;qM^P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004XF*Lt007q5
z)K6G40000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$%}GQ-R9M5s
zmrH0|WfaGM-@P-LXJga!k>})5iJC;a@=*m-v5Hiwh%~VvU5Gouy^t1Mx^XWEE=1}=
z1zS+tP+YWN-3V6Gq)pPyB$M}KGU>eT+<U)!T-;l65h0T_dY1RjobUgg|Nno^xk^O%
zKO<Dnk6#=fZBsBJB7@?2rif>VNKw1BJBDFulp%&;wkgAG$A71)rTnGe#y-CSR76DY
z3V?!<bMK!1sH5X>LIfqAsB)$1Wiksjr4Xf*96sC}Zf<T010bSCM?Yx=(!d>{xGMnK
zb;6!@L+$NHVv%r6Sq``^^!E10F~Cq@h9De*Xamfq7qoV2oj@P3uoVDRj|TdWzx`N4
zEcsz1-uU{lV*|}2XV1jriDtugKq&}^!H}w4zI53d8@pj!rH$hH($wvRyT5(~jETt7
zt|~Bb^Sd<gDR4Ev^xE03?$jG6UOts@Trf?D81VhKmueTk_-s1;$Irh2i$E5*3siP3
zLck6ZZZ@~|z1h>-twcb?7f3@0u3fuf2Zvt=ZUOnA^rfv58ugqme$+%H7l}3Y_4f8g
z9SvH*G+<_W$}JaG^8v_Pz-<x9ipb_x4yYTzgBTjQ(0}yNREr8l4ch@vKp8Nfo%gDx
zd>&W@@*?6s)IRVaJncN$-PM+`0~d($9gw~^rz`h!%fLEdZ70``Du6K1+R+xT+290)
zHB9*9)`Xj1nx5Tr0LnC<>FVl<SvEMXpQTV(_X_!3#kNXodkSD^c(kLX<xo!~u|I6P
zKL3V-nW-sVDlF%K4WPIk{&%DS&+`UTUG0fl4Q$(gW*RV`&gg1!eKoj!WxM%yK!FT)
zbhgJV8*Cj2Fa+b{lkUdKY#PV`)jb2Cl<{nPS5LyKf#dkkT&F6_i%Yfg=IUZS{MQZO
zrL!M5Cif-#8xOQZs<z*Nj1bID-__;9N<QGf062RBK)bbpuI|o6wd(UPfdH2l=5)1~
zUklo9S?ZW@^|s={wp3fZ`oMlbC<K$^cihd~+#Il05C3%oP|A3&J=L42T3`qM4>!PE
zI-?7#=}aI%YwrLU#?uE|y5m+2wD#?n&HO!pHUs`^djeo+<U)U{ClxPSVA-JYx1Y?+
zq%LhNEeE$RNu68nwgHIeKHuASw6PKhP~mSt3z@7g-(On{CSavrTh~E>8fZG$7JI<I
zD1QLm8Nco3vXe9QHlVry42_&WnMfvI-FKinUatBM@H8yWFKDZ@QEZ4Ntbl*}p?wz&
zjhsJ;FakW$(UWR9e&UtZnj1Ad4?-pgkZfu<Prmg|bK;T1?`!QoWm~0-N~s_I?Hgdr
zx^AVJq2bYvLr0EWJ$2@E>QKv(n5d{xE<>dXw&UMk84ziJeMxBA51HwEwaZ_Ble_uT
zmmjRo{dpbO*p47WTW>t>{zxnm(b_W?=d&8n)pCW!xjBFQ2t;BD)!Nx<I3?Iv@rPn@
zvk<$#p6vrB0$b`GRX`~f8hBy&TthVZp6gf##PdShwVg^amsco_QeG$=4absA2L&+@
z6u??`VrnJ*`;WjCU`9l|odQt60pM|<2Z-U*ZUt6z{Y9K85dTLdE5K~94HtH-fdGUV
xBu@kfNKjG-@B#p4@XieW<^ttii}1gUzW_fmfyxNM?-Kw3002ovPDHLkV1o6lda(ci

literal 0
Hc$@<O00001

diff --git a/src/data/textunder.png b/src/data/textunder.png
new file mode 100644
index 0000000000000000000000000000000000000000..288eac3f1ce15cef5cc1e1e0e13399dab7969acd
GIT binary patch
literal 1644
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

literal 0
Hc$@<O00001

diff --git a/src/data/zh_CN.qm b/src/data/zh_CN.qm
new file mode 100644
index 0000000000000000000000000000000000000000..6f33d6b36107438bed0a3e81b704296f7deb2d32
GIT binary patch
literal 1767
zc$~ddZ%kWN6hDvBjN<D^O>|3T(#1av7%MY_EtPDjQzqK`cztEvqaD<iwqOTn%N}Xi
zo(NrCR~$rxg$3jPIQ5H}X6hPsB<OTHhaa5dgHEHUA5dqq$byN_bMK@6N%W(;H|_7{
zynBA<o^yWp*1y@Y`t;9J<7d{EzUzPH?JsTzfRj*pwh-v38lkufs;0IhZh*!oW)Sa$
z`-2Z7?m-+v{0MOvfU_Yc5krUv5I;do0TgWGqFX;iR0>|C{sm7O<l$csUtdu*f;<JE
zAtH|f5Ru2Q3K4k>n-G!55JW^C!;uveAEXh#HoYOdgSb?D;`-MB3U^;sn^h4XGvCm1
z4dP2(`1i2^PsWddxCHCqW;}C+k*3A{(=1XmW~rN{PsccBmY8{JJ2RJxadOz#;JNUS
zIM^gtc%KIw)L=0-f-SbgNNd8jxxtpXG$v_QbuM#RaK<)g7QJbb(s*Bqk|ZY*7x!!t
z`v{O~a!)*+4WM=ZQ<EC+S`!Hor>jQeN6$yDqn@%=j6WEmKaDfeQZxFdJiS~l*yZw8
zg)C^iT<)Hi%jH?R_La1k`AX!s=vr6`+w~x^&s|+DO_V(IYI{~#B4(|Ok`6IaN1oJI
zvbPLux=YrTih^x)PI@+CO4QQ~($k}-+=YU3Uv}?i;jA3jteT0E3^S6pJW0TkkDB`S
zk@qz|pS0X4JWW8klr?F5#5BSYbHt1#IW3oZn?t`wLLFy34yh$*K@W3!nwUdDx{3}E
zvtZFnkYs_v`9RC5&BiW|S^MWPxjA>I*iFm_Lz&+--W%>*tInvWj+`gZ)~CL#&J1#G
zMd6!zwrITAFGwWgoyvTdo`$+e5jL?_T2zv~jXk@<t$`OXvmzSs01LSO@0pEo8sB|u
ze*>*$*d85_ax`$*PAbQLnwZefnbHM=0@3Ggu<iRzz0gxJc{Dhia6mDbjPx?-a-+Ip
za=Q)XM(+kQU;A%TL!r@2!#4bRrih7T#2t@5Kp+~@c-kQKd-X>=3B6Z(2!GC>Q<AtP
zrJMD(Up+J*F$Eg@Ym{UnC*|@V^>*I4^Gok>b&i}P3*O^n&q?2So10rFyV*A0f6RRn
z<;1q@O<6DHzyo*qN)E>e2v*ddpDc`UQZ8_4{D*Ol6l?r_8IM5DG11T)&D`qqY3$sl
z@c~PF79G^T#6#sk<B4Ah&hSdPV&Lw8MM=v0yAS$%_2_!3SJE<5BG8LVUkLVL*MD7D
z+_v1E_y%<@U?In18<pfB*LoKv7=9&-a&F%0f6rAX_^1Uv>)QHY6Kdras0qy*>Epvf
zR5F^x@~j3Y&T8nuX@gFj4(P_|fH=gB^rg}}q71aRu%_ROO{WhRGq27pjy^7i{6{_O
p^dl?DaBbqEW;N0`jkDuxS`S(H{|9#kVqCFN<V<+FdOCXh;ScG;$zK2f

literal 0
Hc$@<O00001

diff --git a/src/ipmsg.h b/src/ipmsg.h
index 1e4ff96..6e0365a 100644
--- a/src/ipmsg.h
+++ b/src/ipmsg.h
@@ -11,7 +11,8 @@

#ifndef IPMSG_H
#define IPMSG_H
-
+#include <QtNetwork>
+#include <QTime>
#include <QtGui>
//IP Messenger 通信协议V1.2定义

@@ -141,6 +142,9 @@
#define HOSTLIST_DUMMY "\b"
#define HLIST_ENTRY_SEPARATOR ':'

+//肥鸽子的协议
+#define PIGEONS_VERSION 0x0100
+
//一般定义
#define MAX_SOCKBUF 65536
#define MAX_UDPBUF 16384
@@ -163,7 +167,8 @@
#define DEFAULT_PRIORITYMAX 5

class MsgBuf {
- private :
+ //private :
+ public :
QString username;
QString hostname;
int version;
@@ -172,9 +177,31 @@ class MsgBuf {
QString extend;

public :
- //MsgBuf();
+ MsgBuf(){
+ username = QHostInfo::localHostName();
+ hostname = QHostInfo::localHostName();
+ version = PIGEONS_VERSION;
+ packetno = QDateTime::currentDateTime().toTime_t();//实际返回uint,有点不匹配
+ }
//~MsgBuf();
};
+class MsgMng{
+ public:
+ MsgBuf msg;
+ quint32 addr;
+ int portNo;
+ private:
+ MsgMng();
+ unsigned long getPacketno();
+ QString getUsername();
+ QString getHostname();
+ quint32 getAddress();
+ int getVersion();
+ unsigned long getCommand();
+ unsigned long getExtend();
+ MsgBuf* makeMsg(unsigned long command, QString extend);
+ void parseMsg();
+};

class CfgAllDialog {
private :
@@ -184,7 +211,7 @@ class CfgAllDialog {
bool fileattchOpt;
bool encryOpt;
bool utf8Opt;
-
+
//CfgAllDialog();
//~CfgAllDialog();
void changeCfgAll();
@@ -205,7 +232,7 @@ class CfgSendDialog {
bool noaddlistOpt;
bool readcheckOpt;
bool secretexOpt;
-
+
//CfgSendDialog();
//~CfgSendDialog();
void changCfgSend();
diff --git a/src/main.cpp b/src/main.cpp
index 8b88ff9..cf578b8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -14,7 +14,7 @@

int main( int argc, char *argv[])
{
- //Q_INIT_RESOURCE(resource);
+ Q_INIT_RESOURCE(resource);

QApplication app( argc, argv);

diff --git a/src/mainWindow.cpp b/src/mainWindow.cpp
index 06faf87..84e9d27 100644
--- a/src/mainWindow.cpp
+++ b/src/mainWindow.cpp
@@ -18,32 +18,36 @@
MainWindow::MainWindow()
{
initWindow();
+ //initServer();
+ initUp();
}

-void MainWindow::initWindow()
+void MainWindow::initServer()
{
- setWindowTitle(tr("Pigeons"));
- userListWidget = new QListWidget(this);
- userListWidgetItem = new QListWidgetItem(QIcon(":/data/openimage.png"),"kongove",userListWidget,1);
- userListWidgetItem = new QListWidgetItem("zhao",userListWidget,2);
- userListWidgetItem = new QListWidgetItem("mei",userListWidget,3);
- userListWidgetItem = new QListWidgetItem("gaohui",userListWidget,4);
- userListWidgetItem = new QListWidgetItem("lilei",userListWidget,5);
- userListWidgetItem = new QListWidgetItem("wangcong",userListWidget,6);
-
-/*QListWidgetItem::QListWidgetItem(const QListWidgetItem&)
-QListWidgetItem::QListWidgetItem(const QIcon&, const QString&, QListWidget*, int)
-QListWidgetItem::QListWidgetItem(const QString&, QListWidget*, int)
-QListWidgetItem::QListWidgetItem(QListWidget*, int)*/
-
- userListWidget->setMinimumSize(150,450);
- userListWidget->setMinimumSize(200,600);
-
-
-}
+ hostStringList = new QStringList();

+ //监听UDP数据包,如果有数据包抵达调用receiveessag槽进行处理
+ udpSocket = new QUdpSocket(this);
+ udpSocket->bind(IPMSG_DEFAULT_PORT);
+ //tcpSocket = new QTcpSocket(this);
+ //tcpSocket->bind(IPMSG_DEFAULT_PORT);
+ //connect(udpSocket, SIGNAL(readyRead()), this, SLOT(recvUdp()));
+ //connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(service->receiveTcp()));
+ //service->broadcast(IPMSG_BR_ENTRY, NULL);
+}
void MainWindow::initUp()
{
+/* hostStringList = new QStringList();
+
+ //监听UDP数据包,如果有数据包抵达调用receiveessag槽进行处理
+ udpSocket = new QUdpSocket(this);
+ udpSocket->bind(IPMSG_DEFAULT_PORT);
+ //tcpSocket = new QTcpSocket(this);
+ //tcpSocket->bind(IPMSG_DEFAULT_PORT);
+ //connect(udpSocket, SIGNAL(readyRead()), this, SLOT(recvUdp()));
+ //connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(service->receiveTcp()));
+ //service->broadcast(IPMSG_BR_ENTRY, NULL); */
+ ;

}

@@ -54,7 +58,8 @@ void MainWindow::exit()

void MainWindow::addSub()
{
-
+ sub = new SubWindow();
+ sub->show();
}

void MainWindow::delSub()
@@ -71,3 +76,231 @@ void MainWindow::delUserList()
{

}
+
+/*
+ void MainWindow::recvUdp()
+ {
+//service = new Serve();
+//service->receiveUdp();
+}
+
+void MainWindow::recvTcp()
+{
+//service = new Serve();
+//service->receiveTcp();
+}
+*/
+
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+ //service->broadcast(IPMSG_BR_EXIT, NULL);
+ event->accept();
+}
+
+void MainWindow::about()
+{
+ QMessageBox::information(this, tr("About"),tr("About application"));
+}
+
+void MainWindow::enabledSendButton()
+{
+ sendButton->setEnabled(true);
+}
+
+
+
+
+//槽函数,打开图片文件
+void MainWindow::openImage()
+{
+ //实现图像同步的策略为,先复制图像到自己和别人机器的 temp-image/ 下,然后在数据包中加入HTML的显示本地图像代码
+ QString image = QFileDialog::getOpenFileName(this, tr("Open Image File..."),
+ "temp-image/", tr("Image-Files (*.png *.gif *.bmp *.jpeg *.jpg)"));
+ QFile::copy(image, QString("temp-image/") + QFileInfo(image).fileName());
+ if (image.isEmpty())
+ {
+ return;
+ }
+ inputTextEdit->append("<img src='temp-image/" + QFileInfo(image).fileName() + "' />");
+ //广播图片
+ QByteArray datagram;
+ QDataStream out(&datagram,QIODevice::WriteOnly);
+
+ out << 4;
+
+ out << QFileInfo(image).fileName();
+
+ QImageReader imageReader(image);
+ imageReader.setFormat(QFileInfo(image).suffix().toAscii());
+ out << imageReader.read();
+
+ udpSocket->writeDatagram(datagram.data(), qint64(datagram.size()),
+ QHostAddress::Broadcast, IPMSG_DEFAULT_PORT);
+}
+
+//设置字体颜色
+void MainWindow::setFontColor()
+{
+ QColor col = QColorDialog::getColor(inputTextEdit->textColor(), this);
+ if (!col.isValid())
+ {
+ return;
+ }
+ inputTextEdit->setTextColor(col);
+
+ QPixmap pix(16, 16);
+ pix.fill(col);
+ colorButton->setIcon(pix);
+}
+
+//槽函数,设置字体大小
+void MainWindow::setFontSize(const QString &size)
+{
+ inputTextEdit->setFontPointSize(size.toFloat());
+}
+
+//槽函数,设置输入字体为粗体
+void MainWindow::setBoldFont(bool flag)
+{
+ if(flag == true)
+ {
+ inputTextEdit->setFontWeight(QFont::Bold);
+ }
+ else
+ inputTextEdit->setFontWeight(QFont::Normal);
+}
+
+//初始化聊天室界面和程序基本信息
+void MainWindow::initWindow()
+{
+
+// setWindowTitle(tr("Pigeons"));
+
+ messageWindow = new QWidget(this);
+ messageWindow->resize(200,600);
+ messageWindow->setMinimumSize(180,600);
+ messageWindow->setMaximumSize(200,600);
+ messageWindow->setWindowTitle(tr("localqq"));
+
+ /*f(){
+ recordTextEdit = new QTextEdit(messageWindow);
+ recordTextEdit->setReadOnly(true);
+ recordTextEdit->setMinimumSize(600,300);
+
+ inputTextEdit = new QTextEdit(messageWindow);
+ inputTextEdit->setMinimumSize(490,100);
+ inputTextEdit->setMaximumSize(600,180);
+
+ editToolBar = new QToolBar(messageWindow);
+
+
+ //编辑工具栏上的字体
+ fontComboBox = new QComboBox(editToolBar);
+ editToolBar->addWidget(fontComboBox);
+ fontComboBox->setEditable(true);
+ QFontDatabase fontDB;
+ fontComboBox->addItems(fontDB.families());
+ connect(fontComboBox, SIGNAL(activated(const QString &)),
+ inputTextEdit, SLOT(setFontFamily(const QString &)));
+ fontComboBox->setCurrentIndex(fontComboBox->findText(QApplication::font().family()));
+
+ //编辑工具栏的字体大小
+ sizeComboBox = new QComboBox(editToolBar);
+ editToolBar->addWidget(sizeComboBox);
+ sizeComboBox->setEditable(true);
+ foreach(int size, fontDB.standardSizes())
+ sizeComboBox->addItem(QString::number(size));
+ connect(sizeComboBox, SIGNAL(activated(const QString &)),
+ this, SLOT(setFontSize(const QString &)));
+ sizeComboBox->setCurrentIndex(sizeComboBox->findText(QString::number(QApplication::font().pointSize())));
+
+ //粗体
+ boldButton = new QToolButton(editToolBar);
+ editToolBar->addWidget(boldButton);
+ boldButton->setCheckable(true);
+ boldButton->setIcon(QIcon(":/data/textbold.png"));
+ connect(boldButton, SIGNAL(toggled(bool)), this, SLOT(setBoldFont(bool)));
+
+ //斜体
+ italicButton = new QToolButton(editToolBar);
+ editToolBar->addWidget(italicButton);
+ italicButton->setCheckable(true);
+ italicButton->setIcon(QIcon(":/data/textitalic.png"));
+ connect(italicButton, SIGNAL(toggled(bool)), inputTextEdit, SLOT(setFontItalic(bool)));
+
+ //下划线
+ underlineButton = new QToolButton(editToolBar);
+ editToolBar->addWidget(underlineButton);
+ underlineButton->setCheckable(true);
+ underlineButton->setIcon(QIcon(":/data/textunder.png"));
+ connect(underlineButton, SIGNAL(toggled(bool)), inputTextEdit, SLOT(setFontUnderline(bool)));
+
+ //颜色
+ colorButton = new QToolButton(editToolBar);
+ editToolBar->addWidget(colorButton);
+ colorButton->setIcon(QIcon(":/data/textcolor.png"));
+ connect(colorButton, SIGNAL(clicked()), this, SLOT(setFontColor()));
+
+ //打开图片
+ imageButton = new QToolButton(editToolBar);
+ editToolBar->addWidget(imageButton);
+ imageButton->setIcon(QIcon(":/data/openimage.png"));
+ connect(imageButton, SIGNAL(clicked()), this, SLOT(openImage()));//
+
+
+ //发送按钮
+ sendButton = new QPushButton(tr("&Send"), messageWindow);
+ sendButton->setEnabled(false);
+ connect(inputTextEdit, SIGNAL(textChanged()), this, SLOT(enabledSendButton()));
+ //connect(sendButton, SIGNAL(clicked()), this, SLOT(service->sendUdp()));//
+
+
+ //关于按钮
+ aboutButton = new QPushButton(tr("&About"),messageWindow);
+ connect(aboutButton, SIGNAL(clicked()), this, SLOT(about()));
+ } */
+
+ //用户昵称表
+ userListWidget = new QListWidget(messageWindow);
+ userListWidgetItem = new QListWidgetItem(QIcon(":/data/openimage.png"),"kongove",userListWidget);
+ userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),"zhaochongri",userListWidget);
+ userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),"mei",userListWidget);
+ userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),"gaohui",userListWidget);
+ userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),"lilei",userListWidget);
+ userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),"wangcong",userListWidget);
+ /*QListWidgetItem::QListWidgetItem(const QListWidgetItem&)
+ QListWidgetItem::QListWidgetItem(const QIcon&, const QString&, QListWidget*, int)
+ QListWidgetItem::QListWidgetItem(const QString&, QListWidget*, int)
+ QListWidgetItem::QListWidgetItem(QListWidget*, int)*/
+ userListWidget->setMinimumSize(180,420);
+ userListWidget->setMaximumSize(200,600);
+ connect(userListWidget, SIGNAL(itemDoubleClicked (QListWidgetItem*)),this,SLOT(addSub()));//
+
+ //退出按钮
+ //quitButton = new QPushButton(tr("&Quit"),messageWindow);
+ //connect(quitButton,SIGNAL(clicked()), this, SLOT(close()));
+
+ //布局
+ QHBoxLayout *buttonLayout = new QHBoxLayout;
+ //buttonLayout->addWidget(aboutButton);
+ //buttonLayout->addStretch(3);
+ //buttonLayout->addWidget(sendButton);
+ //buttonLayout->addStretch(1);
+ //buttonLayout->addWidget(quitButton);
+
+ QVBoxLayout *leftLayout = new QVBoxLayout;
+ //leftLayout->addWidget(recordTextEdit);
+ //leftLayout->addWidget(editToolBar);
+ //leftLayout->addWidget(inputTextEdit);
+
+ QGridLayout *mainLayout = new QGridLayout;
+ mainLayout->addLayout(leftLayout,0,0);
+ mainLayout->addWidget(userListWidget,0,1);
+ mainLayout->addLayout(buttonLayout,1,0,1,2);
+ mainLayout->setSizeConstraint(QLayout::SetFixedSize);
+
+ messageWindow->setLayout(mainLayout);
+ messageWindow->show();
+}
+
+
diff --git a/src/mainWindow.h b/src/mainWindow.h
index c1759f8..2aed403 100644
--- a/src/mainWindow.h
+++ b/src/mainWindow.h
@@ -11,6 +11,7 @@

#include <QtGui>
#include <QtNetwork>
+#include <QDebug>
#include "ipmsg.h"
#include "subWindow.h"

@@ -18,26 +19,78 @@ class MainWindow : public QWidget
{
Q_OBJECT

- public :
- CfgAllDialog cfgall;
- //QMap sublist(address,subWindow)
+ public:
+ MainWindow();
+ //初始化聊天室
+ void initWindow();
+ //聊天室窗口
+ void initUp();
+ void exit();
+ QWidget *messageWindow;
+ //显示聊天记录的文本编辑框
+ QTextEdit *recordTextEdit;
+ //输入文本编辑框
+ QTextEdit *inputTextEdit;
+ //关于按钮
+ QPushButton *aboutButton;
+ //发送按钮
+ QPushButton *sendButton;
+ //退出按钮
+ QPushButton *quitButton;
+ //右侧的用户列表,保存其他用户的登录昵称
+
int userCount;
QStringList userList;
QListWidget *userListWidget;
QListWidgetItem *userListWidgetItem;
+ //QMap sublist(address,subWindow)
+ CfgAllDialog cfgall;

- MainWindow();
+ //编辑inpuTextEdit的包括字体,颜色等行为的工具栏
+ QToolBar *editToolBar;
+ QComboBox *fontComboBox;
+ QComboBox *sizeComboBox;
+ QToolButton *boldButton;
+ QToolButton *italicButton;
+ QToolButton *underlineButton;
+ QToolButton *colorButton;
+ QToolButton *imageButton;

- private :
- QPushButton cfgAllButton;
- //Serve service;
+ //UDP连接用的socket
+ QUdpSocket *udpSocket;
+ QTcpSocket *tcpSocket;
+ //保存收发的消息
+ QString message;
+ //保存当前聊天室用户列表的主机名(为扩展:下一版本用TCP实现单对单聊天,这个是连接的关键)
+ QStringList *hostStringList;
+ //处理系统关闭事件
+ void closeEvent(QCloseEvent *event);

- void initWindow(); //初始化聊天室
- void initUp();
- void exit();
+ public slots:
+ //设置字体尺寸
+ void setFontSize(const QString &);
+ //设置粗体
+ void setBoldFont(bool);
+ //设置字体颜色
+ void setFontColor();
+ //打开图像文件
+ void openImage();
+ //开启发送按钮
+ void enabledSendButton();
+ //关于
+ void about();
+ private:
+ SubWindow *sub;
+ Serve *service;
+ QPushButton cfgAllButton;
+ private slots:
+ void initServer();
void addSub();
void delSub();
void addUserList();
void delUserList();
+ //void recvUdp();
+ //void recvTcp();

};
+
diff --git a/src/msgManage.cpp b/src/msgManage.cpp
index e69de29..a24209d 100644
--- a/src/msgManage.cpp
+++ b/src/msgManage.cpp
@@ -0,0 +1,22 @@
+#include "ipmsg.h"
+
+MsgMng::MsgMng(){
+
+}
+unsigned long MsgMng::getPacketno(){}
+QString MsgMng::getUsername(){}
+QString MsgMng::getHostname(){}
+quint32 MsgMng::getAddress(){}
+int MsgMng::getVersion(){}
+unsigned long MsgMng::getCommand(){}
+unsigned long MsgMng::getExtend(){}
+
+MsgBuf* MsgMng::makeMsg(unsigned long command, QString extend)
+{
+ MsgBuf *m = new MsgBuf;
+ m->command = command;
+ m->extend = extend;
+ return m;
+}
+
+void MsgMng::parseMsg(){}
diff --git a/src/serve.cpp b/src/serve.cpp
index e69de29..696b866 100644
--- a/src/serve.cpp
+++ b/src/serve.cpp
@@ -0,0 +1,172 @@
+#include "serve.h"
+
+void Serve::broadcast(unsigned long command, QString extend)
+{
+ MsgBuf *msg = new MsgBuf;
+ msg->command = command;
+ msg->extend = extend;
+ QByteArray datagram;
+ datagram.append(QString("%1:%2:%3:%4:%5:%6")
+ .arg(msg->version)
+ .arg(msg->packetno)
+ .arg(msg->username)
+ .arg(msg->hostname)
+ .arg(msg->command)
+ .arg(msg->extend));
+ udpSocket->writeDatagram(datagram.data(), qint64(datagram.size()),
+ QHostAddress::Broadcast, IPMSG_DEFAULT_PORT);
+}
+
+void Serve::sendUdp()
+{
+
+}
+void Serve::receiveUdp()
+{
+ while (udpSocket->hasPendingDatagrams())
+ {
+ QByteArray datagram;
+ datagram.resize(udpSocket->pendingDatagramSize());
+ udpSocket->readDatagram(datagram.data(), datagram.size());
+
+ //开始解码
+ int receiveVersion = 1; //保存解码数据包版本
+ unsigned long receivePacketno = 0; //保存数据包的编号
+ QString receiveUsername = NULL; //保存解码后的数据包的用户昵称
+ QString receiveHostname = NULL; //保存解码数据包后的主机名
+ unsigned long receiveCommand = 0; //保存命令字
+ QString receiveExtend = NULL; //保存附加信息
+
+ if(!datagram.isEmpty())
+ {
+ QList<QByteArray> list=datagram.split (':');
+ QListIterator<QByteArray> i(list);
+ for( int j =0;i.hasNext();j++)
+ switch(j)
+ {
+ case 0:receiveVersion = atoi(i.next());break;
+ case 1:receivePacketno = atoi(i.next());break;
+ case 2:receiveUsername = i.next();break;
+ case 3:receiveHostname = i.next();break;
+ case 4:receiveCommand = atol(i.next());break;
+ case 5:receiveExtend = i.next();break;
+ default:break;
+ }
+ }
+
+qDebug()<<datagram;
+qDebug()<<receiveUsername;
+qDebug()<<receiveHostname;
+qDebug()<<receiveExtend;
+qDebug()<<receiveVersion;
+qDebug()<<receivePacketno;
+qDebug()<<receiveCommand;
+
+unsigned long recvCmd;
+unsigned long recvOpt;
+recvCmd=GET_MODE(receiveCommand);
+recvOpt=GET_OPT(receiveCommand);
+
+MsgBuf *msg;
+//msg = makeMsg(receiveFlag, receiveBag,receiveUserName,receiveHostName, receiveCmd, receiveExtend);
+
+ switch (recvCmd)
+ {
+ case IPMSG_BR_ENTRY:
+ msgBrEntry(msg);
+ break;
+
+ case IPMSG_BR_EXIT:
+ msgBrExit(msg);
+ break;
+
+ case IPMSG_ANSENTRY:
+ msgAnsEntry(msg);
+ break;
+
+ case IPMSG_BR_ABSENCE:
+ msgBrAbsence(msg);
+ break;
+
+ case IPMSG_SENDMSG:
+ msgSendMsg(msg);
+ break;
+
+ case IPMSG_RECVMSG:
+ msgRecvMsg(msg);
+ break;
+
+ case IPMSG_READMSG:
+ case IPMSG_ANSREADMSG:
+ msgReadMsg(msg);
+ break;
+
+ case IPMSG_BR_ISGETLIST2:
+ msgBrIsGetList(msg);
+ break;
+
+ case IPMSG_OKGETLIST:
+ msgOkGetList(msg);
+ break;
+
+ case IPMSG_GETLIST:
+ msgGetList(msg);
+ break;
+
+ case IPMSG_ANSLIST:
+ msgAnsList(msg);
+ break;
+
+ case IPMSG_GETINFO:
+ msgGetInfo(msg);
+ break;
+
+ case IPMSG_SENDINFO:
+ msgSendInfo(msg);
+ break;
+
+ case IPMSG_GETPUBKEY:
+ msgGetPubKey(msg);
+ break;
+
+ case IPMSG_ANSPUBKEY:
+ msgAnsPubKey(msg);
+ break;
+
+ case IPMSG_GETABSENCEINFO:
+ msgGetAbsenceInfo(msg);
+ break;
+
+ case IPMSG_SENDABSENCEINFO:
+ msgSendAbsenceInfo(msg);
+ break;
+
+ case IPMSG_RELEASEFILES:
+ msgReleaseFiles(msg);
+ break;
+ }
+ }
+}
+void Serve::sendTcp(){}
+void Serve::receiveTcp(){}
+void Serve::msgBrEntry(MsgBuf *msg){}
+void Serve::msgBrExit(MsgBuf *msg){}
+void Serve::msgAnsEntry(MsgBuf *msg){}
+void Serve::msgBrAbsence(MsgBuf *msg){}
+void Serve::msgSendMsg(MsgBuf *msg){}
+void Serve::msgRecvMsg(MsgBuf *msg){}
+void Serve::msgReadMsg(MsgBuf *msg){}
+void Serve::msgBrIsGetList(MsgBuf *msg){}
+void Serve::msgOkGetList(MsgBuf *msg){}
+void Serve::msgGetList(MsgBuf *msg){}
+void Serve::msgAnsList(MsgBuf *msg){}
+void Serve::msgGetInfo(MsgBuf *msg){}
+void Serve::msgSendInfo(MsgBuf *msg){}
+void Serve::msgGetPubKey(MsgBuf *msg){}
+void Serve::msgAnsPubKey(MsgBuf *msg){}
+void Serve::msgGetAbsenceInfo(MsgBuf *msg){}
+void Serve::msgSendAbsenceInfo(MsgBuf *msg){}
+void Serve::msgReleaseFiles(MsgBuf *msg){}
+void Serve::msgInfoSub(MsgBuf *msg){}
+
+
diff --git a/src/serve.h b/src/serve.h
new file mode 100644
index 0000000..e8990a2
--- /dev/null
+++ b/src/serve.h
@@ -0,0 +1,38 @@
+#include <QtGui>
+#include <QtNetwork>
+#include <QDebug>
+#include "ipmsg.h"
+
+class Serve{
+
+public slots:
+
+ void broadcast(unsigned long command, QString extend);
+ void sendUdp();
+ void sendTcp();
+ void receiveUdp();
+ void receiveTcp();
+public:
+ void msgBrEntry(MsgBuf *msg);
+ void msgBrExit(MsgBuf *msg);
+ void msgAnsEntry(MsgBuf *msg);
+ void msgBrAbsence(MsgBuf *msg);
+ void msgSendMsg(MsgBuf *msg);
+ void msgRecvMsg(MsgBuf *msg);
+ void msgReadMsg(MsgBuf *msg);
+ void msgBrIsGetList(MsgBuf *msg);
+ void msgOkGetList(MsgBuf *msg);
+ void msgGetList(MsgBuf *msg);
+ void msgAnsList(MsgBuf *msg);
+ void msgGetInfo(MsgBuf *msg);
+ void msgSendInfo(MsgBuf *msg);
+ void msgGetPubKey(MsgBuf *msg);
+ void msgAnsPubKey(MsgBuf *msg);
+ void msgGetAbsenceInfo(MsgBuf *msg);
+ void msgSendAbsenceInfo(MsgBuf *msg);
+ void msgReleaseFiles(MsgBuf *msg);
+ void msgInfoSub(MsgBuf *msg);
+
+private:
+ QUdpSocket *udpSocket;
+};
diff --git a/src/subWindow.cpp b/src/subWindow.cpp
index e69de29..73ad80b 100644
--- a/src/subWindow.cpp
+++ b/src/subWindow.cpp
@@ -0,0 +1,205 @@
+#include "subWindow.h"
+
+//构造函数,初始化登录窗口
+SubWindow::SubWindow()
+{
+ initialize();
+}
+
+//处理关闭事件
+void SubWindow::closeEvent(QCloseEvent *event)
+{
+ //广播用户注销信息
+ //writeData(2);
+ //接受信号,执行退出
+ event->accept();
+}
+
+//关于本程序
+void SubWindow::about()
+{
+ QMessageBox::information(this, tr("About"),tr("About application"));
+}
+
+//激活发送按钮
+void SubWindow::enabledSendButton()
+{
+ sendButton->setEnabled(true);
+}
+
+//设置字体颜色
+void SubWindow::setFontColor()
+{
+ QColor col = QColorDialog::getColor(inputTextEdit->textColor(), this);
+ if (!col.isValid())
+ {
+ return;
+ }
+ inputTextEdit->setTextColor(col);
+
+ QPixmap pix(16, 16);
+ pix.fill(col);
+ colorButton->setIcon(pix);
+}
+
+//槽函数,打开图片文件
+void SubWindow::openImage()
+{
+ //实现图像同步的策略为,先复制图像到自己和别人机器的 temp-image/ 下,然后在数据包中加入HTML的显示本地图像代码
+ QString image = QFileDialog::getOpenFileName(this, tr("Open Image File..."),
+ "temp-image/", tr("Image-Files (*.png *.gif *.bmp *.jpeg *.jpg)"));
+ QFile::copy(image, QString("temp-image/") + QFileInfo(image).fileName());
+ if (image.isEmpty())
+ {
+ return;
+ }
+ inputTextEdit->append("<img src='temp-image/" + QFileInfo(image).fileName() + "' />");
+
+
+ //广播图片
+ QByteArray datagram;
+ QDataStream out(&datagram,QIODevice::WriteOnly);
+
+ out << 4;
+
+ out << QFileInfo(image).fileName();
+
+ QImageReader imageReader(image);
+ imageReader.setFormat(QFileInfo(image).suffix().toAscii());
+ out << imageReader.read();
+}
+
+//槽函数,设置字体大小
+void SubWindow::setFontSize(const QString &size)
+{
+ inputTextEdit->setFontPointSize(size.toFloat());
+}
+
+//槽函数,设置输入字体为粗体
+void SubWindow::setBoldFont(bool flag)
+{
+ if(flag == true)
+ {
+ inputTextEdit->setFontWeight(QFont::Bold);
+ }
+ else
+ inputTextEdit->setFontWeight(QFont::Normal);
+}
+
+//初始化聊天室界面和程序基本信息
+void SubWindow::initialize()
+{
+
+ resize(620,600);
+ setMinimumSize(620,600);
+ setMaximumSize(620,600);
+ setWindowTitle(tr("localqq"));
+
+ messageWindow = new QWidget(this);
+ messageWindow->resize(620,600);
+
+ recordTextEdit = new QTextEdit(messageWindow);
+ recordTextEdit->setReadOnly(true);
+ recordTextEdit->setMinimumSize(600,300);
+
+ inputTextEdit = new QTextEdit(messageWindow);
+ inputTextEdit->setMinimumSize(490,100);
+ inputTextEdit->setMaximumSize(600,180);
+
+ editToolBar = new QToolBar(messageWindow);
+
+ //编辑工具栏上的字体
+ fontComboBox = new QComboBox(editToolBar);
+ editToolBar->addWidget(fontComboBox);
+ fontComboBox->setEditable(true);
+ QFontDatabase fontDB;
+ fontComboBox->addItems(fontDB.families());
+ connect(fontComboBox, SIGNAL(activated(const QString &)),
+ inputTextEdit, SLOT(setFontFamily(const QString &)));
+ fontComboBox->setCurrentIndex(fontComboBox->findText(QApplication::font().family()));
+
+ //编辑工具栏的字体大小
+ sizeComboBox = new QComboBox(editToolBar);
+ editToolBar->addWidget(sizeComboBox);
+ sizeComboBox->setEditable(true);
+ foreach(int size, fontDB.standardSizes())
+ sizeComboBox->addItem(QString::number(size));
+ connect(sizeComboBox, SIGNAL(activated(const QString &)),
+ this, SLOT(setFontSize(const QString &)));
+ sizeComboBox->setCurrentIndex(sizeComboBox->findText(QString::number(QApplication::font().pointSize())));
+
+ //粗体
+ boldButton = new QToolButton(editToolBar);
+ editToolBar->addWidget(boldButton);
+ boldButton->setCheckable(true);
+ boldButton->setIcon(QIcon(":/data/textbold.png"));
+ connect(boldButton, SIGNAL(toggled(bool)), this, SLOT(setBoldFont(bool)));
+
+ //斜体
+ italicButton = new QToolButton(editToolBar);
+ editToolBar->addWidget(italicButton);
+ italicButton->setCheckable(true);
+ italicButton->setIcon(QIcon(":/data/textitalic.png"));
+ connect(italicButton, SIGNAL(toggled(bool)), inputTextEdit, SLOT(setFontItalic(bool)));
+
+ //下划线
+ underlineButton = new QToolButton(editToolBar);
+ editToolBar->addWidget(underlineButton);
+ underlineButton->setCheckable(true);
+ underlineButton->setIcon(QIcon(":/data/textunder.png"));
+ connect(underlineButton, SIGNAL(toggled(bool)), inputTextEdit, SLOT(setFontUnderline(bool)));
+
+ //颜色
+ colorButton = new QToolButton(editToolBar);
+ editToolBar->addWidget(colorButton);
+ colorButton->setIcon(QIcon(":/data/textcolor.png"));
+ connect(colorButton, SIGNAL(clicked()), this, SLOT(setFontColor()));
+
+ //打开图片
+ imageButton = new QToolButton(editToolBar);
+ editToolBar->addWidget(imageButton);
+ imageButton->setIcon(QIcon(":/data/openimage.png"));
+ connect(imageButton, SIGNAL(clicked()), this, SLOT(openImage()));
+
+ //发送按钮
+ sendButton = new QPushButton(tr("&Send"), messageWindow);
+ sendButton->setEnabled(false);
+ connect(inputTextEdit, SIGNAL(textChanged()), this, SLOT(enabledSendButton()));
+ connect(sendButton, SIGNAL(clicked()), this, SLOT(sendMessage()));
+
+ //关于按钮
+ aboutButton = new QPushButton(tr("&About"),messageWindow);
+ connect(aboutButton, SIGNAL(clicked()), this, SLOT(about()));
+
+ //用户昵称表
+ //userListWidget = new QListWidget(messageWindow);
+ //userListWidget->setMinimumSize(120,420);
+ //userListWidget->setMaximumSize(180,600);
+
+ //退出按钮
+ quitButton = new QPushButton(tr("&Quit"),messageWindow);
+ connect(quitButton,SIGNAL(clicked()), this, SLOT(close()));
+
+ //布局
+ QHBoxLayout *buttonLayout = new QHBoxLayout;
+ buttonLayout->addWidget(aboutButton);
+ buttonLayout->addStretch(3);
+ buttonLayout->addWidget(sendButton);
+ buttonLayout->addStretch(1);
+ buttonLayout->addWidget(quitButton);
+
+ QVBoxLayout *leftLayout = new QVBoxLayout;
+ leftLayout->addWidget(recordTextEdit);
+ leftLayout->addWidget(editToolBar);
+ leftLayout->addWidget(inputTextEdit);
+
+ QGridLayout *mainLayout = new QGridLayout;
+ mainLayout->addLayout(leftLayout,0,0);
+ //mainLayout->addWidget(userListWidget,0,1);
+ mainLayout->addLayout(buttonLayout,1,0,1,2);
+ mainLayout->setSizeConstraint(QLayout::SetFixedSize);
+
+ messageWindow->setLayout(mainLayout);
+ messageWindow->show();
+}
+
diff --git a/src/subWindow.h b/src/subWindow.h
index e69de29..d066432 100644
--- a/src/subWindow.h
+++ b/src/subWindow.h
@@ -0,0 +1,57 @@
+#include <QtGui>
+#include <QtNetwork>
+#include <QDebug>
+#include "ipmsg.h"
+#include "serve.h"
+
+class SubWindow : public QDialog
+{
+ //Q_OBJECT
+
+ public:
+ SubWindow();
+ public slots:
+ private:
+ QWidget *messageWindow;
+ //处理系统关闭事件
+ void closeEvent(QCloseEvent *event);
+ //根据flag编码UDP数据包并发送之
+ void writeData(int flag);
+ //显示聊天记录的文本编辑框
+ QTextEdit *recordTextEdit;
+ //输入文本编辑框
+ QTextEdit *inputTextEdit;
+ //关于按钮和发送按钮
+ QPushButton *aboutButton;
+ QPushButton *sendButton;
+ //右侧的用户列表,保存其他用户的登录昵称
+ QListWidget *userListWidget;
+ QListWidgetItem *userListWidgetItem;
+ //退出按钮
+ QPushButton *quitButton;
+ //编辑inpuTextEdit的包括字体,颜色等行为的工具栏
+ QToolBar *editToolBar;
+ QComboBox *fontComboBox;
+ QComboBox *sizeComboBox;
+ QToolButton *boldButton;
+ QToolButton *italicButton;
+ QToolButton *underlineButton;
+ QToolButton *colorButton;
+ QToolButton *imageButton;
+ private slots:
+
+ //初始化聊天室
+ void initialize();
+ //设置字体尺寸
+ void setFontSize(const QString &);
+ //设置粗体
+ void setBoldFont(bool);
+ //设置字体颜色
+ void setFontColor();
+ //打开图像文件
+ void openImage();
+ //开启发送按钮
+ void enabledSendButton();
+ //关于
+ void about();
+};
--
1.5.2.5

Jianjun Kong

unread,
Apr 19, 2008, 4:40:54 AM4/19/08
to aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, zhaoc...@gmail.com, xiyou...@googlegroups.com, Jianjun Kong
在 08-4-19,Jianjun Kong<kongj...@gmail.com> 写道:

不能使用git的请到 http://kongove.cn/down/pigeons.tar.bz
利用 修改代码后可以制作补丁提交到新闻组。把源码打包放到网上,给个链接。

网上的免费网盘很多,如:
www.100disk.com

chongri zhao

unread,
Apr 19, 2008, 5:43:57 AM4/19/08
to Jianjun Kong, aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, xiyou...@googlegroups.com
刚才加了两个文件resource.qrc &&zh_CN.ts

--
There is a will,there is a way!!!

Jianjun Kong

unread,
Apr 21, 2008, 8:22:05 AM4/21/08
to chongri zhao, aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, xiyou...@googlegroups.com
On Sat, Apr 19, 2008 at 05:43:57PM +0800, chongri zhao wrote:
> 刚才加了两个文件resource.qrc &&zh_CN.ts

(大家把对pigeons代码的修改补丁贴到这里,并简单描述)

赵崇日上边补丁发布后,这两天我做了进一步完善:

0008-update-files.patch
0009-Add-AUTHORS-README-Update-TODO.patch
0010-update-TODO.patch
0011-Change-of-sendMessage.patch
0012-Updata-of-send-message-etc.patch
0013-update-of-Serve-etc.patch

没有彻底搞清除的问题:
1. 不同类之间信号和槽的应用
2. MainWindow有一个成员Serve service,新建SubWindow时,把service传递过去初始化,这样SubWindow就可以通过传递的指针使用唯一的Serve类了。在Serve类中对MainWindow中方法的使用,除了信号槽之外还有什么方法,能不能把mainWindow的指针传递给Serve,和上面一样使用(正在探索,尽量减少信号槽的使用,提高效率)。
3. msgSendMsg() msg...等函数是对接收来的udp包初步处理后,再交给他们处理? 我原来还以为是用来处理发送消息的。msgSendMsg()完成把MsgBuf里的相关内容输出到子窗口等任务。

具体见代码 http://repo.or.cz/w/pigeons.git

TODO:
1. 完善类图
2. 对类图方法做详细描述
3. 规范代码,使用git维护
4. 熟悉飞鸽协议
5. 开始初步编码
6. 合并前期测试代码到git树
7. 所有开发基于当前最新git树,或者要及时汇入git树
8. Makefile暂时性使用qmake自动生成的,等程序发布时,需要写个configure的脚本,自动生成Makefile,方便用户编译、安装
9. 解决不同类之间信号和槽的应用问题

明天下午在一块去老校区和梅讨论一下下边的项目安排和遇到的技术问题。

--
| Olympic of world,Tebit of China!
|
| Jianjun Kong | www.kongove.cn
| Xi'an Institute of Post & Telecommunications

Jianjun Kong

unread,
Apr 27, 2008, 8:28:59 AM4/27/08
to chongri zhao, aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, xiyou...@googlegroups.com
> TODO:
> 1. 完善类图
> 2. 对类图方法做详细描述
> 3. 规范代码,使用git维护
> 4. 熟悉飞鸽协议
> 5. 开始初步编码
> 6. 合并前期测试代码到git树
> 7. 所有开发基于当前最新git树,或者要及时汇入git树
> 8. Makefile暂时性使用qmake自动生成的,等程序发布时,需要写个configure的脚本,自动生成Makefile,方便用户编译、安装
> 9. 解决不同类之间信号和槽的应用问题

最近做的一些改进:
添加在线用户到窗口内,并对重复等情况做了处理
对类的划分再次做小的调整,把一些小块合并。
详见repo.or.cz/w/pigeons.git


Jianjun Kong

unread,
May 7, 2008, 7:08:31 PM5/7/08
to chongri zhao, aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, xiyou...@googlegroups.com
现在关于QT使用等基本问题基本解决,不同类之间信号和槽的调用也已实现。
下面我们需要对飞鸽协议做深入研究,不知道有没有类似RFC(或者相近的)文档。
那样可以让我们更加清晰的了解协议工作的过程。
考虑到性能问题,学习QT中回调函数的使用,尽量用回调函数代替信号和槽。


BTW:大家都加把劲,我今早六点多起来做的补丁。马上要去上课~
From ea973c9eff2edbc07e2d5b503a3b26ce57bdd8c1 Mon Sep 17 00:00:00 2001
From: Jianjun Kong <kongj...@gmail.com>
Date: Thu, 8 May 2008 15:00:33 +0800
Subject: [PATCH] update TODO and show user to list

1. update TODO
2. update of show users to list

Signed-off-by: Jianjun Kong <kongj...@gmail.com>
---

TODO | 6 +++---
src/serve.cpp | 6 ++++--
2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/TODO b/TODO
index 7cf8e8a..75cc106 100644
--- a/TODO
+++ b/TODO
@@ -1,9 +1,9 @@


1. 完善类图
2. 对类图方法做详细描述
3. 规范代码,使用git维护

-4. 熟悉飞鸽协议
-5. 开始初步编码
+4. 对飞鸽协议的具体交互做深入理解
+5. 开始核心功能实现编码


6. 合并前期测试代码到git树
7. 所有开发基于当前最新git树,或者要及时汇入git树
8. Makefile暂时性使用qmake自动生成的,等程序发布时,需要写个configure的脚本,自动生成Makefile,方便用户编译、安装

-9. 解决不同类之间信号和槽的应用问题
+9. 考虑到性能问题,学习QT中回调函数的使用,尽量用回调函数代替信号和槽
diff --git a/src/serve.cpp b/src/serve.cpp
index e9ed953..e875962 100644
--- a/src/serve.cpp
+++ b/src/serve.cpp
@@ -59,11 +59,13 @@ void Serve::sendUdp(MsgMng *msg)
//msg->extend="This is broadcast message(There seems a bug if the message it too long)";
qDebug()<<"---sendUdp---";
qDebug()<<"Username:"<<msg->username;
- /*qDebug()<<"Hostname:"<<msg->hostname;
+ qDebug()<<"Hostname:"<<msg->hostname;
+ qDebug()<<"HostAddress:"<<msg->address;
qDebug()<<"Version:"<<msg->version;
qDebug()<<"Packetno:"<<msg->packetno;
qDebug()<<"Command:"<<msg->command;
- qDebug()<<"Extend:"<<msg->extend;*/
+ qDebug()<<"Extend:"<<msg->extend;
+

QByteArray datagram;


datagram.append(QString("%1:%2:%3:%4:%5:%6")

--
1.5.2.5

--
| The girl you most love is uncertain to become your wife!
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Jianjun Kong

unread,
May 9, 2008, 7:34:34 AM5/9/08
to chongri zhao, aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, xiyou...@googlegroups.com
On Thu, May 08, 2008 at 07:08:31AM +0800, Jianjun Kong wrote:
> 现在关于QT使用等基本问题基本解决,不同类之间信号和槽的调用也已实现。
> 下面我们需要对飞鸽协议做深入研究,不知道有没有类似RFC(或者相近的)文档。
> 那样可以让我们更加清晰的了解协议工作的过程。
> 考虑到性能问题,学习QT中回调函数的使用,尽量用回调函数代替信号和槽。
>
>
> BTW:大家都加把劲,我今早六点多起来做的补丁。马上要去上课~
> From ea973c9eff2edbc07e2d5b503a3b26ce57bdd8c1 Mon Sep 17 00:00:00 2001
> From: Jianjun Kong <kongj...@gmail.com>
> Date: Thu, 8 May 2008 15:00:33 +0800
> Subject: [PATCH] update TODO and show user to list
>
> 1. update TODO
> 2. update of show users to list
>
> Signed-off-by: Jianjun Kong <kongj...@gmail.com>
> ---
> TODO | 6 +++---

Another patch of pigeons. Please pull the git tree.
Sometimes it's a kind of enjoyment to talk with myself.


From 61d6f6aae524980830f8659e2f2bda2c47bb6844 Mon Sep 17 00:00:00 2001
From: Jianjun Kong <kongj...@gmail.com>
Date: Fri, 9 May 2008 19:19:17 +0800
Subject: [PATCH] update process message

更新:
1. 特殊处理对自己发送消息;
2. 对接收到的html字符串单独处理,解决无法正常显示的问题;

下面要做的:
1. 实现userlist与窗口用户的一一对应关系
2. 通过QHostAddress来区分不同主机
3. 考虑在用户上线是边创建subWindow对象,用户双击头像是只是显示窗口
4. 把近期对pigeons设计上的一些调整,修改到类图上,这样可以帮助其他人了解项目

Signed-off-by: Jianjun Kong <kongj...@gmail.com>
---

TODO | 10 ++++------
src/mainWindow.cpp | 5 +++--
src/serve.cpp | 17 +++++++++++++----
src/subWindow.cpp | 14 ++++++++++----
src/subWindow.h | 2 +-
5 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/TODO b/TODO
index 75cc106..cc5cf66 100644
--- a/TODO
+++ b/TODO
@@ -1,9 +1,7 @@
-1. 完善类图
+1. 把近期对pigeons设计上的一些调整,修改到类图上,这样可以帮助其他人了解项目


2. 对类图方法做详细描述
3. 规范代码,使用git维护

4. 对飞鸽协议的具体交互做深入理解
-5. 开始核心功能实现编码
-6. 合并前期测试代码到git树
-7. 所有开发基于当前最新git树,或者要及时汇入git树
-8. Makefile暂时性使用qmake自动生成的,等程序发布时,需要写个configure的脚本,自动生成Makefile,方便用户编译、安装
-9. 考虑到性能问题,学习QT中回调函数的使用,尽量用回调函数代替信号和槽
+5. 实现userlist与窗口用户的一一对应关系,通过QHostAddress来区分不同主机;考虑在用户上线是边创建subWindow对象,用户双击头像是只是显示窗口
+6. Makefile暂时性使用qmake自动生成的,等程序发布时,需要写个configure的脚本,自动生成Makefile,方便用户编译、安装
+7. 考虑到性能问题,学习QT中回调函数的使用,尽量用回调函数代替信号和槽
diff --git a/src/mainWindow.cpp b/src/mainWindow.cpp
index 17cd644..a1ca91f 100644
--- a/src/mainWindow.cpp
+++ b/src/mainWindow.cpp
@@ -84,7 +84,8 @@ void MainWindow::showuserlist()

void MainWindow::addSub()
{
- sub = new SubWindow(service);
+ QHostAddress addr=QHostAddress::LocalHost;
+ sub = new SubWindow(service,addr);
sub->show();
}

@@ -228,7 +229,7 @@ void MainWindow::initWindow()
messageWindow->resize(200,600);
messageWindow->setMinimumSize(190,600);
messageWindow->setMaximumSize(200,600);
- messageWindow->setWindowTitle(tr("localqq"));
+ //messageWindow->setWindowTitle(tr("localqq"));

/*f(){
recordTextEdit = new QTextEdit(messageWindow);
diff --git a/src/serve.cpp b/src/serve.cpp
index e875962..d75312e 100644
--- a/src/serve.cpp
+++ b/src/serve.cpp
@@ -57,6 +57,10 @@ void Serve::sendUdp(MsgMng *msg)
//qDebug()<<"Username:"<<msgmng->msgbuf->username;
//qDebug()<<"Hostname:"<<msgmng->msg->hostname;


//msg->extend="This is broadcast message(There seems a bug if the message it too long)";

+
+ //QString str=msg->address.toString()+":"+msg->username;
+ //msg->address=getAddress(str);
+

qDebug()<<"---sendUdp---";
qDebug()<<"Username:"<<msg->username;

qDebug()<<"Hostname:"<<msg->hostname;
@@ -65,7 +69,12 @@ void Serve::sendUdp(MsgMng *msg)


qDebug()<<"Packetno:"<<msg->packetno;
qDebug()<<"Command:"<<msg->command;

qDebug()<<"Extend:"<<msg->extend;
-
+
+ if(msg->address==QHostAddress::LocalHost){
+ emit msgSendMsg(msg);
+ qDebug()<<"sendUdp---to localhost";
+ return;


+ }

QByteArray datagram;
datagram.append(QString("%1:%2:%3:%4:%5:%6")

@@ -89,7 +98,7 @@ void Serve::sendUdp(MsgMng *msg)

qDebug()<<"SendUdp:"<<datagram;
udpSocket->writeDatagram(datagram.data(), (qint64)datagram.size(),
- msgmng->address, IPMSG_DEFAULT_PORT);
+ msg->address, IPMSG_DEFAULT_PORT);
//QHostAddress::Broadcast, IPMSG_DEFAULT_PORT);
}
void Serve::receiveUdp()
@@ -269,8 +278,8 @@ if(sendCmd==IPMSG_SENDMSG)
void Serve::receiveTcp(){}
void Serve::msgBrEntry(MsgMng *msg)
{
- qDebug()<<"msgBrEntry address:"<<msgmng->address;
- qDebug()<<"["<<QDateTime::currentDateTime().toString(tr("yyyy-MM-dd hh:mm:ss"))<<"] "<<msgmng->username<<"is online.";
+ qDebug()<<"msgBrEntry address:"<<msg->address;
+ qDebug()<<"["<<QDateTime::currentDateTime().toString(tr("yyyy-MM-dd hh:mm:ss"))<<"] "<<msg->username<<"is online.";
msg->command=IPMSG_ANSENTRY;
msg->extend="";
emit addUser(msg);
diff --git a/src/subWindow.cpp b/src/subWindow.cpp
index 31bfcba..ec58fdd 100644
--- a/src/subWindow.cpp
+++ b/src/subWindow.cpp
@@ -1,19 +1,21 @@
#include "subWindow.h"

//构造函数,初始化登录窗口
-SubWindow::SubWindow(Serve *ser)
+SubWindow::SubWindow(Serve *ser, QHostAddress addr)
{
initialize();
service = ser;
msgmng = new MsgMng;
+ msgmng->address = addr;
connect(service, SIGNAL(msgSendMsg(MsgMng *)) , this, SLOT(showMessage(MsgMng *)));
}

void SubWindow::showMessage(MsgMng *msg)
{
qDebug()<<"["<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")<<"] "<<msg->username<<":\n"<<msg->extend;
- recordTextEdit->append("\n[" + QDateTime::currentDateTime().toString(tr("yyyy-MM-dd hh:mm:ss"))
- + tr("] ") +msg->username + tr(":\n")+msg->extend);
+ recordTextEdit->append("[" + QDateTime::currentDateTime().toString(tr("yyyy-MM-dd hh:mm:ss"))
+ + tr("] ") +msg->username);
+ recordTextEdit->append(msg->extend);
}

//处理关闭事件
@@ -32,12 +34,16 @@ void SubWindow::closeEvent(QCloseEvent *event)
void SubWindow::sendMessage()
{
message = inputTextEdit->toHtml();
- recordTextEdit->append("\n[" + QDateTime::currentDateTime().toString(tr("yyyy-MM-dd hh:mm:ss"))
+ qDebug()<<"mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmessage:"<<message;
+ recordTextEdit->append("[" + QDateTime::currentDateTime().toString(tr("yyyy-MM-dd hh:mm:ss"))
+ tr("] ") +tr("konogve:") +message);
//connect(fontComboBox, SIGNAL(activated(const QString &)),inputTextEdit, SLOT(setFontFamily(const QString &)));
MsgMng *msg = new MsgMng;
msg->command=IPMSG_SENDMSG;
msg->extend=message;
+ msg->address=msgmng->address;
+ //QString str=msg->address.toString()+":"+msg->username;
+ //msg->address=getAddress(str);
service->sendUdp(msg);
qDebug()<<"End of sendUdp";
//清除发送框
diff --git a/src/subWindow.h b/src/subWindow.h
index 03cc508..251f2e5 100644
--- a/src/subWindow.h
+++ b/src/subWindow.h
@@ -20,7 +20,7 @@ class SubWindow : public QDialog
Q_OBJECT

public:
- SubWindow(Serve *ser);
+ SubWindow(Serve *ser,QHostAddress addr);
Serve *service;
MsgMng *msgmng;
public slots:
--
1.5.2.5

Jianjun Kong

unread,
May 9, 2008, 10:53:53 PM5/9/08
to chongri zhao, aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, xiyou...@googlegroups.com
On Fri, May 09, 2008 at 07:34:34PM +0800, Jianjun Kong wrote:

<snip>

> 更新:
> 1. 特殊处理对自己发送消息;
> 2. 对接收到的html字符串单独处理,解决无法正常显示的问题;
>
> 下面要做的:
> 1. 实现userlist与窗口用户的一一对应关系
> 2. 通过QHostAddress来区分不同主机

1, 2 points have realised by me,and it can also process the host which has more than one ip address.
QHostInfo.address() return a QList class, which save all ip of one host.
QHostInfo info=QHostInfo::fromName("localhost");
if (!info.addresses().isEmpty()) {
if(info.addresses().indexOf(msg->address)){
emit msgSendMsg(msg);
qDebug()<<"sendUdp---to localhost";
return;
}
}

QT assist if very useful~~~~!

> 3. 考虑在用户上线是边创建subWindow对象,用户双击头像是只是显示窗口
> 4. 把近期对pigeons设计上的一些调整,修改到类图上,这样可以帮助其他人了解项目

it has been updated, and upload to git tree, goon improve it~

other update:
1. Sending message
Maybe I have make a big progress to communicate with pigeons on windows, Next we should process the options of commands text.

2. Process of ip address and username

TODO:
1. 把近期对pigeons设计上的一些调整,修改到类图上,这样可以帮助其他人了解项目
2. 对飞鸽协议的具体交互做深入理解,特别是commond字段的参数组合
3. 划分任务,集体参与
4. 考虑在用户上线是边创建subWindow对象,用户双击头像是只是显示窗口
5. 考虑到性能问题,学习QT中回调函数的使用,尽量用回调函数代替信号和槽


From 65563905077e17f8afde68cf43fc30054a44bd99 Mon Sep 17 00:00:00 2001
From: Jianjun Kong <kongj...@gmail.com>
Date: Sat, 10 May 2008 10:48:38 +0800
Subject: [PATCH] update of send message


1. 通过QHostAddress来区分不同主机,实现userlist与窗口用户的对应关系
2. 增加了一些对ip地址、用户名的处理
3. 更新类图,把近期修改添加了上去


Signed-off-by: Jianjun Kong <kongj...@gmail.com>
---
TODO | 10 ++++------

doc/pigeons.png | Bin 0 -> 36970 bytes
src/main.cpp | 6 +++---
src/mainWindow.cpp | 26 ++++++++++++++++++--------
src/mainWindow.h | 2 +-
src/serve.cpp | 16 ++++++++++------
src/subWindow.cpp | 16 ++++++++++------
src/subWindow.h | 2 +-
src/zh_CN.ts | 8 ++++----
9 files changed, 51 insertions(+), 35 deletions(-)
create mode 100644 doc/pigeons.png

diff --git a/TODO b/TODO
index cc5cf66..2c9bbdc 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,5 @@
1. 把近期对pigeons设计上的一些调整,修改到类图上,这样可以帮助其他人了解项目
-2. 对类图方法做详细描述
-3. 规范代码,使用git维护
-4. 对飞鸽协议的具体交互做深入理解
-5. 实现userlist与窗口用户的一一对应关系,通过QHostAddress来区分不同主机;考虑在用户上线是边创建subWindow对象,用户双击头像是只是显示窗口
-6. Makefile暂时性使用qmake自动生成的,等程序发布时,需要写个configure的脚本,自动生成Makefile,方便用户编译、安装
-7. 考虑到性能问题,学习QT中回调函数的使用,尽量用回调函数代替信号和槽
+2. 对飞鸽协议的具体交互做深入理解,特别是commond字段的参数组合
+3. 划分任务,集体参与
+4. 考虑在用户上线是边创建subWindow对象,用户双击头像是只是显示窗口
+5. 考虑到性能问题,学习QT中回调函数的使用,尽量用回调函数代替信号和槽
diff --git a/doc/pigeons.png b/doc/pigeons.png
new file mode 100644
index 0000000000000000000000000000000000000000..97f01e9368cc55b4ca4d47de58b1baaf91b27a32
GIT binary patch
literal 36970
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

literal 0
Hc$@<O00001

diff --git a/src/main.cpp b/src/main.cpp
index cf578b8..d43205a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -19,9 +19,9 @@ int main( int argc, char *argv[])
QApplication app( argc, argv);

//加载翻译文件
- //QTranslator translator;
- //translator.load(":/data/zh_CN");
- //app.installTranslator(&translator);
+ QTranslator translator;
+ translator.load(":/data/zh_CN");
+ app.installTranslator(&translator);

MainWindow mainwindow;
mainwindow.show();
diff --git a/src/mainWindow.cpp b/src/mainWindow.cpp
index a1ca91f..e2e159a 100644
--- a/src/mainWindow.cpp
+++ b/src/mainWindow.cpp
@@ -68,8 +68,10 @@ void MainWindow::showuserlist()
foreach(QString str, sublist)
{
qDebug()<<"User:"<<str;
- QStringList s=str.split(":");
- userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),s.at(1),userListWidget);
+ //QStringList s=str.split(":");
+ //QStringList s=str.split(":");
+ //userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),s.at(1),userListWidget);
+ userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"), str, userListWidget);
//userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),u.toString,userListWidget);
}

@@ -82,10 +84,15 @@ void MainWindow::showuserlist()

}

-void MainWindow::addSub()
+void MainWindow::addSub(QListWidgetItem *u)
{
- QHostAddress addr=QHostAddress::LocalHost;
- sub = new SubWindow(service,addr);
+ //QHostAddress addr=QHostAddress::LocalHost;
+ //QHostAddress addr=u.text();
+ qDebug()<<"u->text:"<<u->text();
+ /*QStringList s=(u->text()).split(":");
+ QHostAddress addr=(QHostAddress)s.at(0);
+ qDebug()<<"s.at(0) address:"<<s.at(0);*/
+ sub = new SubWindow(service,u->text());
sub->show();
}

@@ -97,9 +104,12 @@ void MainWindow::delSub()
void MainWindow::addUserList(MsgMng *msg)
//void MainWindow::addUserList(QHostAddress addr,QString username)
{
- if(usercount<1)
+ //if(usercount<1){
//if(msg->username == "ubuntu")
- qDebug()<<"Don't Add Localhost to UserList";
+ QHostInfo info=QHostInfo::fromName("localhost");
+ if(usercount<1 && info.addresses().indexOf(msg->address)){
+ qDebug()<<"Don't Add Localhost to UserList";
+ }
else
{
qDebug()<<"AddUserList:"<<msg->address<<":"<<msg->username;
@@ -323,7 +333,7 @@ void MainWindow::initWindow()
QListWidgetItem::QListWidgetItem(QListWidget*, int)*/
userListWidget->setMinimumSize(190,420);
userListWidget->setMaximumSize(200,600);
- connect(userListWidget, SIGNAL(itemDoubleClicked (QListWidgetItem*)),this,SLOT(addSub()));//
+ connect(userListWidget, SIGNAL(itemDoubleClicked (QListWidgetItem*)),this,SLOT(addSub(QListWidgetItem *)));//

//退出按钮


quitButton = new QPushButton(tr("&Quit"),messageWindow);

diff --git a/src/mainWindow.h b/src/mainWindow.h
index d0fa9b0..460c1cc 100644
--- a/src/mainWindow.h
+++ b/src/mainWindow.h
@@ -88,7 +88,7 @@ class MainWindow : public QWidget
QPushButton cfgAllButton;
private slots:
void initServer();
- void addSub();
+ void addSub(QListWidgetItem *u);
void delSub();
void addUserList(MsgMng *msg);
void delUserList();
diff --git a/src/serve.cpp b/src/serve.cpp
index d75312e..76f0b5a 100644
--- a/src/serve.cpp
+++ b/src/serve.cpp
@@ -69,13 +69,17 @@ void Serve::sendUdp(MsgMng *msg)


qDebug()<<"Packetno:"<<msg->packetno;
qDebug()<<"Command:"<<msg->command;
qDebug()<<"Extend:"<<msg->extend;
-

- if(msg->address==QHostAddress::LocalHost){
- emit msgSendMsg(msg);
- qDebug()<<"sendUdp---to localhost";
- return;
+ QHostInfo info=QHostInfo::fromName("localhost");
+ if (!info.addresses().isEmpty()) {
+ //qDebug()<<info.addresses().first();
+ //if(msg->address==info.addresses().first()){
+ if(info.addresses().indexOf(msg->address)){


+ emit msgSendMsg(msg);
+ qDebug()<<"sendUdp---to localhost";
+ return;
+ }
}

-


+
QByteArray datagram;
datagram.append(QString("%1:%2:%3:%4:%5:%6")

.arg(msg->version)
diff --git a/src/subWindow.cpp b/src/subWindow.cpp
index ec58fdd..ef2b5b9 100644
--- a/src/subWindow.cpp
+++ b/src/subWindow.cpp
@@ -1,12 +1,16 @@
#include "subWindow.h"

//构造函数,初始化登录窗口
-SubWindow::SubWindow(Serve *ser, QHostAddress addr)
+SubWindow::SubWindow(Serve *ser, QString str)


{
initialize();
service = ser;
msgmng = new MsgMng;

- msgmng->address = addr;
+
+ QStringList s=str.split(":");
+ qDebug()<<"s.at(0) address:"<<s.at(0);
+ msgmng->username = s.at(1);
+ msgmng->address = (QHostAddress)s.at(0);


connect(service, SIGNAL(msgSendMsg(MsgMng *)) , this, SLOT(showMessage(MsgMng *)));
}

@@ -14,7 +18,7 @@ void SubWindow::showMessage(MsgMng *msg)


{
qDebug()<<"["<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")<<"] "<<msg->username<<":\n"<<msg->extend;

recordTextEdit->append("[" + QDateTime::currentDateTime().toString(tr("yyyy-MM-dd hh:mm:ss"))

- + tr("] ") +msg->username);
+ + tr("] ") +msg->username+" :");
recordTextEdit->append(msg->extend);
}

@@ -34,16 +38,16 @@ void SubWindow::closeEvent(QCloseEvent *event)


void SubWindow::sendMessage()
{
message = inputTextEdit->toHtml();

- qDebug()<<"mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmessage:"<<message;


recordTextEdit->append("[" + QDateTime::currentDateTime().toString(tr("yyyy-MM-dd hh:mm:ss"))

- + tr("] ") +tr("konogve:") +message);
+ + tr("] ") +tr("konogve :") +message);


//connect(fontComboBox, SIGNAL(activated(const QString &)),inputTextEdit, SLOT(setFontFamily(const QString &)));
MsgMng *msg = new MsgMng;
msg->command=IPMSG_SENDMSG;
msg->extend=message;

msg->address=msgmng->address;


//QString str=msg->address.toString()+":"+msg->username;

- //msg->address=getAddress(str);
+ qDebug()<<"sendMessage() msgmng->address"<<msgmng->address;
+ qDebug()<<"sendMessage() msg->address"<<msg->address;


service->sendUdp(msg);
qDebug()<<"End of sendUdp";
//清除发送框
diff --git a/src/subWindow.h b/src/subWindow.h

index 251f2e5..efbdf84 100644


--- a/src/subWindow.h
+++ b/src/subWindow.h
@@ -20,7 +20,7 @@ class SubWindow : public QDialog
Q_OBJECT

public:

- SubWindow(Serve *ser,QHostAddress addr);
+ SubWindow(Serve *ser,QString str);


Serve *service;
MsgMng *msgmng;
public slots:

diff --git a/src/zh_CN.ts b/src/zh_CN.ts
index aa1a545..47d55cc 100644
--- a/src/zh_CN.ts
+++ b/src/zh_CN.ts
@@ -1,6 +1,6 @@
<!DOCTYPE TS><TS>
<context>
- <name>MainWindow</name>
+ <name>SubWindow</name>
<message>
<source>Please input your nickname</source>
<translation>请输入您在聊天室的昵称:</translation>
@@ -20,8 +20,8 @@
<message>
<source>About application</source>
<translation>肥鸽子 0.1 版
-<byte value="x9"/>崇日改编制作
-<byte value="x9"/>06年4月20日</translation>
+<byte value="x9"/>Xiyou-Linux-Group改编制作
+<byte value="x9"/>2008年4月20日</translation>
</message>
<message>
<source>yyyy-MM-dd hh:mm:ss</source>
@@ -40,7 +40,7 @@
<byte value="x9"/></translation>
</message>
<message>
- <source>localqq</source>
+ <source>Pigeons</source>
<translation>局域网聊天室 0.1版</translation>
</message>
<message>
--
1.5.2.5

Jianjun Kong

unread,
May 14, 2008, 2:11:55 AM5/14/08
to chongri zhao, aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, xiyou...@googlegroups.com

周四对pigeons做详细讲解

Fix a bug of recognize localhost.

From 9e5d9b91e6532a7af221eb5adebcf049a1d66766 Mon Sep 17 00:00:00 2001
From: Jianjun Kong <kongj...@gmail.com>
Date: Wed, 14 May 2008 14:08:45 +0800
Subject: [PATCH] fix a bug of recognize localhost

fix-a-bug-of-recognize-localhost

Signed-off-by: Jianjun Kong <kongj...@gmail.com>
---

src/mainWindow.cpp | 6 +++---
src/serve.cpp | 10 +++++++++-
2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/mainWindow.cpp b/src/mainWindow.cpp
index e2e159a..17cf3e4 100644
--- a/src/mainWindow.cpp
+++ b/src/mainWindow.cpp
@@ -107,11 +107,11 @@ void MainWindow::addUserList(MsgMng *msg)


//if(usercount<1){
//if(msg->username == "ubuntu")

QHostInfo info=QHostInfo::fromName("localhost");

- if(usercount<1 && info.addresses().indexOf(msg->address)){
+ /*if( 0 && usercount<1 && info.addresses().indexOf(msg->address)){


qDebug()<<"Don't Add Localhost to UserList";
}

else
- {
+ {*/


qDebug()<<"AddUserList:"<<msg->address<<":"<<msg->username;

//userListWidgetItem = new QListWidgetItem(QIcon(":/data/openimage.png"), msg->username, userListWidget);
QString str=msg->address.toString()+":"+msg->username;
@@ -125,7 +125,7 @@ void MainWindow::addUserList(MsgMng *msg)

//userstringlist << msg->username;
//hostStringList << msg->address;
- }
+ //}
//qDebug()<<"msg->address:"<<msg->address<<" LocalHost:"<< fromName("localhost");
usercount++;
showuserlist();
diff --git a/src/serve.cpp b/src/serve.cpp
index 76f0b5a..f7108f9 100644
--- a/src/serve.cpp
+++ b/src/serve.cpp
@@ -70,10 +70,18 @@ void Serve::sendUdp(MsgMng *msg)


qDebug()<<"Command:"<<msg->command;
qDebug()<<"Extend:"<<msg->extend;

QHostInfo info=QHostInfo::fromName("localhost");

+ foreach(QHostAddress addr, info.addresses())
+ {
+ qDebug()<<"Localhost-Address:"<<addr;
+ }
+
if (!info.addresses().isEmpty()) {
//qDebug()<<info.addresses().first();
//if(msg->address==info.addresses().first()){
- if(info.addresses().indexOf(msg->address)){
+ qDebug()<<"info.addresses().indexOf(msg->address)= "<< info.addresses().indexOf(msg->address) ;
+ //if(info.addresses().indexOf(msg->address)!=-1){
+ //if(msg->address==QHostAddress("192.168.21.35")) {
+ if(msg->address==msgmng->address) {


emit msgSendMsg(msg);
qDebug()<<"sendUdp---to localhost";
return;

--
1.5.2.5


--
| Feel Earthquake, Feel Fright!

Jianjun Kong

unread,
May 15, 2008, 11:22:45 AM5/15/08
to chongri zhao, aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, xiyou...@googlegroups.com, Wang-Yagang
实现了和windows下飞鸽传书的消息通信功能,还可能存在一下bug需要修补。
大的飞跃呀~

From 1bc080661e57221ceebd56267b2b1fe55e810c8b Mon Sep 17 00:00:00 2001
From: Jianjun Kong <kongj...@gmail.com>
Date: Thu, 15 May 2008 23:18:27 +0800
Subject: [PATCH] Realizate communicate with WinIpMsg

Realizate communicate with IpMsg in Windows system through messages.

Signed-off-by: Jianjun Kong <kongj...@gmail.com>
---

TODO | 1 +
src/serve.cpp | 34 +++++++++++++++++++++++++++++++---
src/subWindow.cpp | 9 ++++++---
3 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/TODO b/TODO
index 2c9bbdc..2b9ab1c 100644
--- a/TODO
+++ b/TODO
@@ -3,3 +3,4 @@


3. 划分任务,集体参与
4. 考虑在用户上线是边创建subWindow对象,用户双击头像是只是显示窗口
5. 考虑到性能问题,学习QT中回调函数的使用,尽量用回调函数代替信号和槽

+6. 修复bug,考虑增加传输文件
diff --git a/src/serve.cpp b/src/serve.cpp
index f7108f9..501c9a6 100644
--- a/src/serve.cpp
+++ b/src/serve.cpp
@@ -70,6 +70,7 @@ void Serve::sendUdp(MsgMng *msg)


qDebug()<<"Command:"<<msg->command;
qDebug()<<"Extend:"<<msg->extend;
QHostInfo info=QHostInfo::fromName("localhost");

+ //QHostInfo info=QHostInfo::fromName(QHostInfo::localHostName());
foreach(QHostAddress addr, info.addresses())
{
qDebug()<<"Localhost-Address:"<<addr;
@@ -81,6 +82,9 @@ void Serve::sendUdp(MsgMng *msg)
qDebug()<<"info.addresses().indexOf(msg->address)= "<< info.addresses().indexOf(msg->address) ;
//if(info.addresses().indexOf(msg->address)!=-1){
//if(msg->address==QHostAddress("192.168.21.35")) {
+ qDebug()<<"msg->address:"<<msg->address;
+ qDebug()<<"msgmng->address:"<<msgmng->address;


+
if(msg->address==msgmng->address) {
emit msgSendMsg(msg);
qDebug()<<"sendUdp---to localhost";

@@ -125,7 +129,7 @@ void Serve::receiveUdp()
datagram.resize(udpSocket->pendingDatagramSize());
udpSocket->readDatagram(datagram.data(), datagram.size(), &addr, &port);
qDebug()<<"Ip:Port "<<addr<<":"<<port;
- msgmng->address=addr;
+ //msgmng->address=addr;
//开始解码


int receiveVersion = 1; //保存解码数据包版本

unsigned long receivePacketno = 0; //保存数据包的编号

@@ -133,7 +137,6 @@ void Serve::receiveUdp()


QString receiveHostname = NULL; //保存解码数据包后的主机名

unsigned long receiveCommand = 0; //保存命令字

QString receiveExtend = NULL; //保存附加信息

-
if(!datagram.isEmpty())
{


QList<QByteArray> list=datagram.split (':');

@@ -142,6 +145,7 @@ void Serve::receiveUdp()
switch(j)
{


case 0:receiveVersion = atoi(i.next());break;

+ //case 1:receivePacketno = atoi(stringPacketno=i.next());break;


case 1:receivePacketno = atoi(i.next());break;

case 2:receiveUsername = i.next();break;

case 3:receiveHostname = i.next();break;

@@ -158,16 +162,23 @@ void Serve::receiveUdp()
qDebug()<<"Version:"<<receiveVersion;
qDebug()<<"Packetno:"<<receivePacketno;
qDebug()<<"Extend:"<<receiveExtend;*/
-
+ if(receiveUsername==QHostInfo::localHostName())
+ {
+ msgmng->address=addr;
+ }
unsigned long recvCmd;
unsigned long recvOpt;
recvCmd=GET_MODE(receiveCommand);
+ qDebug()<<"recvCmd:"<<recvCmd;
recvOpt=GET_OPT(receiveCommand);
+ qDebug()<<"recvOpt:"<<recvOpt;

MsgMng *msg;
msg = msgmng->makeMng(receiveUsername, receiveHostname, receiveCommand, receiveExtend, addr);


//msg = makeMsg(receiveFlag, receiveBag,receiveUserName,receiveHostName, receiveCmd, receiveExtend);

+ QByteArray datagramm;
+
switch (recvCmd)
{
case IPMSG_BR_ENTRY:
@@ -188,6 +199,23 @@ void Serve::receiveUdp()

case IPMSG_SENDMSG:
emit msgSendMsg(msg);
+
+ // msg=msgmng->makeMng((QHostInfo::localHostName()),(QHostInfo::localHostName()), 33, (QString)receivePacketno, addr);
+ msg->username="linux-desktop";
+ msg->hostname="linux-desktop";
+ msg->address=addr;
+ msg->command=33;
+
+
+ datagramm.append(QString("%1:%2:%3:%4:%5:%6")
+ .arg(msg->version)
+ .arg(receivePacketno)


+ .arg(msg->username)
+ .arg(msg->hostname)
+ .arg(msg->command)

+ .arg(receivePacketno));
+ qDebug()<<"SSSSendUdp:"<<datagramm;
+ udpSocket->writeDatagram(datagramm.data(), (qint64)datagramm.size(),msg->address, IPMSG_DEFAULT_PORT);
break;

case IPMSG_RECVMSG:
diff --git a/src/subWindow.cpp b/src/subWindow.cpp
index ef2b5b9..cbaf2dc 100644
--- a/src/subWindow.cpp
+++ b/src/subWindow.cpp
@@ -37,12 +37,15 @@ void SubWindow::closeEvent(QCloseEvent *event)
//发送消息
void SubWindow::sendMessage()
{
- message = inputTextEdit->toHtml();
+ //message = inputTextEdit->toHtml();
+ message = inputTextEdit->toPlainText();


recordTextEdit->append("[" + QDateTime::currentDateTime().toString(tr("yyyy-MM-dd hh:mm:ss"))
- + tr("] ") +tr("konogve :") +message);

+ + tr("] ") + (QHostInfo::localHostName())+tr(":\n") +message);


//connect(fontComboBox, SIGNAL(activated(const QString &)),inputTextEdit, SLOT(setFontFamily(const QString &)));
MsgMng *msg = new MsgMng;

- msg->command=IPMSG_SENDMSG;
+ //msg->command=IPMSG_SENDMSG;
+ msg->command=288;
+ //msg->command=33;


msg->extend=message;
msg->address=msgmng->address;
//QString str=msg->address.toString()+":"+msg->username;

--
1.5.2.5

Jianjun Kong

unread,
May 16, 2008, 1:35:02 AM5/16/08
to chongri zhao, aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, xiyou...@googlegroups.com, Wang-Yagang

1. 用户下线时,关闭updSocket,释放资源,并广播”IPMSG_BR_EXIT“,提示其他;
2. 处理其他用户下线,从用户列表中删除;

TODO:
1. 未双击打开窗口前,接收到消息后,创建子窗口;
2. 中文传输乱码问题;
3. 区分版本,对pigeons采用Html文本传输,这样可以控制样式;


From 83038b1578498ef5733b4793fd92be2e8e737de9 Mon Sep 17 00:00:00 2001
From: Jianjun Kong <kongj...@gmail.com>
Date: Fri, 16 May 2008 13:32:26 +0800
Subject: [PATCH] update of exit

1. 用户下线时,关闭 updSocket,释放资源,并广播”IPMSG_BR_EXIT“,提示其他;
2. 处理其他用户下线,从用户列表中删除;

Signed-off-by: Jianjun Kong <kongj...@gmail.com>
---

TODO | 14 ++++++++------
src/mainWindow.cpp | 41 +++++++++++++++++++++++++++++++++++++++--
src/mainWindow.h | 2 +-
src/serve.cpp | 9 ++++-----
src/serve.h | 3 ++-
src/subWindow.cpp | 5 +++--
6 files changed, 57 insertions(+), 17 deletions(-)

diff --git a/TODO b/TODO
index 2b9ab1c..efa9ee4 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,8 @@
-1. 把近期对pigeons设计上的一些调整,修改到类图上,这样可以帮助其他人了解项目
-2. 对飞鸽协议的具体交互做深入理解,特别是commond字段的参数组合
-3. 划分任务,集体参与
-4. 考虑在用户上线是边创建subWindow对象,用户双击头像是只是显示窗口
-5. 考虑到性能问题,学习QT中回调函数的使用,尽量用回调函数代替信号和槽
-6. 修复bug,考虑增加传输文件
+
+1. 未双击打开窗口前,接收到消息后,创建子窗口,考虑在用户上线是边创建subWindow对象,用户双击头像是只是显示窗口;
+2. 中文传输乱码问题;
+3. 区分版本,对pigeons采用Html文本传输,这样可以控制样式;
+4. 把近期对pigeons设计上的一些调整,修改到类图上,这样可以帮助其他人了解项目
+5. 对飞鸽协议的具体交互做深入理解,特别是commond字段的参数组合
+6. 考虑到性能问题,学习QT中回调函数的使用,尽量用回调函数代替信号和槽
+7. 修复bug,考虑增加传输文件
diff --git a/src/mainWindow.cpp b/src/mainWindow.cpp
index 17cf3e4..eeb5da0 100644
--- a/src/mainWindow.cpp
+++ b/src/mainWindow.cpp
@@ -22,6 +22,7 @@ MainWindow::MainWindow()
usercount = 0;
initUp();
connect(service, SIGNAL(addUser(MsgMng *)) , this, SLOT(addUserList(MsgMng *)));
+ connect(service, SIGNAL(msgBrExit(MsgMng *)) , this, SLOT(delUserList(MsgMng *)));
}

void MainWindow::initServer()
@@ -57,6 +58,12 @@ void MainWindow::initUp()

void MainWindow::exit()
{
+ /*MsgMng *msg = new MsgMng;
+ msg->command = IPMSG_BR_EXIT;
+ msg->extend="";
+ service->broadcast(6291458, NULL);
+ //接受信号,执行退出
+ event->accept();*/

}
void MainWindow::showuserlist()
@@ -71,7 +78,7 @@ void MainWindow::showuserlist()
//QStringList s=str.split(":");
//QStringList s=str.split(":");

//userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),s.at(1),userListWidget);

- userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"), str, userListWidget);
+ userListWidgetItem = new QListWidgetItem(QIcon(":/data/openimage.png"), str, userListWidget);


//userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),u.toString,userListWidget);
}

@@ -119,6 +126,7 @@ void MainWindow::addUserList(MsgMng *msg)
if(!s.compare(str))
return ;

+ qDebug()<<"sublist.insert(usercount, str):"<<usercount<<"++"<<str;
sublist.insert(usercount, str);
//sublist.insert(usercount, msg->address.toString());
//sublist.insert(msg->address, msg->username+":"+usercount);
@@ -132,9 +140,32 @@ void MainWindow::addUserList(MsgMng *msg)

}

-void MainWindow::delUserList()
+void MainWindow::delUserList(MsgMng *msg)
{
+ QString str=msg->address.toString()+":"+msg->username;
+ int i=0;
+ foreach(QString s, sublist)
+ {
+ qDebug()<<"i:"<<i;
+ if(!s.compare(str))
+ {
+ sublist.remove(i);
+ usercount--;
+ qDebug()<<"sublist.remove(i):"<<str<<"++"<<i;
+ }
+ i++;
+ }
+ //qDebug()<<"sublist[str]:"<<sublist[str];
+ /*sublist.remove(sublist.(str));
+ sublist.remove(0);
+ sublist.remove(1);
+ sublist.remove(2);*/

+ showuserlist();
+ /*foreach(QString s, sublist)
+ if(!s.compare(str))
+ return ;*/
+ qDebug()<<"delUserList()---------------";
}

/*
@@ -153,6 +184,11 @@ void MainWindow::recvTcp()

void MainWindow::closeEvent(QCloseEvent *event)
{
+ qDebug()<<"closeEvent()------------------------------------";
+ MsgMng *msg = new MsgMng;
+ msg->command = IPMSG_BR_EXIT;
+ msg->extend="";
+ service->broadcast(6291458, NULL);
//service->broadcast(IPMSG_BR_EXIT, NULL);
event->accept();
}
@@ -335,6 +371,7 @@ void MainWindow::initWindow()
userListWidget->setMaximumSize(200,600);


connect(userListWidget, SIGNAL(itemDoubleClicked (QListWidgetItem*)),this,SLOT(addSub(QListWidgetItem *)));//

+


//退出按钮
quitButton = new QPushButton(tr("&Quit"),messageWindow);

connect(quitButton,SIGNAL(clicked()), this, SLOT(close()));
diff --git a/src/mainWindow.h b/src/mainWindow.h
index 460c1cc..0b9d6c1 100644
--- a/src/mainWindow.h
+++ b/src/mainWindow.h
@@ -91,7 +91,7 @@ class MainWindow : public QWidget


void addSub(QListWidgetItem *u);
void delSub();
void addUserList(MsgMng *msg);

- void delUserList();
+ void delUserList(MsgMng *msg);
//void recvUdp();
//void recvTcp();

diff --git a/src/serve.cpp b/src/serve.cpp
index 501c9a6..ea9892b 100644
--- a/src/serve.cpp
+++ b/src/serve.cpp
@@ -186,7 +186,7 @@ void Serve::receiveUdp()
break;

case IPMSG_BR_EXIT:
- msgBrExit(msg);
+ emit msgBrExit(msg);
break;

case IPMSG_ANSENTRY:
@@ -351,9 +351,9 @@ void Serve::msgBrEntry(MsgMng *msg)
userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),msg->hostSub.userName,userListWidget);
} */
}
-void Serve::msgBrExit(MsgMng *msg)
+/*void Serve::msgBrExit(MsgMng *msg)
{
-/*
+
for( int count = 0; count < hostStringList->size(); count ++)
{
if( (msg->hostSub.hostName == hostStringList->at(count))
@@ -368,8 +368,7 @@ void Serve::msgBrExit(MsgMng *msg)
recordTextEdit->append( "\n[ " + QDateTime::currentDateTime().toString(tr("yyyy-MM-dd hh:mm:ss"))
+ tr(" ] System information \n\t") + msg->hostSub.userName);

-*/
-}
+}*/
void Serve::msgAnsEntry(MsgMng *msg)
{
emit addUser(msg);
diff --git a/src/serve.h b/src/serve.h
index 0b9aa7d..dfb3b3d 100644
--- a/src/serve.h
+++ b/src/serve.h
@@ -25,6 +25,7 @@ public slots:
void receiveUdp();
void receiveTcp();
signals:
+ void msgBrExit(MsgMng *msg);
void msgSendMsg(MsgMng *msg);
void addUser(MsgMng *msg);
public:
@@ -32,7 +33,7 @@ public:
QUdpSocket *udpSocket;
Serve();
void msgBrEntry(MsgMng *msg);
- void msgBrExit(MsgMng *msg);
+
void msgAnsEntry(MsgMng *msg);
void msgBrAbsence(MsgMng *msg);

diff --git a/src/subWindow.cpp b/src/subWindow.cpp
index cbaf2dc..f84007f 100644
--- a/src/subWindow.cpp
+++ b/src/subWindow.cpp
@@ -26,12 +26,13 @@ void SubWindow::showMessage(MsgMng *msg)
void SubWindow::closeEvent(QCloseEvent *event)
{
//广播用户注销信息
- MsgMng *msg = new MsgMng;
+ /*MsgMng *msg = new MsgMng;
msg->command = IPMSG_BR_EXIT;
msg->extend="";
- service->broadcast(6291458, NULL);
+ service->broadcast(6291458, NULL);*/
//接受信号,执行退出
event->accept();
+ service->udpSocket->close();
}

//发送消息
--
1.5.2.5

Jianjun Kong

unread,
May 16, 2008, 8:17:26 AM5/16/08
to chongri zhao, aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, xiyou...@googlegroups.com
From 4d87c2a2344bc5e6207cf404cc96d2df7e6db448 Mon Sep 17 00:00:00 2001
From: Jianjun Kong <kongj...@gmail.com>
Date: Fri, 16 May 2008 20:14:24 +0800
Subject: [PATCH] add subislist

1、利用QMap::subislist<QString, int>来存放子窗口创建标志位,1为创建,0为未创建;
2、利用subislist,保证未创建子窗口前接收到消息,则自动创建;若已创建这利用之完成消息通信;子窗口退出后则标志为清零,使得后面可利用双击、或接收消息来创建子窗口;
3、在subWindow中添加delSub信号,当子窗口退出时,发送信号;槽放在mainWindow里,通过调用这个槽实现标志位清零。

Signed-off-by: Jianjun Kong <kongj...@gmail.com>
---

TODO | 9 ++-----
src/mainWindow.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++---------
src/mainWindow.h | 4 ++-
src/serve.cpp | 2 +
src/subWindow.cpp | 6 ++++-
src/subWindow.h | 2 +
6 files changed, 62 insertions(+), 19 deletions(-)

diff --git a/TODO b/TODO
index efa9ee4..234f621 100644
--- a/TODO
+++ b/TODO
@@ -1,8 +1,5 @@
-
-1. 未双击打开窗口前,接收到消息后,创建子窗口,考虑在用户上线是边创建subWindow对象,用户双击头像是只是显示窗口;
+1. 变量、socket的那天资源的释放;


2. 中文传输乱码问题;
3. 区分版本,对pigeons采用Html文本传输,这样可以控制样式;

-4. 把近期对pigeons设计上的一些调整,修改到类图上,这样可以帮助其他人了解项目
-5. 对飞鸽协议的具体交互做深入理解,特别是commond字段的参数组合
-6. 考虑到性能问题,学习QT中回调函数的使用,尽量用回调函数代替信号和槽
-7. 修复bug,考虑增加传输文件
+4. 对飞鸽协议的具体交互做深入理解,特别是commond字段的参数组合
+5. 修复bug,考虑增加传输文件
diff --git a/src/mainWindow.cpp b/src/mainWindow.cpp
index eeb5da0..cf29d3c 100644


--- a/src/mainWindow.cpp
+++ b/src/mainWindow.cpp
@@ -22,6 +22,7 @@ MainWindow::MainWindow()
usercount = 0;
initUp();
connect(service, SIGNAL(addUser(MsgMng *)) , this, SLOT(addUserList(MsgMng *)));
+
connect(service, SIGNAL(msgBrExit(MsgMng *)) , this, SLOT(delUserList(MsgMng *)));
}

@@ -81,14 +82,6 @@ void MainWindow::showuserlist()


userListWidgetItem = new QListWidgetItem(QIcon(":/data/openimage.png"), str, userListWidget);
//userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),u.toString,userListWidget);
}

-
- /*userListWidgetItem = new QListWidgetItem(QIcon(":/data/openimage.png"),"kongove",userListWidget);
- userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),"zhaochongri",userListWidget);
- userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),"mei",userListWidget);
- userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),"gaohui",userListWidget);
- userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),"lilei",userListWidget);
- userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),"wangcong",userListWidget);*/
-
}

void MainWindow::addSub(QListWidgetItem *u)
@@ -99,13 +92,23 @@ void MainWindow::addSub(QListWidgetItem *u)
/*QStringList s=(u->text()).split(":");
QHostAddress addr=(QHostAddress)s.at(0);


qDebug()<<"s.at(0) address:"<<s.at(0);*/

- sub = new SubWindow(service,u->text());
- sub->show();
+ QString str=u->text();
+ qDebug()<<"str:"<<str;
+ if(subislist[str]!=1)
+ {
+ sub = new SubWindow(service, u->text());
+ connect(sub , SIGNAL(delSub(QString)) , this, SLOT(delSub(QString)));
+ sub->show();
+ subislist[str]=1;
+ }
}

-void MainWindow::delSub()
+void MainWindow::delSub(QString str)
{

+ qDebug()<<"MainWindow::delSub(QString str)";
+ subislist[str]=0;
+
}

void MainWindow::addUserList(MsgMng *msg)
@@ -122,12 +125,45 @@ void MainWindow::addUserList(MsgMng *msg)


qDebug()<<"AddUserList:"<<msg->address<<":"<<msg->username;

//userListWidgetItem = new QListWidgetItem(QIcon(":/data/openimage.png"), msg->username, userListWidget);


QString str=msg->address.toString()+":"+msg->username;

+ qDebug()<<"AddUserList: msg->command:"<<msg->command;
+ qDebug()<<"subislist[str1]:" << subislist[str];
+ /*foreach((int i, subislist)
+ {
+ if(subislist[str]==0) //subWindows is not exist
+ {
+ //qDebug()<<"sublist.insert(usercount, str):"<<usercount<<"++"<<str;
+ }
+ else
+ {
+ // sub = new SubWindow(service,str);
+ subislist.insert(str, 0);
+ }
+ }*/
+
+ if(msg->command==288)
+ {
+ /*foreach(int i, subislist)
+ {*/
+ if(subislist[str]==0) //subWindows is not exist
+ {
+ //qDebug()<<"sublist.insert(usercount, str):"<<usercount<<"++"<<str;
+ sub = new SubWindow(service,str);
+ connect(sub , SIGNAL(delSub(QString)) , this, SLOT(delSub(QString)));
+ sub->show();
+ subislist[str]=1;
+ }
+ //}
+ }
+
foreach(QString s, sublist)
if(!s.compare(str))
return ;



qDebug()<<"sublist.insert(usercount, str):"<<usercount<<"++"<<str;
sublist.insert(usercount, str);

+ subislist.insert(str, 0);
+ qDebug()<<"subislist[str2]:" << subislist[str];
+


//sublist.insert(usercount, msg->address.toString());
//sublist.insert(msg->address, msg->username+":"+usercount);

diff --git a/src/mainWindow.h b/src/mainWindow.h
index 0b9d6c1..c3cf9c3 100644
--- a/src/mainWindow.h
+++ b/src/mainWindow.h
@@ -45,6 +45,7 @@ class MainWindow : public QWidget
QListWidget *userListWidget;
QListWidgetItem *userListWidgetItem;
QMap <int, QString> sublist;//hostaddress, username:usercount
+ QMap <QString, int> subislist;//
//QMap <QHostAddress , QString> sublist;//hostaddress, username:usercount
CfgAllDialog cfgall;
Serve *service;
@@ -82,6 +83,7 @@ class MainWindow : public QWidget
void enabledSendButton();
//关于
void about();
+ void delSub(QString str);
private:
SubWindow *sub;

@@ -89,7 +91,7 @@ class MainWindow : public QWidget
private slots:
void initServer();
void addSub(QListWidgetItem *u);
- void delSub();
+
void addUserList(MsgMng *msg);


void delUserList(MsgMng *msg);
//void recvUdp();

diff --git a/src/serve.cpp b/src/serve.cpp
index ea9892b..02d5f08 100644
--- a/src/serve.cpp
+++ b/src/serve.cpp
@@ -86,6 +86,7 @@ void Serve::sendUdp(MsgMng *msg)
qDebug()<<"msgmng->address:"<<msgmng->address;

if(msg->address==msgmng->address) {
+ //emit addUser(msg);


emit msgSendMsg(msg);
qDebug()<<"sendUdp---to localhost";

return;
@@ -198,6 +199,7 @@ void Serve::receiveUdp()
break;

case IPMSG_SENDMSG:
+ emit addUser(msg);
emit msgSendMsg(msg);



// msg=msgmng->makeMng((QHostInfo::localHostName()),(QHostInfo::localHostName()), 33, (QString)receivePacketno, addr);

diff --git a/src/subWindow.cpp b/src/subWindow.cpp
index f84007f..15672cf 100644
--- a/src/subWindow.cpp
+++ b/src/subWindow.cpp
@@ -30,9 +30,13 @@ void SubWindow::closeEvent(QCloseEvent *event)


msg->command = IPMSG_BR_EXIT;
msg->extend="";

service->broadcast(6291458, NULL);*/
+
+ QString str=msgmng->address.toString()+":"+msgmng->username;
+ emit delSub(str);
+ qDebug()<<"emit delSub(str)";
+ service->udpSocket->close();
//接受信号,执行退出
event->accept();
- service->udpSocket->close();
}

//发送消息
diff --git a/src/subWindow.h b/src/subWindow.h
index efbdf84..ea7b777 100644
--- a/src/subWindow.h
+++ b/src/subWindow.h
@@ -23,6 +23,8 @@ class SubWindow : public QDialog


SubWindow(Serve *ser,QString str);
Serve *service;
MsgMng *msgmng;

+ signals:
+ void delSub(QString str);
public slots:
void showMessage(MsgMng *msg);
//void showMessage(QString msg, QString user);
--
1.5.2.5

Jianjun Kong

unread,
May 24, 2008, 2:02:11 PM5/24/08
to chongri zhao, aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, xiyou...@googlegroups.com
添加选择文件功能

下来需要做的:
1. 测试IPmsg协议对于文件传书的具体交互过程
2. 用QT实现TCP传输、接收文件
3. 进行适当的外网通信测试,尝试利用映射地址进行通信,为Pigeons走向外网做准备。

----
下面第一个是图片,在这里看起来是乱码。

Signed-off-by: Jianjun Kong <kongj...@gmail.com>
---

src/data/file.png | Bin 0 -> 1030 bytes
src/resource.qrc | 1 +
src/subWindow.cpp | 20 ++++++++++++++++++++
src/subWindow.h | 3 +++
4 files changed, 24 insertions(+), 0 deletions(-)
create mode 100644 src/data/file.png

diff --git a/src/data/file.png b/src/data/file.png
new file mode 100644
index 0000000000000000000000000000000000000000..08a45aa2bd3f3ce70abdb28bf8837276b5d38525
GIT binary patch
literal 1030
zc$@(S1o``kP)<h;3K|Lk000e1NJLTq001HY001Be1^@s6caN&c00001b5ch_0Itp)
z=>Px#32;bRa{vGf6951U69E94oEQKA00(qQO+^RT1sD+}8fSqdH~;_xm`OxIR9M69
zmoaY~RTPE4`*vd_YFk0ZR){ME!bZY!L4$&^1t@JAgn%HiSOE$60sN7rauFdRiZm$@
z4T(|#N|XqYMPcG3PC)=61dijKcMrwP&dkov?5?d8De|P%?Atf{-kEdHJ@<}D;!zlZ
zM`SbtSzcMwQPz$+tS&Ss7Eftrc7aH{_D?Mny}iG=e(5WFSU`qOdV1+~Ex)|ZM(0C9
zyVdx|%a^XOwBFH2Z>`aJ@64e9b-&nD=Yw~xk&zRNt9oH&mG?J3=C42Qv3LJplts_X
z=-=CJPcd_RmK)cua`D2~pdL_R);zr`RJ7m(9q_|9n^w!n^2(Z~XBT+;>{))@-sZo(
z1H2@oJ`hQmJz#tH23Nkj%qO3H%EHOHK@26(!(wpm+}dGz{T+4AtkP#D2lC_h-`b0B
zZ0O$ae{%cQE*_2{>KXT#aQ*5vPM?00>8FnK)7Dl+|K4~Fi07Ys7Pl$N;ThD30_V?v
z$v=Dhpn!~Qlk|X;4PiL1z4{6(FD<gYbCVdJz}+#kkwA<Dlw^Cin#DSGti`!=8_dnm
z6M+z*mSKZr|2{iAzmY_61+Y+3Nvq)+@&_83HL-WV{M-z`Z2gSWM%I)J#YV1F6Q11~
zCUBUsK+>HZ!;uZ<K^hh-D9MFc0C1bkKiz$_v&sTd83<``*_3|zcxw)=W5Whug9yYL
zMnaXcK3c1U#RynUMW`M$$r#HBC>LkIFuXCgK`=?>R@LgvCjpY7Rh_cK(CubNC^ZU`
zR9{1$dV$Pxd(R-2Jf)P1`4d-xrt<=9I9%4ar_{Mwc7TtI_{4KVn4F~NL&|CoW(^#~
zghY<Z#-yVkdLHBm=y@E^NQ`ObI4#_qhc*;&gO(tP6NDy-5tk7$e89vCJL$7GnyE09
z=;mp->#}ADNY6!d;W)B@RNc7RXZVEeuV)Y8B#93_NKI%Wi9k4%Y&)o41J(8BIau~v
z&tuu7>)U`Nrp=Eq+?2bKnrcaPJ)6gV{7UPoC5V`4h{0ivBncitC_h-1R@t&P@+UH-
zaW8RQe6@ip9XxHddNHXsmV-c2OE+TXQjtQeq5(*@QtsvoAVuAh3*;y(Bh~Ve1L<}*
zWwFQZ?Ym6RE--mccv0TRHvj<Ky>k=u2Xwoe>U7d}ap=8fX}u$FJvn0A&|p|0W5aXC
z`t3vrp@=OI;yxF;pL6n=c^mnH_4wWQF_6;uA7^U!nvai3M*si-07*qoM6N<$g7)6z
Aj{pDw

literal 0
Hc$@<O00001

diff --git a/src/resource.qrc b/src/resource.qrc
index 5415b1f..c4487cb 100644
--- a/src/resource.qrc
+++ b/src/resource.qrc
@@ -8,5 +8,6 @@
<file>data/textunder.png</file>
<file>data/textcolor.png</file>
<file>data/openimage.png</file>
+ <file>data/file.png</file>
</qresource>
</RCC>
diff --git a/src/subWindow.cpp b/src/subWindow.cpp
index 15672cf..bd90e7e 100644
--- a/src/subWindow.cpp
+++ b/src/subWindow.cpp
@@ -117,6 +117,20 @@ void SubWindow::openImage()
out << imageReader.read();
}

+void SubWindow::selectFile()
+{
+ QString file = QFileDialog::getOpenFileName(this, tr("Select File..."),
+ "~", tr("Image-Files (*)"));
+ //QFile::copy(image, QString("temp-image/") + QFileInfo(image).fileName());
+ if (file.isEmpty())
+ {
+ qDebug()<<"file is empty";
+ return;
+ }
+
+ inputTextEdit->append("Send file: "+QFileInfo(file).fileName());
+
+}
//槽函数,设置字体大小
void SubWindow::setFontSize(const QString &size)
{
@@ -210,6 +224,12 @@ void SubWindow::initialize()
editToolBar->addWidget(imageButton);
imageButton->setIcon(QIcon(":/data/openimage.png"));


connect(imageButton, SIGNAL(clicked()), this, SLOT(openImage()));
+

+ //发送文件
+ fileButton = new QToolButton(editToolBar);
+ editToolBar->addWidget(fileButton);
+ fileButton->setIcon(QIcon(":/data/file.png"));
+ connect(fileButton, SIGNAL(clicked()), this, SLOT(selectFile()));

//发送按钮


sendButton = new QPushButton(tr("&Send"), messageWindow);

diff --git a/src/subWindow.h b/src/subWindow.h
index ea7b777..b3f3f3a 100644
--- a/src/subWindow.h
+++ b/src/subWindow.h
@@ -57,6 +57,7 @@ class SubWindow : public QDialog
QToolButton *underlineButton;
QToolButton *colorButton;
QToolButton *imageButton;
+ QToolButton *fileButton;
private slots:

//初始化聊天室
@@ -69,6 +70,8 @@ class SubWindow : public QDialog
void setFontColor();
//打开图像文件
void openImage();
+ //选择发送文件
+ void selectFile();
//开启发送按钮
void enabledSendButton();
//关于
--
1.5.2.5

Jianjun Kong

unread,
May 24, 2008, 9:10:40 PM5/24/08
to chongri zhao, aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, xiyou...@googlegroups.com
1. 固定了MainWindow的大小
2. 为发送文件获取文件路径
3. 字符转换成UTF-8,解决中文乱码(有待测试)

---
TODO:
1. 经测试,Version字段不同就不能通信,我们可以利用未使用的Hostname字段对 Pigeons 进行区分,比如当 hostname = username+"pigeons" 是则确定其为pigeons。
2. 测试字符编码转换是否有bug
3. 测试IPmsg协议对于文件传书的具体交互过程,先实现发送文件


Signed-off-by: Jianjun Kong <kongj...@gmail.com>
---

TODO | 7 ++++---
src/mainWindow.cpp | 8 +++++---
src/serve.cpp | 29 ++++++++++++++++++++++++-----
src/serve.h | 2 +-
src/subWindow.cpp | 31 +++++++++++++++++++++++++------
src/subWindow.h | 2 +-
6 files changed, 60 insertions(+), 19 deletions(-)

diff --git a/TODO b/TODO
index 234f621..5266de7 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,6 @@
1. 变量、socket的那天资源的释放;
-2. 中文传输乱码问题;
+2. 测试中文传输乱码问题;
3. 区分版本,对pigeons采用Html文本传输,这样可以控制样式;
-4. 对飞鸽协议的具体交互做深入理解,特别是commond字段的参数组合
-5. 修复bug,考虑增加传输文件
+4. 测试IPmsg协议对于文件传书的具体交互过程
+5. 用QT实现TCP传输、接收文件
+6. 进行适当的外网通信测试,尝试利用映射地址进行通信,为Pigeons走向外网做准备。
diff --git a/src/mainWindow.cpp b/src/mainWindow.cpp
index cf29d3c..77aabbc 100644
--- a/src/mainWindow.cpp
+++ b/src/mainWindow.cpp
@@ -305,11 +305,14 @@ void MainWindow::setBoldFont(bool flag)
//初始化聊天室界面和程序基本信息
void MainWindow::initWindow()
{
-
+ resize(220,480);
+ setMinimumSize(220,480);
+ setMaximumSize(220,480);
+
setWindowTitle(tr("Pigeons"));
messageWindow = new QWidget(this);
messageWindow->resize(200,600);
- messageWindow->setMinimumSize(190,600);
+ messageWindow->setMinimumSize(200,600);
messageWindow->setMaximumSize(200,600);
//messageWindow->setWindowTitle(tr("localqq"));

@@ -324,7 +327,6 @@ void MainWindow::initWindow()

editToolBar = new QToolBar(messageWindow);

-
//编辑工具栏上的字体
fontComboBox = new QComboBox(editToolBar);
editToolBar->addWidget(fontComboBox);
diff --git a/src/serve.cpp b/src/serve.cpp
index aed0c36..c0298f8 100644
--- a/src/serve.cpp
+++ b/src/serve.cpp
@@ -93,14 +93,30 @@ void Serve::sendUdp(MsgMng *msg)
}
}

- QByteArray datagram;
+ /*QByteArray datagram;
datagram.append(QString("%1:%2:%3:%4:%5:%6")
.arg(msg->version)
.arg(msg->packetno)
.arg(msg->username)
.arg(msg->hostname)
.arg(msg->command)
- .arg(msg->extend));
+ .arg(msg->extend)); */
+ QByteArray datagram;
+ datagram.append(QString("%1:%2")
+ .arg(msg->version)
+ .arg(msg->packetno));
+
+ QByteArray data2 = msg->username.toUtf8();
+ QByteArray data3 = msg->hostname.toUtf8();
+
+ QByteArray data4;
+ data4.append(QString("%1")
+ .arg(msg->command));
+ QByteArray data5 = msg->extend.toUtf8();
+ datagram += data2;
+ datagram += data3;
+ datagram += data4;
+ datagram += data5;

/*QByteArray *datagram=new QByteArray;
datagram->append(QString("%1:%2:%3:%4:%5:%6")
@@ -203,8 +219,8 @@ void Serve::receiveUdp()


emit msgSendMsg(msg);

// msg=msgmng->makeMng((QHostInfo::localHostName()),(QHostInfo::localHostName()), 33, (QString)receivePacketno, addr);

- msg->username="linux-desktop";
- msg->hostname="linux-desktop";
+ msg->username=QHostInfo::localHostName();
+ msg->hostname=QHostInfo::localHostName();
msg->address=addr;
msg->command=33;
//msg->command=IPMSG_ANSENTRY;
@@ -276,8 +292,11 @@ void Serve::receiveUdp()
}
}
}
-void Serve::sendTcp()
+void Serve::sendTcp(MsgMng *msg, QString file)
{
+ (void)msg;
+ (void)file;
+ qDebug()<<"SendTcp file:"<<file;
/*unsigned long sendCmd;
unsigned long sendOpt;
sendCmd=GET_MODE(sendCommand);
diff --git a/src/serve.h b/src/serve.h
index dfb3b3d..10fd245 100644
--- a/src/serve.h
+++ b/src/serve.h
@@ -21,7 +21,7 @@ public slots:



void broadcast(unsigned long command, QString extend);

void sendUdp(MsgMng *);
- void sendTcp();
+ void sendTcp(MsgMng *, QString);


void receiveUdp();
void receiveTcp();
signals:

diff --git a/src/subWindow.cpp b/src/subWindow.cpp
index bd90e7e..67b4d5e 100644
--- a/src/subWindow.cpp
+++ b/src/subWindow.cpp
@@ -41,9 +41,13 @@ void SubWindow::closeEvent(QCloseEvent *event)

//发送消息
void SubWindow::sendMessage()
-{
+{

+
//message = inputTextEdit->toHtml();

- message = inputTextEdit->toPlainText();


+ message = inputTextEdit->toPlainText();

+ //char *m = inputTextEdit->toPlainText();
+ //message=message.toUtf8();
+ //message = m->fromUtf8(m, -1);
recordTextEdit->append("[" + QDateTime::currentDateTime().toString(tr("yyyy-MM-dd hh:mm:ss"))


+ tr("] ") + (QHostInfo::localHostName())+tr(":\n") +message);
//connect(fontComboBox, SIGNAL(activated(const QString &)),inputTextEdit, SLOT(setFontFamily(const QString &)));

@@ -117,9 +121,9 @@ void SubWindow::openImage()
out << imageReader.read();
}

-void SubWindow::selectFile()
+void SubWindow::sendFile()
{
- QString file = QFileDialog::getOpenFileName(this, tr("Select File..."),
+ QString file = QFileDialog::getOpenFileName(this, tr("Send File..."),


"~", tr("Image-Files (*)"));

//QFile::copy(image, QString("temp-image/") + QFileInfo(image).fileName());

if (file.isEmpty())
@@ -128,7 +132,22 @@ void SubWindow::selectFile()
return;
}

- inputTextEdit->append("Send file: "+QFileInfo(file).fileName());
+ recordTextEdit->append("[" + QDateTime::currentDateTime().toString(tr("yyyy-MM-dd hh:mm:ss"))
+ + tr("] ") + (QHostInfo::localHostName())+tr(":\n") +"Send File: "+file);
+ //inputTextEdit->append("Send file: "+file);
+ //inputTextEdit->append("Send file: "+QFileInfo(file).fileName());


+ MsgMng *msg = new MsgMng;

+ //msg->command=IPMSG_SENDMSG;
+ msg->command=288;
+ //msg->command=33;

+ msg->extend=message;
+ msg->address=msgmng->address;
+ //QString str=msg->address.toString()+":"+msg->username;
+ qDebug()<<"sendMessage() msgmng->address"<<msgmng->address;
+ qDebug()<<"sendMessage() msg->address"<<msg->address;
+ service->sendTcp(msg, file);
+ qDebug()<<"End of sendTcp";
+

}
//槽函数,设置字体大小
@@ -229,7 +248,7 @@ void SubWindow::initialize()
fileButton = new QToolButton(editToolBar);
editToolBar->addWidget(fileButton);
fileButton->setIcon(QIcon(":/data/file.png"));
- connect(fileButton, SIGNAL(clicked()), this, SLOT(selectFile()));
+ connect(fileButton, SIGNAL(clicked()), this, SLOT(sendFile()));



//发送按钮
sendButton = new QPushButton(tr("&Send"), messageWindow);
diff --git a/src/subWindow.h b/src/subWindow.h

index b3f3f3a..0d22d3f 100644
--- a/src/subWindow.h
+++ b/src/subWindow.h
@@ -71,7 +71,7 @@ class SubWindow : public QDialog
//打开图像文件
void openImage();
//选择发送文件
- void selectFile();
+ void sendFile();

Jianjun Kong

unread,
May 24, 2008, 10:33:09 PM5/24/08
to chongri zhao, aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, xiyou...@googlegroups.com
区分Pigeons和Ipmsg用户,用不同头像显示,并能对Pigeons发送消息进行样式控制。

Signed-off-by: Jianjun Kong <kongj...@gmail.com>
---

src/data/ipmsg.png | Bin 0 -> 5481 bytes
src/mainWindow.cpp | 11 +++++++++--
src/msgManage.cpp | 2 +-
src/resource.qrc | 1 +
src/subWindow.cpp | 12 ++++++++----
5 files changed, 19 insertions(+), 7 deletions(-)
create mode 100644 src/data/ipmsg.png

diff --git a/src/data/ipmsg.png b/src/data/ipmsg.png
new file mode 100644
index 0000000000000000000000000000000000000000..8d29dbbdbfe47f40ed0c0e2c252eaa6a0f4ba46b
GIT binary patch
literal 5481
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

literal 0
Hc$@<O00001

diff --git a/src/mainWindow.cpp b/src/mainWindow.cpp
index 77aabbc..8a83320 100644
--- a/src/mainWindow.cpp
+++ b/src/mainWindow.cpp
@@ -79,7 +79,10 @@ void MainWindow::showuserlist()


//QStringList s=str.split(":");
//QStringList s=str.split(":");

//userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),s.at(1),userListWidget);
- userListWidgetItem = new QListWidgetItem(QIcon(":/data/openimage.png"), str, userListWidget);
+ if (str.endsWith("*"))
+ userListWidgetItem = new QListWidgetItem(QIcon(":/data/openimage.png"), str, userListWidget);
+ else
+ userListWidgetItem = new QListWidgetItem(QIcon(":/data/ipmsg.png"), str, userListWidget);


//userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),u.toString,userListWidget);
}
}

@@ -124,7 +127,11 @@ void MainWindow::addUserList(MsgMng *msg)
{*/


qDebug()<<"AddUserList:"<<msg->address<<":"<<msg->username;
//userListWidgetItem = new QListWidgetItem(QIcon(":/data/openimage.png"), msg->username, userListWidget);

- QString str=msg->address.toString()+":"+msg->username;
+ QString str;
+ if (msg->hostname == msg->username+"*")
+ str=msg->address.toString()+":"+msg->username+"*";
+ else
+ str=msg->address.toString()+":"+msg->username;


qDebug()<<"AddUserList: msg->command:"<<msg->command;

qDebug()<<"subislist[str1]:" << subislist[str];

/*foreach((int i, subislist)
diff --git a/src/msgManage.cpp b/src/msgManage.cpp
index 0dacd09..5d15e16 100644
--- a/src/msgManage.cpp
+++ b/src/msgManage.cpp
@@ -13,7 +13,7 @@

MsgMng::MsgMng(){
username = QHostInfo::localHostName();
- hostname = QHostInfo::localHostName();
+ hostname = QHostInfo::localHostName()+"*";
version = PIGEONS_VERSION;


packetno = QDateTime::currentDateTime().toTime_t();//实际返回uint,有点不匹配

diff --git a/src/resource.qrc b/src/resource.qrc
index c4487cb..507da0a 100644
--- a/src/resource.qrc
+++ b/src/resource.qrc
@@ -9,5 +9,6 @@


<file>data/textcolor.png</file>
<file>data/openimage.png</file>

<file>data/file.png</file>
+ <file>data/ipmsg.png</file>
</qresource>
</RCC>
diff --git a/src/subWindow.cpp b/src/subWindow.cpp
index 67b4d5e..52ebde1 100644
--- a/src/subWindow.cpp
+++ b/src/subWindow.cpp
@@ -10,6 +10,7 @@ SubWindow::SubWindow(Serve *ser, QString str)
QStringList s=str.split(":");
qDebug()<<"s.at(0) address:"<<s.at(0);
msgmng->username = s.at(1);
+ msgmng->hostname = s.at(1);


msgmng->address = (QHostAddress)s.at(0);
connect(service, SIGNAL(msgSendMsg(MsgMng *)) , this, SLOT(showMessage(MsgMng *)));
}

@@ -42,14 +43,17 @@ void SubWindow::closeEvent(QCloseEvent *event)


//发送消息
void SubWindow::sendMessage()
{
-

- //message = inputTextEdit->toHtml();


- message = inputTextEdit->toPlainText();

+ qDebug()<<"sendMessage():"<<msgmng->hostname<<":"<<msgmng->username;
+ if(msgmng->hostname.endsWith("*"))
+ message = inputTextEdit->toHtml();
+ else


+ message = inputTextEdit->toPlainText();

//char *m = inputTextEdit->toPlainText();

//message=message.toUtf8();

//message = m->fromUtf8(m, -1);
recordTextEdit->append("[" + QDateTime::currentDateTime().toString(tr("yyyy-MM-dd hh:mm:ss"))

- + tr("] ") + (QHostInfo::localHostName())+tr(":\n") +message);
+ + tr("] ") + (QHostInfo::localHostName()));
+ recordTextEdit->append(message);


//connect(fontComboBox, SIGNAL(activated(const QString &)),inputTextEdit, SLOT(setFontFamily(const QString &)));

MsgMng *msg = new MsgMng;

//msg->command=IPMSG_SENDMSG;
--
1.5.2.5

Jianjun Kong

unread,
May 31, 2008, 3:29:22 AM5/31/08
to chongri zhao, aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, xiyou...@googlegroups.com
更新需求说明文档

BTW:
请赵崇日将更新的概要设计文档迅速push上去。

Jianjun Kong

unread,
May 31, 2008, 9:24:09 PM5/31/08
to chongri zhao, aurt...@gmail.com, xiaoch...@gmail.com, lile...@gmail.com, meiyan...@gmail.com, xiyou...@googlegroups.com

添加刷新用于列表功能;
修补一个关闭Udp Socket 的 bug;
对窗口布局细节做了调整。

Signed-off-by: Jianjun Kong <kongj...@gmail.com>
---

README | 2 +-
TODO | 7 ++---
src/mainWindow.cpp | 54 ++++++++++++++++++++++++++++++++-------------------
src/mainWindow.h | 4 +++
src/subWindow.cpp | 2 +-
5 files changed, 43 insertions(+), 26 deletions(-)

diff --git a/README b/README
index e2eba7a..2297b58 100644
--- a/README
+++ b/README
@@ -47,6 +47,6 @@ see file AUTHORS

Skins Designer
==============================================
-
+Zhao Chongri

At the End
diff --git a/TODO b/TODO
index 5266de7..f4f95f9 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,5 @@
1. 变量、socket的那天资源的释放;
2. 测试中文传输乱码问题;
-3. 区分版本,对pigeons采用Html文本传输,这样可以控制样式;
-4. 测试IPmsg协议对于文件传书的具体交互过程
-5. 用QT实现TCP传输、接收文件
-6. 进行适当的外网通信测试,尝试利用映射地址进行通信,为Pigeons走向外网做准备。
+3. 测试IPmsg协议对于文件传书的具体交互过程
+4. 用QT实现TCP传输、接收文件
+5. 进行适当的外网通信测试,尝试利用映射地址进行通信,为Pigeons走向外网做准备。
diff --git a/src/mainWindow.cpp b/src/mainWindow.cpp
index 8a83320..1772437 100644
--- a/src/mainWindow.cpp
+++ b/src/mainWindow.cpp
@@ -67,6 +67,8 @@ void MainWindow::exit()
event->accept();*/

}
+
+//根据sublist显示用户到列表
void MainWindow::showuserlist()
{
userListWidget->clear();
@@ -106,6 +108,7 @@ void MainWindow::addSub(QListWidgetItem *u)
}
}

+//关闭子窗口
void MainWindow::delSub(QString str)
{

@@ -114,6 +117,7 @@ void MainWindow::delSub(QString str)

}

+//添加用户到sublist


void MainWindow::addUserList(MsgMng *msg)
//void MainWindow::addUserList(QHostAddress addr,QString username)
{

@@ -183,6 +187,7 @@ void MainWindow::addUserList(MsgMng *msg)

}

+//把用户从列表删除
void MainWindow::delUserList(MsgMng *msg)
{


QString str=msg->address.toString()+":"+msg->username;

@@ -233,22 +238,36 @@ void MainWindow::closeEvent(QCloseEvent *event)


msg->extend="";
service->broadcast(6291458, NULL);

//service->broadcast(IPMSG_BR_EXIT, NULL);
+ service->udpSocket->close();
event->accept();
}

+//关于Pigeons
void MainWindow::about()
{
QMessageBox::information(this, tr("About"),tr("This project is on Linux+QT4 platform, which was used for transfer files on Internet, providing communication with IP MSG, FeiQ or other clients. It is written for KDE envirenment. This software is released under GPL lisence, for more details about the license, please see the content of file COPYING."));
}

+//刷新用户列表
+void MainWindow::refurbish()
+{
+ service->broadcast(6291457, NULL);


+ int i=0;
+ foreach(QString s, sublist)
+ {

+ sublist.remove(i);
+ usercount--;
+ i++;
+ }
+
+ showuserlist();
+}
+
void MainWindow::enabledSendButton()
{
sendButton->setEnabled(true);
}

-
-
-
//槽函数,打开图片文件
void MainWindow::openImage()
{
@@ -313,14 +332,14 @@ void MainWindow::setBoldFont(bool flag)
void MainWindow::initWindow()
{
resize(220,480);
- setMinimumSize(220,480);
- setMaximumSize(220,480);
+ //setMinimumSize(220,480);
+ //setMaximumSize(220,480);



setWindowTitle(tr("Pigeons"));
messageWindow = new QWidget(this);
messageWindow->resize(200,600);

- messageWindow->setMinimumSize(200,600);
- messageWindow->setMaximumSize(200,600);
+ //messageWindow->setMinimumSize(200,600);
+ //messageWindow->setMaximumSize(200,600);
//messageWindow->setWindowTitle(tr("localqq"));

/*f(){
@@ -399,20 +418,14 @@ void MainWindow::initWindow()


aboutButton = new QPushButton(tr("&About"),messageWindow);

connect(aboutButton, SIGNAL(clicked()), this, SLOT(about()));

+ //刷新按钮
+ refurbishButton = new QPushButton(tr("&Rrfurbish"),messageWindow);
+ connect(refurbishButton, SIGNAL(clicked()), this, SLOT(refurbish()));
+
//用户昵称表
userListWidget = new QListWidget(messageWindow);
showuserlist();


- /*userListWidgetItem = new QListWidgetItem(QIcon(":/data/openimage.png"),"kongove",userListWidget);
- userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),"zhaochongri",userListWidget);
- userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),"mei",userListWidget);
- userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),"gaohui",userListWidget);
- userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),"lilei",userListWidget);
- userListWidgetItem = new QListWidgetItem(QIcon(":/data/QQ.png"),"wangcong",userListWidget);*/

- /*QListWidgetItem::QListWidgetItem(const QListWidgetItem&)
- QListWidgetItem::QListWidgetItem(const QIcon&, const QString&, QListWidget*, int)
- QListWidgetItem::QListWidgetItem(const QString&, QListWidget*, int)
- QListWidgetItem::QListWidgetItem(QListWidget*, int)*/
- userListWidget->setMinimumSize(190,420);
+ userListWidget->setMinimumSize(190,430);


userListWidget->setMaximumSize(200,600);
connect(userListWidget, SIGNAL(itemDoubleClicked (QListWidgetItem*)),this,SLOT(addSub(QListWidgetItem *)));//

@@ -424,9 +437,10 @@ void MainWindow::initWindow()
//布局


QHBoxLayout *buttonLayout = new QHBoxLayout;

buttonLayout->addWidget(aboutButton);
- buttonLayout->addStretch(3);
+ //buttonLayout->addStretch(3);
//buttonLayout->addWidget(sendButton);
//buttonLayout->addStretch(1);
+ buttonLayout->addWidget(refurbishButton);
buttonLayout->addWidget(quitButton);

// QVBoxLayout *leftLayout = new QVBoxLayout;
@@ -439,7 +453,7 @@ void MainWindow::initWindow()
// mainLayout->addWidget(userListWidget,0,1);
// mainLayout->addLayout(buttonLayout,1,0,1,2);
// mainLayout->setSizeConstraint(QLayout::SetFixedSize);
- mainLayout->addWidget(userListWidget,0,1);
+ mainLayout->addWidget(userListWidget,0,0);
mainLayout->addLayout(buttonLayout,1,0,1,2);
mainLayout->setSizeConstraint(QLayout::SetFixedSize);

diff --git a/src/mainWindow.h b/src/mainWindow.h
index c3cf9c3..bd71482 100644
--- a/src/mainWindow.h
+++ b/src/mainWindow.h
@@ -34,6 +34,8 @@ class MainWindow : public QWidget
QTextEdit *inputTextEdit;
//关于按钮
QPushButton *aboutButton;
+
+ QPushButton *refurbishButton;
//发送按钮
QPushButton *sendButton;
//退出按钮
@@ -83,6 +85,8 @@ class MainWindow : public QWidget


void enabledSendButton();
//关于
void about();

+ //刷新
+ void refurbish();


void delSub(QString str);
private:
SubWindow *sub;

diff --git a/src/subWindow.cpp b/src/subWindow.cpp
index 2ff4a92..9c8f052 100644
--- a/src/subWindow.cpp
+++ b/src/subWindow.cpp
@@ -35,7 +35,7 @@ void SubWindow::closeEvent(QCloseEvent *event)


QString str=msgmng->address.toString()+":"+msgmng->username;

emit delSub(str);
qDebug()<<"emit delSub(str)";
- service->udpSocket->close();
+ //service->udpSocket->close();
//接受信号,执行退出
event->accept();
}
--
1.5.2.5

--
{ Jianjun Kong | www.kongove.cn | Happy Hacking }

Reply all
Reply to author
Forward
0 new messages