Fixed copy and paste.

This commit is contained in:
leo
2014-12-15 23:55:17 +00:00
parent b20d52e2f9
commit b3d8fafeb4
12 changed files with 255 additions and 241 deletions
+30
View File
@@ -34,3 +34,33 @@ void lcGroup::FileSave(lcFile* File, const lcArray<lcGroup*>& Groups)
lcint32 GroupIndex = Groups.FindIndex(mGroup);
File->WriteS32(&GroupIndex, 1);
}
void lcGroup::CreateName(const lcArray<lcGroup*>& Groups)
{
if (m_strName[0])
{
bool Found = false;
for (int GroupIdx = 0; GroupIdx < Groups.GetSize(); GroupIdx++)
{
if (!strcmp(Groups[GroupIdx]->m_strName, m_strName))
{
Found = true;
break;
}
}
if (!Found)
return;
}
int i, max = 0;
const char* Prefix = "Group ";
for (int GroupIdx = 0; GroupIdx < Groups.GetSize(); GroupIdx++)
if (strncmp(Groups[GroupIdx]->m_strName, Prefix, strlen(Prefix)) == 0)
if (sscanf(Groups[GroupIdx]->m_strName + strlen(Prefix), " %d", &i) == 1)
if (i > max)
max = i;
sprintf(m_strName, "%s %d", Prefix, max+1);
}
+1
View File
@@ -18,6 +18,7 @@ public:
void FileLoad(lcFile* File);
void FileSave(lcFile* File, const lcArray<lcGroup*>& Groups);
void CreateName(const lcArray<lcGroup*>& Groups);
lcGroup* mGroup;
char m_strName[LC_MAX_GROUP_NAME + 1];
+2 -5
View File
@@ -65,7 +65,6 @@ lcApplication::lcApplication()
lcApplication::~lcApplication()
{
delete mClipboard;
delete mLibrary;
}
@@ -82,12 +81,10 @@ void lcApplication::SetProject(Project* Project)
gMainWindow->UpdateTitle();
}
void lcApplication::SetClipboard(lcFile* Clipboard)
void lcApplication::SetClipboard(const QByteArray& Clipboard)
{
delete mClipboard;
mClipboard = Clipboard;
gMainWindow->UpdatePaste(mClipboard != NULL);
gMainWindow->UpdatePaste(!mClipboard.isEmpty());
}
bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* LibraryInstallPath, const char* LDrawPath, const char* LibraryCachePath)
+3 -3
View File
@@ -52,13 +52,13 @@ public:
void OpenURL(const char* URL);
void RunProcess(const char* ExecutablePath, const lcArray<String>& Arguments);
void GetFileList(const char* Path, lcArray<String>& FileList);
void SetClipboard(lcFile* Clipboard);
void ExportClipboard(lcMemFile* Clipboard);
void SetClipboard(const QByteArray& Clipboard);
void ExportClipboard(const QByteArray& Clipboard);
Project* mProject;
lcPiecesLibrary* mLibrary;
lcPreferences mPreferences;
lcFile* mClipboard;
QByteArray mClipboard;
protected:
void ParseIntegerArgument(int* CurArg, int argc, char* argv[], int* Value);
+76 -200
View File
@@ -202,6 +202,70 @@ bool lcMainWindow::OpenProject(const QString& FileName)
return false;
}
void lcMainWindow::MergeProject()
{
/*
QString LoadFileName = FileName;
if (LoadFileName.isEmpty())
{
LoadFileName = lcGetActiveProject()->GetFileName();
if (LoadFileName.isEmpty())
LoadFileName = lcGetProfileString(LC_PROFILE_PROJECTS_PATH);
LoadFileName = QFileDialog::getOpenFileName(mHandle, tr("Open Project"), LoadFileName, tr("Supported Files (*.lcd *.ldr *.dat *.mpd);;All Files (*.*)"));
if (LoadFileName.isEmpty())
return false;
}
Project* NewProject = new Project();
if (NewProject->Load(LoadFileName))
{
g_App->SetProject(NewProject);
AddRecentFile(LoadFileName);
return true;
}
QMessageBox::information(mHandle, tr("LeoCAD"), tr("Error loading '%1'.").arg(LoadFileName));
delete NewProject;
return false;
*/
/*
case LC_FILE_MERGE:
{
QString FileName;
if (!mFileName.isEmpty())
FileName = mFileName;
else
FileName = lcGetProfileString(LC_PROFILE_PROJECTS_PATH);
FileName = QFileDialog::getOpenFileName(gMainWindow->mHandle, tr("Merge Project"), FileName, tr("Supported Files (*.lcd *.ldr *.dat *.mpd);;All Files (*.*)"));
if (!FileName.isEmpty())
{
// todo: detect format
lcDiskFile file;
if (file.Open(FileName.toLatin1().constData(), "rb")) // todo: qstring
{
if (file.GetLength() != 0)
{
FileLoad(&file, false, true);
CheckPoint("Merging");
}
file.Close();
}
}
} break;
*/
}
bool lcMainWindow::SaveProject(const QString& FileName)
{
QString SaveFileName;
@@ -272,34 +336,11 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId)
case LC_FILE_OPEN:
OpenProject(QString());
break;
/*
case LC_FILE_MERGE:
{
QString FileName;
if (!mFileName.isEmpty())
FileName = mFileName;
else
FileName = lcGetProfileString(LC_PROFILE_PROJECTS_PATH);
case LC_FILE_MERGE:
MergeProject();
break;
FileName = QFileDialog::getOpenFileName(gMainWindow->mHandle, tr("Merge Project"), FileName, tr("Supported Files (*.lcd *.ldr *.dat *.mpd);;All Files (*.*)"));
if (!FileName.isEmpty())
{
// todo: detect format
lcDiskFile file;
if (file.Open(FileName.toLatin1().constData(), "rb")) // todo: qstring
{
if (file.GetLength() != 0)
{
FileLoad(&file, false, true);
CheckPoint("Merging");
}
file.Close();
}
}
} break;
*/
case LC_FILE_SAVE:
SaveProject(lcGetActiveProject()->GetFileName());
break;
@@ -371,184 +412,19 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId)
case LC_EDIT_REDO:
lcGetActiveModel()->RedoAction();
break;
/*
case LC_EDIT_CUT:
lcGetActiveModel()->Cut();
break;
case LC_EDIT_COPY:
{
lcMemFile* Clipboard = new lcMemFile();
lcGetActiveModel()->Copy();
break;
int i = 0;
// lcLight* pLight;
case LC_EDIT_PASTE:
lcGetActiveModel()->Paste();
break;
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
if (mPieces[PieceIdx]->IsSelected())
i++;
Clipboard->WriteBuffer(&i, sizeof(i));
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
{
lcPiece* Piece = mPieces[PieceIdx];
if (Piece->IsSelected())
Piece->FileSave(*Clipboard);
}
i = mGroups.GetSize();
Clipboard->WriteBuffer(&i, sizeof(i));
for (int GroupIdx = 0; GroupIdx < mGroups.GetSize(); GroupIdx++)
mGroups[GroupIdx]->FileSave(Clipboard, mGroups);
i = 0;
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
if (mCameras[CameraIdx]->IsSelected())
i++;
Clipboard->WriteBuffer(&i, sizeof(i));
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
{
lcCamera* pCamera = mCameras[CameraIdx];
if (pCamera->IsSelected())
pCamera->FileSave(*Clipboard);
}
// for (i = 0, pLight = m_pLights; pLight; pLight = pLight->m_pNext)
// if (pLight->IsSelected())
// i++;
// Clipboard->Write(&i, sizeof(i));
// for (pLight = m_pLights; pLight; pLight = pLight->m_pNext)
// if (pLight->IsSelected())
// pLight->FileSave(Clipboard);
if (id == LC_EDIT_CUT)
{
RemoveSelectedObjects();
gMainWindow->UpdateFocusObject(GetFocusObject());
UpdateSelection();
gMainWindow->UpdateAllViews();
CheckPoint("Cutting");
}
g_App->ExportClipboard(Clipboard);
} break;
case LC_EDIT_PASTE:
{
lcFile* file = g_App->mClipboard;
if (file == NULL)
break;
file->Seek(0, SEEK_SET);
ClearSelection(false);
lcArray<lcPiece*> PastedPieces;
int NumPieces;
file->ReadBuffer(&NumPieces, sizeof(NumPieces));
while (NumPieces--)
{
lcPiece* Piece = new lcPiece(NULL);
Piece->FileLoad(*file);
PastedPieces.Add(Piece);
}
lcArray<lcGroup*> Groups;
int NumGroups;
file->ReadBuffer(&NumGroups, sizeof(NumGroups));
while (NumGroups--)
{
lcGroup* Group = new lcGroup();
Group->FileLoad(file);
Groups.Add(Group);
}
for (int PieceIdx = 0; PieceIdx < PastedPieces.GetSize(); PieceIdx++)
{
lcPiece* Piece = PastedPieces[PieceIdx];
Piece->CreateName(mPieces);
Piece->SetStepShow(mCurrentStep);
mPieces.Add(Piece);
Piece->SetSelected(true);
int GroupIndex = LC_POINTER_TO_INT(Piece->GetGroup());
if (GroupIndex != -1)
Piece->SetGroup(Groups[GroupIndex]);
else
Piece->SetGroup(NULL);
}
for (int GroupIdx = 0; GroupIdx < Groups.GetSize(); GroupIdx++)
{
lcGroup* Group = Groups[GroupIdx];
int GroupIndex = LC_POINTER_TO_INT(Group->mGroup);
Group->mGroup = (GroupIndex != -1) ? Groups[GroupIndex] : NULL;
}
for (int GroupIdx = 0; GroupIdx < Groups.GetSize(); GroupIdx++)
{
lcGroup* Group = Groups[GroupIdx];
bool Add = false;
for (int PieceIdx = 0; PieceIdx < PastedPieces.GetSize(); PieceIdx++)
{
lcPiece* Piece = PastedPieces[PieceIdx];
for (lcGroup* PieceGroup = Piece->GetGroup(); PieceGroup; PieceGroup = PieceGroup->mGroup)
{
if (PieceGroup == Group)
{
Add = true;
break;
}
}
if (Add)
break;
}
if (Add)
{
int a, max = 0;
for (int SearchGroupIdx = 0; SearchGroupIdx < mGroups.GetSize(); SearchGroupIdx++)
{
lcGroup* SearchGroup = mGroups[SearchGroupIdx];
if (strncmp("Pasted Group #", SearchGroup ->m_strName, 14) == 0)
if (sscanf(SearchGroup ->m_strName + 14, "%d", &a) == 1)
if (a > max)
max = a;
}
sprintf(Group->m_strName, "Pasted Group #%.2d", max+1);
mGroups.Add(Group);
}
else
delete Group;
}
int NumCameras;
file->ReadBuffer(&NumCameras, sizeof(NumCameras));
while (NumCameras--)
{
lcCamera* pCamera = new lcCamera(false);
pCamera->FileLoad(*file);
pCamera->CreateName(mCameras);
pCamera->SetSelected(true);
mCameras.Add(pCamera);
}
// TODO: lights
CalculateStep();
CheckPoint("Pasting");
gMainWindow->UpdateFocusObject(GetFocusObject());
UpdateSelection();
gMainWindow->UpdateAllViews();
} break;
*/
case LC_EDIT_FIND:
if (gMainWindow->DoDialog(LC_DIALOG_FIND, &gMainWindow->mSearchOptions))
lcGetActiveModel()->FindPiece(true, true);
+1
View File
@@ -130,6 +130,7 @@ public:
void Close();
void NewProject();
bool OpenProject(const QString& FileName);
void MergeProject();
bool SaveProject(const QString& FileName);
bool SaveProjectIfModified();
void HandleCommand(lcCommandId CommandId);
+101 -19
View File
@@ -147,9 +147,6 @@ lcModel::lcModel(const QString& Name)
mProperties.mName = Name;
mProperties.LoadDefaults();
SaveCheckpoint("");
SetSaved();
mCurrentStep = 1;
mBackgroundTexture = NULL;
}
@@ -188,7 +185,7 @@ void lcModel::DeleteModel()
mGroups.DeleteAll();
}
void lcModel::SaveLDraw(QTextStream& Stream) const
void lcModel::SaveLDraw(QTextStream& Stream, bool SelectedOnly) const
{
QLatin1String LineEnding("\r\n");
@@ -206,7 +203,7 @@ void lcModel::SaveLDraw(QTextStream& Stream) const
{
lcPiece* Piece = mPieces[PieceIdx];
if (Piece->GetStepShow() != Step)
if (Piece->GetStepShow() != Step || (SelectedOnly && !Piece->IsSelected()))
continue;
lcGroup* PieceGroup = Piece->GetGroup();
@@ -270,10 +267,22 @@ void lcModel::SaveLDraw(QTextStream& Stream) const
}
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
mCameras[CameraIdx]->SaveLDraw(Stream);
{
lcCamera* Camera = mCameras[CameraIdx];
if (!SelectedOnly || Camera->IsSelected())
Camera->SaveLDraw(Stream);
}
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
mLights[LightIdx]->SaveLDraw(Stream);
{
lcLight* Light = mLights[LightIdx];
if (!SelectedOnly || Light->IsSelected())
Light->SaveLDraw(Stream);
}
Stream.flush();
}
void lcModel::LoadLDraw(QTextStream& Stream)
@@ -437,10 +446,6 @@ void lcModel::LoadLDraw(QTextStream& Stream)
}
}
DeleteHistory();
SaveCheckpoint("");
SetSaved();
CalculateStep();
UpdateBackgroundTexture();
@@ -739,13 +744,9 @@ bool lcModel::LoadBinary(lcFile* file)
mProperties.mBackgroundGradientColor2[2] = (float)((unsigned char) ((rgb) >> 16))/255;
}
DeleteHistory();
SaveCheckpoint("");
SetSaved();
UpdateBackgroundTexture();
CalculateStep();
/*
gMainWindow->UpdateFocusObject(GetFocusObject());
const lcArray<View*>& Views = gMainWindow->GetViews();
@@ -765,10 +766,91 @@ bool lcModel::LoadBinary(lcFile* file)
UpdateSelection();
gMainWindow->UpdateCurrentStep();
gMainWindow->UpdateAllViews();
*/
return true;
}
void lcModel::Merge(lcModel* Other)
{
for (int PieceIdx = 0; PieceIdx < Other->mPieces.GetSize(); PieceIdx++)
{
lcPiece* Piece = Other->mPieces[PieceIdx];
Piece->CreateName(mPieces);
mPieces.Add(Piece);
}
Other->mPieces.RemoveAll();
for (int CameraIdx = 0; CameraIdx < Other->mCameras.GetSize(); CameraIdx++)
{
lcCamera* Camera = Other->mCameras[CameraIdx];
Camera->CreateName(mCameras);
mCameras.Add(Camera);
}
Other->mCameras.RemoveAll();
for (int LightIdx = 0; LightIdx < Other->mLights.GetSize(); LightIdx++)
{
lcLight* Light = Other->mLights[LightIdx];
Light->CreateName(mLights);
mLights.Add(Light);
}
Other->mLights.RemoveAll();
for (int GroupIdx = 0; GroupIdx < Other->mGroups.GetSize(); GroupIdx++)
{
lcGroup* Group = Other->mGroups[GroupIdx];
Group->CreateName(mGroups);
mGroups.Add(Group);
}
Other->mGroups.RemoveAll();
delete Other;
}
void lcModel::Cut()
{
Copy();
if (RemoveSelectedObjects())
{
gMainWindow->UpdateFocusObject(NULL);
UpdateSelection();
gMainWindow->UpdateAllViews();
SaveCheckpoint("Cutting");
}
}
void lcModel::Copy()
{
QByteArray File;
QTextStream Stream(&File, QIODevice::WriteOnly);
SaveLDraw(Stream, true);
g_App->ExportClipboard(File);
}
void lcModel::Paste()
{
if (g_App->mClipboard.isEmpty())
return;
lcModel* Model = new lcModel(QString());
QTextStream Stream(&g_App->mClipboard);
Model->LoadLDraw(Stream);
Merge(Model);
SaveCheckpoint(tr("Pasting"));
CalculateStep();
gMainWindow->UpdateAllViews();
}
void lcModel::GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface) const
{
Scene.Camera = ViewCamera;
@@ -985,7 +1067,7 @@ void lcModel::SaveCheckpoint(const QString& Description)
ModelHistoryEntry->Description = Description;
QTextStream Stream(&ModelHistoryEntry->File);
SaveLDraw(Stream);
SaveLDraw(Stream, false);
mUndoHistory.InsertAt(0, ModelHistoryEntry);
mRedoHistory.DeleteAll();
@@ -3293,7 +3375,7 @@ void lcModel::ShowMinifigDialog()
void lcModel::UpdateInterface()
{
gMainWindow->UpdateUndoRedo(mUndoHistory.GetSize() > 1 ? mUndoHistory[0]->Description : NULL, !mRedoHistory.IsEmpty() ? mRedoHistory[0]->Description : NULL);
gMainWindow->UpdatePaste(g_App->mClipboard != NULL);
gMainWindow->UpdatePaste(!g_App->mClipboard.isEmpty());
gMainWindow->UpdateCategories();
gMainWindow->UpdateTitle();
gMainWindow->SetTool(gMainWindow->GetTool());
+10 -1
View File
@@ -182,14 +182,23 @@ public:
void RemoveFocusPieceFromGroup();
void ShowEditGroupsDialog();
void SaveLDraw(QTextStream& Stream) const;
void SaveLDraw(QTextStream& Stream, bool SelectedOnly) const;
void LoadLDraw(QTextStream& Stream);
bool LoadBinary(lcFile* File);
void Merge(lcModel* Other);
void SetSaved()
{
if (mUndoHistory.IsEmpty())
SaveCheckpoint(QString());
mSavedHistory = mUndoHistory[0];
}
void Cut();
void Copy();
void Paste();
void GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface) const;
void DrawBackground(lcContext* Context);
+16
View File
@@ -57,6 +57,22 @@ void lcLight::SaveLDraw(QTextStream& Stream) const
void lcLight::CreateName(const lcArray<lcLight*>& Lights)
{
if (m_strName[0])
{
bool Found = false;
for (int LightIdx = 0; LightIdx < Lights.GetSize(); LightIdx++)
{
if (!strcmp(Lights[LightIdx]->m_strName, m_strName))
{
Found = true;
break;
}
}
if (!Found)
return;
}
int i, max = 0;
for (int LightIdx = 0; LightIdx < Lights.GetSize(); LightIdx++)
+10 -2
View File
@@ -23,6 +23,7 @@ Project::Project()
{
mModified = false;
mActiveModel = new lcModel(tr("Model #1"));
mActiveModel->SetSaved();
mModels.Add(mActiveModel);
}
@@ -116,7 +117,9 @@ void Project::CreateNewModel()
if (!Name.isEmpty())
{
mModified = true;
mModels.Add(new lcModel(Name));
lcModel* Model = new lcModel(Name);
Model->SetSaved();
mModels.Add(Model);
SetActiveModel(mModels.GetSize() - 1);
gMainWindow->UpdateTitle();
}
@@ -147,6 +150,7 @@ void Project::ShowModelListDialog()
if (!Model)
{
Model = new lcModel(it->first);
Model->SetSaved();
mModified = true;
}
else if (Model->GetProperties().mName != it->first)
@@ -198,6 +202,7 @@ bool Project::Load(const QString& FileName)
lcModel* Model = new lcModel(Name);
mModels.Add(Model);
Model->LoadLDraw(Stream);
Model->SetSaved();
}
}
else
@@ -210,7 +215,10 @@ bool Project::Load(const QString& FileName)
lcModel* Model = new lcModel(tr("Model1"));
if (Model->LoadBinary(&MemFile))
{
mModels.Add(Model);
Model->SetSaved();
}
else
delete Model;
}
@@ -299,7 +307,7 @@ bool Project::Save(const QString& FileName)
if (MPD)
Stream << QLatin1String("0 FILE ") << Model->GetProperties().mName << QLatin1String("\r\n");
Model->SaveLDraw(Stream);
Model->SaveLDraw(Stream, false);
Model->SetSaved();
if (MPD)
+2 -3
View File
@@ -17,12 +17,11 @@ void lcApplication::RunProcess(const char* ExecutablePath, const lcArray<String>
QProcess::execute(ExecutablePath, argumentList);
}
void lcApplication::ExportClipboard(lcMemFile* Clipboard)
void lcApplication::ExportClipboard(const QByteArray& Clipboard)
{
QByteArray clipboardData = QByteArray::fromRawData((const char*)Clipboard->mBuffer, Clipboard->GetLength());
QMimeData *mimeData = new QMimeData();
mimeData->setData("application/vnd.leocad-clipboard", clipboardData);
mimeData->setData("application/vnd.leocad-clipboard", Clipboard);
QApplication::clipboard()->setMimeData(mimeData);
SetClipboard(Clipboard);
+3 -8
View File
@@ -657,17 +657,12 @@ void lcQMainWindow::clipboardChanged()
{
const QString mimeType("application/vnd.leocad-clipboard");
const QMimeData *mimeData = QApplication::clipboard()->mimeData();
lcMemFile *clipboard = NULL;
QByteArray clipboardData;
if (mimeData->hasFormat(mimeType))
{
QByteArray clipboardData = mimeData->data(mimeType);
clipboardData = mimeData->data(mimeType);
clipboard = new lcMemFile();
clipboard->WriteBuffer(clipboardData.constData(), clipboardData.size());
}
g_App->SetClipboard(clipboard);
g_App->SetClipboard(clipboardData);
}
void lcQMainWindow::splitView(Qt::Orientation Orientation)