From 193ea228f7b9ed326b38873a0ce96c0810b093ba Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Mon, 23 Apr 2018 10:53:27 -0300 Subject: [PATCH 01/30] Minor code refactor in BaseObjectView::getScreenDpiFactor --- libobjrenderer/src/baseobjectview.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libobjrenderer/src/baseobjectview.cpp b/libobjrenderer/src/baseobjectview.cpp index 113491dc2b..1a21cd06a7 100644 --- a/libobjrenderer/src/baseobjectview.cpp +++ b/libobjrenderer/src/baseobjectview.cpp @@ -638,8 +638,9 @@ double BaseObjectView::getFontFactor(void) double BaseObjectView::getScreenDpiFactor(void) { - double factor = qApp->screens().at(qApp->desktop()->screenNumber(qApp->activeWindow()))->logicalDotsPerInch() / 96.0f; - double pixel_ratio = qApp->screens().at(qApp->desktop()->screenNumber(qApp->activeWindow()))->devicePixelRatio(); + QScreen *screen = qApp->screens().at(qApp->desktop()->screenNumber(qApp->activeWindow())); + double factor = screen->logicalDotsPerInch() / 96.0f; + double pixel_ratio = screen->devicePixelRatio(); if(factor < 1) return (1); From 762974766f1d51320e2684e780654288973c9b4b Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Mon, 23 Apr 2018 15:01:56 -0300 Subject: [PATCH 02/30] Minor typo fixes in PgModelerCLI Improved the setTag operation in ModelWidget in order to cleanup the assigned tag to a set of objects Minor improvement on DatabaseExplorerWidget to show the rls attributes labels correctly in the attributes grid --- libpgmodeler/src/databasemodel.cpp | 9 +++++ libpgmodeler/src/databasemodel.h | 5 ++- .../src/databaseexplorerwidget.cpp | 7 ++-- libpgmodeler_ui/src/modelwidget.cpp | 16 ++++++--- main-cli/src/pgmodelercli.cpp | 36 +++++++++---------- 5 files changed, 48 insertions(+), 25 deletions(-) diff --git a/libpgmodeler/src/databasemodel.cpp b/libpgmodeler/src/databasemodel.cpp index 201a197e27..d2ad7fe148 100644 --- a/libpgmodeler/src/databasemodel.cpp +++ b/libpgmodeler/src/databasemodel.cpp @@ -8808,6 +8808,15 @@ void DatabaseModel::__getObjectReferences(BaseObject *object, vector &objects) +{ + for(auto &obj : objects) + { + if(BaseGraphicObject::isGraphicObject(obj->getObjectType())) + dynamic_cast(obj)->setModified(true); + } +} + void DatabaseModel::setObjectsModified(vector types) { ObjectType obj_types[]={OBJ_TABLE, OBJ_VIEW, diff --git a/libpgmodeler/src/databasemodel.h b/libpgmodeler/src/databasemodel.h index 11406b0ad2..f0cde903cb 100644 --- a/libpgmodeler/src/databasemodel.h +++ b/libpgmodeler/src/databasemodel.h @@ -561,10 +561,13 @@ class DatabaseModel: public QObject, public BaseObject { meaning that ALL objects directly or inderectly linked to the 'object' are retrieved. */ void __getObjectReferences(BaseObject *object, vector &refs, bool exclude_perms=false); - /*! \brief Marks the graphical objects as modified forcing their redraw. User can specify only a set of + /*! \brief Marks the graphical objects of the provided types as modified forcing their redraw. User can specify only a set of graphical objects to be marked */ void setObjectsModified(vector types={}); + //! \brief Marks the graphical objects in the list as modified forcing their redraw. + void setObjectsModified(vector &objects); + /*! \brief Marks the objects with code invalidated forcing their code regeneration. User can specify only a set of graphical objects to be marked */ void setCodesInvalidated(vector types={}); diff --git a/libpgmodeler_ui/src/databaseexplorerwidget.cpp b/libpgmodeler_ui/src/databaseexplorerwidget.cpp index 1f47174fe2..395c187a24 100644 --- a/libpgmodeler_ui/src/databaseexplorerwidget.cpp +++ b/libpgmodeler_ui/src/databaseexplorerwidget.cpp @@ -93,7 +93,8 @@ const attribs_map DatabaseExplorerWidget::attribs_i18n { {SERVER_VERSION, QT_TR_NOOP("Server version")}, {IDENT_FILE, QT_TR_NOOP("Ident file")}, {PASSWORD_ENCRYPTION, QT_TR_NOOP("Password encryption")}, {CONNECTION, QT_TR_NOOP("Connection ID")}, {SERVER_PID, QT_TR_NOOP("Server PID")}, {SERVER_PROTOCOL, QT_TR_NOOP("Server protocol")}, {REFERRERS, QT_TR_NOOP("Referrers")}, {IDENTITY_TYPE, QT_TR_NOOP("Identity")}, {COMMAND, QT_TR_NOOP("Command")}, - {USING_EXP, QT_TR_NOOP("USING expr.")}, {CHECK_EXP, QT_TR_NOOP("CHECK expr.")}, {ROLES, QT_TR_NOOP("Roles")} + {USING_EXP, QT_TR_NOOP("USING expr.")}, {CHECK_EXP, QT_TR_NOOP("CHECK expr.")}, {ROLES, QT_TR_NOOP("Roles")}, + {RLS_ENABLED, QT_TR_NOOP("RLS enabled")}, {RLS_FORCED, QT_TR_NOOP("RLS forced")} }; DatabaseExplorerWidget::DatabaseExplorerWidget(QWidget *parent): QWidget(parent) @@ -509,7 +510,9 @@ void DatabaseExplorerWidget::formatOperatorAttribs(attribs_map &attribs) void DatabaseExplorerWidget::formatTableAttribs(attribs_map &attribs) { formatBooleanAttribs(attribs, { ParsersAttributes::OIDS, - ParsersAttributes::UNLOGGED }); + ParsersAttributes::UNLOGGED, + ParsersAttributes::RLS_ENABLED, + ParsersAttributes::RLS_FORCED}); formatOidAttribs(attribs, { ParsersAttributes::PARENTS }, OBJ_TABLE, true); } diff --git a/libpgmodeler_ui/src/modelwidget.cpp b/libpgmodeler_ui/src/modelwidget.cpp index 000c455c1d..24166edcf7 100644 --- a/libpgmodeler_ui/src/modelwidget.cpp +++ b/libpgmodeler_ui/src/modelwidget.cpp @@ -2006,11 +2006,13 @@ void ModelWidget::setTag(void) { op_id=op_list->registerObject(obj, Operation::OBJECT_MODIFIED, -1); tab->setTag(dynamic_cast(tag)); - tab->setModified(true); } } op_list->finishOperationChain(); + db_model->setObjectsModified(selected_objects); + scene->clearSelection(); + emit s_objectModified(); } catch(Exception &e) @@ -3134,9 +3136,9 @@ void ModelWidget::configureSubmenu(BaseObject *object) menus[i]->clear(); //Configuring actions "Move to schema", "Change Owner" and "Set tag" - if((i==0 && accepts_schema) || - (i==1 && accepts_owner) || - (i==2 && tab_or_view)) + if((types[i] == OBJ_SCHEMA && accepts_schema) || + (types[i] == OBJ_ROLE && accepts_owner) || + (types[i]==OBJ_TAG && tab_or_view)) { obj_list=db_model->getObjects(types[i]); @@ -3147,6 +3149,12 @@ void ModelWidget::configureSubmenu(BaseObject *object) } else { + if(types[i] == OBJ_TAG) + { + menus[i]->addAction(trUtf8("None"), this, SLOT(setTag())); + menus[i]->addSeparator(); + } + while(!obj_list.empty()) { act=new QAction(obj_list.back()->getName(), menus[i]); diff --git a/main-cli/src/pgmodelercli.cpp b/main-cli/src/pgmodelercli.cpp index c21c60a513..1ab1809edf 100644 --- a/main-cli/src/pgmodelercli.cpp +++ b/main-cli/src/pgmodelercli.cpp @@ -366,50 +366,50 @@ bool PgModelerCLI::isOptionRecognized(QString &op, bool &accepts_val) void PgModelerCLI::showMenu(void) { out << endl; - out << trUtf8("Usage: pgmodeler-cli [OPTIONS]") << endl; out << QString("pgModeler ") << GlobalAttributes::PGMODELER_VERSION << trUtf8(" command line interface.") << endl; out << trUtf8("PostgreSQL Database Modeler Project - pgmodeler.io") << endl; out << trUtf8("Copyright 2006-2018 Raphael A. Silva ") << endl; out << endl; - out << trUtf8("This CLI tool provides several operations over models and databases without the need to perform them\non pgModeler's graphical interface. All available options are described below.") << endl; + out << trUtf8("Usage: pgmodeler-cli [OPTIONS]") << endl << endl; + out << trUtf8("This CLI tool provides several operations over models and databases without the need to perform them\nin pgModeler's graphical interface. All available options are described below.") << endl; out << endl; out << trUtf8("General options: ") << endl; - out << trUtf8(" %1, %2 [FILE]\t\t Input model file (.dbm). This is mandatory in fix, export operations.").arg(short_opts[INPUT]).arg(INPUT) << endl; - out << trUtf8(" %1, %2 [DBNAME]\t Input database name. This is mandatory import operation.").arg(short_opts[INPUT_DB]).arg(INPUT_DB) << endl; - out << trUtf8(" %1, %2 [FILE]\t\t Output file. Mandatory use in fixing model or exporting to file, png or svg.").arg(short_opts[OUTPUT]).arg(OUTPUT) << endl; + out << trUtf8(" %1, %2 [FILE]\t\t Input model file (.dbm). This is mandatory for fix, export operations.").arg(short_opts[INPUT]).arg(INPUT) << endl; + out << trUtf8(" %1, %2 [DBNAME]\t Input database name. This is mandatory for import operation.").arg(short_opts[INPUT_DB]).arg(INPUT_DB) << endl; + out << trUtf8(" %1, %2 [FILE]\t\t Output file. This is mandatory for fixing model or exporting to file, png or svg.").arg(short_opts[OUTPUT]).arg(OUTPUT) << endl; out << trUtf8(" %1, %2\t\t Try to fix the structure of the input model file in order to make it loadable again.").arg(short_opts[FIX_MODEL]).arg(FIX_MODEL) << endl; - out << trUtf8(" %1, %2 [NUMBER]\t Model fix tries. When reaching the maximum count the invalid objects will be discard.").arg(short_opts[FIX_TRIES]).arg(FIX_TRIES) << endl; + out << trUtf8(" %1, %2 [NUMBER]\t Model fix tries. When reaching the maximum count the invalid objects will be discarded.").arg(short_opts[FIX_TRIES]).arg(FIX_TRIES) << endl; out << trUtf8(" %1, %2\t\t Export the input model to a sql script file.").arg(short_opts[EXPORT_TO_FILE]).arg(EXPORT_TO_FILE)<< endl; out << trUtf8(" %1, %2\t\t Export the input model to a png image.").arg(short_opts[EXPORT_TO_PNG]).arg(EXPORT_TO_PNG) << endl; out << trUtf8(" %1, %2\t\t Export the input model to a svg file.").arg(short_opts[EXPORT_TO_SVG]).arg(EXPORT_TO_SVG) << endl; out << trUtf8(" %1, %2\t\t Export the input model directly to a PostgreSQL server.").arg(short_opts[EXPORT_TO_DBMS]).arg(EXPORT_TO_DBMS) << endl; out << trUtf8(" %1, %2\t\t Import a database to an output file.").arg(short_opts[IMPORT_DB]).arg(IMPORT_DB) << endl; - out << trUtf8(" %1, %2\t\t\t Compares a model and database or two databases generating a SQL script to synch the latter in relation to the first.").arg(short_opts[DIFF]).arg(DIFF) << endl; + out << trUtf8(" %1, %2\t\t\t Compares a model and a database or two databases generating the SQL script to synch the latter in relation to the first.").arg(short_opts[DIFF]).arg(DIFF) << endl; out << trUtf8(" %1, %2\t\t Force the PostgreSQL version of generated SQL code.").arg(short_opts[PGSQL_VER]).arg(PGSQL_VER) << endl; - out << trUtf8(" %1, %2\t\t\t Silent execution. Only critical errors are shown during process.").arg(short_opts[SILENT]).arg(SILENT) << endl; + out << trUtf8(" %1, %2\t\t\t Silent execution. Only critical messages and errors are shown during process.").arg(short_opts[SILENT]).arg(SILENT) << endl; out << trUtf8(" %1, %2\t\t\t Show this help menu.").arg(short_opts[HELP]).arg(HELP) << endl; out << endl; out << trUtf8("Connection options: ") << endl; out << trUtf8(" %1, %2\t\t List available connections in file %3.").arg(short_opts[LIST_CONNS]).arg(LIST_CONNS).arg(GlobalAttributes::CONNECTIONS_CONF + GlobalAttributes::CONFIGURATION_EXT) << endl; out << trUtf8(" %1, %2 [ALIAS]\t Connection configuration alias to be used.").arg(short_opts[CONN_ALIAS]).arg(CONN_ALIAS) << endl; - out << trUtf8(" %1, %2 [HOST]\t\t PostgreSQL host which a task will operate.").arg(short_opts[HOST]).arg(HOST) << endl; + out << trUtf8(" %1, %2 [HOST]\t\t PostgreSQL host in which a task will operate.").arg(short_opts[HOST]).arg(HOST) << endl; out << trUtf8(" %1, %2 [PORT]\t\t PostgreSQL host listening port.").arg(short_opts[PORT]).arg(PORT) << endl; out << trUtf8(" %1, %2 [USER]\t\t PostgreSQL username.").arg(short_opts[USER]).arg(USER) << endl; out << trUtf8(" %1, %2 [PASSWORD]\t PostgreSQL user password.").arg(short_opts[PASSWD]).arg(PASSWD) << endl; out << trUtf8(" %1, %2 [DBNAME]\t Connection's initial database.").arg(short_opts[INITIAL_DB]).arg(INITIAL_DB) << endl; out << endl; out << trUtf8("PNG and SVG export options: ") << endl; - out << trUtf8(" %1, %2\t\t Draws the grid on the exported png image.").arg(short_opts[SHOW_GRID]).arg(SHOW_GRID) << endl; - out << trUtf8(" %1, %2\t Draws the page delimiters on the exported png image.").arg(short_opts[SHOW_DELIMITERS]).arg(SHOW_DELIMITERS) << endl; - out << trUtf8(" %1, %2\t\t Each page will be exported on a separated png image. (Only for PNG)").arg(short_opts[PAGE_BY_PAGE]).arg(PAGE_BY_PAGE) << endl; - out << trUtf8(" %1, %2 [FACTOR]\t\t Applies a zoom (in percent) before export to png image. Accepted zoom interval: %3-%4 (Only for PNG)").arg(short_opts[ZOOM_FACTOR]).arg(ZOOM_FACTOR).arg(ModelWidget::MINIMUM_ZOOM*100).arg(ModelWidget::MAXIMUM_ZOOM*100) << endl; + out << trUtf8(" %1, %2\t\t Draws the grid in the exported image.").arg(short_opts[SHOW_GRID]).arg(SHOW_GRID) << endl; + out << trUtf8(" %1, %2\t Draws the page delimiters in the exported image.").arg(short_opts[SHOW_DELIMITERS]).arg(SHOW_DELIMITERS) << endl; + out << trUtf8(" %1, %2\t\t Each page will be exported in a separated png image. (Only for PNG images)").arg(short_opts[PAGE_BY_PAGE]).arg(PAGE_BY_PAGE) << endl; + out << trUtf8(" %1, %2 [FACTOR]\t\t Applies a zoom (in percent) before export to png image. Accepted zoom interval: %3-%4 (Only for PNG images)").arg(short_opts[ZOOM_FACTOR]).arg(ZOOM_FACTOR).arg(ModelWidget::MINIMUM_ZOOM*100).arg(ModelWidget::MAXIMUM_ZOOM*100) << endl; out << endl; out << trUtf8("DBMS export options: ") << endl; - out << trUtf8(" %1, %2\t Ignores errors related to duplicated objects that eventually exists on server side.").arg(short_opts[IGNORE_DUPLICATES]).arg(IGNORE_DUPLICATES) << endl; + out << trUtf8(" %1, %2\t Ignores errors related to duplicated objects that eventually exist in the server.").arg(short_opts[IGNORE_DUPLICATES]).arg(IGNORE_DUPLICATES) << endl; out << trUtf8(" %1, %2 [CODES] Ignores additional errors by their codes. A comma-separated list of alphanumeric codes should be provided.").arg(short_opts[IGNORE_ERROR_CODES]).arg(IGNORE_ERROR_CODES) << endl; out << trUtf8(" %1, %2\t\t Drop the database before execute a export process.").arg(short_opts[DROP_DATABASE]).arg(DROP_DATABASE) << endl; out << trUtf8(" %1, %2\t\t Runs the DROP commands attached to SQL-enabled objects.").arg(short_opts[DROP_OBJECTS]).arg(DROP_OBJECTS) << endl; - out << trUtf8(" %1, %2\t\t Simulates a export process. Actually executes all steps but undoing any modification.").arg(short_opts[SIMULATE]).arg(SIMULATE) << endl; + out << trUtf8(" %1, %2\t\t Simulates an export process by executing all steps but undoing any modification in the end.").arg(short_opts[SIMULATE]).arg(SIMULATE) << endl; out << trUtf8(" %1, %2\t\t Generates temporary names for database, roles and tablespaces when in simulation mode.").arg(short_opts[USE_TMP_NAMES]).arg(USE_TMP_NAMES) << endl; out << endl; out << trUtf8("Database import options: ") << endl; @@ -421,13 +421,13 @@ void PgModelerCLI::showMenu(void) out << trUtf8("Diff options: ") << endl; out << trUtf8(" %1, %2 [DBNAME]\t The database used in the comparison. All the SQL code generated is applied to it.").arg(short_opts[COMPARE_TO]).arg(COMPARE_TO) << endl; out << trUtf8(" %1, %2\t\t Save the generated diff code to output file.").arg(short_opts[SAVE_DIFF]).arg(SAVE_DIFF) << endl; - out << trUtf8(" %1, %2\t\t Apply the generated diff code to the database.").arg(short_opts[APPLY_DIFF]).arg(APPLY_DIFF) << endl; - out << trUtf8(" %1, %2\t Don't preview the generated diff code.").arg(short_opts[NO_DIFF_PREVIEW]).arg(NO_DIFF_PREVIEW) << endl; + out << trUtf8(" %1, %2\t\t Apply the generated diff code on the database server.").arg(short_opts[APPLY_DIFF]).arg(APPLY_DIFF) << endl; + out << trUtf8(" %1, %2\t Don't preview the generated diff code when applying it to the server.").arg(short_opts[NO_DIFF_PREVIEW]).arg(NO_DIFF_PREVIEW) << endl; out << trUtf8(" %1, %2\t Drop cluster level objects like roles and tablespaces.").arg(short_opts[DROP_CLUSTER_OBJS]).arg(DROP_CLUSTER_OBJS) << endl; out << trUtf8(" %1, %2\t\t Revoke permissions already set on the database. New permissions configured in the input model are still applied.").arg(short_opts[REVOKE_PERMISSIONS]).arg(REVOKE_PERMISSIONS) << endl; out << trUtf8(" %1, %2\t\t Drop missing objects. Generates DROP commands for objects that are present in the input model but not in the compared database.").arg(short_opts[DROP_MISSING_OBJS]).arg(DROP_MISSING_OBJS) << endl; out << trUtf8(" %1, %2\t Force the drop of missing columns and constraints. Causes only columns and constraints to be dropped, other missing objects aren't removed.").arg(short_opts[FORCE_DROP_COLS_CONSTRS]).arg(FORCE_DROP_COLS_CONSTRS) << endl; - out << trUtf8(" %1, %2\t\t Rename the destination database. When the databases have different names the destination one has its name changed.").arg(short_opts[RENAME_DB]).arg(RENAME_DB) << endl; + out << trUtf8(" %1, %2\t\t Rename the destination database when the names of the involved databases are different.").arg(short_opts[RENAME_DB]).arg(RENAME_DB) << endl; out << trUtf8(" %1, %2\t\t Don't drop or truncate objects in cascade mode.").arg(short_opts[NO_CASCADE_DROP_TRUNC]).arg(NO_CASCADE_DROP_TRUNC) << endl; out << trUtf8(" %1, %2\t Truncate tables prior to alter columns. Avoids errors related to type casting when the new type of a column isn't compatible to the old one.").arg(short_opts[TRUNC_ON_COLS_TYPE_CHANGE]).arg(TRUNC_ON_COLS_TYPE_CHANGE) << endl; out << trUtf8(" %1, %2\t Don't reuse sequences on serial columns. Drop the old sequence assigned to a serial column and creates a new one.").arg(short_opts[NO_SEQUENCE_REUSE]).arg(NO_SEQUENCE_REUSE) << endl; From 01bf0facb58f866cc7ebc40203203b0d7fa01232 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Tue, 24 Apr 2018 16:40:56 -0300 Subject: [PATCH 03/30] Detecting the PostgreSQL version when diffing databases in CLI --- main-cli/src/pgmodelercli.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/main-cli/src/pgmodelercli.cpp b/main-cli/src/pgmodelercli.cpp index 1ab1809edf..7a91ff94e2 100644 --- a/main-cli/src/pgmodelercli.cpp +++ b/main-cli/src/pgmodelercli.cpp @@ -1344,6 +1344,15 @@ void PgModelerCLI::diffModelDatabase(void) diff_hlp.setDiffOption(ModelsDiffHelper::OPT_DONT_DROP_MISSING_OBJS, !parsed_opts.count(DROP_MISSING_OBJS)); diff_hlp.setDiffOption(ModelsDiffHelper::OPT_DROP_MISSING_COLS_CONSTR, !parsed_opts.count(FORCE_DROP_COLS_CONSTRS)); + if(!parsed_opts[PGSQL_VER].isEmpty()) + diff_hlp.setPgSQLVersion(parsed_opts[PGSQL_VER]); + else + { + extra_connection.connect(); + diff_hlp.setPgSQLVersion(extra_connection.getPgSQLVersion(true)); + extra_connection.close(); + } + printMessage(trUtf8("Comparing the generated models...")); diff_hlp.diffModels(); From 42a3a6587777b0a68b5cf3d02fb1db3bb5373385 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Wed, 25 Apr 2018 09:25:25 -0300 Subject: [PATCH 04/30] Added support to RESTART IDENTITY on truncate tables in DatabaseExplorerWidget Added an custom option checkbox in Messagebox for general purpose usage. --- libparsers/src/parsersattributes.cpp | 1 + libparsers/src/parsersattributes.h | 1 + .../src/databaseexplorerwidget.cpp | 3 +- libpgmodeler_ui/src/messagebox.cpp | 17 +- libpgmodeler_ui/src/messagebox.h | 3 + libpgmodeler_ui/ui/messagebox.ui | 356 ++++++++++-------- schemas/alter/truncate.sch | 11 +- 7 files changed, 230 insertions(+), 162 deletions(-) diff --git a/libparsers/src/parsersattributes.cpp b/libparsers/src/parsersattributes.cpp index dd0f7709ba..c68a77b855 100644 --- a/libparsers/src/parsersattributes.cpp +++ b/libparsers/src/parsersattributes.cpp @@ -410,6 +410,7 @@ namespace ParsersAttributes { RENAME=QString("rename"), REPLICATION=QString("replication"), RESTRICTION_FUNC=QString("restriction"), + RESTART_SEQ=QString("restart-seq"), RETURN_TABLE=QString("return-table"), RETURN_TYPE=QString("return-type"), RETURNS_SETOF=QString("returns-setof"), diff --git a/libparsers/src/parsersattributes.h b/libparsers/src/parsersattributes.h index d06ce98284..4e4a78bd14 100644 --- a/libparsers/src/parsersattributes.h +++ b/libparsers/src/parsersattributes.h @@ -424,6 +424,7 @@ namespace ParsersAttributes { RELATIONSHIP, RENAME, REPLICATION, + RESTART_SEQ, RESTRICTION_FUNC, RETURN_TABLE, RETURN_TYPE, diff --git a/libpgmodeler_ui/src/databaseexplorerwidget.cpp b/libpgmodeler_ui/src/databaseexplorerwidget.cpp index 395c187a24..d93cc10784 100644 --- a/libpgmodeler_ui/src/databaseexplorerwidget.cpp +++ b/libpgmodeler_ui/src/databaseexplorerwidget.cpp @@ -1268,6 +1268,7 @@ void DatabaseExplorerWidget::truncateTable(QTreeWidgetItem *item, bool cascade) else msg=trUtf8("Do you really want to cascade truncate the table %1? This action will truncate all the tables that depends on it?").arg(obj_name); + msg_box.setCustomOptionText(trUtf8("Also restart sequences")); msg_box.show(msg, Messagebox::CONFIRM_ICON, Messagebox::YES_NO_BUTTONS); if(msg_box.result()==QDialog::Accepted) @@ -1279,7 +1280,7 @@ void DatabaseExplorerWidget::truncateTable(QTreeWidgetItem *item, bool cascade) attribs[ParsersAttributes::SQL_OBJECT]=BaseObject::getSQLName(OBJ_TABLE); attribs[ParsersAttributes::SIGNATURE]=sch_name + QString(".\"%1\"").arg(obj_name); attribs[ParsersAttributes::CASCADE]=(cascade ? ParsersAttributes::_TRUE_ : ""); - + attribs[ParsersAttributes::RESTART_SEQ]=(msg_box.isCustomOptionChecked() ? ParsersAttributes::_TRUE_ : ""); //Generate the truncate command schparser.ignoreEmptyAttributes(true); diff --git a/libpgmodeler_ui/src/messagebox.cpp b/libpgmodeler_ui/src/messagebox.cpp index efa66df897..4120492e6a 100644 --- a/libpgmodeler_ui/src/messagebox.cpp +++ b/libpgmodeler_ui/src/messagebox.cpp @@ -31,8 +31,10 @@ Messagebox::Messagebox(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f) connect(show_errors_tb,SIGNAL(clicked()),this,SLOT(showExceptionList())); connect(show_errors_tb,SIGNAL(toggled(bool)),show_raw_info_tb,SLOT(setVisible(bool))); connect(show_raw_info_tb,SIGNAL(toggled(bool)),this,SLOT(showExceptionList(void))); - show_errors_tb->setVisible(false); + show_raw_info_tb->setVisible(false); + error_show_btns_wgt->setVisible(false); + custom_option_chk->setVisible(false); } void Messagebox::handleYesOkClick(void) @@ -62,6 +64,17 @@ bool Messagebox::isCancelled(void) return(cancelled); } +void Messagebox::setCustomOptionText(const QString &text) +{ + custom_option_chk->setVisible(!text.isEmpty()); + custom_option_chk->setText(text); +} + +bool Messagebox::isCustomOptionChecked(void) +{ + return(custom_option_chk->isChecked()); +} + void Messagebox::showExceptionList(void) { if(show_errors_tb->isChecked()) @@ -188,7 +201,7 @@ void Messagebox::show(const QString &title, const QString &msg, unsigned icon_ty this->setWindowTitle(aux_title); this->objs_group_wgt->setCurrentIndex(0); this->show_errors_tb->setChecked(false); - this->show_errors_tb->setVisible((exceptions_trw->topLevelItemCount() > 0)); + error_show_btns_wgt->setVisible((exceptions_trw->topLevelItemCount() > 0)); showExceptionList(); this->resize(this->minimumWidth(), this->minimumHeight()); diff --git a/libpgmodeler_ui/src/messagebox.h b/libpgmodeler_ui/src/messagebox.h index d549e1fb15..69228e1c36 100644 --- a/libpgmodeler_ui/src/messagebox.h +++ b/libpgmodeler_ui/src/messagebox.h @@ -67,6 +67,9 @@ class Messagebox: public QDialog, public Ui::Messagebox { bool isCancelled(void); + void setCustomOptionText(const QString &text); + bool isCustomOptionChecked(void); + private slots: void handleYesOkClick(void); void handleNoCancelClick(void); diff --git a/libpgmodeler_ui/ui/messagebox.ui b/libpgmodeler_ui/ui/messagebox.ui index 9f1a235117..38e5e05b28 100644 --- a/libpgmodeler_ui/ui/messagebox.ui +++ b/libpgmodeler_ui/ui/messagebox.ui @@ -10,7 +10,7 @@ 0 0 500 - 175 + 244 @@ -105,7 +105,7 @@ 0 - + 0 @@ -118,91 +118,121 @@ 0 - - 0 - - - - 2 + + + + 40 + 40 + - - - - - 40 - 40 - - - - - 40 - 40 - - - - - - - Qt::AlignCenter - - - - - - - true - - - - 0 - 0 - + + + 40 + 40 + + + + + + + Qt::AlignCenter + + + + + + + true + + + + 0 + 0 + + + + + 0 + 90 + + + + + 16777215 + 16777215 + + + + false + + + false + + + + + + msg + + + Qt::RichText + + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + 4 + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Qt::Vertical + + + + 20 + 84 + + + + + + + + + + Qt::Horizontal - - - 0 - 90 - + + QSizePolicy::Fixed - + - 16777215 - 16777215 + 5 + 20 - - false - - - false - - - - + + + + - msg - - - Qt::RichText - - - true - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - 4 - - - true - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + @@ -316,86 +346,100 @@ - - - - Qt::Horizontal - - + + + - 414 - 27 + 0 + 0 - - - - - - 4 - - - 4 - - - - - - 0 - 0 - - - - Show raw text errors or information. - - - - - - - :/icones/icones/codigofonte.png:/icones/icones/codigofonte.png - - - - 22 - 22 - - - - true - - - - - - - - 0 - 0 - - - - Show/hide exceptions stack. - - - ... - - - - :/icones/icones/refazer.png:/icones/icones/refazer.png - - - - 22 - 22 - - - - true - - - - + + + 0 + + + 0 + + + 4 + + + 4 + + + + + Qt::Horizontal + + + + 415 + 24 + + + + + + + + + 0 + 0 + + + + Show raw text errors or information. + + + + + + + :/icones/icones/codigofonte.png:/icones/icones/codigofonte.png + + + + 22 + 22 + + + + true + + + + + + + + 0 + 0 + + + + Show/hide exceptions stack. + + + ... + + + + :/icones/icones/refazer.png:/icones/icones/refazer.png + + + + 22 + 22 + + + + true + + + + + diff --git a/schemas/alter/truncate.sch b/schemas/alter/truncate.sch index f7b26cbb44..39a822b513 100644 --- a/schemas/alter/truncate.sch +++ b/schemas/alter/truncate.sch @@ -5,9 +5,14 @@ [TRUNCATE ] {sql-object} $sp {signature} +%if {restart-seq} %then + [ RESTART IDENTITY ] +%end + %if {cascade} %then - [ CASCADE] - %end - ; + [ CASCADE] +%end + +; $br [-- ddl-end --] $br From 061ed7be596b8b870e7fd6bdb7511bb098bd7c97 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Wed, 25 Apr 2018 09:47:40 -0300 Subject: [PATCH 05/30] Minor improvement in the text find widgets in SQLExecutionWidget in order to make them closable via dedicated button --- libpgmodeler_ui/src/sqlexecutionwidget.cpp | 2 ++ libpgmodeler_ui/ui/findreplacewidget.ui | 31 +++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/libpgmodeler_ui/src/sqlexecutionwidget.cpp b/libpgmodeler_ui/src/sqlexecutionwidget.cpp index 18d8acf839..fa4405d14d 100644 --- a/libpgmodeler_ui/src/sqlexecutionwidget.cpp +++ b/libpgmodeler_ui/src/sqlexecutionwidget.cpp @@ -51,6 +51,7 @@ SQLExecutionWidget::SQLExecutionWidget(QWidget * parent) : QWidget(parent) layout->addWidget(find_history_wgt); find_history_parent->setLayout(layout); find_history_parent->setVisible(false); + connect(find_history_wgt->hide_tb, SIGNAL(clicked(bool)), find_history_parent, SLOT(hide())); sql_cmd_hl=new SyntaxHighlighter(sql_cmd_txt, false); sql_cmd_hl->loadConfiguration(GlobalAttributes::SQL_HIGHLIGHT_CONF_PATH); @@ -74,6 +75,7 @@ SQLExecutionWidget::SQLExecutionWidget(QWidget * parent) : QWidget(parent) hbox->setContentsMargins(0,0,0,0); hbox->addWidget(find_replace_wgt); find_wgt_parent->setVisible(false); + connect(find_replace_wgt->hide_tb, SIGNAL(clicked(bool)), find_tb, SLOT(toggle())); run_sql_tb->setToolTip(run_sql_tb->toolTip() + QString(" (%1)").arg(run_sql_tb->shortcut().toString())); export_tb->setToolTip(export_tb->toolTip() + QString(" (%1)").arg(export_tb->shortcut().toString())); diff --git a/libpgmodeler_ui/ui/findreplacewidget.ui b/libpgmodeler_ui/ui/findreplacewidget.ui index 9bdea1a4c4..d5972e866d 100644 --- a/libpgmodeler_ui/ui/findreplacewidget.ui +++ b/libpgmodeler_ui/ui/findreplacewidget.ui @@ -7,7 +7,7 @@ 0 0 704 - 62 + 64 @@ -170,6 +170,35 @@ + + + + + 20 + 20 + + + + + 20 + 20 + + + + Hide this widget + + + ... + + + + :/icones/icones/fechar1.png:/icones/icones/fechar1.png + + + true + + + From 0b592180173e3d5748e5e8a861c52d706cc16347 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Wed, 25 Apr 2018 11:46:26 -0300 Subject: [PATCH 06/30] Minor improvement in SQLExecutionWidget to show the amount of time took to run a query --- libpgmodeler_ui/src/sqlexecutionwidget.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libpgmodeler_ui/src/sqlexecutionwidget.cpp b/libpgmodeler_ui/src/sqlexecutionwidget.cpp index fa4405d14d..b00fa0af62 100644 --- a/libpgmodeler_ui/src/sqlexecutionwidget.cpp +++ b/libpgmodeler_ui/src/sqlexecutionwidget.cpp @@ -416,6 +416,7 @@ void SQLExecutionWidget::runSQLCommand(void) { ResultSet res; QStringList conn_notices; + qint64 start_exec=0, end_exec=0, total_exec = 0; output_tb->setChecked(true); @@ -436,9 +437,11 @@ void SQLExecutionWidget::runSQLCommand(void) } QApplication::setOverrideCursor(Qt::WaitCursor); + + start_exec=QDateTime::currentDateTime().toMSecsSinceEpoch(); sql_cmd_conn.executeDMLCommand(cmd, res); - conn_notices=sql_cmd_conn.getNotices(); + conn_notices=sql_cmd_conn.getNotices(); addToSQLHistory(cmd, res.getTupleCount()); output_tbw->setTabEnabled(0, !res.isEmpty()); @@ -474,9 +477,13 @@ void SQLExecutionWidget::runSQLCommand(void) QPixmap(PgModelerUiNS::getIconPath("msgbox_alerta"))); } + end_exec=QDateTime::currentDateTime().toMSecsSinceEpoch(); + total_exec = end_exec - start_exec; + PgModelerUiNS::createOutputListItem(msgoutput_lst, - PgModelerUiNS::formatMessage(trUtf8("[%1]: SQL command successfully executed. %2 %3") + PgModelerUiNS::formatMessage(trUtf8("[%1]: SQL command successfully executed in %2. %3 %4") .arg(QTime::currentTime().toString(QString("hh:mm:ss.zzz"))) + .arg(total_exec >= 1000 ? QString("%1 s").arg(total_exec/1000) : QString("%1 ms").arg(total_exec)) .arg(res.isEmpty() ? trUtf8("Rows affected") : trUtf8("Rows retrieved")) .arg(res.getTupleCount())), QPixmap(PgModelerUiNS::getIconPath("msgbox_info"))); From e446f75c2f75aac4aaddca651d741ea985ba7947 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Thu, 26 Apr 2018 11:19:51 -0300 Subject: [PATCH 07/30] Improved the SQLExecutionWidget in such way that it'll display large amount of data more quickly and consuming less memory. --- libpgmodeler_ui/libpgmodeler_ui.pro | 6 +- libpgmodeler_ui/src/resultsetmodel.cpp | 137 +++++++++++++++++++++ libpgmodeler_ui/src/resultsetmodel.h | 53 ++++++++ libpgmodeler_ui/src/sqlexecutionwidget.cpp | 29 ++++- libpgmodeler_ui/src/sqlexecutionwidget.h | 4 + libpgmodeler_ui/ui/sqlexecutionwidget.ui | 30 ++++- 6 files changed, 255 insertions(+), 4 deletions(-) create mode 100644 libpgmodeler_ui/src/resultsetmodel.cpp create mode 100644 libpgmodeler_ui/src/resultsetmodel.h diff --git a/libpgmodeler_ui/libpgmodeler_ui.pro b/libpgmodeler_ui/libpgmodeler_ui.pro index e0eacb7103..48455934a5 100644 --- a/libpgmodeler_ui/libpgmodeler_ui.pro +++ b/libpgmodeler_ui/libpgmodeler_ui.pro @@ -112,7 +112,8 @@ SOURCES += src/mainwindow.cpp \ src/sceneinfowidget.cpp \ src/bulkdataeditwidget.cpp \ src/policywidget.cpp \ - src/objectstablewidget.cpp + src/objectstablewidget.cpp \ + src/resultsetmodel.cpp HEADERS += src/mainwindow.h \ @@ -212,7 +213,8 @@ HEADERS += src/mainwindow.h \ src/sceneinfowidget.h \ src/bulkdataeditwidget.h \ src/policywidget.h \ - src/objectstablewidget.h + src/objectstablewidget.h \ + src/resultsetmodel.h FORMS += ui/mainwindow.ui \ ui/textboxwidget.ui \ diff --git a/libpgmodeler_ui/src/resultsetmodel.cpp b/libpgmodeler_ui/src/resultsetmodel.cpp new file mode 100644 index 0000000000..425c7da751 --- /dev/null +++ b/libpgmodeler_ui/src/resultsetmodel.cpp @@ -0,0 +1,137 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2018 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +#include "resultsetmodel.h" + +ResultSetModel::ResultSetModel(ResultSet &res, Catalog &catalog, QObject *parent) : QAbstractTableModel(parent) +{ + try + { + Catalog aux_cat = catalog; + vector type_ids; + vector::iterator end; + vector types; + map type_names; + int col = 0; + + col_cnt = res.getColumnCount(); + row_cnt = res.getTupleCount(); + insertColumns(0, col_cnt); + insertRows(0, row_cnt); + + for(col=0; col < col_cnt; col++) + { + header_data.push_back(res.getColumnName(col)); + type_ids.push_back(res.getColumnTypeId(col)); + } + + if(res.accessTuple(ResultSet::FIRST_TUPLE)) + { + do + { + //Fills the current row with the values of current tuple + for(int col=0; col < col_cnt; col++) + { + if(res.isColumnBinaryFormat(col)) + item_data.push_back(trUtf8("[binary data]")); + else + item_data.push_back(res.getColumnValue(col)); + } + } + while(res.accessTuple(ResultSet::NEXT_TUPLE)); + } + + aux_cat.setFilter(Catalog::LIST_ALL_OBJS); + std::sort(type_ids.begin(), type_ids.end()); + end=std::unique(type_ids.begin(), type_ids.end()); + type_ids.erase(end, type_ids.end()); + + types = aux_cat.getObjectsAttributes(OBJ_TYPE, QString(), QString(), type_ids); + col = 0; + + for(auto &tp : types) + type_names[tp[ParsersAttributes::OID].toInt()]=tp[ParsersAttributes::NAME]; + + for(col=0; col < col_cnt; col++) + tooltip_data.push_back(type_names[res.getColumnTypeId(col)]); + } + catch(Exception &e) + { + throw Exception(e.getErrorMessage(), e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} + +int ResultSetModel::rowCount(const QModelIndex &) const +{ + return(row_cnt); +} + +int ResultSetModel::columnCount(const QModelIndex &) const +{ + return(col_cnt); +} + +QModelIndex ResultSetModel::index(int row, int column, const QModelIndex &parent) const +{ + return(QAbstractTableModel::index(row, column, parent)); +} + +QModelIndex ResultSetModel::parent(const QModelIndex &) const +{ + return(QModelIndex()); +} + +QVariant ResultSetModel::data(const QModelIndex &index, int role) const +{ + if(index.row() < row_cnt && index.column() < col_cnt) + { + if(role == Qt::DisplayRole) + return(item_data.at(index.row() * col_cnt + index.column())); + + if(role == Qt::TextAlignmentRole) + return(QVariant(Qt::AlignLeft | Qt::AlignVCenter)); + } + + return(QVariant(QVariant::Invalid)); +} + +QVariant ResultSetModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation == Qt::Horizontal) + { + if(section >= col_cnt) + return(QVariant(QVariant::Invalid)); + + if(role == Qt::DisplayRole) + return(header_data.at(section)); + + if(role == Qt::ToolTipRole) + return(tooltip_data.at(section)); + + if(role == Qt::TextAlignmentRole) + return(QVariant(Qt::AlignLeft | Qt::AlignVCenter)); + } + + return(QAbstractTableModel::headerData(section, orientation, role)); +} + +Qt::ItemFlags ResultSetModel::flags(const QModelIndex &) const +{ + return(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled ); +} + diff --git a/libpgmodeler_ui/src/resultsetmodel.h b/libpgmodeler_ui/src/resultsetmodel.h new file mode 100644 index 0000000000..bb961cfd2b --- /dev/null +++ b/libpgmodeler_ui/src/resultsetmodel.h @@ -0,0 +1,53 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2018 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +/** +\ingroup libpgmodeler_ui +\class ResultSetModel +\brief Implements a model representation of ResultSet class which can be used to show large amount of data in instances of QTableView. +*/ + +#ifndef RESULT_SET_MODEL_H +#define RESULT_SET_MODEL_H + +#include +#include "resultset.h" +#include "catalog.h" + +class ResultSetModel: public QAbstractTableModel { + private: + Q_OBJECT + + int col_cnt, row_cnt; + QStringList item_data, header_data, tooltip_data; + + void insertColumn(int, const QModelIndex &){} + void insertRow(int, const QModelIndex &){} + + public: + ResultSetModel(ResultSet &res, Catalog &catalog, QObject *parent = 0); + virtual int rowCount(const QModelIndex &) const; + virtual int columnCount(const QModelIndex &) const; + virtual QModelIndex index(int row, int column, const QModelIndex &parent) const; + virtual QModelIndex parent(const QModelIndex &) const; + virtual QVariant data(const QModelIndex &index, int role) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; + virtual Qt::ItemFlags flags(const QModelIndex &) const; +}; + +#endif diff --git a/libpgmodeler_ui/src/sqlexecutionwidget.cpp b/libpgmodeler_ui/src/sqlexecutionwidget.cpp index b00fa0af62..85bf035ade 100644 --- a/libpgmodeler_ui/src/sqlexecutionwidget.cpp +++ b/libpgmodeler_ui/src/sqlexecutionwidget.cpp @@ -34,6 +34,8 @@ SQLExecutionWidget::SQLExecutionWidget(QWidget * parent) : QWidget(parent) { setupUi(this); + result_model = nullptr; + sql_cmd_txt=PgModelerUiNS::createNumberedTextEditor(sql_cmd_wgt); cmd_history_txt=PgModelerUiNS::createNumberedTextEditor(cmd_history_parent); cmd_history_txt->setCustomContextMenuEnabled(false); @@ -84,6 +86,7 @@ SQLExecutionWidget::SQLExecutionWidget(QWidget * parent) : QWidget(parent) find_tb->setToolTip(find_tb->toolTip() + QString(" (%1)").arg(find_tb->shortcut().toString())); results_tbw->setItemDelegate(new PlainTextItemDelegate(this, true)); + tableView->setItemDelegate(new PlainTextItemDelegate(this, true)); action_load=new QAction(QIcon(PgModelerUiNS::getIconPath("abrir")), trUtf8("Load"), this); action_save=new QAction(QIcon(PgModelerUiNS::getIconPath("salvar")), trUtf8("Save"), this); @@ -129,6 +132,16 @@ SQLExecutionWidget::SQLExecutionWidget(QWidget * parent) : QWidget(parent) v_splitter->handle(1)->installEventFilter(this); } +SQLExecutionWidget::~SQLExecutionWidget(void) +{ + if(result_model) + { + tableView->blockSignals(true); + tableView->setModel(nullptr); + delete(result_model); + } +} + bool SQLExecutionWidget::eventFilter(QObject *object, QEvent *event) { if(event->type() == QEvent::MouseButtonDblClick && object == v_splitter->handle(1)) @@ -187,7 +200,21 @@ void SQLExecutionWidget::fillResultsTable(ResultSet &res) aux_conn.setConnectionParams(sql_cmd_conn.getConnectionParams()); export_tb->setEnabled(res.getTupleCount() > 0); catalog.setConnection(aux_conn); - fillResultsTable(catalog, res, results_tbw); + + tableView->setSortingEnabled(false); + tableView->blockSignals(true); + tableView->setUpdatesEnabled(false); + tableView->setModel(nullptr); + + if(result_model) + delete(result_model); + + result_model = new ResultSetModel(res, catalog); + + tableView->setModel(result_model); + tableView->resizeColumnsToContents(); + tableView->setUpdatesEnabled(true); + tableView->blockSignals(false); } catch(Exception &e) { diff --git a/libpgmodeler_ui/src/sqlexecutionwidget.h b/libpgmodeler_ui/src/sqlexecutionwidget.h index 8257fc1352..858d46247e 100644 --- a/libpgmodeler_ui/src/sqlexecutionwidget.h +++ b/libpgmodeler_ui/src/sqlexecutionwidget.h @@ -33,6 +33,7 @@ #include "codecompletionwidget.h" #include "numberedtexteditor.h" #include "findreplacewidget.h" +#include "resultsetmodel.h" class SQLExecutionWidget: public QWidget, public Ui::SQLExecutionWidget { private: @@ -74,6 +75,8 @@ class SQLExecutionWidget: public QWidget, public Ui::SQLExecutionWidget { FindReplaceWidget *find_history_wgt; + ResultSetModel *result_model; + /*! \brief Enables/Disables the fields for sql input and execution. When enabling a new connection to server will be opened. */ void enableSQLExecution(bool enable); @@ -103,6 +106,7 @@ class SQLExecutionWidget: public QWidget, public Ui::SQLExecutionWidget { static const QString COLUMN_NULL_VALUE; SQLExecutionWidget(QWidget * parent = 0); + ~SQLExecutionWidget(void); //! \brief Configures the connection to query the server void setConnection(Connection conn); diff --git a/libpgmodeler_ui/ui/sqlexecutionwidget.ui b/libpgmodeler_ui/ui/sqlexecutionwidget.ui index 60d3821d04..5e0821246c 100644 --- a/libpgmodeler_ui/ui/sqlexecutionwidget.ui +++ b/libpgmodeler_ui/ui/sqlexecutionwidget.ui @@ -581,7 +581,7 @@ 4 - + @@ -655,6 +655,34 @@ + + + + QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed + + + true + + + QAbstractItemView::ContiguousSelection + + + true + + + false + + + true + + + true + + + 25 + + + From 1885f34d44f06dba6cdf9d615920720fd8446d0c Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Thu, 26 Apr 2018 15:53:14 -0300 Subject: [PATCH 08/30] Refactored the methods in SQLExecutionWidget that copy results grid as text and csv to accept QTableView instance instead of QTableWidget --- libpgmodeler_ui/src/resultsetmodel.cpp | 24 +-- libpgmodeler_ui/src/resultsetmodel.h | 2 +- libpgmodeler_ui/src/sqlexecutionwidget.cpp | 198 ++++++++++----------- libpgmodeler_ui/src/sqlexecutionwidget.h | 11 +- libpgmodeler_ui/ui/sqlexecutionwidget.ui | 64 ++----- 5 files changed, 123 insertions(+), 176 deletions(-) diff --git a/libpgmodeler_ui/src/resultsetmodel.cpp b/libpgmodeler_ui/src/resultsetmodel.cpp index 425c7da751..548ff7c3da 100644 --- a/libpgmodeler_ui/src/resultsetmodel.cpp +++ b/libpgmodeler_ui/src/resultsetmodel.cpp @@ -29,12 +29,12 @@ ResultSetModel::ResultSetModel(ResultSet &res, Catalog &catalog, QObject *parent map type_names; int col = 0; - col_cnt = res.getColumnCount(); - row_cnt = res.getTupleCount(); - insertColumns(0, col_cnt); - insertRows(0, row_cnt); + col_count = res.getColumnCount(); + row_count = res.getTupleCount(); + insertColumns(0, col_count); + insertRows(0, row_count); - for(col=0; col < col_cnt; col++) + for(col=0; col < col_count; col++) { header_data.push_back(res.getColumnName(col)); type_ids.push_back(res.getColumnTypeId(col)); @@ -45,7 +45,7 @@ ResultSetModel::ResultSetModel(ResultSet &res, Catalog &catalog, QObject *parent do { //Fills the current row with the values of current tuple - for(int col=0; col < col_cnt; col++) + for(int col=0; col < col_count; col++) { if(res.isColumnBinaryFormat(col)) item_data.push_back(trUtf8("[binary data]")); @@ -67,7 +67,7 @@ ResultSetModel::ResultSetModel(ResultSet &res, Catalog &catalog, QObject *parent for(auto &tp : types) type_names[tp[ParsersAttributes::OID].toInt()]=tp[ParsersAttributes::NAME]; - for(col=0; col < col_cnt; col++) + for(col=0; col < col_count; col++) tooltip_data.push_back(type_names[res.getColumnTypeId(col)]); } catch(Exception &e) @@ -78,12 +78,12 @@ ResultSetModel::ResultSetModel(ResultSet &res, Catalog &catalog, QObject *parent int ResultSetModel::rowCount(const QModelIndex &) const { - return(row_cnt); + return(row_count); } int ResultSetModel::columnCount(const QModelIndex &) const { - return(col_cnt); + return(col_count); } QModelIndex ResultSetModel::index(int row, int column, const QModelIndex &parent) const @@ -98,10 +98,10 @@ QModelIndex ResultSetModel::parent(const QModelIndex &) const QVariant ResultSetModel::data(const QModelIndex &index, int role) const { - if(index.row() < row_cnt && index.column() < col_cnt) + if(index.row() < row_count && index.column() < col_count) { if(role == Qt::DisplayRole) - return(item_data.at(index.row() * col_cnt + index.column())); + return(item_data.at(index.row() * col_count + index.column())); if(role == Qt::TextAlignmentRole) return(QVariant(Qt::AlignLeft | Qt::AlignVCenter)); @@ -114,7 +114,7 @@ QVariant ResultSetModel::headerData(int section, Qt::Orientation orientation, in { if(orientation == Qt::Horizontal) { - if(section >= col_cnt) + if(section >= col_count) return(QVariant(QVariant::Invalid)); if(role == Qt::DisplayRole) diff --git a/libpgmodeler_ui/src/resultsetmodel.h b/libpgmodeler_ui/src/resultsetmodel.h index bb961cfd2b..ec1a6a5a34 100644 --- a/libpgmodeler_ui/src/resultsetmodel.h +++ b/libpgmodeler_ui/src/resultsetmodel.h @@ -33,7 +33,7 @@ class ResultSetModel: public QAbstractTableModel { private: Q_OBJECT - int col_cnt, row_cnt; + int col_count, row_count; QStringList item_data, header_data, tooltip_data; void insertColumn(int, const QModelIndex &){} diff --git a/libpgmodeler_ui/src/sqlexecutionwidget.cpp b/libpgmodeler_ui/src/sqlexecutionwidget.cpp index 85bf035ade..1cb0fdf919 100644 --- a/libpgmodeler_ui/src/sqlexecutionwidget.cpp +++ b/libpgmodeler_ui/src/sqlexecutionwidget.cpp @@ -86,7 +86,6 @@ SQLExecutionWidget::SQLExecutionWidget(QWidget * parent) : QWidget(parent) find_tb->setToolTip(find_tb->toolTip() + QString(" (%1)").arg(find_tb->shortcut().toString())); results_tbw->setItemDelegate(new PlainTextItemDelegate(this, true)); - tableView->setItemDelegate(new PlainTextItemDelegate(this, true)); action_load=new QAction(QIcon(PgModelerUiNS::getIconPath("abrir")), trUtf8("Load"), this); action_save=new QAction(QIcon(PgModelerUiNS::getIconPath("salvar")), trUtf8("Save"), this); @@ -108,7 +107,7 @@ SQLExecutionWidget::SQLExecutionWidget(QWidget * parent) : QWidget(parent) connect(output_tb, SIGNAL(toggled(bool)), this, SLOT(toggleOutputPane(bool))); //Signal handling with C++11 lambdas Slots - connect(results_tbw, &QTableWidget::itemPressed, + connect(results_tbw, &QTableView::pressed, [&](){ SQLExecutionWidget::copySelection(results_tbw); }); connect(export_tb, &QToolButton::clicked, @@ -136,8 +135,8 @@ SQLExecutionWidget::~SQLExecutionWidget(void) { if(result_model) { - tableView->blockSignals(true); - tableView->setModel(nullptr); + results_tbw->blockSignals(true); + results_tbw->setModel(nullptr); delete(result_model); } } @@ -201,20 +200,20 @@ void SQLExecutionWidget::fillResultsTable(ResultSet &res) export_tb->setEnabled(res.getTupleCount() > 0); catalog.setConnection(aux_conn); - tableView->setSortingEnabled(false); - tableView->blockSignals(true); - tableView->setUpdatesEnabled(false); - tableView->setModel(nullptr); + results_tbw->setSortingEnabled(false); + results_tbw->blockSignals(true); + results_tbw->setUpdatesEnabled(false); + results_tbw->setModel(nullptr); if(result_model) delete(result_model); result_model = new ResultSetModel(res, catalog); - tableView->setModel(result_model); - tableView->resizeColumnsToContents(); - tableView->setUpdatesEnabled(true); - tableView->blockSignals(false); + results_tbw->setModel(result_model); + results_tbw->resizeColumnsToContents(); + results_tbw->setUpdatesEnabled(true); + results_tbw->blockSignals(false); } catch(Exception &e) { @@ -478,16 +477,8 @@ void SQLExecutionWidget::runSQLCommand(void) if(!res.isEmpty()) { fillResultsTable(res); - output_tbw->setTabText(0, trUtf8("Results (%1)").arg(results_tbw->rowCount())); - - if(res.getTupleCount() > max_result_rows) - { - conn_notices.append(trUtf8("The number of retrieved rows exceeds the maximum allowed in the results grid! The data was trucated.")); - conn_notices.append(trUtf8("Try to limit the result set by adjusting the query.")); - output_tbw->setCurrentIndex(1); - } - else - output_tbw->setCurrentIndex(0); + output_tbw->setTabText(0, trUtf8("Results (%1)").arg(results_tbw->model()->rowCount())); + output_tbw->setCurrentIndex(0); } else { @@ -587,7 +578,7 @@ void SQLExecutionWidget::loadCommands(void) } } -void SQLExecutionWidget::exportResults(QTableWidget *results_tbw) +void SQLExecutionWidget::exportResults(QTableView *results_tbw) { if(!results_tbw) throw Exception(ERR_OPR_NOT_ALOC_OBJECT ,__PRETTY_FUNCTION__,__FILE__,__LINE__); @@ -613,8 +604,18 @@ void SQLExecutionWidget::exportResults(QTableWidget *results_tbw) .arg(csv_file_dlg.selectedFiles().at(0)) , ERR_FILE_DIR_NOT_ACCESSED ,__PRETTY_FUNCTION__,__FILE__,__LINE__); - file.write(generateCSVBuffer(results_tbw, 0, 0, results_tbw->rowCount(), results_tbw->columnCount())); + QApplication::setOverrideCursor(Qt::WaitCursor); + results_tbw->setUpdatesEnabled(false); + results_tbw->blockSignals(true); + results_tbw->selectAll(); + + file.write(generateCSVBuffer(results_tbw)); file.close(); + + results_tbw->clearSelection(); + results_tbw->blockSignals(false); + results_tbw->setUpdatesEnabled(true); + QApplication::restoreOverrideCursor(); } } @@ -628,111 +629,102 @@ int SQLExecutionWidget::getMaxResultRows(void) return(max_result_rows); } -QByteArray SQLExecutionWidget::generateCSVBuffer(QTableWidget *results_tbw, int start_row, int start_col, int row_cnt, int col_cnt) +int SQLExecutionWidget::clearAll(void) { - if(!results_tbw) - throw Exception(ERR_OPR_NOT_ALOC_OBJECT ,__PRETTY_FUNCTION__,__FILE__,__LINE__); - - QByteArray buf; - QStringList line; + Messagebox msg_box; + int res = 0; - //If the selection interval is valid - if(start_row >=0 && start_col >=0 && - start_row + row_cnt <= results_tbw->rowCount() && - start_col + col_cnt <= results_tbw->columnCount()) - { - int col=0, row=0, - max_col=start_col + col_cnt, - max_row=start_row + row_cnt; + msg_box.show(trUtf8("The SQL input field and the results grid will be cleared! Want to proceed?"), + Messagebox::CONFIRM_ICON, Messagebox::YES_NO_BUTTONS); - //Creating the header of csv - for(col=start_col; col < max_col; col++) - line.append(QString("\"%1\"").arg(results_tbw->horizontalHeaderItem(col)->text())); + res = msg_box.result(); - buf.append(line.join(';')); - buf.append('\n'); - line.clear(); + if(res==QDialog::Accepted) + { + sql_cmd_txt->setPlainText(QString()); + msgoutput_lst->clear(); + msgoutput_lst->setVisible(true); + results_parent->setVisible(false); + export_tb->setEnabled(false); + } - //Creating the content - for(row=start_row; row < max_row; row++) - { - for(col=start_col; col < max_col; col++) - line.append(QString("\"%1\"").arg(results_tbw->item(row, col)->text())); + return(res); +} - buf.append(line.join(';')); - line.clear(); - buf.append('\n'); - } - } +QByteArray SQLExecutionWidget::generateCSVBuffer(QTableView *results_tbw) +{ + return(generateBuffer(results_tbw, QChar(';'), true, true)); +} - return(buf); +QByteArray SQLExecutionWidget::generateTextBuffer(QTableView *results_tbw) +{ + return(generateBuffer(results_tbw, QChar('\t'), false, false)); } -QByteArray SQLExecutionWidget::generateTextBuffer(QTableWidget *results_tbw, int start_row, int start_col, int row_cnt, int col_cnt) +QByteArray SQLExecutionWidget::generateBuffer(QTableView *results_tbw, QChar separator, bool incl_col_names, bool use_quotes) { if(!results_tbw) throw Exception(ERR_OPR_NOT_ALOC_OBJECT ,__PRETTY_FUNCTION__,__FILE__,__LINE__); + if(!results_tbw->selectionModel()) + return (QByteArray()); + + QAbstractItemModel *model = results_tbw->model(); + QModelIndexList sel_indexes = results_tbw->selectionModel()->selectedIndexes(); QByteArray buf; QStringList line; + QModelIndex index; + QString str_pattern = use_quotes ? QString("\"%1\"") : QString("%1"); + int start_row = -1, start_col = -1, + row_cnt = 0, col_cnt = 0; - //If the selection interval is valid - if(start_row >=0 && start_col >=0 && - start_row + row_cnt <= results_tbw->rowCount() && - start_col + col_cnt <= results_tbw->columnCount()) - { - int col=0, row=0, - max_col=start_col + col_cnt, - max_row=start_row + row_cnt; - - //Creating the content - for(row=start_row; row < max_row; row++) - { - for(col=start_col; col < max_col; col++) - { - line.push_back(results_tbw->item(row, col)->text()); - } - - buf.append(line.join('\t')); - line.clear(); - buf.append('\n'); - } - } + start_row = sel_indexes.at(0).row(); + start_col = sel_indexes.at(0).column(); + row_cnt = (sel_indexes.last().row() - start_row) + 1; + col_cnt = (sel_indexes.last().column() - start_col) + 1; - return(buf); -} - -int SQLExecutionWidget::clearAll(void) -{ - Messagebox msg_box; - int res = 0; + int col=0, row=0, + max_col=start_col + col_cnt, + max_row=start_row + row_cnt; - msg_box.show(trUtf8("The SQL input field and the results grid will be cleared! Want to proceed?"), - Messagebox::CONFIRM_ICON, Messagebox::YES_NO_BUTTONS); + if(incl_col_names) + { + //Creating the header + for(col=start_col; col < max_col; col++) + line.append(str_pattern.arg(model->headerData(col, Qt::Horizontal).toString())); - res = msg_box.result(); + buf.append(line.join(separator)); + buf.append('\n'); + line.clear(); + } - if(res==QDialog::Accepted) + //Creating the content + for(row=start_row; row < max_row; row++) { - sql_cmd_txt->setPlainText(QString()); - msgoutput_lst->clear(); - msgoutput_lst->setVisible(true); - results_parent->setVisible(false); - export_tb->setEnabled(false); + for(col=start_col; col < max_col; col++) + { + index = model->index(row, col); + line.append(str_pattern.arg(index.data().toString())); + } + + buf.append(line.join(separator)); + line.clear(); + buf.append('\n'); } - return(res); + return(buf); } -void SQLExecutionWidget::copySelection(QTableWidget *results_tbw, bool use_popup, bool csv_is_default) +void SQLExecutionWidget::copySelection(QTableView *results_tbw, bool use_popup, bool csv_is_default) { if(!results_tbw) throw Exception(ERR_OPR_NOT_ALOC_OBJECT ,__PRETTY_FUNCTION__,__FILE__,__LINE__); - QList sel_ranges=results_tbw->selectedRanges(); + QItemSelectionModel *selection = results_tbw->selectionModel(); - if(sel_ranges.count()==1 && (!use_popup || (use_popup && QApplication::mouseButtons()==Qt::RightButton))) + if(selection && (!use_popup || (use_popup && QApplication::mouseButtons()==Qt::RightButton))) { + QModelIndexList sel_indexes = selection->selectedIndexes(); QMenu copy_menu, copy_mode_menu; QAction *act = nullptr, *act_csv = nullptr, *act_txt = nullptr; @@ -747,15 +739,13 @@ void SQLExecutionWidget::copySelection(QTableWidget *results_tbw, bool use_popup if(!use_popup || act) { - QTableWidgetSelectionRange selection=sel_ranges.at(0); + //QTableWidgetSelectionRange selection=sel_ranges.at(0); QByteArray buf; if((use_popup && act == act_csv) || (!use_popup && csv_is_default)) { //Generates the csv buffer and assigns it to application's clipboard - buf=generateCSVBuffer(results_tbw, - selection.topRow(), selection.leftColumn(), - selection.rowCount(), selection.columnCount()); + buf=generateCSVBuffer(results_tbw); /* Making DataManipulationForm instances know that the clipboard has csv buffer * in order to paste the contents properly */ @@ -763,9 +753,7 @@ void SQLExecutionWidget::copySelection(QTableWidget *results_tbw, bool use_popup } else if((use_popup && act == act_txt) || (!use_popup && !csv_is_default)) { - buf=generateTextBuffer(results_tbw, - selection.topRow(), selection.leftColumn(), - selection.rowCount(), selection.columnCount()); + buf=generateTextBuffer(results_tbw); } qApp->clipboard()->setText(buf); diff --git a/libpgmodeler_ui/src/sqlexecutionwidget.h b/libpgmodeler_ui/src/sqlexecutionwidget.h index 858d46247e..4081be8c37 100644 --- a/libpgmodeler_ui/src/sqlexecutionwidget.h +++ b/libpgmodeler_ui/src/sqlexecutionwidget.h @@ -116,16 +116,19 @@ class SQLExecutionWidget: public QWidget, public Ui::SQLExecutionWidget { static void fillResultsTable(Catalog &catalog, ResultSet &res, QTableWidget *results_tbw, bool store_data=false); //! \brief Copy to clipboard (in csv format) the current selected items on results grid - static void copySelection(QTableWidget *results_tbw, bool use_popup=true, bool csv_is_default = false); + static void copySelection(QTableView *results_tbw, bool use_popup=true, bool csv_is_default = false); //! \brief Generates a CSV buffer based upon the selection on the results grid - static QByteArray generateCSVBuffer(QTableWidget *results_tbw, int start_row, int start_col, int row_cnt, int col_cnt); + static QByteArray generateCSVBuffer(QTableView *results_tbw); //! \brief Generates a Plain text buffer based upon the selection on the results grid (this method does not include the column names) - static QByteArray generateTextBuffer(QTableWidget *results_tbw, int start_row, int start_col, int row_cnt, int col_cnt); + static QByteArray generateTextBuffer(QTableView *results_tbw); + + //! \brief Generates a custom text buffer. User can specify a separator for columns, include column names and quote values + static QByteArray generateBuffer(QTableView *results_tbw, QChar separator, bool incl_col_names, bool use_quotes); //! \brief Exports the results to csv file - static void exportResults(QTableWidget *results_tbw); + static void exportResults(QTableView *results_tbw); static void setMaxResultRows(int max_val); diff --git a/libpgmodeler_ui/ui/sqlexecutionwidget.ui b/libpgmodeler_ui/ui/sqlexecutionwidget.ui index 5e0821246c..16305c6758 100644 --- a/libpgmodeler_ui/ui/sqlexecutionwidget.ui +++ b/libpgmodeler_ui/ui/sqlexecutionwidget.ui @@ -605,14 +605,8 @@ 0 - - - - true - - - true - + + QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed @@ -622,67 +616,29 @@ QAbstractItemView::ContiguousSelection - - QAbstractItemView::ScrollPerItem - - - QAbstractItemView::ScrollPerPixel - - + + true + + false - + true + + true + 25 25 - - - ... - - - - - ... - - - - - - QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed - - - true - - - QAbstractItemView::ContiguousSelection - - - true - - - false - - - true - - - true - - - 25 - - - From 316d7ada8a3ce758094df7a21093e6f923f2b661 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Thu, 26 Apr 2018 17:54:57 -0300 Subject: [PATCH 09/30] Removed the experimental max rows limit from SQLExecutionWidget --- conf/defaults/pgmodeler.conf | 3 +- conf/dtd/pgmodeler.dtd | 1 - conf/pgmodeler.conf | 3 +- conf/schemas/pgmodeler.sch | 4 - libparsers/src/parsersattributes.cpp | 1 - libparsers/src/parsersattributes.h | 1 - libpgmodeler_ui/src/generalconfigwidget.cpp | 13 - libpgmodeler_ui/src/sqlexecutionwidget.cpp | 18 +- libpgmodeler_ui/src/sqlexecutionwidget.h | 10 - libpgmodeler_ui/ui/datamanipulationform.ui | 7 +- libpgmodeler_ui/ui/generalconfigwidget.ui | 288 ++++++-------------- 11 files changed, 99 insertions(+), 250 deletions(-) diff --git a/conf/defaults/pgmodeler.conf b/conf/defaults/pgmodeler.conf index 0d280ddfa2..38405c783c 100644 --- a/conf/defaults/pgmodeler.conf +++ b/conf/defaults/pgmodeler.conf @@ -37,8 +37,7 @@ align-objs-to-grid="true" min-object-opacity="10" history-max-length="1000" - use-curved-lines="true" - max-result-rows="20000"/> + use-curved-lines="true"/> diff --git a/conf/dtd/pgmodeler.dtd b/conf/dtd/pgmodeler.dtd index cdea216667..51768e16d0 100644 --- a/conf/dtd/pgmodeler.dtd +++ b/conf/dtd/pgmodeler.dtd @@ -44,7 +44,6 @@ - diff --git a/conf/pgmodeler.conf b/conf/pgmodeler.conf index 0d280ddfa2..38405c783c 100644 --- a/conf/pgmodeler.conf +++ b/conf/pgmodeler.conf @@ -37,8 +37,7 @@ align-objs-to-grid="true" min-object-opacity="10" history-max-length="1000" - use-curved-lines="true" - max-result-rows="20000"/> + use-curved-lines="true"/> diff --git a/conf/schemas/pgmodeler.sch b/conf/schemas/pgmodeler.sch index d68dd6ad17..74715d9844 100644 --- a/conf/schemas/pgmodeler.sch +++ b/conf/schemas/pgmodeler.sch @@ -48,10 +48,6 @@ $sp [setText(simple_obj_creation_chk->statusTip()); @@ -182,9 +179,6 @@ GeneralConfigWidget::GeneralConfigWidget(QWidget * parent) : BaseConfigWidget(pa use_curved_lines_ht=new HintTextWidget(use_curved_lines_hint, this); use_curved_lines_ht->setText(use_curved_lines_chk->statusTip()); - max_result_rows_ht=new HintTextWidget(max_result_rows_hint, this); - max_result_rows_ht->setText(max_result_rows_spb->statusTip()); - selectPaperSize(); QList chk_boxes=this->findChildren(); @@ -308,11 +302,6 @@ void GeneralConfigWidget::loadConfiguration(void) min_obj_opacity_spb->setValue(config_params[ParsersAttributes::CONFIGURATION][ParsersAttributes::MIN_OBJECT_OPACITY].toUInt()); - int value = config_params[ParsersAttributes::CONFIGURATION][ParsersAttributes::MAX_RESULT_ROWS].toInt(); - max_result_rows_chk->setChecked(value > 0); - max_result_rows_spb->setEnabled(value > 0); - max_result_rows_spb->setValue(value); - margin=config_params[ParsersAttributes::CONFIGURATION][ParsersAttributes::PAPER_MARGIN].split(','); custom_size=config_params[ParsersAttributes::CONFIGURATION][ParsersAttributes::PAPER_CUSTOM_SIZE].split(','); @@ -433,7 +422,6 @@ void GeneralConfigWidget::saveConfiguration(void) config_params[ParsersAttributes::CONFIGURATION][ParsersAttributes::MIN_OBJECT_OPACITY]=QString::number(min_obj_opacity_spb->value()); config_params[ParsersAttributes::CONFIGURATION][ParsersAttributes::USE_PLACEHOLDERS]=(use_placeholders_chk->isChecked() ? ParsersAttributes::_TRUE_ : QString()); config_params[ParsersAttributes::CONFIGURATION][ParsersAttributes::HISTORY_MAX_LENGTH]=QString::number(history_max_length_spb->value()); - config_params[ParsersAttributes::CONFIGURATION][ParsersAttributes::MAX_RESULT_ROWS]=QString::number(max_result_rows_chk->isChecked() ? max_result_rows_spb->value() : 0); config_params[ParsersAttributes::CONFIGURATION][ParsersAttributes::USE_CURVED_LINES]=(use_curved_lines_chk->isChecked() ? ParsersAttributes::_TRUE_ : QString()); ObjectsScene::getGridOptions(show_grid, align_grid, show_delim); @@ -552,7 +540,6 @@ void GeneralConfigWidget::applyConfiguration(void) MainWindow::setConfirmValidation(confirm_validation_chk->isChecked()); BaseObjectView::setPlaceholderEnabled(use_placeholders_chk->isChecked()); SQLExecutionWidget::setSQLHistoryMaxLength(history_max_length_spb->value()); - SQLExecutionWidget::setMaxResultRows(max_result_rows_chk->isChecked()? max_result_rows_spb->value() : 0); fnt.setFamily(config_params[ParsersAttributes::CONFIGURATION][ParsersAttributes::CODE_FONT]); fnt.setPointSize(fnt_size); diff --git a/libpgmodeler_ui/src/sqlexecutionwidget.cpp b/libpgmodeler_ui/src/sqlexecutionwidget.cpp index 1cb0fdf919..19b004a8a6 100644 --- a/libpgmodeler_ui/src/sqlexecutionwidget.cpp +++ b/libpgmodeler_ui/src/sqlexecutionwidget.cpp @@ -27,7 +27,6 @@ map SQLExecutionWidget::cmd_history; int SQLExecutionWidget::cmd_history_max_len = 1000; -int SQLExecutionWidget::max_result_rows = 20000; const QString SQLExecutionWidget::COLUMN_NULL_VALUE = QString("␀"); SQLExecutionWidget::SQLExecutionWidget(QWidget * parent) : QWidget(parent) @@ -294,16 +293,13 @@ void SQLExecutionWidget::fillResultsTable(Catalog &catalog, ResultSet &res, QTab for(col=0; col < col_cnt; col++) { item=results_tbw->horizontalHeaderItem(col); - item->setToolTip(res.getColumnName(col) + QString(" [%1]").arg(type_names[res.getColumnTypeId(col)])); + item->setToolTip(type_names[res.getColumnTypeId(col)]); item->setData(Qt::UserRole, type_names[res.getColumnTypeId(col)]); } if(res.accessTuple(ResultSet::FIRST_TUPLE)) { - if(max_result_rows != 0 && res.getTupleCount() > max_result_rows) - results_tbw->setRowCount(max_result_rows); - else - results_tbw->setRowCount(res.getTupleCount()); + results_tbw->setRowCount(res.getTupleCount()); do { @@ -619,16 +615,6 @@ void SQLExecutionWidget::exportResults(QTableView *results_tbw) } } -void SQLExecutionWidget::setMaxResultRows(int max_val) -{ - max_result_rows = (max_val < 0 ? 0 : max_val); -} - -int SQLExecutionWidget::getMaxResultRows(void) -{ - return(max_result_rows); -} - int SQLExecutionWidget::clearAll(void) { Messagebox msg_box; diff --git a/libpgmodeler_ui/src/sqlexecutionwidget.h b/libpgmodeler_ui/src/sqlexecutionwidget.h index 4081be8c37..9b8ff25be8 100644 --- a/libpgmodeler_ui/src/sqlexecutionwidget.h +++ b/libpgmodeler_ui/src/sqlexecutionwidget.h @@ -43,12 +43,6 @@ class SQLExecutionWidget: public QWidget, public Ui::SQLExecutionWidget { static int cmd_history_max_len; - /*! \brief The maximum amount of rows allowed to the results grid. - * This attribute is used to limit the amount of rows inserted in any QTableWidget instance - * by fillResultsTable() in order to avoid memory exhaustion leading to crash depending on - * the amount of rows stored in a result set */ - static int max_result_rows; - SchemaParser schparser; //! \brief Syntax highlighter for sql input field @@ -130,10 +124,6 @@ class SQLExecutionWidget: public QWidget, public Ui::SQLExecutionWidget { //! \brief Exports the results to csv file static void exportResults(QTableView *results_tbw); - static void setMaxResultRows(int max_val); - - static int getMaxResultRows(void); - public slots: void configureSnippets(void); diff --git a/libpgmodeler_ui/ui/datamanipulationform.ui b/libpgmodeler_ui/ui/datamanipulationform.ui index 97d2c9f515..995d5ea701 100644 --- a/libpgmodeler_ui/ui/datamanipulationform.ui +++ b/libpgmodeler_ui/ui/datamanipulationform.ui @@ -1456,10 +1456,13 @@ 0 - 999999 + 1000000 + + + 50 - 500 + 1000 diff --git a/libpgmodeler_ui/ui/generalconfigwidget.ui b/libpgmodeler_ui/ui/generalconfigwidget.ui index e68bad1f52..19c46a92cd 100644 --- a/libpgmodeler_ui/ui/generalconfigwidget.ui +++ b/libpgmodeler_ui/ui/generalconfigwidget.ui @@ -1011,25 +1011,10 @@ 4 - - - - - 0 - 0 - - - - - 22 - 22 - - - - - 22 - 22 - + + + + Souce code editor args: @@ -1163,156 +1148,30 @@ - - - - - - - 0 - 0 - - - - - 60 - 0 - - - - Maximum number of rows to be displayed in the results grid. This is used as a security measure to avoid application crash due to memory exhaustion when retrieving a huge set of data from the database without using filtering keywords like <strong>LIMIT</strong> or <strong>WHERE</strong>. - - - 5000 - - - 500000 - - - 5000 - - - 20000 - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - rows - - - - - - - - 0 - 0 - - - - - 22 - 22 - - - - - 22 - 22 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 25 - 20 - - - - - - - - - - - - - false - - - - - + + - + 0 0 - 0 - 0 + 22 + 22 - - SQL history max. length: - - - - - - - true - - - - - - - Souce code editor: - - - - - - - Configurations directory: + + + 22 + 22 + - - + + 0 @@ -1332,7 +1191,7 @@ - Browse the source code editor application + Open in file manager @@ -1349,10 +1208,17 @@ - - + + + + Overrides the default user interface language defined by the system. Requires restarting the program. <strong>NOTE:</strong> UI translations are third party collaborations thus any typo or mistake should be reported directly to their respective maintainers. + + + + + - + 0 0 @@ -1363,31 +1229,22 @@ 0 - - - 16777215 - 16777215 - + + SQL history max. length: + + + + - Open in file manager - - - - - :/icones/icones/abrir.png:/icones/icones/abrir.png - - - - 22 - 22 - + + false - + Check if there is a new version on server @@ -1400,10 +1257,20 @@ - - - - Souce code editor args: + + + + true + + + + + + + + + + false @@ -1414,30 +1281,55 @@ - - - - Overrides the default user interface language defined by the system. Requires restarting the program. <strong>NOTE:</strong> UI translations are third party collaborations thus any typo or mistake should be reported directly to their respective maintainers. + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + - - - - + Browse the source code editor application + + - - false + + + :/icones/icones/abrir.png:/icones/icones/abrir.png + + + + 22 + 22 + - - + + - Limit SQL results in: + Souce code editor: - - true + + + + + + Configurations directory: From f58e6f818219392ab06170a53b005376d5b0672b Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Thu, 26 Apr 2018 17:55:34 -0300 Subject: [PATCH 10/30] Fixed the import of user defined types which names contains uppercase chars (issue #1114) --- libpgmodeler_ui/src/databaseimporthelper.cpp | 4 ++-- schemas/catalog/usertype.sch | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libpgmodeler_ui/src/databaseimporthelper.cpp b/libpgmodeler_ui/src/databaseimporthelper.cpp index 8743cae066..a0533c8e63 100644 --- a/libpgmodeler_ui/src/databaseimporthelper.cpp +++ b/libpgmodeler_ui/src/databaseimporthelper.cpp @@ -1670,8 +1670,8 @@ void DatabaseImportHelper::createTable(attribs_map &attribs) { /* Building the type name prepending the schema name in order to search it on the user defined types list at PgSQLType class */ - type_name=getObjectName(types[type_oid][ParsersAttributes::SCHEMA], true); - type_name+=QString(".") + types[type_oid][ParsersAttributes::NAME]; + type_name=BaseObject::formatName(getObjectName(types[type_oid][ParsersAttributes::SCHEMA], true), false); + type_name+=QString(".") + BaseObject::formatName(types[type_oid][ParsersAttributes::NAME], false); is_type_registered=PgSQLType::isRegistered(type_name, dbmodel); } else diff --git a/schemas/catalog/usertype.sch b/schemas/catalog/usertype.sch index 155838171a..9d42805268 100644 --- a/schemas/catalog/usertype.sch +++ b/schemas/catalog/usertype.sch @@ -3,7 +3,7 @@ # Code generation can be broken if incorrect changes are made. %if {list} %then - [SELECT tp.oid, replace(tp.oid::regtype::text, ns.nspname || '.', '') AS name FROM pg_type AS tp ] + [SELECT tp.oid, replace(replace(tp.oid::regtype::text,'"', ''), ns.nspname || '.', '') FROM pg_type AS tp ] [ LEFT JOIN pg_namespace AS ns ON tp.typnamespace = ns.oid ] %if {schema} %then @@ -34,7 +34,7 @@ %else %if {attribs} %then - [SELECT tp.oid, replace(tp.oid::regtype::text, ns.nspname || '.', '') AS name, tp.typnamespace AS schema, tp.typowner AS owner, ] + [SELECT tp.oid, replace(replace(tp.oid::regtype::text,'"', ''), ns.nspname || '.', '') AS name, tp.typnamespace AS schema, tp.typowner AS owner, ] #Retrieve the OID for table/view/sequence that generates the composite type [ (SELECT From 32680f675f7f0b7f4427d044f0802da8be19cc6e Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Fri, 27 Apr 2018 15:08:53 -0300 Subject: [PATCH 11/30] The validator now checks if model has columns with spatial datatype and creates the postgis extension automatically --- libpgmodeler/src/databasemodel.cpp | 5 +- libpgmodeler_ui/src/modelvalidationhelper.cpp | 48 +++++++++++++++---- libpgmodeler_ui/src/modelvalidationwidget.cpp | 15 ++++++ libpgmodeler_ui/src/objectdepsrefswidget.cpp | 2 +- libpgmodeler_ui/src/validationinfo.h | 5 +- libpgmodeler_ui/ui/modelvalidationwidget.ui | 4 +- 6 files changed, 65 insertions(+), 14 deletions(-) diff --git a/libpgmodeler/src/databasemodel.cpp b/libpgmodeler/src/databasemodel.cpp index d2ad7fe148..898d38e564 100644 --- a/libpgmodeler/src/databasemodel.cpp +++ b/libpgmodeler/src/databasemodel.cpp @@ -8101,7 +8101,10 @@ void DatabaseModel::getObjectReferences(BaseObject *object, vector { col=tab->getColumn(i1); - if(!col->isAddedByRelationship() && col->getType()==ptr_pgsqltype) + if(!col->isAddedByRelationship() && + (col->getType()==ptr_pgsqltype || + //Special case for postgis extension + (obj_type == OBJ_EXTENSION && object->getName() == QString("postgis") && col->getType().isGiSType()))) { refer=true; refs.push_back(col); diff --git a/libpgmodeler_ui/src/modelvalidationhelper.cpp b/libpgmodeler_ui/src/modelvalidationhelper.cpp index f53c0ff65a..cd0d404ee9 100644 --- a/libpgmodeler_ui/src/modelvalidationhelper.cpp +++ b/libpgmodeler_ui/src/modelvalidationhelper.cpp @@ -46,7 +46,8 @@ ModelValidationHelper::~ModelValidationHelper(void) void ModelValidationHelper::generateValidationInfo(unsigned val_type, BaseObject *object, vector refs) { if(!refs.empty() || - (val_type==ValidationInfo::BROKEN_REL_CONFIG && + val_type==ValidationInfo::MISSING_EXTENSION || + (val_type==ValidationInfo::BROKEN_REL_CONFIG && std::find(inv_rels.begin(), inv_rels.end(), object)==inv_rels.end())) { //Configures a validation info @@ -71,7 +72,7 @@ void ModelValidationHelper::resolveConflict(ValidationInfo &info) //Resolving broken references by swaping the object ids if(info.getValidationType()==ValidationInfo::BROKEN_REFERENCE || - info.getValidationType()==ValidationInfo::SP_OBJ_BROKEN_REFERENCE) + info.getValidationType()==ValidationInfo::SP_OBJ_BROKEN_REFERENCE) { BaseObject *info_obj=info.getObject(), *aux_obj=nullptr; unsigned obj_id=info_obj->getObjectId(); @@ -190,6 +191,13 @@ void ModelValidationHelper::resolveConflict(ValidationInfo &info) refs.pop_back(); } } + //Resolving the absence of postgis extension + else if(info.getValidationType()==ValidationInfo::MISSING_EXTENSION && !db_model->getExtension(QString("postgis"))) + { + Extension *extension = new Extension(); + extension->setName(QString("postgis")); + db_model->addExtension(extension); + } } catch(Exception &e) { @@ -274,13 +282,14 @@ void ModelValidationHelper::validateModel(void) map > dup_objects; map >::iterator mitr; QString name, signal_msg=QString("`%1' (%2)"); + bool postgis_exists = db_model->getObjectIndex(QString("postgis"), OBJ_EXTENSION) >= 0; warn_count=error_count=progress=0; val_infos.clear(); valid_canceled=false; /* Step 1: Validating broken references. This situation happens when a object references another - whose id is smaller than the id of the first one. */ + which id is smaller than the id of the first one. */ for(i=0; i < count && !valid_canceled; i++) { obj_list=db_model->getObjectList(types[i]); @@ -508,8 +517,31 @@ void ModelValidationHelper::validateModel(void) i++; mitr++; } + // Step 3: Checking if columns of any table is using GiS data types and the postgis extension is not created. + if(!postgis_exists) + { + obj_list=db_model->getObjectList(OBJ_TABLE); + itr=obj_list->begin(); + i=0; + + while(itr!=obj_list->end() && !valid_canceled) + { + table = dynamic_cast(*itr); + itr++; + + for(auto &obj : *table->getObjectList(OBJ_COLUMN)) + { + col = dynamic_cast(obj); + + if(col->getType().isGiSType()) + generateValidationInfo(ValidationInfo::MISSING_EXTENSION, col, {}); + } - /* Step 3: Checking if there are some invalidated relationship. In some cases, specially with identifier and generalization relationships, + progress=30 + ((i/static_cast(obj_list->size()))*20); + } + } + + /* Step 4: Checking if there are some invalidated relationship. In some cases, specially with identifier and generalization relationships, the columns aren't correctly propagated due to creation order and special behavior of those objects. Thus, in order to keep all columns synchonized it is need to make this step and change the relationship creation order if needed. This step is executed only when there is no validation infos generated because for each broken relationship there is the need to do a revalidation of all relationships */ @@ -520,7 +552,7 @@ void ModelValidationHelper::validateModel(void) while(itr!=obj_list->end() && !valid_canceled) { - progress=30 + ((i/static_cast(obj_list->size()))*20); + progress=40 + ((i/static_cast(obj_list->size()))*20); if(dynamic_cast(*itr)->isInvalidated()) generateValidationInfo(ValidationInfo::BROKEN_REL_CONFIG, *itr, {}); @@ -529,7 +561,6 @@ void ModelValidationHelper::validateModel(void) } } - if(!valid_canceled && !fix_mode) { //Step 3 (optional): Validating the SQL code onto a local DBMS. @@ -575,8 +606,9 @@ void ModelValidationHelper::applyFixes(void) { if(!validate_rels) validate_rels=(val_infos[i].getValidationType()==ValidationInfo::BROKEN_REFERENCE || - val_infos[i].getValidationType()==ValidationInfo::SP_OBJ_BROKEN_REFERENCE || - val_infos[i].getValidationType()==ValidationInfo::NO_UNIQUE_NAME); + val_infos[i].getValidationType()==ValidationInfo::SP_OBJ_BROKEN_REFERENCE || + val_infos[i].getValidationType()==ValidationInfo::NO_UNIQUE_NAME || + val_infos[i].getValidationType()==ValidationInfo::MISSING_EXTENSION); /* Checking if a broken relatinship is found, when this is the case all the pending validation info will not be analyzed until no broken relationship is found */ diff --git a/libpgmodeler_ui/src/modelvalidationwidget.cpp b/libpgmodeler_ui/src/modelvalidationwidget.cpp index 9319a73cff..9017267c01 100644 --- a/libpgmodeler_ui/src/modelvalidationwidget.cpp +++ b/libpgmodeler_ui/src/modelvalidationwidget.cpp @@ -266,6 +266,16 @@ void ModelValidationWidget::updateValidation(ValidationInfo val_info) .arg(val_info.getObject()->getObjectId())); else if(val_info.getValidationType()==ValidationInfo::SQL_VALIDATION_ERR) label->setText(trUtf8("SQL validation failed due to error(s) below. NOTE: These errors does not invalidates the model but may affect operations like export and diff.")); + else if(val_info.getValidationType() == ValidationInfo::MISSING_EXTENSION) + { + Column *col = dynamic_cast(val_info.getObject()); + + label->setText(trUtf8("The column %1 on %2 (%3) is referencing the geospatial data type %4 but the postgis extension is not present in the model!") + .arg(col->getName()) + .arg(col->getParentTable()->getSignature(true)) + .arg(BaseObject::getTypeName(OBJ_TABLE)) + .arg(~col->getType())); + } else label->setText(val_info.getErrors().at(0)); @@ -306,6 +316,11 @@ void ModelValidationWidget::updateValidation(ValidationInfo val_info) PgModelerUiNS::createOutputTreeItem(output_trw, trUtf8("HINT: try to swap the relationship by another ones that somehow are linked to it through generated columns or constraints to solve this issue. Note that other objects may be lost in the swap process."), QPixmap(PgModelerUiNS::getIconPath("msgbox_alerta")), item); } + else if(val_info.getValidationType()==ValidationInfo::MISSING_EXTENSION) + { + PgModelerUiNS::createOutputTreeItem(output_trw, trUtf8("HINT: Create the extension in the model or let it be created by applying the needed fixes."), + QPixmap(PgModelerUiNS::getIconPath("msgbox_alerta")), item); + } else { //Listing the referrer object on output pane diff --git a/libpgmodeler_ui/src/objectdepsrefswidget.cpp b/libpgmodeler_ui/src/objectdepsrefswidget.cpp index dd9e022078..01e834b5a0 100644 --- a/libpgmodeler_ui/src/objectdepsrefswidget.cpp +++ b/libpgmodeler_ui/src/objectdepsrefswidget.cpp @@ -84,12 +84,12 @@ void ObjectDepsRefsWidget::updateObjectTables(void) objs.erase(std::find(objs.begin(), objs.end(), this->object)); ObjectFinderWidget::updateObjectTable(dependences_tbw, objs); + objs.clear(); if(!inc_ind_refs_chk->isChecked()) model->getObjectReferences(object, objs); else model->__getObjectReferences(object, objs); - objs.clear(); ObjectFinderWidget::updateObjectTable(references_tbw, objs); references_tbw->resizeColumnsToContents(); diff --git a/libpgmodeler_ui/src/validationinfo.h b/libpgmodeler_ui/src/validationinfo.h index 81773c2289..4ff4872670 100644 --- a/libpgmodeler_ui/src/validationinfo.h +++ b/libpgmodeler_ui/src/validationinfo.h @@ -50,8 +50,9 @@ class ValidationInfo { BROKEN_REFERENCE=1, SP_OBJ_BROKEN_REFERENCE=2, BROKEN_REL_CONFIG=3, - SQL_VALIDATION_ERR=4, - VALIDATION_ABORTED=5; + MISSING_EXTENSION=4, + SQL_VALIDATION_ERR=5, + VALIDATION_ABORTED=6; ValidationInfo(void); ValidationInfo(unsigned val_type, BaseObject *object, vector references); diff --git a/libpgmodeler_ui/ui/modelvalidationwidget.ui b/libpgmodeler_ui/ui/modelvalidationwidget.ui index 6530560647..fdc016a937 100644 --- a/libpgmodeler_ui/ui/modelvalidationwidget.ui +++ b/libpgmodeler_ui/ui/modelvalidationwidget.ui @@ -718,7 +718,7 @@ Try to resolve the reported issues. - Apply Fix + Apply fixes @@ -753,7 +753,7 @@ Change the creation order for two objects by swapping their ids - Swap Ids + Swap ids From d37bf2da05136186023fa716e570db8e86b30dbd Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Fri, 27 Apr 2018 16:20:07 -0300 Subject: [PATCH 12/30] Fixed the catalog query for user defined types --- schemas/catalog/usertype.sch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/catalog/usertype.sch b/schemas/catalog/usertype.sch index 9d42805268..f0c8175641 100644 --- a/schemas/catalog/usertype.sch +++ b/schemas/catalog/usertype.sch @@ -3,7 +3,7 @@ # Code generation can be broken if incorrect changes are made. %if {list} %then - [SELECT tp.oid, replace(replace(tp.oid::regtype::text,'"', ''), ns.nspname || '.', '') FROM pg_type AS tp ] + [SELECT tp.oid, replace(replace(tp.oid::regtype::text,'"', ''), ns.nspname || '.', '') AS name FROM pg_type AS tp ] [ LEFT JOIN pg_namespace AS ns ON tp.typnamespace = ns.oid ] %if {schema} %then From cf4c89390f4abc17dbce4d2c1f4a3a8027dccabe Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Sun, 29 Apr 2018 10:16:02 -0300 Subject: [PATCH 13/30] Added support to source code selection by clicking and moving the mouse over the line numbers widget --- libpgmodeler_ui/src/linenumberswidget.cpp | 34 +++++++++++++++++++++++ libpgmodeler_ui/src/linenumberswidget.h | 9 +++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/libpgmodeler_ui/src/linenumberswidget.cpp b/libpgmodeler_ui/src/linenumberswidget.cpp index 11db826fd8..d01c9371aa 100644 --- a/libpgmodeler_ui/src/linenumberswidget.cpp +++ b/libpgmodeler_ui/src/linenumberswidget.cpp @@ -19,14 +19,20 @@ #include "linenumberswidget.h" #include #include +#include "exception.h" QColor LineNumbersWidget::font_color=Qt::lightGray; QColor LineNumbersWidget::bg_color=Qt::black; LineNumbersWidget::LineNumbersWidget(QPlainTextEdit * parent) : QWidget(parent) { + if(!parent) + throw Exception(ERR_ASG_NOT_ALOC_OBJECT ,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + parent_edt = qobject_cast(parent); first_line=line_count=0; dy=0; + has_selection = false; } void LineNumbersWidget::drawLineNumbers(unsigned first_line, unsigned line_count, int dy) @@ -67,6 +73,34 @@ void LineNumbersWidget::paintEvent(QPaintEvent *event) } } +void LineNumbersWidget::mousePressEvent(QMouseEvent *event) +{ + if(event->buttons() == Qt::LeftButton && !has_selection) + { + QTextCursor cursor = parent_edt->cursorForPosition(QPoint(0, event->pos().y())); + cursor.select(QTextCursor::LineUnderCursor); + parent_edt->setTextCursor(cursor); + has_selection = true; + } +} + +void LineNumbersWidget::mouseMoveEvent(QMouseEvent *event) +{ + if(event->buttons() == Qt::LeftButton && has_selection) + { + QTextCursor cursor = parent_edt->cursorForPosition(QPoint(0, event->pos().y())), + curr_cursor = parent_edt->textCursor(); + + curr_cursor.setPosition(cursor.position(), QTextCursor::KeepAnchor); + parent_edt->setTextCursor(curr_cursor); + } +} + +void LineNumbersWidget::mouseReleaseEvent(QMouseEvent *) +{ + has_selection = false; +} + QColor LineNumbersWidget::getBackgroundColor(void) { return(LineNumbersWidget::bg_color); diff --git a/libpgmodeler_ui/src/linenumberswidget.h b/libpgmodeler_ui/src/linenumberswidget.h index ac83e76c25..76e3b39aaf 100644 --- a/libpgmodeler_ui/src/linenumberswidget.h +++ b/libpgmodeler_ui/src/linenumberswidget.h @@ -32,6 +32,10 @@ class LineNumbersWidget : public QWidget { private: Q_OBJECT + QPlainTextEdit *parent_edt; + + bool has_selection; + //! \brief The first line number that must be drawn unsigned first_line, @@ -49,9 +53,12 @@ class LineNumbersWidget : public QWidget { protected: void paintEvent(QPaintEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *); public: - explicit LineNumbersWidget(QPlainTextEdit *parent = 0); + explicit LineNumbersWidget(QPlainTextEdit *parent); /*! \brief Draw the lines starting from 'first_line' and stoping at fisrt_line + line_count -1. The dy param. defines an initial Y translation before drawn lines */ From 9d2ebe23882bad05a4c9a5746760302305cf6772 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Mon, 30 Apr 2018 16:45:46 -0300 Subject: [PATCH 14/30] Selected lines numbers are now correctly highlighted in LineNumbersWidget --- libpgmodeler_ui/src/linenumberswidget.cpp | 71 +++++++++++++++++-- libpgmodeler_ui/src/linenumberswidget.h | 5 ++ tests/src/linenumberstest/linenumberstest.cpp | 60 ++++++++++++++++ tests/src/linenumberstest/linenumberstest.pro | 3 + tests/tests.pro | 11 +-- 5 files changed, 140 insertions(+), 10 deletions(-) create mode 100644 tests/src/linenumberstest/linenumberstest.cpp create mode 100644 tests/src/linenumberstest/linenumberstest.pro diff --git a/libpgmodeler_ui/src/linenumberswidget.cpp b/libpgmodeler_ui/src/linenumberswidget.cpp index d01c9371aa..ef34a3e880 100644 --- a/libpgmodeler_ui/src/linenumberswidget.cpp +++ b/libpgmodeler_ui/src/linenumberswidget.cpp @@ -20,6 +20,7 @@ #include #include #include "exception.h" +#include QColor LineNumbersWidget::font_color=Qt::lightGray; QColor LineNumbersWidget::bg_color=Qt::black; @@ -33,6 +34,10 @@ LineNumbersWidget::LineNumbersWidget(QPlainTextEdit * parent) : QWidget(parent) first_line=line_count=0; dy=0; has_selection = false; + first_sel_line = -1; + last_sel_line = -1; + + connect(parent_edt, SIGNAL(selectionChanged()), this, SLOT(updateSelectedLineNumbers())); } void LineNumbersWidget::drawLineNumbers(unsigned first_line, unsigned line_count, int dy) @@ -57,8 +62,11 @@ void LineNumbersWidget::setColors(const QColor &font_color, const QColor &bg_col void LineNumbersWidget::paintEvent(QPaintEvent *event) { QPainter painter(this); - int y=dy, height=fontMetrics().height(); + int y = dy, height = 0; unsigned last_line=first_line + line_count; + QFont font = painter.font(); + unsigned fs_line = std::min(first_sel_line, last_sel_line), + ls_line = std::max(first_sel_line, last_sel_line); //Repaint the widget to clear previous drawn numbers painter.fillRect(event->rect(), bg_color); @@ -67,8 +75,10 @@ void LineNumbersWidget::paintEvent(QPaintEvent *event) //Draw line numbers for(unsigned lin=first_line; lin < last_line; lin++) { - painter.drawText(0, y, this->width(), fontMetrics().height(), - Qt::AlignHCenter, QString::number(lin)); + font.setBold(lin-1 >= fs_line && lin-1 <= ls_line); + height = QFontMetrics(font).height(); + painter.setFont(font); + painter.drawText(0, y, this->width(), height, Qt::AlignHCenter, QString::number(lin)); y+=height; } } @@ -78,9 +88,13 @@ void LineNumbersWidget::mousePressEvent(QMouseEvent *event) if(event->buttons() == Qt::LeftButton && !has_selection) { QTextCursor cursor = parent_edt->cursorForPosition(QPoint(0, event->pos().y())); + + parent_edt->blockSignals(true); cursor.select(QTextCursor::LineUnderCursor); parent_edt->setTextCursor(cursor); has_selection = true; + first_sel_line = last_sel_line = cursor.blockNumber(); + this->update(); } } @@ -91,14 +105,43 @@ void LineNumbersWidget::mouseMoveEvent(QMouseEvent *event) QTextCursor cursor = parent_edt->cursorForPosition(QPoint(0, event->pos().y())), curr_cursor = parent_edt->textCursor(); - curr_cursor.setPosition(cursor.position(), QTextCursor::KeepAnchor); - parent_edt->setTextCursor(curr_cursor); + last_sel_line = cursor.blockNumber(); + + //If the current selected line is the same as the first one (when the first click ocurred) + if(first_sel_line == cursor.blockNumber()) + { + //Forcing the selection of the whole line + cursor.movePosition(QTextCursor::StartOfLine); + cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); + parent_edt->setTextCursor(cursor); + } + //If the user wants selects lines below the first + else if(first_sel_line < cursor.blockNumber()) + { + cursor.movePosition(QTextCursor::EndOfLine); + curr_cursor.setPosition(cursor.position(), QTextCursor::KeepAnchor); + parent_edt->setTextCursor(curr_cursor); + } + //If the user wants selects lines above the first + else + { + int pos = curr_cursor.position(); + + //We first move the cursor related to the mouse position to the start of the line + cursor.movePosition(QTextCursor::StartOfLine); + //Then we move it to the position of the current cursor (where the click occured) + cursor.setPosition(pos, QTextCursor::KeepAnchor); + parent_edt->setTextCursor(cursor); + } + + this->update(); } } void LineNumbersWidget::mouseReleaseEvent(QMouseEvent *) { has_selection = false; + parent_edt->blockSignals(false); } QColor LineNumbersWidget::getBackgroundColor(void) @@ -106,4 +149,22 @@ QColor LineNumbersWidget::getBackgroundColor(void) return(LineNumbersWidget::bg_color); } +void LineNumbersWidget::updateSelectedLineNumbers(void) +{ + QTextCursor cursor = parent_edt->textCursor(); + if(cursor.hasSelection()) + { + QTextCursor start = cursor, + end = cursor; + + start.setPosition(cursor.selectionStart()); + first_sel_line = start.blockNumber(); + end.setPosition(cursor.selectionEnd()); + last_sel_line = end.blockNumber(); + } + else + first_sel_line = last_sel_line = -1; + + this->update(); +} diff --git a/libpgmodeler_ui/src/linenumberswidget.h b/libpgmodeler_ui/src/linenumberswidget.h index 76e3b39aaf..309fa8fad5 100644 --- a/libpgmodeler_ui/src/linenumberswidget.h +++ b/libpgmodeler_ui/src/linenumberswidget.h @@ -45,6 +45,8 @@ class LineNumbersWidget : public QWidget { //! \brief The y axis increment to start drawn the line number int dy; + int first_sel_line, last_sel_line; + //! \brief Font color for drawn line numbers static QColor font_color, @@ -68,6 +70,9 @@ class LineNumbersWidget : public QWidget { static void setColors(const QColor &font_color, const QColor &bg_color); static QColor getBackgroundColor(void); + + private slots: + void updateSelectedLineNumbers(void); }; #endif diff --git a/tests/src/linenumberstest/linenumberstest.cpp b/tests/src/linenumberstest/linenumberstest.cpp new file mode 100644 index 0000000000..37aaff4e1b --- /dev/null +++ b/tests/src/linenumberstest/linenumberstest.cpp @@ -0,0 +1,60 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2018 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +#include +#include "numberedtexteditor.h" +#include +#include + +class LineNumbersTest: public QObject { + private: + Q_OBJECT + + private slots: + void handleLineSelectionUsingMouse(void); +}; + +void LineNumbersTest::handleLineSelectionUsingMouse(void) +{ + QDialog *dlg=new QDialog; + NumberedTextEditor *edt=new NumberedTextEditor(dlg); + QHBoxLayout *layout=new QHBoxLayout(dlg); + + LineNumbersWidget::setColors(Qt::darkGray, QColor(230,230,230)); + layout->addWidget(edt); + dlg->setMinimumSize(640,480); + + edt->setPlainText("--\n\ +-- PostgreSQL database dump\n\ +--\n\ +-- Dumped from database version 9.4.4\n\ +-- Dumped by pg_dump version 9.4.4\n\ +-- Started on 2015-07-20 19:24:52 WEST\n\ +\n\ +SET statement_timeout = 0;\n\ +SET lock_timeout = 0;\n\ +SET client_encoding = 'UTF8';\n\ +SET standard_conforming_strings = on;\n\ +SET check_function_bodies = false;\n\ +SET client_min_messages = warning;"); + + dlg->exec(); +} + +QTEST_MAIN(LineNumbersTest) +#include "linenumberstest.moc" diff --git a/tests/src/linenumberstest/linenumberstest.pro b/tests/src/linenumberstest/linenumberstest.pro new file mode 100644 index 0000000000..728f7a5aa1 --- /dev/null +++ b/tests/src/linenumberstest/linenumberstest.pro @@ -0,0 +1,3 @@ +include(../../tests.pri) +SOURCES += linenumberstest.cpp + diff --git a/tests/tests.pro b/tests/tests.pro index 6e60d5c27b..b8020f0218 100644 --- a/tests/tests.pro +++ b/tests/tests.pro @@ -8,9 +8,10 @@ # refactored code, containing almost all changes done by the refactoring author. TEMPLATE = subdirs SUBDIRS = src/main \ - src/baseobjecttest \ - src/roletest \ - src/syntaxhighlightertest \ - src/databasemodeltest \ - src/schemaparsertest +src/baseobjecttest \ +src/roletest \ +src/syntaxhighlightertest \ +src/databasemodeltest \ +src/schemaparsertest \ +src/linenumberstest \ From bd51e975f9544529249738d377f7eb195cf82f4e Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Tue, 1 May 2018 08:23:56 -0300 Subject: [PATCH 15/30] Improved the selected lines highlighting in LineNumbersWidget --- libpgmodeler_ui/src/linenumberswidget.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libpgmodeler_ui/src/linenumberswidget.cpp b/libpgmodeler_ui/src/linenumberswidget.cpp index ef34a3e880..670937cae4 100644 --- a/libpgmodeler_ui/src/linenumberswidget.cpp +++ b/libpgmodeler_ui/src/linenumberswidget.cpp @@ -36,7 +36,6 @@ LineNumbersWidget::LineNumbersWidget(QPlainTextEdit * parent) : QWidget(parent) has_selection = false; first_sel_line = -1; last_sel_line = -1; - connect(parent_edt, SIGNAL(selectionChanged()), this, SLOT(updateSelectedLineNumbers())); } @@ -78,6 +77,17 @@ void LineNumbersWidget::paintEvent(QPaintEvent *event) font.setBold(lin-1 >= fs_line && lin-1 <= ls_line); height = QFontMetrics(font).height(); painter.setFont(font); + + if(font.bold()) + { + painter.setBrush(bg_color.dark(150)); + painter.setPen(Qt::transparent); + painter.drawRect(QRect(-1, y, this->width() + 1, height)); + painter.setPen(font_color.light(180)); + } + else + painter.setPen(font_color); + painter.drawText(0, y, this->width(), height, Qt::AlignHCenter, QString::number(lin)); y+=height; } From c4ff4fff6d8e7d2ac63b898126e13bd924038c76 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Wed, 2 May 2018 08:29:15 -0300 Subject: [PATCH 16/30] Added column names to the code completion widget used in the filter widget at DataManipulationForm --- libpgmodeler_ui/src/codecompletionwidget.cpp | 8 +++++++- libpgmodeler_ui/src/codecompletionwidget.h | 7 +++++-- libpgmodeler_ui/src/datamanipulationform.cpp | 3 +++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libpgmodeler_ui/src/codecompletionwidget.cpp b/libpgmodeler_ui/src/codecompletionwidget.cpp index 5324a4f59e..737dd633a0 100644 --- a/libpgmodeler_ui/src/codecompletionwidget.cpp +++ b/libpgmodeler_ui/src/codecompletionwidget.cpp @@ -35,7 +35,7 @@ CodeCompletionWidget::CodeCompletionWidget(QPlainTextEdit *code_field_txt, bool name_list=new QListWidget(completion_wgt); name_list->setSpacing(2); name_list->setIconSize(QSize(16,16)); - name_list->setSortingEnabled(true); + name_list->setSortingEnabled(false); persistent_chk=new QCheckBox(completion_wgt); persistent_chk->setText(trUtf8("Make &persistent")); @@ -258,6 +258,12 @@ void CodeCompletionWidget::insertCustomItems(const QStringList &names, const QSt } } +void CodeCompletionWidget::insertCustomItems(const QStringList &names, const QString &tooltip, ObjectType obj_type) +{ + for(auto &name : names) + insertCustomItem(name, tooltip, QPixmap(PgModelerUiNS::getIconPath(obj_type))); +} + void CodeCompletionWidget::clearCustomItems(void) { custom_items.clear(); diff --git a/libpgmodeler_ui/src/codecompletionwidget.h b/libpgmodeler_ui/src/codecompletionwidget.h index 347104e912..d8faf7a3d5 100644 --- a/libpgmodeler_ui/src/codecompletionwidget.h +++ b/libpgmodeler_ui/src/codecompletionwidget.h @@ -112,11 +112,14 @@ class CodeCompletionWidget: public QWidget highlighter uses an different configuration */ void configureCompletion(DatabaseModel *db_model, SyntaxHighlighter *syntax_hl=nullptr, const QString &keywords_grp=QString("keywords")); - //! \brief Inserts a custom named item on the list with a custom icon. Custom item will be always appear at the beggining of the list + //! \brief Inserts a custom named item on the list with a custom icon. Custom item will always appear at the beggining of the list void insertCustomItem(const QString &name, const QString &tooltip, const QPixmap &icon); - //! \brief Inserts several custom named item on the list with a custom icon. Custom item will be always appear at the beggining of the list + //! \brief Inserts several custom named item on the list with a custom icon. Custom item will always appear at the beggining of the list void insertCustomItems(const QStringList &names, const QStringList &tooltips, const QPixmap &icon); + +//! \brief Inserts several custom named items on the list with an icon related to the obj_type. Custom item will always appear at the beggining of the list + void insertCustomItems(const QStringList &names, const QString &tooltip, ObjectType obj_type); //! \brief Clear the custom added items void clearCustomItems(void); diff --git a/libpgmodeler_ui/src/datamanipulationform.cpp b/libpgmodeler_ui/src/datamanipulationform.cpp index 64ab8b381e..0e7394af5e 100644 --- a/libpgmodeler_ui/src/datamanipulationform.cpp +++ b/libpgmodeler_ui/src/datamanipulationform.cpp @@ -374,6 +374,9 @@ void DataManipulationForm::retrieveData(void) paste_tb->setEnabled(!qApp->clipboard()->text().isEmpty() && table_cmb->currentData().toUInt() == OBJ_TABLE && !col_names.isEmpty()); + + code_compl_wgt->clearCustomItems(); + code_compl_wgt->insertCustomItems(col_names, trUtf8("Column"), OBJ_COLUMN); } catch(Exception &e) { From 888a2329f6aa613ea42d0c693ee187d64d7aba19 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Wed, 2 May 2018 17:47:02 -0300 Subject: [PATCH 17/30] Fixed a bug when selecting line in LineNumbersWidget from bottom to top. Fixed the tab behavior on comment box (issue #1116) --- libpgmodeler_ui/src/linenumberswidget.cpp | 53 +++++++------------ libpgmodeler_ui/src/linenumberswidget.h | 2 +- libpgmodeler_ui/ui/baseobjectwidget.ui | 3 ++ tests/src/linenumberstest/linenumberstest.cpp | 32 ++++++++++- 4 files changed, 55 insertions(+), 35 deletions(-) diff --git a/libpgmodeler_ui/src/linenumberswidget.cpp b/libpgmodeler_ui/src/linenumberswidget.cpp index 670937cae4..ad73c30467 100644 --- a/libpgmodeler_ui/src/linenumberswidget.cpp +++ b/libpgmodeler_ui/src/linenumberswidget.cpp @@ -21,6 +21,7 @@ #include #include "exception.h" #include +#include QColor LineNumbersWidget::font_color=Qt::lightGray; QColor LineNumbersWidget::bg_color=Qt::black; @@ -31,12 +32,13 @@ LineNumbersWidget::LineNumbersWidget(QPlainTextEdit * parent) : QWidget(parent) throw Exception(ERR_ASG_NOT_ALOC_OBJECT ,__PRETTY_FUNCTION__,__FILE__,__LINE__); parent_edt = qobject_cast(parent); - first_line=line_count=0; + first_line=line_count=start_sel_pos=0; dy=0; has_selection = false; - first_sel_line = -1; - last_sel_line = -1; - connect(parent_edt, SIGNAL(selectionChanged()), this, SLOT(updateSelectedLineNumbers())); + start_sel_line = -1; + end_sel_line = -1; + + connect(parent_edt, SIGNAL(selectionChanged()), this, SLOT(updateSelectedLineNumbers())); } void LineNumbersWidget::drawLineNumbers(unsigned first_line, unsigned line_count, int dy) @@ -64,8 +66,8 @@ void LineNumbersWidget::paintEvent(QPaintEvent *event) int y = dy, height = 0; unsigned last_line=first_line + line_count; QFont font = painter.font(); - unsigned fs_line = std::min(first_sel_line, last_sel_line), - ls_line = std::max(first_sel_line, last_sel_line); + unsigned fs_line = std::min(start_sel_line, end_sel_line), + ls_line = std::max(start_sel_line, end_sel_line); //Repaint the widget to clear previous drawn numbers painter.fillRect(event->rect(), bg_color); @@ -99,12 +101,11 @@ void LineNumbersWidget::mousePressEvent(QMouseEvent *event) { QTextCursor cursor = parent_edt->cursorForPosition(QPoint(0, event->pos().y())); - parent_edt->blockSignals(true); cursor.select(QTextCursor::LineUnderCursor); parent_edt->setTextCursor(cursor); has_selection = true; - first_sel_line = last_sel_line = cursor.blockNumber(); - this->update(); + start_sel_line = end_sel_line = cursor.blockNumber(); + start_sel_pos = cursor.position(); } } @@ -115,43 +116,29 @@ void LineNumbersWidget::mouseMoveEvent(QMouseEvent *event) QTextCursor cursor = parent_edt->cursorForPosition(QPoint(0, event->pos().y())), curr_cursor = parent_edt->textCursor(); - last_sel_line = cursor.blockNumber(); + end_sel_line = cursor.blockNumber(); - //If the current selected line is the same as the first one (when the first click ocurred) - if(first_sel_line == cursor.blockNumber()) - { - //Forcing the selection of the whole line - cursor.movePosition(QTextCursor::StartOfLine); - cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); - parent_edt->setTextCursor(cursor); - } //If the user wants selects lines below the first - else if(first_sel_line < cursor.blockNumber()) + if(start_sel_line < end_sel_line) { cursor.movePosition(QTextCursor::EndOfLine); curr_cursor.setPosition(cursor.position(), QTextCursor::KeepAnchor); parent_edt->setTextCursor(curr_cursor); } //If the user wants selects lines above the first - else + else if(start_sel_line > end_sel_line) { - int pos = curr_cursor.position(); - - //We first move the cursor related to the mouse position to the start of the line - cursor.movePosition(QTextCursor::StartOfLine); - //Then we move it to the position of the current cursor (where the click occured) - cursor.setPosition(pos, QTextCursor::KeepAnchor); - parent_edt->setTextCursor(cursor); + curr_cursor.setPosition(start_sel_pos); + curr_cursor.movePosition(QTextCursor::EndOfLine); + curr_cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, curr_cursor.position() - cursor.position()); + parent_edt->setTextCursor(curr_cursor); } - - this->update(); } } void LineNumbersWidget::mouseReleaseEvent(QMouseEvent *) { has_selection = false; - parent_edt->blockSignals(false); } QColor LineNumbersWidget::getBackgroundColor(void) @@ -169,12 +156,12 @@ void LineNumbersWidget::updateSelectedLineNumbers(void) end = cursor; start.setPosition(cursor.selectionStart()); - first_sel_line = start.blockNumber(); + start_sel_line = start.blockNumber(); end.setPosition(cursor.selectionEnd()); - last_sel_line = end.blockNumber(); + end_sel_line = end.blockNumber(); } else - first_sel_line = last_sel_line = -1; + start_sel_line = end_sel_line = -1; this->update(); } diff --git a/libpgmodeler_ui/src/linenumberswidget.h b/libpgmodeler_ui/src/linenumberswidget.h index 309fa8fad5..1b6bc033da 100644 --- a/libpgmodeler_ui/src/linenumberswidget.h +++ b/libpgmodeler_ui/src/linenumberswidget.h @@ -45,7 +45,7 @@ class LineNumbersWidget : public QWidget { //! \brief The y axis increment to start drawn the line number int dy; - int first_sel_line, last_sel_line; + int start_sel_line, end_sel_line, start_sel_pos; //! \brief Font color for drawn line numbers static QColor font_color, diff --git a/libpgmodeler_ui/ui/baseobjectwidget.ui b/libpgmodeler_ui/ui/baseobjectwidget.ui index c3db5ea209..6d8136f248 100644 --- a/libpgmodeler_ui/ui/baseobjectwidget.ui +++ b/libpgmodeler_ui/ui/baseobjectwidget.ui @@ -507,6 +507,9 @@ This will disable the code of all child and referrer objects. 80 + + true + diff --git a/tests/src/linenumberstest/linenumberstest.cpp b/tests/src/linenumberstest/linenumberstest.cpp index 37aaff4e1b..8fe9823259 100644 --- a/tests/src/linenumberstest/linenumberstest.cpp +++ b/tests/src/linenumberstest/linenumberstest.cpp @@ -37,7 +37,7 @@ void LineNumbersTest::handleLineSelectionUsingMouse(void) LineNumbersWidget::setColors(Qt::darkGray, QColor(230,230,230)); layout->addWidget(edt); - dlg->setMinimumSize(640,480); + dlg->setMinimumSize(640,220); edt->setPlainText("--\n\ -- PostgreSQL database dump\n\ @@ -51,6 +51,36 @@ SET lock_timeout = 0;\n\ SET client_encoding = 'UTF8';\n\ SET standard_conforming_strings = on;\n\ SET check_function_bodies = false;\n\ +SET client_min_messages = warning;\n\ +--\n\ +-- PostgreSQL database dump\n\ +--\n\ +-- Dumped from database version 9.4.4\n\ +-- Dumped by pg_dump version 9.4.4\n\ +-- Started on 2015-07-20 19:24:52 WEST\n\ +SET statement_timeout = 0;\n\ +SET lock_timeout = 0;\n\ +SET client_encoding = 'UTF8';\n\ +SET standard_conforming_strings = on;\n\ +SET check_function_bodies = false;\n\ +SET client_min_messages = warning;\n\ +-- Dumped from database version 9.4.4\n\ +-- Dumped by pg_dump version 9.4.4\n\ +-- Started on 2015-07-20 19:24:52 WEST\n\ +SET statement_timeout = 0;\n\ +SET lock_timeout = 0;\n\ +SET client_encoding = 'UTF8';\n\ +SET standard_conforming_strings = on;\n\ +SET check_function_bodies = false;\n\ +SET client_min_messages = warning;\n\ +-- Dumped from database version 9.4.4\n\ +-- Dumped by pg_dump version 9.4.4\n\ +-- Started on 2015-07-20 19:24:52 WEST\n\ +SET statement_timeout = 0;\n\ +SET lock_timeout = 0;\n\ +SET client_encoding = 'UTF8';\n\ +SET standard_conforming_strings = on;\n\ +SET check_function_bodies = false;\n\ SET client_min_messages = warning;"); dlg->exec(); From ba2a671010ce362eceeede51ee53a56d602b63eb Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Thu, 3 May 2018 09:44:05 -0300 Subject: [PATCH 18/30] Disabled the drag & drop for items in the side listing at ConfigurationForm (issue #1117) --- libpgmodeler_ui/ui/configurationform.ui | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libpgmodeler_ui/ui/configurationform.ui b/libpgmodeler_ui/ui/configurationform.ui index c33ee5bf83..e2e72b0462 100644 --- a/libpgmodeler_ui/ui/configurationform.ui +++ b/libpgmodeler_ui/ui/configurationform.ui @@ -117,7 +117,7 @@ false - QAbstractItemView::DragOnly + QAbstractItemView::NoDragDrop Qt::IgnoreAction @@ -205,6 +205,9 @@ :/icones/icones/relationshiptv.png:/icones/icones/relationshiptv.png + + ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled + @@ -244,6 +247,9 @@ :/icones/icones/codesnippet.png:/icones/icones/codesnippet.png + + ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled + From 36ccf2d1393bca4dff6cc0ed8176ae86cc8b0214 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Thu, 3 May 2018 09:51:29 -0300 Subject: [PATCH 19/30] Fixed the check boxes disabling linked to identifier (issue #1118) --- libpgmodeler_ui/src/relationshipwidget.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libpgmodeler_ui/src/relationshipwidget.cpp b/libpgmodeler_ui/src/relationshipwidget.cpp index f96962eb41..478dd38fa2 100644 --- a/libpgmodeler_ui/src/relationshipwidget.cpp +++ b/libpgmodeler_ui/src/relationshipwidget.cpp @@ -157,8 +157,12 @@ RelationshipWidget::RelationshipWidget(QWidget *parent): BaseObjectWidget(parent connect(deferrable_chk, SIGNAL(toggled(bool)), deferral_cmb, SLOT(setEnabled(bool))); connect(deferrable_chk, SIGNAL(toggled(bool)), deferral_lbl, SLOT(setEnabled(bool))); - connect(identifier_chk, SIGNAL(toggled(bool)), table1_mand_chk, SLOT(setDisabled(bool))); - connect(identifier_chk, SIGNAL(toggled(bool)), table2_mand_chk, SLOT(setDisabled(bool))); + connect(identifier_chk, &QCheckBox::toggled, [&](){ + table1_mand_chk->setDisabled(identifier_chk->isChecked()); + table2_mand_chk->setEnabled(!identifier_chk->isChecked() && + this->object && + dynamic_cast(this->object)->getRelationshipType() != BaseRelationship::RELATIONSHIP_1N); + }); connect(attributes_tab, SIGNAL(s_rowsRemoved(void)), this, SLOT(removeObjects(void))); connect(attributes_tab, SIGNAL(s_rowAdded(int)), this, SLOT(addObject(void))); From f33ad6769017c436767f474a97b44047a1706289 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Thu, 3 May 2018 14:36:45 -0300 Subject: [PATCH 20/30] Refactored the LineNumbersWidget improving the line selection feature --- libpgmodeler_ui/src/linenumberswidget.cpp | 55 ++++++++++------------- libpgmodeler_ui/src/linenumberswidget.h | 5 +-- 2 files changed, 25 insertions(+), 35 deletions(-) diff --git a/libpgmodeler_ui/src/linenumberswidget.cpp b/libpgmodeler_ui/src/linenumberswidget.cpp index ad73c30467..35b564f698 100644 --- a/libpgmodeler_ui/src/linenumberswidget.cpp +++ b/libpgmodeler_ui/src/linenumberswidget.cpp @@ -36,9 +36,8 @@ LineNumbersWidget::LineNumbersWidget(QPlainTextEdit * parent) : QWidget(parent) dy=0; has_selection = false; start_sel_line = -1; - end_sel_line = -1; - connect(parent_edt, SIGNAL(selectionChanged()), this, SLOT(updateSelectedLineNumbers())); + connect(parent_edt, SIGNAL(selectionChanged()), this, SLOT(update())); } void LineNumbersWidget::drawLineNumbers(unsigned first_line, unsigned line_count, int dy) @@ -66,8 +65,17 @@ void LineNumbersWidget::paintEvent(QPaintEvent *event) int y = dy, height = 0; unsigned last_line=first_line + line_count; QFont font = painter.font(); - unsigned fs_line = std::min(start_sel_line, end_sel_line), - ls_line = std::max(start_sel_line, end_sel_line); + unsigned fs_line = 0, ls_line = 0; + QTextCursor cursor = parent_edt->textCursor(); + + if(cursor.hasSelection()) + { + QTextCursor start = cursor, end = cursor; + start.setPosition(cursor.selectionStart(), QTextCursor::MoveAnchor); + fs_line = start.blockNumber(); + end.setPosition(cursor.selectionEnd(), QTextCursor::KeepAnchor); + ls_line = end.blockNumber(); + } //Repaint the widget to clear previous drawn numbers painter.fillRect(event->rect(), bg_color); @@ -76,7 +84,7 @@ void LineNumbersWidget::paintEvent(QPaintEvent *event) //Draw line numbers for(unsigned lin=first_line; lin < last_line; lin++) { - font.setBold(lin-1 >= fs_line && lin-1 <= ls_line); + font.setBold(cursor.hasSelection() && lin-1 >= fs_line && lin-1 <= ls_line); height = QFontMetrics(font).height(); painter.setFont(font); @@ -101,10 +109,10 @@ void LineNumbersWidget::mousePressEvent(QMouseEvent *event) { QTextCursor cursor = parent_edt->cursorForPosition(QPoint(0, event->pos().y())); + has_selection = true; cursor.select(QTextCursor::LineUnderCursor); parent_edt->setTextCursor(cursor); - has_selection = true; - start_sel_line = end_sel_line = cursor.blockNumber(); + start_sel_line = cursor.blockNumber(); start_sel_pos = cursor.position(); } } @@ -116,23 +124,28 @@ void LineNumbersWidget::mouseMoveEvent(QMouseEvent *event) QTextCursor cursor = parent_edt->cursorForPosition(QPoint(0, event->pos().y())), curr_cursor = parent_edt->textCursor(); - end_sel_line = cursor.blockNumber(); - //If the user wants selects lines below the first - if(start_sel_line < end_sel_line) + if(start_sel_line < cursor.blockNumber()) { cursor.movePosition(QTextCursor::EndOfLine); curr_cursor.setPosition(cursor.position(), QTextCursor::KeepAnchor); parent_edt->setTextCursor(curr_cursor); } //If the user wants selects lines above the first - else if(start_sel_line > end_sel_line) + else if(start_sel_line > cursor.blockNumber()) { curr_cursor.setPosition(start_sel_pos); curr_cursor.movePosition(QTextCursor::EndOfLine); curr_cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, curr_cursor.position() - cursor.position()); parent_edt->setTextCursor(curr_cursor); } + else + { + cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); + parent_edt->setTextCursor(cursor); + } + + this->update(); } } @@ -145,23 +158,3 @@ QColor LineNumbersWidget::getBackgroundColor(void) { return(LineNumbersWidget::bg_color); } - -void LineNumbersWidget::updateSelectedLineNumbers(void) -{ - QTextCursor cursor = parent_edt->textCursor(); - - if(cursor.hasSelection()) - { - QTextCursor start = cursor, - end = cursor; - - start.setPosition(cursor.selectionStart()); - start_sel_line = start.blockNumber(); - end.setPosition(cursor.selectionEnd()); - end_sel_line = end.blockNumber(); - } - else - start_sel_line = end_sel_line = -1; - - this->update(); -} diff --git a/libpgmodeler_ui/src/linenumberswidget.h b/libpgmodeler_ui/src/linenumberswidget.h index 1b6bc033da..420f63b2c6 100644 --- a/libpgmodeler_ui/src/linenumberswidget.h +++ b/libpgmodeler_ui/src/linenumberswidget.h @@ -45,7 +45,7 @@ class LineNumbersWidget : public QWidget { //! \brief The y axis increment to start drawn the line number int dy; - int start_sel_line, end_sel_line, start_sel_pos; + int start_sel_line, start_sel_pos; //! \brief Font color for drawn line numbers static QColor font_color, @@ -70,9 +70,6 @@ class LineNumbersWidget : public QWidget { static void setColors(const QColor &font_color, const QColor &bg_color); static QColor getBackgroundColor(void); - - private slots: - void updateSelectedLineNumbers(void); }; #endif From a24c03edefe7c285fd697473469e8bed4dfbc7be Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Thu, 3 May 2018 15:00:46 -0300 Subject: [PATCH 21/30] Removing unused includes --- libpgmodeler_ui/src/linenumberswidget.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libpgmodeler_ui/src/linenumberswidget.cpp b/libpgmodeler_ui/src/linenumberswidget.cpp index 35b564f698..eb8ffb76b6 100644 --- a/libpgmodeler_ui/src/linenumberswidget.cpp +++ b/libpgmodeler_ui/src/linenumberswidget.cpp @@ -20,8 +20,6 @@ #include #include #include "exception.h" -#include -#include QColor LineNumbersWidget::font_color=Qt::lightGray; QColor LineNumbersWidget::bg_color=Qt::black; From e267b6d418c635513bb3c3912102f92b7a01f71e Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Fri, 4 May 2018 14:33:48 -0300 Subject: [PATCH 22/30] Minor fixes in messages in PgModelerCLI --- main-cli/src/pgmodelercli.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/main-cli/src/pgmodelercli.cpp b/main-cli/src/pgmodelercli.cpp index 7a91ff94e2..a618817666 100644 --- a/main-cli/src/pgmodelercli.cpp +++ b/main-cli/src/pgmodelercli.cpp @@ -1383,9 +1383,10 @@ void PgModelerCLI::diffModelDatabase(void) QString res, buff, line; QTextStream in(stdin), preview; + buff += "\n** Press ENTER to scroll the preview **\n"; buff += "\n### DIFF PREVIEW ###\n\n"; buff += diff_hlp.getDiffDefinition(); - buff += "\n### END PREVIEW ###\n\n"; + buff += "\n### END OF PREVIEW ###\n\n"; preview.setString(&buff, QIODevice::ReadOnly); @@ -1406,7 +1407,7 @@ void PgModelerCLI::diffModelDatabase(void) } out << endl; - out << trUtf8("** WARNING: you are about to apply the generated SQL code to the server! Data can be lost in the process.") << endl; + out << trUtf8("** WARNING: You are about to apply the generated diff code to the server. Data can be lost in the process!") << endl; do { From 2a427a6dedddb4ab014918e42107ca26322e6528 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Mon, 7 May 2018 09:33:16 -0300 Subject: [PATCH 23/30] Updates on CHANGELOG.md and RELEASENOTES.md for 0.9.1 --- CHANGELOG.md | 47 +++++++++++++++++++++++++ RELEASENOTES.md | 93 ++++++++++++++++++++++++------------------------- 2 files changed, 92 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ac057b6c7..6e598663c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,53 @@ Change Log --------- +v0.9.1 +------ +Release date: May 14, 2018
+ +* [New] Added support to line selection by clicking and moving the mouse over the line numbers widget in any source code field. +* [New] The validator now checks if the model has columns referencing spatial data types and creates the postgis extension automatically when fixing the model. +* [New] Added support to RESTART IDENTITY on truncate tables in DatabaseExplorerWidget. +* [New] Added an custom option checkbox in Messagebox for general purpose usage. +* [New] Added support to diff operation in CLI. +* [New] Added support to import database from CLI. +* [New] Adding missing types regrole and regnamespace. +* [Change] Added column names to the code completion widget used in the filter widget at DataManipulationForm. +* [Change] Improved the SQLExecutionWidget in such way that it'll display large amount of data more quickly and consuming less memory. +* [Change] Minor improvement in SQLExecutionWidget to show the amount of time took to run a query. +* [Change] Minor improvement in the text find widgets in SQL tool in order to make them closable via dedicated button. +* [Change] Improved the set tag operation in ModelWidget in order to cleanup the assigned tags to a set of objects. +* [Change] Minor improvement on DatabaseExplorerWidget to show the rls attributes labels correctly in the attributes grid. +* [Change] Refactored all the CLI options. +* [Change] Minor change in Connection::generateConnectionString in order to put the dbname param in the start of the string. +* [Change] Improved the performance of the row duplication action in DataManipulationForm. +* [Change] Minor improvement in order to update the schemas boxes when the tables have their extended attributes box toggled. +* [Change] Improved the performance of "Move to schema" operation. +* [Change] Added an busy cursor while closing a model. +* [Change] Improved the object selection in object finder. +* [Change] Changed the behaviour of select and fade buttons in ObjectFinderWidget in such way to enable the user to select/fade the objects in the listing (or not included in the results). +* [Fix] Fixed the check boxes disabling when dealing with identifier relationships. +* [Fix] Disabled the drag & drop for items in the side listing at ConfigurationForm. +* [Fix] Fixed the tab behavior on comment box in all editing forms of database objects. +* [Fix] Fixed the catalog query for user defined types. +* [Fix] Fixed the import of user defined types which names contains uppercase characters. +* [Fix] Minor typo fixes in CLI. +* [Fix] Fix window scaling on HiDPI/Retina screens. +* [Fix] Minor fix in Connection::getConnectionId in order to omit port when that parameter is not configured in the connection. +* [Fix] Fixed a bug in ModelExportHelper that was failing to remane the database when the command appeared. +* [Fix] Fixed a bug in CollationWidget that was referencing the collation attributes LC_??? using the wrong constant. +* [Fix] Fixed the behaviour of the message box that warns about the need of validate the model prior to export, save or diff. Now rejecting the dialog (i.e. closing it) will be considered that the user wants to proceed with the pending operation even with an invalid model. +* [Fix] Fixed the import of comments for constraints,triggers, index and rules. +* [Fix] The value input in BulkDataEditWidget will be focused as soon as the widget appears. +* [Fix] Fixed a bug in the aggregate import process. +* [Fix] Minor fix in DataManipulationForm to avoid the generation of a where clause when the filter is filled only with spaces. +* [Fix] Minor fix in the magnfier tool to use the same render hints as the canvas viewport. +* [Fix] Fixed a bug in the diff process that was trying to recreate the whole database when the "Force recreation" option was set. +* [Fix] Fixed a bug when showing the source of tables in DatabaseExplorerWidget when these objects have permissions assigned. +* [Fix] Adjusting tables position when the parent schema is moved and the alignment to grid is enabled. +* [Fix] Minor fix in the CLI menu. +* [Fix] Fixed the saving process for large models by stopping the threads related to temp models saving while the model file is being written. + v0.9.1-beta1 ------ Release date: April 6, 2018
diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 3840d69f48..ca78f91910 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -1,50 +1,47 @@ -v0.9.1-beta1 +v0.9.1 ------ -Release date: April 6, 2018
-Changes since: v0.9.1-beta
- -Summary: finally we've reached the last beta release of the 0.9.1! This time pgModeler brings important fixes and new features requested long ago which are finally implemented in experimental stage.
- -The first new feature we have in this release is the support to multiples relationships for the same pair of tables. In previous versions, pgModeler would refuse to create a second relationship between the tables A and B. From now on, pgModeler will accept the creation of one-to-many and many-to-many relationships linking A and B more then once. For the other kinds of relationships (generalization, copy, one-to-one) the old rule is still valid: only one relationship per table pair is accepted.
- -Some missing features of PostgreSQL are present in this version too being them: row level security (RLS) and identity columns. For RLS, introduced in PostgreSQL 9.5, we have added the related options to toggle it in tables (ENABLE|FORCE RLS) as well the support to policy objects which are the main part of this new security modality. The identity columns, introduced in PostgreSQL 10, are now fully supported by pgModeler and you can make use of them from the column editing form.
- -Other new feature is the support to multiple check constraints by domains. Actually, this is more a patch than a new feature because pgModeler was unaware that domains could support more than one check constraint, so we have fixed that now.
- -Now, talking about changes, we fixed an old missinterpretation of the PostgreSQL's documentations by changing the way extensions are stored in the database model. Previously, this kind of objects were stored at schemas level but the right way to store them is at database level. So now instead of seeing extensions in the schema's subtree you'll see them in the database subtree. All validation rules, export, import and diff processes were fixed in such way to reflect the right way to treat these objects.
- -Another important change, and that one is related to an annoying behaviour of the tool, is that pgModeler will silently ignore the absence of the plugins folder and proceed with the normal startup avoiding the display of a message box regarding the missing folder and automatically disabling the plugins search mechanism.
- -In the fixes section, we've included a patch for a bug that was causing recurrent crashes on macOS when the user tried to load a second model file making almost impossible the working on two or more database models at once. Also, we've patched the reverse engineering in such way to avoid the duplication of data types related to tables, sequences and views which was causing problems in the validation process. Another fix was done in the diff process that was generating a malformed DROP command for extensions.
- -The set of changes of this release has 47 entries between new features, changes, improvements and bug fixes. Below we highlight some of them, for the complete list, please, consider reading the CHANGELOG.md.
- -* [New] Added the ability to create multiples one-to-many and many-to-many relatationships between the same pair of tables. -* [New] Added the ability to use more special ascii chars in the middle of object names. -* [New] Added support to multi line comments in UI. -* [New] Added full support to row level security (RLS), including export, import and diff of this kind of object. -* [New] Added support to bulk data editing in DataManipulationForm. -* [New] Added an option to diff process to force the generation of DROP commands for columns and constraints even if the missing objects need to be preserved. This is useful to work with partial models and the user need to remove columns/constraints and preserve the rest of objects. -* [New] Added support to identity columns (PostgreSQL 10). -* [New] Added the support to BYPASSRLS option on roles. -* [New] Added support to IS_TEMPLATE and ALLOW_CONNECTIONS options in database object. -* [New] Added the procedures to fix old style domains in CLI. -* [New] Added support to multiple check constraint in domains. -* [New] Added support to sort items alphabetically (ascending) or by oid in DatabaseExplorerWidget. -* [Change] Changed the input mode of the password field in ConnectionsConfigWidget in order to hide the passwords in the form. NOTE: the passwords are still in plain text in the config file. -* [Change] Moved extensions from schema level to database level in order to reproduce better the PostgreSQL's behavior. -* [Change] In GeneralConfigWidget when restoring default settings the default settings for syntax highlight are restored as well. -* [Change] pgModeler will not try to create the plugins path anymore. This will avoid constant error messages during startup. Now, it'll silently ignore the absence of that folder and skip the plugin loading. -* [Change] Improved the source editing in external application. The use is informed about the app running state and the contents for the source editor field are locked until the user closes the external app. -* [Fix] Fixed the query catalog for built-in types to include the types related to domains. -* [Fix] Fixed the extension creation, allowing only one instance of the named extension per database no matter the schema used to allocate its children objects. -* [Fix] Fixed a bug when dropping Functions in DatabaseExplorerWidget. -* [Fix] Fixed a bug that was causing the disabling of connections for database models created prior to 0.9.1-beta1. -* [Fix] Fixed a bug on import process that was wrongly creating types derivated from tables/sequence/views causing duplication problems during validation. -* [Fix] Fixed a crash on macOs when opening a second model. -* [Fix] Fixed an issue in diff process that was generating a malformed DROP command for extensions. -* [Fix] Fixed the diff for domains which contain multiple check constraints. -* [Fix] Fixed a bug that was not selecting the correct spatial type in the widget. -* [Fix] Fixed a conflict of shortcuts in DatabaseExplorerWidget. Now F5 updates a leaf/subtree and Alt+F5 performs quick refresh of the tree. -* [Fix] Fixed a problem with sqlexecutionwidget.ui that is not building properly in Qt 5.10. +Release date: May 14, 2018
+Changes since: v0.9.1-beta1
+ +Summary: after eight months of hard work we finally have the stable release 0.9.1. This version is a mark in the pgModeler's development and so important as the release 0.8.2 in terms of improvements because it brought features requested long ago and that will make pgModeler even better to work with, being some of them: crow's foot notation support, multiple relationships for the same table pair, support to row level security, identity columns and much more.
+ +For this release specifically (considering only the work after 0.9.1-beta1), the golden rule was to fix bugs, adjust the current features and introduce few new things and thus was done: 21 bug fixes, 14 changes/improvements and 7 new features. + +The majority of new features are related to the CLI which received the ability to import and diff databases which can make it even better to integrate to automtated deployment processess or run quick tasks over models or databases without the need to open pgModeler's GUI.
+ +Some important improvements were done in the overall performance of the SQL tool. The query execution and results display are a lot better now being quicker and less eager in terms of memory consumption avoiding crashes when querying large tables. The data manipulation also received a patch that makes the row duplication more efficient.
+ +Now, for the fixes, another patch was introduced in order to resize correctly dialogs in HiDPI/Retina displays. Several reverse engineering bugs were fixes and now databases are imported more precisely compared to previous releases. Lastly, a bug that seems to happen only on macOS while dealing with large models is finally fixed and was related to some running threads messing around with the main process avoiding it to correctly save the model and causing hang ups sometimes.
+ +The whole set of changes of this release (considering the alpha and beta stages) has 152 entries being 43 new features, 47 changes/improvements and 62 bug fixes. Below we highlight some of news for the work since 0.9.1-beta1, for the complete list of changes, please, take a look into the CHANGELOG.md.
+ +* [New] Added support to line selection by clicking and moving the mouse over the line numbers widget in any source code field. +* [New] The validator now checks if the model has columns referencing spatial data types and creates the postgis extension automatically when fixing the model. +* [New] Added support to RESTART IDENTITY on truncate tables in DatabaseExplorerWidget. +* [New] Added support to diff operation in CLI. +* [New] Added support to import database from CLI. +* [New] Adding missing types regrole and regnamespace. +* [Change] Added column names to the code completion widget used in the filter widget at DataManipulationForm. +* [Change] Improved the SQLExecutionWidget in such way that it'll display large amount of data more quickly and consuming less memory. +* [Change] Minor improvement in SQLExecutionWidget to show the amount of time took to run a query. +* [Change] Minor improvement in the text find widgets in SQL tool in order to make them closable via dedicated button. +* [Change] Improved the set tag operation in ModelWidget in order to cleanup the assigned tags to a set of objects. +* [Change] Refactored all the CLI options. +* [Change] Improved the performance of the row duplication action in DataManipulationForm. +* [Change] Improved the performance of "Move to schema" operation. +* [Change] Changed the behaviour of select and fade buttons in ObjectFinderWidget in such way to enable the user to select/fade the objects in the listing (or not included in the results). +* [Fix] Fixed the tab behavior on comment box in all editing forms of database objects. +* [Fix] Fixed the catalog query for user defined types. +* [Fix] Fixed the import of user defined types which names contains uppercase characters. +* [Fix] Fix window scaling on HiDPI/Retina screens. +* [Fix] Fixed a bug in ModelExportHelper that was failing to remane the database when the command appeared. +* [Fix] Fixed a bug in CollationWidget that was referencing the collation attributes LC_??? using the wrong constant. +* [Fix] Fixed the behaviour of the message box that warns about the need of validate the model prior to export, save or diff. Now rejecting the dialog (i.e. closing it) will be considered that the user wants to proceed with the pending operation even with an invalid model. +* [Fix] Fixed the import of comments for constraints,triggers, index and rules. +* [Fix] Fixed a bug in the aggregate import process. +* [Fix] Minor fix in DataManipulationForm to avoid the generation of a where clause when the filter is filled only with spaces. +* [Fix] Minor fix in the magnfier tool to use the same render hints as the canvas viewport. +* [Fix] Fixed a bug in the diff process that was trying to recreate the whole database when the "Force recreation" option was set. +* [Fix] Fixed a bug when showing the source of tables in DatabaseExplorerWidget when these objects have permissions assigned. +* [Fix] Fixed the saving process for large models by stopping the threads related to temp models saving while the model file is being written. From 01374a1b636959915b4a01dc66a0eb518c93783f Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Tue, 8 May 2018 11:37:49 -0300 Subject: [PATCH 24/30] Improved the object duplication/copy operation so the rules, index, triggers, and policies can be copied together with the parent object (issue #1120) --- libpgmodeler_ui/src/modelwidget.cpp | 48 ++++++++++++++++------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/libpgmodeler_ui/src/modelwidget.cpp b/libpgmodeler_ui/src/modelwidget.cpp index 24166edcf7..128f436c64 100644 --- a/libpgmodeler_ui/src/modelwidget.cpp +++ b/libpgmodeler_ui/src/modelwidget.cpp @@ -2212,9 +2212,9 @@ void ModelWidget::copyObjects(bool duplicate_mode) vector deps; BaseObject *object=nullptr; TableObject *tab_obj=nullptr; - Table *table=nullptr; + BaseTable *table=nullptr; Constraint *constr=nullptr; - ObjectType types[]={ OBJ_TRIGGER, OBJ_INDEX, OBJ_CONSTRAINT }; + ObjectType types[]={ OBJ_TRIGGER, OBJ_RULE, OBJ_INDEX, OBJ_CONSTRAINT, OBJ_POLICY }; unsigned i, type_id, count; Messagebox msg_box; @@ -2256,11 +2256,11 @@ void ModelWidget::copyObjects(bool duplicate_mode) /* Copying the special objects (which references columns added by relationship) in order to be correclty created when pasted */ - if(object->getObjectType()==OBJ_TABLE) + if(object->getObjectType()==OBJ_TABLE || object->getObjectType() == OBJ_VIEW) { - table=dynamic_cast
(object); + table=dynamic_cast(object); - for(type_id=0; type_id < 3; type_id++) + for(type_id=0; type_id < 4; type_id++) { count=table->getObjectCount(types[type_id]); @@ -2273,14 +2273,16 @@ void ModelWidget::copyObjects(bool duplicate_mode) columns added by relationship. Case the object is a constraint, it cannot be a primary key because this type of constraint is treated separetely by relationships */ if(!tab_obj->isAddedByRelationship() && - ((constr && + (!constr || + (((constr && (constr->getConstraintType()==ConstraintType::foreign_key || (constr->getConstraintType()==ConstraintType::unique && - constr->isReferRelationshipAddedColumn()))) || - (types[type_id]==OBJ_TRIGGER && dynamic_cast(tab_obj)->isReferRelationshipAddedColumn()) || - (types[type_id]==OBJ_INDEX && dynamic_cast(tab_obj)->isReferRelationshipAddedColumn()))) + constr->isReferRelationshipAddedColumn()))))))) deps.push_back(tab_obj); } + + if(object->getObjectType() == OBJ_VIEW && type_id >= 2) + break; } } } @@ -2376,7 +2378,7 @@ void ModelWidget::pasteObjects(void) aux_object=db_model->getObject(aux_name, obj_type); else { - if(sel_view && (obj_type==OBJ_TRIGGER || obj_type==OBJ_RULE)) + if(sel_view && (obj_type==OBJ_TRIGGER || obj_type==OBJ_RULE || obj_type==OBJ_INDEX)) aux_object=sel_view->getObject(aux_name, obj_type); else if(sel_table) aux_object=sel_table->getObject(aux_name, obj_type); @@ -2422,7 +2424,12 @@ void ModelWidget::pasteObjects(void) else { if(tab_obj) - tab_obj->setName(PgModelerNS::generateUniqueName(tab_obj, (*sel_table->getObjectList(tab_obj->getObjectType())), false, QString("_cp"), true)); + { + if(sel_table) + tab_obj->setName(PgModelerNS::generateUniqueName(tab_obj, (*sel_table->getObjectList(tab_obj->getObjectType())), false, QString("_cp"), true)); + else + tab_obj->setName(PgModelerNS::generateUniqueName(tab_obj, (*sel_view->getObjectList(tab_obj->getObjectType())), false, QString("_cp"), true)); + } else object->setName(PgModelerNS::generateUniqueName(object, (*db_model->getObjectList(object->getObjectType())), false, QString("_cp"), true)); @@ -2469,11 +2476,12 @@ void ModelWidget::pasteObjects(void) parent=sel_view; /* Only generates the XML for a table object when the selected receiver object - is a table or is a view and the current object is a trigger or rule (because + is a table or is a view and the current object is a trigger, index, or rule (because view's only accepts this two types) */ if(sel_table || (sel_view && (tab_obj->getObjectType()==OBJ_TRIGGER || - tab_obj->getObjectType()==OBJ_RULE))) + tab_obj->getObjectType()==OBJ_RULE || + tab_obj->getObjectType()==OBJ_INDEX))) { //Backups the original parent table orig_parent_tab=tab_obj->getParentTable(); @@ -2551,17 +2559,11 @@ void ModelWidget::pasteObjects(void) //Special case for table objects if(tab_obj) { - if(sel_table && - (tab_obj->getObjectType()==OBJ_COLUMN || tab_obj->getObjectType()==OBJ_RULE)) + if(sel_table && tab_obj->getObjectType()==OBJ_COLUMN) { sel_table->addObject(tab_obj); sel_table->setModified(true); } - else if(sel_view && tab_obj->getObjectType()==OBJ_RULE) - { - sel_view->addObject(tab_obj); - sel_view->setModified(true); - } //Updates the fk relationships if the constraint is a foreign-key if(constr && constr->getConstraintType()==ConstraintType::foreign_key) @@ -2641,7 +2643,11 @@ void ModelWidget::duplicateObject(void) table = dynamic_cast(object)->getParentTable(); PgModelerNS::copyObject(&dup_object, object, obj_type); - dup_object->setName(PgModelerNS::generateUniqueName(dup_object, *dynamic_cast
(table)->getObjectList(obj_type), false, QString("_cp"))); + + if(table->getObjectType() == OBJ_TABLE) + dup_object->setName(PgModelerNS::generateUniqueName(dup_object, *dynamic_cast
(table)->getObjectList(obj_type), false, QString("_cp"))); + else + dup_object->setName(PgModelerNS::generateUniqueName(dup_object, *dynamic_cast(table)->getObjectList(obj_type), false, QString("_cp"))); op_id=op_list->registerObject(dup_object, Operation::OBJECT_CREATED, -1, table); table->addObject(dup_object); From 196f54a6f751df53f698ab51d8708361c6acfeb1 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Tue, 8 May 2018 11:46:12 -0300 Subject: [PATCH 25/30] Additional updates on CHANGELOG.md and RELEASENOTES.md --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e598663c4..7474f1ebfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ v0.9.1 * [New] Added support to diff operation in CLI. * [New] Added support to import database from CLI. * [New] Adding missing types regrole and regnamespace. +* [Change] Improved the copy/duplicate operation in order to copy rules, index, trigger and policies together to their parents. * [Change] Added column names to the code completion widget used in the filter widget at DataManipulationForm. * [Change] Improved the SQLExecutionWidget in such way that it'll display large amount of data more quickly and consuming less memory. * [Change] Minor improvement in SQLExecutionWidget to show the amount of time took to run a query. diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ca78f91910..4034cefe83 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -22,6 +22,7 @@ The whole set of changes of this release (considering the alpha and beta stages) * [New] Added support to diff operation in CLI. * [New] Added support to import database from CLI. * [New] Adding missing types regrole and regnamespace. +* [Change] Improved the copy/duplicate operation in order to copy rules, index, trigger and policies together to their parents. * [Change] Added column names to the code completion widget used in the filter widget at DataManipulationForm. * [Change] Improved the SQLExecutionWidget in such way that it'll display large amount of data more quickly and consuming less memory. * [Change] Minor improvement in SQLExecutionWidget to show the amount of time took to run a query. From 79eb5247fa75ca4301320e4d22dc92db37aad36c Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Wed, 9 May 2018 16:16:24 -0300 Subject: [PATCH 26/30] Minor layout adjustment on AboutWidget Minor layout adjustment on DonationWidget --- conf/ui-style.conf | 26 +- libpgmodeler_ui/src/aboutwidget.cpp | 19 +- .../src/appearanceconfigwidget.cpp | 2 +- libpgmodeler_ui/src/baseconfigwidget.cpp | 4 +- libpgmodeler_ui/src/baseconfigwidget.h | 5 +- .../src/connectionsconfigwidget.cpp | 2 +- libpgmodeler_ui/src/generalconfigwidget.cpp | 7 +- .../src/relationshipconfigwidget.cpp | 2 +- libpgmodeler_ui/src/snippetsconfigwidget.cpp | 2 +- libpgmodeler_ui/ui/aboutwidget.ui | 936 +++++------------- libpgmodeler_ui/ui/donatewidget.ui | 8 +- 11 files changed, 293 insertions(+), 720 deletions(-) diff --git a/conf/ui-style.conf b/conf/ui-style.conf index 0320e1a21a..cc481818e7 100644 --- a/conf/ui-style.conf +++ b/conf/ui-style.conf @@ -34,12 +34,14 @@ UpdateNotifierWidget > QFrame } AboutWidget > QFrame > QLabel#title_lbl, -AboutWidget > QFrame > QLabel#slogan_lbl, AboutWidget > QFrame > QLabel#about_lbl, -AboutWidget > QFrame > QLabel#pgmodeler_ver_lbl, AboutWidget > QFrame > QLabel#build_lbl, AboutWidget > QFrame > QLabel#copyright_lbl { - color: #000; + color: #000; +} + +AboutWidget > QFrame > QLabel#pgmodeler_ver_lbl { + color: #4C7DD0; } DonateWidget > QFrame > QLabel#title_lbl, @@ -436,23 +438,8 @@ QTabWidget#models_tbw > QTabBar::tab:selected { margin-top: 0px; } -/*QSplitter#h_splitter::handle { - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FAFAFA , stop: 1 #E0E0E0); -} */ - -/*QSplitter#h_splitter_opr_objs::handle { - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FAFAFA , stop: 1 #E0E0E0); - border-left: 1px solid #404040; -}*/ - -/*QSplitter#v_splitter::handle, QSplitter#v_splitter1::handle,QSplitter#v_splitter2::handle { - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FAFAFA , stop: 1 #E0E0E0); -} */ - SQLToolWidget > QWidget#bg_frame { - /*background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FAFAFA , stop: 1 #E0E0E0);*/ - /*border-bottom: 1px solid #d0d0d0; - border-top: transparent;*/ + } /* Floating hint widget member of HintTextWidget */ @@ -471,7 +458,6 @@ HintTextWidget > QWidget HintTextWidget > QWidget > QLabel { color: #0000c0; - /*font-size: 8pt;*/ } QTabWidget#databases_tbw > QTabBar::close-button { diff --git a/libpgmodeler_ui/src/aboutwidget.cpp b/libpgmodeler_ui/src/aboutwidget.cpp index 5c36d6391d..7e01b667c3 100644 --- a/libpgmodeler_ui/src/aboutwidget.cpp +++ b/libpgmodeler_ui/src/aboutwidget.cpp @@ -31,14 +31,13 @@ AboutWidget::AboutWidget(QWidget *parent) : QWidget(parent) drop_shadow->setBlurRadius(30); this->setGraphicsEffect(drop_shadow); - pgmodeler_ver_lbl->setText(QString("v%1").arg(GlobalAttributes::PGMODELER_VERSION)); - build_num_lbl->setText(GlobalAttributes::PGMODELER_BUILD_NUMBER); - - for(int row=0; row < contributors_tab->rowCount(); row++) - contributors_tab->item(row, 2)->setToolTip(contributors_tab->item(row, 2)->text().replace(QString("; "), QString(";\n"))); + PgModelerUiNS::configureWidgetFont(title_lbl, PgModelerUiNS::HUGE_FONT_FACTOR); + PgModelerUiNS::configureWidgetFont(pgmodeler_ver_lbl, PgModelerUiNS::HUGE_FONT_FACTOR); + PgModelerUiNS::configureWidgetFont(build_lbl, PgModelerUiNS::BIG_FONT_FACTOR); + PgModelerUiNS::configureWidgetFont(build_num_lbl, PgModelerUiNS::BIG_FONT_FACTOR); - contributors_tab->sortByColumn(0, Qt::AscendingOrder); - contributors_tab->resizeColumnsToContents(); + pgmodeler_ver_lbl->setText(QString("v%1 ").arg(GlobalAttributes::PGMODELER_VERSION)); + build_num_lbl->setText(QString("%1 Qt %2").arg(GlobalAttributes::PGMODELER_BUILD_NUMBER).arg(QT_VERSION_STR)); connect(hide_tb, &QToolButton::clicked, this, [&](){ @@ -46,12 +45,6 @@ AboutWidget::AboutWidget(QWidget *parent) : QWidget(parent) emit s_visibilityChanged(false); }); - PgModelerUiNS::configureWidgetFont(title_lbl, PgModelerUiNS::HUGE_FONT_FACTOR); - PgModelerUiNS::configureWidgetFont(slogan_lbl, PgModelerUiNS::BIG_FONT_FACTOR); - PgModelerUiNS::configureWidgetFont(pgmodeler_ver_lbl, PgModelerUiNS::HUGE_FONT_FACTOR); - PgModelerUiNS::configureWidgetFont(build_lbl, PgModelerUiNS::MEDIUM_FONT_FACTOR); - PgModelerUiNS::configureWidgetFont(build_num_lbl, PgModelerUiNS::MEDIUM_FONT_FACTOR); - float factor = BaseObjectView::getScreenDpiFactor(); this->adjustSize(); this->resize(this->minimumWidth() * factor, this->minimumHeight() * factor); diff --git a/libpgmodeler_ui/src/appearanceconfigwidget.cpp b/libpgmodeler_ui/src/appearanceconfigwidget.cpp index 15104d7136..6bfb5c8178 100644 --- a/libpgmodeler_ui/src/appearanceconfigwidget.cpp +++ b/libpgmodeler_ui/src/appearanceconfigwidget.cpp @@ -384,7 +384,7 @@ void AppearanceConfigWidget::restoreDefaults(void) { try { - BaseConfigWidget::restoreDefaults(GlobalAttributes::OBJECTS_STYLE_CONF); + BaseConfigWidget::restoreDefaults(GlobalAttributes::OBJECTS_STYLE_CONF, false); this->loadConfiguration(); setConfigurationChanged(true); } diff --git a/libpgmodeler_ui/src/baseconfigwidget.cpp b/libpgmodeler_ui/src/baseconfigwidget.cpp index 8a94221c0b..e211d74e14 100644 --- a/libpgmodeler_ui/src/baseconfigwidget.cpp +++ b/libpgmodeler_ui/src/baseconfigwidget.cpp @@ -99,7 +99,7 @@ void BaseConfigWidget::saveConfiguration(const QString &conf_id, map%1!").arg(bkp_filename), Messagebox::INFO_ICON); diff --git a/libpgmodeler_ui/src/baseconfigwidget.h b/libpgmodeler_ui/src/baseconfigwidget.h index 572f584f5f..9225a529ba 100644 --- a/libpgmodeler_ui/src/baseconfigwidget.h +++ b/libpgmodeler_ui/src/baseconfigwidget.h @@ -55,8 +55,9 @@ class BaseConfigWidget: public QWidget { //! \brief Get a configuratoin key from the xml parser void getConfigurationParams(map &config_params, const vector &key_attribs); - //! \brief Restore the configuration specified by conf_in loading them from the original file (conf/defaults) - void restoreDefaults(const QString &conf_id); + /*! \brief Restore the configuration specified by conf_in loading them from the original file (conf/defaults) + * The silent parameter indicates that the restoration should not emit a message box informing the restoration sucess */ + void restoreDefaults(const QString &conf_id, bool silent); //! \brief Adds a parameter to the specified configuration parameters set static void addConfigurationParam(map &config_params, const QString ¶m, const attribs_map &attribs); diff --git a/libpgmodeler_ui/src/connectionsconfigwidget.cpp b/libpgmodeler_ui/src/connectionsconfigwidget.cpp index 6af970c210..6a764e5dda 100644 --- a/libpgmodeler_ui/src/connectionsconfigwidget.cpp +++ b/libpgmodeler_ui/src/connectionsconfigwidget.cpp @@ -451,7 +451,7 @@ void ConnectionsConfigWidget::restoreDefaults(void) try { //Restore the default connection config file - BaseConfigWidget::restoreDefaults(GlobalAttributes::CONNECTIONS_CONF); + BaseConfigWidget::restoreDefaults(GlobalAttributes::CONNECTIONS_CONF, false); //Remove all connections while(connections_cmb->count() > 0) diff --git a/libpgmodeler_ui/src/generalconfigwidget.cpp b/libpgmodeler_ui/src/generalconfigwidget.cpp index 162a0765fb..b9dada0f9d 100644 --- a/libpgmodeler_ui/src/generalconfigwidget.cpp +++ b/libpgmodeler_ui/src/generalconfigwidget.cpp @@ -557,9 +557,10 @@ void GeneralConfigWidget::restoreDefaults(void) { try { - BaseConfigWidget::restoreDefaults(GlobalAttributes::GENERAL_CONF); - BaseConfigWidget::restoreDefaults(GlobalAttributes::XML_HIGHLIGHT_CONF); - BaseConfigWidget::restoreDefaults(GlobalAttributes::SQL_HIGHLIGHT_CONF); + BaseConfigWidget::restoreDefaults(GlobalAttributes::GENERAL_CONF, false); + BaseConfigWidget::restoreDefaults(GlobalAttributes::XML_HIGHLIGHT_CONF, true); + BaseConfigWidget::restoreDefaults(GlobalAttributes::SQL_HIGHLIGHT_CONF, true); + BaseConfigWidget::restoreDefaults(GlobalAttributes::UI_STYLE_CONF, true); this->loadConfiguration(); this->applyConfiguration(); setConfigurationChanged(true); diff --git a/libpgmodeler_ui/src/relationshipconfigwidget.cpp b/libpgmodeler_ui/src/relationshipconfigwidget.cpp index 8703e73d1e..e869133b14 100644 --- a/libpgmodeler_ui/src/relationshipconfigwidget.cpp +++ b/libpgmodeler_ui/src/relationshipconfigwidget.cpp @@ -191,7 +191,7 @@ void RelationshipConfigWidget::restoreDefaults(void) { try { - BaseConfigWidget::restoreDefaults(GlobalAttributes::RELATIONSHIPS_CONF); + BaseConfigWidget::restoreDefaults(GlobalAttributes::RELATIONSHIPS_CONF, false); this->loadConfiguration(); setConfigurationChanged(true); } diff --git a/libpgmodeler_ui/src/snippetsconfigwidget.cpp b/libpgmodeler_ui/src/snippetsconfigwidget.cpp index c270999116..67d02a78f7 100644 --- a/libpgmodeler_ui/src/snippetsconfigwidget.cpp +++ b/libpgmodeler_ui/src/snippetsconfigwidget.cpp @@ -484,7 +484,7 @@ void SnippetsConfigWidget::restoreDefaults(void) { try { - BaseConfigWidget::restoreDefaults(GlobalAttributes::SNIPPETS_CONF); + BaseConfigWidget::restoreDefaults(GlobalAttributes::SNIPPETS_CONF, false); this->loadConfiguration(); setConfigurationChanged(true); } diff --git a/libpgmodeler_ui/ui/aboutwidget.ui b/libpgmodeler_ui/ui/aboutwidget.ui index 2fdb9dcc26..5df306c8fd 100644 --- a/libpgmodeler_ui/ui/aboutwidget.ui +++ b/libpgmodeler_ui/ui/aboutwidget.ui @@ -9,8 +9,8 @@ 0 0 - 575 - 550 + 550 + 530 @@ -21,14 +21,14 @@ - 575 - 550 + 550 + 530 16777215 - 600 + 550 @@ -68,7 +68,7 @@ QFrame::Raised - + 6 @@ -81,32 +81,7 @@ 6 - - 6 - - - - - - 0 - 0 - - - - - 75 - true - - - - PostgreSQL Database Modeler - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - + @@ -116,14 +91,14 @@ - 100 - 100 + 50 + 50 - 100 - 100 + 50 + 50 @@ -137,190 +112,32 @@ - - - - - 0 - 0 - - - - - 0 - 0 - - - - - false - - - - QFrame::NoFrame - - - Open source data modeling tool designed for PostgreSQL. No more DDL commands written by hand, let pgModeler do the job for you! This software reunites the concepts of entity-relationship diagrams and the features that PostgreSQL implements as extensions of SQL standards. - - - Qt::PlainText - - - Qt::AlignJustify|Qt::AlignTop - - - true - - - 0 - - - Qt::TextSelectableByMouse - - - - - - - - 0 - 0 - - - - - 230 - 0 - - - - - 16777215 - 16777215 - - - - - true - - - - Design, configure, deploy - - - - - - - - - - 0 - 0 - - - - <html><head/><body><p><a href="http://pgmodeler.com.br"><span style=" text-decoration: underline; color:#2980b9;">https://pgmodeler.io</span></a></p></body></html> - - - Qt::RichText - - - 5 - - - true - - - - - - - pgModeler is proudly a brazilian software! - - - - - - - - - :/imagens/imagens/brazil_flag.png - - - Qt::AlignHCenter|Qt::AlignTop - - - + + - - - - 0 - 0 - - - - <html><head/><body><p>Copyright 2006-2016 - Raphael Araújo e Silva &lt;<a href="mailto:raphael@pgmodeler.com.br"><span style=" text-decoration: underline; color:#0057ae;">raphael@pgmodeler.io</span></a>&gt;</p></body></html> + + + Qt::Horizontal - - Qt::AutoText - - - 5 - - - true + + + 40 + 20 + - + - - - - - - - 20 - 20 - - - - - 20 - 20 - - - - Hide this widget - - - ... - - - - :/icones/icones/fechar1.png:/icones/icones/fechar1.png - - - true - - - - - - - 6 - - + - + 0 0 - 60 + 0 0 @@ -337,19 +154,15 @@ true + + + - 0.0.0.0 + 0.0.0 - - - - - - 6 - - + @@ -368,20 +181,17 @@ Qt::LeftToRight - Build: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + build: -1 - + - + 0 0 @@ -436,482 +246,258 @@ -1 + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + PostgreSQL Database Modeler + + + Qt::AlignCenter + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + - - - - - 0 - 0 - - + + - 0 - 0 + 20 + 20 - - 0 + + + 20 + 20 + + + + Hide this widget + + + ... + + + + :/icones/icones/fechar1.png:/icones/icones/fechar1.png + + + true - - - License - - - - 4 - - - 4 - - - 4 - - - 4 - - - - - - Droid Sans Tamil - - - - QFrame::Sunken - - - QAbstractScrollArea::AdjustToContents - - - false - - - QTextEdit::WidgetWidth - - - true - - - <!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:'Droid Sans Tamil'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Courier';">pgModeler - PostgreSQL Database Modeler<br />Copyright 2006-2016 - Raphael Araújo e Silva<br /><br />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 version 3.<br /><br />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.<br /><br />The complete text of GPLv3 is at LICENSE file on pgModeler's source code root directory. Also, you can get the complete GNU General Public License at &lt;</span><a href="http://www.gnu.org/licenses"><span style=" font-family:'Courier'; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses</span></a><span style=" font-family:'Courier';">&gt;</span></p></body></html> - - - false - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - - Contributors - - - - 4 - - - 4 - - - 4 - - - 4 - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - false - - - - QFrame::NoFrame - - - <html><head/><body><p>This page is dedicated to all contributors who gave a bit of their time in make pgModeler a better software somehow. The complete list of people that helped pgModeler can be found at <a href="https://github.com/pgmodeler/pgmodeler/graphs/contributors"><span style=" text-decoration: underline; color:#00a489;">GitHub</span></a>.</p><p>If you have a great idea to improve pgModeler please submit it <a href="http://github.com/pgmodeler/pgmodeler/issues"><span style=" text-decoration: underline; color:#00a489;">here</span></a>. No ideas for now but want to help? Why not donate a few bucks <a href="http://pgmodeler.com.br/#donate"><span style=" text-decoration: underline; color:#00a489;">here</span></a>!?</p></body></html> - - - Qt::RichText - - - Qt::AlignJustify|Qt::AlignTop - - - true - - - 0 - - - true - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - - - - - 0 - 0 - - - - Qt::ScrollBarAsNeeded - - - Qt::ScrollBarAsNeeded - - - QAbstractItemView::NoEditTriggers - - - false - - - true - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectItems - - - QAbstractItemView::ScrollPerItem - - - true - - - false - - - true - - - true - - - false - - - true - - - false - - - false - - - false - - - - 1 - - - - - 2 - - - - - 3 - - - - - 4 - - - - - 5 - - - - - 6 - - - - - 7 - - - - - 8 - - - - - 9 - - - - - 10 - - - - - Name - - - - - Country - - - - - Contribution - - - - - Damien Degois - - - - - France - - - - :/icones/icones/flag_france.png:/icones/icones/flag_france.png - - - - - French UI translation and several improvements in auxiliary scripts. - - - - - Ji Bin - - - - - China - - - - :/icones/icones/flag_china.png:/icones/icones/flag_china.png - - - - - Chinese UI translation and small fixes. - - - - - Pierre-Samuel LE STANG - - - - - France - - - - :/icones/icones/flag_france.png:/icones/icones/flag_france.png - - - - - French UI translation. - - - - - Lisandro Damián Nicanor - - - - - Argentina - - - - :/icones/icones/flag_argentina.png:/icones/icones/flag_argentina.png - - - - - Improvements on build scripts enabling the custom packaging in Linux distros; Per-user settings; pgModeler's package maintainer in Debian Linux. - - - - - Pavel Alexeev - - - - - Russia - - - - :/icones/icones/flag_russia.png:/icones/icones/flag_russia.png - - - - - Additional work for packaging in Linux distros; pgModeler's package maintainer in Fedora Linux. - - - - - Mariusz Fik - - - - - Poland - - - - :/icones/icones/flag_poland.png:/icones/icones/flag_poland.png - - - - - Custom packaging first ideas. Tester of first version of custom packaging patch. - - - - - Jonathan DUPRE - - - - - France - - - - :/icones/icones/flag_france.png:/icones/icones/flag_france.png - - - - - French UI translation. - - - - - Gilberto Castillo - - - - - Cuba - - - - :/icones/icones/flag_cuba.png:/icones/icones/flag_cuba.png - - - - - Spanish UI translation. - - - - - -Danúbio Viana Nogueira - - - - - Brazil - - - - :/imagens/imagens/brazil_flag.png:/imagens/imagens/brazil_flag.png - - - - - Brazilian Portuguese UI translation. - - - - - Alfredo Marcillo - - - - - Ecuador - - - - :/icones/icones/flag_ecuador.png:/icones/icones/flag_ecuador.png - - - - - Spanish UI translation review. - - - - - - - + Qt::Vertical - QSizePolicy::Expanding + QSizePolicy::Fixed 20 - 10 + 20 + + + + + 0 + 0 + + + + + 0 + 0 + + + + + false + + + + QFrame::NoFrame + + + Open source data modeling tool designed for PostgreSQL. No more DDL commands written by hand, let pgModeler do the job for you! This software reunites the concepts of entity-relationship diagrams and the features that PostgreSQL implements as extensions of SQL standards. + + + Qt::PlainText + + + Qt::AlignJustify|Qt::AlignTop + + + true + + + 0 + + + Qt::TextSelectableByMouse + + + + + + + License + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + QFrame::Sunken + + + QAbstractScrollArea::AdjustToContents + + + false + + + QTextEdit::WidgetWidth + + + true + + + <!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:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Courier';">pgModeler - PostgreSQL Database Modeler<br />Copyright 2006-2018 - Raphael Araújo e Silva<br /><br />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 version 3.<br /><br />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.<br /><br />The complete text of GPLv3 is at LICENSE file on pgModeler's source code root directory. Also, you can get the complete GNU General Public License at &lt;</span><a href="http://www.gnu.org/licenses"><span style=" font-family:'Courier'; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses</span></a><span style=" font-family:'Courier';">&gt;</span></p></body></html> + + + false + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + + 0 + 0 + + + + <html><head/><body><p><a href="http://pgmodeler.com.br"><span style=" text-decoration: underline; color:#2980b9;">https://pgmodeler.io</span></a></p></body></html> + + + Qt::RichText + + + 5 + + + true + + + + + + + pgModeler is proudly a brazilian software! + + + + + + + + + :/imagens/imagens/brazil_flag.png + + + Qt::AlignHCenter|Qt::AlignTop + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Copyright 2006-2018 - Raphael Araújo e Silva &lt;<a href="mailto:raphael@pgmodeler.com.br"><span style=" text-decoration: underline; color:#0057ae;">raphael@pgmodeler.io</span></a>&gt;</p></body></html> + + + Qt::AutoText + + + 5 + + + true + + + + + diff --git a/libpgmodeler_ui/ui/donatewidget.ui b/libpgmodeler_ui/ui/donatewidget.ui index d150e9660d..82b6988a59 100644 --- a/libpgmodeler_ui/ui/donatewidget.ui +++ b/libpgmodeler_ui/ui/donatewidget.ui @@ -166,6 +166,12 @@ + + + 0 + 0 + + 0 @@ -203,7 +209,7 @@ - 40 + 118 20 From 10721157fefe0534330469a5c20386d724ac5619 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Fri, 11 May 2018 14:24:11 -0300 Subject: [PATCH 27/30] Fixed a bug when import identity columns in certain cases when the identity column was followed by another column which datatype was not accepted for identity, e.g, text after smallint (issue #1123) --- libpgmodeler_ui/src/databaseimporthelper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libpgmodeler_ui/src/databaseimporthelper.cpp b/libpgmodeler_ui/src/databaseimporthelper.cpp index a0533c8e63..3030f94852 100644 --- a/libpgmodeler_ui/src/databaseimporthelper.cpp +++ b/libpgmodeler_ui/src/databaseimporthelper.cpp @@ -1695,6 +1695,7 @@ void DatabaseImportHelper::createTable(attribs_map &attribs) type_def=getDependencyObject(itr->second[ParsersAttributes::TYPE_OID], OBJ_DOMAIN); } + col.setIdentityType(BaseType::null); col.setType(PgSQLType::parseString(type_name)); col.setNotNull(!itr->second[ParsersAttributes::NOT_NULL].isEmpty()); col.setComment(itr->second[ParsersAttributes::COMMENT]); From db432407c6e051823cc0c4f1f956061900c66808 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Fri, 11 May 2018 14:24:31 -0300 Subject: [PATCH 28/30] Minor typo fixes in dbmodel.sch --- schemas/sql/dbmodel.sch | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/schemas/sql/dbmodel.sch b/schemas/sql/dbmodel.sch index 722d21f128..4642eecdb9 100644 --- a/schemas/sql/dbmodel.sch +++ b/schemas/sql/dbmodel.sch @@ -25,14 +25,14 @@ $br $br %if {role} %then {role} %end %if {tablespace} %then - [-- Tablespaces creation must be done outside an multicommand file.] $br - [-- These commands were put in this file only for convenience.] $br + [-- Tablespaces creation must be done outside a multicommand file.] $br + [-- These commands were put in this file only as a convenience.] $br {tablespace} $br %end $br - [-- Database creation must be done outside an multicommand file.] $br - [-- These commands were put in this file only for convenience.] $br + [-- Database creation must be done outside a multicommand file.] $br + [-- These commands were put in this file only as a convenience.] $br {database} $br %end From 046925b6da35ec35e1d27cd1a14a0d41d1588cfa Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Fri, 11 May 2018 14:32:35 -0300 Subject: [PATCH 29/30] Additional updates for CHANGELOG.md and RELEASENOTES.md --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7474f1ebfb..005b7d7ba2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ v0.9.1 * [Change] Added an busy cursor while closing a model. * [Change] Improved the object selection in object finder. * [Change] Changed the behaviour of select and fade buttons in ObjectFinderWidget in such way to enable the user to select/fade the objects in the listing (or not included in the results). +* [Fix] Fixed a bug when import identity columns in certain cases when the identity column was followed by another column which data type was not accepted for identity, e.g, text after smallint. * [Fix] Fixed the check boxes disabling when dealing with identifier relationships. * [Fix] Disabled the drag & drop for items in the side listing at ConfigurationForm. * [Fix] Fixed the tab behavior on comment box in all editing forms of database objects. diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 4034cefe83..f77074d8b2 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -32,6 +32,7 @@ The whole set of changes of this release (considering the alpha and beta stages) * [Change] Improved the performance of the row duplication action in DataManipulationForm. * [Change] Improved the performance of "Move to schema" operation. * [Change] Changed the behaviour of select and fade buttons in ObjectFinderWidget in such way to enable the user to select/fade the objects in the listing (or not included in the results). +* [Fix] Fixed a bug when import identity columns in certain cases when the identity column was followed by another column which data type was not accepted for identity, e.g, text after smallint. * [Fix] Fixed the tab behavior on comment box in all editing forms of database objects. * [Fix] Fixed the catalog query for user defined types. * [Fix] Fixed the import of user defined types which names contains uppercase characters. From 07015d4cb236a0dc75fbb9fc8238a645488fac7a Mon Sep 17 00:00:00 2001 From: Eric Lemesre Date: Thu, 26 Jul 2018 18:49:03 +0200 Subject: [PATCH 30/30] Fix spelling-error --- lang/es_ES.qm | Bin 310128 -> 310133 bytes lang/es_ES.ts | 26 +++++++++---------- lang/fr_FR.qm | Bin 224921 -> 224927 bytes lang/fr_FR.ts | 16 ++++++------ lang/nl_NL.qm | Bin 329146 -> 329151 bytes lang/nl_NL.ts | 16 ++++++------ lang/pt_BR.qm | Bin 111678 -> 111681 bytes lang/pt_BR.ts | 20 +++++++------- lang/zh_CN.qm | Bin 74005 -> 74008 bytes lang/zh_CN.ts | 16 ++++++------ libpgmodeler/src/databasemodel.cpp | 2 +- libpgmodeler_ui/src/databaseimportform.cpp | 2 +- libpgmodeler_ui/src/datamanipulationform.cpp | 2 +- libpgmodeler_ui/src/modelexportform.cpp | 2 +- libpgmodeler_ui/src/modelobjectswidget.cpp | 2 +- libpgmodeler_ui/src/modelwidget.cpp | 2 +- libpgmodeler_ui/src/sourcecodewidget.cpp | 2 +- libpgmodeler_ui/ui/aggregatewidget.ui | 2 +- libpgmodeler_ui/ui/generalconfigwidget.ui | 6 ++--- libpgmodeler_ui/ui/mainwindow.ui | 2 +- libpgmodeler_ui/ui/modeldatabasediffform.ui | 2 +- libpgmodeler_ui/ui/modelexportform.ui | 2 +- libpgmodeler_ui/ui/tabledatawidget.ui | 2 +- libutils/src/exception.cpp | 2 +- 24 files changed, 63 insertions(+), 63 deletions(-) diff --git a/lang/es_ES.qm b/lang/es_ES.qm index 15fab2a28b2263b7d19ad807dae8451b42d3abf3..1ba8d107282fa4b5ac428d199930b2da3151bc08 100644 GIT binary patch delta 17614 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 delta 17553 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 - Funtion Inputs + Function Inputs Entradas de Funciones @@ -2301,7 +2301,7 @@ Desmarcando esto hará que el SQL que se adjunta al final del mandato CREATE DAT - <strong>WARNING:</strong> Once commited its not possible to undo the changes! Proceed with saving? + <strong>WARNING:</strong> Once committed its not possible to undo the changes! Proceed with saving? <strong>WARNING:</strong> Una vez que su cometido no es posible deshacer los cambios! Procedo con salvar? @@ -3678,7 +3678,7 @@ Ref. column(s): %2 - Importing process sucessfuly ended! + Importing process successfully ended! Proceso de Importación terminado satisfactoriamente! @@ -5208,7 +5208,7 @@ Mensage retornada por el SGBD: `%1' - Assignement of an invalid object name pattern to the relationship `%1'! + Assignment of an invalid object name pattern to the relationship `%1'! Asignacion de un patrón de nombre de objeto no válido a la relación `%1'! @@ -5766,7 +5766,7 @@ Mensage retornada por el SGBD: `%1' - Souce code editor: + Source code editor: @@ -5776,7 +5776,7 @@ Mensage retornada por el SGBD: `%1' - Clear the entire SQL comand history. + Clear the entire SQL command history. @@ -5806,7 +5806,7 @@ Mensage retornada por el SGBD: `%1' - Souce code editor args: + Source code editor args: @@ -6271,7 +6271,7 @@ Mensage retornada por el SGBD: `%1' - Toogle the model validation widgets + Toggle the model validation widgets Cambiar el modelo de validación del widgets @@ -7586,7 +7586,7 @@ Mensage retornada por el SGBD: `%1' - This advanced option causes pgModeler to ignore extra errors by their numeric codes. These errors must be informed in the input below and separeted by space. For the complete list of error codes check the PostgreSQL docs, section <strong> Appendix A. PostgreSQL Error Codes</strong>. <strong>WARNING:</strong> use this option with extreme care since it can interfere in final export result. + This advanced option causes pgModeler to ignore extra errors by their numeric codes. These errors must be informed in the input below and separated by space. For the complete list of error codes check the PostgreSQL docs, section <strong> Appendix A. PostgreSQL Error Codes</strong>. <strong>WARNING:</strong> use this option with extreme care since it can interfere in final export result. @@ -7822,7 +7822,7 @@ Mensage retornada por el SGBD: `%1' - This advanced option causes pgModeler to ignore extra errors by their numeric codes. These errors must be informed in the input below and separeted by space. For the complete list of error codes check the PostgreSQL docs, section <strong> Appendix A. PostgreSQL Error Codes</strong>. <strong>WARNING:</strong> use this option with extreme care since it can interfere in final export result. + This advanced option causes pgModeler to ignore extra errors by their numeric codes. These errors must be informed in the input below and separated by space. For the complete list of error codes check the PostgreSQL docs, section <strong> Appendix A. PostgreSQL Error Codes</strong>. <strong>WARNING:</strong> use this option with extreme care since it can interfere in final export result. @@ -8001,7 +8001,7 @@ Mensage retornada por el SGBD: `%1' - Exporting process sucessfuly ended! + Exporting process successfully ended! Proceso de exportación terminó satisfactoriamente! @@ -12451,7 +12451,7 @@ modos se describen a continuación. -- NOTE: the code below contains the SQL for the selected object -- as well for its dependencies and children (if applicable). -- --- This feature is only a convinience in order to permit you to test +-- This feature is only a convenience in order to permit you to test -- the whole object's SQL definition at once. -- -- When exporting or generating the SQL for the whole database model @@ -12610,7 +12610,7 @@ modos se describen a continuación. - Some invalid or duplicated columns were detected. In order to solve this issue double-click the header of the highlighted ones in order to define the correct name in which the data belongs to or delete the entire column. Note that these columns are completely igored when generating the <strong>INSERT</strong> commands. + Some invalid or duplicated columns were detected. In order to solve this issue double-click the header of the highlighted ones in order to define the correct name in which the data belongs to or delete the entire column. Note that these columns are completely ignored when generating the <strong>INSERT</strong> commands. diff --git a/lang/fr_FR.qm b/lang/fr_FR.qm index 7b1f0ecfd4496306b88ed58dc09713d7396eb7e5..eb60e10b670c9c07d75d37a7a8887e6fc370352d 100644 GIT binary patch delta 13635 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 s8*Condition initiale: - Funtion Inputs + Function Inputs Entrées de la fonction @@ -1834,7 +1834,7 @@ Sinon (décoché) pgModeler ajoutera ce code après la commande SQL CREATE DATAB [données binaires] - <strong>WARNING:</strong> Once commited its not possible to undo the changes! Proceed with saving? + <strong>WARNING:</strong> Once committed its not possible to undo the changes! Proceed with saving? <strong>ATTENTION:</strong> Une fois validés (Commit), il ne sera plus possible d'annuler les changements ! Sauvegarder les changements ? @@ -2896,7 +2896,7 @@ Ref. column(s): %2 Processus d'importation interrompu par l'utilisateur ! - Importing process sucessfuly ended! + Importing process successfully ended! Processus d'importation terminé avec succès ! @@ -4106,7 +4106,7 @@ Message returned by the DBMS: `%1' - Assignement of an invalid object name pattern to the relationship `%1'! + Assignment of an invalid object name pattern to the relationship `%1'! @@ -5450,7 +5450,7 @@ Voulez-vous vraiment le FERMER SANS le SAUVEGARDER? - Toogle the model validation widgets + Toggle the model validation widgets @@ -6425,7 +6425,7 @@ Voulez-vous vraiment le FERMER SANS le SAUVEGARDER? Processus d'exportation annulé par l'utilisateur! - Exporting process sucessfuly ended! + Exporting process successfully ended! Processus d'exportation terminé avec succès! @@ -9986,7 +9986,7 @@ accepted structure. All available options are described below. -- NOTE: the code below contains the SQL for the selected object -- as well for its dependencies and children (if applicable). -- --- This feature is only a convinience in order to permit you to test +-- This feature is only a convenience in order to permit you to test -- the whole object's SQL definition at once. -- -- When exporting or generating the SQL for the whole database model @@ -10076,7 +10076,7 @@ accepted structure. All available options are described below. Ins - Some invalid or duplicated columns were detected. In order to solve this issue double-click the header of the highlighted ones in order to define the correct name in which the data belongs to or delete the entire column. Note that these columns are completely igored when generating the <strong>INSERT</strong> commands. + Some invalid or duplicated columns were detected. In order to solve this issue double-click the header of the highlighted ones in order to define the correct name in which the data belongs to or delete the entire column. Note that these columns are completely ignored when generating the <strong>INSERT</strong> commands. diff --git a/lang/nl_NL.qm b/lang/nl_NL.qm index 5a3df20d0b94a409b732d14df809b6fe64e342eb..eedb44c49b0d6db3ee4891b49a9d7526211b5b9a 100644 GIT binary patch delta 17876 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 delta 17836 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 - Funtion Inputs + Function Inputs Functie Invoer @@ -2262,7 +2262,7 @@ Deze optie afvinken zorgt ervoor dat de SQL wordt ingevoegd na het CREATE DATABA - <strong>WARNING:</strong> Once commited its not possible to undo the changes! Proceed with saving? + <strong>WARNING:</strong> Once committed its not possible to undo the changes! Proceed with saving? <strong>OPGEPAST: </strong> Eens toegepast is het niet langer mogelijk om aanpassingen ongedaan te maken! Bent u zeker dat u wilt opslaan? @@ -3532,7 +3532,7 @@ Ref. column(s): %2 - Importing process sucessfuly ended! + Importing process successfully ended! Het import proces werd succesvol beëindigt! @@ -5024,7 +5024,7 @@ Het bericht dat terugkwam van de DBMS is: `%1' - Assignement of an invalid object name pattern to the relationship `%1'! + Assignment of an invalid object name pattern to the relationship `%1'! Toewijzijng van een ongeldig objectnaamspatroon aan de relatie `%1'! @@ -6092,7 +6092,7 @@ Het bericht dat terugkwam van de DBMS is: `%1' - Toogle the model validation widgets + Toggle the model validation widgets Toon of verberg het modelvalidatie-widget @@ -7925,7 +7925,7 @@ Het bericht dat terugkwam van de DBMS is: `%1' - Exporting process sucessfuly ended! + Exporting process successfully ended! Het export proces werd succesvol beëindigt! @@ -12347,7 +12347,7 @@ laatste geaccepteerde structuur. Alle beschikbare opties worden hieronder beschr -- NOTE: the code below contains the SQL for the selected object -- as well for its dependencies and children (if applicable). -- --- This feature is only a convinience in order to permit you to test +-- This feature is only a convenience in order to permit you to test -- the whole object's SQL definition at once. -- -- When exporting or generating the SQL for the whole database model @@ -12472,7 +12472,7 @@ laatste geaccepteerde structuur. Alle beschikbare opties worden hieronder beschr - Some invalid or duplicated columns were detected. In order to solve this issue double-click the header of the highlighted ones in order to define the correct name in which the data belongs to or delete the entire column. Note that these columns are completely igored when generating the <strong>INSERT</strong> commands. + Some invalid or duplicated columns were detected. In order to solve this issue double-click the header of the highlighted ones in order to define the correct name in which the data belongs to or delete the entire column. Note that these columns are completely ignored when generating the <strong>INSERT</strong> commands. diff --git a/lang/pt_BR.qm b/lang/pt_BR.qm index 9060df3e01d45506eda6f864b5b0c80e2d546e09..23863665a5f62157f3be17ede12ba1d833b23d5b 100644 GIT binary patch delta 8311 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 CtF(^* delta 8322 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 NiCO>toy?l&{U4{DwzdEO diff --git a/lang/pt_BR.ts b/lang/pt_BR.ts index caf91dac77..8ed286f7a6 100644 --- a/lang/pt_BR.ts +++ b/lang/pt_BR.ts @@ -275,7 +275,7 @@ O projeto pgModeler trata de uma ferramenta CASE para a criação de modelos de Condição Inicial: - Funtion Inputs + Function Inputs Entradas da Função @@ -2640,7 +2640,7 @@ Unchecking this will cause the SQL to be appended at the end of CREATE DATABASE - <strong>WARNING:</strong> Once commited its not possible to undo the changes! Proceed with saving? + <strong>WARNING:</strong> Once committed its not possible to undo the changes! Proceed with saving? @@ -3628,7 +3628,7 @@ Ref. column(s): %2 - Importing process sucessfuly ended! + Importing process successfully ended! @@ -5853,7 +5853,7 @@ Message returned by the DBMS: `%1' - Assignement of an invalid object name pattern to the relationship `%1'! + Assignment of an invalid object name pattern to the relationship `%1'! @@ -6238,7 +6238,7 @@ Message returned by the DBMS: `%1' Criando objetos No banco de dados '%1'... - Exporting process sucessfuly ended! + Exporting process successfully ended! Exportação finalizada com sucesso! @@ -6553,7 +6553,7 @@ Agradecimentos especiais aos amigos da equipe de desenvolvimento de software da Condição Inicial: - Funtion Inputs + Function Inputs Entradas da Função @@ -7971,7 +7971,7 @@ Agradecimentos especiais aos amigos da equipe de desenvolvimento de software da - Toogle the model validation widgets + Toggle the model validation widgets @@ -9124,7 +9124,7 @@ Agradecimentos especiais aos amigos da equipe de desenvolvimento de software da Criando objetos No banco de dados '%1'... - Exporting process sucessfuly ended! + Exporting process successfully ended! Processo de exportação finalizado com sucesso! @@ -13704,7 +13704,7 @@ disponíveis estão descritos abaixo. -- NOTE: the code below contains the SQL for the selected object -- as well for its dependencies and children (if applicable). -- --- This feature is only a convinience in order to permit you to test +-- This feature is only a convenience in order to permit you to test -- the whole object's SQL definition at once. -- -- When exporting or generating the SQL for the whole database model @@ -13916,7 +13916,7 @@ disponíveis estão descritos abaixo. - Some invalid or duplicated columns were detected. In order to solve this issue double-click the header of the highlighted ones in order to define the correct name in which the data belongs to or delete the entire column. Note that these columns are completely igored when generating the <strong>INSERT</strong> commands. + Some invalid or duplicated columns were detected. In order to solve this issue double-click the header of the highlighted ones in order to define the correct name in which the data belongs to or delete the entire column. Note that these columns are completely ignored when generating the <strong>INSERT</strong> commands. diff --git a/lang/zh_CN.qm b/lang/zh_CN.qm index 45596b5ae3c8382b0854de8c6ebeaf8443167880..a665ef83cd7c68510b7ce746e4e33b528f92640c 100644 GIT binary patch delta 7579 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 delta 7555 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 diff --git a/lang/zh_CN.ts b/lang/zh_CN.ts index deba0c9869..0925a59292 100644 --- a/lang/zh_CN.ts +++ b/lang/zh_CN.ts @@ -270,7 +270,7 @@ GPLv3 的完整内容放在源代码根目录的 LICENSE 文件中。完整的 G 最终条件: - Funtion Inputs + Function Inputs 函数输入 @@ -1953,7 +1953,7 @@ Unchecking this will cause the SQL to be appended at the end of CREATE DATABASE - <strong>WARNING:</strong> Once commited its not possible to undo the changes! Proceed with saving? + <strong>WARNING:</strong> Once committed its not possible to undo the changes! Proceed with saving? @@ -2941,7 +2941,7 @@ Ref. column(s): %2 - Importing process sucessfuly ended! + Importing process successfully ended! @@ -4543,7 +4543,7 @@ Message returned by the DBMS: `%1' - Assignement of an invalid object name pattern to the relationship `%1'! + Assignment of an invalid object name pattern to the relationship `%1'! @@ -5817,7 +5817,7 @@ Message returned by the DBMS: `%1' - Toogle the model validation widgets + Toggle the model validation widgets @@ -6950,7 +6950,7 @@ Message returned by the DBMS: `%1' 正在对数据库 '%1' 创建对象... - Exporting process sucessfuly ended! + Exporting process successfully ended! 成功导出! @@ -10764,7 +10764,7 @@ p, li { white-space: pre-wrap; } -- NOTE: the code below contains the SQL for the selected object -- as well for its dependencies and children (if applicable). -- --- This feature is only a convinience in order to permit you to test +-- This feature is only a convenience in order to permit you to test -- the whole object's SQL definition at once. -- -- When exporting or generating the SQL for the whole database model @@ -10846,7 +10846,7 @@ p, li { white-space: pre-wrap; } Ins - Some invalid or duplicated columns were detected. In order to solve this issue double-click the header of the highlighted ones in order to define the correct name in which the data belongs to or delete the entire column. Note that these columns are completely igored when generating the <strong>INSERT</strong> commands. + Some invalid or duplicated columns were detected. In order to solve this issue double-click the header of the highlighted ones in order to define the correct name in which the data belongs to or delete the entire column. Note that these columns are completely ignored when generating the <strong>INSERT</strong> commands. diff --git a/libpgmodeler/src/databasemodel.cpp b/libpgmodeler/src/databasemodel.cpp index 898d38e564..1e9b59e006 100644 --- a/libpgmodeler/src/databasemodel.cpp +++ b/libpgmodeler/src/databasemodel.cpp @@ -6802,7 +6802,7 @@ map DatabaseModel::getCreationOrder(unsigned def_type, b { for(auto &object : (*obj_list)) { - /* If the object is a FK relationship it's stored in a separeted list in order to have the + /* If the object is a FK relationship it's stored in a separated list in order to have the code generated at end of whole definition (after foreign keys definition) */ if(object->getObjectType()==BASE_RELATIONSHIP && dynamic_cast(object)->getRelationshipType()==BaseRelationship::RELATIONSHIP_FK) diff --git a/libpgmodeler_ui/src/databaseimportform.cpp b/libpgmodeler_ui/src/databaseimportform.cpp index a52611c7b0..aa30540b1b 100644 --- a/libpgmodeler_ui/src/databaseimportform.cpp +++ b/libpgmodeler_ui/src/databaseimportform.cpp @@ -529,7 +529,7 @@ void DatabaseImportForm::handleImportFinished(Exception e) model_wgt->getDatabaseModel()->setInvalidated(false); - finishImport(trUtf8("Importing process sucessfuly ended!")); + finishImport(trUtf8("Importing process successfully ended!")); ico_lbl->setPixmap(QPixmap(PgModelerUiNS::getIconPath("msgbox_info"))); import_helper->closeConnection(); diff --git a/libpgmodeler_ui/src/datamanipulationform.cpp b/libpgmodeler_ui/src/datamanipulationform.cpp index 0e7394af5e..eee33987ce 100644 --- a/libpgmodeler_ui/src/datamanipulationform.cpp +++ b/libpgmodeler_ui/src/datamanipulationform.cpp @@ -1230,7 +1230,7 @@ void DataManipulationForm::saveChanges(void) QString cmd; Messagebox msg_box; - msg_box.show(trUtf8("WARNING: Once commited its not possible to undo the changes! Proceed with saving?"), + msg_box.show(trUtf8("WARNING: Once committed its not possible to undo the changes! Proceed with saving?"), Messagebox::ALERT_ICON, Messagebox::YES_NO_BUTTONS); diff --git a/libpgmodeler_ui/src/modelexportform.cpp b/libpgmodeler_ui/src/modelexportform.cpp index 1442cc6b0f..d0cd81941b 100644 --- a/libpgmodeler_ui/src/modelexportform.cpp +++ b/libpgmodeler_ui/src/modelexportform.cpp @@ -324,7 +324,7 @@ void ModelExportForm::handleExportCanceled(void) void ModelExportForm::handleExportFinished(void) { QPixmap ico=QPixmap(PgModelerUiNS::getIconPath("msgbox_info")); - QString msg=trUtf8("Exporting process sucessfuly ended!"); + QString msg=trUtf8("Exporting process successfully ended!"); finishExport(msg); ico_lbl->setPixmap(ico); diff --git a/libpgmodeler_ui/src/modelobjectswidget.cpp b/libpgmodeler_ui/src/modelobjectswidget.cpp index b7aa3839f4..92cd2473d9 100644 --- a/libpgmodeler_ui/src/modelobjectswidget.cpp +++ b/libpgmodeler_ui/src/modelobjectswidget.cpp @@ -469,7 +469,7 @@ void ModelObjectsWidget::updateSchemaTree(QTreeWidgetItem *root) int count, count2, i; QPixmap group_icon=QPixmap(PgModelerUiNS::getIconPath(QString(BaseObject::getSchemaName(OBJ_SCHEMA)) + QString("_grp"))); - //Removing the OBJ_TABLE and OBJ_VIEW types since they are handled separetedly + //Removing the OBJ_TABLE and OBJ_VIEW types since they are handled separatedly types.erase(std::find(types.begin(), types.end(), OBJ_TABLE)); types.erase(std::find(types.begin(), types.end(), OBJ_VIEW)); diff --git a/libpgmodeler_ui/src/modelwidget.cpp b/libpgmodeler_ui/src/modelwidget.cpp index 128f436c64..3fb4f64bd0 100644 --- a/libpgmodeler_ui/src/modelwidget.cpp +++ b/libpgmodeler_ui/src/modelwidget.cpp @@ -2234,7 +2234,7 @@ void ModelWidget::copyObjects(bool duplicate_mode) Messagebox::CONFIRM_ICON, Messagebox::YES_NO_BUTTONS); } - /* When in cut operation is necessary to store the selected objects in a separeted list + /* When in cut operation is necessary to store the selected objects in a separated list in order to correclty cut (remove) the object on the source model */ if(ModelWidget::cut_operation) cutted_objects=selected_objects; diff --git a/libpgmodeler_ui/src/sourcecodewidget.cpp b/libpgmodeler_ui/src/sourcecodewidget.cpp index 02c9d73241..75f274d982 100644 --- a/libpgmodeler_ui/src/sourcecodewidget.cpp +++ b/libpgmodeler_ui/src/sourcecodewidget.cpp @@ -162,7 +162,7 @@ void SourceCodeWidget::generateSourceCode(int) aux_def=trUtf8("-- NOTE: the code below contains the SQL for the selected object\n\ -- as well for its dependencies and children (if applicable).\n\ -- \n\ --- This feature is only a convinience in order to permit you to test\n\ +-- This feature is only a convenience in order to permit you to test\n\ -- the whole object's SQL definition at once.\n\ -- \n\ -- When exporting or generating the SQL for the whole database model\n\ diff --git a/libpgmodeler_ui/ui/aggregatewidget.ui b/libpgmodeler_ui/ui/aggregatewidget.ui index 059fdfffab..4dc6342ab1 100644 --- a/libpgmodeler_ui/ui/aggregatewidget.ui +++ b/libpgmodeler_ui/ui/aggregatewidget.ui @@ -72,7 +72,7 @@ - Funtion Inputs + Function Inputs diff --git a/libpgmodeler_ui/ui/generalconfigwidget.ui b/libpgmodeler_ui/ui/generalconfigwidget.ui index 19c46a92cd..f4534a0e24 100644 --- a/libpgmodeler_ui/ui/generalconfigwidget.ui +++ b/libpgmodeler_ui/ui/generalconfigwidget.ui @@ -1014,7 +1014,7 @@ - Souce code editor args: + Source code editor args: @@ -1113,7 +1113,7 @@ Qt::StrongFocus - Clear the entire SQL comand history. + Clear the entire SQL command history. Clear history @@ -1322,7 +1322,7 @@ - Souce code editor: + Source code editor: diff --git a/libpgmodeler_ui/ui/mainwindow.ui b/libpgmodeler_ui/ui/mainwindow.ui index fa5ee1db02..1fb9a7503c 100644 --- a/libpgmodeler_ui/ui/mainwindow.ui +++ b/libpgmodeler_ui/ui/mainwindow.ui @@ -479,7 +479,7 @@ - Toogle the model validation widgets + Toggle the model validation widgets &Validation diff --git a/libpgmodeler_ui/ui/modeldatabasediffform.ui b/libpgmodeler_ui/ui/modeldatabasediffform.ui index 4fccfe761c..9d3a3279d1 100644 --- a/libpgmodeler_ui/ui/modeldatabasediffform.ui +++ b/libpgmodeler_ui/ui/modeldatabasediffform.ui @@ -1568,7 +1568,7 @@ - This advanced option causes pgModeler to ignore extra errors by their numeric codes. These errors must be informed in the input below and separeted by space. For the complete list of error codes check the PostgreSQL docs, section <strong> Appendix A. PostgreSQL Error Codes</strong>. <strong>WARNING:</strong> use this option with extreme care since it can interfere in final export result. + This advanced option causes pgModeler to ignore extra errors by their numeric codes. These errors must be informed in the input below and separated by space. For the complete list of error codes check the PostgreSQL docs, section <strong> Appendix A. PostgreSQL Error Codes</strong>. <strong>WARNING:</strong> use this option with extreme care since it can interfere in final export result. Ignore error codes diff --git a/libpgmodeler_ui/ui/modelexportform.ui b/libpgmodeler_ui/ui/modelexportform.ui index e0003788ae..06f3750783 100644 --- a/libpgmodeler_ui/ui/modelexportform.ui +++ b/libpgmodeler_ui/ui/modelexportform.ui @@ -511,7 +511,7 @@ - This advanced option causes pgModeler to ignore extra errors by their numeric codes. These errors must be informed in the input below and separeted by space. For the complete list of error codes check the PostgreSQL docs, section <strong> Appendix A. PostgreSQL Error Codes</strong>. <strong>WARNING:</strong> use this option with extreme care since it can interfere in final export result. + This advanced option causes pgModeler to ignore extra errors by their numeric codes. These errors must be informed in the input below and separated by space. For the complete list of error codes check the PostgreSQL docs, section <strong> Appendix A. PostgreSQL Error Codes</strong>. <strong>WARNING:</strong> use this option with extreme care since it can interfere in final export result. Ignore error codes diff --git a/libpgmodeler_ui/ui/tabledatawidget.ui b/libpgmodeler_ui/ui/tabledatawidget.ui index 8760d88775..afed1dd957 100644 --- a/libpgmodeler_ui/ui/tabledatawidget.ui +++ b/libpgmodeler_ui/ui/tabledatawidget.ui @@ -601,7 +601,7 @@ - Some invalid or duplicated columns were detected. In order to solve this issue double-click the header of the highlighted ones in order to define the correct name in which the data belongs to or delete the entire column. Note that these columns are completely igored when generating the <strong>INSERT</strong> commands. + Some invalid or duplicated columns were detected. In order to solve this issue double-click the header of the highlighted ones in order to define the correct name in which the data belongs to or delete the entire column. Note that these columns are completely ignored when generating the <strong>INSERT</strong> commands. true diff --git a/libutils/src/exception.cpp b/libutils/src/exception.cpp index 7e731343ed..986f6913f2 100644 --- a/libutils/src/exception.cpp +++ b/libutils/src/exception.cpp @@ -219,7 +219,7 @@ QString Exception::messages[ERROR_COUNT][2]={ {"ERR_VALIDATION_FAILURE", QT_TR_NOOP("The validation process failed due to an error triggered by the validation helper. For more details about the error check the exception stack!")}, {"ERR_REG_EXT_NOT_HANDLING_TYPE", QT_TR_NOOP("The extension `%1' is registered as a data type and cannot have the attribute `handles datatype' modified!")}, {"ERR_ALOC_INV_FK_RELATIONSHIP", QT_TR_NOOP("The fk relationship `%1' cannot be created because the foreign-key that represents it was not created on table `%2'!")}, - {"ERR_ASG_INV_NAME_PATTERN", QT_TR_NOOP("Assignement of an invalid object name pattern to the relationship `%1'!")}, + {"ERR_ASG_INV_NAME_PATTERN", QT_TR_NOOP("Assignment of an invalid object name pattern to the relationship `%1'!")}, {"ERR_REF_INV_NAME_PATTERN_ID", QT_TR_NOOP("Reference to an invalid object name pattern id on the relationship `%1'!")}, {"ERR_INV_USE_VARIADIC_PARAM_MODE", QT_TR_NOOP("Invalid use of variadic parameter mode! This mode can be used only with an array or \"any\" data type!")}, {"ERR_MIX_INCOMP_EXPORT_OPTS", QT_TR_NOOP("Mixing incompatibles DBMS export modes: `ignore object duplications', `drop database' or `drop objects' cannot be used with `simulate export'!")},