Compare commits

..
18 Commits
Author SHA1 Message Date
Gokhan Simsek eddf2b0339 Export_Import: Reverting MainWindow class back to the version just before the start of this branch in order to solve merge conflict. 2016-10-13 23:15:48 +03:00
Gokhan Simsek f2226c92b3 Export_Import: Cancelling some customizations done for the design attempt of export dialog with custom explorer tree items 2016-10-13 22:58:25 +03:00
Gokhan Simsek 466709df23 Export_Import: Cancelling tree widget structure due to unnecessary complexity created; Enabling export button only a collection is selected; Adding "show details" button and feature. 2016-10-13 12:01:17 +03:00
Gokhan Simsek 702459918b ReplicaSet: Adding functionality refresh replica set view via "Refresh" context menu items both on Server and Replica Set Folder explorer tree items. Adding ExplorerReplicaSetFolderItem as a new specialized class. Adding new connection type "ConnectionRefresh" and function MongoServer::tryRefresh function to use updating whole connection view. 2016-10-12 15:50:58 +03:00
Gokhan Simsek 4efbd8b90a Export_Import: Adding support for multiple simultaneous exports in auto mode as well; adding enableDisableWidgets function to disable some widgets during export operation 2016-10-10 02:22:52 +03:00
Gokhan Simsek 655bfcba0a Export_Import: Adding support for multiple simultaneous exports in manual mode; Making export dialog mode-less 2016-10-09 18:27:54 +03:00
Gokhan Simsek 041356ebac Export_Import: Adding progress dialog for long lasting exports for auto mode 2016-10-09 13:52:35 +03:00
Gokhan Simsek 32e9ceb741 Export_Import: Appending mongo export output into auto mode result dialog 2016-10-09 01:00:29 +03:00
Gokhan Simsek 1aeb0e42dc Export_Import: Adding manual export mode 2016-10-08 23:30:33 +03:00
Gokhan Simsek 9c419b1f2e ReplicaSet: Enabling this feature which was disabled code due to release 0.9.0 Final 2016-10-07 19:15:14 +03:00
Gokhan Simsek 1cfb1b6287 Export_Import: Adding code to support query argument; Moving all changes to _mongoExportArgs into one location inside accept() function. 2016-10-02 22:23:49 +03:00
Gokhan Simsek 6f5124616a Export_Import: Adding support to export in CSV format 2016-10-02 21:40:21 +03:00
Gokhan Simsek 3ba2f8ae93 Export_Import: Working export getting arguments from UI; adding smart filename and path creation when collection selected; adding browse directory functionality. 2016-10-01 18:17:44 +03:00
Gokhan Simsek b6d87141f2 Export_Import: First working mongo export with local executable directory and static arguments 2016-09-30 22:56:31 +03:00
Gokhan Simsek 993e9355bb Export_Import: Not creating "Functions", "User" and "Indexes" folders if items are created inside exp/imp dialog 2016-09-30 22:01:52 +03:00
Gokhan Simsek 7ebc059430 Export_Import: Adding function to be able to customize ExplorerDatabaseTreeItem in order to use it inside Export Dialog 2016-09-09 19:52:46 +03:00
Gokhan Simsek 0d3fda185f Export_Import: Adding new dialog/class ExportDialog and it's first visual template; adding import action into main window 2016-09-09 13:41:25 +03:00
Gokhan Simsek 38df06261b New branch Export_Import; adding export tool bar item into main windows; adding icons for export and import 2016-09-08 14:09:11 +03:00
50 changed files with 982 additions and 818 deletions
+47 -64
View File
@@ -1,78 +1,61 @@
Latest Release:
Robomongo 0.9.0 Final (30 Sep, 2016)
http://blog.robomongo.org/robomongo-0-9-0-final/
Robomongo 0.9.0 RC10 (Aug 8, 2016)
http://blog.robomongo.org/robomongo-rc10/
Robomongo 0.9.0:
Major Features:
- Support for MongoDB 3.x and WiredTiger engine. Robomongo now embeds MongoDB 3.2 shell.
(Ability to use the latest shell functionality)
- SSH tunnel support for connections added.
- SSL tunnel support added.
- MongoDB Atlas (Cloud MongoDB) support added.
- Both MONGODB-CR and SCRAM-SHA-1 authentication mechanisms are supported.
- Allow direct connections to Replica Set members and support IPv6 protocol.
- Loading of huge list of collections is now faster.
- Create Collection dialog is now expandable to support all advanced options.
(Supporting all major mongoDB versions 3.2, 3.0, 2.6 and all storage engine types (WiredTiger
and MMAPV1) is added.)
- Windows High DPI support.
- Full size editor with dockable output window.
Fixed:
- Incorrect representation of floating-point numbers (fixed since RC3). This bug was a reason of a big number of issues:
#910, #748, #697, #699, #760, #815, #870, #892,
#894, #905, #945, #974, #978, #990, #831, #842
- SSH connection failure to servers on Ubuntu and OS X with the following error:
"Resource temporarily unavailable. Error when starting up SSH session: -8" (#1090)
What's new in 0.9.0 Final (30 Sep, 2016)
http://blog.robomongo.org/robomongo-0-9-0-final/
New Features:
- Full size editor with dockable output window.
- New JSON object context menu items: "Copy Name" and "Copy Path" are added.
- New database context menu items: "Current Operations" and "Kill Operation" are added.
- Minimize to Tray Icon for Windows.
Other Changes
- Cloud platforms Compose, mLab and Amazon EC2 were tested and added as supported platforms.
- Maximize/Restore result button behavior and icon have been improved.
- For better code quality and code reviews, Robomongo Code Quality and Robomongo Code Review pages have been created.
https://github.com/paralect/robomongo/wiki/Robomongo-Code-Review
https://github.com/paralect/robomongo/wiki/Robomongo-Code-Quality
Highlights from Robomongo 0.9.0 RCs:
Major Features:
- Support for MongoDB 3.x and WiredTiger engine. Robomongo now embeds MongoDB 3.2 shell.
(Ability to use the latest shell functionality)
- SSH tunnel support for connections added.
- Support for SSL connections added.
- MongoDB Atlas (Cloud MongoDB) support added.
- Both MONGODB-CR and SCRAM-SHA-1 authentication mechanisms are supported.
- Allow direct connections to Replica Set members and support IPv6 protocol.
- Loading of huge list of collections is now faster.
- Create Collection dialog is now expandable to support all advanced options.
(Supporting all major mongoDB versions 3.2, 3.0, 2.6 and all storage engine types (WiredTiger
and MMAPV1) is added.)
- Windows High DPI support.
Fixed:
- Incorrect representation of floating-point numbers (fixed since RC3). This bug was a reason of a big number of issues:
#910, #748, #697, #699, #760, #815, #870, #892,
#894, #905, #945, #974, #978, #990, #831, #842
- SSH connection failure to servers on Ubuntu and OS X with the following error:
"Resource temporarily unavailable. Error when starting up SSH session: -8" (#1090)
What's new in RC10 (Aug 8, 2016)
http://blog.robomongo.org/robomongo-rc10/
New Features:
- SSL connections with advanced options are now supported.
- MongoDB Atlas (Cloud MongoDB) is supported.
- Cross Platform High DPI enhancements.
Enhancements:
- For better security, OpenSSL has been upgraded to OpenSSL 1.0.1p.
- Qt has been updated from Qt 5.5 to latest Qt 5.7. With this update there are many
enhancements including cross platform High DPI support.
New Features:
- SSL connections with advanced options are now supported.
- MongoDB Atlas (Cloud MongoDB) is supported.
- Cross Platform High DPI enhancements.
Enhancements:
- For better security, OpenSSL has been upgraded to OpenSSL 1.0.1p.
- Qt has been updated from Qt 5.5 to latest Qt 5.7. With this update there are many
enhancements including cross platform High DPI support.
What's new in RC9 (May 30, 2016)
http://blog.robomongo.org/robomongo-rc9/
New Features:
- Create Collection dialog with advanced options.
- New feature has been added to save/restore window sizes. (#1102)
- Connection settings from previous versions of Robomongo are
now automatically imported starting from Robomongo 0.9.0 RC9. (#1086)
- Support for querying documents by UUIDs is added, both in legacy and new encoding. (#432)
Fixed:
- SSH connection failure to servers on Ubuntu and OS X with the following error:
"Resource temporarily unavailable. Error when starting up SSH session: -8" (#1090)
- Correct handling of create/drop of databases and collections. (#1083)
New Features:
- Create Collection dialog with advanced options.
- New feature has been added to save/restore window sizes. (#1102)
- Connection settings from previous versions of Robomongo are
now automatically imported starting from Robomongo 0.9.0 RC9. (#1086)
- Support for querying documents by UUIDs is added, both in legacy and new encoding. (#432)
Fixed:
- SSH connection failure to servers on Ubuntu and OS X with the following error:
"Resource temporarily unavailable. Error when starting up SSH session: -8" (#1090)
- Correct handling of create/drop of databases and collections. (#1083)
What's new in RC8 (April 14, 2016)
http://blog.robomongo.org/robomongo-rc8/
What's new in RC7 (March 4, 2016)
http://blog.robomongo.org/robomongo-rc7
@@ -147,7 +130,7 @@ Robomongo 0.9.0:
* [Andres Kievsky]
- Added new app icon in a variety of png and iDraw formats (#693)
* [Michael Steinacher]
- Retina text display support (#724)
- Retina text display support (#724)
0.8.4 / November 27, 2013
+1 -1
View File
@@ -8,7 +8,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
set(PROJECT_VERSION_MAJOR "0")
set(PROJECT_VERSION_MINOR "9")
set(PROJECT_VERSION_PATCH "0")
set(PROJECT_VERSION_BUILD "")
set(PROJECT_VERSION_BUILD "-RC10")
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${PROJECT_VERSION_BUILD}")
# Modules
+27 -36
View File
@@ -7,39 +7,31 @@ Starting from version 0.9, Robomongo is compatibile with MongoDB 3.x (including
Robomongo 0.8.x embeds the **MongoDB 2.4.0** shell.
What's new in latest Robomongo 0.9.0 Final?
What's new in latest Robomongo 0.9.0 RC10?
====================================
Latest release of Robomongo 0.9.0 Final includes:
- Full size editor with dockable output window.
(Becoming the first and only MongoDB admin tool providing this feature)
- Two result object context menu items: "Copy Name" and "Copy Path" added.
- Two database context menu items: "Copy Name" and "Copy Path" added.
- Minimize to Tray Icon for Windows.
Latest release of Robomongo 0.9.0 RC10 includes:
- Support for SSL
- MongoDB Atlas Support
- HiDPI enhancements
Central feature of this release is full size editor with dockable output window feature. With this new feature, Robomongo can be used with maximized/full size query editor with dockable/floating output window. This feature is very useful especially when you have long scripts or you just want to see output window in your second monitor.
Central feature of this release is full support for TSL/SSL protocol with advanced options. This version also brings support to MongoDB Atlas cloud service and includes enhancements for HiDPI displays.
Blog: http://blog.robomongo.org/robomongo-0-9-0-final/
Blog: http://blog.robomongo.org/robomongo-rc10
Download: https://robomongo.org/download
Watch: [Robomongo youtube channel](https://www.youtube.com/channel/UCM_7WAseRWeeiBikExppstA)
Follow: https://twitter.com/Robomongo
What's Planned for the Next Releases?
What's Planned for the Next Release?
====================================
We are currently working towards [Robomongo 1.0.0 milestone](https://github.com/paralect/robomongo/milestone/18).
We are currently working towards [Robomongo 0.9.0 RC11 milestone](https://github.com/paralect/robomongo/milestone/16).
Currently in progress:
- Replica Sets
- Export/Import
Planned for Next Release:
- Support creating connections from connections strings
- Support enabling SSH and SSL at the same time
- Replica Sets Support
Plans for Future:
- User Roles
- Support execution of multiple simultaneous queries [#1161](https://github.com/paralect/robomongo/issues/1161)
- Enhancements for stability, running without crashes ([Stability Milestone](https://github.com/paralect/robomongo/milestone/15))
- Enhancements for stability, running without crashes
- More Documentation
- Unit Tests
- Refactoring Debug Log module
@@ -47,19 +39,20 @@ Plans for Future:
Supported Platforms
===============
| MongoDB Versions |
| :-------------------- |
| 3.2 |
| 3.0 |
| 2.6 |
**Supported MongoDBs:**
| MongoDB Cloud Platforms|
| :------------ |
| MongoDB Atlas |
| Compose |
| mLab |
| ObjectRocket |
| Amazon EC2 |
| MongoDB Versions | MongoDB Cloud |
| :-------------------- | :------------ |
| 3.2 | MongoDB Atlas |
| 3.0 | Compose |
| 2.6 | mLab |
| | ObjectRocket |
**Note**: Currently Robomongo supports connection to single server of a replica set. Support for connection to **Replica Sets** is one of the most important features of next Robomongo release plan.
**Supported OS Platforms:**
| Windows | Mac | Linux |
|:---------------------- | :---------------| :---------------------------|
@@ -70,15 +63,14 @@ Supported Platforms
\* latest stable build
**Note**: Currently Robomongo supports connection to single server of a replica set. Support for connection to **Replica Sets** is planned in next release Robomongo 1.0.0.
Download
========
You can download tested install packages for OS X, Windows, and Linux from our site: [www.robomongo.org](http://www.robomongo.org).
The latest stable release is currently [**Robomongo 0.9.0 Final**](http://blog.robomongo.org/robomongo-0-9-0-final/).
The latest release candidate is currently **Robomongo 0.9.0 RC10**. (http://blog.robomongo.org/robomongo-rc10/).
The latest stable release is currently **Robomongo 0.8.5**. (http://blog.robomongo.org/whats-new-in-robomongo-0-8-5/)
Support
=======
@@ -104,7 +96,6 @@ Contribute!
### Suggest Features
New feature suggestions or UI improvements are always welcome.
[Create a new feature request on github](https://github.com/paralect/robomongo/issues/new)
This project is powered by open source volunteers, so we have a limited amount of development resource to address all requests. We will certainly make best efforts to progress (particularly for those with strong community upvotes).
+1
View File
@@ -75,6 +75,7 @@ set(SOURCES
# Isolated scope #4
gui/dialogs/PreferencesDialog.cpp
gui/dialogs/ConnectionsDialog.cpp
gui/dialogs/ExportDialog.cpp
# Isolated scope #5
gui/editors/PlainJavaScriptEditor.cpp
+2 -2
View File
@@ -58,8 +58,8 @@ int main(int argc, char *argv[], char** envp)
Robomongo::AppStyleUtils::initStyle();
// Application main window
Robomongo::MainWindow mainWindow;
mainWindow.show();
Robomongo::MainWindow win;
win.show();
int rc = app.exec();
rbm_ssh_cleanup();
+61 -60
View File
@@ -25,10 +25,10 @@ namespace Robomongo
{
namespace detail
{
bool isSimpleType(Robomongo::BsonTreeItem const *item)
bool isSimpleType(Robomongo::BsonTreeItem *item)
{
return BsonUtils::isSimpleType(item->type())
|| BsonUtils::isUuidType(item->type(), item->binType());
return Robomongo::BsonUtils::isSimpleType(item->type())
|| Robomongo::BsonUtils::isUuidType(item->type(), item->binType());
}
bool isObjectIdType(Robomongo::BsonTreeItem *item)
@@ -41,17 +41,17 @@ namespace Robomongo
return indexes.count() > 1;
}
bool isDocumentType(BsonTreeItem const *item)
bool isDocumentType(BsonTreeItem *item)
{
return BsonUtils::isDocument(item->type());
return Robomongo::BsonUtils::isDocument(item->type());
}
bool isArrayChild(BsonTreeItem const *item)
bool isArrayChild(BsonTreeItem *item)
{
return BsonUtils::isArray(dynamic_cast<BsonTreeItem*>(item->parent())->type());
return Robomongo::BsonUtils::isArray(dynamic_cast<BsonTreeItem *>(item->parent())->type());
}
bool isDocumentRoot(BsonTreeItem const *item)
bool isDocumentRoot(BsonTreeItem *item)
{
return ( item == item->superParent() );
}
@@ -158,18 +158,19 @@ namespace Robomongo
if (onItem && isEditable) menu->addAction(_editDocumentAction);
if (onItem) menu->addAction(_viewDocumentAction);
if (isEditable) menu->addAction(_insertDocumentAction);
if (onItem && (isSimple || isDocument)) menu->addSeparator();
if (onItem && isSimple) menu->addAction(_copyValueAction);
if (onItem && (isSimple || isDocument)) menu->addSeparator();
if (onItem && isSimple) menu->addAction(_copyValueAction);
if (onItem && (isSimple || isDocument) && isNotArrayChild && !isRoot)
menu->addAction(_copyValueNameAction);
if (onItem && (isSimple || isDocument) && !isRoot)
menu->addAction(_copyValuePathAction);
if (onItem && isObjectId) menu->addAction(_copyTimestampAction);
if (onItem && isDocument) menu->addAction(_copyJsonAction);
if (onItem && isEditable) menu->addSeparator();
if (onItem && isEditable) menu->addAction(_deleteDocumentAction);
}
@@ -244,53 +245,6 @@ namespace Robomongo
}
}
void Notifier::onCopyNameDocument()
{
QModelIndex const& selectedInd = _observer->selectedIndex();
if (!selectedInd.isValid())
return;
BsonTreeItem const *documentItem = QtUtils::item<BsonTreeItem*>(selectedInd);
if (!documentItem)
return;
if (!(detail::isSimpleType(documentItem) || detail::isDocumentType(documentItem) ||
!detail::isArrayChild(documentItem) || !detail::isDocumentRoot(documentItem)))
return;
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(QString::fromStdString(documentItem->fieldName()));
}
void Notifier::onCopyPathDocument()
{
QModelIndex const& selectedInd = _observer->selectedIndex();
if (!selectedInd.isValid())
return;
BsonTreeItem const *documentItem = QtUtils::item<BsonTreeItem*>(selectedInd);
if (!documentItem)
return;
if (!(detail::isSimpleType(documentItem) || detail::isDocumentType(documentItem) ||
!detail::isDocumentRoot(documentItem)))
return;
QStringList namesList;
BsonTreeItem const *documentItemHelper = documentItem;
while (!detail::isDocumentRoot(documentItemHelper)) {
if (!detail::isArrayChild(documentItemHelper)) {
namesList.push_front(QString::fromStdString(documentItemHelper->fieldName()));
}
documentItemHelper = dynamic_cast<BsonTreeItem*>(documentItemHelper->parent());
}
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(namesList.join("."));
}
void Notifier::handleDeleteCommand()
{
if (_observer->selectedIndexes().count() > 1) {
@@ -389,7 +343,7 @@ namespace Robomongo
json, true, dynamic_cast<QWidget*>(_observer));
editor->setWindowTitle("View Document");
editor->exec();
editor->show();
}
void Notifier::onInsertDocument()
@@ -432,6 +386,53 @@ namespace Robomongo
clipboard->setText(documentItem->value());
}
void Notifier::onCopyNameDocument()
{
QModelIndex selectedInd = _observer->selectedIndex();
if (!selectedInd.isValid())
return;
BsonTreeItem *documentItem = QtUtils::item<BsonTreeItem*>(selectedInd);
if (!documentItem)
return;
if ( !(detail::isSimpleType(documentItem) || detail::isDocumentType(documentItem) ||
!detail::isArrayChild(documentItem) || !detail::isDocumentRoot(documentItem)) )
return;
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(QString::fromStdString(documentItem->fieldName()));
}
void Notifier::onCopyPathDocument()
{
QModelIndex selectedInd = _observer->selectedIndex();
if (!selectedInd.isValid())
return;
BsonTreeItem *documentItem = QtUtils::item<BsonTreeItem*>(selectedInd);
if (!documentItem)
return;
if ( !(detail::isSimpleType(documentItem) || detail::isDocumentType(documentItem) ||
!detail::isDocumentRoot(documentItem)) )
return;
QStringList namesList;
BsonTreeItem *documentItemHelper = documentItem;
while ( !detail::isDocumentRoot(documentItemHelper) ) {
if ( !detail::isArrayChild(documentItemHelper) ) {
namesList.push_front( QString::fromStdString(documentItemHelper->fieldName()) );
}
documentItemHelper = dynamic_cast<BsonTreeItem *>(documentItemHelper->parent());
}
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(namesList.join("."));
}
void Notifier::onCopyTimestamp()
{
QModelIndex selectedInd = _observer->selectedIndex();
+4 -6
View File
@@ -18,10 +18,10 @@ namespace Robomongo
namespace detail
{
bool isSimpleType(BsonTreeItem const *item);
bool isSimpleType(BsonTreeItem *item);
bool isObjectIdType(BsonTreeItem *item);
bool isMultiSelection(const QModelIndexList &indexes);
bool isDocumentType(BsonTreeItem const *item);
bool isDocumentType(BsonTreeItem *item);
QModelIndexList uniqueRows(QModelIndexList indexes, bool returnSuperParents = false);
}
@@ -55,15 +55,13 @@ namespace Robomongo
void onViewDocument();
void onInsertDocument();
void onCopyDocument();
void onCopyNameDocument();
void onCopyPathDocument();
void onCopyTimestamp();
void onCopyJson();
void handle(InsertDocumentResponse *event);
void handle(RemoveDocumentResponse *event);
private Q_SLOTS:
void onCopyNameDocument();
void onCopyPathDocument();
private:
QAction *_deleteDocumentAction;
QAction *_deleteDocumentsAction;
+7 -6
View File
@@ -26,7 +26,10 @@ namespace Robomongo
{
MongoWorker::MongoWorker(ConnectionSettings *connection, bool isLoadMongoRcJs, int batchSize,
int mongoTimeoutSec, int shellTimeoutSec, QObject *parent) : QObject(parent),
_connSettings(connection),
_scriptEngine(NULL),
_dbclient(nullptr),
_dbclientRepSet(nullptr),
_isAdmin(true),
_isLoadMongoRcJs(isLoadMongoRcJs),
_batchSize(batchSize),
@@ -34,10 +37,7 @@ namespace Robomongo
_dbAutocompleteCacheTimerId(-1),
_mongoTimeoutSec(mongoTimeoutSec),
_shellTimeoutSec(shellTimeoutSec),
_isQuiting(0),
_dbclient(nullptr),
_dbclientRepSet(nullptr),
_connSettings(connection)
_isQuiting(0)
{
_thread = new QThread();
moveToThread(_thread);
@@ -663,10 +663,11 @@ namespace Robomongo
mongo::DBClientBase *MongoWorker::getConnection(bool mayReturnNull /* = false */)
{
// --- Configure SSL first --- // todo: move to function?
// --- Configure SSL first --- Todo: move to function?
// As a precaution reset SSL global params for any kind of connection request (SSL or non-SSL)
resetGlobalSSLparams();
// Update global SSL mode and global mongo SSL settings
// Update global mongo SSL settings according to SSL enable/disabled status
if (_connSettings->sslSettings()->sslEnabled())
{
// Force SSL mode for outgoing connections
+2 -5
View File
@@ -130,10 +130,11 @@ namespace Robomongo
* @brief Send event to this MongoWorker
*/
void send(Event *event);
DatabasesContainerType getDatabaseNamesSafe();
std::string getAuthBase() const;
std::unique_ptr<mongo::DBClientConnection> _dbclient;
std::unique_ptr<mongo::DBClientReplicaSet> _dbclientRepSet;
mongo::DBClientBase *getConnection(bool mayReturnNull = false);
MongoClient *getClient();
@@ -152,7 +153,6 @@ namespace Robomongo
* @brief Send reply event to object 'obj'
*/
void reply(QObject *receiver, Event *event);
QThread *_thread;
QMutex _firstConnectionMutex;
@@ -167,9 +167,6 @@ namespace Robomongo
int _shellTimeoutSec;
QAtomicInteger<int> _isQuiting;
std::unique_ptr<mongo::DBClientConnection> _dbclient;
std::unique_ptr<mongo::DBClientReplicaSet> _dbclientRepSet;
ConnectionSettings *_connSettings;
// Collection of created databases.
@@ -30,8 +30,8 @@ namespace Robomongo
_imported(false),
_sshSettings(new SshSettings()),
_sslSettings(new SslSettings()),
_isReplicaSet(false),
_replicaSetSettings(new ReplicaSetSettings())
_replicaSetSettings(new ReplicaSetSettings()),
_isReplicaSet(false)
{ }
void ConnectionSettings::fromVariant(const QVariantMap &map) {
@@ -39,8 +39,7 @@ namespace Robomongo
setServerHost(QtUtils::toStdString(map.value("serverHost").toString().left(maxLength)));
setServerPort(map.value("serverPort").toInt());
setDefaultDatabase(QtUtils::toStdString(map.value("defaultDatabase").toString()));
//// Temporarily disable Replica Setet - feature is under development
//setReplicaSet(map.value("isReplicaSet").toBool());
setReplicaSet(map.value("isReplicaSet").toBool());
QVariantList list = map.value("credentials").toList();
for (QVariantList::const_iterator it = list.begin(); it != list.end(); ++it) {
@@ -57,10 +56,9 @@ namespace Robomongo
_sslSettings->fromVariant(map.value("ssl").toMap());
}
//// Temporarily disable Replica Setet - feature is under development
//if (isReplicaSet()) {
// _replicaSetSettings->fromVariant(map.value("replicaSet").toMap());
//}
if (isReplicaSet()) {
_replicaSetSettings->fromVariant(map.value("replicaSet").toMap());
}
//#ifdef MONGO_SSL
// ,SSLInfo(map.value("sslEnabled").toBool(),QtUtils::toStdString(map.value("sslPemKeyFile").toString()))
@@ -98,8 +96,7 @@ namespace Robomongo
setServerPort(source->serverPort());
setDefaultDatabase(source->defaultDatabase());
setImported(source->imported());
//// Temporarily disable Replica Setet - feature is under development
//setReplicaSet(source->isReplicaSet());
setReplicaSet(source->isReplicaSet());
clearCredentials();
QList<CredentialSettings *> cred = source->credentials();
@@ -126,11 +123,10 @@ namespace Robomongo
map.insert("serverHost", QtUtils::toQString(serverHost()));
map.insert("serverPort", serverPort());
map.insert("defaultDatabase", QtUtils::toQString(defaultDatabase()));
//// Temporarily disable Replica Setet - feature is under development
//map.insert("isReplicaSet", isReplicaSet());
//if (isReplicaSet()) {
// map.insert("replicaSet", _replicaSetSettings->toVariant());
//}
map.insert("isReplicaSet", isReplicaSet());
if (isReplicaSet()) {
map.insert("replicaSet", _replicaSetSettings->toVariant());
}
#ifdef MONGO_SSL
SSLInfo infl = _info.sslInfo();
@@ -160,7 +160,7 @@ namespace Robomongo
private:
CredentialSettings *findCredential(const std::string &databaseName) const;
bool _isReplicaSet;
std::string _connectionName;
std::string _host;
int _port;
@@ -168,7 +168,6 @@ namespace Robomongo
QList<CredentialSettings *> _credentials;
SshSettings *_sshSettings;
SslSettings *_sslSettings;
bool _isReplicaSet;
ReplicaSetSettings *_replicaSetSettings;
// Was this connection imported from somewhere?
@@ -31,7 +31,7 @@ namespace Robomongo
{
// Extract and set replica members
std::vector<std::string> vec;
auto itr = map.begin();
auto& itr = map.begin();
int idx = 0;
do
{
@@ -30,12 +30,17 @@ namespace Robomongo
QVariant toVariant() const;
void fromVariant(const QVariantMap &map);
//// todo: remove
//void addMember(const std::string& str) { _members.push_back(str); }
// Getters
//
const std::vector<std::string>& members() const { return _members; }
const std::vector<mongo::HostAndPort> membersToHostAndPort() const;
ReadPreference readPreference() const { return _readPreference; }
// Setters
//
void setMembers(const std::vector<std::string>& members) { _members = members; }
void setReadPreference(ReadPreference readPreference) { _readPreference = readPreference; }
+20 -13
View File
@@ -47,16 +47,15 @@ namespace Robomongo
_timeZone(Utc),
_viewMode(Robomongo::Tree),
_autocompletionMode(AutocompleteAll),
_loadMongoRcJs(false),
_minimizeToTray(false),
_lineNumbers(false),
_disableConnectionShortcuts(false),
_batchSize(50),
_disableConnectionShortcuts(false),
_textFontFamily(""),
_textFontPointSize(-1),
_textFontPointSize(-1),
_lineNumbers(false),
_loadMongoRcJs(false),
_imported(false),
_mongoTimeoutSec(10),
_shellTimeoutSec(15),
_imported(false)
_shellTimeoutSec(15)
{
load();
LOG_MSG("SettingsManager initialized in " + _configPath, mongo::logger::LogSeverity::Info(), false);
@@ -146,11 +145,17 @@ namespace Robomongo
_viewMode = Custom; // Default View Mode
}
_autoExpand = map.contains("autoExpand") ? map.value("autoExpand").toBool() : true;
_autoExec = map.contains("autoExec") ? map.value("autoExec").toBool() : true;
_minimizeToTray = map.contains("minimizeToTray") ? map.value("minimizeToTray").toBool() : false;
_lineNumbers = map.contains("lineNumbers") ? map.value("lineNumbers").toBool() : false;
_imported = map.contains("imported") ? map.value("imported").toBool() : false;
_autoExpand = map.contains("autoExpand") ?
map.value("autoExpand").toBool() : true;
_autoExec = map.contains("autoExec") ?
map.value("autoExec").toBool() : true;
_lineNumbers = map.contains("lineNumbers") ?
map.value("lineNumbers").toBool() : false;
_imported = map.contains("imported") ?
map.value("imported").toBool() : false;
// 4. Load TimeZone
int timeZone = map.value("timeZone").toInt();
@@ -275,9 +280,11 @@ namespace Robomongo
}
map.insert("connections", list);
map.insert("autoExec", _autoExec);
map.insert("minimizeToTray", _minimizeToTray);
map.insert("toolbars", _toolbars);
map.insert("imported", _imported);
return map;
@@ -86,9 +86,6 @@ namespace Robomongo
void setAutoExec(bool isAutoExec) { _autoExec = isAutoExec; }
bool autoExec() const { return _autoExec; }
void setMinimizeToTray(bool isMinimizingToTray) { _minimizeToTray = isMinimizingToTray; }
bool minimizeToTray() const { return _minimizeToTray; }
void setLineNumbers(bool showLineNumbers) { _lineNumbers = showLineNumbers; }
bool lineNumbers() const { return _lineNumbers; }
@@ -151,7 +148,6 @@ namespace Robomongo
bool _loadMongoRcJs;
bool _autoExpand;
bool _autoExec;
bool _minimizeToTray;
bool _lineNumbers;
bool _disableConnectionShortcuts;
int _batchSize;
+17 -17
View File
@@ -46,7 +46,7 @@ namespace Robomongo
const QIcon &GuiRegistry::replicaSetIcon() const
{
static const QIcon replicaSetIc(":/robomongo/icons/replica_set_16x16.png");
static const QIcon replicaSetIc = QIcon(":/robomongo/icons/replica_set_16x16.png");
return replicaSetIc;
}
@@ -96,26 +96,14 @@ namespace Robomongo
const QIcon &GuiRegistry::maximizeIcon() const
{
static const QIcon maximizeIc(":/robomongo/icons/maximize.png");
static const QIcon maximizeIc = QIcon(":/robomongo/icons/maximize.gif");
return maximizeIc;
}
const QIcon &GuiRegistry::minimizeIcon() const
const QIcon &GuiRegistry::maximizeHighlightedIcon() const
{
static const QIcon minimizeIc(":/robomongo/icons/minimize.png");
return minimizeIc;
}
const QIcon &GuiRegistry::undockIcon() const
{
static const QIcon undockIc(":/robomongo/icons/undock.png");
return undockIc;
}
const QIcon &GuiRegistry::dockIcon() const
{
static const QIcon dockIc(":/robomongo/icons/dock.png");
return dockIc;
static const QIcon maximizeHighlightedIc = QIcon(":/robomongo/icons/maximize_highlighted_16x16.png");
return maximizeHighlightedIc;
}
const QIcon &GuiRegistry::textIcon() const
@@ -336,6 +324,18 @@ namespace Robomongo
return stopIc;
}
const QIcon &GuiRegistry::exportIcon() const
{
static const QIcon exportIc = QIcon(":/robomongo/icons/export_64x64.png");
return exportIc;
}
const QIcon &GuiRegistry::importIcon() const
{
static const QIcon importIc = QIcon(":/robomongo/icons/import_64x64.png");
return importIc;
}
const QIcon &GuiRegistry::mainWindowIcon() const
{
static const QIcon mainWindowIc = QIcon(":/robomongo/icons/logo-256x256.png");
+3 -3
View File
@@ -39,9 +39,7 @@ namespace Robomongo
const QIcon& userIcon() const;
const QIcon& functionIcon() const;
const QIcon& maximizeIcon() const;
const QIcon& minimizeIcon() const;
const QIcon& undockIcon() const;
const QIcon& dockIcon() const;
const QIcon& maximizeHighlightedIcon() const;
const QIcon& textIcon() const;
const QIcon& textHighlightedIcon() const;
const QIcon& treeIcon() const;
@@ -60,6 +58,8 @@ namespace Robomongo
const QIcon& connectIcon() const;
const QIcon& executeIcon() const;
const QIcon& stopIcon() const;
const QIcon& exportIcon() const;
const QIcon& importIcon() const;
const QIcon& mainWindowIcon() const;
const QIcon& bsonObjectIcon() const;
const QIcon& bsonArrayIcon() const;
+19 -149
View File
@@ -17,7 +17,6 @@
#include <QStatusBar>
#include <QHBoxLayout>
#include <QSettings>
#include <QSystemTrayIcon>
#include <mongo/logger/log_severity.h>
#include "robomongo/core/settings/SettingsManager.h"
@@ -38,7 +37,6 @@
#include "robomongo/gui/dialogs/PreferencesDialog.h"
#include "robomongo/gui/GuiRegistry.h"
#include "robomongo/gui/AppStyle.h"
#include "robomongo/gui/widgets/workarea/QueryWidget.h"
namespace
{
@@ -70,30 +68,21 @@ namespace
Robomongo::AppRegistry::instance().settingsManager()->save();
}
void saveMinimizeToTraySettings(bool isMinimizingToTray)
{
Robomongo::AppRegistry::instance().settingsManager()->setMinimizeToTray(isMinimizingToTray);
Robomongo::AppRegistry::instance().settingsManager()->save();
}
void saveLineNumbers(bool showLineNumbers)
{
Robomongo::AppRegistry::instance().settingsManager()->setLineNumbers(showLineNumbers);
Robomongo::AppRegistry::instance().settingsManager()->save();
}
}
/* End of anonymous namespace */
}
namespace Robomongo
{
/* ------ ConnectionMenu ------ */
class ConnectionMenu : public QMenu
{
public:
ConnectionMenu(QWidget *parent) : QMenu(parent) {}
protected:
virtual void keyPressEvent(QKeyEvent *event) override
virtual void keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_F12) {
hide();
@@ -104,16 +93,11 @@ namespace Robomongo
}
};
/* ------ MainWindow ------ */
MainWindow::MainWindow()
: BaseClass(),
_workArea(nullptr),
_app(AppRegistry::instance().app()),
_connectionsMenu(nullptr),
#if defined(Q_OS_WIN)
_trayIcon(nullptr),
#endif
_allowExit(false)
_workArea(NULL),
_connectionsMenu(NULL)
{
QColor background = palette().window().color();
QString controlKey = "Ctrl";
@@ -151,7 +135,7 @@ namespace Robomongo
// Exit action
QAction *exitAction = new QAction("&Exit", this);
exitAction->setShortcuts(QKeySequence::Quit);
VERIFY(connect(exitAction, SIGNAL(triggered()), this, SLOT(exit())));
VERIFY(connect(exitAction, SIGNAL(triggered()), this, SLOT(close())));
// Connect action
_connectAction = new QAction("&Connect...", this);
@@ -182,26 +166,6 @@ namespace Robomongo
QWidgetAction *connectButtonAction = new QWidgetAction(this);
connectButtonAction->setDefaultWidget(_connectButton);
// Tray icon
#if defined(Q_OS_WIN)
_trayIcon = new QSystemTrayIcon(GuiRegistry::instance().mainWindowIcon());
VERIFY(connect(_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
this, SLOT(trayActivated(QSystemTrayIcon::ActivationReason))));
QAction *trayMinimizeAction = new QAction("Minimize to Tray", _trayIcon);
VERIFY(connect(trayMinimizeAction, SIGNAL(triggered()), this, SLOT(toggleMinimize())));
QAction *trayExitAction = new QAction("Exit", _trayIcon);
VERIFY(connect(trayExitAction, SIGNAL(triggered()), this, SLOT(exit())));
QMenu *contextMenu = new QMenu();
contextMenu->addAction(trayMinimizeAction);
contextMenu->addSeparator();
contextMenu->addAction(trayExitAction);
_trayIcon->setContextMenu(contextMenu);
#endif
// Orientation action
_orientationAction = new QAction("&Rotate", this);
_orientationAction->setShortcut(Qt::Key_F10);
@@ -418,14 +382,6 @@ namespace Robomongo
VERIFY(connect(autoExec, SIGNAL(triggered()), this, SLOT(toggleAutoExec())));
optionsMenu->addAction(autoExec);
#if defined(Q_OS_WIN)
QAction *minimizeTray = new QAction("Close button should minimize to system tray");
minimizeTray->setCheckable(true);
minimizeTray->setChecked(AppRegistry::instance().settingsManager()->minimizeToTray());
VERIFY(connect(minimizeTray, SIGNAL(triggered()), this, SLOT(toggleMinimizeToTray())));
optionsMenu->addAction(minimizeTray);
#endif
QAction *preferencesAction = new QAction("Preferences", this);
VERIFY(connect(preferencesAction, SIGNAL(triggered()), this, SLOT(openPreferences())));
preferencesAction->setVisible(false);
@@ -552,9 +508,6 @@ namespace Robomongo
AppRegistry::instance().bus()->subscribe(this, OperationFailedEvent::Type);
restoreWindowsSettings();
// Catch application windows focus changes
VERIFY(connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(on_focusChanged())));
}
void MainWindow::createStylesMenu()
@@ -616,12 +569,6 @@ namespace Robomongo
AppRegistry::instance().settingsManager()->save();
}
void MainWindow::exit()
{
_allowExit = true;
close();
}
void MainWindow::restoreWindowsSettings()
{
QSettings settings("Paralect", "Robomongo");
@@ -629,6 +576,8 @@ namespace Robomongo
if (settings.contains("MainWindow/geometry"))
{
restoreGeometry(settings.value("MainWindow/geometry").toByteArray());
restoreState(settings.value("MainWindow/windowState").toByteArray());
settings.setValue("windowState", saveState());
}
else
{
@@ -651,6 +600,7 @@ namespace Robomongo
{
QSettings settings("Paralect", "Robomongo");
settings.setValue("MainWindow/geometry", saveGeometry());
settings.setValue("MainWindow/windowState", saveState());
}
void MainWindow::open()
@@ -686,6 +636,16 @@ namespace Robomongo
}
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_F12) {
_connectButton->showMenu();
return;
}
BaseClass::keyPressEvent(event);
}
void MainWindow::updateConnectionsMenu()
{
_connectionsMenu->clear();
@@ -719,10 +679,6 @@ namespace Robomongo
void MainWindow::manageConnections()
{
#if defined(Q_OS_WIN)
_trayIcon->hide(); // hide the tray icon so the main window can't be hidden behind the connections dialog
#endif
static bool checkForImported = true;
ConnectionsDialog dialog(AppRegistry::instance().settingsManager(), checkForImported, this);
int result = dialog.exec();
@@ -754,10 +710,6 @@ namespace Robomongo
}
}
#if defined(Q_OS_WIN)
_trayIcon->show(); // show the tray icon once the connections dialog is gone
#endif
// on linux focus is lost - we need to activate main window back
activateWindow();
}
@@ -1018,51 +970,10 @@ namespace Robomongo
QMessageBox::information(NULL, "Operation failed", QtUtils::toQString(ss.str()));
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_F12) {
_connectButton->showMenu();
return;
}
BaseClass::keyPressEvent(event);
}
void MainWindow::closeEvent(QCloseEvent *event)
{
saveWindowsSettings();
#if defined(Q_OS_WIN)
if (AppRegistry::instance().settingsManager()->minimizeToTray() && !_allowExit) {
event->ignore();
hide(); // hide the window because it can be reopened with the tray icon
}
else {
if (_trayIcon->isVisible())
_trayIcon->hide();
QMainWindow::closeEvent(event);
}
#else
QMainWindow::closeEvent(event);
#endif
}
void MainWindow::hideEvent(QHideEvent *event)
{
#if defined(Q_OS_WIN)
if (_trayIcon->contextMenu()->actions().size() > 0 && isHidden()) {
_trayIcon->contextMenu()->actions().at(0)->setText("Show Robomongo");
}
#endif
}
void MainWindow::showEvent(QShowEvent *event)
{
#if defined(Q_OS_WIN)
if (_trayIcon->contextMenu()->actions().size() > 0) {
_trayIcon->contextMenu()->actions().at(0)->setText("Minimize to Tray");
}
#endif
}
void MainWindow::handle(QueryWidgetUpdatedEvent *event)
@@ -1106,7 +1017,7 @@ namespace Robomongo
_logDock = new QDockWidget(tr("Logs"));
_logDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea);
_logDock->setWidget(log);
_logDock->setFeatures(QDockWidget::DockWidgetClosable);
_logDock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable);
_logDock->setVisible(false);
QAction *action = _logDock->toggleViewAction();
@@ -1136,7 +1047,6 @@ namespace Robomongo
_workArea = new WorkAreaTabWidget(this);
AppRegistry::instance().bus()->subscribe(_workArea, OpeningShellEvent::Type);
VERIFY(connect(_workArea, SIGNAL(currentChanged(int)), this, SLOT(updateMenus())));
VERIFY(connect(_workArea, SIGNAL(currentChanged(int)), this, SLOT(on_tabChange())));
QHBoxLayout *hlayout = new QHBoxLayout;
hlayout->setContentsMargins(0, 3, 0, 0);
@@ -1170,44 +1080,4 @@ namespace Robomongo
AppRegistry::instance().settingsManager()->setToolbarSettings("explorer", isVisible);
AppRegistry::instance().settingsManager()->save();
}
void MainWindow::on_tabChange()
{
auto activeTab = dynamic_cast<QueryWidget*>(_workArea->currentWidget());
if (activeTab) {
activeTab->bringDockToFront();
}
}
void MainWindow::toggleMinimize()
{
if (isHidden()) {
show();
}
else {
hide();
}
}
void MainWindow::trayActivated(QSystemTrayIcon::ActivationReason reason)
{
if (QSystemTrayIcon::DoubleClick == reason && isHidden()) {
show();
}
}
void MainWindow::toggleMinimizeToTray()
{
QAction *send = qobject_cast<QAction*>(sender());
saveMinimizeToTraySettings(send->isChecked());
}
void MainWindow::on_focusChanged()
{
// If focus is on floating output window, make it's parent (which is a QueryWidget tab) as active tab
auto const activeDock = dynamic_cast<QueryWidget::CustomDockWidget*>(qApp->activeWindow());
if (activeDock) {
_workArea->setCurrentWidget(activeDock->getParentQueryWidget());
}
}
}
+2 -19
View File
@@ -1,7 +1,6 @@
#pragma once
#include <QMainWindow>
#include <QSystemTrayIcon>
QT_BEGIN_NAMESPACE
class QLabel;
class QToolBar;
@@ -28,6 +27,7 @@ namespace Robomongo
public:
typedef QMainWindow BaseClass;
MainWindow();
void keyPressEvent(QKeyEvent *event);
public Q_SLOTS:
void manageConnections();
@@ -51,7 +51,6 @@ namespace Robomongo
void save();
void saveAs();
void changeStyle(QAction *);
void exit();
void setDefaultUuidEncoding();
void setJavaUuidEncoding();
@@ -72,10 +71,7 @@ namespace Robomongo
void handle(OperationFailedEvent *event);
protected:
void keyPressEvent(QKeyEvent *event) override;
void closeEvent(QCloseEvent *event) override;
void hideEvent(QHideEvent *event) override;
void showEvent(QShowEvent *event) override;
void closeEvent(QCloseEvent *event);
private Q_SLOTS:
void updateMenus();
@@ -87,14 +83,6 @@ namespace Robomongo
void onOpenSaveToolbarVisibilityChanged(bool isVisisble);
void onExecToolbarVisibilityChanged(bool isVisisble);
void onExplorerVisibilityChanged(bool isVisisble);
void on_tabChange();
void toggleMinimize();
void trayActivated(QSystemTrayIcon::ActivationReason reason);
void toggleMinimizeToTray();
// On application focus changes
void on_focusChanged();
private:
void updateConnectionsMenu();
@@ -124,11 +112,6 @@ namespace Robomongo
QAction *_orientationAction;
QToolBar *_execToolBar;
#if defined(Q_OS_WIN)
QSystemTrayIcon *_trayIcon;
#endif
bool _allowExit;
};
}
+1 -1
View File
@@ -19,7 +19,7 @@ namespace
"<br/>"
"<a href=\"https://" PROJECT_GITHUB_FORK "\">Fork</a> project or <a href=\"https://" PROJECT_GITHUB_ISSUES "\">submit</a> issues/proposals on GitHub. <br/>"
"<br/>"
"Copyright 2013-2016 <a href=\"http://" PROJECT_COMPANYNAME_DOMAIN "\">" PROJECT_COMPANYNAME "</a>. All rights reserved.<br/>"
"Copyright 2013-2016 <a href=\"http:// " PROJECT_COMPANYNAME_DOMAIN "\">" PROJECT_COMPANYNAME "</a>. All rights reserved.<br/>"
"<br/>"
"The program is provided AS IS with NO WARRANTY OF ANY KIND, "
"INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A "
@@ -10,6 +10,8 @@
#include <QComboBox>
#include <QListWidget>
#include <QListWidgetItem>
#include <QShortCut>
#include <QKeySequence>
#include "robomongo/core/utils/QtUtils.h"
#include "robomongo/core/settings/ConnectionSettings.h"
@@ -90,12 +92,14 @@ namespace Robomongo
_readPreference->setCurrentIndex(static_cast<int>(replicaSettings->readPreference()));
}
new QShortcut(QKeySequence(Qt::Key_Delete), this, SLOT(deleteItem()));
QGridLayout *connectionLayout = new QGridLayout;
connectionLayout->setAlignment(Qt::AlignTop);
//// Temporarily disable Replica Set - feature is under development
//connectionLayout->addWidget(_typeLabel, 1, 0);
//connectionLayout->addWidget(_connectionType, 1, 1, 1, 3);
//connectionLayout->addWidget(new QLabel(""), 2, 0);
connectionLayout->addWidget(_typeLabel, 1, 0);
connectionLayout->addWidget(_connectionType, 1, 1, 1, 3);
connectionLayout->addWidget(new QLabel(""), 2, 0);
connectionLayout->addWidget(_nameLabel, 3, 0);
connectionLayout->addWidget(_connectionName, 3, 1, 1, 3);
connectionLayout->addWidget(_connInfoLabel, 4, 1, 1, 3);
@@ -45,7 +45,6 @@ namespace Robomongo
QPushButton *_discoverButton;
QLabel *_readPrefLabel;
QComboBox *_readPreference;
ConnectionSettings *const _settings;
};
}
@@ -243,7 +243,6 @@ namespace Robomongo
if (state) // resize, dialog is expanding
{
setMinimumSize(560, 440);
_validateJsonButton->setHidden(_advancedOptions->currentIndex() == OPTIONS_TAB);
QSettings settings("Paralect", "Robomongo");
if (settings.contains("CreateCollectionDialog/size"))
{
@@ -258,8 +257,7 @@ namespace Robomongo
else // resize, dialog is shrinking
{
saveWindowSettings(); // save expanded geometry first
_validateJsonButton->hide();
setFixedSize(300, 150);
setMinimumSize(300, 150);
adjustSize();
}
}
+505
View File
@@ -0,0 +1,505 @@
#include "robomongo/gui/dialogs/ExportDialog.h"
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLineEdit>
#include <QTextEdit>
#include <QLabel>
#include <QDialogButtonBox>
#include <QTreeWidget>
#include <QComboBox>
#include <QGroupBox>
#include <QApplication>
#include <QProcess>
#include <QDir>
#include <QFileDialog>
#include <QDateTime>
#include <QMessageBox>
#include <QPlainTextEdit>
#include <QFileInfo>
#include <QSizePolicy>
#include <QProgressDialog>
#include "robomongo/core/utils/QtUtils.h"
#include "robomongo/core/domain/App.h"
#include "robomongo/core/AppRegistry.h"
#include "robomongo/core/domain/MongoCollection.h"
#include "robomongo/core/domain/MongoDatabase.h"
#include "robomongo/gui/widgets/explorer/ExplorerServerTreeItem.h"
#include "robomongo/gui/widgets/workarea/IndicatorLabel.h"
#include "robomongo/gui/widgets/explorer/ExplorerWidget.h"
#include "robomongo/gui/widgets/explorer/ExplorerTreeWidget.h"
#include "robomongo/gui/widgets/explorer/ExplorerServerTreeItem.h"
#include "robomongo/gui/widgets/explorer/ExplorerCollectionTreeItem.h"
#include "robomongo/gui/widgets/explorer/ExplorerDatabaseCategoryTreeItem.h"
#include "robomongo/gui/widgets/explorer/ExplorerDatabaseTreeItem.h"
#include "robomongo/gui/widgets/explorer/ExplorerReplicaSetTreeItem.h"
#include "robomongo/gui/utils/GuiConstants.h"
#include "robomongo/gui/GuiRegistry.h"
namespace Robomongo
{
//const QSize ExportDialog::dialogSize = QSize(500, 250); // todo: remove
namespace
{
const QString defaultDir = "D:\\exports\\"; // Default location
auto const AUTO_MODE_SIZE = QSize(500, 450);
auto const MANUAL_MODE_SIZE = QSize(500, 400);
auto const SHOW_DETAILS = "<a href='error' style='color: #777777;'>Show details</a>";
auto const HIDE_DETAILS = "<a href='error' style='color: #777777;'>Hide details</a>";
// This structure represents the arguments as in "mongoexport.exe --help"
// See http://docs.mongodb.org/manual/reference/program/mongoexport/ for more information
struct MongoExportArgs
{
static QString db(const QString& dbName) { return ("--db" + dbName); }
static QString collection(const QString& collection) { return ("--collection" + collection); }
// i.e. absFilePath: "/exports/coll1.json"
static QString out(const QString& absFilePath) { return ("--out " + absFilePath); }
};
}
ExportDialog::ExportDialog(QString const& dbName, QString const& collName, QWidget *parent) :
QDialog(parent), _mode(AUTO), _mongoExportArgs(), _activeProcess(nullptr)
{
setWindowTitle("Export Collection");
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); // Remove help button (?)
setMinimumSize(AUTO_MODE_SIZE);
//setFixedHeight(AUTO_MODE_SIZE.height());
_activeProcess = new QProcess(this);
//_activeProcess->setProcessChannelMode(QProcess::MergedChannels);
VERIFY(connect(_activeProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
this, SLOT(on_exportFinished(int, QProcess::ExitStatus))));
VERIFY(connect(_activeProcess, SIGNAL(errorOccurred(QProcess::ProcessError)),
this, SLOT(on_processErrorOccurred(QProcess::ProcessError))));
// todo: move to a global location
// Enable copyable text for QMessageBox
qApp->setStyleSheet("QMessageBox { messagebox-text-interaction-flags: 5; }");
const QString serverName = "localhost:20017"; // todo: remove
Indicator *serverIndicator = new Indicator(GuiRegistry::instance().serverIcon(), serverName);
// Horizontal line
QFrame *horline = new QFrame();
horline->setFrameShape(QFrame::HLine);
horline->setFrameShadow(QFrame::Sunken);
// Widgets related to Input
auto dbNameLabel = new QLabel("Database Name:");
auto dbNameLineEdit = new QLineEdit;
auto dbNameLay = new QHBoxLayout;
dbNameLay->addWidget(dbNameLabel);
dbNameLay->addWidget(dbNameLineEdit);
auto collNameLabel = new QLabel("Collection Name:");
auto collNameLineEdit = new QLineEdit;
auto collNameLay = new QHBoxLayout;
collNameLay->addWidget(collNameLabel);
collNameLay->addWidget(collNameLineEdit);
auto selectedCollLay = new QGridLayout;
selectedCollLay->setAlignment(Qt::AlignTop);
selectedCollLay->setColumnStretch(2, 1);
auto serverIcon = new QLabel("<html><img src=':/robomongo/icons/server_16x16.png'></html>");
auto dbIcon = new QLabel("<html><img src=':/robomongo/icons/database_16x16.png'></html>");
auto collIcon = new QLabel("<html><img src=':/robomongo/icons/collection_16x16.png'></html>");
selectedCollLay->addWidget(serverIcon, 1, 0);
selectedCollLay->addWidget(new QLabel("Server: "), 1, 1);
selectedCollLay->addWidget(new QLabel("local_(2)"), 1, 2);
selectedCollLay->addWidget(dbIcon, 2, 0);
selectedCollLay->addWidget(new QLabel("Database: "), 2, 1);
selectedCollLay->addWidget(new QLabel(dbName), 2, 2);
selectedCollLay->addWidget(collIcon, 3, 0);
selectedCollLay->addWidget(new QLabel("Collection: "), 3, 1);
selectedCollLay->addWidget(new QLabel(collName), 3, 2);
// Widgets related to Output
_formatComboBox = new QComboBox;
_formatComboBox->addItem("JSON");
_formatComboBox->addItem("CSV");
VERIFY(connect(_formatComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(on_formatComboBox_change(int))));
_fieldsLabel = new QLabel("Fields:");
_fields = new QLineEdit; // todo: make textedit
// Initially hidden
_fieldsLabel->setHidden(true);
_fields->setHidden(true);
_query = new QLineEdit("{}"); // todo: can use JSON frame
_outputFileName = new QLineEdit;
_outputDir = new QLineEdit;
_browseButton = new QPushButton("...");
_browseButton->setMaximumWidth(50);
VERIFY(connect(_browseButton, SIGNAL(clicked()), this, SLOT(on_browseButton_clicked())));
// Export summary widgets
_exportOutput = new QTextEdit;
QFontMetrics font(_exportOutput->font());
_exportOutput->setFixedHeight((4+1.5) * (font.lineSpacing())); // 4-line text edit
_exportOutput->setReadOnly(true);
_mongoExportOutput = new QTextEdit;
_mongoExportOutput->setFixedHeight(4 * (font.lineSpacing() + 8)); // 4-line text edit
_mongoExportOutput->setReadOnly(true);
_mongoExportOutput->setHidden(true);
// Attempt to fix issue for Windows High DPI button height is slightly taller than other widgets
#ifdef Q_OS_WIN
_browseButton->setMaximumHeight(HighDpiContants::WIN_HIGH_DPI_BUTTON_HEIGHT);
#endif
auto outputsInnerLay = new QGridLayout;
outputsInnerLay->addWidget(new QLabel("Format:"), 0, 0);
outputsInnerLay->addWidget(_formatComboBox, 0, 1, 1, 2);
outputsInnerLay->addWidget(_fieldsLabel, 1, 0, Qt::AlignTop);
outputsInnerLay->addWidget(_fields, 1, 1, 1, 2);
outputsInnerLay->addWidget(new QLabel("Query:"), 2, 0);
outputsInnerLay->addWidget(_query, 2, 1, 1, 2);
outputsInnerLay->addWidget(new QLabel("File Name:"), 3, 0);
outputsInnerLay->addWidget(_outputFileName, 3, 1, 1, 2);
outputsInnerLay->addWidget(new QLabel("Directory:"), 4, 0);
outputsInnerLay->addWidget(_outputDir, 4, 1);
outputsInnerLay->addWidget(_browseButton, 4, 2);
//outputsInnerLay->addWidget(new QLabel("Result:"), 5, 0, Qt::AlignTop);
//outputsInnerLay->addWidget(_exportOutput, 6, 0, 1, 3, Qt::AlignTop);
auto manualLayout = new QGridLayout;
auto cmdLabel = new QLabel("Command:");
cmdLabel->setFixedHeight(cmdLabel->sizeHint().height());
_manualExportCmd = new QTextEdit;
QFontMetrics font1(_manualExportCmd->font());
_manualExportCmd->setFixedHeight(2 * (font1.lineSpacing()+8)); // 2-line text edit
manualLayout->addWidget(cmdLabel, 0, 0, Qt::AlignTop);
manualLayout->addWidget(_manualExportCmd, 1, 0, Qt::AlignTop);
// Button box and Manual Mode button
_modeButton = new QPushButton("Manual Mode");
VERIFY(connect(_modeButton, SIGNAL(clicked()), this, SLOT(on_modeButton_clicked())));
_buttonBox = new QDialogButtonBox(this);
_buttonBox->setOrientation(Qt::Horizontal);
_buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Save);
_buttonBox->button(QDialogButtonBox::Save)->setText("E&xport");
_buttonBox->button(QDialogButtonBox::Save)->setMaximumWidth(70);
_buttonBox->button(QDialogButtonBox::Cancel)->setMaximumWidth(70);
VERIFY(connect(_buttonBox, SIGNAL(accepted()), this, SLOT(accept())));
VERIFY(connect(_buttonBox, SIGNAL(rejected()), this, SLOT(reject())));
// Sub layouts
auto serverIndicatorlayout = new QHBoxLayout();
if (!serverName.isEmpty()) {
serverIndicatorlayout->addWidget(serverIndicator, 0, Qt::AlignLeft);
}
// Input layout
_inputsGroupBox = new QGroupBox("Selected Collection");
_inputsGroupBox->setLayout(selectedCollLay);
_inputsGroupBox->setStyleSheet("QGroupBox::title { left: 0px }");
_inputsGroupBox->setFixedHeight(_inputsGroupBox->sizeHint().height());
// Outputs
_autoOutputsGroup = new QGroupBox("Output Properties");
_autoOutputsGroup->setLayout(outputsInnerLay);
_autoOutputsGroup->setStyleSheet("QGroupBox::title { left: 0px }");
_autoOutputsGroup->setFixedHeight(_autoOutputsGroup->sizeHint().height());
// Manual Groupbox
_manualGroupBox = new QGroupBox("Manual Export");
_manualGroupBox->setLayout(manualLayout);
_manualGroupBox->setStyleSheet("QGroupBox::title { left: 0px }");
_manualGroupBox->setHidden(true);
// Export Summary
auto exportSummaryGroup = new QGroupBox("Export Summary");
exportSummaryGroup->setStyleSheet("QGroupBox::title { left: 0px }");
_viewOutputLink = new QLabel(SHOW_DETAILS);
VERIFY(connect(_viewOutputLink, SIGNAL(linkActivated(QString)), this, SLOT(on_viewOutputLink(QString))));
_viewOutputLink->setFixedHeight(_viewOutputLink->sizeHint().height());
auto tempLayout = new QVBoxLayout();
//tempLayout->setSizeConstraint(QLayout::SetFixedSize);
tempLayout->addWidget(_exportOutput, Qt::AlignTop);
tempLayout->addWidget(_viewOutputLink, Qt::AlignLeft | Qt::AlignTop);
//tempLayout->addWidget(_mongoExportOutput);
exportSummaryGroup->setLayout(tempLayout);
exportSummaryGroup->setFixedHeight(exportSummaryGroup->sizeHint().height());
// Buttonbox layout
auto hButtonBoxlayout = new QHBoxLayout();
hButtonBoxlayout->addStretch(1);
hButtonBoxlayout->addWidget(_buttonBox);
hButtonBoxlayout->addWidget(_modeButton);
// Main Layout
auto layout = new QVBoxLayout();
layout->addWidget(_inputsGroupBox, Qt::AlignTop);
//layout->addWidget(horline, Qt::AlignTop);
layout->addWidget(_autoOutputsGroup, Qt::AlignTop);
layout->addWidget(_manualGroupBox);
layout->addWidget(exportSummaryGroup, Qt::AlignTop);
layout->addLayout(hButtonBoxlayout);
setLayout(layout);
// todo: move to function
// Help user filling inputs automatically
auto date = QDateTime::currentDateTime().toString("dd.MM.yyyy");
auto time = QDateTime::currentDateTime().toString("hh.mm.ss");
auto timeStamp = date + "_" + time;
auto format = _formatComboBox->currentIndex() == 0 ? "json" : "csv";
_outputFileName->setText(dbName + "." + collName + "_" + timeStamp + "." + format);
_outputDir->setText(defaultDir);
_manualExportCmd->setText("mongoexport --db " + dbName + " --collection " + collName +
" --out " + _outputDir->text() + _outputFileName->text());
// todo: setExportArgs()
// First set db and coll
_mongoExportArgs = " --db " + dbName + " --collection " + collName;
_outputFileName->setFocus();
}
void ExportDialog::setOkButtonText(const QString &text)
{
_buttonBox->button(QDialogButtonBox::Save)->setText(text);
}
// todo: remove
void ExportDialog::setInputLabelText(const QString &text)
{
//_inputLabel->setText(text);
}
// todo: remove
void ExportDialog::setInputText(const QString &text)
{
//_inputEdit->setText(text);
//_inputEdit->selectAll();
}
void ExportDialog::accept()
{
QString mongoExport = "D:\\mongo_export\\bin\\mongoexport.exe";
bool disable = false;
enableDisableWidgets(disable);
if (AUTO == _mode)
{
_exportOutput->clear();
_exportOutput->setText("Exporting...");
// If CSV append output format and fields
if (_formatComboBox->currentIndex() == 1) {
if (_fields->text().isEmpty()) {
QMessageBox::critical(this, "Error", "\"Fields\" option is required in CSV mode.");
return;
}
_mongoExportArgs.append(" --type=csv");
_mongoExportArgs.append(" --fields " + _fields->text().replace(" ", ""));
}
if (!_query->text().isEmpty() && _query->text() != "{}") {
_mongoExportArgs.append(" --query " + _query->text());
}
// Append file path and name
auto absFilePath = _outputDir->text() + _outputFileName->text();
_mongoExportArgs.append(" --out " + absFilePath);
// Start mongoexport non-blocking
_activeProcess->start(mongoExport + _mongoExportArgs);
}
else if (MANUAL == _mode)
{
_exportOutput->clear();
_exportOutput->setText("Exporting...");
// todo: check if _activeProcess->state() is QProcess::NotRunning
// Start mongoexport non-blocking
_activeProcess->start("D:\\mongo_export\\bin\\" + _manualExportCmd->toPlainText());
}
}
void ExportDialog::ui_itemExpanded(QTreeWidgetItem *item)
{
auto categoryItem = dynamic_cast<ExplorerDatabaseCategoryTreeItem *>(item);
if (categoryItem) {
categoryItem->expand();
return;
}
ExplorerServerTreeItem *serverItem = dynamic_cast<ExplorerServerTreeItem *>(item);
if (serverItem) {
serverItem->expand();
return;
}
auto dirItem = dynamic_cast<ExplorerCollectionDirIndexesTreeItem *>(item);
if (dirItem) {
dirItem->expand();
}
}
void ExportDialog::ui_itemDoubleClicked(QTreeWidgetItem *item, int column)
{
//auto collectionItem = dynamic_cast<ExplorerCollectionTreeItem*>(item);
//if (collectionItem) {
// AppRegistry::instance().app()->openShell(collectionItem->collection());
// return;
//}
// todo
//auto dbTreeItem = dynamic_cast<ExplorerDatabaseTreeItem*>(item);
//if (dbTreeItem) {
// dbTreeItem->applySettingsForExportDialog();
//}
}
void ExportDialog::on_browseButton_clicked()
{
// Select output directory
QString origDir = QFileDialog::getExistingDirectory(this, tr("Select Directory"), defaultDir,
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
auto dir = QDir::toNativeSeparators(origDir);
QApplication::activeModalWidget()->raise();
QApplication::activeModalWidget()->activateWindow();
if (dir.isNull())
return;
_outputDir->setText(dir + "\\");
}
void ExportDialog::on_formatComboBox_change(int index)
{
bool const isCsv = static_cast<bool>(index);
_fieldsLabel->setVisible(isCsv);
_fields->setVisible(isCsv);
// todo: divide ui_itemClicked()
//ui_itemClicked(_treeWidget->currentItem());
}
void ExportDialog::on_modeButton_clicked()
{
_exportOutput->clear();
_mode = (AUTO == _mode ? MANUAL : AUTO);
_modeButton->setText(AUTO == _mode ? "Manual Mode" : "Auto Mode");
_autoOutputsGroup->setVisible(AUTO == _mode);
_manualGroupBox->setVisible(MANUAL == _mode);
setMinimumSize(AUTO == _mode ? AUTO_MODE_SIZE : MANUAL_MODE_SIZE);
_inputsGroupBox->setTitle(AUTO == _mode ? "Selected Collection" : "Selected Server");
adjustSize();
}
void ExportDialog::on_exportFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
bool enable = true;
enableDisableWidgets(enable);
// Extract absolute file path
QString absFilePath;
if (AUTO == _mode)
{
absFilePath = _outputDir->text() + _outputFileName->text();
}
else if (MANUAL == _mode)
{
// extract absolute file path string
QStringList strlist1 = _manualExportCmd->toPlainText().split("--out");
if (strlist1.size() > 1) {
QString str1 = strlist1[1];
QStringList strlist2 = str1.split("--");
if (strlist2.size() > 1) {
absFilePath = strlist2[0];
}
else {
absFilePath = str1;
}
}
}
absFilePath.replace(" ", ""); // todo: handle paths with white spaces
// todo: also check process exit code
// Check exported file exists and mongoexport output does not contain error
QFileInfo const file(absFilePath);
_mongoExportOutputStr = _activeProcess->readAllStandardError(); // Extract mongoexport command output
if (file.exists() && file.isFile() && _mongoExportOutputStr.contains("exported")) {
QStringList splitA = _mongoExportOutputStr.split("exported");
QStringList splitB = splitA[1].split("records");
_exportResult = "Export Successful: \n"
"Exported file: " + absFilePath + "\n"
"Number of records exported:" + splitB[0];
_exportOutput->setText(_exportResult);
}
else {
_exportOutput->setText("Export Failed.\n");
_exportOutput->append("Output:\n" + _mongoExportOutputStr);
}
_exportOutput->moveCursor(QTextCursor::Start);
}
void ExportDialog::on_processErrorOccurred(QProcess::ProcessError error)
{
bool enable = true;
enableDisableWidgets(enable);
if (QProcess::FailedToStart == error) {
_exportOutput->setText("Error: \"mongoexport\" process failed to start. Either the "
"invoked program is missing, or you may have insufficient permissions to invoke the program.");
}
else if (QProcess::Crashed == error) {
_exportOutput->setText("Error: \"mongoexport\" process crashed some time after starting"
" successfully..");
}
else {
_exportOutput->setText("Error: \"mongoexport\" process failed. Error code: "
+ QString::number(error));
}
_exportOutput->moveCursor(QTextCursor::Start);
}
void ExportDialog::on_viewOutputLink(QString)
{
QMessageBox::information(this, "Details", _mongoExportOutputStr);
}
Indicator *ExportDialog::createDatabaseIndicator(const QString &database)
{
return new Indicator(GuiRegistry::instance().databaseIcon(), database);
}
Indicator *ExportDialog::createCollectionIndicator(const QString &collection)
{
return new Indicator(GuiRegistry::instance().collectionIcon(), collection);
}
void ExportDialog::enableDisableWidgets(bool enable) const
{
// Auto mode widgets
//_treeWidget->setEnabled(enable);
_formatComboBox->setEnabled(enable);
_fieldsLabel->setEnabled(enable);
_fields->setEnabled(enable);
_query->setEnabled(enable);
_outputFileName->setEnabled(enable);
_outputDir->setEnabled(enable);
_browseButton->setEnabled(enable);
_buttonBox->button(QDialogButtonBox::Save)->setEnabled(enable);
_modeButton->setEnabled(enable);
// Manual mode widgets
//_treeWidget->setEnabled(enable);
_manualExportCmd->setEnabled(enable);
_buttonBox->button(QDialogButtonBox::Save)->setEnabled(enable);
_modeButton->setEnabled(enable);
}
}
+94
View File
@@ -0,0 +1,94 @@
#pragma once
#include <QDialog>
#include <QProcess>
QT_BEGIN_NAMESPACE
class QLabel;
class QDialogButtonBox;
class QLineEdit;
class QTreeWidgetItem;
class QTreeWidget;
class QComboBox;
class QPushButton;
class QGroupBox;
class QTextEdit;
class QProcess;
QT_END_NAMESPACE
namespace Robomongo
{
class Indicator;
class ExportDialog : public QDialog
{
Q_OBJECT
enum MODE
{
AUTO = 0,
MANUAL = 1
};
public:
explicit ExportDialog(QString const& dbName, QString const& collName, QWidget *parent = 0);
//QString databaseName() const;
void setOkButtonText(const QString &text);
void setInputLabelText(const QString &text);
void setInputText(const QString &text);
enum { maxLenghtName = 60 };
//const static QSize dialogSize;
public Q_SLOTS:
virtual void accept();
private Q_SLOTS:
void ui_itemExpanded(QTreeWidgetItem *item);
void ui_itemDoubleClicked(QTreeWidgetItem *item, int column);
void on_browseButton_clicked();
void on_formatComboBox_change(int index);
void on_modeButton_clicked();
void on_exportFinished(int exitCode, QProcess::ExitStatus exitStatus);
void on_processErrorOccurred(QProcess::ProcessError);
void on_viewOutputLink(QString);
private:
// todo: remove
Indicator *createDatabaseIndicator(const QString &database);
Indicator *createCollectionIndicator(const QString &collection);
// Enable/Disable widgets during/after export operation
// @param enable: true to enable, false to disable widgets
void enableDisableWidgets(bool enable) const;
// Auto Mode
QGroupBox* _inputsGroupBox;
QComboBox* _formatComboBox;
QLabel* _fieldsLabel;
QLineEdit* _fields;
QLineEdit* _query;
QLineEdit* _outputFileName;
QLineEdit* _outputDir;
QPushButton* _browseButton;
QGroupBox* _autoOutputsGroup;
QTextEdit* _exportOutput;
QLabel* _viewOutputLink;
//
QTextEdit* _mongoExportOutput;
// Manual Mode
QTextEdit* _manualExportCmd;
QPushButton* _modeButton;
QGroupBox* _manualGroupBox;
// Common
QDialogButtonBox* _buttonBox;
MODE _mode;
QString _dbName;
QString _collName;
QString _mongoExportArgs;
QString _exportResult;
QString _mongoExportOutputStr;
QProcess* _activeProcess; // pointer to running/finished process
};
}
+2 -4
View File
@@ -20,10 +20,6 @@
<file>scripts/esprima.js</file>
<file>scripts/uuidhelpers.js</file>
<file>icons/maximize.gif</file>
<file>icons/undock.png</file>
<file>icons/dock.png</file>
<file>icons/maximize.png</file>
<file>icons/minimize.png</file>
<file>icons/text_16x16.png</file>
<file>icons/tree_16x16.png</file>
<file>icons/rotate_16x16.png</file>
@@ -66,5 +62,7 @@
<file>icons/index_16x16.png</file>
<file>icons/hide_64x64.png</file>
<file>icons/show_64x64.png</file>
<file>icons/export_64x64.png</file>
<file>icons/import_64x64.png</file>
</qresource>
</RCC>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 B

@@ -35,6 +35,7 @@ namespace Robomongo
R_REGISTER_EVENT(CollectionIndexesLoadingEvent)
const QString ExplorerCollectionDirIndexesTreeItem::labelText = "Indexes";
/* ------------ Class ExplorerCollectionDirIndexesTreeItem ------------ */
ExplorerCollectionDirIndexesTreeItem::ExplorerCollectionDirIndexesTreeItem(QTreeWidgetItem *parent)
:BaseClass(parent)
{
@@ -200,6 +201,8 @@ namespace Robomongo
}
}
/* ------------ Class ExplorerCollectionTreeItem ------------ */
ExplorerCollectionTreeItem::ExplorerCollectionTreeItem(QTreeWidgetItem *parent, ExplorerDatabaseTreeItem *databaseItem, MongoCollection *collection) :
BaseClass(parent), _collection(collection), _databaseItem(databaseItem)
{
@@ -267,13 +270,12 @@ namespace Robomongo
AppRegistry::instance().bus()->subscribe(_databaseItem, LoadCollectionIndexesResponse::Type, this);
AppRegistry::instance().bus()->subscribe(_databaseItem, DeleteCollectionIndexResponse::Type, this);
AppRegistry::instance().bus()->subscribe(this, CollectionIndexesLoadingEvent::Type, this);
setText(0, QtUtils::toQString(_collection->name()));
setIcon(0, GuiRegistry::instance().collectionIcon());
_indexDir = new ExplorerCollectionDirIndexesTreeItem(this);
addChild(_indexDir);
// setToolTip(0, buildToolTip(collection));
setExpanded(false);
setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
@@ -98,11 +98,11 @@ namespace Robomongo
_collectionFolderItem->setIcon(0, GuiRegistry::instance().folderIcon());
addChild(_collectionFolderItem);
_javascriptFolderItem = new ExplorerDatabaseCategoryTreeItem(this, Functions);
_javascriptFolderItem->setText(0, "Functions");
_javascriptFolderItem->setIcon(0, GuiRegistry::instance().folderIcon());
addChild(_javascriptFolderItem);
_functionsFolderItem = new ExplorerDatabaseCategoryTreeItem(this, Functions);
_functionsFolderItem->setText(0, "Functions");
_functionsFolderItem->setIcon(0, GuiRegistry::instance().folderIcon());
addChild(_functionsFolderItem);
_usersFolderItem = new ExplorerDatabaseCategoryTreeItem(this, Users);
_usersFolderItem->setText(0, "Users");
_usersFolderItem->setIcon(0, GuiRegistry::instance().folderIcon());
@@ -218,8 +218,8 @@ namespace Robomongo
void ExplorerDatabaseTreeItem::handle(MongoDatabaseFunctionsLoadedEvent *event)
{
if (event->isError()) {
_javascriptFolderItem->setText(0, "Functions");
_javascriptFolderItem->setExpanded(false);
_functionsFolderItem->setText(0, "Functions");
_functionsFolderItem->setExpanded(false);
std::stringstream ss;
ss << "Cannot load list of functions.\n\nError:\n" << event->error().errorMessage();
@@ -230,13 +230,13 @@ namespace Robomongo
std::vector<MongoFunction> functions = event->functions();
int count = functions.size();
_javascriptFolderItem->setText(0, detail::buildName("Functions", count));
_functionsFolderItem->setText(0, detail::buildName("Functions", count));
// Do not expand, when we do not have functions
if (count == 0)
_javascriptFolderItem->setExpanded(false);
_functionsFolderItem->setExpanded(false);
QtUtils::clearChildItems(_javascriptFolderItem);
QtUtils::clearChildItems(_functionsFolderItem);
for (int i = 0; i < functions.size(); ++i) {
MongoFunction fun = functions[i];
@@ -251,7 +251,7 @@ namespace Robomongo
void ExplorerDatabaseTreeItem::handle(MongoDatabaseFunctionsLoadingEvent *event)
{
_javascriptFolderItem->setText(0, detail::buildName("Functions", -1));
_functionsFolderItem->setText(0, detail::buildName("Functions", -1));
}
void ExplorerDatabaseTreeItem::handle(MongoDatabaseUsersLoadingEvent *event)
@@ -261,13 +261,15 @@ namespace Robomongo
void ExplorerDatabaseTreeItem::addCollectionItem(MongoCollection *collection)
{
ExplorerCollectionTreeItem *collectionItem = new ExplorerCollectionTreeItem(_collectionFolderItem, this, collection);
auto collectionItem = new ExplorerCollectionTreeItem(_collectionFolderItem, this, collection);
collectionItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_collectionFolderItem->addChild(collectionItem);
}
void ExplorerDatabaseTreeItem::addSystemCollectionItem(MongoCollection *collection)
{
ExplorerCollectionTreeItem *collectionItem = new ExplorerCollectionTreeItem(_collectionSystemFolderItem, this, collection);
auto collectionItem = new ExplorerCollectionTreeItem(_collectionSystemFolderItem, this, collection);
collectionItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
_collectionSystemFolderItem->addChild(collectionItem);
}
@@ -284,8 +286,8 @@ namespace Robomongo
void ExplorerDatabaseTreeItem::addFunctionItem(MongoDatabase *database, const MongoFunction &function)
{
ExplorerFunctionTreeItem *functionItem = new ExplorerFunctionTreeItem(_javascriptFolderItem, database, function);
_javascriptFolderItem->addChild(functionItem);
ExplorerFunctionTreeItem *functionItem = new ExplorerFunctionTreeItem(_functionsFolderItem, database, function);
_functionsFolderItem->addChild(functionItem);
}
void ExplorerDatabaseTreeItem::ui_refreshDatabase()
@@ -68,7 +68,7 @@ namespace Robomongo
EventBus *_bus;
ExplorerDatabaseCategoryTreeItem *_collectionFolderItem;
ExplorerDatabaseCategoryTreeItem *_javascriptFolderItem;
ExplorerDatabaseCategoryTreeItem *_functionsFolderItem;
ExplorerDatabaseCategoryTreeItem *_usersFolderItem;
ExplorerTreeItem *_collectionSystemFolderItem;
MongoDatabase *const _database;
@@ -13,6 +13,7 @@
#include "robomongo/core/utils/QtUtils.h"
#include "robomongo/core/AppRegistry.h"
#include "robomongo/core/EventBus.h"
#include "robomongo/gui/widgets/explorer/ExplorerDatabaseTreeItem.h"
#include "robomongo/gui/dialogs/CreateDatabaseDialog.h"
#include "robomongo/gui/GuiRegistry.h"
@@ -20,8 +21,8 @@
namespace
{
// todo : modify or move to a common header
void openCurrentServerShell(Robomongo::ConnectionSettings const *connSettings, const QString &script)
// todo : modify or move to common header
void openCurrentServerShell(Robomongo::ConnectionSettings* connSettings, const QString &script)
{
auto const scriptStr = Robomongo::ScriptInfo(script, true);
Robomongo::AppRegistry::instance().app()->openShell(connSettings, scriptStr);
@@ -80,7 +81,6 @@ namespace Robomongo
BaseClass::_contextMenu->addSeparator();
BaseClass::_contextMenu->addAction(showLog);
// Todo: remove ?
//_bus->subscribe(this, DatabaseListLoadedEvent::Type, _server);
//_bus->subscribe(this, MongoServerLoadingDatabasesEvent::Type, _server);
@@ -25,7 +25,6 @@ namespace Robomongo
ConnectionSettings const* connectionSettings() const { return _connSettings.get(); }
public Q_SLOTS:
// Todo: remove or update
//void databaseRefreshed(const QList<MongoDatabase *> &dbs);
//void handle(DatabaseListLoadedEvent *event);
//void handle(MongoServerLoadingDatabasesEvent *event);
@@ -109,7 +109,6 @@ namespace Robomongo
auto const& repMembers = repSetSettings->membersToHostAndPort();
bool isPrimary;
auto const& repMembersHealths = _server->getRepMembersHealths();
// todo: refactor loop to do without "i"
for (int i = 0; i < repMembers.size() && i < repMembersHealths.size(); ++i)
{
isPrimary = (_server->getRepPrimary() == repMembers[i]);
@@ -9,6 +9,7 @@
#include "robomongo/core/domain/App.h"
#include "robomongo/core/utils/QtUtils.h"
#include "robomongo/gui/MainWindow.h"
#include "robomongo/gui/widgets/explorer/ExplorerTreeWidget.h"
#include "robomongo/gui/widgets/explorer/ExplorerServerTreeItem.h"
#include "robomongo/gui/widgets/explorer/ExplorerCollectionTreeItem.h"
@@ -18,7 +19,7 @@
namespace Robomongo
{
ExplorerWidget::ExplorerWidget(QWidget *parent) : BaseClass(parent),
ExplorerWidget::ExplorerWidget(MainWindow *parentMainWindow) : BaseClass(parentMainWindow),
_progress(0)
{
_treeWidget = new ExplorerTreeWidget(this);
@@ -28,7 +29,10 @@ namespace Robomongo
vlaout->addWidget(_treeWidget, Qt::AlignJustify);
VERIFY(connect(_treeWidget, SIGNAL(itemExpanded(QTreeWidgetItem *)), this, SLOT(ui_itemExpanded(QTreeWidgetItem *))));
VERIFY(connect(_treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(ui_itemDoubleClicked(QTreeWidgetItem *, int))));
VERIFY(connect(_treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
this, SLOT(ui_itemDoubleClicked(QTreeWidgetItem *, int))));
VERIFY(connect(_treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
parentMainWindow, SLOT(onExplorerItemSelected(QTreeWidgetItem *))));
setLayout(vlaout);
@@ -39,6 +43,11 @@ namespace Robomongo
movie->start();
}
QTreeWidgetItem* ExplorerWidget::getSelectedTreeItem() const
{
return _treeWidget->currentItem();
}
void ExplorerWidget::keyPressEvent(QKeyEvent *event)
{
if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Enter))
@@ -137,7 +146,8 @@ namespace Robomongo
auto replicaMemberItem = dynamic_cast<ExplorerReplicaSetTreeItem*>(item);
if (replicaMemberItem) {
AppRegistry::instance().app()->openShell(replicaMemberItem->connectionSettings(), ScriptInfo("", true));
auto const scriptStr = Robomongo::ScriptInfo("", true);
AppRegistry::instance().app()->openShell(replicaMemberItem->connectionSettings(), scriptStr);
return;
}
@@ -11,6 +11,8 @@ QT_END_NAMESPACE
namespace Robomongo
{
class MainWindow;
/**
* @brief Explorer widget (usually you'll see it at the left of main window)
*/
@@ -20,7 +22,8 @@ namespace Robomongo
public:
typedef QWidget BaseClass;
ExplorerWidget(QWidget *parent);
ExplorerWidget(MainWindow *parent);
QTreeWidgetItem* getSelectedTreeItem() const;
protected Q_SLOTS:
void handle(ConnectingEvent *event);
@@ -23,8 +23,7 @@
namespace Robomongo
{
OutputItemContentWidget::OutputItemContentWidget(ViewMode viewMode, MongoShell *shell, const QString &text, double secs,
bool multipleResults, bool firstItem, bool lastItem, QWidget *parent) :
OutputItemContentWidget::OutputItemContentWidget(OutputWidget *out, ViewMode viewMode, MongoShell *shell, const QString &text, double secs, QWidget *parent) :
BaseClass(parent),
_textView(NULL),
_bsonTreeview(NULL),
@@ -41,18 +40,16 @@ namespace Robomongo
_isFirstPartRendered(false),
_text(text),
_shell(shell),
_outputWidget(dynamic_cast<OutputWidget*>(parentWidget())),
_initialSkip(0),
_initialLimit(0),
_out(out),
_mod(NULL),
_viewMode(viewMode)
{
setup(secs, multipleResults, firstItem, lastItem);
setup(secs);
}
OutputItemContentWidget::OutputItemContentWidget(ViewMode viewMode, MongoShell *shell, const QString &type,
const std::vector<MongoDocumentPtr> &documents, const MongoQueryInfo &queryInfo,
double secs, bool multipleResults, bool firstItem, bool lastItem, QWidget *parent) :
OutputItemContentWidget::OutputItemContentWidget(OutputWidget *out, ViewMode viewMode, MongoShell *shell, const QString &type, const std::vector<MongoDocumentPtr> &documents, const MongoQueryInfo &queryInfo, double secs, QWidget *parent) :
BaseClass(parent),
_textView(NULL),
_bsonTreeview(NULL),
@@ -73,17 +70,17 @@ namespace Robomongo
_shell(shell),
_initialSkip(queryInfo._skip),
_initialLimit(queryInfo._limit),
_outputWidget(dynamic_cast<OutputWidget*>(parentWidget())),
_out(out),
_mod(NULL),
_viewMode(viewMode)
{
setup(secs, multipleResults, firstItem, lastItem);
setup(secs);
}
void OutputItemContentWidget::setup(double secs, bool multipleResults, bool firstItem, bool lastItem)
void OutputItemContentWidget::setup(double secs)
{
setContentsMargins(0, 0, 0, 0);
_header = new OutputItemHeaderWidget(this, multipleResults, firstItem, lastItem);
_header = new OutputItemHeaderWidget(this);
if (_queryInfo._info.isValid()) {
_header->setCollection(QtUtils::toQString(_queryInfo._info._ns.collectionName()));
@@ -167,8 +164,8 @@ namespace Robomongo
info._limit = limit;
info._skip = skip;
info._batchSize = batchSize;
_outputWidget->showProgress();
_shell->query(_outputWidget->resultIndex(this), info);
_out->showProgress();
_shell->query(_out->resultIndex(this), info);
}
void OutputItemContentWidget::update(const MongoQueryInfo &inf, const std::vector<MongoDocumentPtr> &documents)
@@ -315,16 +312,6 @@ namespace Robomongo
_isTableModeInitialized = false;
}
void OutputItemContentWidget::applyDockUndockSettings(bool isDocking) const
{
_header->applyDockUndockSettings(isDocking);
}
void OutputItemContentWidget::toggleOrientation(Qt::Orientation orientation) const
{
_header->toggleOrientation(orientation);
}
void OutputItemContentWidget::jsonPartReady(const QString &json)
{
// check that this is our current thread
@@ -25,11 +25,8 @@ namespace Robomongo
public:
typedef QWidget BaseClass;
OutputItemContentWidget(ViewMode viewMode, MongoShell *shell, const QString &text, double secs,
bool multipleResults, bool firstItem, bool lastItem, QWidget *parent);
OutputItemContentWidget(ViewMode viewMode, MongoShell *shell, const QString &type,
const std::vector<MongoDocumentPtr> &documents, const MongoQueryInfo &queryInfo,
double secs, bool multipleResults, bool firstItem, bool lastItem, QWidget *parent);
OutputItemContentWidget(OutputWidget *out, ViewMode viewMode, MongoShell *shell, const QString &text, double secs, QWidget *parent = NULL);
OutputItemContentWidget(OutputWidget *out, ViewMode viewMode, MongoShell *shell, const QString &type, const std::vector<MongoDocumentPtr> &documents, const MongoQueryInfo &queryInfo, double secs, QWidget *parent = NULL);
int _initialSkip;
int _initialLimit;
void update(const MongoQueryInfo &inf, const std::vector<MongoDocumentPtr> &documents);
@@ -42,9 +39,6 @@ namespace Robomongo
void refreshOutputItem();
void markUninitialized();
void applyDockUndockSettings(bool isDocking) const;
void toggleOrientation(Qt::Orientation orientation) const;
Q_SIGNALS:
void restoredSize();
void maximizedPart();
@@ -62,7 +56,7 @@ namespace Robomongo
void paging_leftClicked(int skip, int limit);
private:
void setup(double secs, bool multipleResults, bool firstItem, bool lastItem);
void setup(double secs);
FindFrame *configureLogText();
BsonTreeModel *configureModel();
@@ -82,7 +76,7 @@ namespace Robomongo
MongoShell *_shell;
OutputItemHeaderWidget *_header;
OutputWidget *_outputWidget;
OutputWidget *_out;
bool _isTextModeSupported;
bool _isTreeModeSupported;
bool _isTableModeSupported;
@@ -7,8 +7,6 @@
#include "robomongo/core/utils/QtUtils.h"
#include "robomongo/gui/GuiRegistry.h"
#include "robomongo/gui/widgets/workarea/QueryWidget.h"
#include "robomongo/gui/widgets/workarea/OutputWidget.h"
#include "robomongo/gui/widgets/workarea/OutputItemContentWidget.h"
#include "robomongo/gui/widgets/workarea/IndicatorLabel.h"
#include "robomongo/core/AppRegistry.h"
@@ -29,16 +27,19 @@ namespace
namespace Robomongo
{
OutputItemHeaderWidget::OutputItemHeaderWidget(OutputItemContentWidget *outputItemContentWidget, bool multipleResults,
bool firstItem, bool lastItem, QWidget *parent) :
OutputItemHeaderWidget::OutputItemHeaderWidget(OutputItemContentWidget *output, QWidget *parent) :
QFrame(parent),
_maxButton(nullptr), _dockUndockButton(nullptr), _maximized(false), _multipleResults(multipleResults),
_firstItem(firstItem), _lastItem(lastItem), _orientation(Qt::Vertical)
_maximized(false)
{
setContentsMargins(5, 0, 0, 0);
auto const* outputWidget = qobject_cast<OutputWidget*>(outputItemContentWidget->parentWidget());
_orientation = outputWidget->getOrientation();
// Maximize button
_maxButton = new QPushButton;
_maxButton->setIcon(GuiRegistry::instance().maximizeIcon());
_maxButton->setToolTip("Maximize or restore back this output result. You also can double-click on result's header.");
_maxButton->setFixedSize(18, 18);
_maxButton->setFlat(true);
VERIFY(connect(_maxButton, SIGNAL(clicked()), this, SLOT(maximizePart())));
// Text mode button
_textButton = new QPushButton(this);
@@ -77,30 +78,10 @@ namespace Robomongo
_customButton->setFlat(true);
_customButton->setCheckable(true);
// Create maximize button only if there are multiple results
if (_multipleResults) {
_maxButton = new QPushButton;
_maxButton->setIcon(GuiRegistry::instance().maximizeIcon());
_maxButton->setToolTip("Maximize this output result (double-click on result's header)");
_maxButton->setFixedSize(18, 18);
_maxButton->setFlat(true);
VERIFY(connect(_maxButton, SIGNAL(clicked()), this, SLOT(maximizeMinimizePart())));
}
auto dockWidget = qobject_cast<QueryWidget::CustomDockWidget*>(outputItemContentWidget->parentWidget()->parentWidget());
auto queryWidget = dockWidget->getParentQueryWidget();
_dockUndockButton = new QPushButton;
_dockUndockButton->setFixedSize(18, 18);
_dockUndockButton->setFlat(true);
_dockUndockButton->setHidden(true);
applyDockUndockSettings(!dockWidget->isFloating());
VERIFY(connect(_dockUndockButton, SIGNAL(clicked()), queryWidget, SLOT(dockUndock())));
VERIFY(connect(_textButton, SIGNAL(clicked()), outputItemContentWidget, SLOT(showText())));
VERIFY(connect(_treeButton, SIGNAL(clicked()), outputItemContentWidget, SLOT(showTree())));
VERIFY(connect(_tableButton, SIGNAL(clicked()), outputItemContentWidget, SLOT(showTable())));
VERIFY(connect(_customButton, SIGNAL(clicked()), outputItemContentWidget, SLOT(showCustom())));
VERIFY(connect(_textButton, SIGNAL(clicked()), output, SLOT(showText())));
VERIFY(connect(_treeButton, SIGNAL(clicked()), output, SLOT(showTree())));
VERIFY(connect(_tableButton, SIGNAL(clicked()), output, SLOT(showTable())));
VERIFY(connect(_customButton, SIGNAL(clicked()), output, SLOT(showCustom())));
_collectionIndicator = new Indicator(GuiRegistry::instance().collectionIcon());
_timeIndicator = new Indicator(GuiRegistry::instance().timeIcon());
@@ -122,49 +103,33 @@ namespace Robomongo
layout->addWidget(createVerticalLine());
layout->addSpacing(2);
if (outputItemContentWidget->isCustomModeSupported()) {
if (output->isCustomModeSupported()) {
layout->addWidget(_customButton, 0, Qt::AlignRight);
_customButton->show();
}
if (outputItemContentWidget->isTreeModeSupported()) {
if (output->isTreeModeSupported()) {
layout->addWidget(_treeButton, 0, Qt::AlignRight);
_treeButton->show();
}
if (outputItemContentWidget->isTableModeSupported()) {
if (output->isTableModeSupported()) {
layout->addWidget(_tableButton, 0, Qt::AlignRight);
_tableButton->show();
}
if (outputItemContentWidget->isTextModeSupported())
if (output->isTextModeSupported())
layout->addWidget(_textButton, 0, Qt::AlignRight);
if (_multipleResults) {
layout->addWidget(_maxButton, 0, Qt::AlignRight);
}
layout->addSpacing(3);
_verticalLine = createVerticalLine();
_verticalLine->setHidden(true);
layout->addWidget(_verticalLine);
layout->addWidget(_dockUndockButton);
layout->addWidget(createVerticalLine());
layout->addWidget(_maxButton, 0, Qt::AlignRight);
setLayout(layout);
// Update dock/undock button visibility
if (_multipleResults) {
updateDockButtonOnToggleOrientation();
}
else {
_verticalLine->setVisible(true);
_dockUndockButton->setVisible(true);
}
}
void OutputItemHeaderWidget::mouseDoubleClickEvent(QMouseEvent *)
{
maximizeMinimizePart();
maximizePart();
}
void OutputItemHeaderWidget::showText()
@@ -215,27 +180,6 @@ namespace Robomongo
_customButton->setChecked(true);
}
void OutputItemHeaderWidget::applyDockUndockSettings(bool isDocking)
{
if (isDocking) {
_dockUndockButton->setIcon(GuiRegistry::instance().undockIcon());
_dockUndockButton->setToolTip("Undock into separate window");
}
else {
_dockUndockButton->setIcon(GuiRegistry::instance().dockIcon());
_dockUndockButton->setToolTip("Dock into main window");
}
}
void OutputItemHeaderWidget::toggleOrientation(Qt::Orientation orientation)
{
if (!_firstItem && !_lastItem)
return;
_orientation = orientation;
updateDockButtonOnToggleOrientation();
}
void OutputItemHeaderWidget::setTime(const QString &time)
{
_timeIndicator->setVisible(!time.isEmpty());
@@ -248,47 +192,20 @@ namespace Robomongo
_collectionIndicator->setText(collection);
}
void OutputItemHeaderWidget::maximizeMinimizePart()
void OutputItemHeaderWidget::maximizePart()
{
// No maximize/minimize behaviour if there is only one query result
if (!_multipleResults) {
return;
}
if (_maximized) { // restoring original size
if (_maximized) {
//item->_output->restoreSize();
emit restoredSize();
_maxButton->setIcon(GuiRegistry::instance().maximizeIcon());
_maxButton->setToolTip("Maximize this output result (double-click on result header)");
updateDockButtonOnToggleOrientation();
}
else { // maximizing
else {
//item->_output->maximizePart(item);
emit maximizedPart();
_maxButton->setIcon(GuiRegistry::instance().minimizeIcon());
_maxButton->setToolTip("Restore back to original size (double-click on result header)");
_verticalLine->setVisible(true);
_dockUndockButton->setVisible(true);
_maxButton->setIcon(GuiRegistry::instance().maximizeHighlightedIcon());
}
_maximized = !_maximized;
}
void OutputItemHeaderWidget::updateDockButtonOnToggleOrientation() const
{
if (!_multipleResults)
return;
if (_firstItem) {
_verticalLine->setVisible(Qt::Vertical == _orientation);
_dockUndockButton->setVisible(Qt::Vertical == _orientation);
}
else if (_lastItem) {
_verticalLine->setVisible(Qt::Horizontal == _orientation);
_dockUndockButton->setVisible(Qt::Horizontal == _orientation);
}
else {
_verticalLine->setVisible(false);
_dockUndockButton->setVisible(false);
}
}
}
@@ -19,15 +19,12 @@ namespace Robomongo
Q_OBJECT
public:
OutputItemHeaderWidget(OutputItemContentWidget *output, bool multipleResults, bool firstItem, bool lastItem,
QWidget *parent = nullptr);
OutputItemHeaderWidget(OutputItemContentWidget *output, QWidget *parent = 0);
PagingWidget *paging() const { return _paging; }
void showText();
void showTree();
void showTable();
void showCustom();
void applyDockUndockSettings(bool docking);
void toggleOrientation(Qt::Orientation orientation);
protected:
virtual void mouseDoubleClickEvent(QMouseEvent *);
@@ -39,26 +36,17 @@ namespace Robomongo
public Q_SLOTS:
void setTime(const QString &time);
void setCollection(const QString &collection);
void maximizeMinimizePart();
void maximizePart();
private:
void updateDockButtonOnToggleOrientation() const;
QPushButton *_textButton;
QPushButton *_treeButton;
QPushButton *_tableButton;
QPushButton *_customButton;
QPushButton *_maxButton;
QFrame *_verticalLine;
QPushButton *_dockUndockButton;
Indicator *_collectionIndicator;
Indicator *_timeIndicator;
PagingWidget *_paging;
bool _maximized;
bool _multipleResults;
bool _firstItem;
bool _lastItem;
Qt::Orientation _orientation;
};
}
@@ -14,8 +14,9 @@ namespace Robomongo
{
OutputWidget::OutputWidget(QWidget *parent) :
QFrame(parent),
_splitter(new QSplitter)
_splitter(NULL)
{
_splitter = new QSplitter;
_splitter->setOrientation(Qt::Vertical);
_splitter->setHandleWidth(1);
_splitter->setContentsMargins(0, 0, 0, 0);
@@ -34,13 +35,11 @@ namespace Robomongo
if (_prevResultsCount > 0) {
clearAllParts();
}
int const RESULTS_SIZE = _prevResultsCount = results.size();
bool const multipleResults = (RESULTS_SIZE > 1);
int count = _prevResultsCount = results.size();
_outputItemContentWidgets.clear();
for (int i = 0; i < RESULTS_SIZE; ++i) {
for (int i = 0; i<count; ++i) {
MongoShellResult shellResult = results[i];
OutputItemContentWidget *output = NULL;
double secs = shellResult.elapsedMs() / 1000.f;
ViewMode viewMode = AppRegistry::instance().settingsManager()->viewMode();
@@ -49,22 +48,14 @@ namespace Robomongo
_prevViewModes.pop_back();
}
bool const firstItem = (0 == i);
bool const lastItem = (RESULTS_SIZE-1 == i);
OutputItemContentWidget* item = nullptr;
if (shellResult.documents().size() > 0) {
item = new OutputItemContentWidget(viewMode, shell, QtUtils::toQString(shellResult.type()),
shellResult.documents(), shellResult.queryInfo(), secs, multipleResults,
firstItem, lastItem, this);
output = new OutputItemContentWidget(this, viewMode, shell, QtUtils::toQString(shellResult.type()), shellResult.documents(), shellResult.queryInfo(), secs);
} else {
item = new OutputItemContentWidget(viewMode, shell, QtUtils::toQString(shellResult.response()), secs,
multipleResults, firstItem, lastItem, this);
output = new OutputItemContentWidget(this, viewMode, shell, QtUtils::toQString(shellResult.response()), secs);
}
VERIFY(connect(item, SIGNAL(maximizedPart()), this, SLOT(maximizePart())));
VERIFY(connect(item, SIGNAL(restoredSize()), this, SLOT(restoreSize())));
_splitter->addWidget(item);
_outputItemContentWidgets.push_back(item);
VERIFY(connect(output, SIGNAL(maximizedPart()), this, SLOT(maximizePart())));
VERIFY(connect(output, SIGNAL(restoredSize()), this, SLOT(restoreSize())));
_splitter->addWidget(output);
}
tryToMakeAllPartsEqualInSize();
@@ -75,22 +66,17 @@ namespace Robomongo
if (partIndex >= _splitter->count())
return;
auto outputItemContentWidget = qobject_cast<OutputItemContentWidget*>(_splitter->widget(partIndex));
outputItemContentWidget->update(queryInfo, documents);
outputItemContentWidget->refreshOutputItem();
OutputItemContentWidget *output = (OutputItemContentWidget *) _splitter->widget(partIndex);
output->update(queryInfo, documents);
output->refreshOutputItem();
}
void OutputWidget::toggleOrientation()
{
bool const horizontal = _splitter->orientation() == Qt::Horizontal;
_splitter->setOrientation(horizontal ? Qt::Vertical : Qt::Horizontal);
int const COUNT = _splitter->count();
if (COUNT > 1) {
auto const* firstItem = qobject_cast<OutputItemContentWidget*>(_splitter->widget(0));
auto const* lastItem = qobject_cast<OutputItemContentWidget*>(_splitter->widget(COUNT-1));
firstItem->toggleOrientation(_splitter->orientation());
lastItem->toggleOrientation(_splitter->orientation());
}
if (_splitter->orientation() == Qt::Horizontal)
_splitter->setOrientation(Qt::Vertical);
else
_splitter->setOrientation(Qt::Horizontal);
}
void OutputWidget::enterTreeMode()
@@ -168,18 +154,6 @@ namespace Robomongo
_progressBarPopup->hide();
}
void OutputWidget::applyDockUndockSettings(bool isDocking) const
{
for (auto const& item : _outputItemContentWidgets) {
item->applyDockUndockSettings(isDocking);
}
}
Qt::Orientation OutputWidget::getOrientation() const
{
return _splitter->orientation();
}
void OutputWidget::clearAllParts()
{
_prevViewModes.clear();
@@ -19,7 +19,7 @@ namespace Robomongo
Q_OBJECT
public:
explicit OutputWidget(QWidget *parent);
explicit OutputWidget(QWidget *parent = 0);
void present(MongoShell *shell, const std::vector<MongoShellResult> &documents);
void updatePart(int partIndex, const MongoQueryInfo &queryInfo, const std::vector<MongoDocumentPtr> &documents);
@@ -31,13 +31,11 @@ namespace Robomongo
void enterCustomMode();
int resultIndex(OutputItemContentWidget *result);
void showProgress();
void hideProgress();
void applyDockUndockSettings(bool isDocking) const;
Qt::Orientation getOrientation() const;
private Q_SLOTS:
void restoreSize();
void maximizePart();
@@ -48,6 +46,5 @@ namespace Robomongo
void tryToMakeAllPartsEqualInSize();
QSplitter *_splitter;
ProgressBarPopup *_progressBarPopup;
std::vector<OutputItemContentWidget*> _outputItemContentWidgets;
};
}
@@ -1,14 +1,10 @@
#include "robomongo/gui/widgets/workarea/QueryWidget.h"
#include <QObject>
#include <QPushButton>
#include <QApplication>
#include <QLabel>
#include <QFileInfo>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QMainWindow>
#include <QDockWidget>
#include <Qsci/qsciscintilla.h>
#include <Qsci/qscilexerjavascript.h>
#include <mongo/client/dbclientinterface.h>
@@ -28,8 +24,6 @@
#include "robomongo/gui/GuiRegistry.h"
#include "robomongo/gui/widgets/workarea/OutputWidget.h"
#include "robomongo/gui/widgets/workarea/ScriptWidget.h"
#include "robomongo/gui/widgets/workarea/OutputItemContentWidget.h"
#include "robomongo/gui/widgets/workarea/OutputItemHeaderWidget.h"
#include "robomongo/gui/editors/PlainJavaScriptEditor.h"
#include "robomongo/gui/editors/JSLexer.h"
@@ -40,45 +34,33 @@ namespace Robomongo
QueryWidget::QueryWidget(MongoShell *shell, QWidget *parent) :
QWidget(parent),
_shell(shell),
_viewer(nullptr),
_dock(nullptr),
_viewer(NULL),
_isTextChanged(false)
{
AppRegistry::instance().bus()->subscribe(this, DocumentListLoadedEvent::Type, shell);
AppRegistry::instance().bus()->subscribe(this, ScriptExecutedEvent::Type, shell);
AppRegistry::instance().bus()->subscribe(this, AutocompleteResponse::Type, shell);
_scriptWidget = new ScriptWidget(_shell, this);
_scriptWidget = new ScriptWidget(_shell);
VERIFY(connect(_scriptWidget, SIGNAL(textChanged()), this, SLOT(textChange())));
// Need to use QMainWindow in order to make use of all features of docking.
// (Note: Qt full support for dock windows implemented only for QMainWindow)
_viewer = new OutputWidget(this);
_outputWindow = new QMainWindow;
_dock = new CustomDockWidget(this);
_dock->setAllowedAreas(Qt::NoDockWidgetArea);
_dock->setFeatures(QDockWidget::DockWidgetFloatable);
_dock->setWidget(_viewer);
_dock->setTitleBarWidget(new QWidget);
VERIFY(connect(_dock, SIGNAL(topLevelChanged(bool)), this, SLOT(on_dock_undock())));
_outputWindow->addDockWidget(Qt::BottomDockWidgetArea, _dock);
_viewer = new OutputWidget();
_outputLabel = new QLabel(this);
_outputLabel->setContentsMargins(0, 5, 0, 0);
_outputLabel->setVisible(false);
_line = new QFrame(this);
_line->setFrameShape(QFrame::HLine);
_line->setFrameShadow(QFrame::Raised);
QFrame *line = new QFrame(this);
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Raised);
_mainLayout = new QVBoxLayout;
_mainLayout->setSpacing(0);
_mainLayout->setContentsMargins(0, 0, 0, 0);
_mainLayout->addWidget(_scriptWidget);
_mainLayout->addWidget(_line);
_mainLayout->addWidget(_outputLabel, 0, Qt::AlignTop);
_mainLayout->addWidget(_outputWindow, 1);
setLayout(_mainLayout);
QVBoxLayout *layout = new QVBoxLayout;
layout->setSpacing(0);
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(_scriptWidget, 0, Qt::AlignTop);
layout->addWidget(line);
layout->addWidget(_outputLabel, 0, Qt::AlignTop);
layout->addWidget(_viewer, 1);
setLayout(layout);
}
void QueryWidget::setScriptFocus()
@@ -96,22 +78,6 @@ namespace Robomongo
_scriptWidget->hideAutocompletion();
}
void QueryWidget::bringDockToFront()
{
_dock->raise(); // required for MAC only; possible Qt bug
_dock->activateWindow();
}
bool QueryWidget::outputWindowDocked() const
{
if (_dock) {
return !_dock->isFloating();
}
else { // _dock is not initialized yet, but it will be docked when initialized
return true;
}
}
void QueryWidget::execute()
{
QString query = _scriptWidget->selectedText();
@@ -220,17 +186,12 @@ namespace Robomongo
_viewer->showProgress();
}
void QueryWidget::dockUndock()
{
// Toggle between dock/undock
_dock->setFloating(!_dock->isFloating());
};
void QueryWidget::hideProgress()
{
_viewer->hideProgress();
}
void QueryWidget::handle(DocumentListLoadedEvent *event)
{
hideProgress();
@@ -280,30 +241,6 @@ namespace Robomongo
_scriptWidget->showAutocompletion(event->list, QtUtils::toQString(event->prefix) );
}
void QueryWidget::on_dock_undock()
{
if (!_dock->isFloating()) { // If output window docked
// Settings to revert to docked mode
_scriptWidget->ui_queryLinesCountChanged();
_mainLayout->addWidget(_scriptWidget);
_mainLayout->addWidget(_line);
_mainLayout->addWidget(_outputWindow, 1);
_dock->setFeatures(QDockWidget::DockWidgetFloatable);
_dock->setTitleBarWidget(new QWidget);
_viewer->applyDockUndockSettings(true);
}
else { // output window undocked(floating)
// Settings for query window in order to use maximum space
_scriptWidget->disableFixedHeight();
_mainLayout->addWidget(_scriptWidget, 1);
_mainLayout->addWidget(_line);
_mainLayout->addWidget(_outputWindow);
_dock->setFeatures(QDockWidget::DockWidgetClosable);
_dock->setTitleBarWidget(nullptr);
_viewer->applyDockUndockSettings(false);
}
}
void QueryWidget::updateCurrentTab()
{
const QString &shellQuery = QtUtils::toQString(_shell->query());
@@ -1,15 +1,9 @@
#pragma once
#include <QWidget>
#include <QDockWidget>
#include <QCloseEvent>
QT_BEGIN_NAMESPACE
class QLabel;
class QVBoxLayout;
class QMainWindow;
class QPushButton;
class QFrame;
QT_END_NAMESPACE
#include "robomongo/core/Core.h"
@@ -30,11 +24,8 @@ namespace Robomongo
Q_OBJECT
public:
class CustomDockWidget;
typedef QWidget BaseClass;
QueryWidget(MongoShell *shell, QWidget *parent = NULL);
~QueryWidget();
void toggleOrientation();
void activateTabContent();
@@ -48,12 +39,8 @@ namespace Robomongo
void setScriptFocus();
void showAutocompletion();
void hideAutocompletion();
// Bring active tab's dock into front
void bringDockToFront();
// Get output window's dock status
bool outputWindowDocked() const;
~QueryWidget();
Q_SIGNALS:
void titleChanged(const QString &text);
@@ -68,18 +55,11 @@ namespace Robomongo
void openFile();
void textChange();
void showProgress();
public Q_SLOTS:
void handle(DocumentListLoadedEvent *event);
void handle(ScriptExecutedEvent *event);
void handle(AutocompleteResponse *event);
private Q_SLOTS:
// Make adjustments between output window dock/undock events
void on_dock_undock();
// Toggle output window between dock/undock status
void dockUndock();
private:
void hideProgress();
void updateCurrentTab();
@@ -89,37 +69,8 @@ namespace Robomongo
OutputWidget *_viewer;
ScriptWidget *_scriptWidget;
QLabel *_outputLabel;
QDockWidget *_dock;
QMainWindow *_outputWindow;
QFrame *_line;
QVBoxLayout *_mainLayout;
MongoShellExecResult _currentResult;
bool _isTextChanged;
};
/* ------- class CustomDockWidget -------- */
/* Custom dock widget for output window */
class QueryWidget::CustomDockWidget : public QDockWidget
{
Q_OBJECT
public:
CustomDockWidget(QueryWidget* parent)
: _parent(parent)
{}
QueryWidget* getParentQueryWidget() const { return _parent; }
protected:
// Dock instead of close
void closeEvent(QCloseEvent *event) override
{
event->ignore();
setFloating(false);
}
private:
QueryWidget* _parent;
};
}
@@ -4,6 +4,7 @@
#include <QKeyEvent>
#include <QCompleter>
#include <QStringListModel>
#include <QMessageBox>
#include <Qsci/qscilexerjavascript.h>
#include <Qsci/qsciscintilla.h>
@@ -13,7 +14,6 @@
#include "robomongo/core/utils/QtUtils.h"
#include "robomongo/gui/widgets/workarea/IndicatorLabel.h"
#include "robomongo/gui/widgets/workarea/QueryWidget.h"
#include "robomongo/gui/GuiRegistry.h"
#include "robomongo/gui/editors/JSLexer.h"
#include "robomongo/gui/editors/FindFrame.h"
@@ -49,9 +49,8 @@ namespace
namespace Robomongo
{
ScriptWidget::ScriptWidget(MongoShell *shell, QueryWidget *parent) :
ScriptWidget::ScriptWidget(MongoShell *shell) :
_shell(shell),
_parent(parent),
_textChanged(false),
_disableTextAndCursorNotifications(false)
{
@@ -64,7 +63,7 @@ namespace Robomongo
layout->setSpacing(0);
layout->setContentsMargins(5, 1, 5, 5);
layout->addWidget(_topStatusBar, 0, Qt::AlignTop);
layout->addWidget(_queryText);
layout->addWidget(_queryText, 1, Qt::AlignTop);
setLayout(layout);
// Query text widget
@@ -216,36 +215,23 @@ namespace Robomongo
scin->setIgnoreTabKey(false);
}
void ScriptWidget::disableFixedHeight() const
{
_queryText->setMinimumSize(0, 0);
_queryText->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
_queryText->sciScintilla()->setMinimumSize(0, 0);
_queryText->sciScintilla()->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
_queryText->sciScintilla()->setFocus();
}
void ScriptWidget::ui_queryLinesCountChanged()
{
// Set fixed size only if output widget is docked
if (_parent->outputWindowDocked())
{
int lines = _queryText->sciScintilla()->lines();
int editorTotalHeight = editorHeight(lines);
int lines = _queryText->sciScintilla()->lines();
int height = editorHeight(lines);
int maxHeight = editorHeight(18);
if (editorTotalHeight > maxHeight) {
editorTotalHeight = maxHeight;
}
// Hide & Show solves problem of UI blinking
_queryText->hide();
_queryText->setFixedHeight(editorTotalHeight);
_queryText->sciScintilla()->setFixedHeight(editorTotalHeight);
_queryText->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
_queryText->setMaximumHeight(editorTotalHeight + FindFrame::HeightFindPanel);
_queryText->sciScintilla()->setFocus();
_queryText->show();
}
int maxHeight = editorHeight(18);
if (height > maxHeight)
height = maxHeight;
// Hide & Show solves problem of UI blinking
_queryText->hide();
_queryText->setFixedHeight(height);
_queryText->sciScintilla()->setFixedHeight(height);
_queryText->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
_queryText->setMaximumHeight(height+FindFrame::HeightFindPanel);
_queryText->sciScintilla()->setFocus();
_queryText->show();
}
void ScriptWidget::onTextChanged()
@@ -15,7 +15,6 @@ namespace Robomongo
class TopStatusBar;
class MongoShell;
class Indicator;
class QueryWidget;
class AutoCompletionInfo
{
@@ -50,7 +49,7 @@ namespace Robomongo
Q_OBJECT
public:
ScriptWidget(MongoShell *shell, QueryWidget* parent);
ScriptWidget(MongoShell *shell);
/**
* @reimp
@@ -71,16 +70,12 @@ namespace Robomongo
bool getDisableTextAndCursorNotifications() { return _disableTextAndCursorNotifications; }
void setDisableTextAndCursorNotifications(const bool value) { _disableTextAndCursorNotifications = value; }
void disableFixedHeight() const;
Q_SIGNALS:
void textChanged();
public Q_SLOTS:
void setText(const QString &text);
void ui_queryLinesCountChanged();
private Q_SLOTS:
void ui_queryLinesCountChanged();
void onTextChanged();
void onCursorPositionChanged(int line, int index);
void onCompletionActivated(const QString&);
@@ -116,9 +111,6 @@ namespace Robomongo
QCompleter *_completer;
MongoShell *_shell;
AutoCompletionInfo _currentAutoCompletionInfo;
QueryWidget *_parent;
bool _textChanged;
bool _disableTextAndCursorNotifications;
};