Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ if (ENABLE_TESTS)
test/testimageutils.cpp
test/testlayertree.cpp
test/testlinks.cpp
test/testlocalprojectsmanager.cpp
test/testmaptools.cpp
test/testmerginapi.cpp
test/testmodels.cpp
Expand Down Expand Up @@ -268,6 +269,7 @@ if (ENABLE_TESTS)
test/testimageutils.h
test/testlayertree.h
test/testlinks.h
test/testlocalprojectsmanager.h
test/testmaptools.h
test/testmerginapi.h
test/testmodels.h
Expand Down
12 changes: 12 additions & 0 deletions app/activeproject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ ActiveProject::ActiveProject( AppSettings &appSettings
}
} );

// listen to local project rename event to unload mProject before it is renamed on disk
QObject::connect(
&mLocalProjectsManager,
&LocalProjectsManager::aboutToRenameLocalProject,
this, [this]( const QString & projectId )
{
if ( projectId == mLocalProject.id() )
{
load( QLatin1String() );
}
} );

// listen to metadata changes of opened LocalProject (e.g. local version update or namespace update)
QObject::connect(
&mLocalProjectsManager,
Expand Down
27 changes: 27 additions & 0 deletions app/projectsmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ void ProjectsModel::initializeProjectsModel()
QObject::connect( mLocalProjectsManager, &LocalProjectsManager::localProjectAdded, this, &ProjectsModel::onProjectAdded );
QObject::connect( mLocalProjectsManager, &LocalProjectsManager::aboutToRemoveLocalProject, this, &ProjectsModel::onAboutToRemoveProject );
QObject::connect( mLocalProjectsManager, &LocalProjectsManager::localProjectDataChanged, this, &ProjectsModel::onProjectDataChanged );
QObject::connect( mLocalProjectsManager, &LocalProjectsManager::localProjectRenamed, this, &ProjectsModel::onProjectRenamed );
QObject::connect( mLocalProjectsManager, &LocalProjectsManager::renameLocalProjectFinished, this, &ProjectsModel::renameLocalProjectFinished );
QObject::connect( mLocalProjectsManager, &LocalProjectsManager::dataDirReloaded, this, &ProjectsModel::loadLocalProjects );

emit modelInitialized();
Expand Down Expand Up @@ -380,6 +382,31 @@ void ProjectsModel::removeLocalProject( const QString &projectId )
mLocalProjectsManager->removeLocalProject( projectId );
}

QString ProjectsModel::canRenameProject( const QString &projectId, const QString &newName ) const
{
return mLocalProjectsManager->validateRename( projectId, newName );
}

void ProjectsModel::renameLocalProject( const QString &projectId, const QString &newName )
{
mLocalProjectsManager->renameLocalProject( projectId, newName );
}

void ProjectsModel::onProjectRenamed( const QString &oldProjectId, const LocalProject &localProject )
{
int ix = projectIndexFromId( oldProjectId );

if ( ix < 0 )
return;

Project &project = mProjects[ix];

project.local = localProject;

QModelIndex editIndex = index( ix );
emit dataChanged( editIndex, editIndex );
}

void ProjectsModel::migrateProject( const QString &projectId )
{
int ix = projectIndexFromId( projectId );
Expand Down
9 changes: 9 additions & 0 deletions app/projectsmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ class ProjectsModel : public QAbstractListModel
//! Forwards call to LocalProjectsManager to remove local project
Q_INVOKABLE void removeLocalProject( const QString &projectId );

//! Forwards call to LocalProjectsManager to check whether a rename is valid
Q_INVOKABLE QString canRenameProject( const QString &projectId, const QString &newName ) const;

//! Forwards call to LocalProjectsManager to rename local project
Q_INVOKABLE void renameLocalProject( const QString &projectId, const QString &newName );

//! Migrates local project to mergin
Q_INVOKABLE void migrateProject( const QString &projectId );

Expand Down Expand Up @@ -170,6 +176,7 @@ class ProjectsModel : public QAbstractListModel
void onProjectAdded( const LocalProject &project );
void onAboutToRemoveProject( const LocalProject &project );
void onProjectDataChanged( const LocalProject &project );
void onProjectRenamed( const QString &oldProjectId, const LocalProject &project );

void onAuthChanged();

Expand All @@ -193,6 +200,8 @@ class ProjectsModel : public QAbstractListModel

void activeProjectIdChanged( QString projectId );

void renameLocalProjectFinished( bool success );

private:

int projectIndexFromId( const QString &projectId ) const;
Expand Down
1 change: 1 addition & 0 deletions app/qml/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ set(MM_QML
project/components/MMProjectStatusItem.qml
project/components/MMProjectWizardDelegate.qml
project/components/MMProjectDelegate.qml
project/components/MMRenameProjectDialog.qml
settings/MMAboutPage.qml
settings/MMChangelogPage.qml
settings/MMLogPage.qml
Expand Down
58 changes: 57 additions & 1 deletion app/qml/project/MMProjectList.qml
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ Item {
return ["changes", "remove"]
}
else if ( !model.ProjectIsMergin && model.ProjectIsLocal ) {
return ["upload", "remove"]
return ["upload", "remove", "rename"]
}
return ["download"]
}
Expand Down Expand Up @@ -176,6 +176,10 @@ Item {
}
onStopSyncRequested: controllerModel.stopProjectSync( projectId )
onShowChangesRequested: root.showLocalChangesRequested( projectId )
onRenameRequested: () => {
renameDialogLoader.projectIdToRename = projectId
renameDialogLoader.active = true
}
}
}

Expand Down Expand Up @@ -306,6 +310,58 @@ Item {
}
}

Loader {
id: renameDialogLoader

property string projectIdToRename: ""

active: false
asynchronous: true

sourceComponent: MMProjectComponents.MMRenameProjectDialog {
id: renameDialog

onRenameClicked: function( newName ) {
if ( !renameDialogLoader.projectIdToRename ) {
return
}

controllerModel.renameLocalProject( renameDialogLoader.projectIdToRename, newName )
}

onTextEdited: function( text ) {
canRenameCheckTimer.pendingText = text
canRenameCheckTimer.restart()
}

Comment thread
xkello marked this conversation as resolved.
onClosed: renameDialogLoader.active = false

Component.onCompleted: open()

Connections {
target: controllerModel

function onRenameLocalProjectFinished( success ) {
if ( success ) {
renameDialog.close()
}
}
}

Timer {
id: canRenameCheckTimer

property string pendingText: ""

interval: 300

onTriggered: {
renameDialog.errorText = controllerModel.canRenameProject( renameDialogLoader.projectIdToRename, pendingText )
}
}
}
}

MMDownloadProjectDialog {
id: downloadProjectDialog

Expand Down
8 changes: 7 additions & 1 deletion app/qml/project/components/MMProjectDelegate.qml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Control {
property bool projectIsInSync: false
property real projectSyncProgress: 0.0

property var projectActionButtons: [] // possible values: upload, changes, sync, download, remove
property var projectActionButtons: [] // possible values: upload, changes, sync, download, remove, rename

property bool projectIsOpened: false

Expand All @@ -35,6 +35,7 @@ Control {
signal removeRequested()
signal stopSyncRequested()
signal showChangesRequested()
signal renameRequested()

height: implicitHeight

Expand Down Expand Up @@ -307,6 +308,11 @@ Control {
"name": qsTr("Upload"),
"iconSource": __style.uploadIcon,
"callback": () => root.migrateRequested()
},
"rename": {
"name": qsTr("Rename project"),
"iconSource": __style.editIcon,
"callback": () => root.renameRequested()
}
}
}
Expand Down
61 changes: 61 additions & 0 deletions app/qml/project/components/MMRenameProjectDialog.qml
Comment thread
Withalion marked this conversation as resolved.
Comment thread
xkello marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

import QtQuick

import "../../components"
import "../../inputs"

MMDrawer {
id: root

property alias errorText: newNameField.errorMsg

signal renameClicked( string newName )
signal textEdited( string text )

drawerHeader.title: qsTr( "Rename project" )
drawerHeader.titleFont: __style.t2

onAboutToShow: () => {
newNameField.errorMsg = ""
newNameField.text = ""
}

drawerContent: Column {
id: contentColumn

width: parent.width
spacing: newNameField.errorMsg ? __style.margin12 : __style.spacing40

MMTextInput {
id: newNameField

width: contentColumn.width
textFieldBackground.color: __style.lightGreenColor

placeholderText: qsTr( "Enter the new name" )
Comment thread
Withalion marked this conversation as resolved.

onTextEdited: ( text ) => {
newNameField.errorMsg = ""
root.textEdited( text )
}
}

MMButton {
width: contentColumn.width

text: qsTr( "Confirm" )

onClicked: {
root.renameClicked( newNameField.text )
}
}
}
}
6 changes: 6 additions & 0 deletions app/test/inputtests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "testimageutils.h"
#include "testmaptools.h"
#include "testlayertree.h"
#include "testlocalprojectsmanager.h"
#include "testactiveproject.h"
#include "testprojectchecksumcache.h"
#include "testmultieditmanager.h"
Expand Down Expand Up @@ -172,6 +173,11 @@ int InputTests::runTest() const
TestLayerTree layerTreeTest;
nFailed = QTest::qExec( &layerTreeTest, mTestArgs );
}
else if ( mTestRequested == "--testLocalProjectsManager" )
{
TestLocalProjectsManager localProjectsManagerTest;
nFailed = QTest::qExec( &localProjectsManagerTest, mTestArgs );
}
else if ( mTestRequested == "--testActiveProject" )
{
TestActiveProject activeProjectTest( mApi );
Expand Down
Loading
Loading