mindmapwidget.cpp 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582
  1. #include "mindmapwidget.h"
  2. #include "ui_mindmapwidget.h"
  3. MindMapWidget::MindMapWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MindMapWidget)
  4. {
  5. ui->setupUi(this);
  6. m_selObject = nullptr;
  7. m_rootPoint = QPoint(32, 0);
  8. m_mousedownFlag = false;
  9. m_projectId = -1;
  10. m_cutObject = nullptr;
  11. m_backgroundId = 0;
  12. m_screenshotFlag = false;
  13. setMouseTracking(true);
  14. m_hasEntranceNode = false;
  15. }
  16. MindMapWidget::~MindMapWidget()
  17. {
  18. delete ui;
  19. }
  20. void MindMapWidget::openProject(int id)
  21. {
  22. m_rootPoint = QPoint(32, 0);
  23. m_projectId = id;
  24. clear();
  25. addNode(-1, id);
  26. loadBackground();
  27. update();
  28. m_myDao->sqliteWrapper->execute(QString("insert into mind_history(pid) values (%1)").arg(id));
  29. m_hasEntranceNode = false;
  30. }
  31. void MindMapWidget::entranceNode(int pid, int id)
  32. {
  33. m_rootPoint = QPoint(32, 0);
  34. clear();
  35. addNode(pid, id);
  36. m_hasEntranceNode = true;
  37. update();
  38. }
  39. void MindMapWidget::backToMindMap()
  40. {
  41. openProject(m_projectId);
  42. }
  43. void MindMapWidget::paintEvent(QPaintEvent *event)
  44. {
  45. drawImage(this, rect().width(), rect().height());
  46. }
  47. void MindMapWidget::mouseDoubleClickEvent(QMouseEvent *event)
  48. {
  49. if (editEnable) {
  50. QPoint pt = mapFromGlobal(cursor().pos());
  51. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  52. MindMapObject *obj = m_mindMapObjects.at(i);
  53. if (obj->imgRect.contains(pt)) {
  54. showPixmapDialog *dlg = new showPixmapDialog();
  55. dlg->setImage(obj->img());
  56. dlg->exec();
  57. delete dlg;
  58. }
  59. }
  60. emit onDoubleClick();
  61. }
  62. }
  63. void MindMapWidget::drawRemark(QPainter &painter)
  64. {
  65. QFont font;
  66. if (m_selObject != nullptr) {
  67. QString remark = m_selObject->message().trimmed();
  68. if (remark != nullptr) {
  69. QStringList infos = remark.split("\n");
  70. int index = getMaxLen(infos);
  71. QRect rc;
  72. QFontMetrics fm = painter.fontMetrics();
  73. rc.setRect(m_selObject->rect.right() + 32, m_selObject->rect.top(), fm.width(infos[index]) + 64,
  74. fm.height() * infos.count());
  75. painter.setPen(QColor(197, 197, 197));
  76. QColor shadowColor;
  77. shadowColor = QColor(0, 0, 0, 200); //阴影颜色设置
  78. painter.fillRect(rc.x(), rc.y(), rc.width(), rc.height(), shadowColor); //画影罩效果
  79. painter.setBrush(QBrush(QColor(255, 255, 255, 200)));
  80. painter.drawRect(rc);
  81. painter.drawLine(
  82. QPoint(m_selObject->rect.right(), m_selObject->rect.top() + m_selObject->rect.height() / 2),
  83. QPoint(rc.left(), rc.top()));
  84. int l = rc.left() + 32;
  85. int t = rc.top();
  86. painter.setPen(Qt::black);
  87. font = painter.font();
  88. font.setPointSize(11);
  89. font.setBold(false);
  90. painter.setFont(font);
  91. for (int i = 0; i < infos.count(); i++) {
  92. QRect textRc;
  93. textRc.setRect(l, t, rc.width() - 32, fm.height());
  94. painter.drawText(textRc, Qt::AlignLeft | Qt::AlignVCenter, infos[i]);
  95. t += fm.height();
  96. }
  97. }
  98. }
  99. }
  100. void MindMapWidget::clear()
  101. {
  102. qDeleteAll(m_mindMapObjects);
  103. m_mindMapObjects.clear();
  104. }
  105. void MindMapWidget::addNode(int pid, int id)
  106. {
  107. int i = 1;
  108. if (pid == -1) {
  109. MindMapObject *obj = new MindMapObject(this);
  110. QSqlQuery qry;
  111. QString sql = QString("select "
  112. "pid,id,name,remark,link,fontcolor,backColor,sxh,showNum,bold,italics,overline,underline,"
  113. "strikeOut,img,shrink,message from mind_data where id=%1 order by sxh,id")
  114. .arg(id);
  115. m_myDao->sqliteWrapper->select(sql, qry);
  116. if (qry.next()) {
  117. addNodeInfo(obj, 1, qry);
  118. obj->setPid(-1);
  119. addNode(obj->id());
  120. }
  121. } else {
  122. QSqlQuery qry;
  123. QString sql = QString("select "
  124. "pid,id,name,remark,link,fontcolor,backColor,sxh,shownum,bold,italics,overline,underline,"
  125. "strikeOut,img,shrink,message from mind_data where pid=%1 order by sxh,id")
  126. .arg(pid);
  127. m_myDao->sqliteWrapper->select(sql, qry);
  128. i = 1;
  129. while (qry.next()) {
  130. MindMapObject *obj = new MindMapObject(this);
  131. addNodeInfo(obj, i, qry);
  132. addNode(obj->id());
  133. i++;
  134. }
  135. }
  136. }
  137. void MindMapWidget::addNodeInfo(MindMapObject *obj, int i, QSqlQuery &qry)
  138. {
  139. obj->setId(qry.value(1).toInt());
  140. obj->setPid(qry.value(0).toInt());
  141. obj->setName(qry.value(2).toString());
  142. obj->setRemark(qry.value(3).toString());
  143. obj->setLink(qry.value(4).toString());
  144. if (!qry.value(16).isNull()) {
  145. obj->setMessage(qry.value(16).toString());
  146. }
  147. int fontcolor = qry.value(5).isNull() ? 0 : qry.value(5).toInt();
  148. obj->setFontColor(fontcolor);
  149. int backColor = qry.value(6).isNull() ? ColorTable::lastIndex() : qry.value(6).toInt();
  150. obj->setBackColor(backColor);
  151. int sxh = qry.value(7).toInt();
  152. if (sxh != i) {
  153. if (m_hasEntranceNode == false) {
  154. m_myDao->sqliteWrapper->execute(QString("update mind_data set sxh=%1 where id=%2").arg(i).arg(obj->id()));
  155. }
  156. }
  157. obj->setSxh(i);
  158. obj->setBold(getQryValueBool(qry, "bold"));
  159. obj->setItalics(getQryValueBool(qry, "italics"));
  160. obj->setOverline(getQryValueBool(qry, "overline"));
  161. obj->setUnderline(getQryValueBool(qry, "underline"));
  162. obj->setStrikeOut(getQryValueBool(qry, "strikeOut"));
  163. obj->setShrink(getQryValueBool(qry, "shrink"));
  164. obj->setHasImg(qry.value("img").isNull() == false);
  165. if (!qry.value("img").isNull()) {
  166. QByteArray ba = qry.value("img").toByteArray();
  167. QBuffer buf(&ba);
  168. QImage img;
  169. img.load(&buf, "png");
  170. QPixmap pix = QPixmap::fromImage(img);
  171. obj->setImg(pix);
  172. }
  173. addMarkNodes(obj);
  174. bool showNum = ((qry.value("shownum").isNull()) || (qry.value("showNum").toInt() == 0)) ? false : true;
  175. obj->setShowNum(showNum);
  176. m_mindMapObjects << obj;
  177. }
  178. MindMapObject *MindMapWidget::addChildNode(MindMapObject *pobj, int id, QString name)
  179. {
  180. MindMapObject *obj = new MindMapObject(this);
  181. obj->setPid(pobj->id());
  182. obj->setId(id);
  183. obj->setName(name);
  184. obj->setMessage(pobj->message());
  185. m_mindMapObjects << obj;
  186. update();
  187. return obj;
  188. }
  189. void MindMapWidget::setMyDao(MyDao *myDao)
  190. {
  191. m_myDao = myDao;
  192. }
  193. void MindMapWidget::drawNode(int pid, int px, int py, int x, int y, QPainter &painter)
  194. {
  195. int m = 0;
  196. QFont font;
  197. QPoint pt = mapFromGlobal(cursor().pos());
  198. bool isShrink = false;
  199. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  200. MindMapObject *obj = m_mindMapObjects.at(i);
  201. //根节点
  202. if (obj->pid() == pid) {
  203. QRect rc;
  204. int n = 0;
  205. getNodeCount(obj, n);
  206. n = n == 0 ? 1 : n;
  207. n = n * 34;
  208. setNodeNameFont(obj, painter, font);
  209. QFontMetrics fm = painter.fontMetrics();
  210. int reMarkWidth = obj->remark().trimmed() == "" ? 0 : 12;
  211. rc.setRect(x, y + n / 2 + m, fm.width(obj->name()) + 8 + reMarkWidth + 8 + obj->markNodes.count() * 16 + 64,
  212. 24);
  213. obj->remarkRect.setRect(x + fm.width(obj->name()) + 32, rc.top() + (rc.height() - 15) / 2, 12, 15);
  214. obj->addRect.setRect(x + fm.width(obj->name()) + 8 + reMarkWidth + obj->markNodes.count() * 16 + 64,
  215. rc.top() + rc.height() - 8, 16, 16);
  216. if (obj == m_selObject) {
  217. painter.setBrush(QColor(204, 232, 255));
  218. } else {
  219. if (obj->backColor() == ColorTable::lastIndex()) {
  220. painter.setBrush(Qt::NoBrush);
  221. } else {
  222. painter.setBrush(QBrush(ColorTable::getColor(obj->backColor())));
  223. }
  224. }
  225. QRect fillRc = rc;
  226. fillRc.setRight(rc.right() - 16);
  227. obj->rect = fillRc;
  228. painter.fillRect(fillRc, painter.brush());
  229. if (obj->parentObj() != nullptr) {
  230. isShrink = obj->parentObj()->shrink();
  231. }
  232. QPen pen;
  233. //绘制编号
  234. if ((obj->parentObj() != nullptr) && (obj->parentObj()->showNum())) {
  235. painter.setPen(Qt::NoPen);
  236. painter.setBrush(numColor(obj->sxh()));
  237. QRect numRc;
  238. numRc.setRect(fillRc.left() + 2, fillRc.top() + (fillRc.height() - 12) / 2, 12, 12);
  239. painter.drawEllipse(numRc);
  240. painter.setPen(Qt::white);
  241. font = painter.font();
  242. setFontAsDefault(font);
  243. font.setPointSize(9);
  244. painter.setFont(font);
  245. painter.drawText(numRc, Qt::AlignCenter, QString("%1").arg(obj->sxh()));
  246. }
  247. painter.setPen(Qt::black);
  248. setNodeNameFont(obj, painter, font);
  249. QRect textRc = rc;
  250. textRc.setLeft(rc.left() + 16);
  251. pen = painter.pen();
  252. QColor fontColor = m_selObject == obj ? Qt::black : ColorTable::getColor(obj->fontColor());
  253. pen.setColor(fontColor);
  254. painter.setPen(pen);
  255. painter.drawText(textRc, obj->name(), Qt::AlignLeft | Qt::AlignVCenter);
  256. if (reMarkWidth != 0) {
  257. QPixmap remarkPix(":/res/remark.png");
  258. painter.drawPixmap(obj->remarkRect, remarkPix, remarkPix.rect());
  259. }
  260. int markNodeLeft = obj->remarkRect.right() + 8;
  261. for (int mid : obj->markNodes) {
  262. QRect mRc;
  263. mRc.setRect(markNodeLeft, rc.top() + (rc.height() - 12) / 2, 12, 12);
  264. QPixmap mPix(QString(":/res/flags/%1.png").arg(mid));
  265. painter.drawPixmap(mRc, mPix, mPix.rect());
  266. markNodeLeft += 16;
  267. }
  268. //绘制图片
  269. if (obj->hasImg()) {
  270. QPixmap pix = obj->img();
  271. if (!pix.isNull()) {
  272. QPixmap tmpPix = pix.scaled(rc.width() - 16, 120, Qt::KeepAspectRatio, Qt::SmoothTransformation);
  273. QRect pixRc;
  274. pixRc.setRect(textRc.left() - 16, textRc.bottom() + 16, tmpPix.width(), tmpPix.height());
  275. painter.drawPixmap(pixRc, tmpPix, tmpPix.rect());
  276. painter.setBrush(Qt::NoBrush);
  277. painter.setPen(QColor(197, 197, 197));
  278. painter.drawRect(pixRc);
  279. obj->imgRect = pixRc;
  280. }
  281. }
  282. pen = painter.pen();
  283. pen.setWidth(3);
  284. int nodeLevel = 0;
  285. MindMapObject *pobj = obj->parentObj();
  286. // if (pobj == nullptr) {
  287. // pen.setColor(obj->rootColor());
  288. // } else {
  289. // pen.setColor(pobj->lineColor());
  290. // }
  291. while (pobj) {
  292. nodeLevel++;
  293. pobj = pobj->parentObj();
  294. }
  295. Qt::GlobalColor _colors[15] = { Qt::red, Qt::darkRed, Qt::green, Qt::darkGreen, Qt::blue,
  296. Qt::darkBlue, Qt::cyan, Qt::darkCyan, Qt::magenta, Qt::darkMagenta,
  297. Qt::yellow, Qt::darkYellow, Qt::gray, Qt::darkGray, Qt::lightGray };
  298. if (nodeLevel < 15) {
  299. pen.setColor(QColor(_colors[nodeLevel]));
  300. } else {
  301. pen.setColor(QColor(_colors[0]));
  302. }
  303. painter.setPen(pen);
  304. painter.drawLine(rc.left(), rc.bottom() + 1, rc.right(), rc.bottom() + 1);
  305. m += n + (obj->hasImg() ? 132 : 0);
  306. if (pid != -1) {
  307. QPainterPath path;
  308. painter.setBrush(Qt::NoBrush);
  309. QPoint pts[4];
  310. pts[0] = QPoint(px, py);
  311. pts[3] = QPoint(rc.x(), rc.y() + rc.height());
  312. pts[1] = QPoint((pts[0].x() + pts[3].x()) / 2, pts[0].y());
  313. pts[2] = QPoint((pts[0].x() + pts[3].x()) / 2, pts[3].y());
  314. path.moveTo(pts[0]);
  315. path.cubicTo(pts[1], pts[2], pts[3]);
  316. painter.drawPath(path);
  317. }
  318. if (obj->shrink() == false) {
  319. drawNode(obj->id(), rc.right(), rc.top() + rc.height(), rc.right() + 24, rc.top() - n / 2, painter);
  320. } else {
  321. QRect rc = obj->addRect;
  322. painter.setPen(Qt::NoPen);
  323. painter.setBrush(QBrush(QColor(10, 123, 251)));
  324. painter.drawEllipse(rc);
  325. painter.setPen(Qt::white);
  326. font = painter.font();
  327. font.setItalic(false);
  328. font.setUnderline(false);
  329. font.setOverline(false);
  330. font.setStrikeOut(false);
  331. font.setBold(true);
  332. font.setPointSize(16);
  333. painter.setFont(font);
  334. painter.drawText(rc, Qt::AlignCenter, "…");
  335. }
  336. }
  337. }
  338. if (pid != -1) {
  339. QRect rc;
  340. rc.setRect(px - 8, py - 8, 16, 16);
  341. painter.setPen(Qt::NoPen);
  342. painter.setBrush(QBrush(QColor(10, 123, 251)));
  343. painter.drawEllipse(rc);
  344. painter.setPen(Qt::white);
  345. font = painter.font();
  346. font.setItalic(false);
  347. font.setUnderline(false);
  348. font.setOverline(false);
  349. font.setStrikeOut(false);
  350. font.setBold(true);
  351. if (isShrink) {
  352. font.setPointSize(16);
  353. painter.setFont(font);
  354. painter.drawText(rc, Qt::AlignCenter, "…");
  355. } else {
  356. font.setPointSize(24);
  357. painter.setFont(font);
  358. painter.drawText(rc, Qt::AlignCenter, "+");
  359. }
  360. }
  361. }
  362. void MindMapWidget::mousePressEvent(QMouseEvent *event)
  363. {
  364. m_mousedownFlag = true;
  365. QPoint pt = mapFromGlobal(cursor().pos());
  366. m_mousedownPoint = pt;
  367. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  368. MindMapObject *obj = m_mindMapObjects.at(i);
  369. if (obj->addRect.contains(pt)) {
  370. m_selObject = obj;
  371. if (obj->shrink()) {
  372. obj->setShrink(false);
  373. m_myDao->sqliteWrapper->execute(
  374. QString("update mind_data set shrink=0 where id=%1").arg(m_selObject->id()));
  375. } else {
  376. if (editEnable) {
  377. onAddChildNodeEvent();
  378. }
  379. }
  380. update();
  381. return;
  382. }
  383. if (obj->rect.contains(pt)) {
  384. m_selObject = obj;
  385. update();
  386. #ifdef Q_OS_ANDROID
  387. QElapsedTimer t;
  388. t.start();
  389. while (t.elapsed() < 500) {
  390. QApplication::processEvents();
  391. if (m_mousedownFlag == false) {
  392. return;
  393. }
  394. }
  395. showSelPopMenu();
  396. #else
  397. if (event->button() == Qt::RightButton) {
  398. if (editEnable)
  399. showSelPopMenu();
  400. }
  401. #endif
  402. return;
  403. }
  404. }
  405. m_selObject = nullptr;
  406. #ifdef Q_OS_ANDROID
  407. QElapsedTimer t;
  408. t.start();
  409. while (t.elapsed() < 500) {
  410. QApplication::processEvents();
  411. if (m_mousedownFlag == false) {
  412. return;
  413. }
  414. }
  415. showPopMenu();
  416. #else
  417. if (event->button() == Qt::RightButton) {
  418. if (editEnable) {
  419. // showPopMenu();
  420. }
  421. }
  422. #endif
  423. if (m_screenshotFlag == true) {
  424. m_startShot = pt;
  425. }
  426. update();
  427. }
  428. MindMapObject *MindMapWidget::selObject()
  429. {
  430. return m_selObject;
  431. }
  432. void MindMapWidget::setSelObject(MindMapObject *obj)
  433. {
  434. m_selObject = obj;
  435. update();
  436. }
  437. int MindMapWidget::getNodeNeedCount(MindMapObject *pobj)
  438. {
  439. int n = 1;
  440. int m = 0;
  441. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  442. MindMapObject *obj = m_mindMapObjects.at(i);
  443. if (obj->pid() == pobj->id()) {
  444. m += getNodeNeedCount(obj);
  445. }
  446. }
  447. if (m > n) {
  448. return m;
  449. } else {
  450. return n;
  451. }
  452. }
  453. void MindMapWidget::getMindWidgetChildNum(MindMapObject *pobj)
  454. {
  455. pobj->childNum = 0;
  456. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  457. MindMapObject *obj = m_mindMapObjects.at(i);
  458. if (obj->pid() == pobj->id()) {
  459. obj->setParentObj(pobj);
  460. pobj->childNum++;
  461. }
  462. }
  463. }
  464. void MindMapWidget::getMindWidgetsChildNum()
  465. {
  466. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  467. MindMapObject *obj = m_mindMapObjects.at(i);
  468. getMindWidgetChildNum(obj);
  469. }
  470. }
  471. void MindMapWidget::getNodeCount(MindMapObject *pobj, int &n)
  472. {
  473. //折叠
  474. if (pobj->shrink()) {
  475. n = 1;
  476. return;
  477. }
  478. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  479. MindMapObject *obj = m_mindMapObjects.at(i);
  480. if (pobj->id() == obj->pid()) {
  481. if (obj->childNum == 0) {
  482. n++;
  483. }
  484. if (obj->hasImg()) {
  485. n += 4;
  486. }
  487. getNodeCount(obj, n);
  488. }
  489. }
  490. }
  491. void MindMapWidget::mouseReleaseEvent(QMouseEvent *event)
  492. {
  493. m_mousedownFlag = false;
  494. if (m_screenshotFlag == true) {
  495. QPoint pt = mapFromGlobal(cursor().pos());
  496. QRect rc;
  497. getSelectRect(rc, m_startShot, pt);
  498. QPixmap pix = grab(rc);
  499. if (m_saveshotToFile) {
  500. QDir dir;
  501. dir.mkpath(QApplication::applicationDirPath() + "/screenshots");
  502. QString filename = QApplication::applicationDirPath() + "/screenshots/"
  503. + QDateTime::currentDateTime().toString("yyyyMMddhhmmss") + ".png";
  504. pix.save(filename, "png");
  505. filename = filename.replace("/", "\\");
  506. qApp->clipboard()->setText(filename);
  507. } else {
  508. qApp->clipboard()->setPixmap(pix);
  509. }
  510. m_screenshotFlag = false;
  511. }
  512. }
  513. void MindMapWidget::getChilds(int pid, QList<int> &ids)
  514. {
  515. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  516. MindMapObject *obj = m_mindMapObjects.at(i);
  517. if (obj->pid() == pid) {
  518. ids << obj->id();
  519. getChilds(obj->id(), ids);
  520. }
  521. }
  522. }
  523. void MindMapWidget::wheelEvent(QWheelEvent *event)
  524. {
  525. if (!m_mousedownFlag == true) {
  526. if (event->modifiers() == Qt::ControlModifier) {
  527. m_rootPoint.setX(m_rootPoint.x() + event->delta());
  528. } else {
  529. m_rootPoint.setY(m_rootPoint.y() + event->delta());
  530. }
  531. }
  532. update();
  533. }
  534. void MindMapWidget::mouseMoveEvent(QMouseEvent *event)
  535. {
  536. if (m_mousedownFlag) {
  537. QPoint pt = mapFromGlobal(cursor().pos());
  538. if (m_screenshotFlag == true) {
  539. } else {
  540. int x = pt.x() - m_mousedownPoint.x();
  541. int y = pt.y() - m_mousedownPoint.y();
  542. m_rootPoint.setX(m_rootPoint.x() + x);
  543. m_rootPoint.setY(m_rootPoint.y() + y);
  544. m_mousedownPoint = pt;
  545. }
  546. }
  547. update();
  548. }
  549. void MindMapWidget::editNode(MindMapObject *selObj, QString name)
  550. {
  551. selObj->setName(name);
  552. update();
  553. }
  554. void MindMapWidget::delSelObject()
  555. {
  556. if (m_selObject == nullptr) {
  557. return;
  558. }
  559. if (m_selObject->pid() == -1) {
  560. return;
  561. }
  562. int pid = m_selObject->pid();
  563. int ret = QMessageBox::question(this, "提示", "确定删除选中结点吗?");
  564. if (ret == QMessageBox::No) {
  565. return;
  566. }
  567. QList<int> ids;
  568. int id = m_selObject->id();
  569. m_selObject = nullptr;
  570. ids << id;
  571. getChilds(id, ids);
  572. for (int i = 0; i < ids.count(); i++) {
  573. deleteNodeById(ids.at(i));
  574. }
  575. reSetOrder(pid);
  576. update();
  577. }
  578. void MindMapWidget::deleteNodeById(int id)
  579. {
  580. m_myDao->sqliteWrapper->execute(QString("delete from mind_data where id=%1").arg(id));
  581. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  582. MindMapObject *obj = m_mindMapObjects.at(i);
  583. if (obj != nullptr) {
  584. if (obj->id() == id) {
  585. delete obj;
  586. m_mindMapObjects.removeAt(i);
  587. return;
  588. }
  589. }
  590. }
  591. }
  592. int MindMapWidget::projectId()
  593. {
  594. return m_projectId;
  595. }
  596. void MindMapWidget::deleteProject()
  597. {
  598. m_selObject = nullptr;
  599. QList<int> ids;
  600. ids << m_projectId;
  601. getChilds(m_projectId, ids);
  602. for (int i = 0; i < ids.count(); i++) {
  603. deleteNodeById(ids.at(i));
  604. }
  605. m_myDao->sqliteWrapper->execute(QString("delete mind_data where pid=%1").arg(m_projectId));
  606. m_projectId = -1;
  607. update();
  608. }
  609. void MindMapWidget::showSelPopMenu()
  610. {
  611. QPoint pt = m_selObject->rect.bottomLeft();
  612. pt = mapToGlobal(pt);
  613. QMenu *menu = new QMenu(this);
  614. QStringList menuNames;
  615. // menuNames << "打开链接"
  616. // << "使用百度搜索\"" + m_selObject->name() + "\""
  617. // << "复制文本"
  618. // << "粘贴文本"
  619. // << "添加剪贴板图片"
  620. // << "删除图片"
  621. // << "添加空结点"
  622. // << "添加剪贴板内容为结点"
  623. // << "进入结点"
  624. // << "标记结点"
  625. // << "剪切结点"
  626. // << "粘贴结点"
  627. // << "上移结点"
  628. // << "下移结点"
  629. // << "删除结点"
  630. // << "设置下级结点编号"
  631. // << "收缩结点"
  632. // << "返回导图";
  633. menuNames << "复制文本"
  634. << "粘贴文本"
  635. << "删除图片"
  636. << "添加空结点"
  637. << "标记结点"
  638. << "剪切结点"
  639. << "粘贴结点"
  640. << "上移结点"
  641. << "下移结点"
  642. << "删除结点"
  643. << "设置下级结点编号"
  644. << "收缩结点";
  645. for (int i = 0; i < menuNames.count(); i++) {
  646. if (menuNames[i] == "打开链接") {
  647. if (m_selObject->link().trimmed() == "") {
  648. continue;
  649. }
  650. } else if (menuNames[i] == "粘贴结点") {
  651. if (m_cutObject == nullptr) {
  652. continue;
  653. }
  654. } else if (menuNames[i] == "粘贴文本") {
  655. if (qApp->clipboard()->text() == "") {
  656. continue;
  657. }
  658. } else if (menuNames[i] == "添加剪贴板内容为结点") {
  659. if (qApp->clipboard()->text() == "") {
  660. continue;
  661. }
  662. } else if (menuNames[i] == "删除图片") {
  663. if (m_selObject->hasImg() == false) {
  664. continue;
  665. }
  666. } else if (menuNames[i] == "返回导图") {
  667. if (m_hasEntranceNode == false) {
  668. continue;
  669. }
  670. }
  671. QAction *act = new QAction(this);
  672. act->setText(menuNames[i]);
  673. connect(act, &QAction::triggered, this, &MindMapWidget::onPopMenuTrigger);
  674. menu->addAction(act);
  675. }
  676. menu->exec(pt);
  677. delete menu;
  678. m_mousedownFlag = false;
  679. }
  680. void MindMapWidget::showPopMenu()
  681. {
  682. QPoint pt = mapFromGlobal(cursor().pos());
  683. pt = mapToGlobal(pt);
  684. QMenu *menu = new QMenu(this);
  685. QStringList menuNames;
  686. menuNames << "开始截取本窗口"
  687. << "开始截取本窗口,然后自动保存"
  688. << "开始截取桌面"
  689. << "开始截取桌面(不隐藏当前窗口)"
  690. << "查找和替换"
  691. << "返回导图";
  692. for (int i = 0; i < menuNames.count(); i++) {
  693. if (menuNames[i] == "打开链接") {
  694. if (m_selObject->link().trimmed() == "") {
  695. continue;
  696. }
  697. } else if (menuNames[i] == "粘贴结点") {
  698. if (m_cutObject == nullptr) {
  699. continue;
  700. }
  701. } else if (menuNames[i] == "粘贴文本") {
  702. if (qApp->clipboard()->text() == "") {
  703. continue;
  704. }
  705. } else if (menuNames[i] == "添加剪贴板内容为结点") {
  706. if (qApp->clipboard()->text() == "") {
  707. continue;
  708. }
  709. }
  710. QAction *act = new QAction(this);
  711. act->setText(menuNames[i]);
  712. connect(act, &QAction::triggered, this, &MindMapWidget::onPopMenuTrigger);
  713. menu->addAction(act);
  714. }
  715. menu->exec(pt);
  716. delete menu;
  717. m_mousedownFlag = false;
  718. }
  719. void MindMapWidget::releaseMouseFlag()
  720. {
  721. m_mousedownFlag = false;
  722. update();
  723. }
  724. void MindMapWidget::showEditMarkNodeDialog()
  725. {
  726. if (m_selObject == nullptr) {
  727. return;
  728. }
  729. EditMarkNodeDialog *dlg = new EditMarkNodeDialog();
  730. dlg->setMarkNodes(m_selObject->markNodes);
  731. int ret = dlg->exec();
  732. if (ret == QDialog::Accepted) {
  733. m_myDao->sqliteWrapper->execute(QString("delete from mind_flag where pid=%1").arg(m_selObject->id()));
  734. m_selObject->markNodes = dlg->markNodes();
  735. for (int i : m_selObject->markNodes) {
  736. m_myDao->sqliteWrapper->execute(
  737. QString("insert into mind_flag (pid,flag) values (%1,%2)").arg(m_selObject->id()).arg(i));
  738. }
  739. update();
  740. }
  741. delete dlg;
  742. }
  743. void MindMapWidget::addMarkNodes(MindMapObject *obj)
  744. {
  745. QString sql = QString("select flag from mind_flag where pid=%1 order by id").arg(obj->id());
  746. QSqlQuery qry;
  747. m_myDao->sqliteWrapper->select(sql, qry);
  748. while (qry.next()) {
  749. obj->markNodes << qry.value(0).toInt();
  750. }
  751. }
  752. void MindMapWidget::saveDataAsPng()
  753. {
  754. QString path = QFileDialog::getSaveFileName(this, "导出为png", "导出.png", "png图片(*.png)");
  755. if (path == "") {
  756. return;
  757. }
  758. m_rootPoint = QPoint(32, 0);
  759. update();
  760. int w;
  761. int h;
  762. getDrawRect(w, h);
  763. QImage *img = new QImage(w * 2, h * 2, QImage::Format_RGB32);
  764. drawImage(img, w, h, 2);
  765. img->save(path, "png", 100);
  766. delete img;
  767. }
  768. void MindMapWidget::saveDataAsMarkdown()
  769. {
  770. QString path = QFileDialog::getSaveFileName(this, "导出为Markdown", "导出.md", "Markdown文件(*.md)");
  771. if (path == "") {
  772. return;
  773. }
  774. QStringList infos;
  775. showMindLineOutInfo(-1, "", infos, "#");
  776. QFile file(path);
  777. file.open(QIODevice::WriteOnly);
  778. QTextStream stm(&file);
  779. for (int i = 0; i < infos.count(); i++) {
  780. stm << infos[i] + "\n";
  781. }
  782. file.flush();
  783. file.close();
  784. }
  785. void MindMapWidget::saveDataAsTxtFile()
  786. {
  787. QString path = QFileDialog::getSaveFileName(this, "导出为txt文件", "导出.txt", "txt文件(*.txt)");
  788. if (path == "") {
  789. return;
  790. }
  791. QStringList infos;
  792. showMindLineOutInfo(-1, "", infos, "");
  793. qDebug() << infos;
  794. QFile file(path);
  795. file.open(QIODevice::WriteOnly);
  796. QTextStream stm(&file);
  797. for (int i = 0; i < infos.count(); i++) {
  798. if (infos[i].trimmed().isEmpty()) {
  799. stm << infos[i] + "NULL\n";
  800. } else {
  801. stm << infos[i] + "\n";
  802. }
  803. }
  804. file.flush();
  805. file.close();
  806. }
  807. void MindMapWidget::saveDataAsCsvFile()
  808. {
  809. QStringList infos;
  810. showMindLineOutInfo(-1, "", infos, "");
  811. if (infos.count() == 0) {
  812. return;
  813. }
  814. if (infos[0].trimmed().isEmpty()) {
  815. return;
  816. }
  817. QString path = QFileDialog::getSaveFileName(this, "导出为csv文件", infos[0].trimmed() + ".csv", "csv文件(*.csv)");
  818. if (path == "") {
  819. return;
  820. }
  821. QFile file(path);
  822. file.open(QIODevice::WriteOnly);
  823. QTextStream stm(&file);
  824. int sn[16];
  825. memset(sn, 0, sizeof(int) * 16);
  826. int spaceNum = -1;
  827. int level = 0;
  828. for (int i = 1; i < infos.count(); i++) {
  829. int tempSpace = 0;
  830. for (QString s : infos[i]) {
  831. if (s == " ") {
  832. tempSpace++;
  833. } else {
  834. break;
  835. }
  836. }
  837. if (spaceNum == -1) {
  838. spaceNum = tempSpace;
  839. level = 0;
  840. sn[level]++;
  841. } else if (spaceNum < tempSpace) { //空格增加
  842. spaceNum = tempSpace;
  843. level++;
  844. sn[level]++;
  845. } else if (spaceNum == tempSpace) { //同一级
  846. sn[level]++;
  847. } else {
  848. spaceNum = tempSpace;
  849. level = 0;
  850. sn[level]++;
  851. memset((void *)&sn[1], 0, sizeof(int) * 15);
  852. }
  853. QString node = "1";
  854. for (int l : sn) {
  855. if (l > 0) {
  856. node += QString(".%1").arg(l);
  857. } else {
  858. break;
  859. }
  860. }
  861. if (infos[i].trimmed().isEmpty()) {
  862. stm << node + ",NULL\n";
  863. } else {
  864. stm << node + "," + infos[i].trimmed() + "\n";
  865. }
  866. }
  867. file.flush();
  868. file.close();
  869. }
  870. void MindMapWidget::drawImage(QPaintDevice *paintDevice, int imgWidth, int imgHeight, int factor)
  871. {
  872. getMindWidgetsChildNum();
  873. QPoint pt = mapFromGlobal(cursor().pos());
  874. QPainter painter;
  875. painter.begin(paintDevice);
  876. painter.scale(factor, factor);
  877. painter.setRenderHints(QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing);
  878. QRect rc;
  879. rc.setRect(0, 0, imgWidth + 1, imgHeight + 1);
  880. if (m_backgroundId == 0) {
  881. painter.fillRect(rc, Qt::white);
  882. } else {
  883. painter.drawPixmap(rc, m_backGroundPix, m_backGroundPix.rect());
  884. }
  885. int x = m_rootPoint.x();
  886. int y = m_rootPoint.y();
  887. drawNode(-1, x, y, x, y, painter);
  888. drawRemark(painter);
  889. if (m_screenshotFlag == true) {
  890. if (m_mousedownFlag == true) {
  891. QRect drawRc, rc;
  892. getSelectRect(drawRc, m_startShot, pt);
  893. QPen pen = painter.pen();
  894. pen.setColor(Qt::black);
  895. pen.setStyle(Qt::DotLine);
  896. painter.setPen(pen);
  897. QColor color = QColor(0, 0, 0, 128);
  898. rc.setRect(0, 0, width(), drawRc.top());
  899. painter.fillRect(rc, QBrush(color));
  900. rc.setRect(0, drawRc.bottom() + 1, width(), height() - drawRc.bottom() - 1);
  901. painter.fillRect(rc, QBrush(color));
  902. rc.setRect(0, drawRc.top(), drawRc.left(), drawRc.height());
  903. painter.fillRect(rc, QBrush(color));
  904. rc.setRect(drawRc.right() + 1, drawRc.top(), width() - drawRc.right() - 1, drawRc.height());
  905. painter.fillRect(rc, QBrush(color));
  906. painter.setBrush(Qt::NoBrush);
  907. painter.drawRect(drawRc);
  908. pen = painter.pen();
  909. pen.setStyle(Qt::SolidLine);
  910. painter.setPen(pen);
  911. } else {
  912. painter.setPen(QColor(197, 197, 197));
  913. painter.drawLine(0, pt.y(), width(), pt.y());
  914. painter.drawLine(pt.x(), 0, pt.x(), height());
  915. }
  916. }
  917. painter.end();
  918. }
  919. void MindMapWidget::getDrawRect(int &w, int &h)
  920. {
  921. w = 0;
  922. h = 0;
  923. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  924. MindMapObject *obj = m_mindMapObjects.at(i);
  925. QRect rc = obj->rect;
  926. if (rc.right() > w) {
  927. w = rc.right();
  928. }
  929. if (rc.bottom() > h) {
  930. h = rc.bottom();
  931. }
  932. }
  933. w += 128;
  934. h += 128;
  935. }
  936. void MindMapWidget::reSetOrder(int pid)
  937. {
  938. int n = 1;
  939. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  940. MindMapObject *obj = m_mindMapObjects.at(i);
  941. if (obj->pid() == pid) {
  942. obj->setSxh(n);
  943. m_myDao->sqliteWrapper->execute(QString("update mind_data set sxh=%1 where id=%2").arg(n).arg(obj->id()));
  944. n++;
  945. }
  946. }
  947. }
  948. void MindMapWidget::setBackGroundId(int backGroundId)
  949. {
  950. m_backgroundId = backGroundId;
  951. if (m_backgroundId == 0) {
  952. m_backGroundPix = QPixmap();
  953. } else {
  954. m_backGroundPix = QPixmap(QString(":/res/background/%1.jpg").arg(m_backgroundId));
  955. }
  956. update();
  957. }
  958. int MindMapWidget::backGroundId()
  959. {
  960. return m_backgroundId;
  961. }
  962. void MindMapWidget::onAddChildNodeEvent()
  963. {
  964. MindMapObject *selObj = selObject();
  965. if (selObj == nullptr) {
  966. return;
  967. }
  968. int pid = selObj->id();
  969. int maxSxh = getNewMaxSxh(pid);
  970. int id = m_myDao->addNode(selObj->id(), "", maxSxh);
  971. MindMapObject *obj = addChildNode(selObj, id, "");
  972. obj->setSxh(maxSxh);
  973. update();
  974. EditNodeDialog *dlg = new EditNodeDialog();
  975. dlg->setWindowTitle("添加结点");
  976. int ret = dlg->exec();
  977. if (ret == QDialog::Accepted) {
  978. QString name = dlg->getName();
  979. m_myDao->editNode(obj->id(), name, dlg->getMessage());
  980. obj->setMessage(dlg->getMessage());
  981. editNode(obj, name);
  982. } else {
  983. deleteNodeById(id);
  984. reSetOrder(pid);
  985. }
  986. delete dlg;
  987. releaseMouseFlag();
  988. }
  989. void MindMapWidget::onAddChildNodeEvent(QString name)
  990. {
  991. MindMapObject *selObj = selObject();
  992. if (selObj == nullptr) {
  993. return;
  994. }
  995. int pid = selObj->id();
  996. int maxSxh = getNewMaxSxh(pid);
  997. int id = m_myDao->addNode(selObj->id(), name, maxSxh);
  998. addChildNode(selObj, id, name);
  999. releaseMouseFlag();
  1000. }
  1001. int MindMapWidget::getNewMaxSxh(int pid)
  1002. {
  1003. QSqlQuery qry;
  1004. QString sql;
  1005. sql = QString("select max(sxh) from mind_data where pid=%1").arg(pid);
  1006. m_myDao->sqliteWrapper->select(sql, qry);
  1007. if (qry.next()) {
  1008. return qry.value(0).toInt() + 1;
  1009. } else {
  1010. return 1;
  1011. }
  1012. }
  1013. void MindMapWidget::showMindLineOut()
  1014. {
  1015. QStringList infos;
  1016. showMindLineOutInfo(-1, "", infos);
  1017. ShowMindLineOutDialog *dlg = new ShowMindLineOutDialog();
  1018. dlg->setInfos(infos);
  1019. dlg->exec();
  1020. delete dlg;
  1021. }
  1022. void MindMapWidget::showMindLineOutInfo(int pid, QString prefix, QStringList &infos, QString sign, QString space)
  1023. {
  1024. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  1025. MindMapObject *obj = m_mindMapObjects.at(i);
  1026. if (obj->pid() == pid) {
  1027. if (sign == "#") {
  1028. infos << prefix + sign + " " + space + obj->name();
  1029. infos << "\n";
  1030. showMindLineOutInfo(obj->id(), prefix + "#", infos, sign, space + "&emsp;&emsp;");
  1031. } else {
  1032. infos << prefix + sign + obj->name();
  1033. showMindLineOutInfo(obj->id(), prefix + " ", infos, sign);
  1034. }
  1035. }
  1036. }
  1037. }
  1038. void MindMapWidget::showMindLineOutInfoWithRemark(int pid, QString prefix, QStringList &infos, QString sign,
  1039. QString space)
  1040. {
  1041. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  1042. MindMapObject *obj = m_mindMapObjects.at(i);
  1043. if (obj->pid() == pid) {
  1044. if (sign == "#") {
  1045. QString s;
  1046. s = prefix + sign + " " + space + obj->name() + "\t";
  1047. if (obj->message().isEmpty()) {
  1048. s += obj->name();
  1049. } else {
  1050. s += obj->message();
  1051. }
  1052. infos << s;
  1053. infos << "\n";
  1054. showMindLineOutInfoWithRemark(obj->id(), prefix + "#", infos, sign, space + "&emsp;&emsp;");
  1055. } else {
  1056. QString s;
  1057. s = prefix + sign + obj->name() + "\t";
  1058. if (obj->message().isEmpty()) {
  1059. s += obj->name();
  1060. } else {
  1061. s += obj->message();
  1062. }
  1063. infos << s;
  1064. showMindLineOutInfoWithRemark(obj->id(), prefix + " ", infos, sign);
  1065. }
  1066. }
  1067. }
  1068. }
  1069. void MindMapWidget::getSelectRect(QRect &rc, QPoint pt1, QPoint pt2)
  1070. {
  1071. int x = pt1.x();
  1072. if (x > pt2.x()) {
  1073. x = pt2.x();
  1074. }
  1075. int y = pt1.y();
  1076. if (y > pt2.y()) {
  1077. y = pt2.y();
  1078. }
  1079. rc.setRect(x, y, abs(pt1.x() - pt2.x()), abs(pt1.y() - pt2.y()));
  1080. }
  1081. QColor MindMapWidget::numColor(int sxh)
  1082. {
  1083. QColor colors[7] = { QColor(0, 0, 0), QColor(230, 66, 72), QColor(249, 182, 42), QColor(85, 101, 251),
  1084. QColor(187, 58, 172), QColor(43, 204, 91), QColor(28, 171, 252) };
  1085. if ((sxh >= 1) && (sxh <= 5)) {
  1086. return colors[sxh];
  1087. } else {
  1088. return colors[6];
  1089. }
  1090. }
  1091. void MindMapWidget::setNodeFontStyle(int setType)
  1092. {
  1093. if (m_selObject == nullptr) {
  1094. return;
  1095. }
  1096. QStringList fieldNames;
  1097. fieldNames << "bold"
  1098. << "italics"
  1099. << "overline"
  1100. << "underline"
  1101. << "strikeOut"
  1102. << "backColor";
  1103. if (setType <= 4) {
  1104. bool b = m_selObject->value(setType);
  1105. m_selObject->setValue(setType, !b);
  1106. b = m_selObject->value(setType);
  1107. m_myDao->sqliteWrapper->execute(QString("update mind_data set %1=%2 "
  1108. "where id=%3")
  1109. .arg(fieldNames[setType])
  1110. .arg(b2i(b))
  1111. .arg(m_selObject->id()));
  1112. } else if (setType == SET_FONT_BACKCOLOR) {
  1113. m_selObject->setBackColor(ColorTable::backColorIndex);
  1114. m_myDao->sqliteWrapper->execute(QString("update mind_data set backcolor=%1 "
  1115. "where id=%2")
  1116. .arg(ColorTable::backColorIndex)
  1117. .arg(m_selObject->id()));
  1118. } else if (setType == SET_FONT_COLOR) {
  1119. m_selObject->setFontColor(ColorTable::fontColorIndex);
  1120. m_myDao->sqliteWrapper->execute(QString("update mind_data set fontcolor=%1 "
  1121. "where id=%2")
  1122. .arg(ColorTable::fontColorIndex)
  1123. .arg(m_selObject->id()));
  1124. }
  1125. update();
  1126. }
  1127. void MindMapWidget::setFontStyle()
  1128. {
  1129. if (m_selObject == nullptr) {
  1130. return;
  1131. }
  1132. ColorTable::fontColorIndex = m_selObject->fontColor();
  1133. ColorTable::backColorIndex = m_selObject->backColor();
  1134. m_myDao->saveGlobalSet("fontcolorindex", ColorTable::fontColorIndex);
  1135. m_myDao->saveGlobalSet("backcolorindex", ColorTable::backColorIndex);
  1136. }
  1137. void MindMapWidget::applyFontStyle()
  1138. {
  1139. if (m_selObject == nullptr) {
  1140. return;
  1141. }
  1142. m_selObject->setFontColor(ColorTable::fontColorIndex);
  1143. m_selObject->setBackColor(ColorTable::backColorIndex);
  1144. m_myDao->sqliteWrapper->execute(QString("update mind_data set fontColor=%1 where id=%2")
  1145. .arg(ColorTable::fontColorIndex)
  1146. .arg(m_selObject->id()));
  1147. m_myDao->sqliteWrapper->execute(QString("update mind_data set backcolor=%1 where id=%2")
  1148. .arg(ColorTable::backColorIndex)
  1149. .arg(m_selObject->id()));
  1150. }
  1151. int MindMapWidget::b2i(bool b)
  1152. {
  1153. return b == true ? 1 : 0;
  1154. }
  1155. void MindMapWidget::setNodeNameFont(MindMapObject *obj, QPainter &painter, QFont &font)
  1156. {
  1157. font = painter.font();
  1158. font.setBold(obj->bold());
  1159. font.setItalic(obj->italics());
  1160. font.setUnderline(obj->underline());
  1161. font.setOverline(obj->overline());
  1162. font.setStrikeOut(obj->strikOut());
  1163. font.setPointSize(14);
  1164. painter.setFont(font);
  1165. }
  1166. void MindMapWidget::setFontAsDefault(QFont &font)
  1167. {
  1168. font.setItalic(false);
  1169. font.setUnderline(false);
  1170. font.setOverline(false);
  1171. font.setStrikeOut(false);
  1172. font.setBold(false);
  1173. }
  1174. void MindMapWidget::showBackColorEditDialog()
  1175. {
  1176. EditColorDialog *dlg = new EditColorDialog();
  1177. connect(dlg, &EditColorDialog::onAddColorIndex, this, &MindMapWidget::onAddColorIndex);
  1178. int ret = dlg->exec();
  1179. if (ret == QDialog::Accepted) {
  1180. int color = dlg->colorIndex();
  1181. ColorTable::backColorIndex = color;
  1182. m_myDao->saveGlobalSet("backcolorindex", color);
  1183. if (m_selObject != nullptr) {
  1184. m_selObject->setBackColor(color);
  1185. m_myDao->sqliteWrapper->execute(
  1186. QString("update mind_data set backColor=%1 where id=%2").arg(color).arg(m_selObject->id()));
  1187. }
  1188. update();
  1189. }
  1190. delete dlg;
  1191. }
  1192. void MindMapWidget::showFontColorEditDialog()
  1193. {
  1194. EditColorDialog *dlg = new EditColorDialog();
  1195. connect(dlg, &EditColorDialog::onAddColorIndex, this, &MindMapWidget::onAddColorIndex);
  1196. int ret = dlg->exec();
  1197. if (ret == QDialog::Accepted) {
  1198. int color = dlg->colorIndex();
  1199. m_myDao->saveGlobalSet("fontcolorindex", color);
  1200. ColorTable::fontColorIndex = color;
  1201. if (m_selObject != nullptr) {
  1202. m_selObject->setFontColor(color);
  1203. m_myDao->sqliteWrapper->execute(
  1204. QString("update mind_data set fontColor=%1 where id=%2").arg(color).arg(m_selObject->id()));
  1205. }
  1206. update();
  1207. }
  1208. delete dlg;
  1209. }
  1210. void MindMapWidget::saveMindMapAsNewProject()
  1211. {
  1212. QString sql;
  1213. int mpid;
  1214. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  1215. MindMapObject *oldObj = m_mindMapObjects.at(i);
  1216. sql = QString("insert into mind_data(name,remark,fontcolor,backcolor,sxh,shownum,bold,italics,"
  1217. "underline,overline,strikeOut) select name,remark,fontcolor,backcolor,sxh,shownum,bold,italics,"
  1218. "underline,overline,strikeOut from mind_data where id=%1")
  1219. .arg(oldObj->id());
  1220. m_myDao->sqliteWrapper->execute(sql);
  1221. int maxId = m_myDao->sqliteWrapper->getMaxId("mind_data");
  1222. MindMapObject *newObj = oldObj->newObj();
  1223. newObj->setId(maxId);
  1224. if (oldObj->pid() == -1) {
  1225. mpid = maxId;
  1226. newObj->setPid(-1);
  1227. m_myDao->sqliteWrapper->execute(QString("update mind_data set pid=-1 where id=%1").arg(maxId));
  1228. QDateTime d = QDateTime::currentDateTime();
  1229. QString s = oldObj->name() + d.toString("副本yyyyMMddhhmmss");
  1230. sql = QString("update mind_data set name='%1' where id=%2").arg(s).arg(maxId);
  1231. m_myDao->sqliteWrapper->execute(sql);
  1232. }
  1233. }
  1234. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  1235. MindMapObject *oldObj = m_mindMapObjects.at(i);
  1236. MindMapObject *newObj = oldObj->newObj();
  1237. if (newObj->pid() != -1) {
  1238. int pid = newObj->srcObj()->parentObj()->newObj()->id();
  1239. sql = QString("update mind_data set pid=%1 where id=%2").arg(pid).arg(newObj->id());
  1240. m_myDao->sqliteWrapper->execute(sql);
  1241. newObj->setPid(pid);
  1242. }
  1243. }
  1244. for (int i = 0; i < m_mindMapObjects.count(); i++) {
  1245. MindMapObject *oldObj = m_mindMapObjects.at(i);
  1246. MindMapObject *newObj = oldObj->newObj();
  1247. sql = QString("insert into mind_flag(pid,flag) "
  1248. "select %1 as pid,flag from mind_flag where pid=%2")
  1249. .arg(newObj->id())
  1250. .arg(oldObj->id());
  1251. m_myDao->sqliteWrapper->execute(sql);
  1252. }
  1253. sql = QString("insert into mind_set(pid,bid) values (%1,%2)").arg(mpid).arg(m_backgroundId);
  1254. m_myDao->sqliteWrapper->execute(sql);
  1255. openProject(mpid);
  1256. }
  1257. QList<MindMapObject *> &MindMapWidget::mindMapObjects()
  1258. {
  1259. return m_mindMapObjects;
  1260. }
  1261. MyDao *MindMapWidget::myDao()
  1262. {
  1263. return m_myDao;
  1264. }
  1265. void MindMapWidget::onPopMenuTrigger()
  1266. {
  1267. m_mousedownFlag = false;
  1268. QAction *act = static_cast<QAction *>(sender());
  1269. if (act->text() == "打开链接") {
  1270. if (m_selObject->link().startsWith("http")) {
  1271. QDesktopServices::openUrl(m_selObject->link());
  1272. } else {
  1273. QDesktopServices::openUrl(QUrl::fromLocalFile(m_selObject->link()));
  1274. }
  1275. } else if (act->text().startsWith("使用百度搜索")) {
  1276. QDesktopServices::openUrl("https://www.baidu.com/s?wd=" + m_selObject->name());
  1277. } else if (act->text() == "剪切结点") {
  1278. m_cutObject = m_selObject;
  1279. } else if (act->text() == "粘贴结点") {
  1280. if (m_cutObject == nullptr) {
  1281. return;
  1282. }
  1283. int id = m_selObject->id();
  1284. int newPid = m_selObject->id();
  1285. m_cutObject->setPid(newPid);
  1286. m_myDao->sqliteWrapper->execute(QString("update mind_data set pid=%1 where id=%2").arg(newPid).arg(id));
  1287. m_cutObject = nullptr;
  1288. update();
  1289. } else if (act->text() == "标记结点") {
  1290. showEditMarkNodeDialog();
  1291. } else if (act->text() == "复制文本") {
  1292. qApp->clipboard()->setText(m_selObject->name());
  1293. } else if (act->text() == "应用上次文字效果") {
  1294. if (m_selObject == nullptr) {
  1295. return;
  1296. }
  1297. int color;
  1298. color = ColorTable::fontColorIndex;
  1299. m_selObject->setFontColor(color);
  1300. m_myDao->sqliteWrapper->execute(
  1301. QString("update mind_data set fontColor=%1 where id=%2").arg(color).arg(m_selObject->id()));
  1302. color = ColorTable::backColorIndex;
  1303. m_selObject->setBackColor(color);
  1304. m_myDao->sqliteWrapper->execute(
  1305. QString("update mind_data set backColor=%1 where id=%2").arg(color).arg(m_selObject->id()));
  1306. update();
  1307. } else if (act->text() == "上移结点") {
  1308. int pid = m_selObject->pid();
  1309. int m = m_mindMapObjects.indexOf(m_selObject);
  1310. for (int i = m - 1; i >= 0; i--) {
  1311. MindMapObject *obj = m_mindMapObjects.at(i);
  1312. if (obj->pid() == pid) {
  1313. m_mindMapObjects.swap(i, m);
  1314. reSetOrder(pid);
  1315. update();
  1316. return;
  1317. }
  1318. }
  1319. } else if (act->text() == "下移结点") {
  1320. int pid = m_selObject->pid();
  1321. int m = m_mindMapObjects.indexOf(m_selObject);
  1322. for (int i = m + 1; i < m_mindMapObjects.count(); i++) {
  1323. MindMapObject *obj = m_mindMapObjects.at(i);
  1324. if (obj->pid() == pid) {
  1325. m_mindMapObjects.swap(i, m);
  1326. reSetOrder(pid);
  1327. update();
  1328. return;
  1329. }
  1330. }
  1331. } else if (act->text() == "删除结点") {
  1332. delSelObject();
  1333. } else if (act->text() == "进入结点") {
  1334. if (m_selObject == nullptr) {
  1335. return;
  1336. }
  1337. entranceNode(-1, m_selObject->id());
  1338. } else if (act->text() == "返回导图") {
  1339. backToMindMap();
  1340. } else if (act->text() == "粘贴文本") {
  1341. if (m_selObject == nullptr) {
  1342. return;
  1343. }
  1344. QString text = qApp->clipboard()->text();
  1345. if (text.trimmed() == "") {
  1346. return;
  1347. }
  1348. m_selObject->setName(text);
  1349. m_myDao->editNode(m_selObject->id(), text);
  1350. update();
  1351. } else if (act->text() == "添加剪贴板图片") {
  1352. if (m_selObject == nullptr) {
  1353. return;
  1354. }
  1355. QPixmap pix = qApp->clipboard()->pixmap();
  1356. if (!pix.isNull()) {
  1357. m_selObject->setImg(pix);
  1358. m_selObject->setHasImg(true);
  1359. m_myDao->addPix(m_selObject->id(), pix);
  1360. update();
  1361. }
  1362. } else if (act->text() == "删除图片") {
  1363. if (m_selObject == nullptr) {
  1364. return;
  1365. }
  1366. m_selObject->setHasImg(false);
  1367. QPixmap pix = QPixmap();
  1368. m_selObject->setImg(pix);
  1369. m_myDao->sqliteWrapper->execute(QString("update mind_data set img=null where id=%1").arg(m_selObject->id()));
  1370. update();
  1371. } else if (act->text() == "添加空结点") {
  1372. onAddChildNodeEvent("");
  1373. } else if (act->text() == "添加剪贴板内容为结点") {
  1374. onAddChildNodeEvent(qApp->clipboard()->text());
  1375. } else if (act->text() == "开始截取本窗口") {
  1376. m_screenshotFlag = true;
  1377. m_saveshotToFile = false;
  1378. } else if (act->text() == "开始截取本窗口,然后自动保存") {
  1379. m_screenshotFlag = true;
  1380. m_saveshotToFile = true;
  1381. } else if (act->text() == "设置下级结点编号") {
  1382. m_selObject->setShowNum(!m_selObject->showNum());
  1383. int shownum = m_selObject->showNum() == true ? 1 : 0;
  1384. m_myDao->sqliteWrapper->execute(
  1385. QString("update mind_data set shownum=%1 where id=%2").arg(shownum).arg(m_selObject->id()));
  1386. update();
  1387. } else if (act->text() == "查找和替换") {
  1388. SearchAndReplaceDialog *dlg = new SearchAndReplaceDialog();
  1389. dlg->setMindMapWidget(this);
  1390. dlg->exec();
  1391. } else if (act->text() == "开始截取桌面") {
  1392. startShootScreen();
  1393. } else if (act->text() == "开始截取桌面(不隐藏当前窗口)") {
  1394. startShootScreen(false);
  1395. } else if (act->text() == "收缩结点") {
  1396. if (m_selObject == nullptr) {
  1397. return;
  1398. }
  1399. m_selObject->setShrink(true);
  1400. m_myDao->sqliteWrapper->execute(QString("update mind_data set shrink=1 where id=%1").arg(m_selObject->id()));
  1401. update();
  1402. }
  1403. }
  1404. void MindMapWidget::onAddColorIndex(int colorIndex)
  1405. {
  1406. QString sql = QString("insert into mind_color(colorindex) values (%1)").arg(colorIndex);
  1407. m_myDao->sqliteWrapper->execute(sql);
  1408. }
  1409. int MindMapWidget::getMaxLen(QStringList &stl)
  1410. {
  1411. int n = 0;
  1412. int index = 0;
  1413. for (int i = 0; i < stl.count(); i++) {
  1414. int m = stl[i].length();
  1415. if (m > n) {
  1416. n = m;
  1417. index = i;
  1418. }
  1419. }
  1420. return index;
  1421. }
  1422. void MindMapWidget::loadBackground()
  1423. {
  1424. QSqlQuery qry;
  1425. m_myDao->sqliteWrapper->select(QString("select bid from mind_set where pid=%1").arg(m_projectId), qry);
  1426. if (qry.next()) {
  1427. m_backgroundId = qry.value(0).toInt();
  1428. } else {
  1429. m_backgroundId = 0;
  1430. }
  1431. setBackGroundId(m_backgroundId);
  1432. }
  1433. int MindMapWidget::getQryValue(QSqlQuery &qry, int index, int defaultValue)
  1434. {
  1435. if (qry.value(index).isNull()) {
  1436. return defaultValue;
  1437. } else {
  1438. return qry.value(index).toInt();
  1439. }
  1440. }
  1441. int MindMapWidget::getQryValue(QSqlQuery &qry, QString fieldName, int defaultValue)
  1442. {
  1443. if (qry.value(fieldName).isNull()) {
  1444. return defaultValue;
  1445. } else {
  1446. return qry.value(fieldName).toInt();
  1447. }
  1448. }
  1449. bool MindMapWidget::getQryValueBool(QSqlQuery &qry, QString fieldName, bool defaultValue)
  1450. {
  1451. if (qry.value(fieldName).isNull()) {
  1452. return defaultValue;
  1453. } else {
  1454. return qry.value(fieldName).toInt() == 1;
  1455. }
  1456. }