def show_content(self):
     if self.content_shown:
         return
     self.content_shown = True
     self.mainlayout.removeWidget(self.welcomewidget)
     self.welcomewidget.deleteLater()
     del(self.welcomewidget)
     self.contentwidget = MainProjectWidget(self)
     self.mainlayout.insertWidget(2, self.contentwidget)
     self.update_window_menu()
class ProjectWindow(QMainWindow):
    about_dlg = None
    modal_dialog = False
    project = None
    def __init__(self, app, project):
        super(ProjectWindow, self).__init__()
        self.app = app
        self.setMinimumSize(650, 500)
        self.project = project
        self.content_shown = False
        self.contentwidget = None
        self.copy_paste_target_widget = None
        
        self.toolbar = ProjectToolbar(self)

        self.mainlayout = QVBoxLayout()
        self.mainlayout.setContentsMargins(0, 0, 0, 0)
        self.menubar = self.construct_menu_bar()
        self.mainlayout.addWidget(self.menubar)
        self.mainlayout.addWidget(self.toolbar)
        self.welcomewidget = WelcomeWidget(self)

        self.mainlayout.addWidget(self.welcomewidget)

        layoutwidget = QWidget()
        layoutwidget.setLayout(self.mainlayout)
        self.setCentralWidget(layoutwidget)

        self.update_title()
        self.update_menu()

        current_size = self.size()
        new_w = max(current_size.width(), 800)
        new_h = max(current_size.height(), 600)
        self.resize(new_w, new_h)

    def copy_paste_widget_focus(self, widget):
        self.copy_paste_target_widget = widget
        self.update_menu()
        
    def project_change_notify(self):
        """ This should get called if any file in the project is changed (to
            make this window display unsaved changes etc.)
        """
        self.update_title()
        self.update_menu()
        self.update_undo()
        if self.content_shown and self.contentwidget != None:
            self.contentwidget.tabs.update_tab_titles()
            self.contentwidget.update_file_list()
        for window in get_app_singleton().windows:
            if not hasattr(window, "content_shown"):
                # a popout winodw
                if window.project == self.project:
                    window.current_file_view.update_toolbar()
                    window.update_title()
                    window.update_toolbar()
        
    def open_and_show_file(self, file):
        if not self.content_shown:
            raise RuntimeError("cannot switch to file without showing " + \
                "project contents first")
        self.contentwidget.open_and_show_file(file)

    def show_content(self):
        if self.content_shown:
            return
        self.content_shown = True
        self.mainlayout.removeWidget(self.welcomewidget)
        self.welcomewidget.deleteLater()
        del(self.welcomewidget)
        self.contentwidget = MainProjectWidget(self)
        self.mainlayout.insertWidget(2, self.contentwidget)
        self.update_window_menu()

    def update_language(self):
        if self.modal_dialog:
            self.app.update_language_canceled = True
            return
        self.reconstruct_menu()
        self.reconstruct_contents()
        self.update_title()
        if self.content_shown:
            self.contentwidget.update_language()

    def reconstruct_menu(self):
        self.mainlayout.removeWidget(self.menubar)
        self.menubar.deleteLater()
        del(self.menubar)
        self.menubar = self.construct_menu_bar()
        self.mainlayout.insertWidget(0, self.menubar)
        self.update_menu()
        
    def reconstruct_contents(self):
        if self.project == None:
            self.mainlayout.removeWidget(self.welcomewidget)
            self.welcomewidget.deleteLater()
            del(self.welcomewidget)
            self.welcomewidget = WelcomeWidget(self)
            self.mainlayout.insertWidget(1, self.welcomewidget)
    
    def do_edit_undo_local(self):
        return
        
    def do_edit_redo_local(self):
        return
        
    def do_edit_paste(self):
        if self.copy_paste_target_widget != None:
            self.copy_paste_target_widget.insert(
                 get_app_singleton().clipboard().text(QClipboard.Clipboard))
    
    def do_edit_copy(self):
        if self.copy_paste_target_widget != None:
            if not self.copy_paste_target_widget.hasSelectedText():
                return
            get_app_singleton().clipboard().setText(
                self.copy_paste_target_widget.selectedText())
    
    def do_edit_cut(self):
        if self.copy_paste_target_widget != None:
            if not self.copy_paste_target_widget.hasSelectedText():
                return
            get_app_singleton().clipboard().setText(
                self.copy_paste_target_widget.selectedText())
            self.copy_paste_target_widget.insert("")
    
    def do_edit_select_all(self):
        if self.copy_paste_target_widget != None:
            self.copy_paste_target_widget.selectAll()
            
    def update_undo(self):
        """ Check if there's stuff to undo/redo and enable menu entries
            accordingly. """
        if self.project == None:
            return
        undo_file_name = l("undo_undo_prefix")
        redo_file_name = l("undo_redo_prefix")
        undo_file_enabled = False
        redo_file_enabled = False
        gotfile = None
        if self.content_shown and self.contentwidget != None:
            gotfile = self.contentwidget.fileshown
        if gotfile != None:
            # per file changes:
            change = self.project.changestracker.get_undoable_change_of_file(\
                gotfile)
            if change != None:
                undo_file_enabled = True
                undo_file_name = undo_file_name + ": " + change.\
                    get_description()
            else:
                undo_file_name = undo_file_name + ": " + l("undo_none")
            change = self.project.changestracker.get_redoable_change_of_file(\
                gotfile)
            if change != None:
                redo_file_enabled = True
                redo_file_name = redo_file_name + ": " + change.\
                    get_description()
            else:
                redo_file_name = redo_file_name + ": " + l("undo_none_redo")
            
        else:
            undo_file_name = undo_file_name + ": " + l("undo_nofile")
            redo_file_name = redo_file_name + ": " + l("undo_nofile")
        # global changes:
        undo_global_name = l("undo_undo_global_prefix")
        redo_global_name = l("undo_redo_global_prefix")
        undo_global_enabled = False
        redo_global_enabled = False
        change = self.project.changestracker.get_undoable_global_change()
        if change != None:
            undo_global_enabled = True
            undo_global_name = undo_global_name + ": " + change.\
                get_description()
        else:
            undo_global_name = undo_global_name + ": " + l("undo_none")
        change = self.project.changestracker.get_redoable_global_change()
        if change != None:
            redo_global_enabled = True
            redo_global_name = redo_global_name + ": " + change.\
                get_description()
        else:
            redo_global_name = redo_global_name + ": " + l("undo_none_redo")

        # apply text and enabled states:
        self.editmenuactions["undo"].setText(undo_file_name)
        self.editmenuactions["redo"].setText(redo_file_name)
        self.editmenuactions["undo_global"].setText(undo_global_name)
        self.editmenuactions["redo_global"].setText(redo_global_name)
        if undo_file_enabled:
            self.editmenuactions["undo"].setEnabled(1)
        else:
            self.editmenuactions["undo"].setEnabled(0)
        if redo_file_enabled:
            self.editmenuactions["redo"].setEnabled(1)
        else:
            self.editmenuactions["redo"].setEnabled(0)
        if undo_global_enabled:
            self.editmenuactions["undo_global"].setEnabled(1)
        else:
            self.editmenuactions["undo_global"].setEnabled(0)
        if redo_global_enabled:
            self.editmenuactions["redo_global"].setEnabled(1)
        else:
            self.editmenuactions["redo_global"].setEnabled(0)

    def is_game_running(self):
        return False
        
    def construct_menu_bar(self):
        bar = QMenuBar()
        
        # Project menu:
        self.projectmenuactions = dict()
        projectmenu = QMenu(l("projwin_menu_project"))
        self.projectmenuactions["new"] = \
            projectmenu.addAction(QIcon.fromTheme("document-new"),
            l("projwin_menu_project_new"), self.new_project_window)
        self.projectmenuactions["open"] = \
            projectmenu.addAction(QIcon.fromTheme("document-open"),
            l("projwin_menu_project_open"), self.open_project_window)
        projectmenu.addSeparator()
        self.projectmenuactions["save"] = \
            projectmenu.addAction(QIcon.fromTheme("document-save"),
            l("projwin_menu_project_saveall"))
        self.projectmenuactions["save"].setShortcut(
            QKeySequence.Save)
        self.projectmenuactions["saveas"] = \
            projectmenu.addAction(
            l("projwin_menu_project_saveas"))
        projectmenu.addSeparator()
        if self.project != None:
            self.projectmenuactions["close"] = \
                projectmenu.addAction(
                l("projwin_menu_project_close"), self.close_window)
        else:
            self.projectmenuactions["close"] = \
                projectmenu.addAction(
                l("projwin_menu_project_closewindow"), self.close_window)
        self.projectmenuactions["quit"] = \
            projectmenu.addAction(QIcon.fromTheme("application-exit"),
            l("projwin_menu_project_quit"), self.app.close_all)
        
        # File menu:
        filemenu = QMenu(l("projwin_menu_file"))
        self.filemenu = filemenu
        self.filemenuactions = dict()
        
        self.filemenuactions["new"] = \
            filemenu.addAction(QIcon.fromTheme("document-new"),
                l("projwin_menu_file_new"))
        self.filemenuactions["add"] = \
            filemenu.addAction(l("projwin_menu_file_add"))
        self.filemenuactions["addfolder"] = \
            filemenu.addAction(QIcon.fromTheme("folder-new"),
            l("projwin_menu_file_addfolder"))
        filemenu.addSeparator()
        self.filemenuactions["save"] = \
            filemenu.addAction(QIcon.fromTheme("document-save"),
                l("projwin_menu_file_save"))
        self.filemenuactions["rename"] = \
            filemenu.addAction(l("projwin_menu_file_rename"))
        filemenu.addSeparator()
        self.filemenuactions["remove"] = \
            filemenu.addAction(QIcon.fromTheme("edit-delete"),
            l("projwin_menu_file_remove"))
        
        # Edit menu:
        editmenu = QMenu(l("projwin_menu_edit"))
        self.editmenu = editmenu
        self.editmenu.aboutToShow.connect(self.update_menu)
        self.editmenuactions = dict()

        self.editmenuactions["undo"] = \
            editmenu.addAction(QIcon.fromTheme("edit-undo"),
            "undo_local", self.do_edit_undo_local)
        self.editmenuactions["undo"].setShortcut(
            QKeySequence.Undo)
        self.editmenuactions["redo"] = \
            editmenu.addAction(QIcon.fromTheme("edit-redo"),
            "redo_local", self.do_edit_redo_local)
        self.editmenuactions["redo"].setShortcut(
            QKeySequence.Redo)
        editmenu.addSeparator()
        self.editmenuactions["undo_global"] = \
            editmenu.addAction(QIcon.fromTheme("edit-undo"),
            "undo_global")
        self.editmenuactions["redo_global"] = \
            editmenu.addAction(QIcon.fromTheme("edit-redo"),
            "redo_global")
        self.update_undo()
        editmenu.addSeparator()
        self.editmenuactions["cut"] = \
            editmenu.addAction(QIcon.fromTheme("edit-cut"),
            l("projwin_menu_edit_cut"), self.do_edit_cut)
        self.editmenuactions["cut"].setShortcut(
            QKeySequence.Cut)
        self.editmenuactions["copy"] = \
            editmenu.addAction(QIcon.fromTheme("edit-copy"),
            l("projwin_menu_edit_copy"), self.do_edit_copy)
        self.editmenuactions["copy"].setShortcut(
            QKeySequence.Copy)
        self.editmenuactions["paste"] = \
            editmenu.addAction(QIcon.fromTheme("edit-paste"),
            l("projwin_menu_edit_paste"), self.do_edit_paste)
        self.editmenuactions["paste"].setShortcut(
            QKeySequence.Paste)
        editmenu.addSeparator()
        self.editmenuactions["select_all"] = \
            editmenu.addAction(
            l("projwin_menu_edit_select_all"), self.do_edit_select_all)
        self.editmenuactions["select_all"].setShortcut(
                    QKeySequence.SelectAll)
        # Run menu
        runmenu = QMenu(l("projwin_menu_run"))
        self.runmenu = runmenu
        self.runmenuactions = dict()
        
        self.runmenuactions["run_in_editor"] = \
            runmenu.addAction(QIcon.fromTheme("media-playback-start"),
            l("projwin_menu_run_in_editor"))
        runmenu.addSeparator()
        self.runmenuactions["run_in_editor_from_start"] = \
            runmenu.addAction(
            l("projwin_menu_run_in_editor_from_start"))
        self.runmenuactions["run_external"] = \
            runmenu.addAction(QIcon.fromTheme("go-jump"),
            l("projwin_menu_run_external"))
        runmenu.addSeparator()
        self.runmenuactions["run_pause"] = \
            runmenu.addAction(QIcon.fromTheme("media-playback-pause"),
            l("projwin_menu_run_pause"))
        runmenu.addSeparator()
        self.runmenuactions["run_stop"] = \
            runmenu.addAction(QIcon.fromTheme("process-stop"),
            l("projwin_menu_run_stop"))

        # Settings > Language menu
        languagesmenu = QMenu(l("projwin_menu_settings_language"))
        languagesmenu.setIcon(QIcon.fromTheme("preferences-desktop-locale"))
        def other_language(language):
            change_language(language)
            assert(get_current_language() == language)
            self.app.update_language()
        for (id, name) in list_languages():
            a = languagesmenu.addAction(
                name,
                lambda id=id: other_language(id)
                )
            if id == get_current_language():
                a.setCheckable(True)
                a.setChecked(True)
        # Settings menu
        self.settingsmenuactions = dict()
        settingsmenu = QMenu(l("projwin_menu_settings"))
        settingsmenu.addMenu(languagesmenu)
        
        # Window menu
        self.windowmenuactions = dict()
        windowmenu = QMenu(l("projwin_menu_window"))
        self.windowmenuactions["new"] = \
            windowmenu.addAction(QIcon.fromTheme("window-new"),
            l("projwin_menu_window_new"),
            self.new_window)
        windowmenu.addSeparator()
        self.windowmenuactions["dock_filelist"] = \
            windowmenu.addAction(
            l("projwin_menu_window_dock_filelist"),
            lambda: self.contentwidget.toggle_dock_visible("filelist")) 
        self.windowmenuactions["dock_filelist"].setCheckable(True)
        windowmenu.addSeparator()
        self.windowmenuactions["close"] = \
            windowmenu.addAction(l("projwin_menu_window_close"),
            self.close_window)
        
        # About menu
        self.aboutmenuactions = dict()
        aboutmenu = QMenu(l("projwin_menu_about"))
            
        self.aboutmenuactions["new"] = \
            aboutmenu.addAction(QIcon.fromTheme("help-about"),
            l("projwin_menu_about_about"),
            lambda pwin=self: pwin.open_about_dlg())
            
        bar.addMenu(projectmenu)
        bar.addMenu(self.filemenu)
        bar.addMenu(self.editmenu)
        bar.addMenu(self.runmenu)
        bar.addMenu(settingsmenu)
        bar.addMenu(windowmenu)
        bar.addMenu(aboutmenu)
        return bar
        
    def closeEvent(self, event):
        if self.modal_dialog:
            self.app.close_canceled = True
            event.ignore()
            return
        
        for window in get_app_singleton().windows:
            if not hasattr(window, "content_shown"):
                # this is a popout window. close it if it belongs to us:
                if window.project == self.project:
                    window.close()
        event.accept()
        
    def new_project_window(self):
        self.new_project_window = NewProjectWindow(self)
        self.new_project_window.exec_()
        del(self.new_project_window)
    
    def open_project_window(self):
        self.open_project_window = OpenProjectWindow(self)
        self.open_project_window.exec_()
        del(self.open_project_window)
        
    def close_window(self):
        self.close()

    def new_window(self):
        self.app.open_project_window()

    def open_about_dlg(self):
        if self.about_dlg:
            self.about_dlg.activateWindow()
            #self.about_dlg.raise()
            return
        self.about_dlg = AboutWindow(self)
        self.about_dlg.show()

    def update_title(self):
        name = None
        if self.project != None:
            name = self.project.name
        modifiedIndicator = ""
        if name == None:
            name = l("projwin_no_project")
            modifiedIndicator = ""
        if self.project != None:
            if self.project.has_unsaved_changes():
                modifiedIndicator = "*"
        fileName = ""
        fileModifiedIndicator = ""
        if self.content_shown and self.contentwidget != None:
            if self.contentwidget.fileshown != None:
                fileName = self.contentwidget.fileshown
                if self.project.changestracker.file_has_changes(fileName):
                    fileModifiedIndicator = "* - "
                else:
                    fileModifiedIndicator = " - "
        self.setWindowTitle(name + modifiedIndicator + " - " + \
            fileName + fileModifiedIndicator + l("projwin_title"))

    def update_window_menu(self):
        if self.project == None:
            self.windowmenuactions["dock_filelist"].setEnabled(0)
            return
        else:
            self.windowmenuactions["dock_filelist"].setEnabled(1)

        if not self.content_shown:
            return

        if self.contentwidget.is_dock_visible("filelist"):
            self.windowmenuactions["dock_filelist"].setChecked(True)
        else:
            self.windowmenuactions["dock_filelist"].setChecked(False)
    def update_menu(self):
        self.update_window_menu()
        if self.project == None:
            self.projectmenuactions["save"].setEnabled(0)
            self.projectmenuactions["saveas"].setEnabled(0)
            self.projectmenuactions["close"].setEnabled(1)
            self.filemenu.setEnabled(0)
            self.editmenu.setEnabled(0)
            self.runmenu.setEnabled(0)
            self.projectmenuactions["close"].setText(\
                l("projwin_menu_project_closewindow"))
        else:
            if self.project.has_unsaved_changes():
                self.projectmenuactions["save"].setEnabled(1)
            else:
                self.projectmenuactions["save"].setEnabled(0)
            self.runmenu.setEnabled(1)
            self.editmenu.setEnabled(1)
            self.projectmenuactions["saveas"].setEnabled(1)
            self.projectmenuactions["close"].setEnabled(1)
            self.projectmenuactions["close"].setText(\
                l("projwin_menu_project_close"))
            
            self.filemenu.setEnabled(1)
            
            if self.is_game_running():
                self.runmenuactions["run_in_editor"].setEnabled(0)
                self.runmenuactions["run_in_editor_from_start"].setEnabled(0)
                self.runmenuactions["run_external"].setEnabled(0)
                self.runmenuactions["run_pause"].setEnabled(1)
                self.runmenuactions["run_stop"].setEnabled(1)
            else:
                self.runmenuactions["run_in_editor"].setEnabled(1)
                self.runmenuactions["run_in_editor_from_start"].setEnabled(1)
                self.runmenuactions["run_external"].setEnabled(1)
                self.runmenuactions["run_pause"].setEnabled(0)
                self.runmenuactions["run_stop"].setEnabled(0)
                
            # if file shown:
            if self.contentwidget != None and \
                    self.contentwidget.isFileShown():
                self.filemenuactions["save"].setEnabled(0)
                if self.project.changestracker.file_has_changes(\
                        self.contentwidget.fileshown):
                    self.filemenuactions["save"].setEnabled(1)
                self.filemenuactions["rename"].setEnabled(1)
                self.filemenuactions["remove"].setEnabled(1)

                # if text editable focussed:
                if self.copy_paste_target_widget != None:
                    if self.copy_paste_target_widget.hasSelectedText():
                        self.editmenuactions["cut"].setEnabled(1)
                        self.editmenuactions["copy"].setEnabled(1)
                    else:
                        self.editmenuactions["cut"].setEnabled(0)
                        self.editmenuactions["copy"].setEnabled(0)
                    if len(get_app_singleton().clipboard().text(\
                            QClipboard.Clipboard)) > 0:
                        self.editmenuactions["paste"].setEnabled(1)
                    else:
                        self.editmenuactions["paste"].setEnabled(0)
                        
                    text = self.copy_paste_target_widget.text()
                    if len(text) > 0:
                        self.editmenuactions["select_all"].setEnabled(1)
                    else:
                        self.editmenuactions["select_all"].setEnabled(0)
                else:
                    self.editmenuactions["cut"].setEnabled(0)
                    self.editmenuactions["copy"].setEnabled(0)
                    self.editmenuactions["paste"].setEnabled(0)
                    self.editmenuactions["select_all"].setEnabled(0)
            else:
                # ..otherwise:
                self.filemenuactions["save"].setEnabled(0)
                self.filemenuactions["rename"].setEnabled(0)
                self.filemenuactions["remove"].setEnabled(0)
                self.editmenuactions["cut"].setEnabled(0)
                self.editmenuactions["copy"].setEnabled(0)
                self.editmenuactions["paste"].setEnabled(0)
                self.editmenuactions["select_all"].setEnabled(0)