Commit 330d62a4 authored by Harish Fulara's avatar Harish Fulara Committed by Alexandru Băluț

ui: welcome window integration

parent 7c53a243
Pipeline #16282 passed with stage
in 38 minutes 53 seconds
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkScrolledWindow" id="scrolled_window">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
<child>
<object class="GtkViewport" id="view_port">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="topvbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkInfoBar" id="infobar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_close_button">True</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can_focus">False</property>
<property name="spacing">6</property>
<property name="layout_style">end</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child internal-child="content_area">
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="spacing">16</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="recent_projects_topvbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="margin_top">30</property>
<property name="margin_bottom">10</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="recent_projects_labelbox">
<property name="name">recent_projects_labelbox</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="recent_projects_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Recent Projects</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkListBox" id="recent_projects_listbox">
<property name="name">recent_projects_listbox</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
......@@ -7,35 +7,11 @@
<property name="can_focus">False</property>
<property name="halign">end</property>
<child>
<object class="GtkMenuItem" id="menu_new">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">win.new-project</property>
<property name="label" translatable="yes">New project</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menu_open">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">win.open-project</property>
<property name="label" translatable="yes">Open project...</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="menu_sep1">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menu_save_as">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Save the current project under a new name or a different location</property>
<property name="action_name">win.save-as</property>
<property name="action_name">editor.save-as</property>
<property name="label" translatable="yes">Save As...</property>
<property name="use_underline">True</property>
</object>
......@@ -129,9 +105,9 @@
<object class="GtkMenuItem" id="menu_about">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">win.about</property>
<property name="label" translatable="yes">About</property>
<property name="use_underline">True</property>
<signal name="activate" handler="_aboutCb" swapped="no"/>
</object>
</child>
</object>
......
......@@ -29,7 +29,6 @@ from gi.repository import Gtk
from pitivi.configure import RELEASES_URL
from pitivi.configure import VERSION
from pitivi.dialogs.startupwizard import StartUpWizard
from pitivi.effects import EffectsManager
from pitivi.mainwindow import MainWindow
from pitivi.pluginmanager import PluginManager
......@@ -58,6 +57,7 @@ class Pitivi(Gtk.Application, Loggable):
action_log (UndoableActionLog): The undo/redo log for the current project.
effects (EffectsManager): The effects which can be applied to a clip.
gui (MainWindow): The main window of the app.
recent_manager (Gtk.RecentManager): Manages recently used projects.
project_manager (ProjectManager): The holder of the current project.
settings (GlobalSettings): The application-wide settings.
system (pitivi.utils.system.System): The system running the app.
......@@ -84,7 +84,7 @@ class Pitivi(Gtk.Application, Loggable):
self._last_action_time = Gst.util_get_timestamp()
self.gui = None
self.__welcome_wizard = None
self.recent_manager = Gtk.RecentManager.get_default()
self.__inhibit_cookies = {}
self._version_information = {}
......@@ -152,6 +152,7 @@ class Pitivi(Gtk.Application, Loggable):
self.project_manager.connect(
"new-project-loaded", self._newProjectLoaded)
self.project_manager.connect("project-closed", self._projectClosed)
self.project_manager.connect("project-saved", self.__project_saved_cb)
self._createActions()
self._syncDoUndo()
......@@ -198,27 +199,21 @@ class Pitivi(Gtk.Application, Loggable):
self.gui.present()
# No need to show the welcome wizard.
return
self.createMainWindow()
self.welcome_wizard.show()
@property
def welcome_wizard(self):
if not self.__welcome_wizard:
self.__welcome_wizard = StartUpWizard(self)
return self.__welcome_wizard
self.create_main_window()
self.gui.show_perspective(self.gui.greeter)
self.gui.show()
def createMainWindow(self):
def create_main_window(self):
if self.gui:
return
self.gui = MainWindow(self)
self.gui.setup_ui()
self.add_window(self.gui)
self.gui.checkScreenConstraints()
# We might as well show it.
self.gui.show()
def do_open(self, giofiles, unused_count, unused_hint):
assert giofiles
self.createMainWindow()
self.create_main_window()
self.gui.show()
if len(giofiles) > 1:
self.warning(
"Can open only one project file at a time. Ignoring the rest!")
......@@ -238,8 +233,6 @@ class Pitivi(Gtk.Application, Loggable):
self.warning(
"Not closing since running project doesn't want to close")
return False
if self.welcome_wizard:
self.welcome_wizard.hide()
if self.gui:
self.gui.destroy()
self.threads.stopAllThreads()
......@@ -276,13 +269,23 @@ class Pitivi(Gtk.Application, Loggable):
self._setScenarioFile(project.get_uri())
def _newProjectLoaded(self, unused_project_manager, project):
uri = project.get_uri()
if uri:
# We remove the project from recent projects list
# and then re-add it to this list to make sure it
# gets positioned at the top of the recent projects list.
self.recent_manager.remove_item(uri)
self.recent_manager.add_item(uri)
self.action_log = UndoableActionLog()
self.action_log.connect("pre-push", self._action_log_pre_push_cb)
self.action_log.connect("commit", self._actionLogCommit)
self.action_log.connect("move", self._action_log_move_cb)
self.project_observer = ProjectObserver(project, self.action_log)
def __project_saved_cb(self, unused_project_manager, unused_project, uri):
if uri:
self.recent_manager.add_item(uri)
def _projectClosed(self, unused_project_manager, project):
if project.loaded:
self.action_log = None
......@@ -389,7 +392,7 @@ class Pitivi(Gtk.Application, Loggable):
self.project_manager.current_project.setModificationState(dirty)
# In the tests we do not want to create any gui
if self.gui is not None:
self.gui.showProjectStatus()
self.gui.editor.showProjectStatus()
def simple_inhibit(self, reason, flags):
"""Informs the session manager about actions to be inhibited.
......
......@@ -785,7 +785,7 @@ class TransformationProperties(Gtk.Expander, Loggable):
for prop in ["posx", "posy", "width", "height"]:
self.__update_spin_btn(prop)
# Keep the overlay stack in sync with the spin buttons values
self.app.gui.viewer.overlay_stack.update(self.source)
self.app.gui.editor.viewer.overlay_stack.update(self.source)
def __source_property_changed_cb(self, unused_source, unused_element, param):
self.__update_spin_btn(param.name)
......@@ -862,7 +862,7 @@ class TransformationProperties(Gtk.Expander, Loggable):
if value != cvalue:
self.__set_prop(prop, value)
self.app.gui.viewer.overlay_stack.update(self.source)
self.app.gui.editor.viewer.overlay_stack.update(self.source)
def __set_source(self, source):
if self.source:
......@@ -888,7 +888,7 @@ class TransformationProperties(Gtk.Expander, Loggable):
if source:
self._selected_clip = clip
self.__set_source(source)
self.app.gui.viewer.overlay_stack.select(source)
self.app.gui.editor.viewer.overlay_stack.select(source)
self.show()
return
......
# -*- coding: utf-8 -*-
# Pitivi video editor
# Copyright (c) 2005, Edward Hervey <bilboed@bilboed.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301, USA.
"""Pitivi's about dialog."""
from gettext import gettext as _
from gi.repository import GES
from gi.repository import Gst
from gi.repository import Gtk
from pitivi.configure import APPNAME
from pitivi.configure import APPURL
from pitivi.configure import GITVERSION
from pitivi.configure import in_devel
from pitivi.configure import VERSION
# pylint: disable=too-few-public-methods
class AboutDialog(Gtk.AboutDialog):
"""Pitivi's about dialog.
Displays info regarding Pitivi's version, license,
maintainers, contributors, etc.
Attributes:
app (Pitivi): The app.
"""
def __init__(self, app):
Gtk.AboutDialog.__init__(self)
self.set_program_name(APPNAME)
self.set_website(APPURL)
if in_devel():
version_str = _("Development version: %s") % GITVERSION
elif not app.isLatest():
version_str = _("Version %(cur_ver)s — %(new_ver)s is available") % \
{"cur_ver": GITVERSION,
"new_ver": app.getLatest()}
elif GITVERSION:
version_str = _("Version %s") % GITVERSION
else:
version_str = _("Version %s") % VERSION
self.set_version(version_str)
comments = ["",
"GES %s" % ".".join(map(str, GES.version())),
"GTK+ %s" % ".".join(map(str, (Gtk.MAJOR_VERSION, Gtk.MINOR_VERSION))),
"GStreamer %s" % ".".join(map(str, Gst.version()))]
self.set_comments("\n".join(comments))
authors = [_("Current maintainers:"),
"Jean-François Fortin Tam <nekohayo@gmail.com>",
"Thibault Saunier <tsaunier@gnome.org>",
"Mathieu Duponchelle <mduponchelle1@gmail.com>",
"Alexandru Băluț <alexandru.balut@gmail.com>",
"",
_("Past maintainers:"),
"Edward Hervey <bilboed@bilboed.com>",
"Alessandro Decina <alessandro.decina@collabora.co.uk>",
"Brandon Lewis <brandon_lewis@berkeley.edu>",
"",
# Translators: this paragraph is to be translated, the list
# of contributors is shown dynamically as a clickable link
# below it
_("Contributors:\n" +
"A handwritten list here would...\n" +
"• be too long,\n" +
"• be frequently outdated,\n" +
"• not show their relative merit.\n\n" +
"Out of respect for our contributors, we point you instead to:\n"),
# Translators: keep the %s at the end of the 1st line
_("The list of contributors on Ohloh %s\n" +
"Or you can run: git shortlog -s -n")
% "http://ohloh.net/p/pitivi/contributors", ]
self.set_authors(authors)
# Translators: See
# https://developer.gnome.org/gtk3/stable/GtkAboutDialog.html#gtk-about-dialog-set-translator-credits
# for details on how this is used.
translators = _("translator-credits")
if translators != "translator-credits":
self.set_translator_credits(translators)
documenters = ["Jean-François Fortin Tam <nekohayo@gmail.com>", ]
self.set_documenters(documenters)
self.set_license_type(Gtk.License.LGPL_2_1)
self.set_icon_name("pitivi")
self.set_logo_icon_name("pitivi")
self.connect("response", self.__about_response_cb)
self.set_transient_for(app.gui)
@staticmethod
def __about_response_cb(dialog, unused_response):
dialog.destroy()
# -*- coding: utf-8 -*-
# Pitivi video editor
# Copyright (c) 2005, Edward Hervey <bilboed@bilboed.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301, USA.
"""Dialog for browsing through projects to open an existing project."""
from gettext import gettext as _
from gi.repository import GES
from gi.repository import Gtk
# pylint: disable=too-few-public-methods
class BrowseProjectsDialog(Gtk.FileChooserDialog):
"""Displays the Gtk.FileChooserDialog for browsing projects.
Attributes:
app (Pitivi): The app.
"""
def __init__(self, app):
Gtk.FileChooserDialog.__init__(self)
self.set_title(_("Open File..."))
self.set_transient_for(app.gui)
self.set_action(Gtk.FileChooserAction.OPEN)
self.add_buttons(_("Cancel"), Gtk.ResponseType.CANCEL,
_("Open"), Gtk.ResponseType.OK)
self.set_default_response(Gtk.ResponseType.OK)
self.set_select_multiple(False)
# TODO: Remove this set_current_folder call when GTK bug 683999 is
# fixed
self.set_current_folder(app.settings.lastProjectFolder)
formatter_assets = GES.list_assets(GES.Formatter)
formatter_assets.sort(
key=lambda x: - x.get_meta(GES.META_FORMATTER_RANK))
for format_ in formatter_assets:
filt = Gtk.FileFilter()
filt.set_name(format_.get_meta(GES.META_DESCRIPTION))
filt.add_pattern("*%s" %
format_.get_meta(GES.META_FORMATTER_EXTENSION))
self.add_filter(filt)
default = Gtk.FileFilter()
default.set_name(_("All supported formats"))
default.add_custom(Gtk.FileFilterFlags.URI, self.__can_load_uri, None)
self.add_filter(default)
# pylint: disable=bare-except
@staticmethod
def __can_load_uri(filterinfo, unused_uri):
try:
return GES.Formatter.can_load_uri(filterinfo.uri)
except:
return False
# -*- coding: utf-8 -*-
# Pitivi video editor
# Copyright (c) 2010 Mathieu Duponchelle <seeed@laposte.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301, USA.
import os
from gettext import gettext as _
from gi.repository import Gdk
from gi.repository import GES
from gi.repository import Gtk
from pitivi.check import missing_soft_deps
from pitivi.configure import get_ui_dir
from pitivi.dialogs.depsmanager import DepsManager
from pitivi.shortcuts import show_shortcuts
from pitivi.utils.misc import show_user_manual
from pitivi.utils.ui import fix_infobar
class StartUpWizard(object):
"""A Wizard displaying recent projects.
Allows the user to:
- create a new project and open the settings dialog (Create button),
- create a new project with the default settings (dialog close or ESC),
- load a recently opened project (double click recent chooser),
- load a project (Browse button),
- see the quick start manual (User Manual button).
"""
@staticmethod
def _userManualCb(unused_button):
"""Handles a click on the Help button."""
show_user_manual()
def _cheatsheetCb(self, unused_button):
"""Shows the shortcuts cheatsheet."""
show_shortcuts(self.app)
def __init__(self, app):
self.app = app
self.builder = Gtk.Builder()
self.builder.add_from_file(
os.path.join(get_ui_dir(), "startupwizard.ui"))
self.builder.connect_signals(self)
self.window = self.builder.get_object("window1")
# The line below is supremely important, it will NOT work if set
# only by the GtkBuilder file. The DIALOG TypeHint allows proper
# attachment (visually, behaviorally) to MainWindow, and
# prevents other windows from showing on top too easily.
self.window.set_type_hint(Gdk.WindowTypeHint.DIALOG)
self.recent_chooser = self.builder.get_object("recentchooser2")
# FIXME: gtk creates a combo box with only one item, but there is no
# simple way to hide it.
_filter = Gtk.RecentFilter()
_filter.set_name(_("Projects"))
for asset in GES.list_assets(GES.Formatter):
_filter.add_pattern(
'*.' + asset.get_meta(GES.META_FORMATTER_EXTENSION))
self.recent_chooser.add_filter(_filter)
missing_button = self.builder.get_object("missing_deps_button")
if not missing_soft_deps:
missing_button.hide()
vbox = self.builder.get_object("topvbox")
self.infobar = Gtk.InfoBar()
fix_infobar(self.infobar)
vbox.pack_start(self.infobar, True, True, 0)
if self.app.getLatest():
self._appVersionInfoReceivedCb(self.app, None)
else:
self.app.connect(
"version-info-received", self._appVersionInfoReceivedCb)
def _newProjectCb(self, unused_button):
"""Handles a click on the New (Project) button."""
self.app.project_manager.newBlankProject()
def _loadCb(self, unused_recent_chooser):
"""Handles choosing a project on the recent chooser.
This calls the project manager to load the associated URI.
"""
uri = self.recent_chooser.get_current_uri()
self.app.project_manager.loadProject(uri)
def _keyPressCb(self, unused_widget, event):
"""Handles a key press event on the dialog."""
if event.keyval == Gdk.KEY_Escape:
# The user pressed "Esc".
self.app.project_manager.newBlankProject()
def _onBrowseButtonClickedCb(self, unused_button6):
"""Handles a click on the Browse button."""
self.app.gui.openProject()
def _onMissingDepsButtonClickedCb(self, unused_button):
"""Handles a click on the Missing Deps button."""
DepsManager(self.app, parent_window=self.window)
def _deleteCb(self, unused_widget, unused_event):
"""Handles a click on the X button of the dialog."""
self.app.project_manager.newBlankProject()
return True
def show(self):
if self.window.props.visible:
return
self.window.set_transient_for(self.app.gui)
self.window.show()
project_manager = self.app.project_manager
project_manager.connect("new-project-loading", self._projectLoadingCb)
def hide(self):
if not self.window.props.visible:
return
self.window.hide()
project_manager = self.app.project_manager
project_manager.disconnect_by_func(self._projectLoadingCb)
def _projectLoadingCb(self, unused_project_manager, unused_uri):
"""Handles the start of a project load operation."""
self.hide()
def _appVersionInfoReceivedCb(self, app, unused_version_information):
"""Handles new version info."""
if app.isLatest():
# current version, don't show message
return
latest_version = app.getLatest()
if self.app.settings.lastCurrentVersion != latest_version:
# new latest version, reset counter
self.app.settings.lastCurrentVersion = latest_version
self.app.settings.displayCounter = 0
if self.app.settings.displayCounter >= 5:
# current version info already showed 5 times, don't show again
return
# increment counter, create infobar and show info
self.app.settings.displayCounter = self.app.settings.displayCounter + 1
text = _("Pitivi %s is available.") % latest_version
label = Gtk.Label(label=text)
self.infobar.get_content_area().add(label)
self.infobar.set_message_type(Gtk.MessageType.INFO)
self.infobar.show_all()
This diff is collapsed.
......@@ -538,7 +538,7 @@ class EffectListWidget(Gtk.Box, Loggable):
effect_info = self.app.effects.getInfo(effect)
if not effect_info:
return
timeline = self.app.gui.timeline_ui.timeline
timeline = self.app.gui.editor.timeline_ui.timeline
clip = timeline.selection.getSingleClip()
if not clip:
return
......
# -*- coding: utf-8 -*-
# Pitivi video editor
# Copyright (c) 2010 Mathieu Duponchelle <seeed@laposte.net>
# Copyright (c) 2018 Harish Fulara <harishfulara1996@gmail.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301, USA.
"""Pitivi's Welcome/Greeter perspective."""
import os
from gettext import gettext as _
from gi.repository import Gdk
from gi.repository import GES
from gi.repository import Gio
from gi.repository import Gtk
from pitivi.configure import get_ui_dir
from pitivi.dialogs.browseprojects import BrowseProjectsDialog
from pitivi.perspective import Perspective
from pitivi.utils.ui import fix_infobar
from pitivi.utils.ui import GREETER_PERSPECTIVE_CSS
MAX_RECENT_PROJECTS = 10
class ProjectInfoRow(Gtk.ListBoxRow):
"""Displays a project's info.
Attributes:
project: Project's meta-data.
"""
def __init__(self, project):
Gtk.ListBoxRow.__init__(self)
self.uri = project.get_uri()
self.add(Gtk.Label(project.get_display_name(), xalign=0))