Recent Projects and Default Project Location (#415)

* Recent Projects and Default Project Location

* Add to load scene

* Added shortening of long paths and hover effects

* The ComboBox is back baby.

* Browse option
This commit is contained in:
Jeremy Bullock 2020-11-08 23:55:47 -07:00 committed by GitHub
parent dfed2a033d
commit bb63d765ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 458 additions and 105 deletions

View file

@ -272,6 +272,9 @@ public:
TPixel getRasterBackgroundColor() const {
return getColorValue(rasterBackgroundColor);
}
QString getDefaultProjectPath() const {
return getStringValue(defaultProjectPath);
}
// Import Export Tab
QString getFfmpegPath() const { return getStringValue(ffmpegPath); }

View file

@ -67,6 +67,7 @@ enum PreferencesItemId {
// Saving
rasterBackgroundColor,
resetUndoOnSavingLevel,
defaultProjectPath,
//----------
// Import / Export

View file

@ -96,6 +96,7 @@ public:
static void setBrowserPopupController(BrowserPopupController *controller);
static BrowserPopupController *getBrowserPopupController();
void forceOpenBrowser();
protected slots:
/*! Open a static file dialog popup to browse and choose directories. If a

View file

@ -145,9 +145,8 @@ QMutex levelFileMutex;
} // namespace
inline bool isMultipleFrameType(std::string type) {
return (type == "tlv" || type == "tzl" || type == "pli" ||
type == "avi" || type == "gif" || type == "mp4" ||
type == "webm");
return (type == "tlv" || type == "tzl" || type == "pli" || type == "avi" ||
type == "gif" || type == "mp4" || type == "webm");
}
//=============================================================================
@ -686,7 +685,7 @@ void FileBrowser::refreshCurrentFolderItems() {
//-----------------------------------------------------------------------------
void FileBrowser::setFolder(const TFilePath &fp, bool expandNode,
bool forceUpdate) {
bool forceUpdate, bool collapseAll) {
if (fp == m_folder && !forceUpdate) return;
// set the current folder path
@ -699,7 +698,7 @@ void FileBrowser::setFolder(const TFilePath &fp, bool expandNode,
m_folderName->setText(toQString(fp));
refreshCurrentFolderItems();
if (collapseAll) m_folderTreeView->collapseAll();
if (!TFileStatus(fp).isLink())
m_folderTreeView->setCurrentNode(fp, expandNode);
}

View file

@ -99,7 +99,7 @@ types to be displayed in the file browser.
void removeFilterType(const QString &type);
void setFolder(const TFilePath &fp, bool expandNode = false,
bool forceUpdate = false);
bool forceUpdate = false, bool collapseAll = false);
// process when inputting the folder which is not regitered in the folder tree
// (e.g. UNC path in Windows)
void setUnregisteredFolder(const TFilePath &fp);

View file

@ -15,6 +15,7 @@
#include "tapp.h"
#include "toonz/tscenehandle.h"
#include "mainwindow.h"
#include <QFileInfo>
#include <QDir>
@ -774,8 +775,10 @@ void DvDirModelProjectNode::makeCurrent() {
TProjectManager *pm = TProjectManager::instance();
TFilePath projectPath = getProjectPath();
if (!IoCmd::saveSceneIfNeeded(QObject::tr("Change project"))) return;
TFilePath projectFolder = getPath();
pm->setCurrentProjectPath(projectPath);
RecentFiles::instance()->addFilePath(projectFolder.getQString(),
RecentFiles::Project);
IoCmd::newScene();
}
@ -1029,6 +1032,7 @@ DvDirModelRootNode::DvDirModelRootNode()
: DvDirModelNode(0, L"Root")
, m_myComputerNode(0)
, m_networkNode(0)
, m_currentProjectNode(0)
, m_sandboxProjectNode(0) {
m_nodeType = "Root";
}
@ -1077,24 +1081,10 @@ void DvDirModelRootNode::refreshChildren() {
TProjectManager *pm = TProjectManager::instance();
TFilePath sandboxProjectPath = pm->getSandboxProjectFolder();
m_projectPaths.insert(sandboxProjectPath);
m_sandboxProjectNode = new DvDirModelProjectNode(this, sandboxProjectPath);
addChild(m_sandboxProjectNode);
TFilePath projectPath = pm->getCurrentProjectPath().getParentDir();
if (projectPath != pm->getSandboxProjectFolder()) {
m_currentProjectNode = new DvDirModelProjectNode(this, projectPath);
m_projectPaths.insert(projectPath);
addChild(m_currentProjectNode);
}
if (m_projectPaths.size() > 1) {
for (auto i : m_projectPaths) {
if (i == projectPath) continue;
DvDirModelProjectNode *addedProjectNode =
new DvDirModelProjectNode(this, projectPath);
addChild(addedProjectNode);
}
}
m_projectNodes.push_back(m_sandboxProjectNode);
// SVN Repositories
QList<SVNRepository> repositories =
@ -1118,10 +1108,25 @@ void DvDirModelRootNode::refreshChildren() {
new DvDirModelSceneFolderNode(this, L"Scene Folder", TFilePath());
m_sceneFolderNode->setPixmap(QPixmap(":Resources/clapboard.png"));
} else {
TProjectManager *pm = TProjectManager::instance();
RecentFiles *recent = RecentFiles::instance();
QList<QString> recentFiles = recent->getFilesNameList(RecentFiles::Project);
int recentCount = recentFiles.size();
TProjectManager *pm = TProjectManager::instance();
for (auto path : recentFiles) {
TFilePath projectPath(path);
if (TSystem::doesExistFileOrLevel(projectPath) &&
m_projectPaths.find(projectPath) == m_projectPaths.end() &&
pm->isProject(projectPath)) {
DvDirModelProjectNode *addedProjectNode =
new DvDirModelProjectNode(this, projectPath);
m_projectPaths.insert(projectPath);
addChild(addedProjectNode);
m_projectNodes.push_back(addedProjectNode);
}
}
TFilePath projectPath = pm->getCurrentProjectPath().getParentDir();
if (projectPath != pm->getSandboxProjectFolder() &&
(m_projectPaths.find(projectPath) == m_projectPaths.end())) {
if (m_projectPaths.find(projectPath) == m_projectPaths.end()) {
std::string rootString = projectPath.getQString().toStdString();
m_currentProjectNode = new DvDirModelProjectNode(this, projectPath);
m_projectPaths.insert(projectPath);
@ -1150,15 +1155,14 @@ DvDirModelNode *DvDirModelRootNode::getNodeByPath(const TFilePath &path) {
}
// path could be a project, under some project root
for (i = 0; i < (int)m_projectRootNodes.size(); i++) {
node = m_projectRootNodes[i]->getNodeByPath(path);
if (node) return node;
for (i = 0; i < (int)m_projectNodes.size(); i++) {
node = m_projectNodes[i];
DvDirModelProjectNode *projectNode =
dynamic_cast<DvDirModelProjectNode *>(node);
// search in the project folders
for (int j = 0; j < m_projectRootNodes[i]->getChildCount(); j++) {
DvDirModelProjectNode *projectNode =
dynamic_cast<DvDirModelProjectNode *>(
m_projectRootNodes[i]->getChild(j));
if (projectNode) {
if (projectNode) {
if (projectNode->getPath() == path) return node;
for (int j = 0; j < m_projectNodes[i]->getChildCount(); j++) {
// for the normal folder in the project folder
node = projectNode->getNodeByPath(path);
if (node) return node;
@ -1170,10 +1174,6 @@ DvDirModelNode *DvDirModelRootNode::getNodeByPath(const TFilePath &path) {
if (node) return node;
}
}
} else // for the normal folder in the project root
{
node = m_projectRootNodes[i]->getChild(j)->getNodeByPath(path);
if (node) return node;
}
}
}
@ -1341,6 +1341,8 @@ void DvDirModel::refreshFolderChild(const QModelIndex &i) {
for (r = 0; r < count; r++) refreshFolderChild(index(r, 0, i));
}
void DvDirModel::forceRefresh() { onSceneSwitched(); }
//-----------------------------------------------------------------------------
DvDirModelNode *DvDirModel::getNode(const QModelIndex &index) const {

View file

@ -305,8 +305,8 @@ public:
//-----------------------------------------------------------------------------
class DvDirModelRootNode final : public DvDirModelNode {
std::vector<DvDirModelFileFolderNode *> m_projectRootNodes;
std::vector<DvDirModelFileFolderNode *> m_versionControlNodes;
std::vector<DvDirModelProjectNode *> m_projectNodes;
DvDirModelMyComputerNode *m_myComputerNode;
DvDirModelNetworkNode *m_networkNode;
DvDirModelProjectNode *m_sandboxProjectNode;
@ -371,6 +371,8 @@ public:
void refreshFolder(const TFilePath &folderPath,
const QModelIndex &i = QModelIndex());
void refreshFolderChild(const QModelIndex &i = QModelIndex());
// Only used when first launching the program to update recent projects
void forceRefresh();
bool removeRows(int row, int count,
const QModelIndex &parent = QModelIndex()) override;

View file

@ -204,7 +204,7 @@ void FileBrowserPopup::setFileMode(bool isDirectoryOnly) {
//-----------------------------------------------------------------------------
void FileBrowserPopup::setFolder(const TFilePath &folderPath) {
m_browser->setFolder(folderPath, true);
m_browser->setFolder(folderPath, true, true, true);
}
//-----------------------------------------------------------------------------

View file

@ -1939,10 +1939,16 @@ bool IoCmd::loadScene(const TFilePath &path, bool updateRecentFile,
// set dirty for xdts files since converted tnz is not yet saved
TApp::instance()->getCurrentScene()->setDirtyFlag(isXdts);
History::instance()->addItem(scenePath);
if (updateRecentFile)
if (updateRecentFile) {
RecentFiles::instance()->addFilePath(
toQString(scenePath), RecentFiles::Scene,
QString::fromStdString(scene->getProject()->getName().getName()));
}
RecentFiles::instance()->addFilePath(TProjectManager::instance()
->getCurrentProjectPath()
.getParentDir()
.getQString(),
RecentFiles::Project);
QApplication::restoreOverrideCursor();
int forbiddenLevelCount = 0;
@ -2909,6 +2915,17 @@ public:
//-----------------------------------------------------------------------------
class ClearRecentProjectListCommandHandler final : public MenuItemHandler {
public:
ClearRecentProjectListCommandHandler()
: MenuItemHandler(MI_ClearRecentProject) {}
void execute() override {
RecentFiles::instance()->clearRecentFilesList(RecentFiles::Project);
}
} clearRecentProjectListCommandHandler;
//-----------------------------------------------------------------------------
class RevertScene final : public MenuItemHandler {
public:
RevertScene() : MenuItemHandler(MI_RevertScene) {}

View file

@ -730,7 +730,7 @@ int main(int argc, char *argv[]) {
// a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
if (Preferences::instance()->isLatestVersionCheckEnabled())
w.checkForUpdates();
DvDirModel::instance()->forceRefresh();
w.show();
// Show floating panels only after the main window has been shown

View file

@ -1692,6 +1692,9 @@ void MainWindow::defineActions() {
"", tr("Remove everything from the recent scene list."));
createMenuFileAction(MI_ClearRecentLevel, tr("&Clear Recent level File List"),
"", tr("Remove everything from the recent level list."));
createMenuFileAction(MI_ClearRecentProject, tr("&Clear Recent Project List"),
"",
tr("Remove everything from the recent project list."));
menuAct = createMenuLevelAction(MI_NewLevel, tr("&New Level..."), "Alt+N",
tr("Create a new drawing layer."));
@ -3751,7 +3754,10 @@ void MainWindow::onQuit() { close(); }
//=============================================================================
RecentFiles::RecentFiles()
: m_recentScenes(), m_recentSceneProjects(), m_recentLevels() {}
: m_recentScenes()
, m_recentSceneProjects()
, m_recentLevels()
, m_recentProjects() {}
//-----------------------------------------------------------------------------
@ -3771,7 +3777,9 @@ void RecentFiles::addFilePath(QString path, FileType fileType,
QList<QString> files =
(fileType == Scene) ? m_recentScenes : (fileType == Level)
? m_recentLevels
: m_recentFlipbookImages;
: (fileType == Project)
? m_recentProjects
: m_recentFlipbookImages;
int i;
for (i = 0; i < files.size(); i++)
if (files.at(i) == path) {
@ -3790,6 +3798,8 @@ void RecentFiles::addFilePath(QString path, FileType fileType,
m_recentScenes = files;
else if (fileType == Level)
m_recentLevels = files;
else if (fileType == Project)
m_recentProjects = files;
else
m_recentFlipbookImages = files;
@ -3805,6 +3815,8 @@ void RecentFiles::moveFilePath(int fromIndex, int toIndex, FileType fileType) {
m_recentSceneProjects.move(fromIndex, toIndex);
} else if (fileType == Level)
m_recentLevels.move(fromIndex, toIndex);
else if (fileType == Project)
m_recentProjects.move(fromIndex, toIndex);
else
m_recentFlipbookImages.move(fromIndex, toIndex);
saveRecentFiles();
@ -3818,6 +3830,8 @@ void RecentFiles::removeFilePath(int index, FileType fileType) {
m_recentSceneProjects.removeAt(index);
} else if (fileType == Level)
m_recentLevels.removeAt(index);
else if (fileType == Project)
m_recentProjects.removeAt(index);
saveRecentFiles();
}
@ -3826,8 +3840,10 @@ void RecentFiles::removeFilePath(int index, FileType fileType) {
QString RecentFiles::getFilePath(int index, FileType fileType) const {
return (fileType == Scene)
? m_recentScenes[index]
: (fileType == Level) ? m_recentLevels[index]
: m_recentFlipbookImages[index];
: (fileType == Level)
? m_recentLevels[index]
: (fileType == Project) ? m_recentProjects[index]
: m_recentFlipbookImages[index];
}
//-----------------------------------------------------------------------------
@ -3853,6 +3869,8 @@ void RecentFiles::clearRecentFilesList(FileType fileType) {
m_recentSceneProjects.clear();
} else if (fileType == Level)
m_recentLevels.clear();
else if (fileType == Project)
m_recentProjects.clear();
else
m_recentFlipbookImages.clear();
@ -3902,6 +3920,15 @@ void RecentFiles::loadRecentFiles() {
if (!level.isEmpty()) m_recentLevels.append(level);
}
QList<QVariant> projects = settings.value(QString("Projects")).toList();
if (!projects.isEmpty()) {
for (i = 0; i < projects.size(); i++)
m_recentProjects.append(projects.at(i).toString());
} else {
QString project = settings.value(QString("Projects")).toString();
if (!project.isEmpty()) m_recentProjects.append(project);
}
QList<QVariant> flipImages =
settings.value(QString("FlipbookImages")).toList();
if (!flipImages.isEmpty()) {
@ -3915,6 +3942,7 @@ void RecentFiles::loadRecentFiles() {
refreshRecentFilesMenu(Scene);
refreshRecentFilesMenu(Level);
refreshRecentFilesMenu(Flip);
refreshRecentFilesMenu(Project);
}
//-----------------------------------------------------------------------------
@ -3925,6 +3953,7 @@ void RecentFiles::saveRecentFiles() {
settings.setValue(QString("Scenes"), QVariant(m_recentScenes));
settings.setValue(QString("SceneProjects"), QVariant(m_recentSceneProjects));
settings.setValue(QString("Levels"), QVariant(m_recentLevels));
settings.setValue(QString("Projects"), QVariant(m_recentProjects));
settings.setValue(QString("FlipbookImages"),
QVariant(m_recentFlipbookImages));
}
@ -3935,14 +3964,19 @@ QList<QString> RecentFiles::getFilesNameList(FileType fileType) {
QList<QString> files =
(fileType == Scene) ? m_recentScenes : (fileType == Level)
? m_recentLevels
: m_recentFlipbookImages;
: (fileType == Project)
? m_recentProjects
: m_recentFlipbookImages;
QList<QString> names;
int i;
for (i = 0; i < files.size(); i++) {
TFilePath path(files.at(i).toStdWString());
QString str, number;
names.append(number.number(i + 1) + QString(". ") +
str.fromStdWString(path.getWideString()));
if (fileType != Project)
names.append(number.number(i + 1) + QString(". ") +
str.fromStdWString(path.getWideString()));
else
names.append(str.fromStdWString(path.getWideString()));
}
return names;
}

View file

@ -338,15 +338,19 @@ signals:
class RecentFiles {
friend class StartupPopup;
friend class DvDirModelRootNode;
friend class ProjectPopup;
friend class ProjectSettingsPopup;
QList<QString> m_recentScenes;
QList<QString> m_recentSceneProjects;
QList<QString> m_recentLevels;
QList<QString> m_recentFlipbookImages;
QList<QString> m_recentProjects;
RecentFiles();
public:
enum FileType { Scene, Level, Flip, None };
enum FileType { Scene, Level, Flip, Project, None };
static RecentFiles *instance();
~RecentFiles();

View file

@ -249,6 +249,8 @@ void TopBar::loadMenubar() {
addMenuItem(projectManagementMenu, MI_ProjectSettings);
projectManagementMenu->addSeparator();
addMenuItem(projectManagementMenu, MI_SaveDefaultSettings);
projectManagementMenu->addSeparator();
addMenuItem(projectManagementMenu, MI_ClearRecentProject);
}
fileMenu->addSeparator();
QMenu *importMenu = fileMenu->addMenu(tr("Import"));

View file

@ -24,6 +24,7 @@
#define MI_OpenRecentLevel "MI_OpenRecentLevel"
#define MI_ClearRecentScene "MI_ClearRecentScene"
#define MI_ClearRecentLevel "MI_ClearRecentLevel"
#define MI_ClearRecentProject "MI_ClearRecentProject"
#define MI_PrintXsheet "MI_PrintXsheet"
#define MI_NewLevel "MI_NewLevel"
#define MI_NewVectorLevel "MI_NewVectorLevel"

View file

@ -470,9 +470,9 @@ void PreferencesPopup::beforeRoomChoiceChanged() {
//-----------------------------------------------------------------------------
void PreferencesPopup::onColorCalibrationChanged() {
LutManager::instance()->update();
TApp::instance()->getCurrentScene()->notifyPreferenceChanged(
"ColorCalibration");
LutManager::instance()->update();
TApp::instance()->getCurrentScene()->notifyPreferenceChanged(
"ColorCalibration");
}
//-----------------------------------------------------------------------------
@ -1028,6 +1028,7 @@ QString PreferencesPopup::getUIString(PreferencesItemId id) {
{rasterBackgroundColor, tr("Matte color:")},
{resetUndoOnSavingLevel, tr("Clear Undo History when Saving Levels")},
{doNotShowPopupSaveScene, tr("Do not show Save Scene popup warning")},
{defaultProjectPath, tr("Default Project Path:")},
// Import / Export
{ffmpegPath, tr("FFmpeg Path:")},
@ -1320,7 +1321,7 @@ QWidget* PreferencesPopup::createGeneralPage() {
QWidget* widget = new QWidget(this);
QGridLayout* lay = new QGridLayout();
setupLayout(lay);
insertUI(defaultProjectPath, lay);
insertUI(defaultViewerEnabled, lay);
insertUI(rasterOptimizedMemory, lay);
insertUI(startupPopupEnabled, lay);
@ -1471,7 +1472,7 @@ QWidget* PreferencesPopup::createInterfacePage() {
// m_preEditedFuncMap.insert(CurrentRoomChoice,
// &PreferencesPopup::beforeRoomChoiceChanged);
m_onEditedFuncMap.insert(colorCalibrationEnabled,
&PreferencesPopup::onColorCalibrationChanged);
&PreferencesPopup::onColorCalibrationChanged);
return widget;
}

View file

@ -9,6 +9,7 @@
#include "iocommand.h"
#include "filebrowsermodel.h"
#include "dvdirtreeview.h"
#include "mainwindow.h"
// TnzQt includes
#include "toonzqt/menubarcommand.h"
@ -23,15 +24,16 @@
#include "tapp.h"
#include "toonz/tscenehandle.h"
#include "toonz/toonzscene.h"
#include "toonz/preferences.h"
// Qt includes
#include <QPushButton>
#include <QFileInfo>
#include <QFormLayout>
#include <QLabel>
#include <QMainWindow>
#include <QComboBox>
#include <QStandardPaths>
#include <QGroupBox>
using namespace DVGui;
@ -50,17 +52,24 @@ TFilePath getDocumentsPath() {
ProjectPopup::ProjectPopup(bool isModal)
: Dialog(TApp::instance()->getMainWindow(), isModal, false, "Project") {
TProjectManager *pm = TProjectManager::instance();
m_mainFrame->setFixedHeight(100);
// m_mainFrame->setFixedHeight(100);
m_mainFrame->setMinimumWidth(400);
this->layout()->setSizeConstraint(QLayout::SetFixedSize);
m_choosePrjLabel = new QLabel(tr("Project:"), this);
m_prjNameLabel = new QLabel(tr("Project Name:"), this);
m_pathFieldLabel = new QLabel(tr("Create Project In:"), this);
m_nameFld = new LineEdit();
m_choosePrjLabel = new QLabel(tr("Project:"), this);
m_prjNameLabel = new QLabel(tr("Project Name:"), this);
m_pathFieldLabel = new QLabel(tr("Create Project In:"), this);
m_nameFld = new LineEdit();
m_recentProjectLayout = new QGridLayout(this);
m_recentProjectLayout->setSpacing(2);
m_recentProjectLayout->setMargin(4);
m_projectLocationFld =
new DVGui::FileField(this, getDocumentsPath().getQString());
QString defaultProjectLocation =
Preferences::instance()->getDefaultProjectPath();
if (TSystem::doesExistFileOrLevel(TFilePath(defaultProjectLocation))) {
m_projectLocationFld->setPath(defaultProjectLocation);
}
m_nameFld->setMaximumHeight(WidgetHeight);
@ -114,6 +123,11 @@ ProjectPopup::ProjectPopup(bool isModal)
cb->hide();
}
m_topLayout->addLayout(upperLayout);
m_projectGB = new QGroupBox(tr("Recent Projects"), this);
m_projectGB->setLayout(m_recentProjectLayout);
m_projectGB->setAlignment(Qt::AlignLeft);
m_topLayout->addWidget(m_projectGB);
m_projectGB->hide();
}
pm->addListener(this);
@ -271,7 +285,8 @@ void ProjectSettingsPopup::projectChanged() {
if (projectP->getProjectPath() != path) {
projectP->save();
}
RecentFiles::instance()->addFilePath(path.getParentDir().getQString(),
RecentFiles::Project);
updateFieldsFromProject(projectP);
IoCmd::newScene();
accept();
@ -326,6 +341,64 @@ void ProjectSettingsPopup::showEvent(QShowEvent *) {
TProjectP currentProject = TProjectManager::instance()->getCurrentProject();
updateFieldsFromProject(currentProject.getPointer());
if (m_recentProjectLayout) {
while (m_recentProjectLayout->count() > 0) {
QLayoutItem *item = m_recentProjectLayout->takeAt(0);
QWidget *widget = item->widget();
if (widget) delete widget;
delete item;
}
}
RecentFiles *recent = RecentFiles::instance();
QList<QString> recentProjects =
recent->getFilesNameList(RecentFiles::Project);
TProjectManager *pm = TProjectManager::instance();
static QPixmap closeProjectPixmap(
svgToPixmap(getIconThemePath("actions/18/folder_project.svg")));
// setPixmap(closeProjectPixmap);
int i = 0;
for (auto path : recentProjects) {
TFilePath projectPath(path);
if (TSystem::doesExistFileOrLevel(projectPath) &&
pm->isProject(projectPath)) {
QLabel *folderLabel = new QLabel(this);
folderLabel->setPixmap(closeProjectPixmap);
folderLabel->setFixedWidth(20);
folderLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
m_recentProjectLayout->addWidget(folderLabel, i, 0, Qt::AlignRight);
// int slashCount = path.count("\\");
// QString lookFor = slashCount > 0 ? "\\" : "//";
QString labelText = QString::fromStdString(projectPath.getName());
// if (labelText.count(lookFor) > 4) {
// while (labelText.count(lookFor) > 4) {
// int firstIndex = labelText.indexOf(lookFor, 0);
// labelText.remove(0, firstIndex + 1);
// }
// labelText.insert(0, "..." + lookFor);
//}
ClickableProjectLabel *projectLabel =
new ClickableProjectLabel(labelText, this);
projectLabel->setPath(path);
projectLabel->setToolTip(path);
m_recentProjectLayout->addWidget(projectLabel, i, 1, Qt::AlignLeft);
connect(projectLabel, &ClickableProjectLabel::onMouseRelease, [=]() {
m_projectLocationFld->blockSignals(true);
m_projectLocationFld->setPath(projectLabel->getPath());
m_projectLocationFld->blockSignals(false);
projectChanged();
});
i++;
}
}
if (recentProjects.size() > 0) {
m_projectGB->show();
m_recentProjectLayout->setColumnStretch(0, 0);
m_recentProjectLayout->setColumnStretch(1, 10);
} else
m_projectGB->hide();
m_nameFld->setText("");
m_projectLocationFld->blockSignals(true);
@ -336,13 +409,10 @@ void ProjectSettingsPopup::showEvent(QShowEvent *) {
m_oldPath = TFilePath(m_projectLocationFld->getPath());
m_projectLocationFld->blockSignals(false);
resize(600, 75);
QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
setSizePolicy(sizePolicy);
setMinimumSize(QSize(600, 75));
setMaximumSize(QSize(600, 75));
setFixedSize(width(), height());
setSizeGripEnabled(false);
}
@ -467,7 +537,11 @@ void ProjectCreatePopup::showEvent(QShowEvent *) {
cb->setChecked(false);
cb->blockSignals(signalesAlreadyBlocked);
}
QString defaultProjectLocation =
Preferences::instance()->getDefaultProjectPath();
if (TSystem::doesExistFileOrLevel(TFilePath(defaultProjectLocation))) {
m_projectLocationFld->setPath(defaultProjectLocation);
}
m_nameFld->setText("");
resize(600, 150);
@ -485,6 +559,36 @@ void ProjectCreatePopup::setPath(QString path) {
m_projectLocationFld->setPath(path);
}
//=============================================================================
ClickableProjectLabel::ClickableProjectLabel(const QString &text,
QWidget *parent, Qt::WindowFlags f)
: QLabel(text, parent, f) {
m_path = text;
}
//-----------------------------------------------------------------------------
ClickableProjectLabel::~ClickableProjectLabel() {}
//-----------------------------------------------------------------------------
void ClickableProjectLabel::mouseReleaseEvent(QMouseEvent *event) {
emit onMouseRelease(event);
}
//-----------------------------------------------------------------------------
void ClickableProjectLabel::enterEvent(QEvent *) {
setStyleSheet("text-decoration: underline;");
}
//-----------------------------------------------------------------------------
void ClickableProjectLabel::leaveEvent(QEvent *) {
setStyleSheet("text-decoration: none;");
}
//-----------------------------------------------------------------------------
OpenPopupCommandHandler<ProjectCreatePopup> openProjectCreatePopup(

View file

@ -7,6 +7,8 @@
#include "toonz/tproject.h"
#include "filebrowsermodel.h"
#include <QList>
#include <QLabel>
#include <QMouseEvent>
// forward declaration
namespace DVGui {
@ -16,6 +18,8 @@ class CheckBox;
}
class QComboBox;
class QGridLayout;
class QGroupBox;
//=============================================================================
// ProjectPopup
@ -35,6 +39,9 @@ protected:
DVGui::FileField *m_projectLocationFld;
QGridLayout *m_recentProjectLayout;
QGroupBox *m_projectGB;
public:
ProjectPopup(bool isModal);
// da TProjectManager::Listener
@ -89,4 +96,27 @@ protected:
void showEvent(QShowEvent *) override;
};
// The ClickableLabel class is used to allow click and dragging
// on a label to change the value of a linked field
class ClickableProjectLabel : public QLabel {
Q_OBJECT
QString m_path;
protected:
void mouseReleaseEvent(QMouseEvent *) override;
void enterEvent(QEvent *) override;
void leaveEvent(QEvent *) override;
public:
ClickableProjectLabel(const QString &text, QWidget *parent = nullptr,
Qt::WindowFlags f = Qt::WindowFlags());
~ClickableProjectLabel();
void setPath(QString path) { m_path = path; }
QString getPath() { return m_path; }
signals:
void onMouseRelease(QMouseEvent *event);
};
#endif // PROJECTPOPUP_H

View file

@ -109,6 +109,7 @@ StartupPopup::StartupPopup()
.getParentDir()
.getQString();
m_projectLocationFld->setPath(currProjectPath);
m_projectsCB = new QComboBox(this);
m_sceneNameLabel = new QLabel(tr("Scene Name:"));
m_widthLabel = new QLabel(tr("Width:"), this);
m_widthFld = new MeasuredDoubleLineEdit(this);
@ -200,7 +201,9 @@ StartupPopup::StartupPopup()
projectLay->setMargin(8);
{
projectLay->addWidget(m_projectLocationFld, 1);
projectLay->addWidget(m_projectsCB, 1);
projectLay->addWidget(newProjectButton, 0);
m_projectLocationFld->hide();
}
m_projectBox->setLayout(projectLay);
guiLay->addWidget(m_projectBox, 1, 0, 1, 1, Qt::AlignCenter);
@ -214,9 +217,6 @@ StartupPopup::StartupPopup()
Qt::AlignRight | Qt::AlignVCenter);
newSceneLay->addWidget(m_nameFld, 0, 1, 1, 5);
// Save In
// newSceneLay->addWidget(new QLabel(tr("Save In:")), 1, 0,
// Qt::AlignRight | Qt::AlignVCenter);
newSceneLay->addWidget(m_pathFld, 1, 1, 1, 5);
m_pathFld->hide();
newSceneLay->addWidget(new QLabel(tr("Preset:")), 2, 0,
@ -249,9 +249,7 @@ StartupPopup::StartupPopup()
newSceneLay->addWidget(m_resXFld, 4, 1);
newSceneLay->addWidget(m_resXLabel, 4, 2, 1, 1, Qt::AlignCenter);
newSceneLay->addWidget(m_resYFld, 4, 3);
// newSceneLay->addWidget(m_fpsLabel, 5, 0,
// Qt::AlignRight | Qt::AlignVCenter);
// newSceneLay->addWidget(m_fpsFld, 5, 1, 1, 1);
newSceneLay->addWidget(createButton, 6, 1, 1, 3, Qt::AlignLeft);
newSceneLay->setColumnStretch(4, 1);
}
@ -320,16 +318,16 @@ StartupPopup::StartupPopup()
SLOT(onAutoSaveOnChanged(int)));
ret = ret && connect(m_autoSaveTimeFld, SIGNAL(editingFinished()), this,
SLOT(onAutoSaveTimeChanged()));
ret = ret && connect(m_projectLocationFld, SIGNAL(pathChanged()), this,
SLOT(checkProject()));
ret = ret && connect(m_projectsCB, SIGNAL(currentIndexChanged(int)), this,
SLOT(onProjectComboChanged(int)));
assert(ret);
checkProject();
}
//-----------------------------------------------------------------------------
void StartupPopup::showEvent(QShowEvent *) {
loadPresetList();
updateProjectCB();
m_nameFld->setFocus();
m_pathFld->setPath(TApp::instance()
->getCurrentScene()
@ -443,21 +441,93 @@ void StartupPopup::refreshRecentScenes() {
//-----------------------------------------------------------------------------
void StartupPopup::onCreateButton() {
void StartupPopup::updateProjectCB() {
m_updating = true;
m_projectPaths.clear();
m_projectsCB->clear();
TProjectManager *pm = TProjectManager::instance();
TFilePath projectFolder = TFilePath(m_projectLocationFld->getPath());
TFilePath projectPath = pm->projectFolderToProjectPath(projectFolder);
if (!checkProject()) {
DVGui::warning(
tr("The project needs to be a valid project.\n"
"Please select a valid project or create a new project."));
m_projectLocationFld->setFocus();
QString currentProjectPath =
pm->getCurrentProjectPath().getParentDir().getQString();
RecentFiles::instance()->addFilePath(currentProjectPath,
RecentFiles::Project);
TFilePath sandboxFp = pm->getSandboxProjectFolder() + "sandbox_otprj.xml";
m_projectPaths.push_back(sandboxFp);
m_projectsCB->addItem("sandbox");
m_projectsCB->setItemData(0, pm->getSandboxProjectFolder().getQString(),
Qt::ToolTipRole);
QList<QString> recentProjects =
RecentFiles::instance()->getFilesNameList(RecentFiles::Project);
int j = 1;
for (int i = 0; i < recentProjects.size(); i++) {
TFilePath fp(recentProjects.at(i));
if (pm->isProject(fp) &&
recentProjects.at(i) != pm->getSandboxProjectFolder().getQString()) {
m_projectPaths.push_back(pm->projectFolderToProjectPath(fp));
TFilePath prjFile = pm->getProjectPathByProjectFolder(fp);
m_projectsCB->addItem(QString::fromStdString(prjFile.getName()));
m_projectsCB->setItemData(j, recentProjects.at(i), Qt::ToolTipRole);
j++;
}
}
m_projectsCB->addItem(tr("Browse..."));
m_projectsCB->setItemData(j, tr("Open a different project."),
Qt::ToolTipRole);
int i;
for (i = 0; i < m_projectPaths.size(); i++) {
if (pm->getCurrentProjectPath() == m_projectPaths[i]) {
m_projectsCB->setCurrentIndex(i);
break;
}
}
m_pathFld->setPath(TApp::instance()
->getCurrentScene()
->getScene()
->getProject()
->getScenesPath()
.getQString());
m_updating = false;
}
//-----------------------------------------------------------------------------
void StartupPopup::onProjectComboChanged(int index) {
if (m_updating) return;
TProjectManager *pm = TProjectManager::instance();
// The last index is Browse. . .
if (index == m_projectsCB->count() - 1) {
m_projectsCB->blockSignals(true);
for (int i = 0; i < m_projectPaths.size(); i++) {
if (pm->getCurrentProjectPath() == m_projectPaths[i]) {
m_projectsCB->setCurrentIndex(i);
break;
}
}
m_projectsCB->blockSignals(false);
m_projectLocationFld->setPath(
Preferences::instance()->getDefaultProjectPath());
m_projectLocationFld->forceOpenBrowser();
return;
}
assert(TFileStatus(projectPath).doesExist());
pm->setCurrentProjectPath(projectPath);
TFilePath projectFp = m_projectPaths[index];
pm->setCurrentProjectPath(projectFp);
TProjectP currentProject = pm->getCurrentProject();
// In case the project file was upgraded to current version, save it now
if (currentProject->getProjectPath() != projectFp) {
m_projectPaths[index] = currentProject->getProjectPath();
currentProject->save();
}
IoCmd::newScene();
m_pathFld->setPath(TApp::instance()
->getCurrentScene()
@ -465,6 +535,36 @@ void StartupPopup::onCreateButton() {
->getProject()
->getScenesPath()
.getQString());
m_fpsFld->setValue(TApp::instance()
->getCurrentScene()
->getScene()
->getProperties()
->getOutputProperties()
->getFrameRate());
TDimension res = TApp::instance()
->getCurrentScene()
->getScene()
->getCurrentCamera()
->getRes();
m_xRes = res.lx;
m_yRes = res.ly;
m_resXFld->setValue(m_xRes);
m_resYFld->setValue(m_yRes);
TDimensionD size = TApp::instance()
->getCurrentScene()
->getScene()
->getCurrentCamera()
->getSize();
m_widthFld->setValue(size.lx);
m_heightFld->setValue(size.ly);
m_dpi = 120.0;
RecentFiles::instance()->addFilePath(projectFp.getParentDir().getQString(),
RecentFiles::Project);
}
//-----------------------------------------------------------------------------
void StartupPopup::onCreateButton() {
if (m_nameFld->text().trimmed() == "") {
DVGui::warning(tr("The name cannot be empty."));
m_nameFld->setFocus();
@ -555,7 +655,15 @@ void StartupPopup::onProjectLocationChanged() {
if (!TSystem::doesExistFileOrLevel(path)) {
DVGui::warning(tr(
"This is not a valid folder. Please choose an existing location."));
checkProject();
// checkProject();
m_projectsCB->blockSignals(true);
for (int i = 0; i < m_projectPaths.size(); i++) {
if (pm->getCurrentProjectPath() == m_projectPaths[i]) {
m_projectsCB->setCurrentIndex(i);
break;
}
}
m_projectsCB->blockSignals(false);
return;
}
}
@ -573,13 +681,38 @@ void StartupPopup::onProjectLocationChanged() {
->getProject()
->getProjectFolder()
.getQString());
m_projectsCB->blockSignals(true);
for (int i = 0; i < m_projectPaths.size(); i++) {
if (pm->getCurrentProjectPath() == m_projectPaths[i]) {
m_projectsCB->setCurrentIndex(i);
break;
}
}
m_projectsCB->blockSignals(false);
} else {
// Put the combo box back in case of cancelling
m_projectsCB->blockSignals(true);
for (int i = 0; i < m_projectPaths.size(); i++) {
if (pm->getCurrentProjectPath() == m_projectPaths[i]) {
m_projectsCB->setCurrentIndex(i);
break;
}
}
m_projectsCB->blockSignals(false);
ProjectCreatePopup *popup = new ProjectCreatePopup();
popup->setPath(path.getQString());
popup->exec();
}
} else {
if (!IoCmd::saveSceneIfNeeded(QObject::tr("Change Project"))) {
m_projectsCB->blockSignals(true);
for (int i = 0; i < m_projectPaths.size(); i++) {
if (pm->getCurrentProjectPath() == m_projectPaths[i]) {
m_projectsCB->setCurrentIndex(i);
break;
}
}
m_projectsCB->blockSignals(false);
m_projectLocationFld->blockSignals(true);
m_projectLocationFld->setPath(TApp::instance()
->getCurrentScene()
@ -600,7 +733,8 @@ void StartupPopup::onProjectLocationChanged() {
if (projectP->getProjectPath() != projectPath) {
projectP->save();
}
RecentFiles::instance()->addFilePath(
projectPath.getParentDir().getQString(), RecentFiles::Project);
IoCmd::newScene();
}
}
@ -897,6 +1031,7 @@ void StartupPopup::onSceneChanged() {
->getProjectFolder();
std::string pathStr = path.getQString().toStdString();
m_projectLocationFld->setPath(path.getQString());
updateProjectCB();
}
}
@ -957,6 +1092,10 @@ void StartupPopup::onRecentSceneClicked(int index) {
} else
RecentFiles::instance()->moveFilePath(index, 0, RecentFiles::Scene);
RecentFiles::instance()->refreshRecentFilesMenu(RecentFiles::Scene);
TFilePath projectPath =
TProjectManager::instance()->getCurrentProjectPath();
RecentFiles::instance()->addFilePath(
projectPath.getParentDir().getQString(), RecentFiles::Project);
hide();
}
}
@ -1059,22 +1198,6 @@ void StartupPopup::updateSize() {
//-----------------------------------------------------------------------------
bool StartupPopup::checkProject() {
TFilePath currPath = TFilePath(m_projectLocationFld->getPath());
bool isProject = TProjectManager::instance()->isProject(currPath);
if (isProject) {
m_projectLocationFld->getField()->setStyleSheet(
m_pathFld->getField()->styleSheet());
m_projectLocationFld->setToolTip(tr(""));
} else {
m_projectLocationFld->getField()->setStyleSheet("color: red;");
m_projectLocationFld->setToolTip(tr("Not a valid project location"));
}
return isProject;
}
//-----------------------------------------------------------------------------
StartupLabel::StartupLabel(const QString &text, QWidget *parent, int index)
: QLabel(parent), m_index(index) {
setText(text);

View file

@ -50,6 +50,7 @@ class StartupPopup final : public DVGui::Dialog {
QPushButton *m_loadOtherSceneButton;
QPushButton *m_newProjectButton;
QComboBox *m_presetCombo;
QComboBox *m_projectsCB;
QPushButton *m_addPresetBtn, *m_removePresetBtn;
CameraSettingsWidget *m_cameraSettingsWidget;
double m_dpi;
@ -76,9 +77,11 @@ protected:
bool parsePresetString(const QString &str, QString &name, int &xres,
int &yres, double &fx, double &fy, QString &xoffset,
QString &yoffset, double &ar, bool forCleanup = false);
void updateProjectCB();
public slots:
void onRecentSceneClicked(int index);
void onProjectComboChanged(int index);
void onCreateButton();
void onShowAtStartChanged(int index);
void onProjectChanged(int index);
@ -94,7 +97,6 @@ public slots:
void onCameraUnitChanged(int index);
void onAutoSaveOnChanged(int index);
void onAutoSaveTimeChanged();
bool checkProject();
void onProjectLocationChanged();
};

View file

@ -26,6 +26,7 @@
#include <QStringList>
#include <QAction>
#include <QColor>
#include <QStandardPaths>
// boost includes
#include <boost/bind.hpp>
@ -436,6 +437,11 @@ void Preferences::definePreferenceItems() {
setCallBack(rasterBackgroundColor, &Preferences::setRasterBackgroundColor);
QString documentsPath =
QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation)[0];
define(defaultProjectPath, "defaultProjectPath", QMetaType::QString,
documentsPath);
// Import / Export
define(ffmpegPath, "ffmpegPath", QMetaType::QString, "");
define(ffmpegTimeout, "ffmpegTimeout", QMetaType::Int, 600, 1,

View file

@ -90,6 +90,27 @@ FileField::BrowserPopupController *FileField::getBrowserPopupController() {
//-----------------------------------------------------------------------------
void FileField::forceOpenBrowser() {
QString directory = QString();
if (!m_browserPopupController) return;
m_browserPopupController->openPopup(
m_filters, (m_fileMode == QFileDialog::DirectoryOnly),
(m_lastSelectedPath == m_descriptionText) ? "" : m_lastSelectedPath,
this);
if (m_browserPopupController->isExecute())
directory = m_browserPopupController->getPath(m_codePath);
if (!directory.isEmpty()) {
setPath(directory);
m_lastSelectedPath = directory;
emit pathChanged();
return;
}
}
//-----------------------------------------------------------------------------
void FileField::browseDirectory() {
if (!m_fileBrowseButton->hasFocus()) return;
QString directory = QString();