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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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 77df97b917a2a651de0cb146fbc3e9460e9be164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphael=20Ara=C3=BAjo=20e=20Silva?= Date: Mon, 14 May 2018 17:44:13 -0300 Subject: [PATCH 30/36] Update issue templates --- .github/ISSUE_TEMPLATE/Bug_report.md | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/Bug_report.md diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md new file mode 100644 index 0000000000..4de26c77d9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -0,0 +1,35 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. From 888fdb3dd408661b9350723f04b64dcf52235ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphael=20Ara=C3=BAjo=20e=20Silva?= Date: Mon, 14 May 2018 17:52:15 -0300 Subject: [PATCH 31/36] Update issue templates --- .github/ISSUE_TEMPLATE/Bug_report.md | 43 ++++++++++++++-------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md index 4de26c77d9..212fe179f8 100644 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -1,35 +1,34 @@ --- name: Bug report -about: Create a report to help us improve +about: Instructions on how to report pgModeler bugs --- -**Describe the bug** -A clear and concise description of what the bug is. +**Bug description** +_A clear and concise description of what the bug is._ -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error +**How to reproduce** +_Please, if the bug can be reproduceable describe the steps in full details_ **Expected behavior** -A clear and concise description of what you expected to happen. +_A clear and concise description of what you expected to happen._ **Screenshots** -If applicable, add screenshots to help explain your problem. +_If applicable, add screenshots to help explain your problem._ -**Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] +**Info about your desktop** + - OS: + - Version: + - Window manager: + - pgModeler version: + - Qt version: -**Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] +**Stacktrace** +_If pgModeler crashed after the bug raised attach the stacktrace below_ -**Additional context** -Add any other context about the problem here. +``` + Put the stacktrace here! +``` + +**Additional info** +_Add any other information that you may find useful to help in the problem solving._ From 77940269358b9791e1dd27a7b8ece3eaaad018fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphael=20Ara=C3=BAjo=20e=20Silva?= Date: Mon, 14 May 2018 17:54:49 -0300 Subject: [PATCH 32/36] Update issue templates --- .github/ISSUE_TEMPLATE/Bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md index 212fe179f8..1ec4465fc7 100644 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -8,7 +8,7 @@ about: Instructions on how to report pgModeler bugs _A clear and concise description of what the bug is._ **How to reproduce** -_Please, if the bug can be reproduceable describe the steps in full details_ +_Please, if the bug can be reproduceable describe the steps in full details. If possible provide a sample model and/or a SQL dump for test purposes._ **Expected behavior** _A clear and concise description of what you expected to happen._ From 288b8642c3dd3580ddae7b2606fdf4c3c29a8af1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphael=20Ara=C3=BAjo=20e=20Silva?= Date: Mon, 14 May 2018 17:58:42 -0300 Subject: [PATCH 33/36] Update issue templates --- .github/ISSUE_TEMPLATE/Bug_report.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md index 1ec4465fc7..682c7ce7d2 100644 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -1,6 +1,8 @@ --- -name: Bug report -about: Instructions on how to report pgModeler bugs +name: Report a bug +about: Instructions on how to report pgModeler bugs. Before report any bug please + check if someone already has submited issues similiar to yours. Duplicated issues + will be ignored. --- From f466930cc1d1b94af3e352c883a8416b8c56c214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphael=20Ara=C3=BAjo=20e=20Silva?= Date: Tue, 15 May 2018 09:48:52 -0300 Subject: [PATCH 34/36] Update issue templates --- .github/ISSUE_TEMPLATE/Bug_report.md | 4 +++- .github/ISSUE_TEMPLATE/Custom.md | 8 ++++++++ .github/ISSUE_TEMPLATE/Feature_request.md | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 .github/ISSUE_TEMPLATE/Custom.md create mode 100644 .github/ISSUE_TEMPLATE/Feature_request.md diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md index 682c7ce7d2..4d054a0f2e 100644 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -25,11 +25,13 @@ _If applicable, add screenshots to help explain your problem._ - pgModeler version: - Qt version: -**Stacktrace** +**Stacktrace / Debug info** _If pgModeler crashed after the bug raised attach the stacktrace below_ ``` + Put the stacktrace here! + ``` **Additional info** diff --git a/.github/ISSUE_TEMPLATE/Custom.md b/.github/ISSUE_TEMPLATE/Custom.md new file mode 100644 index 0000000000..219c04f5c1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Custom.md @@ -0,0 +1,8 @@ +--- +name: General discussion +about: For any discussion not related to bugs or feature requests please use this + one. + +--- + + diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md new file mode 100644 index 0000000000..f3ad5eb15b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Feature_request.md @@ -0,0 +1,14 @@ +--- +name: Feature request / improvement +about: Give your suggestions for improvements to this project. + +--- + +**Feature description** +_A clear and concise description of what the problem is._ + +**Sample image** +_If the feature requested is a visual improvement, please, attach some images to make it clear._ + +**Additional info** +_Add any other context or screenshots about the feature request here._ From 436585153f372bdcdd01fbbf33faee5af0c5d424 Mon Sep 17 00:00:00 2001 From: "Raphael A. Silva" Date: Thu, 17 May 2018 11:09:26 -0300 Subject: [PATCH 35/36] Minor fix schema file sql/table.sch --- schemas/sql/table.sch | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/schemas/sql/table.sch b/schemas/sql/table.sch index dcbdfd89c4..fe953bf77f 100644 --- a/schemas/sql/table.sch +++ b/schemas/sql/table.sch @@ -33,12 +33,15 @@ %if %not {constr-sql-disabled} %and {constraints} %then [,] $br %end %end + + %if {inh-columns} %then + $br {inh-columns} + %end - %if {inh-columns} %then {inh-columns} %end - - %if {constraints} %then + %if {constraints} %then {constraints} %end + %end $br ) From 954a869952da4bfa1d2f822c5a36c518cb3b3312 Mon Sep 17 00:00:00 2001 From: Ronny Kramer Date: Thu, 31 May 2018 10:44:24 +0200 Subject: [PATCH 36/36] FIXED: Allow people to select another PREFIX path -> the actual issue is that towards the end of the install script where $INSTALL_ROOT is used instead of $PREFIX -> simplest fix was to set $INSTALL_ROOT to $PREFIX -> reordering some allows to use the DEPLOY_VER in the PREFIX --- linuxdeploy.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/linuxdeploy.sh b/linuxdeploy.sh index 045c9c975c..be88cd8b5e 100755 --- a/linuxdeploy.sh +++ b/linuxdeploy.sh @@ -23,20 +23,25 @@ QMAKE_CMD=qmake LOG="$PWD/linuxdeploy.log" QT_IFW_ROOT=/opt/qt-ifw-1.5.0 + +# Prepare setup variables STARTUP_SCRIPT="start-pgmodeler.sh" MIME_UPDATE_SCRIPT="dbm-mime-type.sh" ENV_VARS_SCRIPT="pgmodeler.vars" BUILD_DIR="$PWD/build" DIST_DIR="$PWD/dist" -INSTALL_ROOT="/opt/pgmodeler" +# Detecting current pgModeler version +DEPLOY_VER=`cat libutils/src/globalattributes.cpp | grep PGMODELER_VERSION | sed 's/PGMODELER_VERSION=QString("//g' | sed 's/"),//g' | sed 's/^ *//g' | cut -s -f2` +PREFIX="/opt/pgmodeler" +# Uncomment this line if you want to keep several versions of pgmodeler +#PREFIX="/opt/pgmodeler/$DEPLOY_VER" +INSTALL_ROOT="$PREFIX" INSTALLER_CONF_DIR="$PWD/installer/linux/config" INSTALLER_PKG_DIR="$PWD/installer/linux/packages" INSTALLER_DATA_DIR="$INSTALLER_PKG_DIR/br.com.pgmodeler/data" QT_CONF="$BUILD_DIR/$INSTALL_ROOT/qt.conf" DEP_PLUGINS_DIR="$BUILD_DIR/$INSTALL_ROOT/lib/qtplugins" -# Detecting current pgModeler version -DEPLOY_VER=`cat libutils/src/globalattributes.cpp | grep PGMODELER_VERSION | sed 's/PGMODELER_VERSION=QString("//g' | sed 's/"),//g' | sed 's/^ *//g' | cut -s -f2` GEN_INSTALLER_OPT='-gen-installer' DEMO_VERSION_OPT='-demo-version' NO_QT_LIBS_OPT='-no-qt-libs' @@ -49,7 +54,6 @@ BUNDLE_QT_LIBS=1 BUILD_ALL=0 # pgModeler output paths settings -PREFIX="/opt/pgmodeler" BINDIR=$PREFIX PRIVATEBINDIR=$PREFIX PRIVATELIBDIR="$PREFIX/lib"