find_package(DBus1)
if(DBus1_FOUND)
+ message(STATUS "Deteced DBUS1 available, adding DBUS interfaces")
+
LIST(APPEND QtComponents DBus)
LIST(APPEND QtLibraries Qt6::DBus)
+
+ list(APPEND VymSources src/dbus/adaptormodel.cpp src/dbus/adaptorvym.cpp)
+ include_directories(${CMAKE_SOURCE_DIR}/src/dbus ${CMAKE_SOURCE_DIR}/src)
+ ADD_COMPILE_DEFINITIONS(VYM_DBUS)
endif()
endif()
endif()
-# Add DBUS interfaces, if DBUS is available on platform
-if(DBus1_FOUND)
- list(APPEND VymSources src/dbus/adaptormodel.cpp src/dbus/adaptorvym.cpp)
- include_directories(${CMAKE_SOURCE_DIR}/src/dbus ${CMAKE_SOURCE_DIR}/src)
- ADD_COMPILE_DEFINITIONS(VYM_DBUS)
-endif()
-
# Translations (release)
# To update the translation files based on source code changes
thoughts in tree-like structures. It is also useful for time management,
self-organization and sorting through new ideas and complex contexts.
+VYM includes a powerful personal task manager, which allows to adjust
+priorities or reminds you after easily defined time spans.
+
You can use the scripting capabilities for interesting presentations.
VYM can also retrieve data from the Jira issue tracking system and
talk to the Concluence documentation system.
-VYM runs on Apple and Windows and of course mose Linux platforms.
+VYM runs on Apple and Windows and of course most Linux platforms.
Documentation
-------------
make
make install
- or using Qt Creator:
+ or using Qt Creator (recommended on Mac and Windows):
In "File" do "Open file or project" and select the
"CMakeLists.txt". This will setup the project.
+
+ For testing you probably need to tell vym where to find various
+ files like macros, demos, etc. On the commandline you can do this
+ with the "-l" option. Using Qt Creator you can add a variable
+ VYMHOME to the execution environment pointing to your path to vym
+ sources.
+
Questions and feedback
----------------------
extern QString vymCodeName;
extern QString vymCodeQuality;
-extern QColor vymBlue;
+extern QColor vymBlueColor;
AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent)
{
credits->setHtml(
QString(
- "<style>a:link { color: " + vymBlue.name() + "; background-color: transparent;}</style>"
+ "<style>a:link { color: " + vymBlueColor.name() + "; background-color: transparent;}</style>"
"<center><img src=\"" + iconPath + "vym-128x128.png\"></center>"
"<h3><center>VYM - View Your Mind </h3>"
"<p align=\"center\"> A tool to put the things you have got in your mind into a map.</p>"
model()->detach(branchItemInt);
}
+QString BranchWrapper::getBranchesLayout()
+{
+ QString r = Container::layoutString(branchItemInt->getBranchContainer()->branchesContainerLayout());
+ mainWindow->setScriptResult(r);
+ return r;
+}
+
bool BranchWrapper::getFrameAutoDesign(const bool &useInnerFrame)
{
bool r = branchItemInt->getBranchContainer()->frameAutoDesign(useInnerFrame);
return r;
}
+QString BranchWrapper::getImagesLayout()
+{
+ QString r = branchItemInt->getImagesContainer()->layoutString();
+ mainWindow->setScriptResult(r);
+ return r;
+}
+
void BranchWrapper::getJiraData(bool subtree)
{
model()->getJiraData(subtree, branchItemInt);
model()->setAttribute(branchItemInt, key, value);
}
+void BranchWrapper::setBranchesLayout(const QString &layout)
+{
+ model()->setBranchesLayout(layout, branchItemInt);
+}
+
void BranchWrapper::setFlagByName(const QString &s)
{
model()->setFlagByName(s, branchItemInt);
model()->setHideLinkUnselected(b, branchItemInt);
}
+void BranchWrapper::setImagesLayout(const QString &layout)
+{
+ model()->setImagesLayout(layout, branchItemInt);
+}
+
void BranchWrapper::setNoteRichText(const QString &s)
{
VymNote vn;
void deleteConfluencePageLabel(const QString &labelName);
int depth();
void detach();
+ QString getBranchesLayout();
bool getFrameAutoDesign(const bool & useInnerFrame);
QString getFrameBrushColor(const bool & useInnerFrame);
int getFramePadding(const bool & useInnerFrame);
QString getFrameType(const bool & useInnerFrame);
QString getHeading();
QString getHeadingXML();
+ QString getImagesLayout();
void getJiraData(bool subtree);
QString getNoteText();
QString getNoteXML();
bool selectXLink(int n);
bool selectXLinkOtherEnd(int n);
void setAttribute(const QString &key, const QString &value);
+ void setBranchesLayout(const QString &layout);
void setFlagByName(const QString &);
void setFrameAutoDesign(const bool, const bool);
void setFrameBrushColor(const bool & useInnerFrame, const QString &color);
void setHeadingText(const QString &);
void setHideExport(bool b);
void setHideLinkUnselected(bool b);
+ void setImagesLayout(const QString &layout);
void setNoteRichText(const QString &);
void setNoteText(const QString &);
void setOnlyFlags(QJSValueList args);
void ExportConfluenceDialog::openUrl()
{
- mainWindow->openURL(ui.lineEditURL->text());
+ mainWindow->openUrl(ui.lineEditURL->text());
}
QString ExportConfluenceDialog::getUrl() { return url; }
// Export values
if (key == "postData")
jsobj[key] = QJsonValue::Null;
- else if (ai->value().typeName() == "QDateTime")
+ else if (strcmp(ai->value().typeName(), "QDateTime") == 0)
jsobj[key] = QJsonValue(ai->value().toDateTime().toMSecsSinceEpoch() * 1000);
- else if (ai->value().typeName() == "QString")
+ else if (strcmp(ai->value().typeName(), "QString") == 0)
jsobj[key] = ai->value().toString();
- else if (ai->value().typeName() == "Integer")
- {
+ else if (strcmp(ai->value().typeName(), "Integer") == 0)
jsobj[key] = QJsonValue(ai->value().toInt());
- }
else
qWarning() << "ExportFirefox Unknown attribute type in " << bi->headingPlain() << "Key: " << key;
}
#include <windows.h>
#endif
-#if defined(Q_OS_MACX)
+#if defined(Q_OS_MACOS)
#include "unistd.h"
#endif
bool usingDarkTheme; // Influences some color schemes
bool systemSeemsDark; // Text brighter than background?
QString iconTheme; // "bright" or "dark" depending on usingDarkTheme
-QColor vymBlue;
+
+// Some colors used more often and depending on dark mode
+QColor vymBlueColor;
+QColor vymForegroundColor;
+QColor vymBaseColor;
int warningCount = 0;
int criticalCount = 0;
} else {
// ok, let's find vymBaseDir on my own
-#if defined(Q_OS_MACX)
+#if defined(Q_OS_MACOS)
// Executable is in vym.app/Contents/MacOS, so go up first:
vymBaseDir.setPath(QCoreApplication::applicationDirPath());
vymBaseDir.cdUp();
}
}
+ QPalette palette;
if (usingDarkTheme && settingsDarkTheme == "always") {
qApp->setStyle(QStyleFactory::create("fusion"));
//qApp->setStyle(QStyleFactory::create("Windows"));
//qApp->setStyle(QStyleFactory::create("windowsvista"));
// On Windows, there is no dark palette predefined, let's do that on our own
- QPalette palette;
palette.setColor(QPalette::Window, QColor(53,53,53));
palette.setColor(QPalette::WindowText, Qt::white);
palette.setColor(QPalette::Base, QColor(27, 30, 32));
//palette.setColor(QPalette::Light, Qt::green);
//palette.setColor(QPalette::Midlight, Qt::red);
qApp->setPalette(palette);
- }
+
+ vymBlueColor =QColor::fromString("#00aaff");
+ } else
+ vymBlueColor =QColor::fromString("#0000ff");
+
+ vymForegroundColor = palette.color(QPalette::WindowText);
+ vymBaseColor = palette.color(QPalette::Base);
// Prepare and check translations
vymTranslationsDir = QDir(vymBaseDir.path() + "/translations");
extern QDir vymInstallDir;
#endif
-extern QColor vymBlue;
+extern QColor vymBlueColor;
Main::Main(QWidget *parent) : QMainWindow(parent)
{
// Explorer automagically opens up the URL
// in the user's preferred browser.
s = settings.value(p, "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe").toString();
-#elif defined(Q_OS_MACX)
+#elif defined(Q_OS_MACOS)
s = settings.value(p, "/usr/bin/open").toString();
#else
s = settings.value(p, "xdg-open").toString();
p = "/system/readerPDF";
#if defined(Q_OS_WIN)
s = settings.value(p, "explorer").toString();
-#elif defined(Q_OS_MACX)
+#elif defined(Q_OS_MACOS)
s = settings.value(p, "/usr/bin/open").toString();
#else
s = settings.value(p, "xdg-open").toString();
c = new Command("selectedBranch", Command::AnySel, Command::BranchPar);
modelCommands.append(c);
- c = new Command("selectID", Command::AnySel, Command::BoolPar);
- c->addParameter(Command::StringPar, false, "Unique ID");
- modelCommands.append(c);
-
c = new Command("selectLatestAdded", Command::AnySel, Command::BoolPar);
modelCommands.append(c);
c->addParameter(Command::StringPar, false, "Name of flag");
branchCommands.append(c);
+ c = new Command("setBranchesLayout", Command::BranchSel);
+ c->addParameter(Command::StringPar, false, "Layout of branches in subtree");
+ branchCommands.append(c);
+
c = new Command("setFrameAutoDesign", Command::BranchSel);
c->addParameter(Command::BoolPar, false, useInnerFrameDesc);
c->addParameter(Command::BoolPar, false, "Flag for using automatic frame design");
"Set if links of items should be visible for unselected items");
branchCommands.append(c);
+ c = new Command("setImagesLayout", Command::BranchSel);
+ c->addParameter(Command::StringPar, false, "Layout of images");
+ branchCommands.append(c);
+
c = new Command("setNoteRichText", Command::BranchSel);
c->addParameter(Command::StringPar, false, "Note of branch");
branchCommands.append(c);
// Shortcut to delete selection
a = new QAction(tr("Delete Selection", "Edit menu"), this);
-#if defined(Q_OS_MACX)
+#if defined(Q_OS_MACOS)
a->setShortcut(Qt::Key_Backspace);
#else
a->setShortcut(Qt::Key_Delete);
a = new QAction(QPixmap(":up-diagonal-right.png"), tr("Move branch diagonally up", "Edit menu"),
this);
-#if defined(Q_OS_MACX)
+#if defined(Q_OS_MACOS)
a->setShortcut(Qt::SHIFT | Qt::Key_PageUp);
#else
a->setShortcut(Qt::CTRL | Qt::Key_PageUp);
a = new QAction(QPixmap(":down-diagonal-left.png"), tr("Move branch diagonally down", "Edit menu"),
this);
-#if defined(Q_OS_MACX)
+#if defined(Q_OS_MACOS)
a->setShortcut(Qt::SHIFT | Qt::Key_PageDown);
#else
a->setShortcut(Qt::CTRL | Qt::Key_PageDown);
ADD_SHORTCUT
switchboard.addSwitch("mapOpenUrl", shortcutScope, a, tag);
addAction(a);
- connect(a, SIGNAL(triggered()), this, SLOT(editOpenURL()));
+ connect(a, SIGNAL(triggered()), this, SLOT(openUrl()));
actionListBranches.append(a);
- actionOpenURL = a;
+ actionOpenUrl = a;
- a = new QAction(tr("Open URL in new tab", "Edit menu"), this);
- // a->setShortcut (Qt::CTRL+Qt::Key_U );
- switchboard.addSwitch("mapOpenUrlTab", shortcutScope, a, tag);
- addAction(a);
- connect(a, SIGNAL(triggered()), this, SLOT(editOpenURLTab()));
- actionListBranches.append(a);
- actionOpenURLTab = a;
-
- a = new QAction(tr("Open all URLs in subtree (including scrolled branches)",
- "Edit menu"),
- this);
+ a = new QAction(tr("Open all visible URLs in subtree", "Edit menu"), this);
switchboard.addSwitch("mapOpenUrlsSubTree", shortcutScope, a, tag);
addAction(a);
- connect(a, SIGNAL(triggered()), this, SLOT(editOpenMultipleVisURLTabs()));
+ connect(a, SIGNAL(triggered()), this, SLOT(editOpenMultipleVisUrls()));
actionListBranches.append(a);
- actionOpenMultipleVisURLTabs = a;
+ actionOpenMultipleVisUrls = a;
a = new QAction(tr("Open all URLs in subtree", "Edit menu"), this);
- switchboard.addSwitch("mapOpenMultipleUrlTabs", shortcutScope, a, tag);
+ switchboard.addSwitch("mapOpenMultipleUrls", shortcutScope, a, tag);
addAction(a);
- connect(a, SIGNAL(triggered()), this, SLOT(editOpenMultipleURLTabs()));
+ connect(a, SIGNAL(triggered()), this, SLOT(editOpenMultipleUrls()));
actionListBranches.append(a);
- actionOpenMultipleURLTabs = a;
+ actionOpenMultipleUrls = a;
+
+ a = new QAction(tr("Open all URLs in subtree in private mode", "Edit menu"), this);
+ if (settings.value("/mainwindow/showTestMenu", false).toBool()) {
+ switchboard.addSwitch("mapOpenMultipleUrls", shortcutScope, a, tag);
+ addAction(a);
+ connect(a, SIGNAL(triggered()), this, SLOT(editOpenMultipleUrlsPrivate()));
+ actionListBranches.append(a);
+ }
+ actionOpenMultipleUrlsPrivate = a;
a = new QAction(QPixmap(), tr("Extract URLs from note", "Edit menu"), this);
a->setShortcut(Qt::SHIFT | Qt::Key_N);
branchLinksContextMenu = branchContextMenu->addMenu(
tr("References (URLs, vymLinks, ...)", "Context menu name"));
- branchLinksContextMenu->addAction(actionOpenURL);
- branchLinksContextMenu->addAction(actionOpenURLTab);
- branchLinksContextMenu->addAction(actionOpenMultipleVisURLTabs);
- branchLinksContextMenu->addAction(actionOpenMultipleURLTabs);
+ branchLinksContextMenu->addAction(actionOpenUrl);
+ branchLinksContextMenu->addAction(actionOpenMultipleVisUrls);
+ branchLinksContextMenu->addAction(actionOpenMultipleUrls);
+ branchLinksContextMenu->addAction(actionOpenMultipleUrlsPrivate);
branchLinksContextMenu->addAction(actionURLNew);
branchLinksContextMenu->addAction(actionLocalURL);
branchLinksContextMenu->addAction(actionGetURLsFromNote);
c = QColor::fromString("#aa00ff"); quickColors << c; // Purple
c = QColor::fromString("#0000ff"); quickColors << c; // Blue
c = QColor::fromString("#00aaff"); quickColors << c; // LightBlue
- usingDarkTheme ? vymBlue = c : vymBlue = quickColors.count() - 2;
+ usingDarkTheme ? vymBlueColor = c : vymBlueColor = quickColors.count() - 2;
c = QColor::fromString("#000000"); quickColors << c; // Black
c = QColor::fromString("#444444"); quickColors << c; // Dark gray
c = QColor::fromString("#aaaaaa"); quickColors << c; // Light gray
else
addToolBar (colorsToolbar);
- // Zoom
- zoomToolbar = addToolBar(tr("View toolbar", "View Toolbar name"));
- zoomToolbar->setObjectName("viewTB");
- zoomToolbar->addAction(actionTogglePresentationMode);
- zoomToolbar->addAction(actionToggleHideTmpMode);
- zoomToolbar->addAction(actionZoomIn);
- zoomToolbar->addAction(actionZoomOut);
- zoomToolbar->addAction(actionZoomReset);
- zoomToolbar->addAction(actionCenterOn);
- zoomToolbar->addAction(actionRotateCounterClockwise);
- zoomToolbar->addAction(actionRotateClockwise);
+ // View transformations (shrink/grow/rotate)
+ viewTransformationsToolbar = addToolBar(tr("View toolbar", "View Toolbar name"));
+ viewTransformationsToolbar->setObjectName("viewTB");
+ viewTransformationsToolbar->addAction(actionZoomIn);
+ viewTransformationsToolbar->addAction(actionZoomOut);
+ viewTransformationsToolbar->addAction(actionZoomReset);
+ viewTransformationsToolbar->addAction(actionCenterOn);
+ viewTransformationsToolbar->addAction(actionRotateCounterClockwise);
+ viewTransformationsToolbar->addAction(actionRotateClockwise);
+
+ // Modified special view, e.g. presentation mode or temporary hiding of branches
+ limitedViewToolbar = addToolBar(tr("Limited view toolbar", "View Toolbar name"));
+ limitedViewToolbar->setObjectName("limitedViewTB");
+ limitedViewToolbar->addAction(actionTogglePresentationMode);
+ limitedViewToolbar->addAction(actionToggleHideTmpMode);
// Editors
editorsToolbar = addToolBar(tr("Editors toolbar", "Editor Toolbar name"));
toolbarsMenu->addAction(editActionsToolbar->toggleViewAction());
toolbarsMenu->addAction(selectionToolbar->toggleViewAction());
toolbarsMenu->addAction(colorsToolbar->toggleViewAction());
- toolbarsMenu->addAction(zoomToolbar->toggleViewAction());
+ toolbarsMenu->addAction(viewTransformationsToolbar->toggleViewAction());
+ toolbarsMenu->addAction(limitedViewToolbar->toggleViewAction());
toolbarsMenu->addAction(modModesToolbar->toggleViewAction());
toolbarsMenu->addAction(referencesToolbar->toggleViewAction());
toolbarsMenu->addAction(editorsToolbar->toggleViewAction());
toolbarStates[editActionsToolbar] = true;
toolbarStates[selectionToolbar] = false;
toolbarStates[colorsToolbar] = true;
- toolbarStates[zoomToolbar] = true;
+ toolbarStates[viewTransformationsToolbar] = true;
+ toolbarStates[limitedViewToolbar] = false;
toolbarStates[modModesToolbar] = false;
- toolbarStates[referencesToolbar] = true;
+ toolbarStates[referencesToolbar] = false;
toolbarStates[editorsToolbar] = false;
toolbarStates[standardFlagsToolbar] = true;
- toolbarStates[userFlagsToolbar] = true;
+ toolbarStates[userFlagsToolbar] = false;
// Initialize toolbar visibilities and switch off presentation mode
presentationMode = true;
void Main::fileSaveAs(const File::SaveMode &savemode)
{
+ std::cout << __func__ << " ok0" << std::endl; // FIXME-2 debugging
VymModel *m = currentModel();
if (!m) return;
QString fn = QFileDialog::getSaveFileName(
this, tr("Save map as"), lastMapDir.path(), filter, nullptr,
QFileDialog::DontConfirmOverwrite);
+ std::cout << __func__ << " ok1" << std::endl; // FIXME-2 debugging
if (!fn.isEmpty()) {
// Check for existing file
if (QFile(fn).exists()) {
m->cut();
}
-bool Main::openURL(const QString &url) // FIXME-3 settings for URL and PDF are not really any longer used, only fallback below
+bool Main::openUrl(const QString &url, bool privateMode) // FIXME-3 settings for URL and PDF are not really any longer used, only fallback below
{
- if (url.isEmpty())
- return false;
+ if (url.isEmpty()) {
+ VymModel *m = currentModel();
+ if (m) {
+ QString url = m->getUrl();
+ if (url == "")
+ return false;
+ } else
+ return false;
+ }
+
+ if (privateMode) { // FIXME-3 Currently only Firefox is supported to open private Urls
+ QString browser = settings.value(
+ "/system/readerUrlPrivate",
+ "/Applications/Firefox.app/Contents/MacOS/firefox").toString();
+ QStringList args;
+ args << "--private-window";
+ args << url;
+ if (!QProcess::startDetached(browser, args, QDir::currentPath())) {
+ // try to set path to browser
+ QMessageBox::warning(
+ 0, tr("Warning"),
+ tr("Couldn't find a viewer to open %1.\n").arg(url) +
+ tr("Please use Settings->") +
+ tr("Set application to open an URL"));
+ settingsURL();
+ return false;
+ }
+ return true;
+ }
// Use system settings to open file
bool b = QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode));
if (b) return true;
// Fallback to old vym method to open Url
- QString browser = settings.value("/system/readerURL").toString();
+ QString browser = settings.value("/system/readerUrl").toString();
QStringList args;
args << url;
if (!QProcess::startDetached(browser, args, QDir::currentPath(),
return true;
}
-void Main::openTabs(QStringList urls)
+void Main::openTabs(QStringList urls, bool privateMode)
{
if (urls.isEmpty())
return;
// Other browser, e.g. xdg-open
// Just open all urls and leave it to the system to cope with it
foreach (QString u, urls)
- openURL(u);
+ openUrl(u, privateMode);
}
-void Main::editOpenURL()
-{
- // Open new browser
- VymModel *m = currentModel();
- if (m) {
- QString url = m->getUrl();
- if (url == "")
- return;
- openURL(url);
- }
-}
-void Main::editOpenURLTab()
-{
- VymModel *m = currentModel();
- if (m) {
- QStringList urls;
- urls.append(m->getUrl());
- openTabs(urls);
- }
-}
-
-void Main::editOpenMultipleVisURLTabs(bool ignoreScrolled)
+void Main::editOpenMultipleVisUrls(bool ignoreScrolled, bool privateMode)
{
VymModel *m = currentModel();
if (m) {
QStringList urls;
urls = m->getUrls(ignoreScrolled);
- openTabs(urls);
+ openTabs(urls, privateMode);
}
}
-void Main::editOpenMultipleURLTabs() { editOpenMultipleVisURLTabs(false); }
+void Main::editOpenMultipleUrls() { editOpenMultipleVisUrls(false); }
+
+void Main::editOpenMultipleUrlsPrivate() { editOpenMultipleVisUrls(false, true); }
void Main::editNote2URLs()
{
m->deleteSelection();
}
-void Main::editLoadImage()
+void Main::editLoadImage() // FIXME-2 filter is not used
{
VymModel *m = currentModel();
if (m) {
fd.setNameFilters(filters);
fd.setWindowTitle(vymName + " - " + tr("Load vym script"));
fd.setAcceptMode(QFileDialog::AcceptOpen);
+ fd.show(); // FIXME-2 added to debug #146
+ fd.activateWindow(); // FIXME-2 added to debug #146
if (fd.exec() == QDialog::Accepted) {
if (macros.setPath( fd.selectedFiles().first()))
}
}
-void Main::windowToggleSlideEditors() // FIXME-2 not ported yet like TreeEditor
+void Main::windowToggleSlideEditors()
{
windowSetSlideEditorsVisibility(actionViewToggleSlideEditor->isChecked());
}
selectionToolbar->setEnabled(false);
editorsToolbar->setEnabled(false);
colorsToolbar->setEnabled(false);
- zoomToolbar->setEnabled(false);
+ viewTransformationsToolbar->setEnabled(false);
+ limitedViewToolbar->setEnabled(false);
modModesToolbar->setEnabled(false);
referencesToolbar->setEnabled(false);
standardFlagsToolbar->setEnabled(false);
selectionToolbar->setEnabled(true);
editorsToolbar->setEnabled(true);
colorsToolbar->setEnabled(true);
- zoomToolbar->setEnabled(true);
+ viewTransformationsToolbar->setEnabled(true);
+ limitedViewToolbar->setEnabled(true);
modModesToolbar->setEnabled(true);
referencesToolbar->setEnabled(true);
standardFlagsToolbar->setEnabled(true);
QString url;
if (selti) url = selti->url();
if (url.isEmpty()) {
- actionOpenURL->setEnabled(false);
- actionOpenURLTab->setEnabled(false);
+ actionOpenUrl->setEnabled(false);
actionGetConfluencePageDetails->setEnabled(false);
}
else {
- actionOpenURL->setEnabled(true);
- actionOpenURLTab->setEnabled(true);
+ actionOpenUrl->setEnabled(true);
if (ConfluenceAgent::available())
actionGetConfluencePageDetails->setEnabled(true);
else
standardFlagsMaster->setEnabled(false);
userFlagsMaster->setEnabled(false);
- actionOpenURL->setEnabled(false);
+ actionOpenUrl->setEnabled(false);
actionOpenVymLink->setEnabled(false);
actionOpenVymLinkBackground->setEnabled(false);
actionDeleteVymLink->setEnabled(false);
selectionToolbar->setEnabled(false);
editorsToolbar->setEnabled(false);
colorsToolbar->setEnabled(false);
- zoomToolbar->setEnabled(false);
+ viewTransformationsToolbar->setEnabled(false);
+ limitedViewToolbar->setEnabled(false);
modModesToolbar->setEnabled(false);
referencesToolbar->setEnabled(false);
standardFlagsToolbar->setEnabled(false);
//#include <QStyleFactory>
//qApp->setStyle(QStyleFactory::create("windowsvista"));
+ const char *s1 = "Foo";
+ const char *s2 = "Foo";
+
+ qDebug() << strcmp(s1,s2);
+ return;
+
VymModel *m = currentModel();
if (m) {
m->test();
docname = "vym.pdf";
QStringList searchList;
-#if defined(Q_OS_MACX)
+#if defined(Q_OS_MACOS)
searchList << vymBaseDir.path() + "/doc";
#elif defined(Q_OS_WIN32)
searchList << vymInstallDir.path() + "doc/" + docname;
public slots:
void updateQueries(VymModel *);
- bool openURL(const QString &url);
- void openTabs(QStringList);
- void editOpenURL();
- void editOpenURLTab();
+ bool openUrl(const QString &url = "", bool privateMode = false);
+ void openTabs(QStringList, bool privateMode = false);
private slots:
- void editOpenMultipleVisURLTabs(bool ignoreScrolled = true);
- void editOpenMultipleURLTabs();
+ void editOpenMultipleVisUrls(bool ignoreScrolled = true, bool privateMode = false);
+ void editOpenMultipleUrls();
+ void editOpenMultipleUrlsPrivate();
void editNote2URLs();
void editURL();
void editLocalURL();
QToolBar *selectionToolbar;
QToolBar *editorsToolbar;
QToolBar *colorsToolbar;
- QToolBar *zoomToolbar;
+ QToolBar *viewTransformationsToolbar;
+ QToolBar *limitedViewToolbar;
QToolBar *modModesToolbar;
QToolBar *referencesToolbar;
QToolBar *standardFlagsToolbar;
QAction *actionExpandOneLevel;
QAction *actionCollapseOneLevel;
QAction *actionCollapseUnselected;
- QAction *actionOpenURL;
- QAction *actionOpenURLTab;
- QAction *actionOpenMultipleVisURLTabs;
- QAction *actionOpenMultipleURLTabs;
+ QAction *actionOpenUrl;
+ QAction *actionOpenMultipleVisUrls;
+ QAction *actionOpenMultipleUrls;
+ QAction *actionOpenMultipleUrlsPrivate;
QAction *actionGetURLsFromNote;
QAction *actionURLNew;
QAction *actionLocalURL;
// MapDesign
/////////////////////////////////////////////////////////////////
-MapDesign::MapDesign() // FIXME-1 add options to update styles when relinking (Triggers, Actors)
+MapDesign::MapDesign() // FIXME-3 add options to update styles when relinking (Triggers, Actors)
// Triggers: Never, DepthChanged, Always
// Actors: Inner/Outer-Frames,Fonts,HeadingColor,Rotation Heading/Subtree, ...
{
#include <QApplication>
#include <QGraphicsProxyWidget>
#include <QMenuBar>
+#include <QMessageBox>
#include <QObject>
#include <QPrintDialog>
#include <QPrinter>
extern QString clipboardFile;
extern bool debug;
extern QPrinter *printer;
+extern QDir tmpVymDir;
extern QMenu *branchContextMenu;
extern QMenu *canvasContextMenu;
// systemFlag clicked
if (sysFlagName.contains("system-url") ||
sysFlagName.contains("system-jira") ) {
- if (e->modifiers() & Qt::ControlModifier)
- mainWindow->editOpenURLTab();
- else
- mainWindow->editOpenURL();
+
+ // Open in private mode if ALT is pressed
+ mainWindow->openUrl(
+ model->getUrl(),
+ e->modifiers() & Qt::AltModifier);
} else if (sysFlagName == "system-note")
mainWindow->windowToggleNoteEditor();
else if (sysFlagName == "hideInExport")
qDebug() << "-------------------------------------------";
}
- if (event->mimeData()->hasUrls()) {
+ if (event->mimeData()->hasImage()) {
+ QImage image = qvariant_cast<QImage>(event->mimeData()->imageData());
+ QTemporaryFile tmpFile(tmpVymDir.path() + "/pasted-image-XXXXXX");
+ tmpFile.setAutoRemove( false); // tmpFile is within tmpDir, removed automatically later
+ if (!tmpFile.open())
+ QMessageBox::warning(0, tr("Warning"),
+ "Couldn't open tmpFile " + tmpFile.fileName());
+ else {
+ image.save(tmpFile.fileName(), "PNG", 100);
+ model->loadImage(selbi, tmpFile.fileName());
+ }
+
+ } else if (event->mimeData()->hasUrls()) {
// Try text representation first, which works on windows, but in
// Linux only for https, not local images
QString url = event->mimeData()->text();
extern QFont fixedFont;
extern QFont varFont;
extern QString iconTheme;
-
+extern QColor vymForegroundColor;
+extern QColor vymBaseColor;
extern QAction *actionViewToggleNoteEditor;
extern QString vymName;
TextEditor::TextEditor(const QString eName) // FEATURE #137 insert images with drag & drop
// https://stackoverflow.com/questions/3254652/several-ways-of-placing-an-image-in-a-qtextedit
{
+ //qDebug() << "TE::constr of " << eName;
statusBar()->hide(); // Hide sizeGrip on default, which comes with statusBar
editor = new QTextEdit(this);
connect(editor, SIGNAL(currentCharFormatChanged(const QTextCharFormat &)), this,
SLOT(formatChanged(const QTextCharFormat &)));
- // Don't show menubar per default
- menuBar()->hide();
-
// Load settings
init (eName);
setWindowIcon(QPixmap(":/vym-editor.png"));
// Various states
+ richTextMode = false;
blockChangedSignal = false;
blockTextUpdate = false;
setInactive();
editorName = "Text editor";
setEditorTitle("");
+
+ menuBar()->setNativeMenuBar(false);
}
TextEditor::~TextEditor()
{
shortcutScope = scope;
+ QString n = QString("/satellite/%1/").arg(shortcutScope);
+ colorRichTextEditorBackground = QColor::fromString(
+ settings.value(n + "colors/richTextEditorBackground", vymBaseColor.name()).toString());
+
+ colorRichTextForeground = QColor::fromString(
+ settings.value(n + "colors/richTextForeground", vymForegroundColor.name()).toString());
+
+ colorRichTextBackground = QColor::fromString(
+ settings.value(n + "colors/richTextBackground", vymBaseColor.name()).toString());
+
+ /*
+ qDebug() << "TE::init" << scope;
+ qDebug() << " TEBG=" << colorRichTextEditorBackground.name() << vymBaseColor.name();
+ qDebug() << " RTFG=" << colorRichTextForeground.name() << vymForegroundColor.name();
+ qDebug() << " RTBG=" << colorRichTextBackground.name();
+ */
+
// Toolbars
setupFileActions();
setupEditActions();
setupFormatActions();
setupSettingsActions();
- QString n = QString("/satellite/%1/").arg(shortcutScope);
restoreState(settings.value(n + "state", 0).toByteArray());
+
filenameHint = "";
fixedFontInt = fixedFont;
varFontInt = varFont;
editor->setCurrentFont(varFontInt);
}
- // Default colors for RichText
- QPixmap pix(16, 16);
- colorRichTextEditorBackground.fromString(
- settings.value(n + "colors/richTextEditorBackground", "#ffffff").toString());
- pix.fill(colorRichTextEditorBackground);
- actionActiveEditorBGColor->setIcon(pix);
-
-
- colorRichTextForeground.fromString(
- settings.value(n + "colors/richTextForeground", "#000000").toString());
- pix.fill(colorRichTextForeground);
- actionRichTextFGColor->setIcon(pix);
-
- colorRichTextBackground.fromString(
- settings.value(n + "colors/richTextBackground", "#000000").toString());
- pix.fill(colorRichTextBackground);
- actionRichTextBGColor->setIcon(pix);
-
// Default is PlainText
actionFormatRichText->setChecked(false);
+
+ // Hide RichText format actions on default
+ setRichTextMode(false);
+
clear();
}
actionFileDeleteAll = a;
}
-void TextEditor::setupEditActions() // FIXME-2 Rework (default) toolbars and RT colors
+void TextEditor::setupEditActions()
{
QString tag = tr("Texteditor", "Shortcuts");
QToolBar *editToolBar = addToolBar(tr("Edit Actions"));
connect(a, SIGNAL(triggered()), this, SLOT(toggleRichText()));
formatMenu->addAction(a);
fontHintsToolBar->addAction(a);
- filledEditorActions << a;
+ //filledEditorActions << a;
actionFormatRichText = a;
+ addToolBarBreak();
+
fontToolBar = addToolBar(tr("Fonts", "toolbar in texteditor"));
fontToolBar->setObjectName("noteEditorFontToolBar");
formatMenu->addSeparator();
+ addToolBarBreak();
+
formatToolBar = addToolBar(tr("Format", "toolbar in texteditor"));
formatToolBar->setObjectName("noteEditorFormatToolBar");
- QPixmap pix(16, 16);
- pix.fill(editor->textColor());
- a = new QAction(pix, tr("&Text Color..."), this);
+ //QPixmap pix(16, 16);
+ //pix.fill(editor->textColor());
+ //a = new QAction(pix, tr("&Text Color..."), this);
+ a = new QAction(tr("&Text Color..."), this);
formatMenu->addAction(a);
formatToolBar->addAction(a);
connect(a, SIGNAL(triggered()), this, SLOT(selectTextFGColor()));
filledEditorRichTextActions << a;
actionTextFGColor = a;
- pix.fill(editor->textBackgroundColor());
- a = new QAction(pix, tr("&Text highlight color..."), this);
+ //pix.fill(editor->textBackgroundColor());
+ //a = new QAction(pix, tr("&Text background color..."), this);
+ a = new QAction(tr("&Text background color..."), this);
formatMenu->addAction(a);
formatToolBar->addAction(a);
connect(a, SIGNAL(triggered()), this, SLOT(selectTextBGColor()));
void TextEditor::setRichText(const QString &t)
{
blockChangedSignal = true;
+ richTextMode = true;
editor->setReadOnly(false);
editor->setHtml(t);
actionFormatRichText->setChecked(true);
void TextEditor::setPlainText(const QString &t)
{
blockChangedSignal = true;
+ richTextMode = false;
editor->setReadOnly(false);
editor->setPlainText(t);
// Reset also text format
QTextCharFormat textformat;
- textformat.setForeground(qApp->palette().color(QPalette::WindowText));
+ textformat.setForeground(vymForegroundColor);
textformat.setFont(varFontInt);
editor->setCurrentCharFormat(textformat);
void TextEditor::setRichTextMode(bool b)
{
- //qDebug() << "TE::setRichTextMode b=" << b;
- actionFormatUseFixedFont->setEnabled(false);
if (b) {
setRichText(editor->toHtml());
editor->setTextColor(colorRichTextForeground);
editor->setTextBackgroundColor(colorRichTextBackground);
editor->setTextCursor(cursor);
-
} else {
setPlainText(editor->toPlainText());
+ QTextCursor cursor = editor->textCursor();
+ editor->selectAll();
+ editor->setTextColor(qApp->palette().color(QPalette::WindowText));
+ editor->setTextBackgroundColor(QColor::fromString("00000000"));
+ editor->setTextCursor(cursor);
}
emit textHasChanged(getVymText());
}
void TextEditor::selectTextFGColor()
{
- QColor col = QColorDialog::getColor(editor->textColor(), this);
+ QColor col = QColorDialog::getColor(
+ editor->textColor(),
+ this,
+ tr("Text color","TextEditor windows"),
+ QColorDialog::ShowAlphaChannel);
if (!col.isValid())
return;
editor->setTextColor(col);
- /*
- QPixmap pix( 16, 16 );
- pix.fill( col );
- actionTextColor->setIcon( pix );
- */
}
void TextEditor::selectTextBGColor()
{
- QColor col = QColorDialog::getColor(editor->textBackgroundColor(), this);
+ QColor col = QColorDialog::getColor(
+ editor->textBackgroundColor(),
+ this,
+ tr("Text background color","TextEditor windows"),
+ QColorDialog::ShowAlphaChannel);
if (!col.isValid())
return;
editor->setTextBackgroundColor(col);
- /*
- QPixmap pix( 16, 16 );
- pix.fill( col );
- actionTextColor->setIcon( pix );
- */
}
void TextEditor::textAlign(QAction *a)
a->setEnabled(false);
foreach (QAction* a, filledEditorRichTextActions)
a->setEnabled(false);
+
+ fontToolBar->hide();
+ formatToolBar->hide();
+ actionFormatUseFixedFont->setEnabled(false);
+ actionFormatRichText->setEnabled(false);
return;
}
b = (state == filledEditor && actionFormatRichText->isChecked()) ? true : false;
foreach (QAction* a, filledEditorRichTextActions)
a->setEnabled(b);
+
+ actionFormatRichText->setEnabled(true);
+ if (richTextMode) {
+ actionFormatUseFixedFont->setEnabled(false); // FIXME-3 Maybe even hide it in RT mode
+ fontToolBar->show();
+ formatToolBar->show();
+ } else {
+ actionFormatUseFixedFont->setEnabled(true);
+ fontToolBar->hide();
+ formatToolBar->hide();
+ }
}
void TextEditor::setState(EditorState s)
else
baseColor = colorRichTextEditorBackground;
} else {
- baseColor = p.color(QPalette::Base);
+ baseColor = vymBaseColor;
}
editor->setReadOnly(false);
break;
void TextEditor::selectRichTextEditorBackgroundColor()
{
- QColor col = QColorDialog::getColor(colorRichTextEditorBackground, nullptr);
+ QColor col = QColorDialog::getColor(
+ colorRichTextEditorBackground,
+ nullptr,
+ tr("Text editor background color","TextEditor windows"),
+ QColorDialog::ShowAlphaChannel);
if (!col.isValid())
return;
colorRichTextEditorBackground = col;
void TextEditor::selectRichTextForegroundColor()
{
- QColor col = QColorDialog::getColor(colorRichTextForeground, nullptr);
+ QColor col = QColorDialog::getColor(
+ colorRichTextForeground,
+ nullptr,
+ tr("Text editor default text color","TextEditor windows"),
+ QColorDialog::ShowAlphaChannel);
setRichTextForegroundColor(col);
}
void TextEditor::selectRichTextBackgroundColor()
{
- QColor col = QColorDialog::getColor(colorRichTextBackground, nullptr);
+ QColor col = QColorDialog::getColor(
+ colorRichTextBackground,
+ nullptr,
+ tr("Text editor default text background color","TextEditor windows"),
+ QColorDialog::ShowAlphaChannel);
setRichTextBackgroundColor(col);
}
bool blockChangedSignal;
bool blockTextUpdate; // Set *while* textHasChanged is still being emitted
+ bool richTextMode;
+
QColor colorRichTextEditorBackground;
QColor colorRichTextBackground;
QColor colorRichTextForeground;
#ifndef VERSION_H
#define VERSION_H
-#define __VYM_VERSION "2.9.577"
-#define __VYM_BUILD_DATE "2025-06-24"
+#define __VYM_VERSION "2.9.581"
+#define __VYM_BUILD_DATE "2025-07-04"
#define __VYM_NAME "VYMng" // FIXME "next generation" in in window title
#define __VYM_HOME "http://www.insilmaril.de/vym"
//
//#define __VYM_CODE_QUALITY "Production"
-//#define __VYM_CODE_QUALITY "*Experimental*"
-#define __VYM_CODE_QUALITY "*Beta*"
-#define __VYM_CODENAME "Beta release of upcoming 3.0.0"
+#define __VYM_CODE_QUALITY "*Experimental*"
+//#define __VYM_CODE_QUALITY "*Beta*"
+//#define __VYM_CODENAME "Beta release of upcoming 3.0.0"
+#define __VYM_CODENAME "Debug version of upcoming 33.0.0"
#endif
extern QTextStream vout;
extern bool usingDarkTheme;
-extern QColor vymBlue;
+extern QColor vymBlueColor;
uint VymModel::idLast = 0; // make instance
setScale(- 0.05, true);
}
-void VymModel::resetSelectionSize() // FIXME-3 missing saveState. Switch (back?) to autodesign?
+void VymModel::resetSelectionSize()
{
- ImageItem *selii = getSelectedImage();
- if (selii)
- setScale(1, false);
+ setScale(1, false);
}
-void VymModel::setBranchesLayout(const QString &s, BranchItem *bi) // FIXME-2 no saveState yet (save: positions, auto, layout!)
+void VymModel::setBranchesLayout(const QString &s, BranchItem *bi)
{
// qDebug() << "VM::setBranchesLayout for " << headingText(bi) << s;
QList<BranchItem *> selbis = getSelectedBranches(bi);
// Get layout from mapDesign
layout = mapDesignInt->branchesContainerLayout(selbi->depth());
- if (bc->branchesContainerLayout() != layout)
- bc->setBranchesContainerLayout(layout);
} else {
bc->branchesContainerAutoLayout = false;
layout = Container::layoutFromString(s);
- if (layout != Container::UndefinedLayout)
- bc->setBranchesContainerLayout(layout);
}
- emitDataChanged(selbi);
+ if (bc->branchesContainerLayout() != layout && layout != Container::UndefinedLayout) {
+ QString bv = setBranchVar(bi);
+ QString uc = bv + "map.loadBranchReplace(\"UNDO_PATH\", b);";
+ QString rc = bv + QString("b.setBranchesLayout (\"%1\")").arg(s);
+ QString com = QString("Set branches layout of %1 to %2").arg(getObjectName(bi), layout);
+ logAction(rc, com, __func__);
+
+ saveState(uc, rc, com, bi);
+
+ bc->setBranchesContainerLayout(layout);
+ emitDataChanged(selbi);
+ }
}
// Links might have been added or removed, Nested lists, etc...
}
-void VymModel::setImagesLayout(const QString &s, BranchItem *bi) // FIXME-2 no saveState yet (save positions, too!)
+void VymModel::setImagesLayout(const QString &s, BranchItem *bi)
{
BranchContainer *bc;
QList<BranchItem *> selbis = getSelectedBranches(bi);
foreach (BranchItem *selbi, selbis) {
+ Container::Layout layout;
bc = selbi->getBranchContainer();
if (s == "Auto") {
bc->imagesContainerAutoLayout = true;
- bc->setImagesContainerLayout(
- mapDesignInt->imagesContainerLayout(selbi->depth()));
+ layout = mapDesignInt->imagesContainerLayout(selbi->depth());
} else {
bc->imagesContainerAutoLayout = false;
- Container::Layout layout;
layout = Container::layoutFromString(s);
- if (layout != Container::UndefinedLayout)
- bc->setImagesContainerLayout(layout);
}
- emitDataChanged(selbi);
+
+ if (bc->imagesContainerLayout() != layout && layout != Container::UndefinedLayout) {
+ QString bv = setBranchVar(selbi);
+ QString uc = bv + "map.loadBranchReplace(\"UNDO_PATH\", b);";
+ QString rc = bv + QString("b.setImagesLayout (\"%1\")").arg(s);
+ QString com = QString("Set images layout of %1 to %2").arg(getObjectName(selbi), s);
+ logAction(rc, com, __func__);
+
+ saveState(uc, rc, com, selbi);
+
+ bc->setImagesContainerLayout(layout);
+ emitDataChanged(selbi);
+ }
}
if (!selbis.isEmpty()) {
QString keyName = ji.key();
if (ji.isFinished()) {
keyName = "(" + keyName + ")";
- colorSubtree (vymBlue, bi);
+ colorSubtree (vymBlueColor, bi);
}
setHeadingPlainText(keyName + ": " + ji.summary(), bi);
QString keyName = ji.key();
if (ji.isFinished()) {
keyName = "(" + keyName + ")";
- colorSubtree (vymBlue, bi2);
+ colorSubtree (vymBlueColor, bi2);
}
setHeadingPlainText(keyName + ": " + ji.summary(), bi2);
return mapDesignInt;
}
-void VymModel::applyDesign( // FIXME-1 Check handling of autoDesign option
+void VymModel::applyDesign( // FIXME-2 Check handling of autoDesign option
MapDesign::UpdateMode updateMode,
BranchItem *bi)
{
return;
}
- // FIXME-3 download img to tmpfile and delete after running script in
- // mainWindow
+ // FIXME-4 delete tmp file of image download after running script
QString script;
- script += QString("m = vym.currentMap();m.selectID(\"%1\");")
+ script += QString("m = vym.currentMap();b = m.findBranchBySelection(\"%1\");")
.arg(bi->getUuid().toString());
- script += QString("m.loadImage(\"$TMPFILE\");");
+ script += QString("b.loadImage(\"$TMPFILE\");");
DownloadAgent *agent = new DownloadAgent(url);
agent->setFinishedAction(this, script);
#!/bin/bash
-SRCDIR=test
+SRCDIR=$PWD
VYMTESTDIR=$(mktemp -d /tmp/vym-test-XXXX)
-DEFAULTMAP=$SRCDIR/test/default.vym
+DEFAULTMAP=$SRCDIR/test/maps/test-default.vym
TESTMAP=$VYMTESTDIR/testmap.vym
echo Copying $DEFAULTMAP to $TESTMAP
cp $DEFAULTMAP $TESTMAP
-vym -l -t -n test -R test/vym-selftest.vys $TESTMAP -geometry 768x576-0+0 &
+echo "Copy ok. $PWD"
+vym -l -t -n test -R test/vym-selftest.vys $TESTMAP #-geometry 768x576-0+0 &
+#vym -l -t -n test -R test/vym-selftest.vys $TESTMAP -geometry 768x576-0+0 &
#PID=$!
"extrainfo",
"frames",
"history",
+ "layouts",
"load_legacy_maps",
"mapdesign",
"modify_branches",
];
tests = all_tests;
-//tests = ["scrolling"];
+//tests = ["layouts"];
var verbosity = 0;
var vymBaseDir = vym.vymBaseDir();
-var testDir = vymBaseDir + "/selftests";
+var testDirName = "selftests";
+var testDir = vymBaseDir + "/" + testDirName;
var currentMapPath = "undefined."
var testMapDefault = vymBaseDir + "/test/maps/test-default.vym";
var testMapFrames = vymBaseDir + "/test/maps/test-frames.vym";
closeCurrentMap();
}
+function test_layouts()
+{
+ heading("Layouts");
+
+ map = initMap(testMapDefault);
+
+ // branchesContainerLayout
+ b = map.findBranchBySelection(main_A_string);
+ expect("Initial branches layout is vertical", b.getBranchesLayout(), "Vertical");
+
+ layout = "Horizontal";
+ b.setBranchesLayout(layout);
+ expect(layout + " layout of branches in subtree", b.getBranchesLayout(), layout);
+ map.undo();
+ b = map.findBranchBySelection(main_A_string);
+ expect("After undo layout of branches in subtree is Vertical", b.getBranchesLayout(), "Vertical");
+
+ map.redo();
+ b = map.findBranchBySelection(main_A_string);
+ expect("After redo layout of branches in subtree is " + layout, b.getBranchesLayout(), layout);
+
+ // imagesContainerLayout
+ b = map.findBranchBySelection(branch_0Aa_string);
+ n = b.imageCount();
+
+ success = b.loadImage(vymBaseDir + "/icons/vym.png");
+ expect("loadImage() returns true for first image", success, true);
+ expect("Image count increased after for first image loading", b.imageCount(), n + 1);
+
+ success = b.loadImage(vymBaseDir + "/icons/vym.png");
+ expect("loadImage() returns true for second image", success, true);
+ expect("Image count increased after for second image loading", b.imageCount(), n + 2);
+
+ expect("Initial images layout is grid", b.getImagesLayout(), "GridColumns");
+
+ layout = "Vertical";
+ b.setImagesLayout(layout);
+ expect(layout + " layout of images", b.getImagesLayout(), layout);
+
+ map.undo();
+ b = map.findBranchBySelection(branch_0Aa_string);
+ expect("After undo layout of images is restored", b.getImagesLayout(), "GridColumns");
+
+ map.redo();
+ b = map.findBranchBySelection(branch_0Aa_string);
+ expect("After redo layout of images is " + layout, b.getImagesLayout(), layout);
+
+ closeCurrentMap();
+}
+
function test_load_legacy_maps()
{
heading("Load legacy maps");
success = b.loadImage(vymBaseDir + "/icons/vym.png");
expect("loadImage() returns true for existing image", success, true);
- expect("Image cound increased after loading", b.imageCount(), n + 1);
+ expect("Image count increased after loading", b.imageCount(), n + 1);
success = b.loadImage(vymBaseDir + "/foobar");
expect("loadImage() returns false for not existing image", success, false);
expect("setUrl: unset Url with empty string", main_A.getUrl(), "");
// Try to link to myself using a relative path
- vl = "selftests/maps/current-map.vym";
+ vl = testDirName + "/maps/current-map.vym";
main_A.setVymLink(vl);
s = main_A.getVymLink();
expect("setVymLink returns absolute path", map.getFileDir() + "/" + vl, s);
if (tests.includes("extrainfo")) { test_extrainfo(); }
if (tests.includes("frames")) { test_frames(); }
if (tests.includes("history")) { test_history(); }
+if (tests.includes("layouts")) { test_layouts(); }
if (tests.includes("load_legacy_maps")) { test_load_legacy_maps(); }
if (tests.includes("mapdesign")) { test_mapdesign(); }
if (tests.includes("modify_branches")) { test_modify_branches(); }