diff --git a/.travis.yml b/.travis.yml index 06654b9c..23de3ef6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,15 @@ language: cpp compiler: - - gcc + - g++ - clang before_install: + - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test # for g++ 4.8 - sudo add-apt-repository -y ppa:beineri/opt-qt521 # for Qt 5.2 - sudo apt-get update -qq - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" install: + - if [ "$CXX" == "g++" ]; then sudo apt-get install -qq g++-4.8; sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 90; fi - sudo apt-get install -qq qt52base qt52declarative qt52webkit qt52tools libhunspell-dev - sudo apt-get install -qq libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev before_script: diff --git a/3rdparty/peg-markdown-highlight/peg-markdown-highlight.pro b/3rdparty/peg-markdown-highlight/peg-markdown-highlight.pro index f3968bfc..88e78156 100644 --- a/3rdparty/peg-markdown-highlight/peg-markdown-highlight.pro +++ b/3rdparty/peg-markdown-highlight/peg-markdown-highlight.pro @@ -4,7 +4,7 @@ # #------------------------------------------------- -QT -= core gui +CONFIG -= qt TARGET = pmh TEMPLATE = lib diff --git a/CuteMarkEd.wxs b/CuteMarkEd.wxs index 8d1fe38c..48e2ac3a 100644 --- a/CuteMarkEd.wxs +++ b/CuteMarkEd.wxs @@ -2,23 +2,23 @@ - - + - @@ -26,11 +26,10 @@ DowngradeErrorMessage="CuteMarkEd is already installed with a higher version." AllowSameVersionUpgrades="yes" /> - - + + - @@ -39,7 +38,7 @@ - + @@ -80,13 +79,14 @@ + - - - + + + @@ -110,12 +110,6 @@ - - - - - - @@ -132,7 +126,7 @@ - + @@ -142,14 +136,17 @@ + + + @@ -168,10 +165,15 @@ + + + + + @@ -179,11 +181,10 @@ - + - @@ -201,7 +202,7 @@ - + 1 - + diff --git a/README.md b/README.md index 75c3bfbf..ca2b81c1 100644 --- a/README.md +++ b/README.md @@ -8,15 +8,45 @@ A Qt-based, free and open source markdown editor with live HTML preview, math ex ### DOWNLOAD -[Sources](https://github.com/cloose/CuteMarkEd/archive/v0.11.1.tar.gz) -[MS Windows (Installer)](http://dl.bintray.com/cloose/CuteMarkEd/cutemarked-0.11.1.msi) -[MS Windows (ZIP file)](http://dl.bintray.com/cloose/CuteMarkEd/cutemarked-0.11.1.zip) -[OpenSUSE 13.1 (RPM)](https://build.opensuse.org/project/show?project=home%3Acloose1974) +[Sources](https://github.com/cloose/CuteMarkEd/archive/v0.11.3.tar.gz) +[MS Windows (Installer)](http://dl.bintray.com/cloose/CuteMarkEd/cutemarked-0.11.3.msi) +[MS Windows (ZIP file)](http://dl.bintray.com/cloose/CuteMarkEd/cutemarked-0.11.3.zip) +[OpenSUSE 13.2 (RPM)](https://build.opensuse.org/project/show?project=home%3Acloose1974) [Fedora 20 (RPM)](https://build.opensuse.org/project/show?project=home%3Acloose1974) [Fedora 21 (RPM)](https://build.opensuse.org/project/show?project=home%3Acloose1974) +[Fedora 22 (RPM)](https://build.opensuse.org/project/show?project=home%3Acloose1974) +[Fedora 23 (RPM)](https://build.opensuse.org/project/show?project=home%3Acloose1974) ### NEWS +#### Version 0.11.3 + +Improvements: + +* `IMPROVED` Update Russian translation + +Fixes: + +* `FIXED` Missing links in exported PDF file (#275) +* `FIXED` Use of non-native line endings when a file is saved (#97) +* `FIXED` Corrupt files on system crashes or running out of disk space (#285) +* `FIXED` Accessing all drives although the file explorer is not visible (#273) +* `FIXED` Relative paths in recently used files menu (#256) + +#### Version 0.11.2 + +Improvements: + +* `IMPROVED` Added Hungarian translation + +Fixes: + +* `FIXED` Editor pane jumping up and down during editing (#232) +* `FIXED` Missing mermaid CSS for styling in preview (#241) +* `FIXED` Correct order of HTML Preview/Source menu item (#242) +* `FIXED` Retrieval of last used style on application start on Linux (#257) +* `FIXED` Crash when switching between markdown converters (#260) + #### Version 0.11.1 Improvements: @@ -65,7 +95,7 @@ Fixes: ### DEPENDENCIES -* [Qt 5.2](http://qt-project.org) (LGPL v2.1) +* [Qt 5.4](http://qt-project.org) (LGPL v2.1) * [Discount 2.1.7](http://www.pell.portland.or.us/~orc/Code/discount/) (3-clause BSD) * [PEG Markdown Highlight](http://hasseg.org/peg-markdown-highlight/) (MIT License) * [hunspell 1.3.2](http://hunspell.sourceforge.net/) (LGPL v2.1) diff --git a/app-static/app-static.pro b/app-static/app-static.pro index 1e760ff5..98b75277 100644 --- a/app-static/app-static.pro +++ b/app-static/app-static.pro @@ -8,7 +8,7 @@ QT += gui webkitwidgets TARGET = app-static TEMPLATE = lib -CONFIG += staticlib +CONFIG += staticlib CONFIG += c++11 INCLUDEPATH += $$PWD @@ -21,6 +21,10 @@ SOURCES += \ converter/revealmarkdownconverter.cpp \ template/htmltemplate.cpp \ template/presentationtemplate.cpp \ + themes/jsonthemetranslator.cpp \ + themes/stylemanager.cpp \ + themes/theme.cpp \ + themes/themecollection.cpp \ completionlistmodel.cpp \ datalocation.cpp \ slidelinemapping.cpp \ @@ -43,6 +47,11 @@ HEADERS += \ template/template.h \ template/htmltemplate.h \ template/presentationtemplate.h \ + themes/jsonthemetranslator.h \ + themes/jsonthemetranslatorfactory.h \ + themes/stylemanager.h \ + themes/theme.h \ + themes/themecollection.h \ completionlistmodel.h \ datalocation.h \ slidelinemapping.h \ @@ -68,10 +77,7 @@ HEADERS += \ # # Add search paths below /usr/local for Mac OSX # -macx { - LIBS += -L/usr/local/lib - INCLUDEPATH += /usr/local/include -} +macx:INCLUDEPATH += /usr/local/include # # JSON configuration library @@ -81,14 +87,7 @@ INCLUDEPATH += $$PWD/../libs/jsonconfig # # Discount library # -win32-g++:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../3rdparty/discount/release/ -ldiscount -else:win32-g++:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../3rdparty/discount/debug/ -ldiscount -else:win32-msvc*:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../3rdparty/discount/release/ -llibdiscount -else:win32-msvc*:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../3rdparty/discount/debug/ -llibdiscount -else:unix: LIBS += -L/usr/lib -lmarkdown - win32:INCLUDEPATH += $$PWD/../3rdparty/discount -win32:DEPENDPATH += $$PWD/../3rdparty/discount # # Hoedown library @@ -100,12 +99,5 @@ with_hoedown { SOURCES += converter/hoedownmarkdownconverter.cpp HEADERS += converter/hoedownmarkdownconverter.h - win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../3rdparty/hoedown/release/ -lhoedown - else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../3rdparty/hoedown/debug/ -lhoedown - else:unix: LIBS += -L/usr/lib -lhoedown - - win32 { - INCLUDEPATH += $$PWD/../3rdparty/hoedown - DEPENDPATH += $$PWD/../3rdparty/hoedown - } + win32:INCLUDEPATH += $$PWD/../3rdparty/hoedown } diff --git a/app-static/completionlistmodel.cpp b/app-static/completionlistmodel.cpp index 5d990017..770c38b6 100644 --- a/app-static/completionlistmodel.cpp +++ b/app-static/completionlistmodel.cpp @@ -27,6 +27,7 @@ CompletionListModel::CompletionListModel(QObject *parent) : int CompletionListModel::rowCount(const QModelIndex &parent) const { + Q_UNUSED(parent); return snippets.count() + words.count(); } diff --git a/app-static/converter/hoedownmarkdownconverter.cpp b/app-static/converter/hoedownmarkdownconverter.cpp index 46392fe6..97808bee 100644 --- a/app-static/converter/hoedownmarkdownconverter.cpp +++ b/app-static/converter/hoedownmarkdownconverter.cpp @@ -88,7 +88,7 @@ QString HoedownMarkdownConverter::renderAsHtml(MarkdownDocument *document) if (document) { HoedownMarkdownDocument *doc = dynamic_cast(document); - if (doc->document()) { + if (doc && doc->document()) { hoedown_buffer *in = doc->document(); hoedown_buffer *out = hoedown_buffer_new(64); diff --git a/app-static/converter/revealmarkdownconverter.cpp b/app-static/converter/revealmarkdownconverter.cpp index ff911468..72489a14 100644 --- a/app-static/converter/revealmarkdownconverter.cpp +++ b/app-static/converter/revealmarkdownconverter.cpp @@ -30,7 +30,9 @@ QString RevealMarkdownConverter::renderAsHtml(MarkdownDocument *document) if (document) { RevealMarkdownDocument *doc = dynamic_cast(document); - html = doc->markdownText; + if (doc) { + html = doc->markdownText; + } } return html; diff --git a/app-static/htmlviewsynchronizer.cpp b/app-static/htmlviewsynchronizer.cpp index 87905e02..3ef6061c 100644 --- a/app-static/htmlviewsynchronizer.cpp +++ b/app-static/htmlviewsynchronizer.cpp @@ -46,6 +46,9 @@ void HtmlViewSynchronizer::webViewScrolled() int value = m_webView->page()->mainFrame()->scrollBarValue(Qt::Vertical); m_editor->verticalScrollBar()->setValue(qRound(value * factor)); + + // remember new vertical scrollbar position of markdown editor + rememberScrollBarPos(); } void HtmlViewSynchronizer::scrollValueChanged(int value) diff --git a/app-static/template/htmltemplate.cpp b/app-static/template/htmltemplate.cpp index 9a0db087..83f7c91d 100644 --- a/app-static/template/htmltemplate.cpp +++ b/app-static/template/htmltemplate.cpp @@ -114,6 +114,7 @@ QString HtmlTemplate::buildHtmlHeader(RenderOptions options) const // add mermaid.js script to HTML header if (options.testFlag(Template::DiagramSupport)) { + header += "\n"; header += "\n"; } diff --git a/app-static/themes/jsonthemetranslator.cpp b/app-static/themes/jsonthemetranslator.cpp new file mode 100644 index 00000000..eeb36d7e --- /dev/null +++ b/app-static/themes/jsonthemetranslator.cpp @@ -0,0 +1,51 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "jsonthemetranslator.h" + +namespace { + +static const QLatin1String NAME("name"); +static const QLatin1String MARKDOWN_HIGHLIGHTING("markdownHighlighting"); +static const QLatin1String CODE_HIGHLIGHTING("codeHighlighting"); +static const QLatin1String PREVIEW_STYLESHEET("previewStylesheet"); +static const QLatin1String BUILT_IN("builtIn"); + +} + +Theme JsonThemeTranslator::fromJsonObject(const QJsonObject &object) +{ + QString name = object.value(NAME).toString(); + QString markdownHighlighting = object.value(MARKDOWN_HIGHLIGHTING).toString(); + QString codeHighlighting = object.value(CODE_HIGHLIGHTING).toString(); + QString previewStylesheet = object.value(PREVIEW_STYLESHEET).toString(); + bool builtIn = object.value(BUILT_IN).toBool(); + + return { name, markdownHighlighting, codeHighlighting, previewStylesheet, builtIn }; +} + +QJsonObject JsonThemeTranslator::toJsonObject(const Theme &theme) +{ + QJsonObject object; + object.insert(NAME, theme.name()); + object.insert(MARKDOWN_HIGHLIGHTING, theme.markdownHighlighting()); + object.insert(CODE_HIGHLIGHTING, theme.codeHighlighting()); + object.insert(PREVIEW_STYLESHEET, theme.previewStylesheet()); + object.insert(BUILT_IN, theme.isBuiltIn()); + + return object; +} + diff --git a/app-static/themes/jsonthemetranslator.h b/app-static/themes/jsonthemetranslator.h new file mode 100644 index 00000000..de13f0d8 --- /dev/null +++ b/app-static/themes/jsonthemetranslator.h @@ -0,0 +1,34 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef JSONTHEMETRANSLATOR_H +#define JSONTHEMETRANSLATOR_H + +#include +#include +#include "theme.h" + + +class JsonThemeTranslator : public JsonTranslator +{ +private: + Theme fromJsonObject(const QJsonObject &object); + QJsonObject toJsonObject(const Theme &theme); +}; + +#endif // JSONTHEMETRANSLATOR_H + + diff --git a/app-static/themes/jsonthemetranslatorfactory.h b/app-static/themes/jsonthemetranslatorfactory.h new file mode 100644 index 00000000..5d4994b7 --- /dev/null +++ b/app-static/themes/jsonthemetranslatorfactory.h @@ -0,0 +1,37 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef JSONTHEMETRANSLATORFACTORY_H +#define JSONTHEMETRANSLATORFACTORY_H + +#include +#include + +#include "themes/theme.h" +#include "themes/jsonthemetranslator.h" + + +template <> class JsonTranslatorFactory +{ +public: + static JsonTranslator *create() + { + return new JsonThemeTranslator(); + } +}; + +#endif // JSONTHEMETRANSLATORFACTORY_H + diff --git a/app-static/themes/stylemanager.cpp b/app-static/themes/stylemanager.cpp new file mode 100644 index 00000000..36185d97 --- /dev/null +++ b/app-static/themes/stylemanager.cpp @@ -0,0 +1,72 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "stylemanager.h" + +#include + + +static const QMap BUILTIN_MARKDOWN_HIGHLIGHTINGS = { + { "Default", "default" }, + { "Solarized Light", "solarized-light" }, + { "Solarized Dark", "solarized-dark" }, + { "Clearness Dark", "clearness-dark" }, + { "Byword Dark", "byword-dark" } +}; + +static const QMap BUILTIN_CODE_HIGHLIGHTINGS = { + { "Default", "default" }, + { "Github", "github" }, + { "Solarized Light", "solarized_light" }, + { "Solarized Dark", "solarized_dark" } +}; + +static const QMap BUILTIN_PREVIEW_STYLESHEETS = { + { "Default", "qrc:/css/markdown.css" }, + { "Github", "qrc:/css/github.css" }, + { "Solarized Light", "qrc:/css/solarized-light.css" }, + { "Solarized Dark", "qrc:/css/solarized-dark.css" }, + { "Clearness", "qrc:/css/clearness.css" }, + { "Clearness Dark", "qrc:/css/clearness-dark.css" }, + { "Byword Dark", "qrc:/css/byword-dark.css" } +}; + +QMap StyleManager::customPreviewStylesheets; + + +void StyleManager::insertCustomPreviewStylesheet(const QString &styleName, const QString &stylePath) +{ + customPreviewStylesheets.insert(styleName, stylePath); +} + +QString StyleManager::markdownHighlightingPath(const Theme &theme) +{ + return BUILTIN_MARKDOWN_HIGHLIGHTINGS[theme.markdownHighlighting()]; +} + +QString StyleManager::codeHighlightingPath(const Theme &theme) +{ + return BUILTIN_CODE_HIGHLIGHTINGS[theme.codeHighlighting()]; +} + +QString StyleManager::previewStylesheetPath(const Theme &theme) +{ + if (customPreviewStylesheets.contains(theme.previewStylesheet())) { + return customPreviewStylesheets[theme.previewStylesheet()]; + } + + return BUILTIN_PREVIEW_STYLESHEETS[theme.previewStylesheet()]; +} diff --git a/app-static/themes/stylemanager.h b/app-static/themes/stylemanager.h new file mode 100644 index 00000000..ba4b7fd8 --- /dev/null +++ b/app-static/themes/stylemanager.h @@ -0,0 +1,39 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef STYLEMANAGER_H +#define STYLEMANAGER_H + +#include +#include +#include "theme.h" + + +class StyleManager +{ +public: + void insertCustomPreviewStylesheet(const QString &styleName, const QString &stylePath); + + static QString markdownHighlightingPath(const Theme &theme); + static QString codeHighlightingPath(const Theme &theme); + static QString previewStylesheetPath(const Theme &theme); + +private: + static QMap customPreviewStylesheets; +}; + +#endif // STYLEMANAGER_H + diff --git a/app-static/themes/theme.cpp b/app-static/themes/theme.cpp new file mode 100644 index 00000000..3204f16d --- /dev/null +++ b/app-static/themes/theme.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "theme.h" + +Theme::Theme(const QString &name, + const QString &markdownHighlighting, + const QString &codeHighlighting, + const QString &previewStylesheet, + bool builtIn) : + m_name(name), + m_markdownHighlighting(markdownHighlighting), + m_codeHighlighting(codeHighlighting), + m_previewStylesheet(previewStylesheet), + m_builtIn(builtIn) +{ + checkInvariants(); +} + +void Theme::checkInvariants() const +{ + if (m_name.isEmpty()) { + throw std::runtime_error("theme name must not be empty"); + } + if (m_markdownHighlighting.isEmpty()) { + throw std::runtime_error("markdown highlighting style must not be empty"); + } + if (m_codeHighlighting.isEmpty()) { + throw std::runtime_error("code highlighting style must not be empty"); + } + if (m_previewStylesheet.isEmpty()) { + throw std::runtime_error("preview stylesheet must not be empty"); + } +} diff --git a/app-static/themes/theme.h b/app-static/themes/theme.h new file mode 100644 index 00000000..227a1a75 --- /dev/null +++ b/app-static/themes/theme.h @@ -0,0 +1,64 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef THEME_H +#define THEME_H + +#include +#include + + +class Theme +{ +public: + Theme(const QString &name, + const QString &markdownHighlighting, + const QString &codeHighlighting, + const QString &previewStylesheet, + bool builtIn = false); + + QString name() const { return m_name; } + + QString markdownHighlighting() const { return m_markdownHighlighting; } + + QString codeHighlighting() const { return m_codeHighlighting; } + + QString previewStylesheet() const { return m_previewStylesheet; } + + bool isBuiltIn() const { return m_builtIn; } + + bool operator<(const Theme &rhs) const + { + return m_name < rhs.name(); + } + + bool operator ==(const Theme &rhs) const + { + return m_name == rhs.name(); + } + +private: + void checkInvariants() const; + +private: + QString m_name; + QString m_markdownHighlighting; + QString m_codeHighlighting; + QString m_previewStylesheet; + bool m_builtIn; +}; + +#endif // THEME_H diff --git a/app-static/themes/themecollection.cpp b/app-static/themes/themecollection.cpp new file mode 100644 index 00000000..4f4fe52f --- /dev/null +++ b/app-static/themes/themecollection.cpp @@ -0,0 +1,62 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "themecollection.h" + +#include +#include + +bool ThemeCollection::load(const QString &fileName) +{ + return JsonFile::load(fileName, this); +} + +int ThemeCollection::insert(const Theme &theme) +{ + themesIndex << theme.name(); + themes << theme; + return 0; +} + +int ThemeCollection::count() const +{ + return themes.count(); +} + +const Theme &ThemeCollection::at(int offset) const +{ + return themes.at(offset); +} + +bool ThemeCollection::contains(const QString &name) const +{ + return themesIndex.contains(name); +} + +const Theme ThemeCollection::theme(const QString &name) const +{ + return at(themesIndex.indexOf(name)); +} + +QStringList ThemeCollection::themeNames() const +{ + return themesIndex; +} + +const QString ThemeCollection::name() const +{ + return QStringLiteral("themes"); +} diff --git a/app-static/themes/themecollection.h b/app-static/themes/themecollection.h new file mode 100644 index 00000000..30cd0113 --- /dev/null +++ b/app-static/themes/themecollection.h @@ -0,0 +1,47 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef THEMECOLLECTION_H +#define THEMECOLLECTION_H + +#include +#include +#include +#include "theme.h" + + +class ThemeCollection : public JsonCollection +{ +public: + bool load(const QString &fileName); + + int insert(const Theme &theme); + + int count() const; + const Theme &at(int offset) const; + bool contains(const QString &name) const; + const Theme theme(const QString &name) const; + QStringList themeNames() const; + + const QString name() const; + +private: + QStringList themesIndex; + QList themes; +}; + +#endif // THEMECOLLECTION_H + diff --git a/app/Info.plist b/app/Info.plist new file mode 100644 index 00000000..b5e472f2 --- /dev/null +++ b/app/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleName + CuteMarkEd + CFBundleIconFile + app-icon.icns + CFBundlePackageType + APPL + CFBundleShortVersionString + 0.11.2 + CFBundleSignature + CMDE + CFBundleExecutable + cutemarked + CFBundleIdentifier + io.github.cloose.CuteMarkEd + NSPrincipalClass + NSApplication + NSHighResolutionCapable + True + NSHumanReadableCopyright + © 2013-2016 Christian Loose + + diff --git a/app/aboutdialog.cpp b/app/aboutdialog.cpp index 961af75d..1a3aff92 100644 --- a/app/aboutdialog.cpp +++ b/app/aboutdialog.cpp @@ -17,7 +17,7 @@ #include "aboutdialog.h" #include "ui_aboutdialog.h" -static const QString COPYRIGHT = QStringLiteral("Copyright 2013-2015 Christian Loose"); +static const QString COPYRIGHT = QStringLiteral("Copyright 2013-2016 Christian Loose"); static const QString HOMEPAGE = QStringLiteral("http://cloose.github.io/CuteMarkEd"); AboutDialog::AboutDialog(QWidget *parent) : @@ -26,7 +26,10 @@ AboutDialog::AboutDialog(QWidget *parent) : { ui->setupUi(this); - ui->messageLabel->setText(QString("

CuteMarkEd
Version %1

").arg(qApp->applicationVersion())); + const QString appInfo = QString(ui->messageLabel->text()) + .arg(qApp->applicationDisplayName()) + .arg(qApp->applicationVersion()); + ui->messageLabel->setText(appInfo); const QString description = QString("

%1
%2

%3

") .arg(tr("Qt-based, free and open source markdown editor with live HTML preview")) diff --git a/app/aboutdialog.ui b/app/aboutdialog.ui index 38e12c9e..fb7e52a9 100644 --- a/app/aboutdialog.ui +++ b/app/aboutdialog.ui @@ -32,7 +32,7 @@ - <p><b><font size="5">Program Name</font></b><br>Version 0.1</p> + <p><b><font size="5">%1</font></b><br>Version %2</p> false @@ -109,7 +109,7 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Christian Loose (cloose)</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Creator and maintainer</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> @@ -169,6 +169,9 @@ p, li { white-space: pre-wrap; } <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Daniel Napora (napcok)</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Polish translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Neran93</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Hungarian translation</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html> @@ -186,7 +189,7 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Qt</span><span style=" font-size:8pt;"> (LGPL v2.1)</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://qt-project.org/"><span style=" font-size:8pt; text-decoration: underline; color:#0000ff;">http://qt.io/</span></a></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> diff --git a/app/app-icon.icns b/app/app-icon.icns new file mode 100644 index 00000000..58cabb79 Binary files /dev/null and b/app/app-icon.icns differ diff --git a/app/app.pro b/app/app.pro index 3f3197b1..fcc8524a 100644 --- a/app/app.pro +++ b/app/app.pro @@ -14,7 +14,7 @@ TARGET = cutemarked TEMPLATE = app CONFIG += c++11 -unix { +unix:!macx { CONFIG += link_pkgconfig } @@ -25,13 +25,19 @@ TRANSLATIONS += \ translations/cutemarked_el.ts \ translations/cutemarked_es.ts \ translations/cutemarked_fr.ts \ + translations/cutemarked_hu_HU.ts \ translations/cutemarked_id.ts \ translations/cutemarked_ja.ts \ + translations/cutemarked_pl.ts \ translations/cutemarked_pt_BR.ts \ translations/cutemarked_ru.ts \ translations/cutemarked_zh_CN.ts -RC_FILE = cutemarked.rc +win32:RC_FILE = cutemarked.rc +macx { + ICON = app-icon.icns + QMAKE_INFO_PLIST = Info.plist +} INCLUDEPATH += $$PWD @@ -59,13 +65,19 @@ SOURCES += \ imagetooldialog.cpp \ snippetcompleter.cpp \ snippetstablemodel.cpp \ - aboutdialog.cpp + aboutdialog.cpp \ + statusbarwidget.cpp win32 { SOURCES += \ hunspell/spellchecker_win.cpp } +macx { + SOURCES += \ + hunspell/spellchecker_macx.cpp +} + unix { SOURCES += \ hunspell/spellchecker_unix.cpp @@ -94,7 +106,9 @@ HEADERS += \ imagetooldialog.h \ snippetcompleter.h \ snippetstablemodel.h \ - aboutdialog.h + aboutdialog.h \ + statusbarwidget.h \ + savefileadapter.h FORMS += \ mainwindow.ui \ @@ -121,8 +135,11 @@ OTHER_FILES += \ syntax_da.html \ syntax_de.html \ syntax_el.html \ + syntax_es.html \ + syntax_hu_HU.html \ syntax_id.html \ syntax_ja.html \ + syntax_pt_BR.html \ syntax_zh_CN.html \ styles/solarized-dark.css \ styles/markdown.css \ @@ -131,7 +148,8 @@ OTHER_FILES += \ styles/clearness.css \ styles/byword-dark.css \ styles/solarized-light.css \ - markdown-snippets.json + markdown-snippets.json \ + builtin-htmlpreview-themes.json # translations lrelease.input = TRANSLATIONS @@ -242,7 +260,7 @@ message("Using LIBS=$$LIBS") ## INSTALLATION -unix { +unix:!macx { isEmpty(PREFIX): PREFIX = /usr DATADIR = $${PREFIX}/share diff --git a/app/builtin-htmlpreview-themes.json b/app/builtin-htmlpreview-themes.json new file mode 100644 index 00000000..49f2334f --- /dev/null +++ b/app/builtin-htmlpreview-themes.json @@ -0,0 +1,53 @@ +{ + "themes": [ + { + "name": "Default", + "markdownHighlighting": "Default", + "codeHighlighting": "Default", + "previewStylesheet": "Default", + "builtIn": true + }, + { + "name": "Github", + "markdownHighlighting": "Default", + "codeHighlighting": "Github", + "previewStylesheet": "Github", + "builtIn": true + }, + { + "name": "Solarized Light", + "markdownHighlighting": "Solarized Light", + "codeHighlighting": "Solarized Light", + "previewStylesheet": "Solarized Light", + "builtIn": true + }, + { + "name": "Solarized Dark", + "markdownHighlighting": "Solarized Dark", + "codeHighlighting": "Solarized Dark", + "previewStylesheet": "Solarized Dark", + "builtIn": true + }, + { + "name": "Clearness", + "markdownHighlighting": "Default", + "codeHighlighting": "Default", + "previewStylesheet": "Clearness", + "builtIn": true + }, + { + "name": "Clearness Dark", + "markdownHighlighting": "Clearness Dark", + "codeHighlighting": "Default", + "previewStylesheet": "Clearness Dark", + "builtIn": true + }, + { + "name": "Byword Dark", + "markdownHighlighting": "Byword Dark", + "codeHighlighting": "Default", + "previewStylesheet": "Byword Dark", + "builtIn": true + } + ] +} diff --git a/app/controls/activelabel.cpp b/app/controls/activelabel.cpp index 59b974f1..5237bacb 100644 --- a/app/controls/activelabel.cpp +++ b/app/controls/activelabel.cpp @@ -16,15 +16,18 @@ */ #include "activelabel.h" +#include #include ActiveLabel::ActiveLabel(QWidget *parent) : - QLabel(parent) + QLabel(parent), + m_action(0) { } ActiveLabel::ActiveLabel(const QString &text, QWidget *parent) : - QLabel(text, parent) + QLabel(text, parent), + m_action(0) { } @@ -37,3 +40,43 @@ void ActiveLabel::mouseDoubleClickEvent(QMouseEvent *e) QLabel::mouseDoubleClickEvent(e); } + +void ActiveLabel::setAction(QAction *action) +{ + // if was previously defined, disconnect + if (m_action) { + disconnect(m_action, &QAction::changed, this, &ActiveLabel::updateFromAction); + disconnect(this, &ActiveLabel::doubleClicked, m_action, &QAction::trigger); + } + + // set new action + m_action = action; + + // update label using action's data + updateFromAction(); + + // action action and label to have them synced + // whenever one of them is triggered + connect(m_action, &QAction::changed, this, &ActiveLabel::updateFromAction); + connect(this, &ActiveLabel::doubleClicked, m_action, &QAction::trigger); +} + +void ActiveLabel::updateFromAction() +{ + setStatusTip(m_action->statusTip()); + setToolTip(m_action->toolTip()); + setEnabled(m_action->isEnabled()); + + // update text based on QAction data + QString actionText = m_action->text(); + actionText.remove("&"); + + if (m_action->isCheckable()) { + if (m_action->isChecked()) + setText(QString("%1: %2").arg(actionText).arg(tr("on"))); + else + setText(QString("%1: %2").arg(actionText).arg(tr("off"))); + } else { + setText(actionText); + } +} diff --git a/app/controls/activelabel.h b/app/controls/activelabel.h index f7a63ab3..d9aec758 100644 --- a/app/controls/activelabel.h +++ b/app/controls/activelabel.h @@ -19,18 +19,29 @@ #include +class QAction; + class ActiveLabel : public QLabel { Q_OBJECT + public: explicit ActiveLabel(QWidget *parent = 0); explicit ActiveLabel(const QString &text, QWidget *parent = 0); + void setAction(QAction *action); + +public slots: + void updateFromAction(); + signals: void doubleClicked(); protected: void mouseDoubleClickEvent(QMouseEvent *e) Q_DECL_OVERRIDE; + +private: + QAction *m_action; }; #endif // ACTIVELABEL_H diff --git a/app/controls/fileexplorerwidget.cpp b/app/controls/fileexplorerwidget.cpp index 22704ce0..ebfd5a70 100644 --- a/app/controls/fileexplorerwidget.cpp +++ b/app/controls/fileexplorerwidget.cpp @@ -27,14 +27,13 @@ class FileSortFilterProxyModel : public QSortFilterProxyModel FileExplorerWidget::FileExplorerWidget(QWidget *parent) : QWidget(parent), + initialized(false), ui(new Ui::FileExplorerWidget), model(new QFileSystemModel(this)), sortModel(new FileSortFilterProxyModel(this)) { ui->setupUi(this); - model->setRootPath(""); - sortModel->setDynamicSortFilter(true); sortModel->setSourceModel(model); @@ -51,6 +50,15 @@ FileExplorerWidget::~FileExplorerWidget() delete ui; } +void FileExplorerWidget::showEvent(QShowEvent *event) +{ + if (!initialized) { + model->setRootPath(""); + initialized = true; + } + QWidget::showEvent(event); +} + void FileExplorerWidget::fileOpen(const QModelIndex &index) { QFileInfo info = model->fileInfo(sortModel->mapToSource(index)); diff --git a/app/controls/fileexplorerwidget.h b/app/controls/fileexplorerwidget.h index 4d931781..345b04af 100644 --- a/app/controls/fileexplorerwidget.h +++ b/app/controls/fileexplorerwidget.h @@ -21,10 +21,14 @@ class FileExplorerWidget : public QWidget signals: void fileSelected(const QString &filePath); +protected: + void showEvent(QShowEvent *event); + private slots: void fileOpen(const QModelIndex &index); private: + bool initialized; Ui::FileExplorerWidget *ui; QFileSystemModel *model; QSortFilterProxyModel *sortModel; diff --git a/app/controls/recentfilesmenu.cpp b/app/controls/recentfilesmenu.cpp index 32233add..50d79f83 100644 --- a/app/controls/recentfilesmenu.cpp +++ b/app/controls/recentfilesmenu.cpp @@ -17,6 +17,7 @@ #include "recentfilesmenu.h" #include +#include #include RecentFilesMenu::RecentFilesMenu(QWidget *parent) : @@ -52,9 +53,12 @@ void RecentFilesMenu::saveState() const void RecentFilesMenu::addFile(const QString &fileName) { + QFileInfo fileInfo(fileName); + QString absoluteNativeFileName(QDir::toNativeSeparators(fileInfo.absoluteFilePath())); + // add file to top of list - recentFiles.removeAll(fileName); - recentFiles.prepend(fileName); + recentFiles.removeAll(absoluteNativeFileName); + recentFiles.prepend(absoluteNativeFileName); // remove last entry if list contains more than 10 entries if (recentFiles.size() > 10) { diff --git a/app/hunspell/spellchecker_macx.cpp b/app/hunspell/spellchecker_macx.cpp new file mode 100644 index 00000000..18e8e753 --- /dev/null +++ b/app/hunspell/spellchecker_macx.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2016 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "spellchecker.h" +using hunspell::SpellChecker; + +#include +#include +#include +#include + +#include + +QMap SpellChecker::availableDictionaries() +{ + QMap dictionaries; + + QStringList paths; + paths << (qApp->applicationDirPath() + "/../Resources/dictionaries"); + + foreach (const QString &path, paths) { + QDir dictPath(path); + dictPath.setFilter(QDir::Files); + dictPath.setNameFilters(QStringList() << "*.dic"); + if (dictPath.exists()) { + // loop over all dictionaries in directory + QDirIterator it(dictPath); + while (it.hasNext()) { + it.next(); + + QString language = it.fileName().remove(".dic"); + language.truncate(5); // just language and country code + + Dictionary dict(it.fileName(), it.filePath()); + dictionaries.insert(language, dict); + } + } + } + + return dictionaries; +} diff --git a/app/hunspell/spellchecker_unix.cpp b/app/hunspell/spellchecker_unix.cpp index 59806c58..3f521135 100644 --- a/app/hunspell/spellchecker_unix.cpp +++ b/app/hunspell/spellchecker_unix.cpp @@ -29,7 +29,6 @@ QMap SpellChecker::availableDictionaries() QMap dictionaries; QStringList paths; - // Debian paths << QStringLiteral("/usr/local/share/myspell/dicts") << QStringLiteral("/usr/share/myspell/dicts"); diff --git a/app/main.cpp b/app/main.cpp index f5ec3a61..01ea46ce 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -56,7 +56,7 @@ int main(int argc, char *argv[]) app.setOrganizationName("CuteMarkEd Project"); app.setApplicationName("CuteMarkEd"); app.setApplicationDisplayName("CuteMarkEd"); - app.setApplicationVersion("0.11.1"); + app.setApplicationVersion("0.11.3"); #ifdef Q_OS_WIN QStringList fileTypes; diff --git a/app/mainwindow.cpp b/app/mainwindow.cpp index a4d79707..0b7f059b 100644 --- a/app/mainwindow.cpp +++ b/app/mainwindow.cpp @@ -21,7 +21,9 @@ #include #include #include +#ifndef Q_OS_OSX #include +#endif #include #include #include @@ -47,6 +49,8 @@ #include #include #include +#include +#include #include #include "controls/activelabel.h" #include "controls/findreplacewidget.h" @@ -64,20 +68,22 @@ #include "options.h" #include "optionsdialog.h" #include "revealviewsynchronizer.h" +#include "savefileadapter.h" #include "snippetcompleter.h" #include "tabletooldialog.h" +#include "statusbarwidget.h" MainWindow::MainWindow(const QString &fileName, QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), options(new Options(this)), - styleLabel(0), - wordCountLabel(0), - viewLabel(0), + stylesGroup(new QActionGroup(this)), + statusBarWidget(0), generator(new HtmlPreviewGenerator(options, this)), snippetCollection(new SnippetCollection(this)), viewSynchronizer(0), htmlPreviewController(0), + themeCollection(new ThemeCollection()), splitFactor(0.5), rightViewCollapsed(false) { @@ -124,10 +130,16 @@ void MainWindow::initializeApp() ui->webView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); ui->tocWebView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); - // set last used style - lastUsedStyle(); + themeCollection->load(":/builtin-htmlpreview-themes.json"); + loadCustomStyles(); + setupHtmlPreviewThemes(); + + // apply last used theme + lastUsedTheme(); ui->plainTextEdit->tabWidthChanged(options->tabWidth()); + ui->plainTextEdit->rulerEnabledChanged(options->isRulerEnabled()); + ui->plainTextEdit->rulerPosChanged(options->rulerPos()); // init extension flags ui->actionAutolink->setChecked(options->isAutolinkEnabled()); @@ -158,7 +170,6 @@ void MainWindow::initializeApp() QWebInspector *inspector = new QWebInspector(); inspector->setPage(ui->webView->page()); - loadCustomStyles(); ui->menuLanguages->loadDictionaries(options->dictionaryLanguage()); //: path to built-in snippets resource. @@ -198,8 +209,6 @@ void MainWindow::languageChanged(const Dictionary &dictionary) void MainWindow::fileNew() { if (maybeSave()) { - wordCountLabel->setText(""); - wordCountLabel->setToolTip(""); ui->plainTextEdit->clear(); ui->plainTextEdit->resetHighlighting(); ui->webView->setHtml(QString()); @@ -226,15 +235,22 @@ bool MainWindow::fileSave() return fileSaveAs(); } - QTextDocumentWriter writer(fileName, "plaintext"); + SaveFileAdapter file(fileName); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + return false; + } + + QTextDocumentWriter writer(&file, "plaintext"); bool success = writer.write(ui->plainTextEdit->document()); if (success) { + file.commit(); + // set status to unmodified ui->plainTextEdit->document()->setModified(false); setWindowModified(false); // add to recent file list - recentFilesMenu->addFile(QDir::toNativeSeparators(fileName)); + recentFilesMenu->addFile(fileName); } return success; @@ -304,9 +320,16 @@ void MainWindow::fileExportToHtml() void MainWindow::fileExportToPdf() { + // using temporary QTextDocument instance to get links exported\printed correctly, + // as links will dissappear when printing directly from QWebView in current Qt implementation + // of QWebView::print() method (possible bug in Qt?) + // more info here: http://stackoverflow.com/questions/11629093/add-working-url-into-pdf-using-qt-qprinter + ExportPdfDialog dialog(fileName); if (dialog.exec() == QDialog::Accepted) { - ui->webView->print(dialog.printer()); + QTextDocument doc; + doc.setHtml(ui->webView->page()->currentFrame()->toHtml()); + doc.print(dialog.printer()); } } @@ -464,97 +487,48 @@ void MainWindow::viewChangeSplit() } } -void MainWindow::lastUsedStyle() +void MainWindow::lastUsedTheme() { - if (stylesGroup) { - foreach(QAction *action, stylesGroup->actions()) { - if (action->objectName() == options->lastUsedStyle()) { - action->trigger(); - } - } - } -} - -void MainWindow::styleDefault() -{ - generator->setCodeHighlightingStyle("default"); - ui->plainTextEdit->loadStyleFromStylesheet(stylePath("default")); - ui->webView->page()->settings()->setUserStyleSheetUrl(QUrl("qrc:/css/markdown.css")); - - styleLabel->setText(ui->actionDefault->text()); - options->setLastUsedStyle(ui->actionDefault->objectName()); -} + QString themeName = options->lastUsedTheme(); -void MainWindow::styleGithub() -{ - generator->setCodeHighlightingStyle("github"); - ui->plainTextEdit->loadStyleFromStylesheet(stylePath("default")); - ui->webView->page()->settings()->setUserStyleSheetUrl(QUrl("qrc:/css/github.css")); + currentTheme = themeCollection->theme(themeName); + applyCurrentTheme(); - styleLabel->setText(ui->actionGithub->text()); - options->setLastUsedStyle(ui->actionGithub->objectName()); -} - -void MainWindow::styleSolarizedLight() -{ - generator->setCodeHighlightingStyle("solarized_light"); - ui->plainTextEdit->loadStyleFromStylesheet(stylePath("solarized-light")); - ui->webView->page()->settings()->setUserStyleSheetUrl(QUrl("qrc:/css/solarized-light.css")); - - styleLabel->setText(ui->actionSolarizedLight->text()); - options->setLastUsedStyle(ui->actionSolarizedLight->objectName()); -} - -void MainWindow::styleSolarizedDark() -{ - generator->setCodeHighlightingStyle("solarized_dark"); - ui->plainTextEdit->loadStyleFromStylesheet(stylePath("solarized-dark")); - ui->webView->page()->settings()->setUserStyleSheetUrl(QUrl("qrc:/css/solarized-dark.css")); - - styleLabel->setText(ui->actionSolarizedDark->text()); - options->setLastUsedStyle(ui->actionSolarizedDark->objectName()); + for (auto action : stylesGroup->actions()) { + if (action->text() == themeName) { + action->setChecked(true); + stylesGroup->triggered(action); + break; + } + } } -void MainWindow::styleClearness() +void MainWindow::themeChanged() { - generator->setCodeHighlightingStyle("default"); - ui->plainTextEdit->loadStyleFromStylesheet(stylePath("default")); - ui->webView->page()->settings()->setUserStyleSheetUrl(QUrl("qrc:/css/clearness.css")); - - styleLabel->setText(ui->actionClearness->text()); - options->setLastUsedStyle(ui->actionClearness->objectName()); -} + QAction *action = qobject_cast(sender()); + QString themeName = action->text(); -void MainWindow::styleClearnessDark() -{ - generator->setCodeHighlightingStyle("default"); - ui->plainTextEdit->loadStyleFromStylesheet(stylePath("clearness-dark")); - ui->webView->page()->settings()->setUserStyleSheetUrl(QUrl("qrc:/css/clearness-dark.css")); + currentTheme = themeCollection->theme(themeName); + applyCurrentTheme(); - styleLabel->setText(ui->actionClearnessDark->text()); - options->setLastUsedStyle(ui->actionClearnessDark->objectName()); + options->setLastUsedTheme(themeName); } -void MainWindow::styleBywordDark() +void MainWindow::editorStyleChanged() { - generator->setCodeHighlightingStyle("default"); - ui->plainTextEdit->loadStyleFromStylesheet(stylePath("byword-dark")); - ui->webView->page()->settings()->setUserStyleSheetUrl(QUrl("qrc:/css/byword-dark.css")); - - styleLabel->setText(ui->actionBywordDark->text()); - options->setLastUsedStyle(ui->actionBywordDark->objectName()); + QString markdownHighlighting = StyleManager::markdownHighlightingPath(currentTheme); + ui->plainTextEdit->loadStyleFromStylesheet(stylePath(markdownHighlighting)); } -void MainWindow::styleCustomStyle() +void MainWindow::applyCurrentTheme() { - QAction *action = qobject_cast(sender()); + QString markdownHighlighting = StyleManager::markdownHighlightingPath(currentTheme); + QString codeHighlighting = StyleManager::codeHighlightingPath(currentTheme); + QString previewStylesheet = StyleManager::previewStylesheetPath(currentTheme); - generator->setCodeHighlightingStyle("default"); - ui->plainTextEdit->loadStyleFromStylesheet(stylePath("default")); - ui->webView->page()->settings()->setUserStyleSheetUrl(QUrl::fromLocalFile(action->data().toString())); - - styleLabel->setText(action->text()); - options->setLastUsedStyle(action->objectName()); + generator->setCodeHighlightingStyle(codeHighlighting); + ui->plainTextEdit->loadStyleFromStylesheet(stylePath(markdownHighlighting)); + ui->webView->page()->settings()->setUserStyleSheetUrl(QUrl(previewStylesheet)); } void MainWindow::viewFullScreenMode() @@ -646,8 +620,8 @@ void MainWindow::extrasOptions() { QList actions; // file menu - actions << ui->actionNew - << ui->actionOpen + actions << ui->actionNew + << ui->actionOpen << ui->actionSave << ui->actionSaveAs << ui->actionExportToHTML @@ -678,7 +652,7 @@ void MainWindow::extrasOptions() // view menu actions << ui->dockWidget->toggleViewAction() << ui->fileExplorerDockWidget->toggleViewAction() - << ui->actionHtmlPreview + << ui->actionHtmlSource << ui->actionSplit_1_1 << ui->actionSplit_2_1 << ui->actionSplit_1_2 @@ -714,31 +688,17 @@ void MainWindow::helpAbout() dialog.exec(); } -void MainWindow::styleContextMenu(const QPoint &pos) -{ - QMenu *menu = new QMenu(); - menu->addActions(stylesGroup->actions()); - - menu->exec(styleLabel->mapToGlobal(pos)); -} - -void MainWindow::toggleHtmlView() +void MainWindow::setHtmlSource(bool enabled) { - if (viewLabel->text() == tr("HTML preview")) { + if (enabled) { ui->stackedWidget->setCurrentWidget(ui->htmlSourcePage); - ui->actionHtmlPreview->setText(tr("HTML source")); - viewLabel->setText(tr("HTML source")); - // activate HTML highlighter htmlHighlighter->setEnabled(true); htmlHighlighter->rehighlight(); } else { ui->stackedWidget->setCurrentWidget(ui->webViewPage); - ui->actionHtmlPreview->setText(tr("HTML preview")); - viewLabel->setText(tr("HTML preview")); - // deactivate HTML highlighter htmlHighlighter->setEnabled(false); @@ -746,6 +706,10 @@ void MainWindow::toggleHtmlView() syncWebViewToHtmlSource(); } + // sync view menu action + if (ui->actionHtmlSource->isChecked() != enabled) + ui->actionHtmlSource->setChecked(enabled); + updateSplitter(); } @@ -753,15 +717,6 @@ void MainWindow::plainTextChanged() { QString code = ui->plainTextEdit->toPlainText(); - // update statistics - if (wordCountLabel) { - int words = ui->plainTextEdit->countWords(); - int lines = ui->plainTextEdit->document()->lineCount(); - int chars = ui->plainTextEdit->document()->characterCount(); - wordCountLabel->setText(tr("%1 words").arg(words)); - wordCountLabel->setToolTip(tr("Lines: %1 Words: %2 Characters: %3").arg(lines).arg(words).arg(chars)); - } - // generate HTML from markdown generator->markdownTextChanged(code); @@ -795,15 +750,13 @@ void MainWindow::tocResultReady(const QString &toc) void MainWindow::previewLinkClicked(const QUrl &url) { - if(url.isLocalFile()) - { + if (url.isLocalFile()) { // directories are not supported - if(QFileInfo(url.toLocalFile()).isDir()) return; + if (QFileInfo(url.toLocalFile()).isDir()) return; QString filePath = url.toLocalFile(); // Links to markdown files open new instance - if(filePath.endsWith(".md") || filePath.endsWith(".markdown") || filePath.endsWith(".mdown")) - { + if (filePath.endsWith(".md") || filePath.endsWith(".markdown") || filePath.endsWith(".mdown")) { QProcess::startDetached(qApp->applicationFilePath(), QStringList() << filePath); return; } @@ -846,7 +799,7 @@ bool MainWindow::load(const QString &fileName) // open file QFile file(fileName); - if (!file.open(QFile::ReadOnly)) { + if (!file.open(QFile::ReadOnly | QIODevice::Text)) { return false; } @@ -861,7 +814,7 @@ bool MainWindow::load(const QString &fileName) setFileName(fileName); // add to recent files - recentFilesMenu->addFile(QDir::toNativeSeparators(fileName)); + recentFilesMenu->addFile(fileName); return true; } @@ -924,10 +877,10 @@ void MainWindow::setupUi() htmlPreviewController = new HtmlPreviewController(ui->webView, this); setupActions(); - setupStatusBar(); setupMarkdownEditor(); setupHtmlPreview(); setupHtmlSourceView(); + setupStatusBar(); // hide find/replace widget on startup ui->findReplaceWidget->hide(); @@ -943,14 +896,14 @@ void MainWindow::setupUi() ui->dockWidget_2->resize(550, 400); // show HTML preview on right panel - toggleHtmlView(); + setHtmlSource(ui->actionHtmlSource->isChecked()); connect(options, SIGNAL(proxyConfigurationChanged()), this, SLOT(proxyConfigurationChanged())); connect(options, SIGNAL(markdownConverterChanged()), this, SLOT(markdownConverterChanged())); - connect(options, SIGNAL(editorFontChanged(QFont)), - this, SLOT(lastUsedStyle())); + connect(options, &Options::editorStyleChanged, + this, &MainWindow::editorStyleChanged); readSettings(); setupCustomShortcuts(); @@ -970,11 +923,8 @@ void MainWindow::setupActions() SetActionShortcut(ui->actionNew, QKeySequence::New); SetActionShortcut(ui->actionOpen, QKeySequence::Open); SetActionShortcut(ui->actionSave, QKeySequence::Save); - ui->actionSave->setIcon(QIcon("fa-floppy-o.fontawesome")); SetActionShortcut(ui->actionSaveAs, QKeySequence::SaveAs); - ui->actionExportToPDF->setIcon(QIcon("fa-file-pdf-o.fontawesome")); SetActionShortcut(ui->action_Print, QKeySequence::Print); - ui->action_Print->setIcon(QIcon("fa-print.fontawesome")); SetActionShortcut(ui->actionExit, QKeySequence::Quit); recentFilesMenu = new RecentFilesMenu(ui->menuFile); @@ -985,31 +935,16 @@ void MainWindow::setupActions() // edit menu SetActionShortcut(ui->actionUndo, QKeySequence::Undo); - ui->actionUndo->setIcon(QIcon("fa-undo.fontawesome")); SetActionShortcut(ui->actionRedo, QKeySequence::Redo); - ui->actionRedo->setIcon(QIcon("fa-repeat.fontawesome")); SetActionShortcut(ui->actionCut, QKeySequence::Cut); - ui->actionCut->setIcon(QIcon("fa-scissors.fontawesome")); SetActionShortcut(ui->actionCopy, QKeySequence::Copy); - ui->actionCopy->setIcon(QIcon("fa-files-o.fontawesome")); SetActionShortcut(ui->actionPaste, QKeySequence::Paste); - ui->actionPaste->setIcon(QIcon("fa-clipboard.fontawesome")); + SetActionShortcut(ui->actionStrong, QKeySequence::Bold); - ui->actionStrong->setIcon(QIcon("fa-bold.fontawesome")); SetActionShortcut(ui->actionEmphasize, QKeySequence::Italic); - ui->actionEmphasize->setIcon(QIcon("fa-italic.fontawesome")); - ui->actionStrikethrough->setIcon(QIcon("fa-strikethrough.fontawesome")); - ui->actionCenterParagraph->setIcon(QIcon("fa-align-center.fontawesome")); - ui->actionIncreaseHeaderLevel->setIcon(QIcon("fa-level-up.fontawesome")); - ui->actionBlockquote->setIcon(QIcon("fa-quote-left.fontawesome")); - ui->actionDecreaseHeaderLevel->setIcon(QIcon("fa-level-down.fontawesome")); - - ui->actionInsertTable->setIcon(QIcon("fa-table.fontawesome")); - ui->actionInsertImage->setIcon(QIcon("fa-picture-o.fontawesome")); SetActionShortcut(ui->actionFindReplace, QKeySequence::Find); - ui->actionFindReplace->setIcon(QIcon("fa-search.fontawesome")); SetActionShortcut(ui->actionFindNext, QKeySequence::FindNext); SetActionShortcut(ui->actionFindPrevious, QKeySequence::FindPrevious); @@ -1024,7 +959,6 @@ void MainWindow::setupActions() ui->menuView->insertAction(ui->menuView->actions()[1], ui->fileExplorerDockWidget->toggleViewAction()); SetActionShortcut(ui->fileExplorerDockWidget->toggleViewAction(), QKeySequence(Qt::ALT + Qt::Key_E)); SetActionShortcut(ui->actionFullScreenMode, QKeySequence::FullScreen); - ui->actionFullScreenMode->setIcon(QIcon("fa-arrows-alt.fontawesome")); // extras menu connect(ui->actionMathSupport, SIGNAL(triggered(bool)), @@ -1036,20 +970,11 @@ void MainWindow::setupActions() connect(ui->menuLanguages, SIGNAL(languageTriggered(Dictionary)), this, SLOT(languageChanged(Dictionary))); - // put style actions in a group - stylesGroup = new QActionGroup(this); - ui->actionDefault->setActionGroup(stylesGroup); - ui->actionGithub->setActionGroup(stylesGroup); - ui->actionSolarizedLight->setActionGroup(stylesGroup); - ui->actionSolarizedDark->setActionGroup(stylesGroup); - ui->actionClearness->setActionGroup(stylesGroup); - ui->actionClearnessDark->setActionGroup(stylesGroup); - ui->actionBywordDark->setActionGroup(stylesGroup); - // help menu ui->actionMarkdownSyntax->setShortcut(QKeySequence::HelpContents); - ui->webView->pageAction(QWebPage::Copy)->setIcon(QIcon("fa-copy.fontawesome")); + // set actions icons + setActionsIcons(); // set names for dock widget actions ui->dockWidget->toggleViewAction()->setObjectName("actionTableOfContents"); @@ -1064,35 +989,58 @@ void MainWindow::setupActions() ui->actionInsertImage->setProperty("defaultshortcut", ui->actionInsertImage->shortcut()); ui->dockWidget->toggleViewAction()->setProperty("defaultshortcut", ui->dockWidget->toggleViewAction()->shortcut()); ui->fileExplorerDockWidget->toggleViewAction()->setProperty("defaultshortcut", ui->fileExplorerDockWidget->toggleViewAction()->shortcut()); - ui->actionHtmlPreview->setProperty("defaultshortcut", ui->actionHtmlPreview->shortcut()); + ui->actionHtmlSource->setProperty("defaultshortcut", ui->actionHtmlSource->shortcut()); } -void MainWindow::setupStatusBar() +void MainWindow::setActionsIcons() { - // remove border around statusbar widgets - statusBar()->setStyleSheet("QStatusBar::item { border: 0px solid black }; "); +#ifndef Q_OS_OSX + // file menu + ui->actionSave->setIcon(QIcon("fa-floppy-o.fontawesome")); + ui->actionExportToPDF->setIcon(QIcon("fa-file-pdf-o.fontawesome")); + ui->action_Print->setIcon(QIcon("fa-print.fontawesome")); + + // edit menu + ui->actionUndo->setIcon(QIcon("fa-undo.fontawesome")); + ui->actionRedo->setIcon(QIcon("fa-repeat.fontawesome")); + + ui->actionCut->setIcon(QIcon("fa-scissors.fontawesome")); + ui->actionCopy->setIcon(QIcon("fa-files-o.fontawesome")); + ui->actionPaste->setIcon(QIcon("fa-clipboard.fontawesome")); + + ui->actionStrong->setIcon(QIcon("fa-bold.fontawesome")); + ui->actionEmphasize->setIcon(QIcon("fa-italic.fontawesome")); + ui->actionStrikethrough->setIcon(QIcon("fa-strikethrough.fontawesome")); + ui->actionCenterParagraph->setIcon(QIcon("fa-align-center.fontawesome")); + ui->actionIncreaseHeaderLevel->setIcon(QIcon("fa-level-up.fontawesome")); + ui->actionBlockquote->setIcon(QIcon("fa-quote-left.fontawesome")); + ui->actionDecreaseHeaderLevel->setIcon(QIcon("fa-level-down.fontawesome")); - // add style label to statusbar - styleLabel = new QLabel(ui->actionDefault->text(), this); - styleLabel->setToolTip(tr("Change Preview Style")); - statusBar()->addPermanentWidget(styleLabel, 1); + ui->actionInsertTable->setIcon(QIcon("fa-table.fontawesome")); + ui->actionInsertImage->setIcon(QIcon("fa-picture-o.fontawesome")); + + ui->actionFindReplace->setIcon(QIcon("fa-search.fontawesome")); + + // view menu + ui->actionFullScreenMode->setIcon(QIcon("fa-arrows-alt.fontawesome")); + + ui->webView->pageAction(QWebPage::Copy)->setIcon(QIcon("fa-copy.fontawesome")); +#endif +} - styleLabel->setContextMenuPolicy(Qt::CustomContextMenu); - connect(styleLabel, SIGNAL(customContextMenuRequested(QPoint)), - this, SLOT(styleContextMenu(QPoint))); +void MainWindow::setupStatusBar() +{ + statusBarWidget = new StatusBarWidget(ui->plainTextEdit); + statusBarWidget->setHtmlAction(ui->actionHtmlSource); - // add word count label to statusbar - wordCountLabel = new QLabel(this); - wordCountLabel->setAlignment(Qt::AlignHCenter); - statusBar()->addPermanentWidget(wordCountLabel, 1); + connect(options, &Options::lineColumnEnabledChanged, + statusBarWidget, &StatusBarWidget::showLineColumn); - // add view label to statusbar - viewLabel = new ActiveLabel(this); - viewLabel->setAlignment(Qt::AlignRight); - statusBar()->addPermanentWidget(viewLabel, 1); + statusBarWidget->update(); - connect(viewLabel, SIGNAL(doubleClicked()), - this, SLOT(toggleHtmlView())); + // remove border around statusbar widgets + statusBar()->setStyleSheet("QStatusBar::item { border: 0px solid black }; "); + statusBar()->addPermanentWidget(statusBarWidget, 1); } void MainWindow::setupMarkdownEditor() @@ -1103,10 +1051,14 @@ void MainWindow::setupMarkdownEditor() connect(ui->plainTextEdit, SIGNAL(loadDroppedFile(QString)), this, SLOT(load(QString))); - connect(options, SIGNAL(editorFontChanged(QFont)), - ui->plainTextEdit, SLOT(editorFontChanged(QFont))); - connect(options, SIGNAL(tabWidthChanged(int)), - ui->plainTextEdit, SLOT(tabWidthChanged(int))); + connect(options, &Options::editorFontChanged, + ui->plainTextEdit, &MarkdownEditor::editorFontChanged); + connect(options, &Options::tabWidthChanged, + ui->plainTextEdit, &MarkdownEditor::tabWidthChanged); + connect(options, &Options::rulerEnabledChanged, + ui->plainTextEdit, &MarkdownEditor::rulerEnabledChanged); + connect(options, &Options::rulerPosChanged, + ui->plainTextEdit, &MarkdownEditor::rulerPosChanged); } void MainWindow::setupHtmlPreview() @@ -1231,6 +1183,42 @@ void MainWindow::updateSplitter() ui->splitter->setSizes(childSizes); } +void MainWindow::setupHtmlPreviewThemes() +{ + ui->menuStyles->clear(); + + delete stylesGroup; + stylesGroup = new QActionGroup(this); + + int key = 1; + bool separatorAdded = false; + foreach(const QString &themeName, themeCollection->themeNames()) { + if (!separatorAdded && !themeCollection->theme(themeName).isBuiltIn()) { + addSeparatorAfterBuiltInThemes(); + separatorAdded = true; + } + + QAction *action = ui->menuStyles->addAction(themeName); + action->setShortcut(QKeySequence(tr("Ctrl+%1").arg(key++))); + action->setCheckable(true); + action->setActionGroup(stylesGroup); + connect(action, &QAction::triggered, + this, &MainWindow::themeChanged); + } + + if (statusBarWidget) + statusBarWidget->setStyleActions(stylesGroup); +} + +void MainWindow::addSeparatorAfterBuiltInThemes() +{ + ui->menuStyles->addSeparator(); + + QAction *separator = new QAction(stylesGroup); + separator->setSeparator(true); + stylesGroup->addAction(separator); +} + void MainWindow::loadCustomStyles() { QStringList paths = DataLocation::standardLocations(); @@ -1238,21 +1226,20 @@ void MainWindow::loadCustomStyles() QDir dataPath(paths.first() + QDir::separator() + "styles"); dataPath.setFilter(QDir::Files); if (dataPath.exists()) { - ui->menuStyles->addSeparator(); - // iterate over all files in the styles subdirectory QDirIterator it(dataPath); while (it.hasNext()) { it.next(); QString fileName = it.fileName(); - QAction *action = ui->menuStyles->addAction(QFileInfo(fileName).baseName()); - action->setCheckable(true); - action->setActionGroup(stylesGroup); - action->setData(it.filePath()); + QString styleName = QFileInfo(fileName).baseName(); + QString stylePath = QUrl::fromLocalFile(it.filePath()).toString(); + + Theme customTheme { styleName, "Default", "Default", styleName }; + themeCollection->insert(customTheme); - connect(action, SIGNAL(triggered()), - this, SLOT(styleCustomStyle())); + StyleManager styleManager; + styleManager.insertCustomPreviewStylesheet(styleName, stylePath); } } } diff --git a/app/mainwindow.h b/app/mainwindow.h index 9e001a71..bae34ff7 100644 --- a/app/mainwindow.h +++ b/app/mainwindow.h @@ -20,6 +20,7 @@ #include #include #include +#include namespace Ui { class MainWindow; @@ -37,7 +38,9 @@ class RecentFilesMenu; class Options; class SlideLineMapping; class SnippetCollection; +class ThemeCollection; class ViewSynchronizer; +class StatusBarWidget; class MainWindow : public QMainWindow @@ -83,15 +86,9 @@ private slots: void editInsertImage(); void viewChangeSplit(); - void lastUsedStyle(); - void styleDefault(); - void styleGithub(); - void styleSolarizedLight(); - void styleSolarizedDark(); - void styleClearness(); - void styleClearnessDark(); - void styleBywordDark(); - void styleCustomStyle(); + void lastUsedTheme(); + void themeChanged(); + void editorStyleChanged(); void viewFullScreenMode(); void viewHorizontalLayout(bool checked); @@ -111,8 +108,7 @@ private slots: void helpMarkdownSyntax(); void helpAbout(); - void styleContextMenu(const QPoint &pos); - void toggleHtmlView(); + void setHtmlSource(bool enabled); void plainTextChanged(); void htmlResultReady(const QString &html); @@ -131,6 +127,7 @@ private slots: private: void setupUi(); void setupActions(); + void setActionsIcons(); void setupStatusBar(); void setupMarkdownEditor(); void setupHtmlPreview(); @@ -143,9 +140,12 @@ private slots: bool maybeSave(); void setFileName(const QString &fileName); void updateSplitter(); + void setupHtmlPreviewThemes(); + void addSeparatorAfterBuiltInThemes(); void loadCustomStyles(); void readSettings(); void writeSettings(); + void applyCurrentTheme(); QString stylePath(const QString &styleName); private: @@ -153,14 +153,14 @@ private slots: RecentFilesMenu *recentFilesMenu; Options *options; QActionGroup *stylesGroup; - QLabel *styleLabel; - QLabel *wordCountLabel; - ActiveLabel *viewLabel; + StatusBarWidget* statusBarWidget; HtmlPreviewGenerator* generator; HtmlHighlighter *htmlHighlighter; SnippetCollection *snippetCollection; ViewSynchronizer *viewSynchronizer; HtmlPreviewController *htmlPreviewController; + ThemeCollection *themeCollection; + Theme currentTheme { "Default", "Default", "Default", "Default" }; QString fileName; float splitFactor; bool rightViewCollapsed; diff --git a/app/mainwindow.ui b/app/mainwindow.ui index 0de78cd1..a4f0741a 100644 --- a/app/mainwindow.ui +++ b/app/mainwindow.ui @@ -167,7 +167,7 @@ 0 0 850 - 18 + 21 @@ -239,7 +239,7 @@ &View - + @@ -258,13 +258,6 @@ St&yles - - - - - - - @@ -424,53 +417,6 @@ &Redo - - - true - - - true - - - Default - - - Ctrl+1 - - - - - true - - - Github - - - Ctrl+2 - - - - - true - - - Solarized Light - - - Ctrl+3 - - - - - true - - - Solarized Dark - - - Ctrl+4 - - &About CuteMarkEd... @@ -572,28 +518,6 @@ Code &Highlighting - - - true - - - Clearness - - - Ctrl+5 - - - - - true - - - Clearness Dark - - - Ctrl+6 - - Find/Replace @@ -651,9 +575,15 @@ &Markdown Syntax - + + + true + - HTML &Preview + HTML &Source + + + Show HTML source code in HTML preview window F5 @@ -749,14 +679,6 @@ Ctrl+T - - - Byword Dark - - - Ctrl+7 - - Insert &Image... @@ -979,70 +901,6 @@ - - actionDefault - triggered() - MainWindow - styleDefault() - - - -1 - -1 - - - 399 - 249 - - - - - actionGithub - triggered() - MainWindow - styleGithub() - - - -1 - -1 - - - 399 - 249 - - - - - actionSolarizedLight - triggered() - MainWindow - styleSolarizedLight() - - - -1 - -1 - - - 399 - 249 - - - - - actionSolarizedDark - triggered() - MainWindow - styleSolarizedDark() - - - -1 - -1 - - - 399 - 249 - - - actionAbout triggered() @@ -1363,38 +1221,6 @@ - - actionClearness - triggered() - MainWindow - styleClearness() - - - -1 - -1 - - - 399 - 249 - - - - - actionClearnessDark - triggered() - MainWindow - styleClearnessDark() - - - -1 - -1 - - - 399 - 249 - - - actionFindReplace triggered() @@ -1508,10 +1334,10 @@ - actionHtmlPreview - triggered() + actionHtmlSource + triggered(bool) MainWindow - toggleHtmlView() + setHtmlSource(bool) -1 @@ -1699,22 +1525,6 @@ - - actionBywordDark - triggered() - MainWindow - styleBywordDark() - - - -1 - -1 - - - 424 - 266 - - - actionInsertImage triggered() diff --git a/app/markdowneditor.cpp b/app/markdowneditor.cpp index aaf9c088..3ea9e4bd 100644 --- a/app/markdowneditor.cpp +++ b/app/markdowneditor.cpp @@ -170,6 +170,11 @@ void MarkdownEditor::paintEvent(QPaintEvent *e) if (showHardLinebreaks) { drawLineEndMarker(e); } + + // draw column ruler + if (rulerEnabled) { + drawRuler(e); + } } void MarkdownEditor::resizeEvent(QResizeEvent *event) @@ -252,6 +257,18 @@ void MarkdownEditor::tabWidthChanged(int tabWidth) setTabStopWidth(tabWidth*fm.width(' ')); } +void MarkdownEditor::rulerEnabledChanged(bool enabled) +{ + rulerEnabled = enabled; + viewport()->update(); +} + +void MarkdownEditor::rulerPosChanged(int pos) +{ + rulerPos = pos; + viewport()->update(); +} + void MarkdownEditor::showContextMenu(const QPoint &pos) { QMenu *contextMenu = createStandardContextMenu(); @@ -500,6 +517,27 @@ void MarkdownEditor::drawLineEndMarker(QPaintEvent *e) } } +void MarkdownEditor::drawRuler(QPaintEvent *e) +{ + const QRect rect = e->rect(); + const QFont font = currentCharFormat().font(); + + // calculate vertical offset corresponding given + // column margin in font metrics + int verticalOffset = qRound(QFontMetricsF(font).averageCharWidth() * rulerPos) + + contentOffset().x() + + document()->documentMargin(); + + // draw a ruler with color invert to background color (better readability) + // and with 50% opacity + QPainter p(viewport()); + p.setCompositionMode(QPainter::RasterOp_SourceXorDestination); + p.setPen(QColor(0xff, 0xff, 0xff)); + p.setOpacity(0.5); + + p.drawLine(verticalOffset, rect.top(), verticalOffset, rect.bottom()); +} + QString MarkdownEditor::textUnderCursor() const { QTextCursor cursor = this->textCursor(); @@ -551,7 +589,7 @@ QStringList MarkdownEditor::filterWordList(const QStringList &words, UnaryPredic foreach (const QString &word, words) { if (predicate(word)) { - filteredWordList << word; + filteredWordList << word; } } diff --git a/app/markdowneditor.h b/app/markdowneditor.h index ce730dc7..88d5b513 100644 --- a/app/markdowneditor.h +++ b/app/markdowneditor.h @@ -63,11 +63,14 @@ class MarkdownEditor : public QPlainTextEdit public slots: void tabWidthChanged(int tabWidth); + void editorFontChanged(const QFont &font); + void rulerEnabledChanged(bool enabled); + void rulerPosChanged(int pos); private slots: void updateLineNumberAreaWidth(int newBlockCount); void updateLineNumberArea(const QRect &rect, int dy); - void editorFontChanged(const QFont &font); + void showContextMenu(const QPoint &pos); void replaceWithSuggestion(); void performCompletion(); @@ -77,6 +80,7 @@ private slots: private: bool isUrlToLocalFile(const QMimeData *source) const; void drawLineEndMarker(QPaintEvent *e); + void drawRuler(QPaintEvent *e); QString textUnderCursor() const; QStringList extractDistinctWordsFromDocument() const; QStringList retrieveAllWordsFromDocument() const; @@ -89,6 +93,8 @@ private slots: hunspell::SpellChecker *spellChecker; SnippetCompleter *completer; bool showHardLinebreaks; + bool rulerEnabled; + int rulerPos; }; #endif // MARKDOWNEDITOR_H diff --git a/app/options.cpp b/app/options.cpp index 1737b8cf..14ba8da0 100644 --- a/app/options.cpp +++ b/app/options.cpp @@ -16,17 +16,19 @@ */ #include "options.h" -#include #include static const char* MARKDOWN_CONVERTER = "General/converter"; -static const char* LAST_USED_STYLE = "General/lastusedstyle"; -static const char* STYLE_DEFAULT = "actionDefault"; +static const char* LAST_USED_THEME = "General/lastusedtheme"; +static const char* THEME_DEFAULT = "Default"; static const char* FONT_FAMILY_DEFAULT = "Monospace"; static const char* FONT_FAMILY = "editor/font/family"; static const char* FONT_SIZE = "editor/font/size"; static const char* TAB_WIDTH = "editor/tabwidth"; +static const char* LINECOLUMN_ENABLED = "editor/linecolumn/enabled"; +static const char* RULER_ENABLED = "editor/ruler/enabled"; +static const char* RULER_POS = "editor/ruler/pos"; static const char* PREVIEW_STANDARD_FONT = "preview/standardfont"; static const char* PREVIEW_FIXED_FONT = "preview/fixedfont"; static const char* PREVIEW_SERIF_FONT = "preview/seriffont"; @@ -56,6 +58,7 @@ static const char* DICTIONARY_LANGUAGE = "spelling/language"; static const char* YAMLHEADERSUPPORT_ENABLED = "yamlheadersupport/enabled"; static const char* DIAGRAMSUPPORT_ENABLED = "diagramsupport/enabled"; +static const char* DEPRECATED__LAST_USED_STYLE = "general/lastusedstyle"; Options::Options(QObject *parent) : QObject(parent), @@ -77,8 +80,11 @@ Options::Options(QObject *parent) : m_sourceAtSingleSizeEnabled(true), m_spellingCheckEnabled(true), m_diagramSupportEnabled(false), + m_lineColumnEnabled(true), + m_rulerEnabled(false), + m_rulerPos(80), m_markdownConverter(DiscountMarkdownConverter), - m_lastUsedStyle(STYLE_DEFAULT) + m_lastUsedTheme(THEME_DEFAULT) { } @@ -94,7 +100,9 @@ void Options::apply() emit proxyConfigurationChanged(); emit markdownConverterChanged(); - emit editorFontChanged(editorFont()); + emit lineColumnEnabledChanged(m_lineColumnEnabled); + emit rulerEnabledChanged(m_rulerEnabled); + emit rulerPosChanged(m_rulerPos); } QFont Options::editorFont() const @@ -119,6 +127,39 @@ void Options::setTabWidth(int width) emit tabWidthChanged(width); } +bool Options::isLineColumnEnabled() const +{ + return m_lineColumnEnabled; +} + +void Options::setLineColumnEnabled(bool enabled) +{ + m_lineColumnEnabled = enabled; + emit lineColumnEnabledChanged(enabled); +} + +bool Options::isRulerEnabled() const +{ + return m_rulerEnabled; +} + +void Options::setRulerEnabled(bool enabled) +{ + m_rulerEnabled = enabled; + emit rulerEnabledChanged(enabled); +} + +int Options::rulerPos() const +{ + return m_rulerPos; +} + +void Options::setRulerPos(int pos) +{ + m_rulerPos = pos; + emit rulerPosChanged(pos); +} + QFont Options::standardFont() const { return QFont(m_standardFontFamily); @@ -373,6 +414,7 @@ bool Options::isSourceAtSingleSizeEnabled() const void Options::setSourceAtSingleSizeEnabled(bool enabled) { m_sourceAtSingleSizeEnabled = enabled; + emit editorStyleChanged(); } bool Options::isSpellingCheckEnabled() const @@ -428,14 +470,14 @@ void Options::setMarkdownConverter(Options::MarkdownConverter converter) } } -QString Options::lastUsedStyle() const +QString Options::lastUsedTheme() const { - return m_lastUsedStyle; + return m_lastUsedTheme; } -void Options::setLastUsedStyle(const QString &style) +void Options::setLastUsedTheme(const QString &theme) { - m_lastUsedStyle = style; + m_lastUsedTheme = theme; } void Options::readSettings() @@ -444,13 +486,16 @@ void Options::readSettings() // general settings m_markdownConverter = (Options::MarkdownConverter)settings.value(MARKDOWN_CONVERTER, 0).toInt(); - m_lastUsedStyle = settings.value(LAST_USED_STYLE, STYLE_DEFAULT).toString(); + m_lastUsedTheme = settings.value(LAST_USED_THEME, THEME_DEFAULT).toString(); // editor settings QString fontFamily = settings.value(FONT_FAMILY, FONT_FAMILY_DEFAULT).toString(); int fontSize = settings.value(FONT_SIZE, 10).toInt(); m_tabWidth = settings.value(TAB_WIDTH, 8).toInt(); + m_lineColumnEnabled = settings.value(LINECOLUMN_ENABLED, false).toBool(); + m_rulerEnabled = settings.value(RULER_ENABLED, false).toBool(); + m_rulerPos = settings.value(RULER_POS, 80).toInt(); QFont f(fontFamily, fontSize); f.setStyleHint(QFont::TypeWriter); @@ -502,6 +547,11 @@ void Options::readSettings() m_spellingCheckEnabled = settings.value(SPELLINGCHECK_ENABLED, true).toBool(); m_dictionaryLanguage = settings.value(DICTIONARY_LANGUAGE, "en_US").toString(); + // migrate deprecated lastUsedStyle option + if (settings.contains(DEPRECATED__LAST_USED_STYLE)) { + migrateLastUsedStyleOption(settings); + } + apply(); } @@ -511,12 +561,15 @@ void Options::writeSettings() // general settings settings.setValue(MARKDOWN_CONVERTER, m_markdownConverter); - settings.setValue(LAST_USED_STYLE, m_lastUsedStyle); + settings.setValue(LAST_USED_THEME, m_lastUsedTheme); // editor settings settings.setValue(FONT_FAMILY, font.family()); settings.setValue(FONT_SIZE, font.pointSize()); settings.setValue(TAB_WIDTH, m_tabWidth); + settings.setValue(LINECOLUMN_ENABLED, m_lineColumnEnabled); + settings.setValue(RULER_ENABLED, m_rulerEnabled); + settings.setValue(RULER_POS, m_rulerPos); // html preview settings settings.setValue(PREVIEW_STANDARD_FONT, m_standardFontFamily); @@ -564,3 +617,21 @@ void Options::writeSettings() settings.setValue(SPELLINGCHECK_ENABLED, m_spellingCheckEnabled); settings.setValue(DICTIONARY_LANGUAGE, m_dictionaryLanguage); } + +void Options::migrateLastUsedStyleOption(QSettings &settings) +{ + static const QMap migrations { + { "actionDefault", "Default" }, + { "actionGithub", "Github" }, + { "actionSolarizedLight", "Solarized Light" }, + { "actionSolarizedDark", "Solarized Dark" }, + { "actionClearness", "Clearness" }, + { "actionClearnessDark", "Clearness Dark" }, + { "actionBywordDark", "Byword Dark" } + }; + + QString lastUsedStyle = settings.value(DEPRECATED__LAST_USED_STYLE).toString(); + m_lastUsedTheme = migrations[lastUsedStyle]; + + settings.remove(DEPRECATED__LAST_USED_STYLE); +} diff --git a/app/options.h b/app/options.h index 8cc2c809..68d26307 100644 --- a/app/options.h +++ b/app/options.h @@ -21,6 +21,7 @@ #include #include #include +#include class Options : public QObject { @@ -44,6 +45,15 @@ class Options : public QObject int tabWidth() const; void setTabWidth(int width); + bool isLineColumnEnabled() const; + void setLineColumnEnabled(bool enabled); + + bool isRulerEnabled() const; + void setRulerEnabled(bool enabled); + + int rulerPos() const; + void setRulerPos(int pos); + /* HTML preview options */ QFont standardFont() const; void setStandardFont(const QFont &font); @@ -139,18 +149,26 @@ class Options : public QObject MarkdownConverter markdownConverter() const; void setMarkdownConverter(MarkdownConverter converter); - QString lastUsedStyle() const; - void setLastUsedStyle(const QString &style); + QString lastUsedTheme() const; + void setLastUsedTheme(const QString &theme); void readSettings(); void writeSettings(); signals: void editorFontChanged(const QFont &font); + void editorStyleChanged(); void tabWidthChanged(int tabWidth); + void lineColumnEnabledChanged(bool enabled); + void rulerEnabledChanged(bool enabled); + void rulerPosChanged(int pos); + void proxyConfigurationChanged(); void markdownConverterChanged(); +private: + void migrateLastUsedStyleOption(QSettings &settings); + private: QFont font; int m_tabWidth; @@ -175,9 +193,12 @@ class Options : public QObject bool m_spellingCheckEnabled; bool m_yamlHeaderSupportEnabled; bool m_diagramSupportEnabled; + bool m_lineColumnEnabled; + bool m_rulerEnabled; + int m_rulerPos; QString m_dictionaryLanguage; MarkdownConverter m_markdownConverter; - QString m_lastUsedStyle; + QString m_lastUsedTheme; QString m_standardFontFamily; QString m_fixedFontFamily; QString m_serifFontFamily; diff --git a/app/optionsdialog.cpp b/app/optionsdialog.cpp index ebcb0dad..21508aa2 100644 --- a/app/optionsdialog.cpp +++ b/app/optionsdialog.cpp @@ -287,6 +287,9 @@ void OptionsDialog::readState() ui->sizeComboBox->setCurrentText(QString().setNum(font.pointSize())); ui->sourceSingleSizedCheckBox->setChecked(options->isSourceAtSingleSizeEnabled()); ui->tabWidthSpinBox->setValue(options->tabWidth()); + ui->lineColumnCheckBox->setChecked(options->isLineColumnEnabled()); + ui->rulerEnableCheckBox->setChecked(options->isRulerEnabled()); + ui->rulerPosSpinBox->setValue(options->rulerPos()); // html preview settings ui->standardFontComboBox->setCurrentFont(options->standardFont()); @@ -334,6 +337,9 @@ void OptionsDialog::saveState() options->setEditorFont(font); options->setSourceAtSingleSizeEnabled(ui->sourceSingleSizedCheckBox->isChecked()); options->setTabWidth(ui->tabWidthSpinBox->value()); + options->setLineColumnEnabled(ui->lineColumnCheckBox->isChecked()); + options->setRulerEnabled(ui->rulerEnableCheckBox->isChecked()); + options->setRulerPos(ui->rulerPosSpinBox->value()); options->setMathInlineSupportEnabled(ui->mathInlineCheckBox->isChecked()); options->setMathSupportEnabled(ui->mathSupportCheckBox->isChecked()); diff --git a/app/optionsdialog.ui b/app/optionsdialog.ui index ece773ac..c95be62d 100644 --- a/app/optionsdialog.ui +++ b/app/optionsdialog.ui @@ -87,34 +87,74 @@ Font - - - - - - - - Si&ze: - - - sizeComboBox - - - - - - - - - - &Family: - - - fontComboBox - - + + + + + + + &Family: + + + fontComboBox + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 40 + 6 + + + + + + + + Si&ze: + + + sizeComboBox + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - + Markdown Source at Single Size @@ -169,11 +209,70 @@ + + + + Other + + + + + + + + Display right margin at column: + + + + + + + false + + + 1 + + + 999 + + + 80 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Show cursor position in status bar + + + + + + Qt::Vertical + + QSizePolicy::Expanding + 20 @@ -195,6 +294,35 @@ Fonts + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + S&ans Serif Font: + + + sansSerifFontComboBox + + + + + + + + + @@ -205,19 +333,16 @@ - - + + - - + + Size: - - - @@ -228,19 +353,30 @@ - - - - - + + + + + 0 + 0 + + + - - + + - S&ans Serif Font: + Size: - - sansSerifFontComboBox + + + + + + + 0 + 0 + @@ -257,15 +393,21 @@ - - - - - - - Size: + + + + Qt::Horizontal - + + QSizePolicy::Minimum + + + + 40 + 6 + + + @@ -648,6 +790,22 @@ + + rulerEnableCheckBox + toggled(bool) + rulerPosSpinBox + setEnabled(bool) + + + 115 + 214 + + + 228 + 214 + + + addSnippetButtonClicked() diff --git a/app/resources.qrc b/app/resources.qrc index c364e28d..85ce4a96 100644 --- a/app/resources.qrc +++ b/app/resources.qrc @@ -34,6 +34,7 @@ syntax_id.html syntax_da.html template_presentation.html + builtin-htmlpreview-themes.json images/icon-close.png @@ -47,5 +48,6 @@ scripts/highlight.js/styles/github.css scripts/highlight.js/styles/solarized_dark.css scripts/mermaid/mermaid.full.min.js + scripts/mermaid/mermaid.css diff --git a/app/savefileadapter.h b/app/savefileadapter.h new file mode 100644 index 00000000..0fbb7e89 --- /dev/null +++ b/app/savefileadapter.h @@ -0,0 +1,38 @@ +/* + * Copyright 2016 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef SAVEFILEADAPTER_H +#define SAVEFILEADAPTER_H + +#include + + +class SaveFileAdapter : public QSaveFile +{ +public: + SaveFileAdapter(const QString &name) : + QSaveFile(name) + { + } + + void close() { + // IGNORE - work-around for the problem that QTextDocumentWriter::write() + // calls close() on the device + } + +}; + +#endif // SAVEFILEADAPTER_H diff --git a/app/scripts/mermaid/mermaid.css b/app/scripts/mermaid/mermaid.css new file mode 100644 index 00000000..92802a46 --- /dev/null +++ b/app/scripts/mermaid/mermaid.css @@ -0,0 +1,256 @@ +/* Flowchart variables */ +/* Sequence Diagram variables */ +/* Gantt chart variables */ +.mermaid .label { + color: #333333; +} +.node rect, +.node circle, +.node polygon { + fill: #ececff; + stroke: #ccccff; + stroke-width: 1px; +} +.edgePath .path { + stroke: #333333; +} +.cluster rect { + fill: #ffffde; + rx: 40; + stroke: #aaaa33; + stroke-width: 1px; +} +.cluster text { + fill: #333333; +} +.actor { + stroke: #ccccff; + fill: #ececff; +} +text.actor { + fill: black; + stroke: none; +} +.actor-line { + stroke: grey; +} +.messageLine0 { + stroke-width: 1.5; + stroke-dasharray: "2 2"; + marker-end: "url(#arrowhead)"; + stroke: #333333; +} +.messageLine1 { + stroke-width: 1.5; + stroke-dasharray: "2 2"; + stroke: #333333; +} +#arrowhead { + fill: #333333; +} +#crosshead path { + fill: #333333 !important; + stroke: #333333 !important; +} +.messageText { + fill: #333333; + stroke: none; +} +.labelBox { + stroke: #ccccff; + fill: #ececff; +} +.labelText { + fill: black; + stroke: none; +} +.loopText { + fill: black; + stroke: none; +} +.loopLine { + stroke-width: 2; + stroke-dasharray: "2 2"; + marker-end: "url(#arrowhead)"; + stroke: #ccccff; +} +.note { + stroke: #aaaa33; + fill: #fff5ad; +} +.noteText { + fill: black; + stroke: none; + font-family: 'trebuchet ms', verdana, arial; + font-size: 14px; +} +/** Section styling */ +.section { + stroke: none; + opacity: 0.2; +} +.section0 { + fill: rgba(102, 102, 255, 0.49); +} +.section2 { + fill: #fff400; +} +.section1, +.section3 { + fill: white; + opacity: 0.2; +} +.sectionTitle0 { + fill: #333333; +} +.sectionTitle1 { + fill: #333333; +} +.sectionTitle2 { + fill: #333333; +} +.sectionTitle3 { + fill: #333333; +} +.sectionTitle { + text-anchor: start; + font-size: 11px; + text-height: 14px; +} +/* Grid and axis */ +.grid .tick { + stroke: lightgrey; + opacity: 0.3; + shape-rendering: crispEdges; +} +.grid path { + stroke-width: 0; +} +/* Today line */ +.today { + fill: none; + stroke: red; + stroke-width: 2px; +} +/* Task styling */ +/* Default task */ +.task { + stroke-width: 2; +} +.taskText { + text-anchor: middle; + font-size: 11px; +} +.taskTextOutsideRight { + fill: black; + text-anchor: start; + font-size: 11px; +} +.taskTextOutsideLeft { + fill: black; + text-anchor: end; + font-size: 11px; +} +/* Specific task settings for the sections*/ +.taskText0, +.taskText1, +.taskText2, +.taskText3 { + fill: white; +} +.task0, +.task1, +.task2, +.task3 { + fill: #8a90dd; + stroke: #534fbc; +} +.taskTextOutside0, +.taskTextOutside2 { + fill: black; +} +.taskTextOutside1, +.taskTextOutside3 { + fill: black; +} +/* Active task */ +.active0, +.active1, +.active2, +.active3 { + fill: #bfc7ff; + stroke: #534fbc; +} +.activeText0, +.activeText1, +.activeText2, +.activeText3 { + fill: black !important; +} +/* Completed task */ +.done0, +.done1, +.done2, +.done3 { + stroke: grey; + fill: lightgrey; + stroke-width: 2; +} +.doneText0, +.doneText1, +.doneText2, +.doneText3 { + fill: black !important; +} +/* Tasks on the critical line */ +.crit0, +.crit1, +.crit2, +.crit3 { + stroke: #ff8888; + fill: red; + stroke-width: 2; +} +.activeCrit0, +.activeCrit1, +.activeCrit2, +.activeCrit3 { + stroke: #ff8888; + fill: #bfc7ff; + stroke-width: 2; +} +.doneCrit0, +.doneCrit1, +.doneCrit2, +.doneCrit3 { + stroke: #ff8888; + fill: lightgrey; + stroke-width: 2; + cursor: pointer; + shape-rendering: crispEdges; +} +.doneCritText0, +.doneCritText1, +.doneCritText2, +.doneCritText3 { + fill: black !important; +} +.activeCritText0, +.activeCritText1, +.activeCritText2, +.activeCritText3 { + fill: black !important; +} +.titleText { + text-anchor: middle; + font-size: 18px; + fill: black; +} +/* + + +*/ +text { + font-family: 'trebuchet ms', verdana, arial; + font-size: 14px; +} diff --git a/app/statusbarwidget.cpp b/app/statusbarwidget.cpp new file mode 100644 index 00000000..6591af32 --- /dev/null +++ b/app/statusbarwidget.cpp @@ -0,0 +1,138 @@ +#include "statusbarwidget.h" + +#include +#include +#include +#include +#include +#include + +#include "controls/activelabel.h" +#include "markdowneditor.h" + +StatusBarWidget::StatusBarWidget(MarkdownEditor* editor) : + m_editor(editor), + m_lineColLabel(0), + m_wordCountLabel(0), + m_styleLabel(0), + m_styleActions(0), + m_htmlLabel(0) + +{ + // main layout + QHBoxLayout *topLayout = new QHBoxLayout(this); + topLayout->setContentsMargins(4,0,4,0); + topLayout->setSpacing(4); + + // line&column label + m_lineColLabel = new QLabel; + topLayout->addWidget(m_lineColLabel, 0); + m_lineColLabel->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); + + // word count label + m_wordCountLabel = new QLabel; + m_wordCountLabel->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter); + topLayout->addWidget(m_wordCountLabel, 0); + + // add spacer + topLayout->addItem(new QSpacerItem(0,10, QSizePolicy::Expanding, QSizePolicy::Expanding)); + + // styles label + m_styleLabel = new QLabel; + m_styleLabel->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter); + topLayout->addWidget(m_styleLabel, 0); + + m_styleLabel->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_styleLabel, &QLabel::customContextMenuRequested, this, &StatusBarWidget::styleContextMenu); + + // separator label + topLayout->addWidget(new QLabel("|"), 0); + + // html preview label + m_htmlLabel = new ActiveLabel; + m_htmlLabel->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter); + topLayout->addWidget(m_htmlLabel, 0); + + connect(m_editor, &MarkdownEditor::cursorPositionChanged, this, &StatusBarWidget::cursorPositionChanged); + connect(m_editor, &MarkdownEditor::textChanged, this, &StatusBarWidget::textChanged); +} + +StatusBarWidget::~StatusBarWidget() +{ +} + +void StatusBarWidget::update() +{ + cursorPositionChanged(); + textChanged(); +} + +void StatusBarWidget::showLineColumn(bool enabled) +{ + if (enabled) + m_lineColLabel->show(); + else + m_lineColLabel->hide(); +} + +void StatusBarWidget::setHtmlAction(QAction *action) +{ + m_htmlLabel->setAction(action); +} + +void StatusBarWidget::setStyleActions(QActionGroup *actionGroup) +{ + // if was previously defined, disconnect + if (m_styleActions) { + disconnect(m_styleActions, &QActionGroup::triggered, this, &StatusBarWidget::updateStyleLabel); + } + + // set new actions group + m_styleActions = actionGroup; + updateStyleLabel(); + + connect(m_styleActions, &QActionGroup::triggered, this, &StatusBarWidget::updateStyleLabel); +} + +void StatusBarWidget::cursorPositionChanged() +{ + QTextCursor cursor = m_editor->textCursor(); + + int line = cursor.blockNumber(); + int column = cursor.positionInBlock(); + + m_lineColLabel->setText(tr("Line %1, Column %2 %3") + .arg(QLocale().toString(line + 1)) + .arg(QLocale().toString(column + 1)) + .arg("|") + ); +} + +void StatusBarWidget::textChanged() +{ + // update statistics + if (m_wordCountLabel) { + int words = m_editor->countWords(); + int lines = m_editor->document()->lineCount(); + int chars = m_editor->document()->characterCount(); + + m_wordCountLabel->setText(tr("%1 words").arg(words)); + m_wordCountLabel->setToolTip(tr("Lines: %1 Words: %2 Characters: %3").arg(lines).arg(words).arg(chars)); + } +} + +void StatusBarWidget::styleContextMenu(const QPoint &pos) +{ + if (m_styleActions) { + QMenu menu; + menu.addActions(m_styleActions->actions()); + menu.exec(m_styleLabel->mapToGlobal(pos)); + } +} + +void StatusBarWidget::updateStyleLabel() +{ + QAction* action = m_styleActions->checkedAction(); + if (action) + m_styleLabel->setText(tr("Style: %1").arg(action->text())); +} diff --git a/app/statusbarwidget.h b/app/statusbarwidget.h new file mode 100644 index 00000000..573e0542 --- /dev/null +++ b/app/statusbarwidget.h @@ -0,0 +1,47 @@ +#ifndef STATUSBARWIDGET_H +#define STATUSBARWIDGET_H + +#include + +class QLabel; +class QActionGroup; + +class MarkdownEditor; +class ActiveLabel; + +class StatusBarWidget : public QWidget +{ + Q_OBJECT + +public: + explicit StatusBarWidget(MarkdownEditor* editor); + ~StatusBarWidget(); + +public slots: + void update(); + void showLineColumn(bool enabled); + + void setHtmlAction(QAction *action); + void setStyleActions(QActionGroup *actionGroup); + +private slots: + void cursorPositionChanged(); + void textChanged(); + + void styleContextMenu(const QPoint &pos); + void updateStyleLabel(); + +private: + MarkdownEditor* m_editor; + + QLabel *m_lineColLabel; + QLabel *m_wordCountLabel; + + QLabel *m_styleLabel; + + QActionGroup *m_styleActions; + + ActiveLabel *m_htmlLabel; +}; + +#endif // STATUSBARWIDGET_H diff --git a/app/syntax_hu_HU.html b/app/syntax_hu_HU.html new file mode 100644 index 00000000..83623238 --- /dev/null +++ b/app/syntax_hu_HU.html @@ -0,0 +1,236 @@ + + + + +Markdown szintaxis + + + +

CÍMSOROK

+ + + + + + + + + + + + + + + + +
Markdown bemenetKimenet
+
# Címsor 1
+
+## Címsor 2
+
+### Címsor 3
+
+#### Címsor 4
+
+##### Címsor 5
+
+###### Címsor 6
+
+

Címsor 1

+

Címsor 2

+

Címsor 3

+

Címsor 4

+
Címsor 5
+
Címsor 6
+
+
Címsor 1
+===========
+
+Címsor 2
+-----------
+
+

Címsor 1

+

Címsor 2

+
+

BEKEZDÉSEK

+ + + + + + + + + + + + + + + + +
Markdown bemenetKimenet
+
Egy bekezdés egyszerűen egy
+ vagy több egymás utáni sor
+ szöveg, egy vagy több üres
+ vonallal elválasztva.
+
+Ez egy másik bekezdés.
+
+

Egy bekezdés egyszerűen egy vagy több egymás utáni sor szöveg, egy vagy több üres vonallal elválasztva.

+

Ez egy másik bekezdés.

+
+
Hogy sortörést
+hozz létre, fejez be
+a sort kettő vagy több
+szóközzel.
+
+

Hogy sortörést
hozz létre, fejez be
a sort kettő vagy több
szóközzel.

+
+

LISTÁK

+ + + + + + + + + + + + + + + + + + + + + + + + +
Markdown bemenetKimenet
+
* Elem 1
+* Elem 2
+* Elem 3
+
++ Elem 1
++ Elem 2
++ Elem 3
+
+- Elem 1
+- Elem 2
+- Elem 3
+
+
    +
  • Elem 1
  • +
  • Elem 2
  • +
  • Elem 3
  • +
+
    +
  • Elem 1
  • +
  • Elem 2
  • +
  • Elem 3
  • +
+
    +
  • Elem 1
  • +
  • Elem 2
  • +
  • Elem 3
  • +
+
+
1. Elem 1
+2. Elem 2
+3. Elem 3 
+
+
    +
  1. Elem 1
  2. +
  3. Elem 2
  4. +
  5. Elem 3
  6. +
+
+
* Elem 1
+1. Elem 2
++ Elem 3
+2. Elem 4
+
+
    +
  • Elem 1
      +
    1. Elem 2
        +
      • Elem 3
      • +
      +
    2. +
    3. Elem 4
    4. +
    +
  • +
+
+
Kifejezés
+: Definíció
+
+
+
Kifejezés
+
+ +
Definíció
+
+
+

KIEMELÉS

+ + + + + + + + + + + + + + + + +
Markdown bemenetKimenet
+
*Kiemelt* vagyok
+
+__Kiemelt_ vagyok
+
+

Kiemelt vagyok

+ +

Kiemelt vagyok

+
+
**Félkövér** vagyok
+
+__Félkövér__ vagyok
+
+

Félkövér vagyok

+ +

Félkövér vagyok

+
+ + diff --git a/app/translations.qrc b/app/translations.qrc index 752092d6..457c283f 100644 --- a/app/translations.qrc +++ b/app/translations.qrc @@ -1,15 +1,17 @@ - translations/cutemarked_de.qm translations/cutemarked_cs.qm + translations/cutemarked_da.qm + translations/cutemarked_de.qm translations/cutemarked_el.qm - translations/cutemarked_zh_CN.qm + translations/cutemarked_es.qm translations/cutemarked_fr.qm + translations/cutemarked_hu_HU.qm + translations/cutemarked_id.qm translations/cutemarked_ja.qm - translations/cutemarked_es.qm + translations/cutemarked_pl.qm translations/cutemarked_pt_BR.qm translations/cutemarked_ru.qm - translations/cutemarked_id.qm - translations/cutemarked_da.qm + translations/cutemarked_zh_CN.qm diff --git a/app/translations/cutemarked_da.ts b/app/translations/cutemarked_da.ts index 95b3d111..3d549a3d 100644 --- a/app/translations/cutemarked_da.ts +++ b/app/translations/cutemarked_da.ts @@ -9,23 +9,82 @@ &About - Tab with information about the application &Om A&uthors - Tab with information about the authors of the application &Forfattere - + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Christian Loose (cloose)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Creator and maintainer</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Jörg Preiß (Slesa)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Andreas Reischuck (arBmind)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Aetf (Aetf)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Pavel Fric (Fri)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Czech translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Hu Junqing (LearnShare)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Chinese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Γιάννης Ανθυμίδης (Evropi)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Greek translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Etienne Gauvin (Etn)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">French translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Rémi Verschelde (akien-mga)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">French translation and Mageia package</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Kota Ouchi (kOtaOuchi)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Norihide Sugohara (touyou)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Eai</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Javier (moguman)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Spanish translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Cassio Cardoso (cassiocardoso)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Portuguese (Brazil) translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Victor Nogueira (felladrin)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Portuguese (Brazil) translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Maxim Efremov (maxbart)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Russian translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Bedouin</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Indonesian translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Mljjlm</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Danish translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html> + + + + &Thanks To - Tab with information about 3rd party libraries &Tak Til - + Qt-based, free and open source markdown editor with live HTML preview Qt-baseret, gratis og open source markdown editor med HTML forhåndsvisning @@ -194,22 +253,22 @@ ... - + Case Sensitive Forskel på små og store bogstaver - + Whole Words Only Kun hele ord - + Use Regular Expressions Brug Regulære Udtryk - + Find Options Søgeindstillinger @@ -269,7 +328,7 @@ MainWindow - + about:blank about:blank @@ -285,14 +344,14 @@ - Format - Formater + F&ormat + Verb "to format". sub menu title to choose a formatting like bold, italic. + - - Find/Replace - Søg/Erstat + &Find/Replace + @@ -311,477 +370,494 @@ - Styles - Typografier + St&yles + - Markdown Extensions - Markdown Udvidelser + Markdown E&xtensions + - Languages - Sprog + &Languages + - + Table of contents Indholdsfortegnelse - - + Markdown Syntax Markdown Syntaks - - + + qrc:/syntax.html qrc:/syntax_da.html - + File Explorer Stifinder - + E&xit &Afslut - + &New &Ny - + &Open... Å&bn... - + &Save &Gem - + Save &As... Gem &som... - + &Undo Fo&rtryd - + &Redo &Gentag - + Default Standard - + Ctrl+1 Ctrl+1 - + Github Github - + Ctrl+2 Ctrl+2 - + Solarized Light Solarized Light - + Ctrl+3 Ctrl+3 - + Solarized Dark Solarized Dark - + Ctrl+4 Ctrl+4 - + &About CuteMarkEd... &Om CuteMarkEd... - - Export to HTML... - Eksportér til HTML... + + Export to &HTML... + - - Export to PDF... - Eksportér til PDF... + + &Export to PDF... + - + Split 1:1 Opdel 1:1 - + Split 2:1 Opdel 2:1 - + Split 1:2 Opdel 1:2 - + Split 3:1 Opdel 3:1 - + Split 1:3 Opdel 1:3 - - Copy HTML to Clipboard - Kopiér HTML til Udklipsholder + + Copy &HTML to Clipboard + - + Cu&t &Klip - + &Copy K&opiér - + &Paste Sæt i&nd - + Strong Fed - + Emphasize Kursiv - + &Print... &Udskriv... - - + + Strikethrough Gennemstreget - + Inline Code Indlejret Kode - - Math Support - Understøttelse for Matematik + + &Math Support + - - Code Highlighting - Fremhævning af kode + + Code &Highlighting + - + Clearness Clearness - + Ctrl+5 Ctrl+5 - + Clearness Dark Clearness Dark - + Ctrl+6 Ctrl+6 - - Go to Line - Gå til linje + + Find/Replace + Søg/Erstat - + + Go to &Line + + + + Ctrl+L Ctrl+L - + Center Paragraph Centrér afsnit - + Hard Linebreak Linjeskift - + Ctrl+Return Ctrl+Enter - + Find Next Find næste - + Find Previous Find forrige - - Full Screen Mode - Fuldskærmstilstand + + &Full Screen Mode + - + Blockquote Citat - + Ctrl+Shift+Q Ctrl+Shift+Q - - - - - HTML preview - HTML forhåndsvisning + + &Markdown Syntax + - + + HTML &Preview + + + + F5 F5 - - Show Special Characters + + &Show Special Characters Option to show characters like line feed or tabs - Vis specielle tegn + - - Options... - Indstillinger... + + &Options... + - + Autolink Autolink - + Alphabetic Lists Alfabetisk ordnede lister - + Definition Lists Definitionslister - + SmartyPants SmartyPants - + Language Sprog - - Check Spelling - Kontrollér stavning + + &Check Spelling + - + Increase Header Level Forøg Overskriftsniveau - + Alt+Right Alt+Højre piletast - + Decrease Header Level Formindsk Overskriftsniveau - + Alt+Left Alt+Venstre piletast - + Insert Table... Indsæt Tabel... - + Ctrl+T Ctrl+T - + Byword Dark Byword Dark - + Ctrl+7 Ctrl+7 - - Insert Image... - Indsæt Billede... + + Insert &Image... + - + Ctrl+Shift+I Ctrl+Shift+I - - Horizontal Layout - Vandret Layout + + &Horizontal Layout + - + Footnotes Fodnoter - + Superscript Hævet skrift - - Word Wrap - Tekstombrydning + + &Word Wrap + - - :/markdown-snippets.json - path to built-in snippets resource. - :/markdown-snippets.json + + Ignore Y&AML Header + - + + &Diagram Support + + + + Open File... Åbn Fil... - - - Markdown Files (*.markdown *.md);;All Files (*) - Markdown Filer (*.markdown *.md);;Alle Filer (*) + + + Markdown Files (*.markdown *.md *.mdown);;All Files (*) + - + Save as... Gem som... - + Print Document Udskriv dokument - + Go to... Gå til... - + Line: Line number in the Markdown editor Linje: - - + + + + HTML preview + HTML forhåndsvisning + + + + HTML source HTML kildekode - + %1 words %1 ord - + Lines: %1 Words: %2 Characters: %3 Linjer: %1 Ord: %2 Tegn: %3 - + Change Preview Style Skift forhåndsvisningstypografi - + Save Changes Gem ændringer - + The document has been modified.<br>Do you want to save your changes? Dokumentet er blevet ændret.<br>Vil du gemme dine ændringer? - + untitled.md default file name for new markdown documents unavngivet.md @@ -790,18 +866,17 @@ MarkdownEditor - - Ctrl+Space - Complete - Ctrl+Mellemrum + + Snippet Complete + - + Suggestions Forslag - + Add to User Dictionary Tilføj til brugerordbog @@ -815,8 +890,8 @@ - General - Generelt + &General + @@ -825,127 +900,193 @@ - Converter Library: - Converterbibliotek: + Converter &Library: + - + Discount (Default) Name of a Markdown to HTML converter library Discount (Standard) - + Hoedown Name of a Markdown to HTML converter library Hoedown - + Reveal.js (Presentation) Reveal.js (Præsentation) - - Editor - Editor + + &Editor + - + Font Skrifttype - - Family: - Familie: + + &Family: + - - Size: - Størrelse: + + Si&ze: + - + Tabs Tabs - - Tab width: - Tab bredde: + + &Tab width: + + + + + &HTML Preview + + + + + Fonts + + + + + S&tandard Font: + + + + + + Size: + Størrelse: + + + + Se&rif Font: + + + + + S&ans Serif Font: + + + + + &Fixed Font: + - - Internet - Internet + + &Internet + - + Configure Proxy to Access the Internet Konfigurér Proxy for Tilgang til Internettet - - No proxy - Ingen proxy + + No prox&y + + + + + &Use system proxy settings + + + + + &Manual proxy configuration: + + + + + H&ost: + - - Use system proxy settings - Brug systemindstillinger for proxy + + &Port: + - - Manual proxy configuration: - Manuel proxy konfiguration: + + User &Name: + - - Host: - Host: + + Pass&word: + - - Port: - Port: + + &Snippets + - - User Name: - Brugernavn: + + &Add + - - Password: - Password: + + &Remove + - - Snippets - Tilføjelser + + Short&cuts + - - Add - Tilføj + + Action + - - Remove - Fjern + + Shortcut + - + + Default + + + + Error Title of error message box Fejl - + No snippet selected. Ingen tilføjelse valgt. + + + Conflict + + + + + This shortcut is already used for "%1" + + RecentFilesMenu @@ -963,23 +1104,23 @@ SnippetsTableModel - + Error Title of error message box Fejl - + Not a valid trigger. Den valgte udløser er ikke gyldig - + Trigger Udløser - + Description Beskrivelse diff --git a/app/translations/cutemarked_hu_HU.ts b/app/translations/cutemarked_hu_HU.ts new file mode 100644 index 00000000..3d5b23ca --- /dev/null +++ b/app/translations/cutemarked_hu_HU.ts @@ -0,0 +1,1241 @@ + + + AboutDialog + + + About CuteMarkEd + CuteMarkEd névjegye + + + + &About + &Névjegy + + + + A&uthors + &Közreműködők + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Christian Loose (cloose)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Creator and maintainer</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Jörg Preiß (Slesa)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Andreas Reischuck (arBmind)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Aetf (Aetf)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Pavel Fric (Fri)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Czech translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Hu Junqing (LearnShare)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Chinese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Γιάννης Ανθυμίδης (Evropi)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Greek translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Etienne Gauvin (Etn)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">French translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Rémi Verschelde (akien-mga)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">French translation and Mageia package</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Kota Ouchi (kOtaOuchi)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Norihide Sugohara (touyou)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Eai</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Javier (moguman)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Spanish translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Cassio Cardoso (cassiocardoso)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Portuguese (Brazil) translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Victor Nogueira (felladrin)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Portuguese (Brazil) translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Maxim Efremov (maxbart)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Russian translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Bedouin</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Indonesian translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Mljjlm</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Danish translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Christian Loose (cloose)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Creator and maintainer</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Jörg Preiß (Slesa)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Andreas Reischuck (arBmind)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Aetf (Aetf)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Pavel Fric (Fri)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Czech translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Hu Junqing (LearnShare)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Chinese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Γιάννης Ανθυμίδης (Evropi)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Greek translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Etienne Gauvin (Etn)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">French translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Rémi Verschelde (akien-mga)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">French translation and Mageia package</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Kota Ouchi (kOtaOuchi)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Norihide Sugohara (touyou)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Eai</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Javier (moguman)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Spanish translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Cassio Cardoso (cassiocardoso)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Portuguese (Brazil) translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Victor Nogueira (felladrin)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Portuguese (Brazil) translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Maxim Efremov (maxbart)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Russian translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Bedouin</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Indonesian translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Mljjlm</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Danish translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html> + + + + &Thanks To + Kö&szönet + + + + Qt-based, free and open source markdown editor with live HTML preview + Qt alapú, ingyenes és nyílt forráskódú markdown szerkesztő, élő HTML előnézettel + + + + ExportHtmlDialog + + + Export to HTML + Exportálás HTML-be + + + + Export to: + Exportálás: + + + + ... + ... + + + + <html><head/><body><p>embed the current CSS style into the exported HTML</p></body></html> + <html><head/><body><p>jelenlegi CSS beágyazása az exportált HTML-be</p></body></html> + + + + Include CSS style + CSS stílusok beágyazása + + + + Include Code Highlighting Javascript + Szintaxis kiemelő szkript beágyazása + + + + Export to HTML... + Exportálás HTML formátumba... + + + + HTML Files (*.html *.htm);;All Files (*) + HTML fájlok (*html *.htm);;Minden fájl (*) + + + + ExportPdfDialog + + + Export to PDF + Exportálás PDF formátumba + + + + Export to: + Exportálás: + + + + ... + ... + + + + Paper Size: + Papír mérete: + + + + Orientation: + Tájolás: + + + + Portrait + Állítva + + + + Landscape + Fektetve + + + + A4 (210 x 297 mm, 8.26 x 11.69 inches) + A4 (210 x 297 mm, 8.26 x 11.69 col) + + + + Letter (8.5 x 11 inches, 215.9 x 279.4 mm) + Letter (8.5 x 11 col, 215.9 x 279.4 mm) + + + + Legal (8.5 x 14 inches, 215.9 x 355.6 mm) + Legal (8.5 x 14 col, 215.9 x 355.6 mm) + + + + A3 (297 x 420 mm) + A3 (297 x 420 mm) + + + + A5 (148 x 210 mm) + A5 (148 x 210 mm) + + + + A6 (105 x 148 mm) + A6 (105 x 148 mm) + + + + B4 (250 x 353 mm) + B4 (250 x 353 mm) + + + + B5 (176 x 250 mm, 6.93 x 9.84 inches) + B5 (176 x 250 mm, 6.93 x 9.84 col) + + + + Export to PDF... + Exportálás PDF formátumba... + + + + PDF Files (*.pdf);;All Files (*) + PDF fájlok(*.pdf);;Minden fájl (*) + + + + FindReplaceWidget + + + Find + Keresés + + + + Find: + Keresés: + + + + Replace with: + Csere erre: + + + + Replace + Csere + + + + Replace All + Összes cseréje + + + + ... + ... + + + + Case Sensitive + Kisbetű-nagybetű érzékenység + + + + Whole Words Only + Csak egész szóra + + + + Use Regular Expressions + Reguláris kifejezés használata + + + + Find Options + Kereső beállítása + + + + ImageToolDialog + + + Insert Image + Kép beillesztése + + + + Image Link: + Kép link: + + + + http://example.com/image.jpg + http://példa.hu/kép.jpg + + + + ... + ... + + + + Alternate Text: + Alternatív szöveg: + + + + Optional Title: + Opcionális cím: + + + + Open File + Fájl megnyitása + + + + Images (*.bmp *.gif *.jpg *.jpe *.jpeg *.png *.tif *.tiff *.xpm);;All Files (*) + Képek (*.bmp *.gif *.jpg *.jpe *.jpeg *.png *.tif *.tiff *.xpm);;Minden fájl (*) + + + + LanguageMenu + + + Languages + Nyelvek + + + + MainWindow + + + + about:blank + about:blank + + + + &File + &Fájl + + + + &Edit + S&zerkesztés + + + + F&ormat + Verb "to format". sub menu title to choose a formatting like bold, italic. + F&ormátum + + + + &Find/Replace + Ke&resés és csere + + + + &Help + &Súgó + + + + &View + &Nézet + + + + E&xtras + E&xtrák + + + + St&yles + Stí&lusok + + + + Markdown E&xtensions + Markdown ki&terjesztések + + + + &Languages + &Nyelvek + + + + Table of contents + Tartalomjegyzék + + + + Markdown Syntax + Markdown szintaxis + + + + + qrc:/syntax.html + qrc:/syntax_hu.html + + + + File Explorer + Fájl kezelő + + + + E&xit + &Bezárás + + + + &New + Ú&j + + + + &Open... + &Megnyitás + + + + &Save + M&entés + + + + Save &As... + Me&ntés másként + + + + &Undo + &Visszavonás + + + + &Redo + &Ismét + + + + Default + Alapértelmezett + + + + Ctrl+1 + Ctrl+1 + + + + Github + Github + + + + Ctrl+2 + Ctrl+2 + + + + Solarized Light + Solarized Light + + + + Ctrl+3 + Ctrl+3 + + + + Solarized Dark + Solarized Dark + + + + Ctrl+4 + Ctrl+4 + + + + &About CuteMarkEd... + &A CuteMarkEd-ről + + + + Export to &HTML... + Exportálás &HTML-be + + + + &Export to PDF... + Exportálás &PDF-be + + + + Split 1:1 + Felosztás: 1:1 + + + + Split 2:1 + Felosztás: 2:1 + + + + Split 1:2 + Felosztás: 1:2 + + + + Split 3:1 + Felosztás: 3:1 + + + + Split 1:3 + Felosztás: 1:3 + + + + Copy &HTML to Clipboard + &HTML másolása vágólapra + + + + Cu&t + &Kivágás + + + + &Copy + &Másolás + + + + &Paste + &Beillesztés + + + + Strong + Félkövér + + + + Emphasize + Dőlt + + + + &Print... + &Nyomtatás + + + + + Strikethrough + Áthúzás + + + + Inline Code + Beágyazott kód + + + + &Math Support + &Matematikai formulák támogatása + + + + Code &Highlighting + Szintaxis &kiemelés + + + + Clearness + Clearness + + + + Ctrl+5 + Ctrl+5 + + + + Clearness Dark + Clearness Dark + + + + Ctrl+6 + Ctrl+6 + + + + Find/Replace + Keresés/Csere + + + + Go to &Line + &Ugrás sorra + + + + Ctrl+L + Ctrl+L + + + + Center Paragraph + Középre igazítás + + + + Hard Linebreak + Kemény sortörés + + + + Ctrl+Return + Ctrl+Enter + + + + Find Next + Következő + + + + Find Previous + Előző + + + + &Full Screen Mode + &Teljes képernyő + + + + Blockquote + Idézet + + + + Ctrl+Shift+Q + Ctrl+Shift+Q + + + + &Markdown Syntax + &Markdown szintaxis + + + + HTML &Preview + HTML &előnézet + + + + F5 + F5 + + + + &Show Special Characters + Option to show characters like line feed or tabs + &Speciális karakterek megjelenítése + + + + &Options... + &Opciók... + + + + Autolink + Automata linkké alakítás + + + + Alphabetic Lists + Betűrendes lista + + + + Definition Lists + Definíciós lista + + + + SmartyPants + SmartyPants + + + + Language + Nyelv + + + + &Check Spelling + Nyelvtani &ellenőrzés + + + + Increase Header Level + Címsor szint növelése + + + + Alt+Right + Alt+Jobbra + + + + Decrease Header Level + Címsor szint csökkentése + + + + Alt+Left + Alt+Balra + + + + Insert Table... + Táblázat beillesztése + + + + Ctrl+T + Ctrl+T + + + + Byword Dark + Byword Dark + + + + Ctrl+7 + Ctrl+7 + + + + Insert &Image... + Kép be&szúrása + + + + Ctrl+Shift+I + Ctrl+Shift+I + + + + &Horizontal Layout + &Fekvő elrendezés + + + + Footnotes + Lábjegyzet + + + + Superscript + Felső index + + + + &Word Wrap + &Hosszú sorok törése + + + + Ignore Y&AML Header + Y&AML fejléc figyelmen kívül hagyása + + + + &Diagram Support + Diagram támogatás + + + + Open File... + Fájl megnyitása + + + + + Markdown Files (*.markdown *.md *.mdown);;All Files (*) + Markdown fájlok (*.markdown *md *.mdown);;Minden fájl (*) + + + + Save as... + Mentés másként + + + + Print Document + Nyomtatás + + + + Go to... + Menj... + + + + Line: + Line number in the Markdown editor + Sor: + + + + + + HTML preview + HTML előnézet + + + + + HTML source + HTML forráskód + + + + %1 words + %1 szó + + + + Lines: %1 Words: %2 Characters: %3 + Sor:%1 Szó: %2 Karakter: %3 + + + + Change Preview Style + Előnézet stílusának módosítása + + + + Save Changes + Módosítások mentése + + + + The document has been modified.<br>Do you want to save your changes? + A dokumentum módosítva lett.<br>Mented a módosításokat? + + + + untitled.md + default file name for new markdown documents + névtelen.md + + + + MarkdownEditor + + + Snippet Complete + Kódrészlet befejezve + + + + Suggestions + Ajánlás + + + + Add to User Dictionary + Hozzáadás a felhasználói szótárhoz + + + + OptionsDialog + + + Options... + Beállítások... + + + + &General + &Általános + + + + Markdown Converter + Markdown konvertáló + + + + Converter &Library: + Konvertáló &program + + + + Discount (Default) + Name of a Markdown to HTML converter library + Discount (Alapértelmezett) + + + + Hoedown + Name of a Markdown to HTML converter library + Hoedown + + + + Reveal.js (Presentation) + Reveal.js (Prezentáció) + + + + &Editor + &Szerkesztő + + + + Font + Betűtípus + + + + &Family: + &Család: + + + + Si&ze: + &Méret: + + + + Tabs + Tabulátor + + + + &Tab width: + &Tabulátor szélessége + + + + &HTML Preview + &HTML előnézet + + + + Fonts + Betűtípus + + + + S&tandard Font: + &Hagyományos: + + + + + Size: + Méret: + + + + Se&rif Font: + Se&rif + + + + S&ans Serif Font: + S&ans Serif + + + + &Fixed Font: + &Rögzített szélességű + + + + &Internet + &Internet + + + + Configure Proxy to Access the Internet + Proxy konfigurálása + + + + No prox&y + Nincs prox&y + + + + &Use system proxy settings + &Rendszer proxy beállításainak használata + + + + &Manual proxy configuration: + &Kézi konfigurálás: + + + + H&ost: + H&oszt: + + + + &Port: + &Port: + + + + User &Name: + Felhasználó &név + + + + Pass&word: + &Jelszó: + + + + &Snippets + &Kódrészletek + + + + &Add + Hozzá&adás + + + + &Remove + El&távolítás + + + + Short&cuts + &Billentyűparancsok + + + + Action + Esemény + + + + Shortcut + Billentyűparancs + + + + Default + Alapértelmezett + + + + Error + Title of error message box + Hiba + + + + No snippet selected. + Nincs kódrészlet kiválasztva + + + + Conflict + Ütközés + + + + This shortcut is already used for "%1" + A billentyűparancs már használatban: "%1" + + + + RecentFilesMenu + + + Recent &Files + Le&gutóbbi fájlok + + + + Clear Menu + Menü törlése + + + + SnippetsTableModel + + + Error + Title of error message box + Hiba + + + + Not a valid trigger. + Nem érvényes trigger + + + + Trigger + Trigger + + + + Description + Leírás + + + + TableToolDialog + + + Insert Table + Táblázat beillesztése + + + + Rows: + Sor: + + + + Columns: + Oszlop: + + + + Table: + Táblázat: + + + + Headers + Címsorok + + + + Alignment + Igazítás + + + + Left + Balra + + + + Center + Középre + + + + Right + Jobbra + + + + main + + + The file to open. + A fájl megnyitásához. + + + \ No newline at end of file diff --git a/app/translations/cutemarked_pt_BR.ts b/app/translations/cutemarked_pt_BR.ts index d5b2bb2c..f5b3081b 100644 --- a/app/translations/cutemarked_pt_BR.ts +++ b/app/translations/cutemarked_pt_BR.ts @@ -1,4 +1,94 @@ + + AboutDialog + + + About CuteMarkEd + Sobre o CuteMarkEd + + + + &About + &Sobre + + + + A&uthors + A&utores + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Christian Loose (cloose)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Creator and maintainer</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Jörg Preiß (Slesa)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Andreas Reischuck (arBmind)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Aetf (Aetf)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Pavel Fric (Fri)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Czech translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Hu Junqing (LearnShare)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Chinese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Γιάννης Ανθυμίδης (Evropi)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Greek translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Etienne Gauvin (Etn)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">French translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Rémi Verschelde (akien-mga)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">French translation and Mageia package</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Kota Ouchi (kOtaOuchi)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Norihide Sugohara (touyou)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Eai</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Javier (moguman)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Spanish translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Cassio Cardoso (cassiocardoso)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Portuguese (Brazil) translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Victor Nogueira (felladrin)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Portuguese (Brazil) translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Maxim Efremov (maxbart)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Russian translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Bedouin</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Indonesian translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Mljjlm</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Danish translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html> + + + + + &Thanks To + &Agradecimentos + + + + Qt-based, free and open source markdown editor with live HTML preview + Editor de Markdown com pré-visualização em tempo-real, feito em Qt, gratuito e open source + + ExportHtmlDialog @@ -138,46 +228,50 @@ Procurar - + Find: Procurar: - - - ... - ... - - - + Replace with: Substituir por: - + Replace Substituir - + Replace All Substituir Todos - + + ... + ... + + + Case Sensitive Case Sensitive - + Whole Words Only Só Palavras Inteiras - + Use Regular Expressions Usar Expressões Regulares + + + Find Options + Encontrar Opções + ImageToolDialog @@ -234,7 +328,7 @@ MainWindow - + about:blank about:blank @@ -250,14 +344,14 @@ - Format - Formato + F&ormat + Verb "to format". sub menu title to choose a formatting like bold, italic. + - - Find/Replace - Procurar/Substituir + &Find/Replace + @@ -276,482 +370,494 @@ - Styles - Estilos + St&yles + - Markdown Extensions - Extensões Markdown + Markdown E&xtensions + - Languages - Linguagens + &Languages + - + Table of contents Tabela de conteúdo - - + Markdown Syntax Síntaxe Markdown - - + + qrc:/syntax.html qrc:/syntax_pt_BR.html - + + File Explorer + Gerenciador de Arquivos + + + E&xit S&air - + &New &Novo - + &Open... &Abrir... - + &Save &Salvar - + Save &As... Salvar &Como... - + &Undo &Desfazer - + &Redo &Refazer - + Default Padrão - + Ctrl+1 Ctrl+1 - + Github Github - + Ctrl+2 Ctrl+2 - + Solarized Light Solarized Light - + Ctrl+3 Ctrl+3 - + Solarized Dark Solarized Dark - + Ctrl+4 Ctrl+4 - + &About CuteMarkEd... &Sobre CuteMarkEd... - - Export to HTML... - Exportar para HTML... + + Export to &HTML... + - - Export to PDF... - Exportar para PDF... + + &Export to PDF... + - + Split 1:1 Dividir 1:1 - + Split 2:1 Dividir 2:1 - + Split 1:2 Dividir 1:2 - + Split 3:1 Dividir 3:1 - + Split 1:3 Dividir 1:3 - - Copy HTML to Clipboard - Copiar HTML para Área de Transferência + + Copy &HTML to Clipboard + - + Cu&t Cor&tar - + &Copy &Copiar - + &Paste &Colar - + Strong Negrito - + Emphasize Enfatizar - + &Print... &Imprimir... - - + + Strikethrough Rasura - + Inline Code Código Inline - - Math Support - Suporte a Matemática + + &Math Support + - - Code Highlighting - Destaque de Código + + Code &Highlighting + - + Clearness Clearness - + Ctrl+5 Ctrl+5 - + Clearness Dark Clearness Dark - + Ctrl+6 Ctrl+6 - - Go to Line - Ir para a Linha + + Find/Replace + Procurar/Substituir - + + Go to &Line + + + + Ctrl+L Ctrl+L - + Center Paragraph Centralizar Parágrafo - + Hard Linebreak Quebra de Linha - + Ctrl+Return Ctrl+Return - + Find Next Encontrar o Próximo - + Find Previous Encontrar o Anterior - - Full Screen Mode - Modo Tela Cheia + + &Full Screen Mode + - + Blockquote Citação - - Ctrl+Q - Ctrl+Q + + Ctrl+Shift+Q + Ctrl+Shift+Q - - - - - HTML preview - Prever HTML + + &Markdown Syntax + - + + HTML &Preview + + + + F5 F5 - - Show Special Characters + + &Show Special Characters Option to show characters like line feed or tabs - Mostrar Caracteres Especiais + - - Options... - Opções... + + &Options... + - + Autolink Autolink - + Alphabetic Lists Listas Alfabéticas - + Definition Lists Listas de Definição - + SmartyPants SmartyPants - + Language Linguagens - - Check Spelling - Checar a Ortografia + + &Check Spelling + - + Increase Header Level Aumentar Nível do Título - + Alt+Right Alt+Right - + Decrease Header Level Diminuir Nível do Título - + Alt+Left Alt+Left - + Insert Table... Inserir Tabela... - + Ctrl+T Ctrl+T - + Byword Dark Byword Dark - + Ctrl+7 Ctrl+7 - - Insert Image... - Inserir Imagem... + + Insert &Image... + - - Ctrl+G - Ctrl+G + + Ctrl+Shift+I + Ctrl+Shift+I - - Horizontal Layout - Layout Horizontal + + &Horizontal Layout + - + Footnotes Notas de Rodapé - + Superscript Superscript - - Word Wrap - Quebra de Linha + + &Word Wrap + + + + + Ignore Y&AML Header + - - :/markdown-snippets.json - path to built-in snippets resource. - :/markdown-snippets.json + + &Diagram Support + - + Open File... Abrir Arquivo... - - - Markdown Files (*.markdown *.md);;All Files (*) - Arquivos Markdown (*.markdown *.md);;Todos os Arquivos (*) + + + Markdown Files (*.markdown *.md *.mdown);;All Files (*) + - + Save as... Salvar como... - + Print Document Imprimir Documento - + Go to... Ir para... - + Line: Line number in the Markdown editor Linha: - - About CuteMarkEd - Sobre CuteMarkEd - - - - <p><b>CuteMarkEd %1</b><br>Qt-based, free and open source markdown editor with live HTML preview<br>Copyright 2013 Christian Loose</p><p><a href="http://cloose.github.io/CuteMarkEd">http://cloose.github.io/CuteMarkEd</a></p> - <p><b>CuteMarkEd %1</b><br>Editor de Markdown com pré-visualizador de HTML, baseado em Qt, grátis e de código aberto.<br>Copyright 2013 Christian Loose</p><p><a href="http://cloose.github.io/CuteMarkEd">http://cloose.github.io/CuteMarkEd</a></p> + + + + HTML preview + Prever HTML - - + + HTML source Código HTML - + %1 words %1 palavras - + Lines: %1 Words: %2 Characters: %3 Linhas: %1 Palavras: %2 Caracteres: %3 - + Change Preview Style Mudar Estilo do Pré-Visualizador - + Save Changes Salvar Alterações - + The document has been modified.<br>Do you want to save your changes? Este documento foi modificado.<br>Você gostaria de salvar suas modificações? - + untitled.md default file name for new markdown documents untitled.md @@ -760,18 +866,17 @@ MarkdownEditor - - Ctrl+Space - Complete - Ctrl+Espaço + + Snippet Complete + - + Suggestions Sugestões - + Add to User Dictionary Adicionar Usuário ao Dicinário @@ -785,8 +890,8 @@ - General - Geral + &General + @@ -795,122 +900,193 @@ - Converter Library: - Biblioteca de Conversores: + Converter &Library: + - + Discount (Default) Name of a Markdown to HTML converter library Desconto (Padrão) - + Hoedown Name of a Markdown to HTML converter library Hoedown - - Editor - Editor + + Reveal.js (Presentation) + Reveal.js (Apresentação) + + + + &Editor + - + Font Fonte - - Family: - Família: + + &Family: + - - Size: - Tamanho: + + Si&ze: + - + Tabs Abas - - Tab width: - Largura da aba: + + &Tab width: + + + + + &HTML Preview + + + + + Fonts + + + + + S&tandard Font: + + + + + + Size: + Tamanho: + + + + Se&rif Font: + + + + + S&ans Serif Font: + - - Internet - Internet + + &Fixed Font: + - + + &Internet + + + + Configure Proxy to Access the Internet Configurar Proxy para Acessar a Internet - - No proxy - Sem proxy + + No prox&y + - - Use system proxy settings - Usar configurações de proxy do sistema + + &Use system proxy settings + - - Manual proxy configuration: - Configuração de proxy manual: + + &Manual proxy configuration: + - - Host: - Servidor: + + H&ost: + - - Port: - Porta: + + &Port: + - - User Name: - Nome de Usuário: + + User &Name: + - - Password: - Senha: + + Pass&word: + - - Snippets - Snippets + + &Snippets + - - Add - Adicionar + + &Add + - - Remove - Remover + + &Remove + - + + Short&cuts + + + + + Action + + + + + Shortcut + + + + + Default + + + + Error Title of error message box Erro - + No snippet selected. Nenhum snippet selecionado. + + + Conflict + + + + + This shortcut is already used for "%1" + + RecentFilesMenu @@ -928,23 +1104,23 @@ SnippetsTableModel - + Error Title of error message box Erro - + Not a valid trigger. Não é um trigger válido. - + Trigger Trigger - + Description Descrição @@ -997,4 +1173,12 @@ Direita + + main + + + The file to open. + O arquivo para abrir. + + \ No newline at end of file diff --git a/app/translations/cutemarked_ru.ts b/app/translations/cutemarked_ru.ts index 1c4e307d..e55cc45e 100644 --- a/app/translations/cutemarked_ru.ts +++ b/app/translations/cutemarked_ru.ts @@ -1,4 +1,151 @@ + + AboutDialog + + + About CuteMarkEd + О CuteMarkEd + + + + &About + &О программе + + + + A&uthors + &Авторы + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Christian Loose (cloose)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Creator and maintainer</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Jörg Preiß (Slesa)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Andreas Reischuck (arBmind)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Aetf (Aetf)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Pavel Fric (Fri)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Czech translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Hu Junqing (LearnShare)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Chinese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Γιάννης Ανθυμίδης (Evropi)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Greek translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Etienne Gauvin (Etn)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">French translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Rémi Verschelde (akien-mga)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">French translation and Mageia package</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Kota Ouchi (kOtaOuchi)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Norihide Sugohara (touyou)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Eai</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Javier (moguman)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Spanish translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Cassio Cardoso (cassiocardoso)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Portuguese (Brazil) translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Victor Nogueira (felladrin)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Portuguese (Brazil) translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Maxim Efremov (maxbart)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Russian translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Bedouin</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Indonesian translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Mljjlm</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Danish translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Christian Loose (cloose)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Creator and maintainer</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Jörg Preiß (Slesa)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Andreas Reischuck (arBmind)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Aetf (Aetf)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Code contributor</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Pavel Fric (Fri)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Czech translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Hu Junqing (LearnShare)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Chinese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Γιάννης Ανθυμίδης (Evropi)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Greek translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Etienne Gauvin (Etn)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">French translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Rémi Verschelde (akien-mga)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">French translation and Mageia package</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Kota Ouchi (kOtaOuchi)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Norihide Sugohara (touyou)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Eai</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Japanese translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Javier (moguman)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Spanish translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Cassio Cardoso (cassiocardoso)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Portuguese (Brazil) translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Victor Nogueira (felladrin)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Portuguese (Brazil) translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Maxim Efremov (maxbart)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Russian translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Bedouin</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Indonesian translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Mljjlm</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Danish translation</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html> + + + + &Thanks To + &Благодарности + + + + Qt-based, free and open source markdown editor with live HTML preview + Бесплатный редактор синтаксиса Markdown с предпросмотром в HTML, написанный на Qt и с открытым исходным кодом + + ExportHtmlDialog @@ -19,7 +166,7 @@ <html><head/><body><p>embed the current CSS style into the exported HTML</p></body></html> - <html><head/><body><p>вставить текущий стиль CSS в экспортируемый HTML</p></body></html> + <html><head/><body><p>встроить текущий стиль CSS в экспортируемый HTML</p></body></html> @@ -62,12 +209,12 @@ Paper Size: - Размер бумаги + Размер бумаги: Orientation: - Положение + Ориентация: @@ -87,12 +234,12 @@ Letter (8.5 x 11 inches, 215.9 x 279.4 mm) - Письмо (8.5 x 11 дюймов, 215.9 x 279.4 мм) + Letter (8.5 x 11 дюймов, 215.9 x 279.4 мм) Legal (8.5 x 14 inches, 215.9 x 355.6 mm) - Legal (8.5 x 14 дюймов, 215.9 x 355.6 мм) + Legal (8.5 x 14 дюймов, 215.9 x 355.6 mm) @@ -138,45 +285,49 @@ Найти - + Find: Найти: - - - ... - ... - - - + Replace with: Заменить на: - + Replace Заменить - + Replace All Заменить всё - + + ... + ... + + + Case Sensitive С учётом регистра - + Whole Words Only Только слова целиком - + Use Regular Expressions - Использование регулярных выражений + Использовать регулярные выражения + + + + Find Options + Найти опции @@ -204,12 +355,12 @@ Alternate Text: - Другой текст: + Альтернативный текст: Optional Title: - Дополнительное описание: + Дополнительный заголовок: @@ -234,7 +385,7 @@ MainWindow - + about:blank about:blank @@ -250,14 +401,14 @@ - Format - Формат + F&ormat + Verb "to format". sub menu title to choose a formatting like bold, italic. + &Формат - - Find/Replace - Найти/Заменить + &Find/Replace + &Найти/Заменить @@ -272,486 +423,498 @@ E&xtras - Дополнительно + &Дополнительно - Styles - Стили + St&yles + С&тили - Markdown Extensions + Markdown E&xtensions Расширения Markdown - Languages - Языки + &Languages + &Языки - + Table of contents Оглавление - - + Markdown Syntax - Синтаксис Markdown + Markdown синтаксис - - + + qrc:/syntax.html qrc:/syntax.html - + + File Explorer + Навигация по файлам + + + E&xit Вы&ход - + &New &Новый - + &Open... &Открыть... - + &Save &Сохранить - + Save &As... Сохранить &как... - + &Undo &Отменить - + &Redo &Повторить - + Default Стандартный - + Ctrl+1 Ctrl+1 - + Github Гитхаб - + Ctrl+2 Ctrl+2 - + Solarized Light Ясный Светлый - + Ctrl+3 Ctrl+3 - + Solarized Dark Ясный Тёмный - + Ctrl+4 Ctrl+4 - + &About CuteMarkEd... &О CuteMarkEd... - - Export to HTML... - Экспорт в HTML... + + Export to &HTML... + Экспо&рт в HTML... - - Export to PDF... - Экспорт в PDF... + + &Export to PDF... + Экспор&т в PDF... - + Split 1:1 Размер 1:1 - + Split 2:1 Размер 2:1 - + Split 1:2 Размер 1:2 - + Split 3:1 Размер 3:1 - + Split 1:3 Размер 1:3 - - Copy HTML to Clipboard - Копировать HTML в буфер + + Copy &HTML to Clipboard + Коп&ировать HTML код - + Cu&t Вырез&ать - + &Copy &Копировать - + &Paste &Вставить - + Strong - Изысканный + Жирный - + Emphasize - Подчеркнутый + Курсив - + &Print... &Печать - - + + Strikethrough Зачёркнутый - + Inline Code Инлайн код - - Math Support - Поддержка формул + + &Math Support + Поддержка &формул - - Code Highlighting - Подсветка кода + + Code &Highlighting + Подсветка &кода - + Clearness Ясный - + Ctrl+5 Ctrl+5 - + Clearness Dark Ясный Тёмный - + Ctrl+6 Ctrl+6 - - Go to Line + + Find/Replace + Найти/Заменить + + + + Go to &Line Перейти к строке - + Ctrl+L Ctrl+L - + Center Paragraph - Центр параграфа + Центрировать параграф - + Hard Linebreak - Жесткий разрыв линий + Жёсткий разрыв линий - + Ctrl+Return Ctrl+Enter - + Find Next Найти далее - + Find Previous Найти до - - Full Screen Mode + + &Full Screen Mode Полноэкранный режим - + Blockquote - Цитирование + Цитата - - Ctrl+Q - Ctrl+Q + + Ctrl+Shift+Q + Ctrl+Shift+Q - - - - - HTML preview - Предпросмотр HTML + + &Markdown Syntax + Markdown &синтаксис - + + HTML &Preview + &Предпросмотр HTML + + + F5 F5 - - Show Special Characters + + &Show Special Characters Option to show characters like line feed or tabs - Показать специальные символы + &Показывать специальные символы - - Options... - Опции... + + &Options... + &Опции... - + Autolink Автоссылка - + Alphabetic Lists По алфавиту - + Definition Lists По определению - + SmartyPants SmartyPants - + Language Язык - - Check Spelling - Проверка орфографии + + &Check Spelling + Проверка &орфографии - + Increase Header Level Увеличить уровень заголовка - + Alt+Right Alt+Вправо - + Decrease Header Level Понизить уровень заголовка - + Alt+Left Alt+Влево - + Insert Table... Вставить таблицу... - + Ctrl+T Ctrl+T - + Byword Dark Byword Dark - + Ctrl+7 Ctrl+7 - - Insert Image... - Вставить изображение... + + Insert &Image... + Вставить &изображение... - - Ctrl+G - Ctrl+G + + Ctrl+Shift+I + Ctrl+Shift+I - - Horizontal Layout - Горизонтальный слой + + &Horizontal Layout + &Горизонтальный вид - + Footnotes Примечания - + Superscript Верхний индекс - - Word Wrap - Перенос по словам + + &Word Wrap + Перенос по &словам - - :/markdown-snippets.json - path to built-in snippets resource. - :/markdown-snippets.json + + Ignore Y&AML Header + &Игнорировать YAML заголовок - + + &Diagram Support + Поддержка &диаграмм + + + Open File... Открыть файл... - - - Markdown Files (*.markdown *.md);;All Files (*) + + + Markdown Files (*.markdown *.md *.mdown);;All Files (*) Файлы Markdown (*.markdown *.md);;Все файлы (*) - + Save as... Сохранить как... - + Print Document Печать документа - + Go to... Перейти... - + Line: Line number in the Markdown editor Строка: - - About CuteMarkEd - О CuteMarkEd - - - - <p><b>CuteMarkEd %1</b><br>Qt-based, free and open source markdown editor with live HTML preview<br>Copyright 2013 Christian Loose</p><p><a href="http://cloose.github.io/CuteMarkEd">http://cloose.github.io/CuteMarkEd</a></p> - <p><b>CuteMarkEd %1</b><br>Бесплатный редактор с подсветкой исходного кода и с живым просмотром HTML, написанный на QT<br>Авторские права 2013 Christian Loose</p><p><a href="http://cloose.github.io/CuteMarkEd">http://cloose.github.io/CuteMarkEd</a></p> + + + + HTML preview + Предпросмотр HTML - - + + HTML source Исходный код HTML - + %1 words %1 слов - + Lines: %1 Words: %2 Characters: %3 Линий: %1 Слов: %2 Символов: %3 - + Change Preview Style Сменить стиль предпросмотра - + Save Changes Сохранить изменения - + The document has been modified.<br>Do you want to save your changes? Документ был изменён.<br>Вы хотите сохранить изменения? - + untitled.md default file name for new markdown documents untitled.md @@ -760,20 +923,19 @@ MarkdownEditor - - Ctrl+Space - Complete - Ctrl+Пробел + + Snippet Complete + Шаблон завершен - + Suggestions Предложения - + Add to User Dictionary - Добавить в словарь + Добавить в словарь пользователя @@ -785,131 +947,202 @@ - General - Основные + &General + &Основные Markdown Converter - Конвертер Markdown + Markdown конвертер - Converter Library: - Конвертер Библиотеки: + Converter &Library: + &Библиотека конвертера: - + Discount (Default) Name of a Markdown to HTML converter library - Скидка (по умолчанию) + Discount (по-умолчанию) - + Hoedown Name of a Markdown to HTML converter library Hoedown - - Editor - Редактор + + Reveal.js (Presentation) + Reveal.js (Презентация) - + + &Editor + &Редактор + + + Font Шрифт - - Family: + + &Family: Гарнитура: - - Size: - Размер + + Si&ze: + Размер: - + Tabs - Отступ + Отступы - - Tab width: - Ширина отступа: + + &Tab width: + &Ширина отступа: - - Internet - Интернет + + &HTML Preview + &Предпросмотр HTML - + + Fonts + Шрифт + + + + S&tandard Font: + &Стандартный: + + + + + Size: + Размер: + + + + Se&rif Font: + С &засечками: + + + + S&ans Serif Font: + &Без засечек: + + + + &Fixed Font: + &Фиксированный: + + + + &Internet + &Интернет + + + Configure Proxy to Access the Internet - Настроить Прокси для доступа к интернету + Настройки прокси для доступа к интернет - - No proxy - Без прокси + + No prox&y + &Без прокси - - Use system proxy settings - Использвать системные настройки прокси + + &Use system proxy settings + Испо&льзовать системные настройки прокси - - Manual proxy configuration: - Указать прокси вручную: + + &Manual proxy configuration: + &Указать прокси вручную: - - Host: - Хост: + + H&ost: + &Хост: - - Port: - Порт: + + &Port: + П&орт: - - User Name: - Имя пользователя: + + User &Name: + &Имя пользователя: - - Password: - Пароль: + + Pass&word: + &Пароль: - - Snippets - Сниппеты + + &Snippets + &Шаблоны - - Add - Добавить + + &Add + &Добавить - - Remove - Удалить + + &Remove + &Удалить - + + Short&cuts + Сочетания &клавиш + + + + Action + Действие + + + + Shortcut + Сочетание клавиш + + + + Default + По-умолчанию + + + Error Title of error message box Ошибка - + No snippet selected. - Не выбраны сниппеты + Шаблон не выбран + + + + Conflict + Конфликт + + + + This shortcut is already used for "%1" + Это сочетание клавиш уже используется для "%1" @@ -928,23 +1161,23 @@ SnippetsTableModel - + Error Title of error message box Ошибка - + Not a valid trigger. Недопустимый триггер. - + Trigger Триггер - + Description Описание @@ -959,12 +1192,12 @@ Rows: - Строк: + Строки: Columns: - Столбцов: + Столбцы: @@ -997,4 +1230,12 @@ Справа + + main + + + The file to open. + Файл для чтения. + + \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index f97d735b..8915dab1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,3 @@ -os: MinGW - branches: except: - gh-pages @@ -9,7 +7,7 @@ environment: MINGW_DIR: C:\Qt\Tools\mingw491_32 install: - - set PATH=%PATH%;%QTDIR%\bin;%MINGW_DIR%\bin + - set PATH=%QTDIR%\bin;%MINGW_DIR%\bin;%PATH% - git submodule update --init --recursive before_build: diff --git a/libs/peg-markdown-highlight/peg-markdown-highlight.pro b/libs/peg-markdown-highlight/peg-markdown-highlight.pro index 4a9814d0..32988e03 100644 --- a/libs/peg-markdown-highlight/peg-markdown-highlight.pro +++ b/libs/peg-markdown-highlight/peg-markdown-highlight.pro @@ -8,17 +8,17 @@ QT += core gui widgets TARGET = pmh-adapter TEMPLATE = lib -CONFIG += staticlib +CONFIG += staticlib CONFIG += c++11 SOURCES += \ pmhmarkdownparser.cpp \ - styleparser.cpp + styleparser.cpp HEADERS += \ pmhmarkdownparser.h \ styleparser.h \ - definitions.h + definitions.h ################################################################################################### ## DEPENDENCIES @@ -27,16 +27,5 @@ HEADERS += \ # # peg-markdown-highlight # -win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../3rdparty/peg-markdown-highlight/release/ -lpmh -else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../3rdparty/peg-markdown-highlight/debug/ -lpmh -else:unix: LIBS += -L$$OUT_PWD/../../3rdparty/peg-markdown-highlight/ -lpmh INCLUDEPATH += $$PWD/../../3rdparty/peg-markdown-highlight -DEPENDPATH += $$PWD/../../3rdparty/peg-markdown-highlight - -win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../3rdparty/peg-markdown-highlight/release/libpmh.a -else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../3rdparty/peg-markdown-highlight/debug/libpmh.a -else:win32-msvc*:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../3rdparty/peg-markdown-highlight/release/pmh.lib -else:win32-msvc*:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../3rdparty/peg-markdown-highlight/debug/pmh.lib -else:unix: PRE_TARGETDEPS += $$OUT_PWD/../../3rdparty/peg-markdown-highlight/libpmh.a - diff --git a/rpm/cutemarked.spec b/rpm/cutemarked.spec index 73073280..9064a2d0 100644 --- a/rpm/cutemarked.spec +++ b/rpm/cutemarked.spec @@ -9,7 +9,7 @@ Name: cutemarked Summary: Qt-based Markdown editor Group: Productivity/Text/Editors -Version: 0.11.1 +Version: 0.11.3 Release: 1 License: GPL-2.0+ Url: http://github.com/cloose/CuteMarkEd @@ -31,18 +31,14 @@ BuildRequires: pkgconfig(hunspell) %if 0%{?suse_version} BuildRequires: update-desktop-files BuildRequires: pkgconfig(Qt5Test) +BuildRequires: pkgconfig(Qt5PrintSupport) BuildRequires: libqt5-qttools-devel %endif -%if 0%{?fedora_version} <= 19 -BuildRequires: libqt5-qttools-devel -%endif -%if 0%{?fedora_version} >= 20 -BuildRequires: qt5-qttools-devel -%endif %if 0%{?fedora_version} BuildRequires: desktop-file-utils BuildRequires: pkgconfig(gstreamer-0.10) pkgconfig(gstreamer-app-0.10) BuildRequires: pkgconfig(sqlite3) +BuildRequires: qt5-qttools-devel %endif @@ -81,6 +77,12 @@ make INSTALL_ROOT="%buildroot" install %changelog +* Mon Mar 28 2016 Christian Loose 0.11.3-1 +- New patch version 0.11.3 released + +* Fri Jan 01 2016 Christian Loose 0.11.2-1 +- New patch version 0.11.2 released + * Mon Jul 06 2015 Christian Loose 0.11.1-1 - New patch version 0.11.1 released diff --git a/test/integration/htmltemplatetest.cpp b/test/integration/htmltemplatetest.cpp index 59065be3..750d7941 100644 --- a/test/integration/htmltemplatetest.cpp +++ b/test/integration/htmltemplatetest.cpp @@ -23,38 +23,39 @@ static const QString HTML_TEMPLATE = QStringLiteral(""); static const QString SCROLL_SCRIPT = QStringLiteral(""); +static const QString MERMAID_CSS = QStringLiteral(""); static const QString MERMAID_JS = QStringLiteral(""); static const QString HIGHLIGHT_JS = QStringLiteral("\n\n"); void HtmlTemplateTest::rendersContentInsideBodyTags() { - HtmlTemplate htmlTemplate(HTML_TEMPLATE); + HtmlTemplate htmlTemplate(HTML_TEMPLATE); - QString html = htmlTemplate.render("

TEST

", 0); + QString html = htmlTemplate.render("

TEST

", 0); const QString expected = QStringLiteral("%1\n

TEST

") - .arg(SCROLL_SCRIPT); - QCOMPARE(html, expected); + .arg(SCROLL_SCRIPT); + QCOMPARE(html, expected); } void HtmlTemplateTest::rendersMermaidGraphInsideCodeTags() { - HtmlTemplate htmlTemplate(HTML_TEMPLATE); + HtmlTemplate htmlTemplate(HTML_TEMPLATE); - QString html = htmlTemplate.render("
TEST
", HtmlTemplate::DiagramSupport); + QString html = htmlTemplate.render("
TEST
", HtmlTemplate::DiagramSupport); - const QString expected = QStringLiteral("%1\n%2\n
TEST
") - .arg(SCROLL_SCRIPT).arg(MERMAID_JS); - QCOMPARE(html, expected); + const QString expected = QStringLiteral("%1\n%2\n%3\n
TEST
") + .arg(SCROLL_SCRIPT).arg(MERMAID_CSS).arg(MERMAID_JS); + QCOMPARE(html, expected); } void HtmlTemplateTest::replacesMermaidCodeTagsByDivTagsIfCodeHighlightingEnabled() { - HtmlTemplate htmlTemplate(HTML_TEMPLATE); + HtmlTemplate htmlTemplate(HTML_TEMPLATE); - QString html = htmlTemplate.render("
TEST
", HtmlTemplate::DiagramSupport | HtmlTemplate::CodeHighlighting); + QString html = htmlTemplate.render("
TEST
", HtmlTemplate::DiagramSupport | HtmlTemplate::CodeHighlighting); - const QString expected = QStringLiteral("%1\n%2\n%3\n
\nTEST
") - .arg(SCROLL_SCRIPT).arg(HIGHLIGHT_JS).arg(MERMAID_JS); - QCOMPARE(html, expected); + const QString expected = QStringLiteral("%1\n%2\n%3\n%4\n
\nTEST
") + .arg(SCROLL_SCRIPT).arg(HIGHLIGHT_JS).arg(MERMAID_CSS).arg(MERMAID_JS); + QCOMPARE(html, expected); } diff --git a/test/integration/integration.pro b/test/integration/integration.pro index 786f4aeb..f4bf57d7 100644 --- a/test/integration/integration.pro +++ b/test/integration/integration.pro @@ -9,23 +9,28 @@ QT += gui webkitwidgets TARGET = integrationtest CONFIG += console testcase +CONFIG += c++11 SOURCES += \ discountmarkdownconvertertest.cpp \ htmlpreviewcontrollertest.cpp \ htmltemplatetest.cpp \ jsonsnippetfiletest.cpp \ + jsonthemefiletest.cpp \ main.cpp \ pmhmarkdownparsertest.cpp \ - revealmarkdownconvertertest.cpp + revealmarkdownconvertertest.cpp \ + themecollectiontest.cpp HEADERS += \ discountmarkdownconvertertest.h \ htmlpreviewcontrollertest.h \ htmltemplatetest.h \ jsonsnippetfiletest.h \ + jsonthemefiletest.h \ pmhmarkdownparsertest.h \ - revealmarkdownconvertertest.h + revealmarkdownconvertertest.h \ + themecollectiontest.h target.CONFIG += no_default_install diff --git a/test/integration/jsonthemefiletest.cpp b/test/integration/jsonthemefiletest.cpp new file mode 100644 index 00000000..016d7c92 --- /dev/null +++ b/test/integration/jsonthemefiletest.cpp @@ -0,0 +1,156 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "jsonthemefiletest.h" + + +#include +#include +#include + +#include +#include +#include + + +void JsonThemeFileTest::loadsEmptyThemeCollectionFromFile() +{ + QTemporaryFile themeFile(this); + if (!themeFile.open()) + QFAIL("Failed to create temporary theme file"); + + QTextStream out(&themeFile); out << "{ \"themes\": [] }"; + + themeFile.close(); + + ThemeCollection collection; + bool success = JsonFile::load(themeFile.fileName(), &collection); + + QVERIFY(success); + QCOMPARE(collection.count(), 0); +} + +void JsonThemeFileTest::loadsThemesCollectionFromFile() +{ + QTemporaryFile themeFile(this); + if (!themeFile.open()) + QFAIL("Failed to create temporary theme file"); + + QTextStream out(&themeFile); + out << "{ \"themes\": [" + << " { \"name\": \"default\"," + << " \"markdownHighlighting\": \"default\"," + << " \"codeHighlighting\": \"default\"," + << " \"previewStylesheet\": \"default\"," + << " \"builtIn\": true }," + << " { \"name\": \"dark\"," + << " \"markdownHighlighting\": \"dark\"," + << " \"codeHighlighting\": \"black\"," + << " \"previewStylesheet\": \"dark\" } ] }"; + + themeFile.close(); + + ThemeCollection collection; + bool success = JsonFile::load(themeFile.fileName(), &collection); + + QVERIFY(success); + QCOMPARE(collection.count(), 2); + QCOMPARE(collection.at(0).name(), QLatin1String("default")); + QCOMPARE(collection.at(1).name(), QLatin1String("dark")); +} + +void JsonThemeFileTest::savesEmptyThemesCollectionToFile() +{ + QTemporaryFile themeFile(this); + if (!themeFile.open()) + QFAIL("Failed to create temporary theme file"); + + ThemeCollection collection; + bool success = JsonFile::save(themeFile.fileName(), &collection); + + QVERIFY(success); + + QTextStream in(&themeFile); + QString fileContent = in.readAll().trimmed(); + + QVERIFY(fileContent.startsWith("{")); + QVERIFY(fileContent.contains("\"themes\": [")); + QVERIFY(fileContent.endsWith("}")); +} + +void JsonThemeFileTest::savesThemesCollectionToFile() +{ + QTemporaryFile themeFile(this); + if (!themeFile.open()) + QFAIL("Failed to create temporary theme file"); + + Theme theme1("default", "default", "default", "default"); + + Theme theme2("dark", "dark", "black", "dark"); + + ThemeCollection collection; + collection.insert(theme1); + collection.insert(theme2); + + bool success = JsonFile::save(themeFile.fileName(), &collection); + + QVERIFY(success); + + QTextStream in(&themeFile); + QString fileContent = in.readAll().trimmed(); + + QVERIFY(fileContent.startsWith("{")); + QVERIFY(fileContent.contains("\"themes\": [")); + QVERIFY(fileContent.contains("\"name\": \"default\"")); + QVERIFY(fileContent.contains("\"name\": \"dark\"")); + QVERIFY(fileContent.endsWith("}")); +} + +void JsonThemeFileTest::roundtripTest() +{ + QTemporaryFile themeFile(this); + if (!themeFile.open()) + QFAIL("Failed to create temporary theme file"); + + Theme theme1("default", "default", "default", "default", true); + + Theme theme2("dark", "dark", "black", "dark"); + + ThemeCollection collection1; + collection1.insert(theme1); + collection1.insert(theme2); + + bool saveSuccess = JsonFile::save(themeFile.fileName(), &collection1); + QVERIFY(saveSuccess); + + ThemeCollection collection2; + bool loadSuccess = JsonFile::load(themeFile.fileName(), &collection2); + QVERIFY(loadSuccess); + + QCOMPARE(collection2.count(), 2); + + QCOMPARE(collection2.at(0).name(), theme1.name()); + QCOMPARE(collection2.at(0).markdownHighlighting(), theme1.markdownHighlighting()); + QCOMPARE(collection2.at(0).codeHighlighting(), theme1.codeHighlighting()); + QCOMPARE(collection2.at(0).previewStylesheet(), theme1.previewStylesheet()); + QCOMPARE(collection2.at(0).isBuiltIn(), theme1.isBuiltIn()); + + QCOMPARE(collection2.at(1).name(), theme2.name()); + QCOMPARE(collection2.at(1).markdownHighlighting(), theme2.markdownHighlighting()); + QCOMPARE(collection2.at(1).codeHighlighting(), theme2.codeHighlighting()); + QCOMPARE(collection2.at(1).previewStylesheet(), theme2.previewStylesheet()); + QCOMPARE(collection2.at(0).isBuiltIn(), theme1.isBuiltIn()); +} diff --git a/test/integration/jsonthemefiletest.h b/test/integration/jsonthemefiletest.h new file mode 100644 index 00000000..f2898303 --- /dev/null +++ b/test/integration/jsonthemefiletest.h @@ -0,0 +1,36 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef JSONTHEMEFILETEST_H +#define JSONTHEMEFILETEST_H + +#include + +class JsonThemeFileTest : public QObject +{ + Q_OBJECT + +private slots: + void loadsEmptyThemeCollectionFromFile(); + void loadsThemesCollectionFromFile(); + + void savesEmptyThemesCollectionToFile(); + void savesThemesCollectionToFile(); + + void roundtripTest(); +}; + +#endif // JSONTHEMEFILETEST_H diff --git a/test/integration/main.cpp b/test/integration/main.cpp index 48f5d183..a670e1c6 100644 --- a/test/integration/main.cpp +++ b/test/integration/main.cpp @@ -22,8 +22,10 @@ #include "htmlpreviewcontrollertest.h" #include "htmltemplatetest.h" #include "jsonsnippetfiletest.h" +#include "jsonthemefiletest.h" #include "pmhmarkdownparsertest.h" #include "revealmarkdownconvertertest.h" +#include "themecollectiontest.h" #ifdef ENABLE_HOEDOWN #include "hoedownmarkdownconvertertest.h" @@ -55,8 +57,14 @@ int main(int argc, char *argv[]) HtmlPreviewControllerTest test6; ret += QTest::qExec(&test6, argc, argv); - HtmlTemplateTest test7; - ret += QTest::qExec(&test7, argc, argv); + HtmlTemplateTest test7; + ret += QTest::qExec(&test7, argc, argv); + + JsonThemeFileTest test8; + ret += QTest::qExec(&test8, argc, argv); + + ThemeCollectionTest test9; + ret += QTest::qExec(&test9, argc, argv); return ret; } diff --git a/test/integration/themecollectiontest.cpp b/test/integration/themecollectiontest.cpp new file mode 100644 index 00000000..f97e78ff --- /dev/null +++ b/test/integration/themecollectiontest.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "themecollectiontest.h" + +#include + +#include + +void ThemeCollectionTest::initTestCase() +{ + themeFile = new QTemporaryFile(this); + if (!themeFile->open()) + QFAIL("Failed to create temporary theme file"); + + QTextStream out(themeFile); + out << "{ \"themes\": [" + << " { \"name\": \"default\"," + << " \"markdownHighlighting\": \"default\"," + << " \"codeHighlighting\": \"default\"," + << " \"previewStylesheet\": \"default\" }," + << " { \"name\": \"dark\"," + << " \"markdownHighlighting\": \"dark\"," + << " \"codeHighlighting\": \"black\"," + << " \"previewStylesheet\": \"dark\" } ] }"; +} + +void ThemeCollectionTest::cleanupTestCase() +{ + themeFile->close(); +} + +void ThemeCollectionTest::loadsThemesFromFileIntoCollection() +{ + ThemeCollection themeCollection; + + themeCollection.load(themeFile->fileName()); + + QStringList themeNames = themeCollection.themeNames(); + QCOMPARE(themeNames.count(), 2); + QCOMPARE(themeNames.at(0), QLatin1String("default")); + QCOMPARE(themeNames.at(1), QLatin1String("dark")); +} diff --git a/test/integration/themecollectiontest.h b/test/integration/themecollectiontest.h new file mode 100644 index 00000000..80f2c3d3 --- /dev/null +++ b/test/integration/themecollectiontest.h @@ -0,0 +1,41 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef THEMEMANAGERTEST_H +#define THEMEMANAGERTEST_H + +#include +class QTemporaryFile; +class ThemeCollection; + + +class ThemeCollectionTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void loadsThemesFromFileIntoCollection(); + +private: + QTemporaryFile *themeFile; +}; + +#endif // THEMEMANAGERTEST_H + + diff --git a/test/unit/jsonthemetranslatortest.cpp b/test/unit/jsonthemetranslatortest.cpp new file mode 100644 index 00000000..a100bc9a --- /dev/null +++ b/test/unit/jsonthemetranslatortest.cpp @@ -0,0 +1,120 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "jsonthemetranslatortest.h" + +#include + +#include +#include +#include + +static const QLatin1String A_THEME_NAME("mytheme"); +static const QLatin1String A_MARKDOWN_HIGHLIGHTING("default"); +static const QLatin1String A_CODE_HIGHLIGHTING("monokai"); +static const QLatin1String A_PREVIEW_STYLESHEET("github"); + + +QJsonDocument NewJsonDocumentWithObject(const QJsonObject &jsonObject) +{ + QJsonArray themeArray; + themeArray.append(jsonObject); + + QJsonObject object; + object.insert("themes", themeArray); + + return QJsonDocument(object); +} + +QJsonObject NewJsonThemeObject() +{ + QJsonObject jsonObject; + jsonObject.insert("name", A_THEME_NAME); + jsonObject.insert("markdownHighlighting", A_MARKDOWN_HIGHLIGHTING); + jsonObject.insert("codeHighlighting", A_CODE_HIGHLIGHTING); + jsonObject.insert("previewStylesheet", A_PREVIEW_STYLESHEET); + jsonObject.insert("builtIn", true); + + return jsonObject; +} + +void JsonThemeTranslatorTest::initTestCase() +{ + translator = new JsonThemeTranslator(); +} + +void JsonThemeTranslatorTest::cleanupTestCase() +{ + delete translator; +} + +void JsonThemeTranslatorTest::doesNotProcessInvalidJsonDocument() +{ + QJsonDocument doc; + + ThemeCollection collection; + bool success = translator->processDocument(doc, &collection); + + QVERIFY(!success); + QCOMPARE(collection.count(), 0); +} + +void JsonThemeTranslatorTest::translatesEmptyJsonDocumentToEmptyThemes() +{ + QJsonObject themesObject; + themesObject.insert("themes", QJsonArray()); + + QJsonDocument doc(themesObject); + + ThemeCollection collection; + bool success = translator->processDocument(doc, &collection); + + QVERIFY(success); + QCOMPARE(collection.count(), 0); +} + +void JsonThemeTranslatorTest::translatesJsonDocumentToThemes() +{ + QJsonDocument doc = NewJsonDocumentWithObject(NewJsonThemeObject()); + + ThemeCollection collection; + bool success = translator->processDocument(doc, &collection); + + QVERIFY(success); + QCOMPARE(collection.count(), 1); + QCOMPARE(collection.at(0).name(), A_THEME_NAME); + QCOMPARE(collection.at(0).markdownHighlighting(), A_MARKDOWN_HIGHLIGHTING); + QCOMPARE(collection.at(0).codeHighlighting(), A_CODE_HIGHLIGHTING); + QCOMPARE(collection.at(0).previewStylesheet(), A_PREVIEW_STYLESHEET); + QCOMPARE(collection.at(0).isBuiltIn(), true); +} + +void JsonThemeTranslatorTest::translatesThemesToJsonDocument() +{ + Theme theme(A_THEME_NAME, A_MARKDOWN_HIGHLIGHTING, A_CODE_HIGHLIGHTING, A_PREVIEW_STYLESHEET, true); + ThemeCollection collection; + collection.insert(theme); + + QJsonDocument doc = translator->createDocument(&collection); + + QJsonObject actual = doc.object().value("themes").toArray().first().toObject(); + QCOMPARE(actual["name"].toString(), A_THEME_NAME); + QCOMPARE(actual["markdownHighlighting"].toString(), A_MARKDOWN_HIGHLIGHTING); + QCOMPARE(actual["codeHighlighting"].toString(), A_CODE_HIGHLIGHTING); + QCOMPARE(actual["previewStylesheet"].toString(), A_PREVIEW_STYLESHEET); + QCOMPARE(actual["builtIn"].toBool(), true); +} + diff --git a/test/unit/jsonthemetranslatortest.h b/test/unit/jsonthemetranslatortest.h new file mode 100644 index 00000000..ab44d4de --- /dev/null +++ b/test/unit/jsonthemetranslatortest.h @@ -0,0 +1,44 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef JSONTHEMETRANSLATORTEST_H +#define JSONTHEMETRANSLATORTEST_H + +#include +class JsonThemeTranslator; + + +class JsonThemeTranslatorTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void doesNotProcessInvalidJsonDocument(); + void translatesEmptyJsonDocumentToEmptyThemes(); + void translatesJsonDocumentToThemes(); + void translatesThemesToJsonDocument(); + +private: + JsonThemeTranslator *translator; +}; + +#endif // JSONTHEMETRANSLATORTEST_H + + + diff --git a/test/unit/main.cpp b/test/unit/main.cpp index 155b2995..768e25cb 100644 --- a/test/unit/main.cpp +++ b/test/unit/main.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 Christian Loose + * Copyright 2013-2015 Christian Loose * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,11 +18,15 @@ #include "dictionarytest.h" #include "jsonsnippettranslatortest.h" +#include "jsonthemetranslatortest.h" #include "jsontranslatorfactorytest.h" #include "slidelinemappingtest.h" #include "snippetcollectiontest.h" #include "completionlistmodeltest.h" #include "snippettest.h" +#include "stylemanagertest.h" +#include "themecollectiontest.h" +#include "themetest.h" #include "yamlheadercheckertest.h" int main(int argc, char *argv[]) @@ -53,5 +57,17 @@ int main(int argc, char *argv[]) YamlHeaderCheckerTest test8; ret += QTest::qExec(&test8, argc, argv); + ThemeTest test9; + ret += QTest::qExec(&test9, argc, argv); + + ThemeCollectionTest test10; + ret += QTest::qExec(&test10, argc, argv); + + StyleManagerTest test11; + ret += QTest::qExec(&test11, argc, argv); + + JsonThemeTranslatorTest test12; + ret += QTest::qExec(&test12, argc, argv); + return ret; } diff --git a/test/unit/stylemanagertest.cpp b/test/unit/stylemanagertest.cpp new file mode 100644 index 00000000..87161278 --- /dev/null +++ b/test/unit/stylemanagertest.cpp @@ -0,0 +1,85 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "stylemanagertest.h" + +#include + +#include + +static const Theme defaultTheme("Default", "Default", "Default", "Default"); +static const Theme githubTheme("Github", "Github", "Github", "Github"); +static const Theme solarizedLightTheme("Solarized Light", "Solarized Light", "Solarized Light", "Solarized Light"); +static const Theme solarizedDarkTheme("Solarized Dark", "Solarized Dark", "Solarized Dark", "Solarized Dark"); +static const Theme clearnessTheme("Clearness", "Clearness", "Clearness", "Clearness"); +static const Theme clearnessDarkTheme("Clearness Dark", "Clearness Dark", "Clearness Dark", "Clearness Dark"); +static const Theme bywordDarkTheme("Byword Dark", "Byword Dark", "Byword Dark", "Byword Dark"); + +void StyleManagerTest::returnsPathForMarkdownHighlighting() +{ + StyleManager styleManager; + + QCOMPARE(styleManager.markdownHighlightingPath(defaultTheme), QLatin1String("default")); + QCOMPARE(styleManager.markdownHighlightingPath(solarizedLightTheme), QLatin1String("solarized-light")); + QCOMPARE(styleManager.markdownHighlightingPath(solarizedDarkTheme), QLatin1String("solarized-dark")); + QCOMPARE(styleManager.markdownHighlightingPath(clearnessDarkTheme), QLatin1String("clearness-dark")); + QCOMPARE(styleManager.markdownHighlightingPath(bywordDarkTheme), QLatin1String("byword-dark")); +} + +void StyleManagerTest::returnsPathForCodeHighlighting() +{ + StyleManager styleManager; + + QCOMPARE(styleManager.codeHighlightingPath(defaultTheme), QLatin1String("default")); + QCOMPARE(styleManager.codeHighlightingPath(githubTheme), QLatin1String("github")); + QCOMPARE(styleManager.codeHighlightingPath(solarizedLightTheme), QLatin1String("solarized_light")); + QCOMPARE(styleManager.codeHighlightingPath(solarizedDarkTheme), QLatin1String("solarized_dark")); +} + +void StyleManagerTest::returnsPathForPreviewStylesheet() +{ + StyleManager styleManager; + + QCOMPARE(styleManager.previewStylesheetPath(defaultTheme), QLatin1String("qrc:/css/markdown.css")); + QCOMPARE(styleManager.previewStylesheetPath(githubTheme), QLatin1String("qrc:/css/github.css")); + QCOMPARE(styleManager.previewStylesheetPath(solarizedLightTheme), QLatin1String("qrc:/css/solarized-light.css")); + QCOMPARE(styleManager.previewStylesheetPath(solarizedDarkTheme), QLatin1String("qrc:/css/solarized-dark.css")); + QCOMPARE(styleManager.previewStylesheetPath(clearnessTheme), QLatin1String("qrc:/css/clearness.css")); + QCOMPARE(styleManager.previewStylesheetPath(clearnessDarkTheme), QLatin1String("qrc:/css/clearness-dark.css")); + QCOMPARE(styleManager.previewStylesheetPath(bywordDarkTheme), QLatin1String("qrc:/css/byword-dark.css")); +} + +void StyleManagerTest::returnsPathForCustomPreviewStylesheet() +{ + QString expectedPath = "file:///C:/User/Test/custom.css"; + Theme customTheme("Custom", "Default", "Default", "Custom"); + StyleManager styleManager; + + styleManager.insertCustomPreviewStylesheet("Custom", expectedPath); + + QCOMPARE(styleManager.previewStylesheetPath(customTheme), expectedPath); +} + +void StyleManagerTest::customPreviewStylesheetOverwritesBuiltin() +{ + QString expectedPath = "file:///C:/User/Test/custom.css"; + Theme customTheme("Custom", "Default", "Default", "Github"); + StyleManager styleManager; + + styleManager.insertCustomPreviewStylesheet("Github", expectedPath); + + QCOMPARE(styleManager.previewStylesheetPath(customTheme), expectedPath); +} diff --git a/test/unit/stylemanagertest.h b/test/unit/stylemanagertest.h new file mode 100644 index 00000000..773c9460 --- /dev/null +++ b/test/unit/stylemanagertest.h @@ -0,0 +1,36 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef STYLEMANAGERTEST_H +#define STYLEMANAGERTEST_H + +#include + +class StyleManagerTest : public QObject +{ + Q_OBJECT + +private slots: + void returnsPathForMarkdownHighlighting(); + void returnsPathForCodeHighlighting(); + void returnsPathForPreviewStylesheet(); + void returnsPathForCustomPreviewStylesheet(); + void customPreviewStylesheetOverwritesBuiltin(); +}; + +#endif // STYLEMANAGERTEST_H + + diff --git a/test/unit/themecollectiontest.cpp b/test/unit/themecollectiontest.cpp new file mode 100644 index 00000000..3fbf9511 --- /dev/null +++ b/test/unit/themecollectiontest.cpp @@ -0,0 +1,85 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "themecollectiontest.h" + +#include + +#include + + +void ThemeCollectionTest::returnsConstantNameOfJsonArray() +{ + ThemeCollection collection; + QCOMPARE(collection.name(), QStringLiteral("themes")); +} + +void ThemeCollectionTest::returnsNumberOfThemesInCollection() +{ + ThemeCollection collection; + Theme theme("name", "markdown", "code", "preview"); + collection.insert(theme); + + QCOMPARE(collection.count(), 1); +} + +void ThemeCollectionTest::returnsThemeAtIndexPosition() +{ + ThemeCollection collection; + Theme theme("name", "markdown", "code", "preview"); + collection.insert(theme); + + Theme actual = collection.at(0); + + QCOMPARE(actual, theme); +} + +void ThemeCollectionTest::returnsIfCollectionContainsTheme() +{ + ThemeCollection collection; + Theme theme("name", "markdown", "code", "preview"); + collection.insert(theme); + + QCOMPARE(collection.contains("name"), true); + QCOMPARE(collection.contains("missing"), false); +} + +void ThemeCollectionTest::returnsThemeByName() +{ + ThemeCollection collection; + Theme theme("name", "markdown", "code", "preview"); + collection.insert(theme); + + Theme actual = collection.theme("name"); + + QCOMPARE(actual, theme); +} + +void ThemeCollectionTest::returnsNameOfAllThemes() +{ + Theme theme1("name 1", "markdown", "code", "preview"); + Theme theme2("name 2", "markdown", "code", "preview"); + ThemeCollection collection; + collection.insert(theme1); + collection.insert(theme2); + + QStringList themeNames = collection.themeNames(); + + QCOMPARE(themeNames.count(), 2); + QCOMPARE(themeNames.at(0), theme1.name()); + QCOMPARE(themeNames.at(1), theme2.name()); +} + diff --git a/test/unit/themecollectiontest.h b/test/unit/themecollectiontest.h new file mode 100644 index 00000000..3fc8d15b --- /dev/null +++ b/test/unit/themecollectiontest.h @@ -0,0 +1,37 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef THEMECOLLECTIONTEST_H +#define THEMECOLLECTIONTEST_H + +#include + +class ThemeCollectionTest : public QObject +{ + Q_OBJECT + +private slots: + void returnsConstantNameOfJsonArray(); + void returnsNumberOfThemesInCollection(); + void returnsThemeAtIndexPosition(); + void returnsIfCollectionContainsTheme(); + void returnsThemeByName(); + void returnsNameOfAllThemes(); +}; + +#endif // THEMECOLLECTIONTEST_H + + diff --git a/test/unit/themetest.cpp b/test/unit/themetest.cpp new file mode 100644 index 00000000..5d97e36b --- /dev/null +++ b/test/unit/themetest.cpp @@ -0,0 +1,84 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "themetest.h" + +#include + +#include + +static const QLatin1String A_THEME_NAME("name"); +static const QLatin1String A_MARKDOWN_HIGHLIGHTING("markdown"); +static const QLatin1String A_CODE_HIGHLIGHTING("code"); +static const QLatin1String A_PREVIEW_STYLESHEET("preview"); + +void ThemeTest::isLessThanComparable() +{ + Theme theme1("abc", A_MARKDOWN_HIGHLIGHTING, A_CODE_HIGHLIGHTING, A_PREVIEW_STYLESHEET); + + Theme theme2("xyz", A_MARKDOWN_HIGHLIGHTING, A_CODE_HIGHLIGHTING, A_PREVIEW_STYLESHEET); + + QCOMPARE(theme1 < theme2, true); + QCOMPARE(theme2 < theme1, false); + QCOMPARE(theme1 < theme1, false); +} + +void ThemeTest::isEqualComparable() +{ + Theme theme1("abc", A_MARKDOWN_HIGHLIGHTING, A_CODE_HIGHLIGHTING, A_PREVIEW_STYLESHEET); + + Theme theme2("abc", A_MARKDOWN_HIGHLIGHTING, A_CODE_HIGHLIGHTING, A_PREVIEW_STYLESHEET); + + Theme theme3("xyz", A_MARKDOWN_HIGHLIGHTING, A_CODE_HIGHLIGHTING, A_PREVIEW_STYLESHEET); + + QCOMPARE(theme1 == theme1, true); + QCOMPARE(theme1 == theme2, true); + QCOMPARE(theme1 == theme3, false); +} + +void ThemeTest::throwsIfNameIsEmpty() +{ + try { + Theme theme("", A_MARKDOWN_HIGHLIGHTING, A_CODE_HIGHLIGHTING, A_PREVIEW_STYLESHEET); + QFAIL("Expected exception of type runtime_error not thrown"); + } catch(const std::runtime_error &) {} +} + +void ThemeTest::throwsIfMarkdownHighlightingIsEmpty() +{ + try { + Theme theme(A_THEME_NAME, "", A_CODE_HIGHLIGHTING, A_PREVIEW_STYLESHEET); + QFAIL("Expected exception of type runtime_error not thrown"); + } catch(const std::runtime_error &) {} +} + +void ThemeTest::throwsIfCodeHighlightingIsEmpty() +{ + try { + Theme theme(A_THEME_NAME, A_MARKDOWN_HIGHLIGHTING, "", A_PREVIEW_STYLESHEET); + QFAIL("Expected exception of type runtime_error not thrown"); + } catch(const std::runtime_error &) {} +} + +void ThemeTest::throwsIfPreviewStylesheetIsEmpty() +{ + try { + Theme theme(A_THEME_NAME, A_MARKDOWN_HIGHLIGHTING, A_CODE_HIGHLIGHTING, ""); + QFAIL("Expected exception of type runtime_error not thrown"); + } catch(const std::runtime_error &) {} +} + + diff --git a/test/unit/themetest.h b/test/unit/themetest.h new file mode 100644 index 00000000..9e567742 --- /dev/null +++ b/test/unit/themetest.h @@ -0,0 +1,36 @@ +/* + * Copyright 2015 Christian Loose + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef THEMETEST_H +#define THEMETEST_H + +#include + +class ThemeTest : public QObject +{ + Q_OBJECT + +private slots: + void isLessThanComparable(); + void isEqualComparable(); + void throwsIfNameIsEmpty(); + void throwsIfMarkdownHighlightingIsEmpty(); + void throwsIfCodeHighlightingIsEmpty(); + void throwsIfPreviewStylesheetIsEmpty(); +}; + +#endif // THEMETEST_H + diff --git a/test/unit/unit.pro b/test/unit/unit.pro index ac004fe8..801dba6a 100644 --- a/test/unit/unit.pro +++ b/test/unit/unit.pro @@ -8,27 +8,36 @@ QT += testlib TARGET = unittest CONFIG += console testcase +CONFIG += c++11 SOURCES += \ main.cpp \ completionlistmodeltest.cpp \ snippettest.cpp \ jsonsnippettranslatortest.cpp \ + jsonthemetranslatortest.cpp \ jsontranslatorfactorytest.cpp \ slidelinemappingtest.cpp \ snippetcollectiontest.cpp \ dictionarytest.cpp \ - yamlheadercheckertest.cpp + yamlheadercheckertest.cpp \ + themetest.cpp \ + themecollectiontest.cpp \ + stylemanagertest.cpp HEADERS += \ completionlistmodeltest.h \ snippettest.h \ jsonsnippettranslatortest.h \ + jsonthemetranslatortest.h \ jsontranslatorfactorytest.h \ slidelinemappingtest.h \ snippetcollectiontest.h \ dictionarytest.h \ - yamlheadercheckertest.h + yamlheadercheckertest.h \ + themetest.h \ + themecollectiontest.h \ + stylemanagertest.h target.CONFIG += no_default_install