Compare 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
Gökhan Simsek 0786489924 Update CHANGELOG 2016-10-05 17:28:02 +03:00
Gokhan Simsek 9cc34df185 Fixing the problem where create collection dialog was too large after switching into non-advanced mode from non-option tabs in advanced mode 2016-10-04 22:19:15 +03:00
Gokhan Simsek d5adcdf988 Fixing not working paralect link in about menu; Hiding validate json button when create collection dialog is in basic mode. 2016-10-04 21:41:08 +03:00
Gokhan Simsek 837c0e1a17 MinimizeToTray: Fixing the problem where incorrect context menu was shown when user minimize and right-click on tray icon. 2016-10-04 21:16:46 +03:00
Gökhan Simsek d458f43b63 Update README.md 2016-10-04 20:58:16 +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 be655902b4 Updating CHANGELOG for 0.9.0 Final 2016-09-30 19:37:26 +03:00
Gökhan Simsek f9332befb3 Update README.md for 0.9.0 Final. 2016-09-30 19:19:49 +03:00
Gökhan Simsek 66728df978 Update README.md 2016-09-30 18:32:26 +03:00
Gokhan Simsek 60dc85c2fc To fix the problem where "View Documents" window cannot be brought into front from the behind of floating output window 2016-09-29 12:38:36 +03:00
Gökhan Simsek 4b4eb623b9 Update README.md 2016-09-28 19:21:20 +03:00
Gokhan Simsek d2c98bf559 DockableOutputWindow: Adding code to support this feature after toggle orientation; updating tool tip for maximize output result button 2016-09-27 12:57:09 +03:00
Gokhan Simsek 9a31503996 DockableOutputWindow: Fixing problem where dock/undock icon wasn't updated after re-running existing query tab with undocked output window 2016-09-23 13:09:15 +03:00
Gokhan Simsek cb4622f61f Adding protection for all tray icon code which is Windows only 2016-09-22 14:55:21 +03:00
Gokhan Simsek 1ce1091eca Minor change due to MAC build error 2016-09-22 14:23:23 +03:00
Gokhan Simsek 4546eef1e3 Refactoring some functions to avoid access to private members for better encapsulation 2016-09-22 14:05:53 +03:00
Gokhan Simsek 1d8f24ced2 Code Review: Refactoring and non-major changes for commits from RC10 release (33c89ea) to this commit. 2016-09-22 13:32:40 +03:00
Gokhan Simsek 19a61ba517 Code Review: For pull request #1163(minimize to tray) - More minor refactoring and style changes. 2016-09-21 11:56:28 +03:00
Gokhan Simsek 2b377e35f1 Code Review: For pull request #1163(minimize to tray) - Adding fix for the problem when tray icon double clicked event was not caught and so context menu was showing wrong text. 2016-09-20 21:38:06 +03:00
Gokhan Simsek f5011630a3 Code review: For pull request #1127 (copy path & copy name), constness and access level edits, applying Robomongo Coding Style. 2016-09-20 20:26:54 +03:00
Gokhan Simsek 8967a84f12 DockableOutputWindow: Fix for possible Qt bug (MAC only) where dock window is not brought to front when connected tab is selected 2016-09-20 17:08:23 +03:00
Gokhan Simsek 38bed5e4eb Code review : MinimizeToTray pull request minor changes 2016-09-19 01:32:10 +03:00
Gokhan Simsek 5370ecedd8 ReplicaSet: Temporarily disable Replica Set feature - still under development 2016-09-15 13:18:53 +03:00
Gökhan Simsek 0e8cd5cefc Merge pull request #1163 from JoshJ1091/master
Add system tray icon and implement ability to close to system tray (Windows)
2016-09-14 13:37:10 +02:00
Gokhan Simsek e3c3649b0f Robomongo 0.9.0 2016-09-14 13:06:50 +03:00
Gokhan Simsek 19f953fa54 RepSet: Removing QShortCut due to failed build on Ubuntu 2016-09-14 12:10:28 +03:00
Gokhan Simsek ad1b5e35c7 Merge branch 'DockableOutputWindow' 2016-09-13 19:26:43 +03:00
Gokhan Simsek ff2eb0fef6 DockableOutputWindow: Updating clean versions of maximize and minimize icons; Minor change on ReplicaSetSettings due to failed build on MAC 2016-09-13 19:10:21 +03:00
Gokhan Simsek d356c14f87 DockableOutputWindow: Increasing size of dock/undock button icons 2016-09-12 00:57:14 +03:00
Gokhan Simsek 829cbf890b DockableOutputWindow: Adding new icons for maximize/minimize button 2016-09-11 23:40:12 +03:00
Gokhan Simsek 5ae52d4b4f DockableOutputWindow: Fix to solve crash when floating dock window hovered over bottom part of the maximized query widget 2016-09-11 18:50:18 +03:00
Gokhan Simsek 4608c6b7ee DockableOutputWindow: No maximize (via double click or any other source) if there is only one query result 2016-09-11 16:44:00 +03:00
Gokhan Simsek 7c7a818ca0 Merge branch 'DockableOutputWindow' 2016-09-11 15:59:32 +03:00
Gokhan Simsek 08c6d44185 DockableOutputWindow: Removing the additional horizontal line on bottom of tab title that is seen after undock 2016-09-11 15:56:50 +03:00
Gokhan Simsek dc8495b147 DockableOutputWindow: Adding code for frameless query results dock window; adding functionality to dock/undock from OutputItemHeaderWidget; adding dock/undock buttons and icons into OutputItemHeaderWidget; not showing OutputItemHeaderWidget maximize button if there is one query result; showing only one undock button if there are more than one query results. 2016-09-11 15:16:44 +03:00
Gokhan Simsek e2f5765a87 DockableOutputWindow: Adding code to show OutputWidget maximize button only if there are multiple query results 2016-09-10 16:24:46 +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
Gokhan Simsek 0086df54f0 DockableOutputWindow: Focus on active shell query tab when related dock output window is selected 2016-09-07 20:05:06 +03:00
Gokhan Simsek ddc0c910c8 DockableOutputWindow: Removing unused signal-slot connection 2016-09-07 14:02:04 +03:00
Gokhan Simsek 31f74baef7 DockableOutputWindow: Adding close button on dock output window with custom close event (dock instead of close) 2016-09-07 13:41:39 +03:00
Gokhan Simsek 8cd4f50304 DockableOutputWindow: Fix to solve crash on "Update Documents" 2016-09-07 11:06:55 +03:00
Gokhan Simsek 48f6abb361 DockableOutputWindow: Fix to solve un-selectable query window text issue when output window is floating. 2016-09-06 19:28:34 +03:00
Gokhan Simsek 47039d8685 DockableOutputWindow: Adding code to support full window query editor when output window is docked 2016-09-06 02:51:25 +03:00
Gokhan Simsek bc9aded3b7 DockableOutputWindow: Bring the output dock window front when tabs changed on main window 2016-09-04 21:50:18 +03:00
Gokhan Simsek f919544d1e DockableOutputWindow: Adding docked and undocked(full screen space for queries) modes for query window (ScriptWidget). 2016-09-04 18:59:16 +03:00
Gokhan Simsek ea49d0508a DockableOutputWindow: Adding dock capability for query result window (OutputWidget) 2016-09-03 21:57:08 +03:00
Josh 578447ecc3 Add system tray icon and implement ability to close to system tray
(Windows)
2016-08-18 16:52:26 +01:00
14 changed files with 656 additions and 21 deletions
+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
+12
View File
@@ -324,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");
+2
View File
@@ -58,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;
+3
View File
@@ -576,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
{
@@ -598,6 +600,7 @@ namespace Robomongo
{
QSettings settings("Paralect", "Robomongo");
settings.setValue("MainWindow/geometry", saveGeometry());
settings.setValue("MainWindow/windowState", saveState());
}
void MainWindow::open()
+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
View File
@@ -62,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.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -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;
@@ -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))
@@ -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);