diff --git a/toonz/sources/include/toonz/preferences.h b/toonz/sources/include/toonz/preferences.h index e5d0d9f..6aa4c3d 100644 --- a/toonz/sources/include/toonz/preferences.h +++ b/toonz/sources/include/toonz/preferences.h @@ -269,6 +269,9 @@ public: return m_paletteTypeOnLoadRasterImageAsColorModel; } + void setDefaultImportPolicy(int policy); + int getDefaultImportPolicy() { return m_importPolicy; } + // Drawing tab void setScanLevelType(std::string s); @@ -482,7 +485,7 @@ private: m_chunkSize, m_blanksCount, m_onionPaperThickness, m_step, m_shrink, m_textureSize, m_autocreationType, m_keyframeType, m_animationStep, m_ffmpegTimeout; // seconds - int m_projectRoot; + int m_projectRoot, m_importPolicy; int m_currentLanguage, m_currentStyleSheet, m_undoMemorySize, // in megabytes m_dragCellsBehaviour, m_lineTestFpsCapture, m_defLevelType, m_xsheetStep, diff --git a/toonz/sources/include/toonz/tscenehandle.h b/toonz/sources/include/toonz/tscenehandle.h index 75ad8cf..57aa7bb 100644 --- a/toonz/sources/include/toonz/tscenehandle.h +++ b/toonz/sources/include/toonz/tscenehandle.h @@ -57,6 +57,9 @@ public: } void notifyPixelUnitSelected(bool on) { emit pixelUnitSelected(on); } + void notifyImportPolicyChanged(int policy) { + emit importPolicyChanged(policy); + } void setDirtyFlag(bool dirtyFlag) { if (m_dirtyFlag == dirtyFlag) return; @@ -80,6 +83,7 @@ signals: void nameSceneChanged(); void preferenceChanged(const QString &prefName); void pixelUnitSelected(bool on); + void importPolicyChanged(int policy); }; #endif // TSCENEHANDLE_H diff --git a/toonz/sources/include/toonzqt/dvdialog.h b/toonz/sources/include/toonzqt/dvdialog.h index 6184bf5..a177970 100644 --- a/toonz/sources/include/toonzqt/dvdialog.h +++ b/toonz/sources/include/toonzqt/dvdialog.h @@ -45,6 +45,7 @@ namespace DVGui { const int WidgetHeight = 20; class Dialog; +class MessageAndCheckboxDialog; //============================================================================= @@ -88,6 +89,10 @@ Dialog DVAPI *createMsgBox(MsgType type, const QString &text, const QStringList &buttons, int defaultButtonIndex, QWidget *parent = 0); +MessageAndCheckboxDialog DVAPI *createMsgandCheckbox( + MsgType type, const QString &text, const QString &checkBoxText, + const QStringList &buttons, int defaultButtonIndex, QWidget *parent = 0); + // void DVAPI error(const QString &msg); // void DVAPI info(const QString &msg); @@ -247,6 +252,24 @@ signals: }; //----------------------------------------------------------------------------- + +class DVAPI MessageAndCheckboxDialog final : public DVGui::Dialog { + Q_OBJECT + + int m_checked = 0; + +public: + MessageAndCheckboxDialog(QWidget *parent = 0, bool hasButton = false, + bool hasFixedSize = true, + const QString &name = QString()); + int getChecked() { return m_checked; } + +public slots: + void onCheckboxChanged(int checked); + void onButtonPressed(int id); +}; + +//----------------------------------------------------------------------------- /*! Is a modal dialog with exclusive list of radio button. Exec value depend to checked button. 0 -> Cancel or Close Popup, diff --git a/toonz/sources/toonz/iocommand.cpp b/toonz/sources/toonz/iocommand.cpp index 6bc63ed..b2bced1 100644 --- a/toonz/sources/toonz/iocommand.cpp +++ b/toonz/sources/toonz/iocommand.cpp @@ -148,21 +148,30 @@ public: "File %1 doesn't belong to the current project.\n" "Do you want to import it or load it from its original location?") .arg(QString::fromStdWString(path.getWideString())); - + QString checkBoxLabel = + QObject::tr("Always do this action.") + .arg(QString::fromStdWString(path.getWideString())); QStringList buttons; buttons << QObject::tr("Import") << QObject::tr("Load") << QObject::tr("Cancel"); - - DVGui::Dialog *importDialog = - DVGui::createMsgBox(DVGui::QUESTION, label, buttons, 0); - int ret = importDialog->exec(); - + DVGui::MessageAndCheckboxDialog *importDialog = + DVGui::createMsgandCheckbox(DVGui::QUESTION, label, checkBoxLabel, + buttons, 0); + int ret = importDialog->exec(); + int checked = importDialog->getChecked(); importDialog->deleteLater(); if (ret == 0 || ret == 3) { m_aborted = true; return A_CANCEL; } + if (ret == 1 && checked > 0) { + Preferences::instance()->setDefaultImportPolicy(1); + TApp::instance()->getCurrentScene()->notifyImportPolicyChanged(1); + } else if (ret == 2 && checked > 0) { + Preferences::instance()->setDefaultImportPolicy(2); + TApp::instance()->getCurrentScene()->notifyImportPolicyChanged(2); + } m_importEnabled = (ret == 1); return ret == 1 ? A_IMPORT : A_LOAD; } diff --git a/toonz/sources/toonz/iocommand.h b/toonz/sources/toonz/iocommand.h index 2415e85..c4320b1 100644 --- a/toonz/sources/toonz/iocommand.h +++ b/toonz/sources/toonz/iocommand.h @@ -136,8 +136,8 @@ public: , col0(-1) , row1(-1) , col1(-1) - //, importPolicy(ASK_USER) - , importPolicy(LOAD) + , importPolicy(static_cast( + Preferences::instance()->getDefaultImportPolicy())) , expose(Preferences::instance()->isAutoExposeEnabled()) {} LoadResourceArguments(const TFilePath &fp, @@ -147,8 +147,8 @@ public: , col0(-1) , row1(-1) , col1(-1) - //, importPolicy(ASK_USER) - , importPolicy(LOAD) + , importPolicy(static_cast( + Preferences::instance()->getDefaultImportPolicy())) , expose(Preferences::instance()->isAutoExposeEnabled()) { resourceDatas.push_back(fp); } diff --git a/toonz/sources/toonz/preferencespopup.cpp b/toonz/sources/toonz/preferencespopup.cpp index a86cb7a..fe7e0be 100644 --- a/toonz/sources/toonz/preferencespopup.cpp +++ b/toonz/sources/toonz/preferencespopup.cpp @@ -338,6 +338,19 @@ void PreferencesPopup::onRoomChoiceChanged(int index) { //----------------------------------------------------------------------------- +void PreferencesPopup::onImportPolicyChanged(int index) { + m_pref->setDefaultImportPolicy(index); +} + +//----------------------------------------------------------------------------- + +void PreferencesPopup::onImportPolicyExternallyChanged(int policy) { + // call slot function onImportPolicyChanged() accordingly + m_importPolicy->setCurrentIndex(policy); +} + +//----------------------------------------------------------------------------- + void PreferencesPopup::onScanLevelTypeChanged(const QString &text) { m_pref->setScanLevelType(text.toStdString()); } @@ -1145,6 +1158,8 @@ PreferencesPopup::PreferencesPopup() QComboBox *paletteTypeForRasterColorModelComboBox = new QComboBox(this); + m_importPolicy = new QComboBox; + //--- Import/Export ------------------------------ categoryList->addItem(tr("Import/Export")); m_ffmpegPathFileFld = new DVGui::FileField(this, QString("")); @@ -1376,6 +1391,13 @@ PreferencesPopup::PreferencesPopup() paletteTypeForRasterColorModelComboBox->setCurrentIndex( m_pref->getPaletteTypeOnLoadRasterImageAsColorModel()); + QStringList policies; + policies << tr("Always ask before loading or importing") + << tr("Always import the file to the current project") + << tr("Always load the file from the current location"); + m_importPolicy->addItems(policies); + m_importPolicy->setCurrentIndex(m_pref->getDefaultImportPolicy()); + //--- Import/Export ------------------------------ QString path = m_pref->getFfmpegPath(); m_ffmpegPathFileFld->setPath(path); @@ -1713,6 +1735,15 @@ PreferencesPopup::PreferencesPopup() loadingFrameLay->setMargin(15); loadingFrameLay->setSpacing(10); { + QHBoxLayout *importLay = new QHBoxLayout(); + importLay->setMargin(0); + importLay->setSpacing(5); + { + importLay->addWidget(new QLabel(tr("Default File Import Behavior:"))); + importLay->addWidget(m_importPolicy); + } + importLay->addStretch(0); + loadingFrameLay->addLayout(importLay, 0); loadingFrameLay->addWidget(exposeLoadedLevelsCB, 0, Qt::AlignLeft | Qt::AlignVCenter); loadingFrameLay->addWidget(createSubfolderCB, 0, @@ -1725,11 +1756,11 @@ PreferencesPopup::PreferencesPopup() cacheLay->setHorizontalSpacing(5); cacheLay->setVerticalSpacing(10); { - cacheLay->addWidget(new QLabel(tr("Default TLV Caching Behavior")), 0, + cacheLay->addWidget(new QLabel(tr("Default TLV Caching Behavior:")), 0, 0, Qt::AlignRight | Qt::AlignVCenter); cacheLay->addWidget(initialLoadTlvCachingBehaviorComboBox, 0, 1); - cacheLay->addWidget(new QLabel(tr("Column Icon"), this), 1, 0, + cacheLay->addWidget(new QLabel(tr("Column Icon:"), this), 1, 0, Qt::AlignRight | Qt::AlignVCenter); cacheLay->addWidget(m_columnIconOm, 1, 1); @@ -1742,7 +1773,7 @@ PreferencesPopup::PreferencesPopup() cacheLay->addWidget( new QLabel( - tr("Palette Type on Loading Raster Image as Color Model")), + tr("Palette Type on Loading Raster Image as Color Model:")), 3, 0, Qt::AlignRight | Qt::AlignVCenter); cacheLay->addWidget(paletteTypeForRasterColorModelComboBox, 3, 1, 1, 5); } @@ -2182,6 +2213,11 @@ PreferencesPopup::PreferencesPopup() ret = ret && connect(paletteTypeForRasterColorModelComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onPaletteTypeForRasterColorModelChanged(int))); + ret = ret && connect(m_importPolicy, SIGNAL(currentIndexChanged(int)), + SLOT(onImportPolicyChanged(int))); + ret = ret && connect(TApp::instance()->getCurrentScene(), + SIGNAL(importPolicyChanged(int)), this, + SLOT(onImportPolicyExternallyChanged(int))); //--- Import/Export ---------------------- ret = ret && connect(m_ffmpegPathFileFld, SIGNAL(pathChanged()), this, diff --git a/toonz/sources/toonz/preferencespopup.h b/toonz/sources/toonz/preferencespopup.h index 0f5c307..84973e7 100644 --- a/toonz/sources/toonz/preferencespopup.h +++ b/toonz/sources/toonz/preferencespopup.h @@ -53,7 +53,7 @@ private: QComboBox *m_keyframeType, *m_cellsDragBehaviour, *m_defScanLevelType, *m_defLevelType, *m_autocreationType, *m_levelFormatNames, - *m_columnIconOm, *m_unitOm, *m_cameraUnitOm; + *m_columnIconOm, *m_unitOm, *m_cameraUnitOm, *m_importPolicy; DVGui::MeasuredDoubleLineEdit *m_defLevelWidth, *m_defLevelHeight; @@ -142,6 +142,8 @@ private slots: void onLevelFormatEdited(); void onShow0ThickLinesChanged(int); void onRegionAntialiasChanged(int); + void onImportPolicyChanged(int); + void onImportPolicyExternallyChanged(int policy); #ifdef LINETEST void onLineTestFpsCapture(int); diff --git a/toonz/sources/toonzlib/preferences.cpp b/toonz/sources/toonzlib/preferences.cpp index d6f9768..7899033 100644 --- a/toonz/sources/toonzlib/preferences.cpp +++ b/toonz/sources/toonzlib/preferences.cpp @@ -300,6 +300,7 @@ Preferences::Preferences() , m_useNumpadForSwitchingStyles(true) , m_useArrowKeyToShiftCellSelection(false) , m_inputCellsWithoutDoubleClickingEnabled(false) + , m_importPolicy(0) , m_watchFileSystem(true) { TCamera camera; m_defLevelType = PLI_XSHLEVEL; @@ -578,6 +579,7 @@ Preferences::Preferences() m_useArrowKeyToShiftCellSelection); getValue(*m_settings, "inputCellsWithoutDoubleClickingEnabled", m_inputCellsWithoutDoubleClickingEnabled); + getValue(*m_settings, "importPolicy", m_importPolicy); getValue(*m_settings, "watchFileSystemEnabled", m_watchFileSystem); } @@ -1297,6 +1299,13 @@ void Preferences::setFfmpegTimeout(int seconds) { //----------------------------------------------------------------- +void Preferences::setDefaultImportPolicy(int policy) { + m_importPolicy = policy; + m_settings->setValue("importPolicy", policy); +} + +//----------------------------------------------------------------- + int Preferences::addLevelFormat(const LevelFormat &format) { LevelFormatVector::iterator lft = m_levelFormats.insert( std::upper_bound(m_levelFormats.begin(), m_levelFormats.end(), format, diff --git a/toonz/sources/toonzqt/dvdialog.cpp b/toonz/sources/toonzqt/dvdialog.cpp index ee19d27..c06f481 100644 --- a/toonz/sources/toonzqt/dvdialog.cpp +++ b/toonz/sources/toonzqt/dvdialog.cpp @@ -26,6 +26,7 @@ #include #include #include +#include // boost includes #include @@ -757,11 +758,29 @@ void Dialog::addButtonBarWidget(QWidget *first, QWidget *second, QWidget *third, //============================================================================= +MessageAndCheckboxDialog::MessageAndCheckboxDialog(QWidget *parent, + bool hasButton, + bool hasFixedSize, + const QString &name) + : Dialog(parent, hasButton, hasFixedSize, name) {} + +//============================================================================= + +void MessageAndCheckboxDialog::onButtonPressed(int id) { done(id); } + +//============================================================================= + +void MessageAndCheckboxDialog::onCheckboxChanged(int checked) { + m_checked = checked; +} + +//============================================================================= + RadioButtonDialog::RadioButtonDialog(const QString &labelText, const QList &radioButtonList, QWidget *parent, Qt::WindowFlags f) : Dialog(parent, true, true), m_result(1) { - setWindowTitle(tr("Toonz")); + setWindowTitle(tr("OpenToonz")); setMinimumSize(20, 20); @@ -1206,6 +1225,64 @@ Dialog *DVGui::createMsgBox(MsgType type, const QString &text, //----------------------------------------------------------------------------- +MessageAndCheckboxDialog *DVGui::createMsgandCheckbox( + MsgType type, const QString &text, const QString &checkBoxText, + const QStringList &buttons, int defaultButtonIndex, QWidget *parent) { + MessageAndCheckboxDialog *dialog = new MessageAndCheckboxDialog(parent, true); + dialog->setWindowFlags(dialog->windowFlags() | Qt::WindowStaysOnTopHint); + dialog->setAlignment(Qt::AlignLeft); + QString msgBoxTitle = getMsgBoxTitle(type); + + dialog->setWindowTitle(msgBoxTitle); + + QLabel *mainTextLabel = new QLabel(text, dialog); + mainTextLabel->setObjectName("Label"); + QPixmap iconPixmap = getMsgBoxPixmap(type); + if (!iconPixmap.isNull()) { + QLabel *iconLabel = new QLabel(dialog); + iconLabel->setPixmap(iconPixmap); + + QHBoxLayout *mainLayout = new QHBoxLayout; + mainLayout->addWidget(iconLabel); + mainLayout->addSpacing(16); + mainLayout->addWidget(mainTextLabel); + dialog->addLayout(mainLayout); + } else + dialog->addWidget(mainTextLabel); + + // ButtonGroup: is used only to retrieve the clicked button + QButtonGroup *buttonGroup = new QButtonGroup(dialog); + + for (int i = 0; i < (int)buttons.size(); i++) { + QPushButton *button = new QPushButton(buttons[i], dialog); + if (defaultButtonIndex == i) + button->setDefault(true); + else + button->setDefault(false); + dialog->addButtonBarWidget(button); + + buttonGroup->addButton(button, i + 1); + } + + QCheckBox *dialogCheckBox = new QCheckBox(dialog); + QHBoxLayout *checkBoxLayout = new QHBoxLayout; + QLabel *checkBoxLabel = new QLabel(checkBoxText, dialog); + checkBoxLayout->addWidget(dialogCheckBox); + checkBoxLayout->addWidget(checkBoxLabel); + checkBoxLayout->addStretch(0); + + dialog->addLayout(checkBoxLayout); + + QObject::connect(dialogCheckBox, SIGNAL(stateChanged(int)), dialog, + SLOT(onCheckboxChanged(int))); + QObject::connect(buttonGroup, SIGNAL(buttonPressed(int)), dialog, + SLOT(onButtonPressed(int))); + + return dialog; +} + +//----------------------------------------------------------------------------- + QString DVGui::getText(const QString &title, const QString &labelText, const QString &text, bool *ok) { Dialog dialog(0, true);