backend/wbprivate/workbench/wb_context_ui.cpp (711 lines of code) (raw):
/*
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0,
* as published by the Free Software Foundation.
*
* This program is designed to work with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms, as
* designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an additional
* permission to link the program and your derivative works with the
* separately licensed software that they have either included with
* the program or referenced in the documentation.
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string>
#include "base/ui_form.h"
#include "base/string_utilities.h"
#include "base/file_utilities.h"
#include "base/log.h"
#include "base/notifications.h"
#include "grt.h"
#include "grts/structs.h"
#include "grts/structs.app.h"
#include "grt/editor_base.h"
#include "wb_context_ui.h"
#include "wb_context.h"
#include "model/wb_component.h"
#include "model/wb_component_physical.h"
#include "model/wb_context_model.h"
#include "model/wb_model_diagram_form.h"
#include "sqlide/wb_context_sqlide.h"
#include "wb_overview.h"
#include "model/wb_overview_physical.h"
#include "model/wb_diagram_options.h"
#include "grt/clipboard.h"
#include "grtui/gui_plugin_base.h"
#include "grt_shell_window.h"
#include "license_view.h"
#include "mforms/appview.h"
#include "mforms/home_screen.h"
#include "mforms/home_screen_connections.h"
#include "mforms/home_screen_documents.h"
#include "wb_command_ui.h"
#include "plugin_install_window.h"
using namespace wb;
using namespace bec;
using namespace base;
DEFAULT_LOG_DOMAIN(DOMAIN_WB_CONTEXT_UI)
//--------------------------------------------------------------------------------------------------
std::shared_ptr<WBContextUI> WBContextUI::get() {
static std::shared_ptr<WBContextUI> _singleton(new WBContextUI());
return _singleton;
}
//--------------------------------------------------------------------------------------------------
WBContextUI::WBContextUI() : _wb(new WBContext(false)), _command_ui(new CommandUI(_wb)) {
_shell_window = 0;
_active_form = 0;
_active_main_form = 0;
_addon_download_window = 0;
_plugin_install_window = 0;
_last_unsaved_changes_state = false;
_quitting = false;
_processing_action_open_connection = false;
_home_screen = nullptr;
// to notify that the save status of the doc has changed
scoped_connect(grt::GRT::get()->get_undo_manager()->signal_changed(), std::bind(&WBContextUI::history_changed, this));
// stuff to do when the active form is switched in the UI (through set_active_form)
_form_change_signal.connect(std::bind(&WBContextUI::form_changed, this));
}
//--------------------------------------------------------------------------------------------------
void WBContextUI::cleanUp() {
if (_wb != nullptr) {
_wb->do_close_document(true);
}
delete _addon_download_window;
_addon_download_window = nullptr;
delete _plugin_install_window;
_plugin_install_window = nullptr;
delete _shell_window;
_shell_window = nullptr;
if (_wb != nullptr && !_wb->cancel_idle_tasks()) {
// Idle tasks are currently being executed. Wait a moment and then try again.
g_usleep(static_cast<int>(100000));
_wb->cancel_idle_tasks();
}
delete _wb;
_wb = nullptr;
delete _command_ui;
_command_ui = nullptr;
// home screen should be released by undock operation,
// but it will be left in bad state, we have to clear this
_home_screen = nullptr;
}
//--------------------------------------------------------------------------------------------------
void WBContextUI::reinit() {
if (_wb == nullptr) {
_wb = new WBContext(false);
_command_ui = new CommandUI(_wb);
}
}
//--------------------------------------------------------------------------------------------------
WBContextUI::~WBContextUI() {
cleanUp();
}
//--------------------------------------------------------------------------------------------------
bool WBContextUI::init(WBFrontendCallbacks *callbacks, WBOptions *options) {
// Log set folders.
logInfo(
"Initializing workbench context UI with these values:\n"
"\tbase dir: %s\n\tplugin path: %s\n\tstruct path: %s\n\tmodule path: %s\n\t"
"library path: %s\n\tuser data dir: %s\n\topen at start: %s\n\topen type: %s\n\trun at startup: %s\n\t"
"run type: %s\n\tForce SW rendering: %s\n\tForce OpenGL: %s\n\tquit when done: %s\n",
options->basedir.c_str(), options->plugin_search_path.c_str(), options->struct_search_path.c_str(),
options->module_search_path.c_str(), options->library_search_path.c_str(), options->user_data_dir.c_str(),
options->open_at_startup.c_str(), options->open_at_startup_type.c_str(), options->run_at_startup.c_str(),
options->run_language.c_str(), options->force_sw_rendering ? "Yes" : "No",
options->force_opengl_rendering ? "Yes" : "No", options->quit_when_done ? "Yes" : "No");
bool flag = false;
try {
// this needs to be created after the search paths have been set
// WBContext::init_ will call get_shell_window() at the right time, which
// will trigger the instantiation
//_shell_window = new GRTShellWindow(_wb->get_grt_manager());
flag = _wb->init_(callbacks, options);
if (!options->testing) {
// has to be called after WBContext is initialized
add_backend_builtin_commands();
// look for auto-save files (must be done at startup to not confuse with autosaves created by ourself)
WBContextModel::detect_auto_save_files(_wb->get_auto_save_dir());
WBContextSQLIDE::detect_auto_save_files(_wb->get_auto_save_dir());
}
} catch (const std::exception &e) {
logError("WBContextUI::init, exception '%s'\n", e.what()); // log_error logs to stderr too in debug mode.
} catch (...) {
logError("Some exception has happened. It was caught at WBContextUI::init.\n");
}
return flag;
}
//--------------------------------------------------------------------------------------------------
GRTShellWindow *WBContextUI::get_shell_window() {
if (!_shell_window)
_shell_window = new GRTShellWindow(_wb);
return _shell_window;
}
//--------------------------------------------------------------------------------------------------
void WBContextUI::init_finish(WBOptions *options) {
g_assert(_wb->get_root().is_valid());
show_home_screen();
_wb->init_finish_(options);
NotificationCenter::get()->send("GNAppStarted", nullptr);
}
void WBContextUI::finalize() {
_wb->finalize();
_command_ui->clearBuildInCommands();
if (_home_screen != nullptr)
mforms::App::get()->undock_view(_home_screen);
}
bool WBContextUI::request_quit() {
if (_quitting)
return true;
if (!bec::GRTManager::get()->in_main_thread())
logWarning("request_quit() called in worker thread\n");
{
NotificationInfo info;
info["cancel"] = "0";
NotificationCenter::get()->send("GNAppShouldClose", nullptr, info);
if (info["cancel"] != "0")
return false;
}
if (!_wb->can_close_document())
return false;
if (_wb->get_sqlide_context() && !_wb->get_sqlide_context()->request_quit())
return false;
if (_shell_window != nullptr && !_shell_window->request_quit())
return false;
return true;
}
void WBContextUI::perform_quit() {
_quitting = true;
_wb->do_close_document(true);
_wb->_frontendCallbacks->quit_application();
}
void WBContextUI::reset() {
if (!dynamic_cast<OverviewBE *>(_active_form))
_active_form = 0;
if (!dynamic_cast<OverviewBE *>(_active_main_form))
_active_main_form = 0;
scoped_connect(get_physical_overview()->signal_selection_changed(),
std::bind(&WBContextUI::overview_selection_changed, this));
get_physical_overview()->set_model(_wb->get_document()->physicalModels()[0]);
_wb->request_refresh(RefreshSelection, "", 0);
get_physical_overview()->send_refresh_children(bec::NodeId());
_wb->get_model_context()->refill_catalog_tree();
}
void WBContextUI::history_changed() {
if (!_wb->_file) // check if model is still opened, if not, leave
return;
if (_wb->has_unsaved_changes() != _last_unsaved_changes_state)
_wb->request_refresh(RefreshDocument, "", (NativeHandle)0);
bec::GRTManager::get()->run_once_when_idle(std::bind(&CommandUI::revalidate_edit_menu_items, get_command_ui()));
_last_unsaved_changes_state = _wb->has_unsaved_changes();
}
void WBContextUI::update_current_diagram(bec::UIForm *form) {
ModelDiagramForm *dform = dynamic_cast<ModelDiagramForm *>(form);
if (dform) {
model_DiagramRef diagram(dform->get_model_diagram());
if (diagram.is_valid() && diagram->owner().is_valid())
diagram->owner()->currentDiagram(diagram);
}
}
void WBContextUI::overview_selection_changed() {
if (get_active_main_form() == get_physical_overview()) {
_wb->request_refresh(RefreshSelection, "", (NativeHandle)get_physical_overview()->get_frontend_data());
get_command_ui()->revalidate_edit_menu_items();
}
}
void WBContextUI::load_app_options(bool update) {
if (!update)
_command_ui->load_data();
}
static void add_script_file(WBContextUI *wbui) {
std::string file = wbui->get_wb()->_frontendCallbacks->show_file_dialog("open", _("Add SQL Script File"), "sql");
if (!file.empty()) {
workbench_physical_ModelRef model;
model = workbench_physical_ModelRef::cast_from(wbui->get_wb()->get_model_context()->get_active_model(false));
if (model.is_valid())
wbui->get_wb()->get_component<WBComponentPhysical>()->add_new_stored_script(model, file);
}
}
static void add_note_file(WBContextUI *wbui) {
std::string file =
wbui->get_wb()->_frontendCallbacks->show_file_dialog("open", _("Add Note File"), "Text Files (*.txt)|*.txt");
if (!file.empty()) {
workbench_physical_ModelRef model;
model = workbench_physical_ModelRef::cast_from(wbui->get_wb()->get_model_context()->get_active_model(false));
if (model.is_valid())
wbui->get_wb()->get_component<WBComponentPhysical>()->add_new_stored_note(model, file);
}
}
/** builtin: commands for use in menus and toolbars that are handled by ourselves
*/
void WBContextUI::add_backend_builtin_commands() {
_command_ui->add_builtin_command("show_about", std::bind(&WBContextUI::show_about, this));
_command_ui->add_builtin_command("overview.home", std::bind(&WBContextUI::show_home_screen, this));
_command_ui->add_builtin_command("add_script_file", std::bind(add_script_file, this));
_command_ui->add_builtin_command("add_note_file", std::bind(add_note_file, this));
_command_ui->add_builtin_command("web_mysql_home",
std::bind(&WBContextUI::show_web_page, this, "http://mysql.com/", true));
_command_ui->add_builtin_command(
"web_mysql_docs", std::bind(&WBContextUI::show_web_page, this, "https://dev.mysql.com/doc/workbench/en/", true));
_command_ui->add_builtin_command("web_mysql_blog",
std::bind(&WBContextUI::show_web_page, this, "https://mysqlworkbench.org/", true));
_command_ui->add_builtin_command(
"web_mysql_forum", std::bind(&WBContextUI::show_web_page, this, "https://forums.mysql.com/list.php?152", true));
if (_wb->is_commercial()) {
_command_ui->add_builtin_command("web_support",
std::bind(&WBContextUI::show_web_page, this, "http://support.oracle.com", true));
}
_command_ui->add_builtin_command("help_index", std::bind(&WBContextUI::show_help_index, this));
_command_ui->add_builtin_command("show-license", std::bind(&WBContextUI::showLicense, this));
_command_ui->add_builtin_command("locate_log_file", std::bind(&WBContextUI::locate_log_file, this));
_command_ui->add_builtin_command("show_log_file", std::bind(&WBContextUI::show_log_file, this));
}
#ifndef ___specialforms
//--------------------------------------------------------------------------------------------------
PhysicalOverviewBE *WBContextUI::get_physical_overview() {
return get_wb()->get_model_context() ? get_wb()->get_model_context()->get_overview() : 0;
}
//--------------------------------------------------------------------------------------------------
/*
* Opens the given web page in the system's default browser.
*/
void WBContextUI::show_web_page(const std::string &url, bool internal_browser) {
mforms::Utilities::open_url(url);
}
//--------------------------------------------------------------------------------------------------
void WBContextUI::showLicense() {
LicenseView *view = mforms::manage(new LicenseView(this));
mforms::App::get()->dock_view(view, "maintab");
view->set_title(_("License Info"));
}
//--------------------------------------------------------------------------------------------------
void WBContextUI::show_help_index() {
GUILock lock(_wb, _("Starting Doc Lib"), _("The MySQL Doc Library is opening currently, "
"which should be finished in a moment .\n\nPlease stand by..."));
mforms::Utilities::open_url("http://dev.mysql.com/doc/refman/8.0/en");
}
//--------------------------------------------------------------------------------------------------
void WBContextUI::locate_log_file() {
if (!base::Logger::log_dir().empty())
mforms::Utilities::open_url(base::Logger::log_dir());
}
//--------------------------------------------------------------------------------------------------
void WBContextUI::show_log_file() {
if (!base::Logger::log_filename().empty())
mforms::Utilities::open_url(base::Logger::log_filename());
}
//--------------------------------------------------------------------------------------------------
void WBContextUI::activate_figure(const grt::ValueRef &value) {
ModelDiagramForm *form = 0;
if (model_FigureRef::can_wrap(value)) {
model_FigureRef figure(model_FigureRef::cast_from(value));
form = get_wb()->get_model_context()->get_diagram_form_for_diagram_id(figure->owner().id());
if (form)
form->focus_and_make_visible(figure, true);
} else if (model_ConnectionRef::can_wrap(value)) {
model_ConnectionRef conn(model_ConnectionRef::cast_from(value));
ModelDiagramForm *form = get_wb()->get_model_context()->get_diagram_form_for_diagram_id(conn->owner().id());
if (form)
form->focus_and_make_visible(conn, true);
} else if (model_LayerRef::can_wrap(value)) {
model_LayerRef layer(model_LayerRef::cast_from(value));
ModelDiagramForm *form = get_wb()->get_model_context()->get_diagram_form_for_diagram_id(layer->owner().id());
if (form)
form->focus_and_make_visible(layer, true);
}
}
//--------------------------------------------------------------------------------------------------
void WBContextUI::form_changed() {
_wb->request_refresh(RefreshZoom, "", (NativeHandle)0);
bec::UIForm *form = get_active_main_form();
if (form && form->get_menubar())
get_command_ui()->revalidate_menu_bar(form->get_menubar());
}
bec::ValueInspectorBE *WBContextUI::create_inspector_for_selection(bec::UIForm *form, std::vector<std::string> &items) {
grt::ListRef<model_Object> selection;
// grt::ListRef<model_Object> selection(form->get_selection());
if (dynamic_cast<ModelDiagramForm *>(form))
selection = dynamic_cast<ModelDiagramForm *>(form)->get_selection();
else
return 0;
if (selection.is_valid() && selection.count() > 0) {
if (selection.count() == 1) {
items.push_back(
strfmt("%s: %s", selection[0]->name().c_str(), selection[0].get_metaclass()->get_attribute("caption").c_str()));
return ValueInspectorBE::create(selection[0], false, true);
} else {
std::vector<grt::ObjectRef> list;
items.push_back(_("Multiple Items"));
for (size_t c = selection.count(), i = 0; i < c; i++) {
items.push_back(strfmt("%s: %s", selection[i]->name().c_str(),
selection[i].get_metaclass()->get_attribute("caption").c_str()));
list.push_back(selection.get(i));
}
return ValueInspectorBE::create(list);
}
}
return 0;
}
bec::ValueInspectorBE *WBContextUI::create_inspector_for_selection(std::vector<std::string> &items) {
std::string res;
grt::ListRef<GrtObject> selection(get_physical_overview()->get_selection());
std::string name_mem_name("name");
if (selection.is_valid() && selection.count() > 0) {
if (selection.count() == 1) {
GrtObjectRef obj = selection[0];
if (obj.is_valid() && obj->has_member(name_mem_name)) {
items.push_back(strfmt("%s: %s", obj.get_string_member(name_mem_name).c_str(),
obj.get_metaclass()->get_attribute("caption").c_str()));
return ValueInspectorBE::create(selection[0], false, true);
}
} else {
std::vector<grt::ObjectRef> list;
items.push_back(_("Multiple Items"));
for (size_t c = selection.count(), i = 0; i < c; i++) {
if (!selection[i].is_valid()) // skip "Add item" entry in objects list
continue;
items.push_back(strfmt("%s: %s", selection[i].get_string_member(name_mem_name).c_str(),
selection[i].get_metaclass()->get_attribute("caption").c_str()));
list.push_back(selection.get(i));
}
return ValueInspectorBE::create(list);
}
}
return 0;
}
std::string WBContextUI::get_description_for_selection(grt::ListRef<GrtObject> &activeObjList,
std::vector<std::string> &items) {
std::string res;
if (get_physical_overview() != nullptr) {
grt::ListRef<GrtObject> selection(get_physical_overview()->get_selection());
activeObjList = selection;
std::string comment_mem_name("comment");
std::string name_mem_name("name");
if (selection.is_valid() && selection.count() > 0) {
if (selection.count() == 1) {
GrtObjectRef obj(selection[0]);
if (obj.is_valid() && obj.has_member(comment_mem_name) && obj.has_member(name_mem_name)) {
items.push_back(strfmt("%s: %s", obj->name().c_str(), obj.get_metaclass()->get_attribute("caption").c_str()));
res = obj.get_string_member(comment_mem_name);
}
} else {
items.push_back(_("Multiple Items"));
for (size_t c = selection.count(), i = 0; i < c; i++) {
GrtObjectRef obj(selection[i]);
if (obj.is_valid() && obj.has_member(comment_mem_name) && obj.has_member(name_mem_name)) {
items.push_back(
strfmt("%s: %s", obj->name().c_str(), obj.get_metaclass()->get_attribute("caption").c_str()));
std::string comment = obj.get_string_member(comment_mem_name);
if (0 == i)
res = comment;
else if (0 != res.compare(comment))
res =
"<Multiple Items>\nThat means not all selected items have same comment.\nBeware applying changes will "
"override comments for all selected objects.";
}
}
}
}
}
return res;
}
std::string WBContextUI::get_description_for_selection(bec::UIForm *form, grt::ListRef<GrtObject> &activeObjList,
std::vector<std::string> &items) {
grt::ListRef<model_Object> selection;
if (dynamic_cast<ModelDiagramForm *>(form))
selection = dynamic_cast<ModelDiagramForm *>(form)->get_selection();
else
return get_description_for_selection(activeObjList, items);
std::string res;
activeObjList = grt::ListRef<model_Object>(true);
std::string comment_mem_name("comment");
std::string descr_mem_name("description");
if (selection.is_valid() && selection.count() > 0) {
bool first = true;
for (size_t c = selection.count(), i = 0; i < c; i++) {
model_ObjectRef figure(selection[i]);
WBComponent *comp = _wb->get_component_handling(figure);
GrtObjectRef dbobject;
if (comp)
dbobject = comp->get_object_for_figure(figure);
if (dbobject.is_valid() && dbobject.has_member(comment_mem_name)) {
activeObjList.insert(dbobject);
items.push_back(
strfmt("%s: %s", figure->name().c_str(), figure->get_metaclass()->get_attribute("caption").c_str()));
std::string comment = dbobject.get_string_member(comment_mem_name);
if (first)
res = comment;
else if (0 != res.compare(comment))
res =
_("<Multiple Items>\nThat means not all selected items have same comment.\nBeware applying changes will "
"override comments for all selected objects.");
first = false;
} else if (!dbobject.is_valid() && figure.is_valid() && figure.has_member(descr_mem_name)) {
activeObjList.insert(figure);
items.push_back(
strfmt("%s: %s", figure->name().c_str(), figure->get_metaclass()->get_attribute("caption").c_str()));
std::string comment = figure.get_string_member(descr_mem_name);
if (first)
res = comment;
else if (0 != res.compare(comment))
res =
_("<Multiple Items>\nThat means not all selected items have same comment.\nBeware applying changes will "
"override comments for all selected objects.");
first = false;
}
}
if (items.size() > 1)
items.insert(items.begin(), _("Multiple Items"));
}
return res;
}
void WBContextUI::set_description_for_selection(const grt::ListRef<GrtObject> &objList, const std::string &val) {
if (objList.is_valid() && objList.count() > 0) {
std::string comment_mem_name("comment");
std::string descr_mem_name("description");
grt::AutoUndo undo;
for (size_t c = objList.count(), i = 0; i < c; i++) {
GrtObjectRef obj(objList[i]);
if (obj.is_valid()) {
if (obj.has_member(comment_mem_name)) {
obj.set_member(comment_mem_name, grt::StringRef(val));
get_physical_overview()->send_refresh_for_schema_object(obj, true);
} else if (obj.has_member(descr_mem_name)) {
obj.set_member(descr_mem_name, grt::StringRef(val));
get_physical_overview()->send_refresh_for_schema_object(obj, true);
}
}
}
undo.end(_("Set Object Description"));
}
}
DiagramOptionsBE *WBContextUI::create_diagram_options_be(mdc::CanvasView *view) {
model_DiagramRef model_diagram(get_wb()->get_model_context()->get_active_model_diagram(true));
if (model_diagram.is_valid())
return new DiagramOptionsBE(view, model_diagram, _wb);
else
return 0;
}
std::string WBContextUI::get_active_diagram_info() {
wb::ModelDiagramForm *form = dynamic_cast<wb::ModelDiagramForm *>(get_active_main_form());
if (form)
return form->get_diagram_info_text();
return "";
}
#endif // ___specialforms
#ifndef ___preferences
//-----------------------------------------------------------------------------------
// utility functions for user preferences
void WBContextUI::get_doc_properties(std::string &caption, std::string &version, std::string &author,
std::string &project, std::string &date_created, std::string &date_changed,
std::string &description) {
app_DocumentInfoRef info = _wb->get_document()->info();
caption = info->caption();
version = info->version();
author = info->author();
project = info->project();
date_created = info->dateCreated();
date_changed = info->dateChanged();
description = info->description();
}
void WBContextUI::set_doc_properties(const std::string &caption, const std::string &version, const std::string &author,
const std::string &project, const std::string &date_created,
const std::string &date_changed, const std::string &description) {
app_DocumentInfoRef info = _wb->get_document()->info();
grt::AutoUndo undo;
info->caption(caption);
info->version(version);
info->author(author);
info->project(project);
info->dateCreated(date_created);
info->dateChanged(date_changed);
info->description(description);
undo.end("Change document properties");
}
std::list<WBPaperSize> WBContextUI::get_paper_sizes(bool descr_in_inches) {
std::list<WBPaperSize> sizes;
grt::ListRef<app_PaperType> types(_wb->get_root()->options()->paperTypes());
for (size_t c = types.count(), i = 0; i < c; i++) {
WBPaperSize size;
size.name = types[i]->name();
size.caption = types[i]->caption();
size.width = types[i]->width();
size.height = types[i]->height();
size.margins_set = types[i]->marginsSet() != 0;
size.margin_top = types[i]->marginTop();
size.margin_bottom = types[i]->marginBottom();
size.margin_left = types[i]->marginLeft();
size.margin_right = types[i]->marginRight();
if (descr_in_inches)
size.description = strfmt("%.2f in x %.2f in", size.width * 0.03937, size.height * 0.03937);
else
size.description = strfmt("%.2f cm x %.2f cm", size.width / 10, size.height / 10);
sizes.push_back(size);
}
return sizes;
}
bool WBContextUI::add_paper_size(const std::string &name, double width, double height, bool margins, double margin_top,
double margin_bottom, double margin_left, double margin_right) {
if (grt::find_named_object_in_list(_wb->get_root()->options()->paperTypes(), name).is_valid())
return false;
app_PaperTypeRef type(grt::Initialized);
type->owner(_wb->get_root()->options());
type->name(name);
type->width(width);
type->height(height);
type->marginsSet(margins ? 1 : 0);
type->marginTop(margin_top);
type->marginBottom(margin_bottom);
type->marginLeft(margin_left);
type->marginRight(margin_right);
_wb->get_root()->options()->paperTypes().insert(type);
return true;
}
app_PageSettingsRef WBContextUI::get_page_settings() {
if (_wb->get_document().is_valid())
return _wb->get_document()->pageSettings();
else {
// XXX add proper initialization for non-trivial types in structs.app.h too.
app_PageSettingsRef settings = app_PageSettingsRef(grt::Initialized);
settings->scale(1);
settings->paperType(app_PaperTypeRef());
return settings;
}
}
grt::DictRef WBContextUI::get_model_options(const std::string &model_id) {
grt::ListRef<workbench_physical_Model> pmodels(_wb->get_document()->physicalModels());
for (size_t c = pmodels.count(), i = 0; i < c; i++) {
if (pmodels.get(i).id() == model_id) {
return pmodels.get(i)->options();
}
}
return grt::DictRef();
}
std::vector<std::string> WBContextUI::get_wb_options_keys(const std::string &model) {
std::vector<std::string> keylist;
grt::DictRef options = _wb->get_wb_options();
for (grt::DictRef::const_iterator iter = options.begin(); iter != options.end(); ++iter) {
keylist.push_back(iter->first);
}
return keylist;
}
bool WBContextUI::get_wb_options_value(const std::string &model, const std::string &key, std::string &value) {
grt::DictRef options = _wb->get_wb_options();
grt::ValueRef val;
// If a model is given check if it is set to use global values or its own.
if (!model.empty()) {
grt::DictRef model_options(get_model_options(model));
bool use_global = model_options.get_int("useglobal", 1) != 0;
if (key == "useglobal") {
if (use_global)
value = "1";
else
value = "0";
return true;
}
if (!use_global && model_options.has_key(key))
val = model_options.get(key);
}
if (!val.is_valid() && options.has_key(key))
val = options.get(key);
switch (val.type()) {
case grt::StringType:
case grt::DoubleType:
case grt::IntegerType:
value = val.toString();
return true;
default:
return false;
}
}
void WBContextUI::set_wb_options_value(const std::string &model, const std::string &key, const std::string &value,
const grt::Type default_type) {
grt::DictRef options;
grt::Type type;
if (_wb->get_wb_options().has_key(key))
type = _wb->get_wb_options().get(key).type();
else
type = default_type;
if (!model.empty()) {
options = get_model_options(model);
options.gset("useglobal", 0);
if (options.has_key(key))
type = options.get(key).type();
}
if (!options.is_valid())
options = _wb->get_wb_options();
switch (type) {
case grt::DoubleType: {
grt::DoubleRef v(base::atof<double>(value, 0.0));
if (!options.has_key(key) || options.get_double(key) != *v)
options.set(key, v);
break;
}
case grt::IntegerType: {
grt::IntegerRef v(base::atoi<int>(value, 0));
if (!options.has_key(key) || options.get_int(key) != *v)
options.set(key, v);
break;
}
case grt::StringType: {
grt::StringRef v(value);
if (!options.has_key(key) || options.get_string(key) != *v)
options.set(key, v);
break;
}
default:
throw std::runtime_error("No valid grt type specified when setting options value.");
}
}
void WBContextUI::discard_wb_model_options(const std::string &model) {
grt::DictRef opts = get_model_options(model);
if (opts.is_valid()) {
for (grt::DictRef::const_iterator item = opts.begin(); item != opts.end(); ++item) {
opts.set(item->first, grt::ValueRef());
}
opts.gset("useglobal", 1);
}
}
#endif // ___preferences
#ifndef ___forms
//--------------------------------------------------------------------------------
// Form Management
void *WBContextUI::form_destroyed(void *data) {
UIForm *form = reinterpret_cast<UIForm *>(data);
WBContextUI *wb = reinterpret_cast<WBContextUI *>(form->get_owner_data());
if (wb->_active_form == form)
wb->set_active_form(0);
if (wb->_active_main_form == form)
wb->_active_main_form = 0;
return 0;
}
std::string WBContextUI::get_active_context(bool main_context) {
bec::UIForm *form = main_context ? get_active_main_form() : get_active_form();
if (form)
return form->get_form_context_name();
return "";
}
void WBContextUI::set_active_form(bec::UIForm *form) {
if (_active_form == form)
return;
// register callbacks to form if needed
if (_active_form && form)
_active_form->remove_destroy_notify_callback(_active_form);
_active_form = form;
if (form) {
form->add_destroy_notify_callback(reinterpret_cast<void *>(form), &WBContextUI::form_destroyed);
form->set_owner_data(reinterpret_cast<void *>(this));
}
if (form && form->is_main_form()) {
if (_active_main_form != form) {
_active_main_form = form;
base::NotificationInfo info;
info["form"] = form ? form->form_id() : "";
info["context"] = get_active_context(true);
NotificationCenter::get()->send("GNMainFormChanged", 0, info);
}
}
_form_change_signal(form);
}
bec::UIForm *WBContextUI::get_active_main_form() {
return _active_main_form;
}
bec::UIForm *WBContextUI::get_active_form() {
return _active_form;
}
#endif // ___forms
#ifndef ___others
//-----------------------------------------------------------------------------------
// other functionality for UI
std::string WBContextUI::get_document_name() {
if (_wb->get_filename().empty())
return "Untitled";
else
return base::basename(_wb->get_filename());
}
std::string WBContextUI::get_title() {
if (_wb->get_model_context()) {
#ifndef __APPLE__
if (_wb->has_unsaved_changes())
return get_document_name() + "* - MySQL Workbench";
else
#endif
return get_document_name() + " - MySQL Workbench";
} else
return "MySQL Workbench";
}
#endif // ___others
void WBContextUI::start_plugin_net_install(const std::string &url) {
if (!_addon_download_window)
_addon_download_window = new AddOnDownloadWindow(this);
_addon_download_window->install_addon_from_url(url);
}
bool WBContextUI::start_plugin_install(const std::string &path) {
if (!_plugin_install_window)
_plugin_install_window = new PluginInstallWindow(this);
return _plugin_install_window->install_plugin(path);
}
//--------------------------------------------------------------------------------------------------
static struct RegisterNotifDocs_wb_context_ui {
RegisterNotifDocs_wb_context_ui() {
base::NotificationCenter::get()->register_notification(
"GNAppStarted", "application", "Sent when Workbench starts up and finishes with various initialization routines.",
"", "");
base::NotificationCenter::get()->register_notification("GNAppShouldClose", "application",
"Sent when the user requests Workbench to close. Close can "
"be cancelled by setting the 'cancel' field in the info "
"dict to 1.",
"", "cancel - set to 1 if exit should be cancelled");
base::NotificationCenter::get()->register_notification(
"GNMainFormChanged", "application", "Sent when the main tab from the application is switched.", "",
"form - the ID of the newly active form\n"
"context - the context name of the newly active form");
base::NotificationCenter::get()->register_notification("GNApplicationActivated", "application",
"Sent when the application was activated.", "", "");
base::NotificationCenter::get()->register_notification("GNApplicationDeactivated", "application",
"Sent when the application lost the active status.", "", "");
}
} initdocs_wb_context_ui;