Commit efb80dc6 authored by Tobias WEBER's avatar Tobias WEBER
Browse files

started with script plugins

parent 4bb0d7a3
......@@ -40,6 +40,7 @@ ext/**
plugins/**
!ext/.dir
!plugins/.dir
!plugins/qtas.py
# Temporary files
tmp/**
......
../tools/tascalc/qtas.py
\ No newline at end of file
......@@ -416,94 +416,148 @@ void MainWnd::LoadPlugins()
while(iter.hasNext())
{
std::string dllfile = iter.next().toStdString();
std::string fileext = tl2::get_fileext(dllfile, true);
std::string rawfile = tl2::get_file_nodir(dllfile, false);
if(rawfile == "." || rawfile == "..")
continue;
try
if(fileext == "so" || fileext == "dll" || fileext == "dylib")
{
auto dll = std::make_shared<boost::dll::shared_library>(dllfile);
if(!dll || !dll->is_loaded())
try
{
print_err("Could not load plugin \"", dllfile, "\".");
continue;
}
auto dll = std::make_shared<boost::dll::shared_library>(dllfile);
if(!dll || !dll->is_loaded())
{
print_err("Could not load plugin \"", dllfile, "\".");
continue;
}
if(!dll->has("tl_descr") || !dll->has("tl_init") || !dll->has("tl_create") || !dll->has("tl_destroy"))
{
print_err("Not a valid plugin: \"", dllfile, "\".");
continue;
}
if(!dll->has("tl_descr") || !dll->has("tl_init") || !dll->has("tl_create") || !dll->has("tl_destroy"))
{
print_err("Not a valid plugin: \"", dllfile, "\".");
continue;
}
PluginDlg plugin;
plugin.dll = dll;
PluginDlg plugin;
plugin.dll = dll;
// plugin functions
plugin.f_descr = dll->get<PluginDlg::t_descr>("tl_descr");
plugin.f_init = dll->get<PluginDlg::t_init>("tl_init");
plugin.f_create = dll->get<PluginDlg::t_create>("tl_create");
plugin.f_destroy = dll->get<PluginDlg::t_destroy>("tl_destroy");
// plugin functions
plugin.f_descr = dll->get<PluginDlg::t_descr>("tl_descr");
plugin.f_init = dll->get<PluginDlg::t_init>("tl_init");
plugin.f_create = dll->get<PluginDlg::t_create>("tl_create");
plugin.f_destroy = dll->get<PluginDlg::t_destroy>("tl_destroy");
// plugin descriptors
// plugin descriptors
{
std::vector<std::string> vecdescr;
tl2::get_tokens<std::string, std::string>(plugin.f_descr(), ";", vecdescr);
plugin.name = vecdescr[1];
plugin.descr = vecdescr[2];
// only accept dialog plugins
if(vecdescr[0] != "dlg")
continue;
// skip plugin if another one with the same name is already registered
if(std::find_if(m_plugin_dlgs.begin(), m_plugin_dlgs.end(),
[&plugin](const PluginDlg& otherplugin) -> bool
{
return otherplugin.name == plugin.name;
}) != m_plugin_dlgs.end())
continue;
// add menu item
auto *acTool = new QAction(plugin.name.c_str(), m_pMenu);
acTool->setToolTip(plugin.descr.c_str());
m_pmenuPluginTools->addAction(acTool);
const std::size_t pluginNr = m_plugin_dlgs.size();
connect(acTool, &QAction::triggered, this, [this, pluginNr]()
{
if(pluginNr >= m_plugin_dlgs.size())
{
print_err("Invalid plugin number ", pluginNr, ".");
return;
}
// get plugin corresponding to this menu item
auto& plugin = m_plugin_dlgs[pluginNr];
if(!plugin.inited)
plugin.inited = plugin.f_init();
if(plugin.inited && !plugin.dlg)
plugin.dlg = plugin.f_create(this);
if(plugin.dlg)
{
plugin.dlg->show();
plugin.dlg->activateWindow();
plugin.dlg->raise();
plugin.dlg->setFocus();
}
});
print_out("Tool plugin ", dll->location(), " loaded. ",
"name: \"", plugin.name, "\", ",
"description: \"", plugin.descr, "\".");
m_plugin_dlgs.emplace_back(std::move(plugin));
}
}
catch(const std::exception& ex)
{
std::vector<std::string> vecdescr;
tl2::get_tokens<std::string, std::string>(plugin.f_descr(), ";", vecdescr);
print_err("Error loading plugin \"", dllfile, "\": ", ex.what(), ".");
}
} // dialog plugins in so libraries
else if(fileext == "py")
{
std::ifstream ifstr(dllfile);
if(!ifstr)
continue;
plugin.ty = vecdescr[0];
plugin.name = vecdescr[1];
plugin.descr = vecdescr[2];
PluginScr plugin;
bool bHasName = false;
// skip plugin if another one with the same name is already registered
if(std::find_if(m_plugin_dlgs.begin(), m_plugin_dlgs.end(),
[&plugin](const PluginDlg& otherplugin) -> bool
{
return otherplugin.name == plugin.name;
}) != m_plugin_dlgs.end())
std::string line;
while(std::getline(ifstr, line))
{
tl2::trim(line);
// looking for plugin descriptors in header comments
if(line.size()==0 || line[0]!='#')
continue;
// add menu item
auto *acTool = new QAction(plugin.name.c_str(), m_pMenu);
acTool->setToolTip(plugin.descr.c_str());
m_pmenuPluginTools->addAction(acTool);
const std::size_t pluginNr = m_plugin_dlgs.size();
connect(acTool, &QAction::triggered, this, [this, pluginNr]()
if(line.find("__ident__") != std::string::npos)
{
if(pluginNr >= m_plugin_dlgs.size())
{
print_err("Invalid plugin number ", pluginNr, ".");
return;
}
std::tie(std::ignore, plugin.name) = tl2::split_first<std::string>(line, ":", true, false);
bHasName = true;
}
else if(line.find("__descr__") != std::string::npos)
{
std::tie(std::ignore, plugin.descr) = tl2::split_first<std::string>(line, ":", true, false);
}
}
// not a recognised script plugin
if(!bHasName)
continue;
// get plugin corresponding to this menu item
auto& plugin = m_plugin_dlgs[pluginNr];
if(!plugin.inited)
plugin.inited = plugin.f_init();
// skip plugin if another one with the same name is already registered
if(std::find_if(m_plugin_scr.begin(), m_plugin_scr.end(),
[&plugin](const PluginScr& otherplugin) -> bool
{
return otherplugin.name == plugin.name;
}) != m_plugin_scr.end())
continue;
if(plugin.inited && !plugin.dlg)
plugin.dlg = plugin.f_create(this);
// TODO: Add menu item
if(plugin.dlg)
{
plugin.dlg->show();
plugin.dlg->activateWindow();
plugin.dlg->raise();
plugin.dlg->setFocus();
}
});
print_out("Plugin ", dll->location(), " loaded. ",
"Module type: \"", plugin.ty, "\", ",
"name: \"", plugin.name, "\", ",
"description: \"", plugin.descr, "\".");
m_plugin_dlgs.emplace_back(std::move(plugin));
}
}
catch(const std::exception& ex)
{
print_err("Error loading plugin \"", dllfile, "\": ", ex.what(), ".");
}
print_out("Script plugin \"", dllfile, "\" loaded. ",
"name: \"", plugin.name, "\", ",
"description: \"", plugin.descr, "\".");
m_plugin_scr.emplace_back(std::move(plugin));
} // py script plugins
}
}
}
......
......@@ -31,7 +31,7 @@
struct PluginDlg
{
std::shared_ptr<boost::dll::shared_library> dll;
std::string ty, name, descr;
std::string name, descr;
bool inited = false;
using t_descr = const char*(*)();
......@@ -49,6 +49,16 @@ struct PluginDlg
/**
* script plugins
*/
struct PluginScr
{
std::string name, descr;
};
/**
* main dialog
*/
......@@ -71,7 +81,8 @@ private:
QStringList m_recentFiles;
QString m_curFile;
std::vector<PluginDlg> m_plugin_dlgs;
std::vector<PluginDlg> m_plugin_dlgs; // tool/dialog plugins
std::vector<PluginScr> m_plugin_scr; // callable script plugins
protected:
virtual void showEvent(QShowEvent *pEvt) override;
......
......@@ -4,6 +4,9 @@
# @date 24-oct-18
# @license see 'LICENSE' file
#
# __ident__ : TAS Calculator
# __descr__ : Calculates triple-axis angles.
#
# -----------------------------------------------------------------------------
# dependencies
......@@ -38,9 +41,12 @@ np.set_printoptions(suppress=True, precision=4)
app = qtw.QApplication(sys.argv)
app.setApplicationName("qtas")
app.setStyle("Fusion")
#app.setStyle("Fusion")
sett = qtc.QSettings("tobis_stuff", "in20tool")
if sett.contains("mainwnd/theme"):
app.setStyle(sett.value("mainwnd/theme"))
sett = qtc.QSettings("tobis_stuff", "qtas")
tabs = qtw.QTabWidget()
# -----------------------------------------------------------------------------
......@@ -147,18 +153,18 @@ editBy.textEdited.connect(planeChanged)
editBz.textEdited.connect(planeChanged)
editA.setText("%.6g" % sett.value("a", 5., type=float))
editB.setText("%.6g" % sett.value("b", 5., type=float))
editC.setText("%.6g" % sett.value("c", 5., type=float))
editAlpha.setText("%.6g" % sett.value("alpha", 90., type=float))
editBeta.setText("%.6g" % sett.value("beta", 90., type=float))
editGamma.setText("%.6g" % sett.value("gamma", 90., type=float))
editAx.setText("%.6g" % sett.value("ax", 1., type=float))
editAy.setText("%.6g" % sett.value("ay", 0., type=float))
editAz.setText("%.6g" % sett.value("az", 0., type=float))
editBx.setText("%.6g" % sett.value("bx", 0., type=float))
editBy.setText("%.6g" % sett.value("by", 1., type=float))
editBz.setText("%.6g" % sett.value("bz", 0., type=float))
editA.setText("%.6g" % sett.value("qtas/a", 5., type=float))
editB.setText("%.6g" % sett.value("qtas/b", 5., type=float))
editC.setText("%.6g" % sett.value("qtas/c", 5., type=float))
editAlpha.setText("%.6g" % sett.value("qtas/alpha", 90., type=float))
editBeta.setText("%.6g" % sett.value("qtas/beta", 90., type=float))
editGamma.setText("%.6g" % sett.value("qtas/gamma", 90., type=float))
editAx.setText("%.6g" % sett.value("qtas/ax", 1., type=float))
editAy.setText("%.6g" % sett.value("qtas/ay", 0., type=float))
editAz.setText("%.6g" % sett.value("qtas/az", 0., type=float))
editBx.setText("%.6g" % sett.value("qtas/bx", 0., type=float))
editBy.setText("%.6g" % sett.value("qtas/by", 1., type=float))
editBz.setText("%.6g" % sett.value("qtas/bz", 0., type=float))
xtallayout.addWidget(qtw.QLabel(u"a (\u212b):", xtalpanel), 0,0, 1,1)
xtallayout.addWidget(editA, 0,1, 1,3)
......@@ -356,14 +362,14 @@ editKf.textEdited.connect(KiKfChanged)
editE.textEdited.connect(EChanged)
editDm.setText("%.6g" % sett.value("dm", 3.355, type=float))
editDa.setText("%.6g" % sett.value("da", 3.355, type=float))
edith.setText("%.6g" % sett.value("h", 1., type=float))
editk.setText("%.6g" % sett.value("k", 0., type=float))
editl.setText("%.6g" % sett.value("l", 0., type=float))
#editE.setText("%.6g" % sett.value("E", 0., type=float))
editKi.setText("%.6g" % sett.value("ki", 2.662, type=float))
editKf.setText("%.6g" % sett.value("kf", 2.662, type=float))
editDm.setText("%.6g" % sett.value("qtas/dm", 3.355, type=float))
editDa.setText("%.6g" % sett.value("qtas/da", 3.355, type=float))
edith.setText("%.6g" % sett.value("qtas/h", 1., type=float))
editk.setText("%.6g" % sett.value("qtas/k", 0., type=float))
editl.setText("%.6g" % sett.value("qtas/l", 0., type=float))
#editE.setText("%.6g" % sett.value("qtas/E", 0., type=float))
editKi.setText("%.6g" % sett.value("qtas/ki", 2.662, type=float))
editKf.setText("%.6g" % sett.value("qtas/kf", 2.662, type=float))
Qlayout.addWidget(qtw.QLabel("h (rlu):", Qpanel), 0,0, 1,1)
Qlayout.addWidget(edith, 0,1, 1,2)
......@@ -408,7 +414,7 @@ infolayout = qtw.QGridLayout(infopanel)
comboA3 = qtw.QComboBox(infopanel)
comboA3.addItems(["Takin", "NOMAD", "SICS", "NICOS"])
a3_offs = [np.pi/2., np.pi, 0., 0.]
comboA3.setCurrentIndex(sett.value("a3_conv", 1, type=int))
comboA3.setCurrentIndex(sett.value("qtas/a3_conv", 1, type=int))
def comboA3ConvChanged():
idx = comboA3.currentIndex()
......@@ -446,8 +452,8 @@ dlg.setWindowTitle("TAS Calculator")
mainlayout = qtw.QGridLayout(dlg)
mainlayout.addWidget(tabs)
if sett.contains("geo"):
geo = sett.value("geo")
if sett.contains("qtas/geo"):
geo = sett.value("qtas/geo")
if qt_ver == 4:
geo = geo.toByteArray()
dlg.restoreGeometry(geo)
......@@ -462,26 +468,26 @@ app.exec_()
# save settings
sett.setValue("a", getfloat(editA.text()))
sett.setValue("b", getfloat(editB.text()))
sett.setValue("c", getfloat(editC.text()))
sett.setValue("alpha", getfloat(editAlpha.text()))
sett.setValue("beta", getfloat(editBeta.text()))
sett.setValue("gamma", getfloat(editGamma.text()))
sett.setValue("ax", getfloat(editAx.text()))
sett.setValue("ay", getfloat(editAy.text()))
sett.setValue("az", getfloat(editAz.text()))
sett.setValue("bx", getfloat(editBx.text()))
sett.setValue("by", getfloat(editBy.text()))
sett.setValue("bz", getfloat(editBz.text()))
sett.setValue("dm", getfloat(editDm.text()))
sett.setValue("da", getfloat(editDa.text()))
sett.setValue("h", getfloat(edith.text()))
sett.setValue("k", getfloat(editk.text()))
sett.setValue("l", getfloat(editl.text()))
#sett.setValue("E", getfloat(editE.text()))
sett.setValue("ki", getfloat(editKi.text()))
sett.setValue("kf", getfloat(editKf.text()))
sett.setValue("a3_conv", comboA3.currentIndex())
sett.setValue("geo", dlg.saveGeometry())
sett.setValue("qtas/a", getfloat(editA.text()))
sett.setValue("qtas/b", getfloat(editB.text()))
sett.setValue("qtas/c", getfloat(editC.text()))
sett.setValue("qtas/alpha", getfloat(editAlpha.text()))
sett.setValue("qtas/beta", getfloat(editBeta.text()))
sett.setValue("qtas/gamma", getfloat(editGamma.text()))
sett.setValue("qtas/ax", getfloat(editAx.text()))
sett.setValue("qtas/ay", getfloat(editAy.text()))
sett.setValue("qtas/az", getfloat(editAz.text()))
sett.setValue("qtas/bx", getfloat(editBx.text()))
sett.setValue("qtas/by", getfloat(editBy.text()))
sett.setValue("qtas/bz", getfloat(editBz.text()))
sett.setValue("qtas/dm", getfloat(editDm.text()))
sett.setValue("qtas/da", getfloat(editDa.text()))
sett.setValue("qtas/h", getfloat(edith.text()))
sett.setValue("qtas/k", getfloat(editk.text()))
sett.setValue("qtas/l", getfloat(editl.text()))
#sett.setValue("qtas/E", getfloat(editE.text()))
sett.setValue("qtas/ki", getfloat(editKi.text()))
sett.setValue("qtas/kf", getfloat(editKf.text()))
sett.setValue("qtas/a3_conv", comboA3.currentIndex())
sett.setValue("qtas/geo", dlg.saveGeometry())
# -----------------------------------------------------------------------------
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment