~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
using MonoDevelop.Ide.Projects;
49
49
using MonoDevelop.Core.Assemblies;
50
50
using MonoDevelop.Core.Instrumentation;
 
51
using Mono.TextEditor;
 
52
using System.Diagnostics;
51
53
 
52
54
namespace MonoDevelop.Ide
53
55
{
154
156
                
155
157
                public IAsyncOperation CurrentRunOperation {
156
158
                        get { return currentRunOperation; }
157
 
                        set { currentRunOperation = value; }
 
159
                        set { currentRunOperation = value ?? NullAsyncOperation.Success; }
158
160
                }
159
161
                
160
162
                public bool IsBuilding (IBuildTarget target)
231
233
                                LocalVariable localVar = (LocalVariable)visitable;
232
234
                                IdeApp.Workbench.OpenDocument (localVar.FileName,
233
235
                                                               localVar.Region.Start.Line,
234
 
                                                               localVar.Region.Start.Column,
235
 
                                                               true);
 
236
                                                               localVar.Region.Start.Column);
236
237
                                return;
237
238
                        }
238
239
                        
240
241
                                IParameter para = (IParameter)visitable;
241
242
                                IdeApp.Workbench.OpenDocument (para.DeclaringMember.DeclaringType.CompilationUnit.FileName,
242
243
                                                               para.Location.Line,
243
 
                                                               para.Location.Column,
244
 
                                                               true);
 
244
                                                               para.Location.Column);
245
245
                                return;
246
246
                        }
247
247
                        
262
262
                                IType declaringType = SearchContainingPart (member);
263
263
                                fileName = declaringType.CompilationUnit.FileName;
264
264
                        }
265
 
                        Document doc = IdeApp.Workbench.OpenDocument (fileName, member.Location.Line, member.Location.Column, true);
 
265
                        var doc = IdeApp.Workbench.OpenDocument (fileName, member.Location.Line, member.Location.Column);
266
266
                        if (doc != null) {
267
 
                                MonoDevelop.Ide.Gui.Content.IUrlHandler handler = doc.ActiveView as MonoDevelop.Ide.Gui.Content.IUrlHandler;
268
 
                                if (handler != null)
269
 
                                        handler.Open (member.HelpUrl);
 
267
                                doc.RunWhenLoaded (delegate {
 
268
                                        MonoDevelop.Ide.Gui.Content.IUrlHandler handler = doc.ActiveView as MonoDevelop.Ide.Gui.Content.IUrlHandler;
 
269
                                        if (handler != null)
 
270
                                                handler.Open (member.HelpUrl);
 
271
                                });
270
272
                        }
271
273
                }
272
274
 
312
314
                        try {
313
315
                                if (MessageService.RunCustomDialog (dlg) == (int) Gtk.ResponseType.Ok) {
314
316
                                        
315
 
                                        using (IProgressMonitor mon = IdeApp.Workbench.ProgressMonitors.GetOutputProgressMonitor (GettextCatalog.GetString ("Export Project"), null, true, true)) {
 
317
                                        using (IProgressMonitor mon = IdeApp.Workbench.ProgressMonitors.GetToolOutputProgressMonitor (true)) {
316
318
                                                string folder = dlg.TargetFolder;
317
319
                                                
318
320
                                                string file = entry is WorkspaceItem ? ((WorkspaceItem)entry).FileName : ((SolutionEntityItem)entry).FileName;
526
528
                                var optionsDialog = new ProjectOptionsDialog (IdeApp.Workbench.RootWindow, selectedProject);
527
529
                                var conf = selectedProject.GetConfiguration (IdeApp.Workspace.ActiveConfiguration);
528
530
                                optionsDialog.CurrentConfig = conf != null ? conf.Name : null;
 
531
                                optionsDialog.CurrentPlatform = conf != null ? conf.Platform : null;
529
532
                                try {
530
533
                                        if (panelId != null)
531
534
                                                optionsDialog.SelectPanel (panelId);
540
543
                                                }
541
544
                                                Save (selectedProject);
542
545
                                                IdeApp.Workspace.SavePreferences ();
 
546
                                                IdeApp.Workbench.ReparseOpenDocuments ();
543
547
                                        }
544
548
                                } finally {
545
549
                                        optionsDialog.Destroy ();
621
625
                {
622
626
                        WorkspaceItem res = null;
623
627
                        
624
 
                        FileSelector fdiag = new FileSelector (GettextCatalog.GetString ("Add to Workspace"));
625
 
                        try {
626
 
                                fdiag.SetCurrentFolder (parentWorkspace.BaseDirectory);
627
 
                                fdiag.SelectMultiple = false;
628
 
                                if (MessageService.RunCustomDialog (fdiag) == (int) Gtk.ResponseType.Ok) {
629
 
                                        try {
630
 
                                                res = AddWorkspaceItem (parentWorkspace, fdiag.Filename);
631
 
                                        }
632
 
                                        catch (Exception ex) {
633
 
                                                MessageService.ShowException (ex, GettextCatalog.GetString ("The file '{0}' could not be loaded.", fdiag.Filename));
634
 
                                        }
 
628
                        var dlg = new SelectFileDialog () {
 
629
                                Action = Gtk.FileChooserAction.Open,
 
630
                                CurrentFolder = parentWorkspace.BaseDirectory,
 
631
                                SelectMultiple = false,
 
632
                        };
 
633
                
 
634
                        dlg.AddAllFilesFilter ();
 
635
                        dlg.DefaultFilter = dlg.AddFilter (GettextCatalog.GetString ("Solution Files"), "*.mds", "*.sln");
 
636
                        
 
637
                        if (dlg.Run ()) {
 
638
                                try {
 
639
                                        res = AddWorkspaceItem (parentWorkspace, dlg.SelectedFile);
 
640
                                } catch (Exception ex) {
 
641
                                        MessageService.ShowException (ex, GettextCatalog.GetString ("The file '{0}' could not be loaded.", dlg.SelectedFile));
635
642
                                }
636
 
                        } finally {
637
 
                                fdiag.Destroy ();
638
643
                        }
639
 
                        
 
644
 
640
645
                        return res;
641
646
                }
642
647
                
654
659
                
655
660
                public SolutionItem CreateProject (SolutionFolder parentFolder)
656
661
                {
657
 
                        SolutionItem res = null;
658
662
                        string basePath = parentFolder != null ? parentFolder.BaseDirectory : null;
659
663
                        NewProjectDialog npdlg = new NewProjectDialog (parentFolder, false, basePath);
660
 
                        MessageService.ShowCustomDialog (npdlg);
661
 
                        return res;
 
664
                        if (MessageService.ShowCustomDialog (npdlg) == (int)Gtk.ResponseType.Ok)
 
665
                                return npdlg.NewItem as SolutionItem;
 
666
                        return null;
662
667
                }
663
668
 
664
669
                public SolutionItem AddSolutionItem (SolutionFolder parentFolder)
665
670
                {
666
671
                        SolutionItem res = null;
667
672
                        
668
 
                        FileSelector fdiag = new FileSelector (GettextCatalog.GetString ("Add to Solution"));
669
 
                        try {
670
 
                                fdiag.SetCurrentFolder (parentFolder.BaseDirectory);
671
 
                                fdiag.SelectMultiple = false;
672
 
                                if (MessageService.RunCustomDialog (fdiag) == (int) Gtk.ResponseType.Ok) {
673
 
                                        try {
674
 
                                                res = AddSolutionItem (parentFolder, fdiag.Filename);
675
 
                                        }
676
 
                                        catch (Exception ex) {
677
 
                                                MessageService.ShowException (ex, GettextCatalog.GetString ("The file '{0}' could not be loaded.", fdiag.Filename));
678
 
                                        }
 
673
                        var dlg = new SelectFileDialog () {
 
674
                                Action = Gtk.FileChooserAction.Open,
 
675
                                CurrentFolder = parentFolder.BaseDirectory,
 
676
                                SelectMultiple = false,
 
677
                        };
 
678
                
 
679
                        dlg.AddAllFilesFilter ();
 
680
                        dlg.DefaultFilter = dlg.AddFilter (GettextCatalog.GetString ("Project Files"), "*.*proj", "*.mdp");
 
681
                        
 
682
                        if (dlg.Run ()) {
 
683
                                try {
 
684
                                        res = AddSolutionItem (parentFolder, dlg.SelectedFile);
 
685
                                } catch (Exception ex) {
 
686
                                        MessageService.ShowException (ex, GettextCatalog.GetString ("The file '{0}' could not be loaded.", dlg.SelectedFile));
679
687
                                }
680
 
                        } finally {
681
 
                                fdiag.Destroy ();
682
688
                        }
683
689
                        
684
690
                        if (res != null)
768
774
                public void RemoveSolutionItem (SolutionItem item)
769
775
                {
770
776
                        string question = GettextCatalog.GetString ("Do you really want to remove project '{0}' from '{1}'?", item.Name, item.ParentFolder.Name);
771
 
                        string secondaryText = GettextCatalog.GetString ("The Delete option physically removes the project files from disc.");
 
777
                        string secondaryText = GettextCatalog.GetString ("The Remove option remove the project from the solution, but it will not physically delete any file from disk.");
772
778
                        
773
779
                        SolutionEntityItem prj = item as SolutionEntityItem;
774
780
                        if (prj == null) {
777
783
                                return;
778
784
                        }
779
785
                        
 
786
                        AlertButton delete = new AlertButton (GettextCatalog.GetString ("Delete from Disk"));
780
787
                        AlertButton result = MessageService.AskQuestion (question, secondaryText,
781
 
                                                                         AlertButton.Delete, AlertButton.Cancel, AlertButton.Remove);
782
 
                        if (result == AlertButton.Delete) {
 
788
                                                                         delete, AlertButton.Cancel, AlertButton.Remove);
 
789
                        if (result == delete) {
783
790
                                if (!IdeApp.Workspace.RequestItemUnload (prj))
784
791
                                        return;
785
792
                                ConfirmProjectDeleteDialog dlg = new ConfirmProjectDeleteDialog (prj);
820
827
                        prj.Dispose ();
821
828
                        IdeApp.ProjectOperations.Save (sol);
822
829
                }
 
830
                
 
831
                /// <summary>
 
832
                /// Checks if an execution operation can start (asking the user if necessary)
 
833
                /// </summary>
 
834
                /// <returns>
 
835
                /// True if execution can continue, false otherwise
 
836
                /// </returns>
 
837
                /// <remarks>
 
838
                /// This method must be called before starting an execution operation. If there is already an execution in
 
839
                /// progress, MonoDevelop will ask confirmation for stopping the current operation.
 
840
                /// </remarks>
 
841
                public bool ConfirmExecutionOperation ()
 
842
                {
 
843
                        if (!currentRunOperation.IsCompleted) {
 
844
                                if (MessageService.Confirm (GettextCatalog.GetString ("An application is already running and will have to be stopped. Do you want to continue?"), AlertButton.Yes)) {
 
845
                                        if (currentRunOperation != null && !currentRunOperation.IsCompleted)
 
846
                                                currentRunOperation.Cancel ();
 
847
                                        return true;
 
848
                                } else
 
849
                                        return false;
 
850
                        } else
 
851
                                return true;
 
852
                }
823
853
 
824
854
                public bool CanExecute (IBuildTarget entry)
825
855
                {
1029
1059
                                case BeforeCompileAction.Nothing:
1030
1060
                                        break;
1031
1061
                                case BeforeCompileAction.PromptForSave:
1032
 
                                        foreach (Document doc in IdeApp.Workbench.Documents) {
 
1062
                                        foreach (var doc in IdeApp.Workbench.Documents) {
1033
1063
                                                if (doc.IsDirty && doc.Project != null) {
1034
1064
                                                        if (MessageService.AskQuestion (
1035
1065
                                                            GettextCatalog.GetString ("Save changed documents before building?"),
1044
1074
                                        }
1045
1075
                                        break;
1046
1076
                                case BeforeCompileAction.SaveAllFiles:
1047
 
                                        foreach (Document doc in new List<Document> (IdeApp.Workbench.Documents))
 
1077
                                        foreach (var doc in new List<MonoDevelop.Ide.Gui.Document> (IdeApp.Workbench.Documents))
1048
1078
                                                if (doc.IsDirty && doc.Project != null)
1049
1079
                                                        doc.Save ();
1050
1080
                                        break;
1127
1157
                                        }
1128
1158
                                } catch {}
1129
1159
                                
1130
 
                                Task jumpTask = null;
1131
 
                                switch (IdeApp.Preferences.JumpToFirstErrorOrWarning) {
1132
 
                                case JumpToFirst.Error:
1133
 
                                        jumpTask = tasks.FirstOrDefault (t => t.Severity == TaskSeverity.Error);
1134
 
                                        break;
1135
 
                                case JumpToFirst.ErrorOrWarning:
1136
 
                                        jumpTask = tasks.FirstOrDefault (t => t.Severity == TaskSeverity.Error || t.Severity == TaskSeverity.Warning);
1137
 
                                        break;
1138
 
                                }
1139
 
                                if (jumpTask != null) {
1140
 
                                        tt.Trace ("Jumping to first result position");
1141
 
                                        jumpTask.JumpToPosition ();
 
1160
                                if (tasks != null) {
 
1161
                                        Task jumpTask = null;
 
1162
                                        switch (IdeApp.Preferences.JumpToFirstErrorOrWarning) {
 
1163
                                        case JumpToFirst.Error:
 
1164
                                                jumpTask = tasks.FirstOrDefault (t => t.Severity == TaskSeverity.Error && TaskStore.IsProjectTaskFile (t));
 
1165
                                                break;
 
1166
                                        case JumpToFirst.ErrorOrWarning:
 
1167
                                                jumpTask = tasks.FirstOrDefault (t => (t.Severity == TaskSeverity.Error || t.Severity == TaskSeverity.Warning) && TaskStore.IsProjectTaskFile (t));
 
1168
                                                break;
 
1169
                                        }
 
1170
                                        if (jumpTask != null) {
 
1171
                                                tt.Trace ("Jumping to first result position");
 
1172
                                                jumpTask.JumpToPosition ();
 
1173
                                        }
1142
1174
                                }
1143
1175
                                
1144
1176
                        } finally {
1214
1246
                        return AddFilesToProject (project, files.ToFilePathArray (), targetDirectory);
1215
1247
                }
1216
1248
                
 
1249
                public IList<ProjectFile> AddFilesToProject (Project project, FilePath[] files, FilePath targetDirectory)
 
1250
                {
 
1251
                        return AddFilesToProject (project, files, targetDirectory, null);
 
1252
                }
 
1253
                
 
1254
                public IList<ProjectFile> AddFilesToProject (Project project, FilePath[] files, FilePath targetDirectory,
 
1255
                        string buildAction)
 
1256
                {
 
1257
                        Debug.Assert (targetDirectory.CanonicalPath == project.BaseDirectory.CanonicalPath
 
1258
                                || targetDirectory.IsChildPathOf (project.BaseDirectory));
 
1259
                        
 
1260
                        var targetPaths = new FilePath[files.Length];
 
1261
                        for (int i = 0; i < files.Length; i++)
 
1262
                                targetPaths[i] = targetDirectory.Combine (files[i].FileName);
 
1263
                        
 
1264
                        return AddFilesToProject (project, files, targetPaths, buildAction);
 
1265
                }
 
1266
 
1217
1267
                /// <summary>
1218
1268
                /// Adds files to a project, potentially asking the user whether to move, copy or link the files.
1219
1269
                /// </summary>
1220
 
                public IList<ProjectFile> AddFilesToProject (Project project, FilePath[] files, FilePath targetDirectory)
 
1270
                public IList<ProjectFile> AddFilesToProject (Project project, FilePath[] files, FilePath[] targetPaths,
 
1271
                        string buildAction)
1221
1272
                {
1222
 
                        int action = -1;
 
1273
                        Debug.Assert (project != null);
 
1274
                        Debug.Assert (files != null);
 
1275
                        Debug.Assert (targetPaths != null);
 
1276
                        Debug.Assert (files.Length == targetPaths.Length);
 
1277
                        
 
1278
                        AddAction action = AddAction.Copy;
 
1279
                        bool applyToAll = true;
 
1280
                        bool dialogShown = false;
 
1281
                        
1223
1282
                        IProgressMonitor monitor = null;
1224
1283
                        
1225
1284
                        if (files.Length > 10) {
1229
1288
                        
1230
1289
                        var newFileList = new List<ProjectFile> ();
1231
1290
                        
1232
 
                        using (monitor) {
1233
 
                                foreach (FilePath file in files) {
 
1291
                        //project.AddFile (string) does linear search for duplicate file, so instead we use this HashSet and 
 
1292
                        //and add the ProjectFiles directly. With large project and many files, this should really help perf.
 
1293
                        //Also, this is a better check because we handle vpaths and links.
 
1294
                        //FIXME: it would be really nice if project.Files maintained these hashmaps
 
1295
                        var vpathsInProject = new HashSet<FilePath> (project.Files.Select (pf => pf.ProjectVirtualPath));
 
1296
                        var filesInProject = new Dictionary<FilePath,ProjectFile> ();
 
1297
                        foreach (var pf in project.Files)
 
1298
                                filesInProject [pf.FilePath] = pf;
 
1299
                        
 
1300
                        using (monitor)
 
1301
                        {
 
1302
                                for (int i = 0; i < files.Length; i++) {
 
1303
                                        FilePath file = files[i];
 
1304
                                        
1234
1305
                                        if (monitor != null) {
1235
1306
                                                monitor.Log.WriteLine (file);
1236
1307
                                                monitor.Step (1);
1242
1313
                                                continue;
1243
1314
                                        }
1244
1315
                                        
1245
 
                                        //files in the project directory get added directly in their current location without moving/copying
1246
 
                                        if (file.IsChildPathOf (project.BaseDirectory)) {
1247
 
                                                newFileList.Add (project.AddFile (file));
 
1316
                                        FilePath targetPath = targetPaths[i].CanonicalPath;
 
1317
                                        Debug.Assert (targetPath.IsChildPathOf (project.BaseDirectory));
 
1318
                                        
 
1319
                                        var vpath = targetPath.ToRelative (project.BaseDirectory);
 
1320
                                        if (vpathsInProject.Contains (vpath)) {
 
1321
                                                MessageService.ShowWarning (GettextCatalog.GetString (
 
1322
                                                        "There is a already a file or link in the project with the name '{0}'", vpath));
 
1323
                                                continue;
 
1324
                                        }
 
1325
                                        
 
1326
                                        string fileBuildAction = buildAction;
 
1327
                                        if (string.IsNullOrEmpty (buildAction))
 
1328
                                                fileBuildAction = project.GetDefaultBuildAction (file);
 
1329
                                        
 
1330
                                        //files in the target directory get added directly in their current location without moving/copying
 
1331
                                        if (file.CanonicalPath == targetPath) {
 
1332
                                                AddFileToFolder (newFileList, vpathsInProject, filesInProject, file, fileBuildAction);
1248
1333
                                                continue;
1249
1334
                                        }
1250
1335
                                        
1251
1336
                                        //for files outside the project directory, we ask the user whether to move, copy or link
1252
 
                                        var md = new Gtk.MessageDialog (
1253
 
                                                 IdeApp.Workbench.RootWindow,
1254
 
                                                 Gtk.DialogFlags.Modal | Gtk.DialogFlags.DestroyWithParent,
1255
 
                                                 Gtk.MessageType.Question, Gtk.ButtonsType.None,
1256
 
                                                 GettextCatalog.GetString ("The file {0} is outside the project directory. What would you like to do?", file));
1257
 
 
1258
 
                                        try {
1259
 
                                                Gtk.CheckButton remember = null;
 
1337
                                        
 
1338
                                        AddExternalFileDialog addExternalDialog = null;
 
1339
                                        
 
1340
                                        if (!dialogShown || !applyToAll) {
 
1341
                                                addExternalDialog = new AddExternalFileDialog (file);
1260
1342
                                                if (files.Length > 1) {
1261
 
                                                        remember = new Gtk.CheckButton (GettextCatalog.GetString ("Use the same action for all selected files."));
1262
 
                                                        md.VBox.PackStart (remember, false, false, 0);
1263
 
                                                }
1264
 
                                                
1265
 
                                                const int ACTION_LINK = 3;
1266
 
                                                const int ACTION_COPY = 1;
1267
 
                                                const int ACTION_MOVE = 2;
1268
 
                                                
1269
 
                                                md.AddButton (GettextCatalog.GetString ("_Link"), ACTION_LINK);
1270
 
                                                md.AddButton (Gtk.Stock.Copy, ACTION_COPY);
1271
 
                                                md.AddButton (GettextCatalog.GetString ("_Move"), ACTION_MOVE);
1272
 
                                                md.AddButton (Gtk.Stock.Cancel, Gtk.ResponseType.Cancel);
1273
 
                                                md.VBox.ShowAll ();
1274
 
                                                
1275
 
                                                int ret = -1;
1276
 
                                                if (action < 0) {
1277
 
                                                        ret = MessageService.RunCustomDialog (md);
1278
 
                                                        if (ret < 0)
 
1343
                                                        addExternalDialog.ApplyToAll = applyToAll;
 
1344
                                                        addExternalDialog.ShowApplyAll = true;
 
1345
                                                }
 
1346
                                                if (file.IsChildPathOf (targetPath.ParentDirectory))
 
1347
                                                        addExternalDialog.ShowKeepOption (file.ParentDirectory.ToRelative (targetPath.ParentDirectory));
 
1348
                                                else {
 
1349
                                                        if (action == AddAction.Keep)
 
1350
                                                                action = AddAction.Copy;
 
1351
                                                        addExternalDialog.SelectedAction = action;
 
1352
                                                }
 
1353
                                        }
 
1354
                                        
 
1355
                                        try {
 
1356
                                                if (!dialogShown || !applyToAll) {
 
1357
                                                        if (MessageService.RunCustomDialog (addExternalDialog) == (int) Gtk.ResponseType.Cancel) {
 
1358
                                                                project.Files.AddRange (newFileList.Where (f => f != null));
1279
1359
                                                                return newFileList;
1280
 
                                                        if (remember != null && remember.Active) action = ret;
1281
 
                                                } else {
1282
 
                                                        ret = action;
1283
 
                                                }
1284
 
                                                
1285
 
                                                var targetName = targetDirectory.Combine (file.FileName);
1286
 
                                                
1287
 
                                                if (ret == ACTION_LINK) {
1288
 
                                                        var pf = project.AddFile (file);
1289
 
                                                        pf.Link = project.GetRelativeChildPath (targetName);
 
1360
                                                        }
 
1361
                                                        action = addExternalDialog.SelectedAction;
 
1362
                                                        applyToAll = addExternalDialog.ApplyToAll;
 
1363
                                                        dialogShown = true;
 
1364
                                                }
 
1365
                                                
 
1366
                                                if (action == AddAction.Keep) {
 
1367
                                                        AddFileToFolder (newFileList, vpathsInProject, filesInProject, file, fileBuildAction);
 
1368
                                                        continue;
 
1369
                                                }
 
1370
                                                
 
1371
                                                if (action == AddAction.Link) {
 
1372
                                                        //FIXME: MD project system doesn't cope with duplicate includes - project save/load will remove the file
 
1373
                                                        ProjectFile pf;
 
1374
                                                        if (filesInProject.TryGetValue (file, out pf)) {
 
1375
                                                                var link = pf.Link;
 
1376
                                                                MessageService.ShowWarning (GettextCatalog.GetString (
 
1377
                                                                        "The link '{0}' in the project already includes the file '{1}'", link, file));
 
1378
                                                                continue;
 
1379
                                                        }
 
1380
                                                        
 
1381
                                                        pf = new ProjectFile (file, fileBuildAction) {
 
1382
                                                                Link = vpath
 
1383
                                                        };
 
1384
                                                        vpathsInProject.Add (pf.ProjectVirtualPath);
 
1385
                                                        filesInProject [pf.FilePath] = pf;
1290
1386
                                                        newFileList.Add (pf);
1291
1387
                                                        continue;
1292
1388
                                                }
1293
1389
                                                
1294
1390
                                                try {
1295
 
                                                        if (MoveCopyFile (file, targetName, ret == ACTION_MOVE))
1296
 
                                                                newFileList.Add (project.AddFile (targetName));
1297
 
                                                        else
 
1391
                                                        if (!Directory.Exists (targetPath.ParentDirectory))
 
1392
                                                                FileService.CreateDirectory (targetPath.ParentDirectory);
 
1393
                                                        
 
1394
                                                        if (MoveCopyFile (file, targetPath, action == AddAction.Move)) {
 
1395
                                                                var pf = new ProjectFile (targetPath, fileBuildAction);
 
1396
                                                                vpathsInProject.Add (pf.ProjectVirtualPath);
 
1397
                                                                filesInProject [pf.FilePath] = pf;
 
1398
                                                                newFileList.Add (pf);
 
1399
                                                        }
 
1400
                                                        else {
1298
1401
                                                                newFileList.Add (null);
 
1402
                                                        }
1299
1403
                                                }
1300
1404
                                                catch (Exception ex) {
1301
1405
                                                        MessageService.ShowException (ex, GettextCatalog.GetString (
1303
1407
                                                        newFileList.Add (null);
1304
1408
                                                }
1305
1409
                                        } finally {
1306
 
                                                md.Destroy ();
 
1410
                                                if (addExternalDialog != null)
 
1411
                                                        addExternalDialog.Destroy ();
1307
1412
                                        }
1308
1413
                                }
1309
1414
                        }
 
1415
                        project.Files.AddRange (newFileList.Where (f => f != null));
1310
1416
                        return newFileList;
1311
1417
                }
1312
1418
                
 
1419
                void AddFileToFolder (List<ProjectFile> newFileList, HashSet<FilePath> vpathsInProject, Dictionary<FilePath, ProjectFile> filesInProject, FilePath file, string fileBuildAction)
 
1420
                {
 
1421
                        //FIXME: MD project system doesn't cope with duplicate includes - project save/load will remove the file
 
1422
                        ProjectFile pf;
 
1423
                        if (filesInProject.TryGetValue (file, out pf)) {
 
1424
                                var link = pf.Link;
 
1425
                                MessageService.ShowWarning (GettextCatalog.GetString (
 
1426
                                        "The link '{0}' in the project already includes the file '{1}'", link, file));
 
1427
                                return;
 
1428
                        }
 
1429
                        pf = new ProjectFile (file, fileBuildAction);
 
1430
                        vpathsInProject.Add (pf.ProjectVirtualPath);
 
1431
                        filesInProject [pf.FilePath] = pf;
 
1432
                        newFileList.Add (pf);
 
1433
                }
 
1434
                
1313
1435
                bool MoveCopyFile (string filename, string targetFilename, bool move)
1314
1436
                {
1315
1437
                        if (filename != targetFilename) {
1357
1479
                        try {
1358
1480
                                //get the real ProjectFiles
1359
1481
                                if (sourceProject != null) {
1360
 
                                        var virtualPath = sourcePath.ToRelative (sourceProject.BaseDirectory);
1361
 
                                        filesToMove = sourceProject.Files.GetFilesInVirtualPath (virtualPath).ToList ();
 
1482
                                        if (sourceIsFolder) {
 
1483
                                                var virtualPath = sourcePath.ToRelative (sourceProject.BaseDirectory);
 
1484
                                                filesToMove = sourceProject.Files.GetFilesInVirtualPath (virtualPath).ToList ();
 
1485
                                        } else {
 
1486
                                                filesToMove = new List<ProjectFile> ();
 
1487
                                                var pf = sourceProject.GetProjectFile (sourcePath);
 
1488
                                                if (pf != null)
 
1489
                                                        filesToMove.Add (pf);
 
1490
                                        }
1362
1491
                                }
1363
1492
                                //get all the non-project files and create fake ProjectFiles
1364
1493
                                if (!copyOnlyProjectFiles || sourceProject == null) {
1634
1763
                }
1635
1764
        }
1636
1765
        
1637
 
        class OpenDocumentFileProvider: ITextFileProvider
1638
 
        {
 
1766
        public class TextFileProvider : ITextFileProvider
 
1767
        {
 
1768
                static TextFileProvider instance = new TextFileProvider ();
 
1769
                public static TextFileProvider Instance {
 
1770
                        get {
 
1771
                                return instance;
 
1772
                        }
 
1773
                }
 
1774
                
 
1775
                TextFileProvider ()
 
1776
                {
 
1777
                }
 
1778
                
 
1779
                class ProviderProxy : ITextEditorDataProvider, IEditableTextFile
 
1780
                {
 
1781
                        TextEditorData data;
 
1782
                        public ProviderProxy (TextEditorData data)
 
1783
                        {
 
1784
                                this.data = data;
 
1785
                        }
 
1786
 
 
1787
                        public TextEditorData GetTextEditorData ()
 
1788
                        {
 
1789
                                return data;
 
1790
                        }
 
1791
                        
 
1792
                        #region IEditableTextFile implementation
 
1793
                        public FilePath Name { get { return data.Document.FileName; } }
 
1794
 
 
1795
                        public int Length { get { return data.Length; } }
 
1796
                
 
1797
                        public string GetText (int startPosition, int endPosition)
 
1798
                        {
 
1799
                                return data.GetTextBetween (startPosition, endPosition);
 
1800
                        }
 
1801
                        public char GetCharAt (int position)
 
1802
                        {
 
1803
                                return data.GetCharAt (position);
 
1804
                        }
 
1805
                        
 
1806
                        public int GetPositionFromLineColumn (int line, int column)
 
1807
                        {
 
1808
                                return data.Document.LocationToOffset (line, column);
 
1809
                        }
 
1810
                        
 
1811
                        public void GetLineColumnFromPosition (int position, out int line, out int column)
 
1812
                        {
 
1813
                                var loc = data.Document.OffsetToLocation (position);
 
1814
                                line = loc.Line;
 
1815
                                column = loc.Column;
 
1816
                        }
 
1817
                        
 
1818
                        public int InsertText (int position, string text)
 
1819
                        {
 
1820
                                int result = data.Insert (position, text);
 
1821
                                File.WriteAllText (Name, Text);
 
1822
                                return result;
 
1823
                        }
 
1824
                        
 
1825
                        
 
1826
                        public void DeleteText (int position, int length)
 
1827
                        {
 
1828
                                data.Remove (position, length);
 
1829
                                File.WriteAllText (Name, Text);
 
1830
                        }
 
1831
                        
 
1832
                        public string Text {
 
1833
                                get {
 
1834
                                        return data.Text;
 
1835
                                }
 
1836
                                set {
 
1837
                                        data.Text = value;
 
1838
                                }
 
1839
                        }
 
1840
                        
 
1841
                        #endregion
 
1842
                }
 
1843
                
1639
1844
                public IEditableTextFile GetEditableTextFile (FilePath filePath)
1640
1845
                {
1641
 
                        foreach (Document doc in IdeApp.Workbench.Documents) {
 
1846
                        foreach (var doc in IdeApp.Workbench.Documents) {
1642
1847
                                if (doc.FileName == filePath) {
1643
1848
                                        IEditableTextFile ef = doc.GetContent<IEditableTextFile> ();
1644
1849
                                        if (ef != null) return ef;
1645
1850
                                }
1646
1851
                        }
1647
 
                        return null;
 
1852
                        
 
1853
                        TextEditorData data = new TextEditorData ();
 
1854
                        data.Document.FileName = filePath;
 
1855
                        data.Text = File.ReadAllText (filePath);
 
1856
                        return new ProviderProxy (data);
 
1857
                }
 
1858
                
 
1859
                public TextEditorData GetTextEditorData (FilePath filePath)
 
1860
                {
 
1861
                        bool isOpen;
 
1862
                        return GetTextEditorData (filePath, out isOpen);
 
1863
                }
 
1864
 
 
1865
                public TextEditorData GetTextEditorData (FilePath filePath, out bool isOpen)
 
1866
                {
 
1867
                        foreach (var doc in IdeApp.Workbench.Documents) {
 
1868
                                if (doc.FileName == filePath) {
 
1869
                                        isOpen = true;
 
1870
                                        return doc.Editor;
 
1871
                                }
 
1872
                        }
 
1873
                        
 
1874
                        TextEditorData data = new TextEditorData ();
 
1875
                        data.Document.FileName = filePath;
 
1876
                        data.Text = File.ReadAllText (filePath);
 
1877
                        isOpen = false;
 
1878
                        return data;
1648
1879
                }
1649
1880
        }
1650
1881
}