createmeetingdialog.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. #include "createmeetingdialog.h"
  2. #include <QCloseEvent>
  3. #include <QEventLoop>
  4. #include <QMessageBox>
  5. #include <QRandomGenerator>
  6. #include <QRegularExpression>
  7. #include <QRegularExpressionValidator>
  8. #include <QScrollArea>
  9. CreateMeetingDialog::CreateMeetingDialog(QWidget *parent)
  10. : TDialog(parent)
  11. , m_mainLayout(nullptr)
  12. , m_formLayout(nullptr)
  13. , m_basicGroup(nullptr)
  14. , m_basicLayout(nullptr)
  15. , m_meetingNameEdit(nullptr)
  16. , m_descriptionEdit(nullptr)
  17. , m_startTimeEdit(nullptr)
  18. , m_durationSpinBox(nullptr)
  19. , m_maxParticipantsSpinBox(nullptr)
  20. , m_meetingTypeCombo(nullptr)
  21. , m_securityGroup(nullptr)
  22. , m_securityLayout(nullptr)
  23. , m_passwordCheckBox(nullptr)
  24. , m_passwordLayout(nullptr)
  25. , m_passwordEdit(nullptr)
  26. , m_generatePasswordButton(nullptr)
  27. , m_recordCheckBox(nullptr)
  28. , m_roleGroup(nullptr)
  29. , m_roleLayout(nullptr)
  30. , m_joinAsAdminCheckBox(nullptr)
  31. , m_buttonLayout(nullptr)
  32. , m_createButton(nullptr)
  33. , m_cancelButton(nullptr)
  34. {
  35. setWindowTitle("创建会议");
  36. resize(500, 600);
  37. setupUI();
  38. applyStyles();
  39. setDefaultValues();
  40. // 初始状态下禁用创建按钮
  41. m_createButton->setEnabled(false);
  42. }
  43. CreateMeetingDialog::~CreateMeetingDialog() {}
  44. void CreateMeetingDialog::setupUI()
  45. {
  46. // 创建滚动区域
  47. QScrollArea *scrollArea = new QScrollArea();
  48. scrollArea->setWidgetResizable(true);
  49. scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  50. QWidget *scrollWidget = new QWidget();
  51. scrollArea->setWidget(scrollWidget);
  52. m_mainLayout = new QVBoxLayout(scrollWidget);
  53. m_mainLayout->setContentsMargins(20, 20, 20, 20);
  54. m_mainLayout->setSpacing(20);
  55. // 基本信息组
  56. m_basicGroup = new QGroupBox("基本信息", scrollWidget);
  57. m_basicLayout = new QFormLayout(m_basicGroup);
  58. m_basicLayout->setContentsMargins(15, 15, 15, 15);
  59. m_basicLayout->setSpacing(10);
  60. // 会议名称
  61. m_meetingNameEdit = new QLineEdit();
  62. m_meetingNameEdit->setPlaceholderText("请输入会议名称");
  63. connect(m_meetingNameEdit,
  64. &QLineEdit::textChanged,
  65. this,
  66. &CreateMeetingDialog::onMeetingNameChanged);
  67. m_basicLayout->addRow("会议名称 *:", m_meetingNameEdit);
  68. // 会议描述
  69. m_descriptionEdit = new QTextEdit();
  70. m_descriptionEdit->setPlaceholderText("请输入会议描述(可选)");
  71. m_descriptionEdit->setMaximumHeight(80);
  72. m_basicLayout->addRow("会议描述:", m_descriptionEdit);
  73. // 开始时间
  74. m_startTimeEdit = new QDateTimeEdit();
  75. m_startTimeEdit->setCalendarPopup(true);
  76. m_startTimeEdit->setDisplayFormat("yyyy-MM-dd hh:mm");
  77. m_basicLayout->addRow("开始时间 *:", m_startTimeEdit);
  78. // 会议时长
  79. m_durationSpinBox = new QSpinBox();
  80. m_durationSpinBox->setRange(15, 480); // 15分钟到8小时
  81. m_durationSpinBox->setSuffix(" 分钟");
  82. m_durationSpinBox->setSingleStep(15);
  83. m_basicLayout->addRow("会议时长 *:", m_durationSpinBox);
  84. // 最大参与人数
  85. m_maxParticipantsSpinBox = new QSpinBox();
  86. m_maxParticipantsSpinBox->setRange(2, 100);
  87. m_maxParticipantsSpinBox->setSuffix(" 人");
  88. m_basicLayout->addRow("最大参与人数:", m_maxParticipantsSpinBox);
  89. // 会议类型
  90. m_meetingTypeCombo = new QComboBox();
  91. m_meetingTypeCombo->addItems({"视频会议", "音频会议", "屏幕共享", "网络研讨会"});
  92. m_basicLayout->addRow("会议类型:", m_meetingTypeCombo);
  93. m_mainLayout->addWidget(m_basicGroup);
  94. // 安全设置组
  95. m_securityGroup = new QGroupBox("安全设置", scrollWidget);
  96. m_securityLayout = new QVBoxLayout(m_securityGroup);
  97. m_securityLayout->setContentsMargins(15, 15, 15, 15);
  98. m_securityLayout->setSpacing(10);
  99. // 密码设置
  100. m_passwordCheckBox = new QCheckBox("启用会议密码");
  101. connect(m_passwordCheckBox,
  102. &QCheckBox::toggled,
  103. this,
  104. &CreateMeetingDialog::onPasswordCheckChanged);
  105. m_securityLayout->addWidget(m_passwordCheckBox);
  106. m_passwordLayout = new QHBoxLayout();
  107. m_passwordEdit = new QLineEdit();
  108. m_passwordEdit->setPlaceholderText("请输入6-12位密码");
  109. m_passwordEdit->setMaxLength(12);
  110. m_passwordEdit->setEnabled(false);
  111. // 设置密码验证器
  112. QRegularExpression passwordRegex("[A-Za-z0-9]{6,12}");
  113. QRegularExpressionValidator *passwordValidator = new QRegularExpressionValidator(passwordRegex,
  114. this);
  115. m_passwordEdit->setValidator(passwordValidator);
  116. m_generatePasswordButton = new QPushButton("生成密码");
  117. m_generatePasswordButton->setEnabled(false);
  118. connect(m_generatePasswordButton,
  119. &QPushButton::clicked,
  120. this,
  121. &CreateMeetingDialog::generateRandomPassword);
  122. m_passwordLayout->addWidget(m_passwordEdit);
  123. m_passwordLayout->addWidget(m_generatePasswordButton);
  124. m_securityLayout->addLayout(m_passwordLayout);
  125. // 录制设置
  126. m_recordCheckBox = new QCheckBox("自动录制会议");
  127. m_securityLayout->addWidget(m_recordCheckBox);
  128. m_mainLayout->addWidget(m_securityGroup);
  129. // 角色选择组
  130. m_roleGroup = new QGroupBox("加入方式", scrollWidget);
  131. m_roleLayout = new QVBoxLayout(m_roleGroup);
  132. m_roleLayout->setContentsMargins(15, 15, 15, 15);
  133. m_roleLayout->setSpacing(10);
  134. m_joinAsAdminCheckBox = new QCheckBox("以管理员身份加入会议(可以录制和管理)");
  135. m_joinAsAdminCheckBox->setChecked(true); // 默认选中管理员模式
  136. m_roleLayout->addWidget(m_joinAsAdminCheckBox);
  137. QLabel *roleHint = new QLabel("提示:取消勾选将以观看者身份加入会议");
  138. roleHint->setStyleSheet("color: #666; font-size: 12px;");
  139. m_roleLayout->addWidget(roleHint);
  140. m_mainLayout->addWidget(m_roleGroup);
  141. // 按钮布局
  142. m_buttonLayout = new QHBoxLayout();
  143. m_buttonLayout->addStretch();
  144. m_cancelButton = new QPushButton("取消");
  145. m_createButton = new QPushButton("创建会议");
  146. connect(m_cancelButton, &QPushButton::clicked, this, &CreateMeetingDialog::reject);
  147. connect(m_createButton, &QPushButton::clicked, this, &CreateMeetingDialog::accept);
  148. m_buttonLayout->addWidget(m_cancelButton);
  149. m_buttonLayout->addWidget(m_createButton);
  150. m_mainLayout->addLayout(m_buttonLayout);
  151. // 设置主布局 - 使用TWidget的mainLayout()
  152. mainLayout()->addWidget(scrollArea);
  153. }
  154. void CreateMeetingDialog::applyStyles()
  155. {
  156. setStyleSheet("CreateMeetingDialog {"
  157. " background-color: #f8f9fa;"
  158. "}"
  159. "QScrollArea {"
  160. " border: none;"
  161. " background-color: #f8f9fa;"
  162. "}"
  163. "QGroupBox {"
  164. " font-size: 14px;"
  165. " font-weight: bold;"
  166. " color: #495057;"
  167. " border: 2px solid #e9ecef;"
  168. " border-radius: 8px;"
  169. " margin-top: 10px;"
  170. " background-color: white;"
  171. "}"
  172. "QGroupBox::title {"
  173. " subcontrol-origin: margin;"
  174. " left: 10px;"
  175. " padding: 0 8px 0 8px;"
  176. " background-color: white;"
  177. "}"
  178. "QLabel {"
  179. " font-size: 13px;"
  180. " color: #495057;"
  181. " font-weight: 500;"
  182. "}"
  183. "QLineEdit {"
  184. " border: 2px solid #e9ecef;"
  185. " border-radius: 6px;"
  186. " padding: 8px 12px;"
  187. " font-size: 13px;"
  188. " background-color: white;"
  189. "}"
  190. "QLineEdit:focus {"
  191. " border-color: #007bff;"
  192. " outline: none;"
  193. "}"
  194. "QLineEdit:disabled {"
  195. " background-color: #f8f9fa;"
  196. " color: #6c757d;"
  197. "}"
  198. "QTextEdit {"
  199. " border: 2px solid #e9ecef;"
  200. " border-radius: 6px;"
  201. " padding: 8px 12px;"
  202. " font-size: 13px;"
  203. " background-color: white;"
  204. "}"
  205. "QTextEdit:focus {"
  206. " border-color: #007bff;"
  207. " outline: none;"
  208. "}"
  209. "QDateTimeEdit, QSpinBox, QComboBox {"
  210. " border: 2px solid #e9ecef;"
  211. " border-radius: 6px;"
  212. " padding: 8px 12px;"
  213. " font-size: 13px;"
  214. " background-color: white;"
  215. "}"
  216. "QDateTimeEdit:focus, QSpinBox:focus, QComboBox:focus {"
  217. " border-color: #007bff;"
  218. " outline: none;"
  219. "}"
  220. "QCheckBox {"
  221. " font-size: 13px;"
  222. " color: #495057;"
  223. " spacing: 8px;"
  224. "}"
  225. "QCheckBox::indicator {"
  226. " width: 16px;"
  227. " height: 16px;"
  228. " border: 2px solid #e9ecef;"
  229. " border-radius: 3px;"
  230. " background-color: white;"
  231. "}"
  232. "QCheckBox::indicator:checked {"
  233. " background-color: #007bff;"
  234. " border-color: #007bff;"
  235. " image: url(:/icons/check.png);"
  236. "}"
  237. "QPushButton {"
  238. " border: none;"
  239. " border-radius: 6px;"
  240. " padding: 10px 20px;"
  241. " font-size: 13px;"
  242. " font-weight: 500;"
  243. " min-width: 80px;"
  244. "}"
  245. "#createButton {"
  246. " background-color: #28a745;"
  247. " color: white;"
  248. "}"
  249. "#createButton:hover {"
  250. " background-color: #218838;"
  251. "}"
  252. "#createButton:pressed {"
  253. " background-color: #1e7e34;"
  254. "}"
  255. "#createButton:disabled {"
  256. " background-color: #6c757d;"
  257. " color: #adb5bd;"
  258. "}"
  259. "#cancelButton {"
  260. " background-color: #6c757d;"
  261. " color: white;"
  262. "}"
  263. "#cancelButton:hover {"
  264. " background-color: #545b62;"
  265. "}"
  266. "#generatePasswordButton {"
  267. " background-color: #17a2b8;"
  268. " color: white;"
  269. " min-width: 60px;"
  270. "}"
  271. "#generatePasswordButton:hover {"
  272. " background-color: #138496;"
  273. "}"
  274. "#generatePasswordButton:disabled {"
  275. " background-color: #6c757d;"
  276. " color: #adb5bd;"
  277. "}");
  278. m_createButton->setObjectName("createButton");
  279. m_cancelButton->setObjectName("cancelButton");
  280. m_generatePasswordButton->setObjectName("generatePasswordButton");
  281. }
  282. void CreateMeetingDialog::setDefaultValues()
  283. {
  284. // 设置默认开始时间为当前时间后1小时
  285. QDateTime defaultTime = QDateTime::currentDateTime().addSecs(3600);
  286. m_startTimeEdit->setDateTime(defaultTime);
  287. m_startTimeEdit->setMinimumDateTime(QDateTime::currentDateTime());
  288. // 设置默认时长为60分钟
  289. m_durationSpinBox->setValue(60);
  290. // 设置默认最大参与人数为10人
  291. m_maxParticipantsSpinBox->setValue(10);
  292. // 默认选择视频会议
  293. m_meetingTypeCombo->setCurrentIndex(0);
  294. }
  295. void CreateMeetingDialog::onPasswordCheckChanged(bool checked)
  296. {
  297. m_passwordEdit->setEnabled(checked);
  298. m_generatePasswordButton->setEnabled(checked);
  299. if (!checked) {
  300. m_passwordEdit->clear();
  301. }
  302. validateInput();
  303. }
  304. void CreateMeetingDialog::onMeetingNameChanged()
  305. {
  306. validateInput();
  307. }
  308. void CreateMeetingDialog::validateInput()
  309. {
  310. bool isValid = isValidInput();
  311. m_createButton->setEnabled(isValid);
  312. }
  313. void CreateMeetingDialog::generateRandomPassword()
  314. {
  315. const QString chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  316. QString password;
  317. for (int i = 0; i < 8; ++i) {
  318. int index = QRandomGenerator::global()->bounded(chars.length());
  319. password.append(chars.at(index));
  320. }
  321. m_passwordEdit->setText(password);
  322. }
  323. bool CreateMeetingDialog::isValidInput() const
  324. {
  325. // 检查会议名称
  326. if (m_meetingNameEdit->text().trimmed().isEmpty()) {
  327. return false;
  328. }
  329. // 检查开始时间
  330. if (m_startTimeEdit->dateTime() <= QDateTime::currentDateTime()) {
  331. return false;
  332. }
  333. // 如果启用了密码,检查密码有效性
  334. if (m_passwordCheckBox->isChecked()) {
  335. QString password = m_passwordEdit->text().trimmed();
  336. if (password.length() < 6 || password.length() > 12) {
  337. return false;
  338. }
  339. }
  340. return true;
  341. }
  342. MeetingInfo CreateMeetingDialog::getMeetingInfo() const
  343. {
  344. MeetingInfo info;
  345. info.meetingName = m_meetingNameEdit->text().trimmed();
  346. info.description = m_descriptionEdit->toPlainText().trimmed();
  347. info.startTime = m_startTimeEdit->dateTime();
  348. info.duration = m_durationSpinBox->value();
  349. info.maxParticipants = m_maxParticipantsSpinBox->value();
  350. info.requirePassword = m_passwordCheckBox->isChecked();
  351. info.password = m_passwordEdit->text().trimmed();
  352. info.recordMeeting = m_recordCheckBox->isChecked();
  353. info.meetingType = m_meetingTypeCombo->currentText();
  354. info.joinAsAdmin = m_joinAsAdminCheckBox->isChecked();
  355. return info;
  356. }
  357. bool CreateMeetingDialog::getJoinAsAdmin() const
  358. {
  359. return m_joinAsAdminCheckBox->isChecked();
  360. }
  361. void CreateMeetingDialog::accept()
  362. {
  363. if (!isValidInput()) {
  364. QString errorMsg;
  365. if (m_meetingNameEdit->text().trimmed().isEmpty()) {
  366. errorMsg = "请输入会议名称。";
  367. } else if (m_startTimeEdit->dateTime() <= QDateTime::currentDateTime()) {
  368. errorMsg = "开始时间必须晚于当前时间。";
  369. } else if (m_passwordCheckBox->isChecked()) {
  370. QString password = m_passwordEdit->text().trimmed();
  371. if (password.length() < 6 || password.length() > 12) {
  372. errorMsg = "密码长度必须在6-12位之间。";
  373. }
  374. }
  375. QMessageBox::warning(this, "输入错误", errorMsg);
  376. return;
  377. }
  378. m_meetingInfo = getMeetingInfo();
  379. TDialog::accept();
  380. }
  381. void CreateMeetingDialog::reject()
  382. {
  383. TDialog::reject();
  384. }