Skip to content

Commit

Permalink
Add back temporary projects.
Browse files Browse the repository at this point in the history
  • Loading branch information
grossmj committed Oct 14, 2014
1 parent 165837b commit c6af132
Showing 1 changed file with 100 additions and 34 deletions.
134 changes: 100 additions & 34 deletions gns3/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"""

import os
import tempfile
import socket
import shutil
import json
Expand Down Expand Up @@ -83,6 +84,7 @@ def __init__(self, parent=None):
self._loadSettings()
self._connections()
self._ignore_unsaved_state = False
self._temporary_project = True
self._max_recent_files = 5
self._recent_file_actions = []

Expand Down Expand Up @@ -123,23 +125,6 @@ def __init__(self, parent=None):
# set the window icon
self.setWindowIcon(QtGui.QIcon(":/images/gns3.ico"))

# a project must be created before a user can drop devices
# on the drawing area
self.uiGraphicsView.setEnabled(False)

# let users know they cannot drop anything until
# they create or open a project
text_item = QtGui.QGraphicsTextItem("Please create or open a project")
font = text_item.font()
font.setPointSize(14)
font.setBold(True)
text_item.setFont(font)
text_item.setDefaultTextColor(QtGui.QColor("gray"))
x = text_item.pos().x() - (text_item.boundingRect().width() / 2)
y = text_item.pos().y() - (text_item.boundingRect().height() / 2)
text_item.setPos(x, y)
self.uiGraphicsView.scene().addItem(text_item)

#FIXME: hide the cloud dock for beta release
#self.uiCloudInspectorDockWidget.hide()

Expand Down Expand Up @@ -394,6 +379,9 @@ def _newProjectActionSlot(self):
self._project_settings.update(new_project_settings)
self._saveProject(new_project_settings["project_path"])

else:
self._createTemporaryProject()

self.project_new_signal.emit(self._project_settings["project_path"])

def _openProjectActionSlot(self):
Expand Down Expand Up @@ -432,7 +420,10 @@ def _saveProjectActionSlot(self):
Slot called to save a project.
"""

return self._saveProject(self._project_settings["project_path"])
if self._temporary_project:
return self._saveProjectAs()
else:
return self._saveProject(self._project_settings["project_path"])

def _saveProjectAsActionSlot(self):
"""
Expand Down Expand Up @@ -967,20 +958,27 @@ def checkForUnsavedChanges(self):
"""

if self.testAttribute(QtCore.Qt.WA_WindowModified):
destination_file = os.path.basename(self._project_settings["project_path"])
if self._temporary_project:
destination_file = "untitled.gns3"
else:
destination_file = os.path.basename(self._project_settings["project_path"])
reply = QtGui.QMessageBox.warning(self, "Unsaved changes", 'Save changes to project "{}" before closing?'.format(destination_file),
QtGui.QMessageBox.Discard | QtGui.QMessageBox.Save | QtGui.QMessageBox.Cancel)
if reply == QtGui.QMessageBox.Save:
if self._temporary_project:
return self._saveProjectAs()
return self._saveProject(self._project_settings["project_path"])
elif reply == QtGui.QMessageBox.Cancel:
return False
self._deleteTemporaryProject()
return True

def startupLoading(self):
"""
Called by QTimer.singleShot to load everything needed at startup.
"""

self._createTemporaryProject()
self._newProjectActionSlot()
#self._newsActionSlot()

Expand Down Expand Up @@ -1067,9 +1065,12 @@ def _saveProjectAs(self):
MessageBox(self, "Save project", "Please stop the following nodes before saving the topology to a new location", nodes)
return

default_project_name = os.path.basename(self._project_settings["project_path"])
if default_project_name.endswith(".gns3"):
default_project_name = default_project_name[:-5]
if self._temporary_project:
default_project_name = "untitled"
else:
default_project_name = os.path.basename(self._project_settings["project_path"])
if default_project_name.endswith(".gns3"):
default_project_name = default_project_name[:-5]

try:
projects_dir_path = self.projectsDirPath()
Expand Down Expand Up @@ -1123,9 +1124,16 @@ def _saveProjectAs(self):
# let all modules know about the new project files directory
self.uiGraphicsView.updateProjectFilesDir(new_project_files_dir)

log.info("copying project files from {} to {}".format(self._project_settings["project_files_dir"], new_project_files_dir))
self._thread = ProcessFilesThread(self._project_settings["project_files_dir"], new_project_files_dir)
progress_dialog = ProgressDialog(self._thread, "Project", "Copying project files...", "Cancel", parent=self)
if self._temporary_project:
# move files if saving from a temporary project
log.info("moving project files from {} to {}".format(self._project_settings["project_files_dir"], new_project_files_dir))
self._thread = ProcessFilesThread(self._project_settings["project_files_dir"], new_project_files_dir, move=True)
progress_dialog = ProgressDialog(self._thread, "Project", "Moving project files...", "Cancel", parent=self)
else:
# else, just copy the files
log.info("copying project files from {} to {}".format(self._project_settings["project_files_dir"], new_project_files_dir))
self._thread = ProcessFilesThread(self._project_settings["project_files_dir"], new_project_files_dir)
progress_dialog = ProgressDialog(self._thread, "Project", "Copying project files...", "Cancel", parent=self)
progress_dialog.show()
progress_dialog.exec_()

Expand All @@ -1134,6 +1142,7 @@ def _saveProjectAs(self):
errors = "\n".join(errors)
MessageBox(self, "Save project", "Errors detected while saving the project", errors, icon=QtGui.QMessageBox.Warning)

self._deleteTemporaryProject()
self._project_settings["project_files_dir"] = new_project_files_dir
self._project_settings["project_name"] = project_name
return self._saveProject(topology_file_path)
Expand Down Expand Up @@ -1232,18 +1241,70 @@ def loadProject(self, path):

return True

def _deleteTemporaryProject(self):
"""
Deletes a temporary project.
"""

if self._temporary_project and self._project_settings["project_path"]:
# delete the temporary project files
log.info("deleting temporary project files directory: {}".format(self._project_settings["project_files_dir"]))
shutil.rmtree(self._project_settings["project_files_dir"], ignore_errors=True)
try:
log.info("deleting temporary topology file: {}".format(self._project_settings["project_path"]))
os.remove(self._project_settings["project_path"])
except OSError as e:
log.warning("could not delete temporary topology file: {}: {}".format(self._project_settings["project_path"], e))

def _createTemporaryProject(self):
"""
Creates a temporary project.
"""

self.uiGraphicsView.reset()
try:
with tempfile.NamedTemporaryFile(prefix="gns3-", delete=False) as f:
log.info("creating temporary topology file: {}".format(f.name))
project_files_dir = f.name + "-files"
if not os.path.isdir(project_files_dir):
log.info("creating temporary project files directory: {}".format(project_files_dir))
os.mkdir(project_files_dir)

self._project_settings["project_files_dir"] = project_files_dir
self._project_settings["project_path"] = f.name

except OSError as e:
QtGui.QMessageBox.critical(self, "Save", "Could not create project: {}".format(e))

self.uiGraphicsView.updateProjectFilesDir(self._project_settings["project_files_dir"])
self._setCurrentFile()

def isTemporaryProject(self):
"""
Returns either this is a temporary project or not.
:returns: boolean
"""

return self._temporary_project

def _setCurrentFile(self, path=None):
"""
Sets the current project file path.
:param path: path to project file
"""

self.setWindowFilePath(path)
self._updateRecentFileSettings(path)
self._updateRecentFileActions()
if not path:
self._temporary_project = True
self.setWindowFilePath("Unsaved project")
else:
self._temporary_project = False
self.setWindowFilePath(path)
self._updateRecentFileSettings(path)
self._updateRecentFileActions()

self.setWindowModified(False)
self.uiGraphicsView.setEnabled(True)

def _updateRecentFileSettings(self, path):
"""
Expand Down Expand Up @@ -1348,8 +1409,8 @@ def shutdown_cloud_instances(self, project):
:param project: path to gns3 project file
"""

if not project:
# no project has been created yet
if self._temporary_project:
# do nothing if previous project was temporary
return

with open(project) as f:
Expand Down Expand Up @@ -1378,9 +1439,8 @@ def project_created(self, project):
:param project: path to gns3 project file currently opened
"""

if not project:
# no project has been created yet
if self._temporary_project:
# do nothing if project is temporary
return

with open(project) as f:
Expand Down Expand Up @@ -1450,6 +1510,12 @@ def _create_instance(self, name, flavor, image_id):
return instance, keypair

def _exportProjectActionSlot(self):
if self._temporary_project:
# do nothing if project is temporary
QtGui.QMessageBox.critical(
self, "Export project server",
"Cannot export temporary projects, please save current project first.")
return

upload_thread = UploadProjectThread(self._project_settings, self.cloudSettings())
upload_thread.start()
Expand Down

0 comments on commit c6af132

Please sign in to comment.