vsettingsdialog.cpp 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313
  1. #include "vsettingsdialog.h"
  2. #include <QtWidgets>
  3. #include <QRegExp>
  4. #include <QToolTip>
  5. #include "vconfigmanager.h"
  6. #include "utils/vutils.h"
  7. #include "vconstants.h"
  8. #include "vlineedit.h"
  9. #include "vplantumlhelper.h"
  10. #include "vgraphvizhelper.h"
  11. extern VConfigManager *g_config;
  12. VSettingsDialog::VSettingsDialog(QWidget *p_parent)
  13. : QDialog(p_parent)
  14. {
  15. m_tabList = new QListWidget(this);
  16. m_tabList->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
  17. m_tabs = new QStackedLayout();
  18. // Reset VNote.
  19. m_resetVNoteBtn = new QPushButton(tr("Reset VNote"), this);
  20. m_resetVNoteBtn->setProperty("DangerBtn", true);
  21. m_resetVNoteBtn->setToolTip(tr("Reset all the configurations of VNote"));
  22. connect(m_resetVNoteBtn, &QPushButton::clicked,
  23. this, &VSettingsDialog::resetVNote);
  24. // Reset Layout.
  25. m_resetLayoutBtn = new QPushButton(tr("Reset Layout"), this);
  26. m_resetLayoutBtn->setToolTip(tr("Reset layout of VNote"));
  27. connect(m_resetLayoutBtn, &QPushButton::clicked,
  28. this, &VSettingsDialog::resetLayout);
  29. m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
  30. connect(m_btnBox, &QDialogButtonBox::accepted, this, &VSettingsDialog::saveConfiguration);
  31. connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
  32. m_btnBox->button(QDialogButtonBox::Ok)->setProperty("SpecialBtn", true);
  33. m_btnBox->addButton(m_resetVNoteBtn, QDialogButtonBox::ResetRole);
  34. m_btnBox->addButton(m_resetLayoutBtn, QDialogButtonBox::ResetRole);
  35. QHBoxLayout *tabLayout = new QHBoxLayout();
  36. tabLayout->addWidget(m_tabList);
  37. tabLayout->addLayout(m_tabs);
  38. tabLayout->setContentsMargins(0, 0, 0, 0);
  39. tabLayout->setSpacing(0);
  40. tabLayout->setStretch(0, 0);
  41. tabLayout->setStretch(1, 5);
  42. QVBoxLayout *mainLayout = new QVBoxLayout();
  43. mainLayout->addLayout(tabLayout);
  44. mainLayout->addWidget(m_btnBox);
  45. setLayout(mainLayout);
  46. setWindowTitle(tr("Settings"));
  47. // Add tabs.
  48. addTab(new VGeneralTab(), tr("General"));
  49. addTab(new VLookTab(), tr("Appearance"));
  50. addTab(new VReadEditTab(), tr("Read/Edit"));
  51. addTab(new VNoteManagementTab(), tr("Note Management"));
  52. addTab(new VMarkdownTab(), tr("Markdown"));
  53. m_tabList->setMaximumWidth(m_tabList->sizeHintForColumn(0) + 5);
  54. connect(m_tabList, &QListWidget::currentItemChanged,
  55. this, [this](QListWidgetItem *p_cur, QListWidgetItem *p_pre) {
  56. Q_UNUSED(p_pre);
  57. Q_ASSERT(p_cur);
  58. int idx = p_cur->data(Qt::UserRole).toInt();
  59. Q_ASSERT(idx >= 0);
  60. m_tabs->setCurrentWidget(m_tabs->widget(idx));
  61. });
  62. m_tabList->setCurrentRow(0);
  63. loadConfiguration();
  64. }
  65. void VSettingsDialog::resetVNote()
  66. {
  67. int ret = VUtils::showMessage(QMessageBox::Warning,
  68. tr("Warning"),
  69. tr("Are you sure to reset VNote?"),
  70. tr("All configurations (except notebooks information) "
  71. "will be reset to default values. "
  72. "It is UNRECOVERABLE!"),
  73. QMessageBox::Ok | QMessageBox::Cancel,
  74. QMessageBox::Cancel,
  75. this,
  76. MessageBoxType::Danger);
  77. if (ret == QMessageBox::Cancel) {
  78. return;
  79. }
  80. g_config->resetConfigurations();
  81. VUtils::showMessage(QMessageBox::Information,
  82. tr("Information"),
  83. tr("Please restart VNote to make it work."),
  84. tr("Any change to VNote before restart will be lost!"),
  85. QMessageBox::Ok,
  86. QMessageBox::Ok,
  87. this);
  88. reject();
  89. }
  90. void VSettingsDialog::resetLayout()
  91. {
  92. int ret = VUtils::showMessage(QMessageBox::Warning,
  93. tr("Warning"),
  94. tr("Are you sure to reset the layout of VNote?"),
  95. tr("The view and layout mode will be reset. "
  96. "It is UNRECOVERABLE!"),
  97. QMessageBox::Ok | QMessageBox::Cancel,
  98. QMessageBox::Cancel,
  99. this,
  100. MessageBoxType::Danger);
  101. if (ret == QMessageBox::Cancel) {
  102. return;
  103. }
  104. g_config->resetLayoutConfigurations();
  105. VUtils::showMessage(QMessageBox::Information,
  106. tr("Information"),
  107. tr("Please restart VNote to make it work."),
  108. tr("Any change to VNote before restart will be lost!"),
  109. QMessageBox::Ok,
  110. QMessageBox::Ok,
  111. this);
  112. reject();
  113. }
  114. void VSettingsDialog::addTab(QWidget *p_widget, const QString &p_label)
  115. {
  116. int idx = m_tabs->addWidget(p_widget);
  117. QListWidgetItem *item = new QListWidgetItem(p_label, m_tabList);
  118. item->setData(Qt::UserRole, idx);
  119. }
  120. void VSettingsDialog::loadConfiguration()
  121. {
  122. int idx = 0;
  123. // General Tab.
  124. {
  125. VGeneralTab *generalTab = dynamic_cast<VGeneralTab *>(m_tabs->widget(idx++));
  126. Q_ASSERT(generalTab);
  127. if (!generalTab->loadConfiguration()) {
  128. goto err;
  129. }
  130. }
  131. // Appearance Tab.
  132. {
  133. VLookTab *lookTab = dynamic_cast<VLookTab *>(m_tabs->widget(idx++));
  134. Q_ASSERT(lookTab);
  135. if (!lookTab->loadConfiguration()) {
  136. goto err;
  137. }
  138. }
  139. // Read/Edit Tab.
  140. {
  141. VReadEditTab *readEditTab = dynamic_cast<VReadEditTab *>(m_tabs->widget(idx++));
  142. Q_ASSERT(readEditTab);
  143. if (!readEditTab->loadConfiguration()) {
  144. goto err;
  145. }
  146. }
  147. // Note Management Tab.
  148. {
  149. VNoteManagementTab *noteManagementTab = dynamic_cast<VNoteManagementTab *>(m_tabs->widget(idx++));
  150. Q_ASSERT(noteManagementTab);
  151. if (!noteManagementTab->loadConfiguration()) {
  152. goto err;
  153. }
  154. }
  155. // Markdown Tab.
  156. {
  157. VMarkdownTab *markdownTab = dynamic_cast<VMarkdownTab *>(m_tabs->widget(idx++));
  158. Q_ASSERT(markdownTab);
  159. if (!markdownTab->loadConfiguration()) {
  160. goto err;
  161. }
  162. }
  163. return;
  164. err:
  165. VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
  166. tr("Fail to load configuration."), "",
  167. QMessageBox::Ok, QMessageBox::Ok, NULL);
  168. QMetaObject::invokeMethod(this, "reject", Qt::QueuedConnection);
  169. }
  170. void VSettingsDialog::saveConfiguration()
  171. {
  172. int idx = 0;
  173. // General Tab.
  174. {
  175. VGeneralTab *generalTab = dynamic_cast<VGeneralTab *>(m_tabs->widget(idx++));
  176. Q_ASSERT(generalTab);
  177. if (!generalTab->saveConfiguration()) {
  178. goto err;
  179. }
  180. }
  181. // Appearance Tab.
  182. {
  183. VLookTab *lookTab = dynamic_cast<VLookTab *>(m_tabs->widget(idx++));
  184. Q_ASSERT(lookTab);
  185. if (!lookTab->saveConfiguration()) {
  186. goto err;
  187. }
  188. }
  189. // Read/Edit Tab.
  190. {
  191. VReadEditTab *readEditTab = dynamic_cast<VReadEditTab *>(m_tabs->widget(idx++));
  192. Q_ASSERT(readEditTab);
  193. if (!readEditTab->saveConfiguration()) {
  194. goto err;
  195. }
  196. }
  197. // Note Management Tab.
  198. {
  199. VNoteManagementTab *noteManagementTab = dynamic_cast<VNoteManagementTab *>(m_tabs->widget(idx++));
  200. Q_ASSERT(noteManagementTab);
  201. if (!noteManagementTab->saveConfiguration()) {
  202. goto err;
  203. }
  204. }
  205. // Markdown Tab.
  206. {
  207. VMarkdownTab *markdownTab = dynamic_cast<VMarkdownTab *>(m_tabs->widget(idx++));
  208. Q_ASSERT(markdownTab);
  209. if (!markdownTab->saveConfiguration()) {
  210. goto err;
  211. }
  212. }
  213. accept();
  214. return;
  215. err:
  216. VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
  217. tr("Fail to save configuration. Please try it again."), "",
  218. QMessageBox::Ok, QMessageBox::Ok, NULL);
  219. }
  220. const QVector<QString> VGeneralTab::c_availableLangs = { "System", "English", "Chinese" };
  221. VGeneralTab::VGeneralTab(QWidget *p_parent)
  222. : QWidget(p_parent)
  223. {
  224. // Language combo.
  225. m_langCombo = VUtils::getComboBox(this);
  226. m_langCombo->setToolTip(tr("Choose the language of VNote interface"));
  227. m_langCombo->addItem(tr("System"), "System");
  228. auto langs = VUtils::getAvailableLanguages();
  229. for (auto const &lang : langs) {
  230. m_langCombo->addItem(lang.second, lang.first);
  231. }
  232. // System tray checkbox.
  233. m_systemTray = new QCheckBox(tr("System tray"), this);
  234. m_systemTray->setToolTip(tr("Minimized to the system tray after closing VNote"
  235. " (not supported in macOS)"));
  236. #if defined(Q_OS_MACOS) || defined(Q_OS_MAC)
  237. // Do not support minimized to tray on macOS.
  238. m_systemTray->setEnabled(false);
  239. #endif
  240. // Startup pages.
  241. QLayout *startupLayout = setupStartupPagesLayout();
  242. QFormLayout *optionLayout = new QFormLayout();
  243. optionLayout->addRow(tr("Language:"), m_langCombo);
  244. optionLayout->addRow(m_systemTray);
  245. optionLayout->addRow(tr("Startup pages:"), startupLayout);
  246. QVBoxLayout *mainLayout = new QVBoxLayout();
  247. mainLayout->addLayout(optionLayout);
  248. setLayout(mainLayout);
  249. }
  250. QLayout *VGeneralTab::setupStartupPagesLayout()
  251. {
  252. m_startupPageTypeCombo = VUtils::getComboBox(this);
  253. m_startupPageTypeCombo->setToolTip(tr("Restore tabs or open specific notes on startup"));
  254. m_startupPageTypeCombo->addItem(tr("None"), (int)StartupPageType::None);
  255. m_startupPageTypeCombo->addItem(tr("Continue where you left off"), (int)StartupPageType::ContinueLeftOff);
  256. m_startupPageTypeCombo->addItem(tr("Open specific pages"), (int)StartupPageType::SpecificPages);
  257. connect(m_startupPageTypeCombo, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
  258. this, [this](int p_index) {
  259. int type = m_startupPageTypeCombo->itemData(p_index).toInt();
  260. bool pagesEditVisible = type == (int)StartupPageType::SpecificPages;
  261. m_startupPagesEdit->setVisible(pagesEditVisible);
  262. m_startupPagesAddBtn->setVisible(pagesEditVisible);
  263. });
  264. m_startupPagesEdit = new QPlainTextEdit(this);
  265. m_startupPagesEdit->setProperty("LineEdit", true);
  266. m_startupPagesEdit->setToolTip(tr("Absolute path of the notes to open on startup (one note per line)"));
  267. m_startupPagesAddBtn = new QPushButton(tr("Browse"), this);
  268. m_startupPagesAddBtn->setToolTip(tr("Select files to add as startup pages"));
  269. connect(m_startupPagesAddBtn, &QPushButton::clicked,
  270. this, [this]() {
  271. static QString lastPath = QDir::homePath();
  272. QStringList files = QFileDialog::getOpenFileNames(this,
  273. tr("Select Files As Startup Pages"),
  274. lastPath);
  275. if (files.isEmpty()) {
  276. return;
  277. }
  278. // Update lastPath
  279. lastPath = QFileInfo(files[0]).path();
  280. m_startupPagesEdit->appendPlainText(files.join("\n"));
  281. });
  282. QHBoxLayout *startupPagesBtnLayout = new QHBoxLayout();
  283. startupPagesBtnLayout->addStretch();
  284. startupPagesBtnLayout->addWidget(m_startupPagesAddBtn);
  285. QVBoxLayout *startupPagesLayout = new QVBoxLayout();
  286. startupPagesLayout->addWidget(m_startupPagesEdit);
  287. startupPagesLayout->addLayout(startupPagesBtnLayout);
  288. QVBoxLayout *startupLayout = new QVBoxLayout();
  289. startupLayout->addWidget(m_startupPageTypeCombo);
  290. startupLayout->addLayout(startupPagesLayout);
  291. m_startupPagesEdit->hide();
  292. m_startupPagesAddBtn->hide();
  293. return startupLayout;
  294. }
  295. bool VGeneralTab::loadConfiguration()
  296. {
  297. if (!loadLanguage()) {
  298. return false;
  299. }
  300. if (!loadSystemTray()) {
  301. return false;
  302. }
  303. if (!loadStartupPageType()) {
  304. return false;
  305. }
  306. return true;
  307. }
  308. bool VGeneralTab::saveConfiguration()
  309. {
  310. if (!saveLanguage()) {
  311. return false;
  312. }
  313. if (!saveSystemTray()) {
  314. return false;
  315. }
  316. if (!saveStartupPageType()) {
  317. return false;
  318. }
  319. return true;
  320. }
  321. bool VGeneralTab::loadLanguage()
  322. {
  323. QString lang = g_config->getLanguage();
  324. if (lang.isNull()) {
  325. return false;
  326. } else if (lang == "System") {
  327. m_langCombo->setCurrentIndex(0);
  328. return true;
  329. }
  330. bool found = false;
  331. // lang is the value, not name.
  332. for (int i = 0; i < m_langCombo->count(); ++i) {
  333. if (m_langCombo->itemData(i).toString() == lang) {
  334. found = true;
  335. m_langCombo->setCurrentIndex(i);
  336. break;
  337. }
  338. }
  339. if (!found) {
  340. qWarning() << "invalid language configuration (using default value)";
  341. m_langCombo->setCurrentIndex(0);
  342. }
  343. return true;
  344. }
  345. bool VGeneralTab::saveLanguage()
  346. {
  347. QString curLang = m_langCombo->currentData().toString();
  348. g_config->setLanguage(curLang);
  349. return true;
  350. }
  351. bool VGeneralTab::loadSystemTray()
  352. {
  353. m_systemTray->setChecked(g_config->getMinimizeToStystemTray() != 0);
  354. return true;
  355. }
  356. bool VGeneralTab::saveSystemTray()
  357. {
  358. if (m_systemTray->isEnabled()) {
  359. g_config->setMinimizeToSystemTray(m_systemTray->isChecked() ? 1 : 0);
  360. }
  361. return true;
  362. }
  363. bool VGeneralTab::loadStartupPageType()
  364. {
  365. StartupPageType type = g_config->getStartupPageType();
  366. bool found = false;
  367. for (int i = 0; i < m_startupPageTypeCombo->count(); ++i) {
  368. if (m_startupPageTypeCombo->itemData(i).toInt() == (int)type) {
  369. found = true;
  370. m_startupPageTypeCombo->setCurrentIndex(i);
  371. }
  372. }
  373. Q_ASSERT(found);
  374. const QStringList &pages = g_config->getStartupPages();
  375. m_startupPagesEdit->setPlainText(pages.join("\n"));
  376. bool pagesEditVisible = type == StartupPageType::SpecificPages;
  377. m_startupPagesEdit->setVisible(pagesEditVisible);
  378. m_startupPagesAddBtn->setVisible(pagesEditVisible);
  379. return true;
  380. }
  381. bool VGeneralTab::saveStartupPageType()
  382. {
  383. StartupPageType type = (StartupPageType)m_startupPageTypeCombo->currentData().toInt();
  384. g_config->setStartupPageType(type);
  385. if (type == StartupPageType::SpecificPages) {
  386. QStringList pages = m_startupPagesEdit->toPlainText().split("\n");
  387. g_config->setStartupPages(pages);
  388. }
  389. return true;
  390. }
  391. VLookTab::VLookTab(QWidget *p_parent)
  392. : QWidget(p_parent)
  393. {
  394. m_tbIconSizeSpin = new QSpinBox(this);
  395. m_tbIconSizeSpin->setToolTip(tr("Icon size in pixel of tool bar (restart VNote to make it work)"));
  396. m_tbIconSizeSpin->setMaximum(100);
  397. m_tbIconSizeSpin->setMinimum(5);
  398. QFormLayout *layout = new QFormLayout();
  399. layout->addRow(tr("Tool bar icon size:"), m_tbIconSizeSpin);
  400. setLayout(layout);
  401. }
  402. bool VLookTab::loadConfiguration()
  403. {
  404. if (!loadToolBarIconSize()) {
  405. return false;
  406. }
  407. return true;
  408. }
  409. bool VLookTab::saveConfiguration()
  410. {
  411. if (!saveToolBarIconSize()) {
  412. return false;
  413. }
  414. return true;
  415. }
  416. bool VLookTab::loadToolBarIconSize()
  417. {
  418. int sz = g_config->getToolBarIconSize();
  419. m_tbIconSizeSpin->setValue(sz);
  420. return true;
  421. }
  422. bool VLookTab::saveToolBarIconSize()
  423. {
  424. g_config->setToolBarIconSize(m_tbIconSizeSpin->value());
  425. return true;
  426. }
  427. VReadEditTab::VReadEditTab(QWidget *p_parent)
  428. : QWidget(p_parent)
  429. {
  430. m_readBox = new QGroupBox(tr("Read Mode (For Markdown Only)"));
  431. m_editBox = new QGroupBox(tr("Edit Mode"));
  432. // Web Zoom Factor.
  433. m_customWebZoom = new QCheckBox(tr("Custom Web zoom factor"));
  434. m_customWebZoom->setToolTip(tr("Set the zoom factor of the Web page when reading"));
  435. m_webZoomFactorSpin = new QDoubleSpinBox();
  436. m_webZoomFactorSpin->setMaximum(c_webZoomFactorMax);
  437. m_webZoomFactorSpin->setMinimum(c_webZoomFactorMin);
  438. m_webZoomFactorSpin->setSingleStep(0.25);
  439. connect(m_customWebZoom, &QCheckBox::stateChanged,
  440. this, [this](int p_state) {
  441. this->m_webZoomFactorSpin->setEnabled(p_state == Qt::Checked);
  442. });
  443. QHBoxLayout *zoomFactorLayout = new QHBoxLayout();
  444. zoomFactorLayout->addWidget(m_customWebZoom);
  445. zoomFactorLayout->addWidget(m_webZoomFactorSpin);
  446. // Web flash anchor.
  447. m_flashAnchor = new QCheckBox(tr("Flash current heading"));
  448. m_flashAnchor->setToolTip(tr("Flash current heading on change"));
  449. // Swap file.
  450. m_swapFile = new QCheckBox(tr("Swap file"));
  451. m_swapFile->setToolTip(tr("Automatically save changes to a swap file for backup"));
  452. connect(m_swapFile, &QCheckBox::stateChanged,
  453. this, &VReadEditTab::showTipsAboutAutoSave);
  454. // Auto save.
  455. m_autoSave = new QCheckBox(tr("Auto save"));
  456. m_autoSave->setToolTip(tr("Automatically save the note when editing"));
  457. connect(m_autoSave, &QCheckBox::stateChanged,
  458. this, &VReadEditTab::showTipsAboutAutoSave);
  459. // Key mode.
  460. m_keyModeCB = VUtils::getComboBox();
  461. m_keyModeCB->setToolTip(tr("Choose the key mode in editor"));
  462. m_keyModeCB->addItem(tr("Normal"), (int)KeyMode::Normal);
  463. m_keyModeCB->addItem(tr("Vim"), (int)KeyMode::Vim);
  464. connect(m_keyModeCB, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
  465. this, [this](int p_index) {
  466. int mode = m_keyModeCB->itemData(p_index).toInt();
  467. m_smartIM->setVisible(mode == (int)KeyMode::Vim);
  468. });
  469. // Smart IM in Vim.
  470. m_smartIM = new QCheckBox(tr("Smart input method in Vim mode"));
  471. m_smartIM->setToolTip(tr("Disable input method when leaving Insert mode in Vim mode"));
  472. // Editor zoom delta.
  473. m_editorZoomDeltaSpin = new QSpinBox();
  474. m_editorZoomDeltaSpin->setToolTip(tr("Set the zoom delta of the editor font"));
  475. m_editorZoomDeltaSpin->setMaximum(c_editorZoomDeltaMax);
  476. m_editorZoomDeltaSpin->setMinimum(c_editorZoomDeltaMin);
  477. m_editorZoomDeltaSpin->setSingleStep(1);
  478. QVBoxLayout *readLayout = new QVBoxLayout();
  479. readLayout->addLayout(zoomFactorLayout);
  480. readLayout->addWidget(m_flashAnchor);
  481. m_readBox->setLayout(readLayout);
  482. QFormLayout *editLayout = new QFormLayout();
  483. editLayout->addRow(m_swapFile);
  484. editLayout->addRow(m_autoSave);
  485. editLayout->addRow(tr("Key mode:"), m_keyModeCB);
  486. editLayout->addWidget(m_smartIM);
  487. editLayout->addRow(tr("Editor zoom delta:"), m_editorZoomDeltaSpin);
  488. m_editBox->setLayout(editLayout);
  489. m_smartIM->hide();
  490. m_keyModeCB->setCurrentIndex(0);
  491. QVBoxLayout *mainLayout = new QVBoxLayout();
  492. mainLayout->addWidget(m_readBox);
  493. mainLayout->addWidget(m_editBox);
  494. setLayout(mainLayout);
  495. }
  496. void VReadEditTab::showTipsAboutAutoSave()
  497. {
  498. if (m_autoSave->isChecked() && m_swapFile->isChecked()) {
  499. // Show a tooltip.
  500. QPoint pos = m_editBox->mapToGlobal(QPoint(0, 0));
  501. QToolTip::showText(pos,
  502. tr("It's recommended to enable \"Swap file\" "
  503. "or \"Auto save\", not both"),
  504. m_editBox);
  505. }
  506. }
  507. bool VReadEditTab::loadConfiguration()
  508. {
  509. if (!loadWebZoomFactor()) {
  510. return false;
  511. }
  512. if (!loadFlashAnchor()) {
  513. return false;
  514. }
  515. if (!loadSwapFile()) {
  516. return false;
  517. }
  518. if (!loadAutoSave()) {
  519. return false;
  520. }
  521. if (!loadEditorZoomDelta()) {
  522. return false;
  523. }
  524. if (!loadKeyMode()) {
  525. return false;
  526. }
  527. return true;
  528. }
  529. bool VReadEditTab::saveConfiguration()
  530. {
  531. if (!saveWebZoomFactor()) {
  532. return false;
  533. }
  534. if (!saveFlashAnchor()) {
  535. return false;
  536. }
  537. if (!saveSwapFile()) {
  538. return false;
  539. }
  540. if (!saveAutoSave()) {
  541. return false;
  542. }
  543. if (!saveEditorZoomDelta()) {
  544. return false;
  545. }
  546. if (!saveKeyMode()) {
  547. return false;
  548. }
  549. return true;
  550. }
  551. bool VReadEditTab::loadWebZoomFactor()
  552. {
  553. qreal factor = g_config->getWebZoomFactor();
  554. bool customFactor = g_config->isCustomWebZoomFactor();
  555. if (customFactor) {
  556. if (factor < c_webZoomFactorMin || factor > c_webZoomFactorMax) {
  557. factor = 1;
  558. }
  559. m_customWebZoom->setChecked(true);
  560. m_webZoomFactorSpin->setValue(factor);
  561. } else {
  562. m_customWebZoom->setChecked(false);
  563. m_webZoomFactorSpin->setValue(factor);
  564. m_webZoomFactorSpin->setEnabled(false);
  565. }
  566. return true;
  567. }
  568. bool VReadEditTab::saveWebZoomFactor()
  569. {
  570. if (m_customWebZoom->isChecked()) {
  571. g_config->setWebZoomFactor(m_webZoomFactorSpin->value());
  572. } else {
  573. g_config->setWebZoomFactor(-1);
  574. }
  575. return true;
  576. }
  577. bool VReadEditTab::loadEditorZoomDelta()
  578. {
  579. m_editorZoomDeltaSpin->setValue(g_config->getEditorZoomDelta());
  580. return true;
  581. }
  582. bool VReadEditTab::saveEditorZoomDelta()
  583. {
  584. g_config->setEditorZoomDelta(m_editorZoomDeltaSpin->value());
  585. return true;
  586. }
  587. bool VReadEditTab::loadFlashAnchor()
  588. {
  589. m_flashAnchor->setChecked(g_config->getEnableFlashAnchor());
  590. return true;
  591. }
  592. bool VReadEditTab::saveFlashAnchor()
  593. {
  594. g_config->setEnableFlashAnchor(m_flashAnchor->isChecked());
  595. return true;
  596. }
  597. bool VReadEditTab::loadSwapFile()
  598. {
  599. m_swapFile->setChecked(g_config->getEnableBackupFile());
  600. return true;
  601. }
  602. bool VReadEditTab::saveSwapFile()
  603. {
  604. g_config->setEnableBackupFile(m_swapFile->isChecked());
  605. return true;
  606. }
  607. bool VReadEditTab::loadAutoSave()
  608. {
  609. m_autoSave->setChecked(g_config->getEnableAutoSave());
  610. return true;
  611. }
  612. bool VReadEditTab::saveAutoSave()
  613. {
  614. g_config->setEnableAutoSave(m_autoSave->isChecked());
  615. return true;
  616. }
  617. bool VReadEditTab::loadKeyMode()
  618. {
  619. m_keyModeCB->setCurrentIndex(m_keyModeCB->findData((int)g_config->getKeyMode()));
  620. m_smartIM->setChecked(g_config->getEnableSmartImInVimMode());
  621. return true;
  622. }
  623. bool VReadEditTab::saveKeyMode()
  624. {
  625. g_config->setKeyMode((KeyMode)m_keyModeCB->currentData().toInt());
  626. g_config->setEnableSmartImInVimMode(m_smartIM->isChecked());
  627. return true;
  628. }
  629. VNoteManagementTab::VNoteManagementTab(QWidget *p_parent)
  630. : QWidget(p_parent)
  631. {
  632. m_noteBox = new QGroupBox(tr("Notes"));
  633. m_externalBox = new QGroupBox(tr("External Files"));
  634. // Note.
  635. // Image folder.
  636. m_customImageFolder = new QCheckBox(tr("Custom image folder"), this);
  637. m_customImageFolder->setToolTip(tr("Set the global name of the image folder to hold images "
  638. "of notes (restart VNote to make it work)"));
  639. connect(m_customImageFolder, &QCheckBox::stateChanged,
  640. this, &VNoteManagementTab::customImageFolderChanged);
  641. m_imageFolderEdit = new VLineEdit(this);
  642. m_imageFolderEdit->setPlaceholderText(tr("Name of the image folder"));
  643. m_imageFolderEdit->setToolTip(m_customImageFolder->toolTip());
  644. QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), this);
  645. m_imageFolderEdit->setValidator(validator);
  646. QHBoxLayout *imageFolderLayout = new QHBoxLayout();
  647. imageFolderLayout->addWidget(m_customImageFolder);
  648. imageFolderLayout->addWidget(m_imageFolderEdit);
  649. // Attachment folder.
  650. m_customAttachmentFolder = new QCheckBox(tr("Custom attachment folder"), this);
  651. m_customAttachmentFolder->setToolTip(tr("Set the global name of the attachment folder to hold attachments "
  652. "of notes (restart VNote to make it work)"));
  653. connect(m_customAttachmentFolder, &QCheckBox::stateChanged,
  654. this, &VNoteManagementTab::customAttachmentFolderChanged);
  655. m_attachmentFolderEdit = new VLineEdit(this);
  656. m_attachmentFolderEdit->setPlaceholderText(tr("Name of the attachment folder"));
  657. m_attachmentFolderEdit->setToolTip(m_customAttachmentFolder->toolTip());
  658. validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), this);
  659. m_attachmentFolderEdit->setValidator(validator);
  660. QHBoxLayout *attachmentFolderLayout = new QHBoxLayout();
  661. attachmentFolderLayout->addWidget(m_customAttachmentFolder);
  662. attachmentFolderLayout->addWidget(m_attachmentFolderEdit);
  663. // Single click open.
  664. m_singleClickOpen = new QCheckBox(tr("Single click to open a note in current tab"), this);
  665. m_singleClickOpen->setToolTip(tr("Single click a note in the notes list to open it in current tab, "
  666. "double click to open it in a new tab"));
  667. QFormLayout *noteLayout = new QFormLayout();
  668. noteLayout->addRow(imageFolderLayout);
  669. noteLayout->addRow(attachmentFolderLayout);
  670. noteLayout->addRow(m_singleClickOpen);
  671. m_noteBox->setLayout(noteLayout);
  672. // External File.
  673. // Image folder.
  674. m_customImageFolderExt = new QCheckBox(tr("Custom image folder"), this);
  675. m_customImageFolderExt->setToolTip(tr("Set the path of the global image folder to hold images "
  676. "of external files (restart VNote to make it work).\nYou "
  677. "could use both absolute or relative path here. If "
  678. "absolute path is used, VNote will not manage\nthose images, "
  679. "so you need to clean up unused images manually."));
  680. connect(m_customImageFolderExt, &QCheckBox::stateChanged,
  681. this, &VNoteManagementTab::customImageFolderExtChanged);
  682. m_imageFolderEditExt = new VLineEdit(this);
  683. m_imageFolderEditExt->setToolTip(m_customImageFolderExt->toolTip());
  684. m_imageFolderEditExt->setPlaceholderText(tr("Name of the image folder"));
  685. QHBoxLayout *imageFolderExtLayout = new QHBoxLayout();
  686. imageFolderExtLayout->addWidget(m_customImageFolderExt);
  687. imageFolderExtLayout->addWidget(m_imageFolderEditExt);
  688. QFormLayout *externalLayout = new QFormLayout();
  689. externalLayout->addRow(imageFolderExtLayout);
  690. m_externalBox->setLayout(externalLayout);
  691. QVBoxLayout *mainLayout = new QVBoxLayout();
  692. mainLayout->addWidget(m_noteBox);
  693. mainLayout->addWidget(m_externalBox);
  694. setLayout(mainLayout);
  695. }
  696. bool VNoteManagementTab::loadConfiguration()
  697. {
  698. if (!loadImageFolder()) {
  699. return false;
  700. }
  701. if (!loadAttachmentFolder()) {
  702. return false;
  703. }
  704. if (!loadImageFolderExt()) {
  705. return false;
  706. }
  707. if (!loadSingleClickOpen()) {
  708. return false;
  709. }
  710. return true;
  711. }
  712. bool VNoteManagementTab::saveConfiguration()
  713. {
  714. if (!saveImageFolder()) {
  715. return false;
  716. }
  717. if (!saveAttachmentFolder()) {
  718. return false;
  719. }
  720. if (!saveImageFolderExt()) {
  721. return false;
  722. }
  723. if (!saveSingleClickOpen()) {
  724. return false;
  725. }
  726. return true;
  727. }
  728. bool VNoteManagementTab::loadImageFolder()
  729. {
  730. bool isCustom = g_config->isCustomImageFolder();
  731. m_customImageFolder->setChecked(isCustom);
  732. m_imageFolderEdit->setText(g_config->getImageFolder());
  733. m_imageFolderEdit->setEnabled(isCustom);
  734. return true;
  735. }
  736. bool VNoteManagementTab::saveImageFolder()
  737. {
  738. if (m_customImageFolder->isChecked()) {
  739. g_config->setImageFolder(m_imageFolderEdit->text());
  740. } else {
  741. g_config->setImageFolder("");
  742. }
  743. return true;
  744. }
  745. void VNoteManagementTab::customImageFolderChanged(int p_state)
  746. {
  747. if (p_state == Qt::Checked) {
  748. m_imageFolderEdit->setEnabled(true);
  749. m_imageFolderEdit->selectAll();
  750. m_imageFolderEdit->setFocus();
  751. } else {
  752. m_imageFolderEdit->setEnabled(false);
  753. }
  754. }
  755. bool VNoteManagementTab::loadAttachmentFolder()
  756. {
  757. bool isCustom = g_config->isCustomAttachmentFolder();
  758. m_customAttachmentFolder->setChecked(isCustom);
  759. m_attachmentFolderEdit->setText(g_config->getAttachmentFolder());
  760. m_attachmentFolderEdit->setEnabled(isCustom);
  761. return true;
  762. }
  763. bool VNoteManagementTab::saveAttachmentFolder()
  764. {
  765. if (m_customAttachmentFolder->isChecked()) {
  766. g_config->setAttachmentFolder(m_attachmentFolderEdit->text());
  767. } else {
  768. g_config->setAttachmentFolder("");
  769. }
  770. return true;
  771. }
  772. void VNoteManagementTab::customAttachmentFolderChanged(int p_state)
  773. {
  774. if (p_state == Qt::Checked) {
  775. m_attachmentFolderEdit->setEnabled(true);
  776. m_attachmentFolderEdit->selectAll();
  777. m_attachmentFolderEdit->setFocus();
  778. } else {
  779. m_attachmentFolderEdit->setEnabled(false);
  780. }
  781. }
  782. bool VNoteManagementTab::loadImageFolderExt()
  783. {
  784. bool isCustom = g_config->isCustomImageFolderExt();
  785. m_customImageFolderExt->setChecked(isCustom);
  786. m_imageFolderEditExt->setText(g_config->getImageFolderExt());
  787. m_imageFolderEditExt->setEnabled(isCustom);
  788. return true;
  789. }
  790. bool VNoteManagementTab::saveImageFolderExt()
  791. {
  792. if (m_customImageFolderExt->isChecked()) {
  793. g_config->setImageFolderExt(m_imageFolderEditExt->text());
  794. } else {
  795. g_config->setImageFolderExt("");
  796. }
  797. return true;
  798. }
  799. void VNoteManagementTab::customImageFolderExtChanged(int p_state)
  800. {
  801. if (p_state == Qt::Checked) {
  802. m_imageFolderEditExt->setEnabled(true);
  803. m_imageFolderEditExt->selectAll();
  804. m_imageFolderEditExt->setFocus();
  805. } else {
  806. m_imageFolderEditExt->setEnabled(false);
  807. }
  808. }
  809. bool VNoteManagementTab::loadSingleClickOpen()
  810. {
  811. m_singleClickOpen->setChecked(g_config->getSingleClickClosePreviousTab());
  812. return true;
  813. }
  814. bool VNoteManagementTab::saveSingleClickOpen()
  815. {
  816. g_config->setSingleClickClosePreviousTab(m_singleClickOpen->isChecked());
  817. return true;
  818. }
  819. VMarkdownTab::VMarkdownTab(QWidget *p_parent)
  820. : QWidget(p_parent)
  821. {
  822. // Default note open mode.
  823. m_openModeCombo = VUtils::getComboBox();
  824. m_openModeCombo->setToolTip(tr("Default mode to open a file"));
  825. m_openModeCombo->addItem(tr("Read Mode"), (int)OpenFileMode::Read);
  826. m_openModeCombo->addItem(tr("Edit Mode"), (int)OpenFileMode::Edit);
  827. // Heading sequence.
  828. m_headingSequenceTypeCombo = VUtils::getComboBox();
  829. m_headingSequenceTypeCombo->setToolTip(tr("Enable auto sequence for all headings (in the form like 1.2.3.4.)"));
  830. m_headingSequenceTypeCombo->addItem(tr("Disabled"), (int)HeadingSequenceType::Disabled);
  831. m_headingSequenceTypeCombo->addItem(tr("Enabled"), (int)HeadingSequenceType::Enabled);
  832. m_headingSequenceTypeCombo->addItem(tr("Enabled for intrenal notes only"), (int)HeadingSequenceType::EnabledNoteOnly);
  833. m_headingSequenceLevelCombo = VUtils::getComboBox();
  834. m_headingSequenceLevelCombo->setToolTip(tr("Base level to start heading sequence"));
  835. m_headingSequenceLevelCombo->addItem(tr("1"), 1);
  836. m_headingSequenceLevelCombo->addItem(tr("2"), 2);
  837. m_headingSequenceLevelCombo->addItem(tr("3"), 3);
  838. m_headingSequenceLevelCombo->addItem(tr("4"), 4);
  839. m_headingSequenceLevelCombo->addItem(tr("5"), 5);
  840. m_headingSequenceLevelCombo->addItem(tr("6"), 6);
  841. m_headingSequenceLevelCombo->setEnabled(false);
  842. connect(m_headingSequenceTypeCombo, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
  843. this, [this](int p_index){
  844. if (p_index > -1) {
  845. HeadingSequenceType type = (HeadingSequenceType)m_headingSequenceTypeCombo->itemData(p_index).toInt();
  846. m_headingSequenceLevelCombo->setEnabled(type != HeadingSequenceType::Disabled);
  847. }
  848. });
  849. QHBoxLayout *headingSequenceLayout = new QHBoxLayout();
  850. headingSequenceLayout->addWidget(m_headingSequenceTypeCombo);
  851. headingSequenceLayout->addWidget(m_headingSequenceLevelCombo);
  852. // Color column.
  853. m_colorColumnEdit = new VLineEdit();
  854. m_colorColumnEdit->setToolTip(tr("Specify the screen column in fenced code block "
  855. "which will be highlighted"));
  856. QValidator *validator = new QRegExpValidator(QRegExp("\\d+"), this);
  857. m_colorColumnEdit->setValidator(validator);
  858. QLabel *colorColumnLabel = new QLabel(tr("Color column:"));
  859. colorColumnLabel->setToolTip(m_colorColumnEdit->toolTip());
  860. // MathJax.
  861. m_mathjaxConfigEdit = new VLineEdit();
  862. m_mathjaxConfigEdit->setToolTip(tr("Location of MathJax JavaScript and its configuration "
  863. "(restart VNote to make it work in in-place preview)"));
  864. m_mathjaxConfigEdit->setPlaceholderText(tr("Need to prepend \"file://\" to local path"));
  865. // PlantUML.
  866. m_plantUMLModeCombo = VUtils::getComboBox();
  867. m_plantUMLModeCombo->setToolTip(tr("Enable PlantUML support in Markdown"));
  868. m_plantUMLModeCombo->addItem(tr("Disabled"), PlantUMLMode::DisablePlantUML);
  869. m_plantUMLModeCombo->addItem(tr("Online Service"), PlantUMLMode::OnlinePlantUML);
  870. m_plantUMLModeCombo->addItem(tr("Local JAR"), PlantUMLMode::LocalPlantUML);
  871. m_plantUMLServerEdit = new VLineEdit();
  872. m_plantUMLServerEdit->setToolTip(tr("Server address for online PlantUML"));
  873. m_plantUMLJarEdit = new VLineEdit();
  874. m_plantUMLJarEdit->setToolTip(tr("Location to the PlantUML JAR executable for local PlantUML"));
  875. QPushButton *plantUMLJarTestBtn = new QPushButton(tr("Test"));
  876. plantUMLJarTestBtn->setToolTip(tr("Test PlantUML JAR configuration"));
  877. connect(plantUMLJarTestBtn, &QPushButton::clicked,
  878. this, [this]() {
  879. QString jar = m_plantUMLJarEdit->text();
  880. if (jar.isEmpty() || !QFileInfo::exists(jar)) {
  881. VUtils::showMessage(QMessageBox::Warning,
  882. tr("Warning"),
  883. tr("The JAR file specified does not exist."),
  884. tr("Please input the right absolute file path to the JAR file."),
  885. QMessageBox::Ok,
  886. QMessageBox::Ok,
  887. this);
  888. return;
  889. }
  890. if (!jar.trimmed().toLower().endsWith(".jar")) {
  891. VUtils::showMessage(QMessageBox::Warning,
  892. tr("Warning"),
  893. tr("Please specify the absolute file path to the JAR file."),
  894. tr("It should be something like \"/path/to/plantuml.jar\"."),
  895. QMessageBox::Ok,
  896. QMessageBox::Ok,
  897. this);
  898. return;
  899. }
  900. QString msg;
  901. bool ret = VPlantUMLHelper::testPlantUMLJar(jar, msg);
  902. VUtils::showMessage(QMessageBox::Information,
  903. tr("Information"),
  904. tr("Test %1.").arg((ret ? tr("succeeded") : tr("failed"))),
  905. msg,
  906. QMessageBox::Ok,
  907. QMessageBox::Ok,
  908. this);
  909. });
  910. QHBoxLayout *plantUMLLayout = new QHBoxLayout();
  911. plantUMLLayout->addWidget(m_plantUMLJarEdit);
  912. plantUMLLayout->addWidget(plantUMLJarTestBtn);
  913. // Graphviz.
  914. m_graphvizCB = new QCheckBox(tr("Graphviz"));
  915. m_graphvizCB->setToolTip(tr("Enable Graphviz for drawing graph"));
  916. m_graphvizDotEdit = new VLineEdit();
  917. m_graphvizDotEdit->setPlaceholderText(tr("Empty to detect automatically"));
  918. m_graphvizDotEdit->setToolTip(tr("Location to the GraphViz dot executable"));
  919. QPushButton *graphvizTestBtn = new QPushButton(tr("Test"));
  920. graphvizTestBtn->setToolTip(tr("Test Graphviz executable configuration"));
  921. connect(graphvizTestBtn, &QPushButton::clicked,
  922. this, [this]() {
  923. QString dot = m_graphvizDotEdit->text();
  924. if (dot.isEmpty()) {
  925. dot = "dot";
  926. }
  927. QString msg;
  928. bool ret = VGraphvizHelper::testGraphviz(dot, msg);
  929. VUtils::showMessage(QMessageBox::Information,
  930. tr("Information"),
  931. tr("Test %1.").arg((ret ? tr("succeeded") : tr("failed"))),
  932. msg,
  933. QMessageBox::Ok,
  934. QMessageBox::Ok,
  935. this);
  936. });
  937. QHBoxLayout *graphvizLayout = new QHBoxLayout();
  938. graphvizLayout->addWidget(m_graphvizDotEdit);
  939. graphvizLayout->addWidget(graphvizTestBtn);
  940. QFormLayout *mainLayout = new QFormLayout();
  941. mainLayout->addRow(tr("Open mode:"), m_openModeCombo);
  942. mainLayout->addRow(tr("Heading sequence:"), headingSequenceLayout);
  943. mainLayout->addRow(colorColumnLabel, m_colorColumnEdit);
  944. mainLayout->addRow(tr("MathJax configuration:"), m_mathjaxConfigEdit);
  945. mainLayout->addRow(tr("PlantUML:"), m_plantUMLModeCombo);
  946. mainLayout->addRow(tr("PlantUML server:"), m_plantUMLServerEdit);
  947. mainLayout->addRow(tr("PlantUML JAR:"), plantUMLLayout);
  948. mainLayout->addRow(m_graphvizCB);
  949. mainLayout->addRow(tr("Graphviz executable:"), graphvizLayout);
  950. setLayout(mainLayout);
  951. }
  952. bool VMarkdownTab::loadConfiguration()
  953. {
  954. if (!loadOpenMode()) {
  955. return false;
  956. }
  957. if (!loadHeadingSequence()) {
  958. return false;
  959. }
  960. if (!loadColorColumn()) {
  961. return false;
  962. }
  963. if (!loadMathJax()) {
  964. return false;
  965. }
  966. if (!loadPlantUML()) {
  967. return false;
  968. }
  969. if (!loadGraphviz()) {
  970. return false;
  971. }
  972. return true;
  973. }
  974. bool VMarkdownTab::saveConfiguration()
  975. {
  976. if (!saveOpenMode()) {
  977. return false;
  978. }
  979. if (!saveHeadingSequence()) {
  980. return false;
  981. }
  982. if (!saveColorColumn()) {
  983. return false;
  984. }
  985. if (!saveMathJax()) {
  986. return false;
  987. }
  988. if (!savePlantUML()) {
  989. return false;
  990. }
  991. if (!saveGraphviz()) {
  992. return false;
  993. }
  994. return true;
  995. }
  996. bool VMarkdownTab::loadOpenMode()
  997. {
  998. int mode = (int)g_config->getNoteOpenMode();
  999. bool found = false;
  1000. for (int i = 0; i < m_openModeCombo->count(); ++i) {
  1001. if (m_openModeCombo->itemData(i).toInt() == mode) {
  1002. m_openModeCombo->setCurrentIndex(i);
  1003. found = true;
  1004. break;
  1005. }
  1006. }
  1007. Q_ASSERT(found);
  1008. return true;
  1009. }
  1010. bool VMarkdownTab::saveOpenMode()
  1011. {
  1012. int mode = m_openModeCombo->currentData().toInt();
  1013. g_config->setNoteOpenMode((OpenFileMode)mode);
  1014. return true;
  1015. }
  1016. bool VMarkdownTab::loadHeadingSequence()
  1017. {
  1018. HeadingSequenceType type = g_config->getHeadingSequenceType();
  1019. int level = g_config->getHeadingSequenceBaseLevel();
  1020. if (level < 1 || level > 6) {
  1021. level = 1;
  1022. }
  1023. int idx = m_headingSequenceTypeCombo->findData((int)type);
  1024. Q_ASSERT(idx > -1);
  1025. m_headingSequenceTypeCombo->setCurrentIndex(idx);
  1026. m_headingSequenceLevelCombo->setCurrentIndex(level - 1);
  1027. m_headingSequenceLevelCombo->setEnabled(type != HeadingSequenceType::Disabled);
  1028. return true;
  1029. }
  1030. bool VMarkdownTab::saveHeadingSequence()
  1031. {
  1032. QVariant typeData = m_headingSequenceTypeCombo->currentData();
  1033. Q_ASSERT(typeData.isValid());
  1034. g_config->setHeadingSequenceType((HeadingSequenceType)typeData.toInt());
  1035. g_config->setHeadingSequenceBaseLevel(m_headingSequenceLevelCombo->currentData().toInt());
  1036. return true;
  1037. }
  1038. bool VMarkdownTab::loadColorColumn()
  1039. {
  1040. int colorColumn = g_config->getColorColumn();
  1041. m_colorColumnEdit->setText(QString::number(colorColumn <= 0 ? 0 : colorColumn));
  1042. return true;
  1043. }
  1044. bool VMarkdownTab::saveColorColumn()
  1045. {
  1046. bool ok = false;
  1047. int colorColumn = m_colorColumnEdit->text().toInt(&ok);
  1048. if (ok && colorColumn >= 0) {
  1049. g_config->setColorColumn(colorColumn);
  1050. }
  1051. return true;
  1052. }
  1053. bool VMarkdownTab::loadMathJax()
  1054. {
  1055. m_mathjaxConfigEdit->setText(g_config->getMathjaxJavascript());
  1056. return true;
  1057. }
  1058. bool VMarkdownTab::saveMathJax()
  1059. {
  1060. g_config->setMathjaxJavascript(m_mathjaxConfigEdit->text());
  1061. return true;
  1062. }
  1063. bool VMarkdownTab::loadPlantUML()
  1064. {
  1065. m_plantUMLModeCombo->setCurrentIndex(m_plantUMLModeCombo->findData(g_config->getPlantUMLMode()));
  1066. m_plantUMLServerEdit->setText(g_config->getPlantUMLServer());
  1067. m_plantUMLJarEdit->setText(g_config->getPlantUMLJar());
  1068. return true;
  1069. }
  1070. bool VMarkdownTab::savePlantUML()
  1071. {
  1072. g_config->setPlantUMLMode(m_plantUMLModeCombo->currentData().toInt());
  1073. g_config->setPlantUMLServer(m_plantUMLServerEdit->text());
  1074. g_config->setPlantUMLJar(m_plantUMLJarEdit->text());
  1075. return true;
  1076. }
  1077. bool VMarkdownTab::loadGraphviz()
  1078. {
  1079. m_graphvizCB->setChecked(g_config->getEnableGraphviz());
  1080. m_graphvizDotEdit->setText(g_config->getGraphvizDot());
  1081. return true;
  1082. }
  1083. bool VMarkdownTab::saveGraphviz()
  1084. {
  1085. g_config->setEnableGraphviz(m_graphvizCB->isChecked());
  1086. g_config->setGraphvizDot(m_graphvizDotEdit->text());
  1087. return true;
  1088. }