createmeetingdialog.cpp 14 KB

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