[longomatch] Closes bug: #598675 - Memory leak handling Project objects
- From: Andoni Morales Alastruey <amorales src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [longomatch] Closes bug: #598675 - Memory leak handling Project objects
- Date: Fri, 16 Oct 2009 15:33:51 +0000 (UTC)
commit dd65f5f439e5981ddccbe8732c4574d6e7bfa191
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date: Fri Oct 16 17:05:54 2009 +0200
Closes bug: #598675 - Memory leak handling Project objects
LongoMatch/DB/DataBase.cs | 111 +++++++++------
LongoMatch/DB/Project.cs | 155 ++++++++++---------
LongoMatch/DB/Sections.cs | 4 +
LongoMatch/DB/TeamTemplate.cs | 6 +-
LongoMatch/Gui/Component/ButtonsWidget.cs | 13 +-
LongoMatch/Gui/Component/PlayersListTreeWidget.cs | 5 +
LongoMatch/Gui/Component/PlaysListTreeWidget.cs | 12 +-
LongoMatch/Gui/Component/ProjectDetailsWidget.cs | 25 ++--
LongoMatch/Gui/Component/ProjectListWidget.cs | 62 ++++-----
LongoMatch/Gui/Component/TimeLineWidget.cs | 30 +++--
LongoMatch/Gui/Dialog/OpenProjectDialog.cs | 21 +--
LongoMatch/Gui/Dialog/ProjectsManager.cs | 42 +++---
LongoMatch/Gui/MainWindow.cs | 80 ++++-------
LongoMatch/Handlers/HotKeysManager.cs | 20 ++-
LongoMatch/LongoMatch.mdp | 1 +
LongoMatch/Main.cs | 9 +-
LongoMatch/Makefile.am | 1 +
.../LongoMatch.Gui.Dialog.OpenProjectDialog.cs | 3 +-
LongoMatch/gtk-gui/LongoMatch.Gui.MainWindow.cs | 6 +-
LongoMatch/gtk-gui/gui.stetic | 11 +-
LongoMatch/gtk-gui/objects.xml | 16 +-
21 files changed, 329 insertions(+), 304 deletions(-)
---
diff --git a/LongoMatch/DB/DataBase.cs b/LongoMatch/DB/DataBase.cs
index 1c6446b..209f710 100644
--- a/LongoMatch/DB/DataBase.cs
+++ b/LongoMatch/DB/DataBase.cs
@@ -20,7 +20,7 @@
using System;
using System.IO;
-using System.Collections;
+using System.Collections.Generic;
using System.Reflection;
using Gdk;
using Mono.Unix;
@@ -34,8 +34,6 @@ namespace LongoMatch.DB
public sealed class DataBase
{
- // Database container
- private IObjectContainer db;
// File path of the database
private string file;
// Lock object
@@ -52,7 +50,7 @@ namespace LongoMatch.DB
this.file = file;
if (!System.IO.File.Exists(file)){
// Create new DB and add version
- db = Db4oFactory.OpenFile(file);
+ IObjectContainer db = Db4oFactory.OpenFile(file);
try{
dbVersion= new Version(MAYOR,MINOR);
db.Set(dbVersion);
@@ -60,10 +58,9 @@ namespace LongoMatch.DB
finally{
db.Close();
}
- }
-
+ }
else{
- db = Db4oFactory.OpenFile(file);
+ IObjectContainer db = Db4oFactory.OpenFile(file);
try {
IQuery query = db.Query();
query.Constrain(typeof(Version));
@@ -88,97 +85,107 @@ namespace LongoMatch.DB
get{return dbVersion;}
}
- public ArrayList GetAllDB(){
+ public List<ProjectDescription> GetAllProjects(){
lock(this.locker){
- ArrayList allDB = new ArrayList();
- db = Db4oFactory.OpenFile(file);
+ List<ProjectDescription> list = new List<ProjectDescription>();
+ IObjectContainer db = Db4oFactory.OpenFile(file);
+ db.Ext().Configure().ActivationDepth(1);
try {
IQuery query = db.Query();
query.Constrain(typeof(Project));
IObjectSet result = query.Execute();
while (result.HasNext()){
- allDB.Add(result.Next());
- }
- return allDB;
+ Project p = (Project)result.Next();
+ db.Activate(p.File,3);
+ ProjectDescription pd = new ProjectDescription(p.File.FilePath,
+ p.LocalName, p.VisitorName,
+ p.Season,p.Competition,
+ p.LocalGoals,p.VisitorGoals,
+ p.MatchDate,p.File.Preview);
+ list.Add(pd);
+ }
+ return list;
}
finally
{
- db.Close();
+ CloseDB(db);
}
}
}
public Project GetProject(String filename){
+ Project ret;
lock(this.locker){
- db = Db4oFactory.OpenFile(file);
+ IObjectContainer db = Db4oFactory.OpenFile(file);
try {
IQuery query = db.Query();
query.Constrain(typeof(Project));
query.Descend("file").Descend("filePath").Constrain(filename);
IObjectSet result = query.Execute();
- return (Project)result.Next();
+ ret = (Project) db.Ext().PeekPersisted(result.Next(),10,true);
+ return ret;
}
finally
{
- db.Close();
+ CloseDB(db);
}
}
}
public void AddProject (Project project){
lock(this.locker){
- db = Db4oFactory.OpenFile(file);
+ IObjectContainer db = Db4oFactory.OpenFile(file);
try
{
- if (!this.Exists(project.File.FilePath)){
+ if (!this.Exists(project.File.FilePath,db)){
db.Set (project);
db.Commit();
}
else throw new Exception (Catalog.GetString("The Project for this video file already exists.")+"\n"+Catalog.GetString("Try to edit it whit the Database Manager"));
}
finally {
- db.Close();
+ CloseDB(db);
}
}
}
- public void RemoveProject(Project project){
+ public void RemoveProject(string filePath){
lock(this.locker){
- SetCascadeOptions();
- db = Db4oFactory.OpenFile(file);
+ SetDeleteCascadeOptions();
+ IObjectContainer db = Db4oFactory.OpenFile(file);
try {
IQuery query = db.Query();
query.Constrain(typeof(Project));
- query.Descend("file").Descend("filePath").Constrain(project.File.FilePath);
+ query.Descend("file").Descend("filePath").Constrain(filePath);
IObjectSet result = query.Execute();
- project = (Project)result.Next();
+ Project project = (Project)result.Next();
db.Delete(project);
db.Commit();
}
finally
{
- db.Close();
+ CloseDB(db);
}
}
}
public void UpdateProject(Project project, string previousFileName){
lock(this.locker){
- bool error = false;
-
+ bool error = false;
// Configure db4o to cascade on delete for each one of the objects stored in a Project
- SetCascadeOptions();
- db = Db4oFactory.OpenFile(file);
+ SetUpdateCascadeOptions();
+ IObjectContainer db = Db4oFactory.OpenFile(file);
try {
- // We look for a project with that uses the same file
- if (!Exists(project.File.FilePath)){
- // Delete the old project
+ // We look for a project with the same filename
+ if (!Exists(project.File.FilePath,db)){
IQuery query = db.Query();
query.Constrain(typeof(Project));
query.Descend("file").Descend("filePath").Constrain(previousFileName);
IObjectSet result = query.Execute();
+ //Get the stored object ID and bind it to "offline" modified
Project fd = (Project)result.Next();
- db.Delete(fd);
+ long id = db.Ext().GetID(fd);
+ db.Ext().Bind(project,id);
// Add the updated project
db.Set(project);
db.Commit();
@@ -187,7 +194,7 @@ namespace LongoMatch.DB
error = true;
}
finally{
- db.Close();
+ CloseDB(db);
if (error)
throw new Exception();
}
@@ -196,26 +203,32 @@ namespace LongoMatch.DB
public void UpdateProject(Project project){
lock(this.locker){
- SetCascadeOptions();
- db = Db4oFactory.OpenFile(file);
+ SetUpdateCascadeOptions();
+ IObjectContainer db = Db4oFactory.OpenFile(file);
try {
IQuery query = db.Query();
query.Constrain(typeof(Project));
query.Descend("file").Descend("filePath").Constrain(project.File.FilePath);
IObjectSet result = query.Execute();
Project fd = (Project)result.Next();
- db.Delete(fd);
+ long id = db.Ext().GetID(fd);
+ db.Ext().Bind(project,id);
db.Set(project);
db.Commit();
}
finally
{
- db.Close();
+ CloseDB(db);
}
}
}
- private void SetCascadeOptions(){
+ private void CloseDB(IObjectContainer db){
+ db.Ext().Purge();
+ db.Close();
+ }
+
+ private void SetDeleteCascadeOptions(){
Db4oFactory.Configure().ObjectClass(typeof(Project)).CascadeOnDelete(true);
Db4oFactory.Configure().ObjectClass(typeof(Sections)).CascadeOnDelete(true);
Db4oFactory.Configure().ObjectClass(typeof(TimeNode)).CascadeOnDelete(true);
@@ -227,14 +240,24 @@ namespace LongoMatch.DB
Db4oFactory.Configure().ObjectClass(typeof(Drawing)).CascadeOnDelete(true);
}
- private bool Exists(string filename){
-
+ private void SetUpdateCascadeOptions(){
+ Db4oFactory.Configure().ObjectClass(typeof(Project)).CascadeOnUpdate(true);
+ Db4oFactory.Configure().ObjectClass(typeof(Sections)).CascadeOnUpdate(true);
+ Db4oFactory.Configure().ObjectClass(typeof(TimeNode)).CascadeOnUpdate(true);
+ Db4oFactory.Configure().ObjectClass(typeof(Time)).CascadeOnUpdate(true);
+ Db4oFactory.Configure().ObjectClass(typeof(Team)).CascadeOnUpdate(true);
+ Db4oFactory.Configure().ObjectClass(typeof(HotKey)).CascadeOnUpdate(true);
+ Db4oFactory.Configure().ObjectClass(typeof(Player)).CascadeOnUpdate(true);
+ Db4oFactory.Configure().ObjectClass(typeof(TeamTemplate)).CascadeOnUpdate(true);
+ Db4oFactory.Configure().ObjectClass(typeof(Drawing)).CascadeOnUpdate(true);
+ }
+
+ private bool Exists(string filename, IObjectContainer db){
IQuery query = db.Query();
query.Constrain(typeof(Project));
query.Descend("file").Descend("filePath").Constrain(filename);
IObjectSet result = query.Execute();
return (result.HasNext());
}
- }
-
+ }
}
diff --git a/LongoMatch/DB/Project.cs b/LongoMatch/DB/Project.cs
index 69b8235..5e99c95 100644
--- a/LongoMatch/DB/Project.cs
+++ b/LongoMatch/DB/Project.cs
@@ -35,8 +35,7 @@ namespace LongoMatch.DB
{
private PreviewMediaFile file;
-
-
+
private string title;
private string localName;
@@ -60,9 +59,8 @@ namespace LongoMatch.DB
private TeamTemplate visitorTeamTemplate;
private TeamTemplate localTeamTemplate;
-
- private List<MediaTimeNode>[] dataSectionArray;
-
+ //Keep this fiel for DB retrocompatibility
+ private List<MediaTimeNode>[] dataSectionArray;
public Project(PreviewMediaFile file, String localName, String visitorName, String season, String competition, int localGoals,
@@ -87,6 +85,65 @@ namespace LongoMatch.DB
this.Title = System.IO.Path.GetFileNameWithoutExtension(this.file.FilePath);
}
+
+ public void Clear(){
+ //Help the GC freeing objects
+ foreach (List<MediaTimeNode> list in sectionPlaysList)
+ list.Clear();
+ sectionPlaysList.Clear();
+ Sections.Clear();
+ visitorTeamTemplate.Clear();
+ localTeamTemplate.Clear();
+ sectionPlaysList=null;
+ Sections=null;
+ visitorTeamTemplate=null;
+ localTeamTemplate=null;
+ }
+
+ public PreviewMediaFile File {
+ get{return file;}
+ set{file=value;}
+ }
+
+ public String Title {
+ get{return title;}
+ set{title=value;}
+ }
+
+ public String Season{
+ get{return season;}
+ set{season = value;}
+ }
+
+ public String Competition{
+ get{return competition;}
+ set{competition= value;}
+ }
+
+ public String LocalName {
+ get{ return localName;}
+ set{localName=value;}
+ }
+
+ public String VisitorName {
+ get{ return visitorName;}
+ set{visitorName=value;}
+ }
+
+ public int LocalGoals {
+ get{ return localGoals;}
+ set{localGoals=value;}
+ }
+
+ public int VisitorGoals {
+ get{ return visitorGoals;}
+ set{visitorGoals=value;}
+ }
+
+ public DateTime MatchDate {
+ get{ return matchDate;}
+ set{ matchDate=value;}
+ }
public Sections Sections{
get{ return this.sections;}
@@ -112,6 +169,21 @@ namespace LongoMatch.DB
sections.AddSectionAtPos(tn,sectionIndex);
}
+ public MediaTimeNode AddTimeNode(int dataSection, Time start, Time stop,Pixbuf thumbnail) {
+ MediaTimeNode tn ;
+ List<MediaTimeNode> playsList= sectionPlaysList[dataSection];
+ int count= playsList.Count+1;
+ string name = sections.GetName(dataSection) + " " +count;
+
+ tn = new MediaTimeNode(name, start, stop,"",file.Fps,thumbnail);
+ playsList.Add(tn);
+ return tn;
+ }
+
+ public void DeleteTimeNode(MediaTimeNode tNode,int section) {
+ sectionPlaysList[section].Remove(tNode);
+ }
+
public void DeleteSection(int sectionIndex){
if (sections.Count == 1)
throw new Exception ("You can't remove the last Section");
@@ -120,8 +192,7 @@ namespace LongoMatch.DB
}
public string[] GetSectionsNames(){
- return sections.GetSectionsNames();
-
+ return sections.GetSectionsNames();
}
public Time[] GetSectionsStartTimes(){
@@ -130,23 +201,7 @@ namespace LongoMatch.DB
public Time[] GetSectionsStopTimes(){
return sections.GetSectionsStopTimes();
- }
-
- public MediaTimeNode AddTimeNode(int dataSection, Time start, Time stop,Pixbuf thumbnail) {
- MediaTimeNode tn ;
- List<MediaTimeNode> playsList= sectionPlaysList[dataSection];
- int count= playsList.Count+1;
- string name = sections.GetName(dataSection) + " " +count;
-
- tn = new MediaTimeNode(name, start, stop,"",file.Fps,thumbnail);
- playsList.Add(tn);
- return tn;
-
- }
-
- public void DeleteTimeNode(MediaTimeNode tNode,int section) {
- sectionPlaysList[section].Remove(tNode);
- }
+ }
public TreeStore GetModel (){
Gtk.TreeStore dataFileListStore = new Gtk.TreeStore (typeof (MediaTimeNode));
@@ -192,57 +247,11 @@ namespace LongoMatch.DB
public List<List<MediaTimeNode>> GetDataArray() {
return sectionPlaysList;
}
-
-
- public PreviewMediaFile File {
- get{return file;}
- set{file=value;}
- }
-
-
-
- public String Title {
- get{return title;}
- set{title=value;}
- }
-
- public String Season{
- get{return season;}
- set{season = value;}
- }
- public String Competition{
- get{return competition;}
- set{competition= value;}
- }
-
- public String LocalName {
- get{ return localName;}
- set{localName=value;}
- }
-
- public String VisitorName {
- get{ return visitorName;}
- set{visitorName=value;}
- }
-
- public int LocalGoals {
- get{ return localGoals;}
- set{localGoals=value;}
- }
-
- public int VisitorGoals {
- get{ return visitorGoals;}
- set{visitorGoals=value;}
- }
-
-
- public DateTime MatchDate {
- get{ return matchDate;}
- set{ matchDate=value;}
- }
-
public bool Equals(Project project){
+ if (project == null)
+ return false;
+ else
return this.File.FilePath.Equals(project.File.FilePath);
}
diff --git a/LongoMatch/DB/Sections.cs b/LongoMatch/DB/Sections.cs
index 9b0fc46..7a94b69 100644
--- a/LongoMatch/DB/Sections.cs
+++ b/LongoMatch/DB/Sections.cs
@@ -39,6 +39,10 @@ namespace LongoMatch.DB
this.sectionsList = new List<SectionsTimeNode>();
}
+ public void Clear(){
+ sectionsList.Clear();
+ }
+
public void AddSection(SectionsTimeNode tn){
sectionsList.Add(tn);
}
diff --git a/LongoMatch/DB/TeamTemplate.cs b/LongoMatch/DB/TeamTemplate.cs
index b54f91d..ff6c0ed 100644
--- a/LongoMatch/DB/TeamTemplate.cs
+++ b/LongoMatch/DB/TeamTemplate.cs
@@ -27,7 +27,7 @@ namespace LongoMatch.DB
{
[Serializable]
- public class TeamTemplate
+ public class TeamTemplate
{
private List<Player> playersList;
@@ -39,6 +39,10 @@ namespace LongoMatch.DB
}
+ public void Clear(){
+ playersList.Clear();
+ }
+
public int PlayersCount{
get {return playersList.Count;}
}
diff --git a/LongoMatch/Gui/Component/ButtonsWidget.cs b/LongoMatch/Gui/Component/ButtonsWidget.cs
index 1f9a8ed..db64295 100644
--- a/LongoMatch/Gui/Component/ButtonsWidget.cs
+++ b/LongoMatch/Gui/Component/ButtonsWidget.cs
@@ -43,13 +43,15 @@ namespace LongoMatch.Gui.Component
public Sections Sections{
set{
- this.sections = value;
- int sectionsCount = value.Count;
-
foreach (Widget w in table1.AllChildren){
- w.Unrealize();
table1.Remove(w);
- }
+ w.Destroy();
+ }
+ sections = value;
+ if (value == null)
+ return;
+
+ int sectionsCount = value.Count;
table1.NColumns =(uint) 10;
table1.NRows =(uint) (sectionsCount/10);
@@ -77,7 +79,6 @@ namespace LongoMatch.Gui.Component
}
}
}
-
protected virtual void OnButtonClicked(object sender, System.EventArgs e)
{
diff --git a/LongoMatch/Gui/Component/PlayersListTreeWidget.cs b/LongoMatch/Gui/Component/PlayersListTreeWidget.cs
index fd8e905..813ef4b 100644
--- a/LongoMatch/Gui/Component/PlayersListTreeWidget.cs
+++ b/LongoMatch/Gui/Component/PlayersListTreeWidget.cs
@@ -95,6 +95,11 @@ namespace LongoMatch.Gui.Component
set{playerstreeview.PlayListLoaded=value;}
}
+ public void Clear(){
+ playerstreeview.Model = null;
+ template = null;
+ }
+
protected virtual void OnTimeNodeSelected(MediaTimeNode tNode){
if (TimeNodeSelected != null)
TimeNodeSelected(tNode);
diff --git a/LongoMatch/Gui/Component/PlaysListTreeWidget.cs b/LongoMatch/Gui/Component/PlaysListTreeWidget.cs
index 3403349..05e252a 100644
--- a/LongoMatch/Gui/Component/PlaysListTreeWidget.cs
+++ b/LongoMatch/Gui/Component/PlaysListTreeWidget.cs
@@ -85,10 +85,16 @@ namespace LongoMatch.Gui.Component
public Project Project{
- set{
+ set{
project = value;
- treeview.Model = project.GetModel();
- treeview.Colors = project.Sections.GetColors();
+ if (project != null){
+ treeview.Model = project.GetModel();
+ treeview.Colors = project.Sections.GetColors();
+ }
+ else{
+ treeview.Model = null;
+ treeview.Colors = null;
+ }
}
}
diff --git a/LongoMatch/Gui/Component/ProjectDetailsWidget.cs b/LongoMatch/Gui/Component/ProjectDetailsWidget.cs
index b74e8e7..1aa3032 100644
--- a/LongoMatch/Gui/Component/ProjectDetailsWidget.cs
+++ b/LongoMatch/Gui/Component/ProjectDetailsWidget.cs
@@ -56,8 +56,7 @@ namespace LongoMatch.Gui.Component
private UseType useType;
public ProjectDetailsWidget()
- {
-
+ {
this.Build();
//HACK:The calendar dialog does not respond on win32
@@ -195,8 +194,7 @@ namespace LongoMatch.Gui.Component
project.Season = seasonentry.Text;
project.Sections = Sections;
project.LocalTeamTemplate = LocalTeamTemplate;
- project.VisitorTeamTemplate = VisitorTeamTemplate;
-
+ project.VisitorTeamTemplate = VisitorTeamTemplate;
}
public Project GetProject(){
@@ -224,16 +222,15 @@ namespace LongoMatch.Gui.Component
}
public void Clear(){
- this.LocalName = "";
- this.VisitorName = "";
- this.LocalGoals = 0;
- this.VisitorGoals = 0;
- this.Date = System.DateTime.Today;
- this.Filename = "";
- this.mFile = null;
- }
-
-
+ LocalName = "";
+ VisitorName = "";
+ LocalGoals = 0;
+ VisitorGoals = 0;
+ Date = System.DateTime.Today;
+ Filename = "";
+ mFile = null;
+ edited = false;
+ }
private void FillSections(){
string[] allFiles;
diff --git a/LongoMatch/Gui/Component/ProjectListWidget.cs b/LongoMatch/Gui/Component/ProjectListWidget.cs
index f831566..2a234ca 100644
--- a/LongoMatch/Gui/Component/ProjectListWidget.cs
+++ b/LongoMatch/Gui/Component/ProjectListWidget.cs
@@ -19,7 +19,7 @@
//
using System;
-using System.Collections;
+using System.Collections.Generic;
using System.IO;
using Mono.Unix;
using Gtk;
@@ -31,7 +31,7 @@ using LongoMatch.DB;
namespace LongoMatch.Gui.Component
{
- public delegate void ProjectSelectedHandler (Project project);
+ public delegate void ProjectSelectedHandler (ProjectDescription project);
[System.ComponentModel.Category("LongoMatch")]
[System.ComponentModel.ToolboxItem(true)]
@@ -69,81 +69,75 @@ namespace LongoMatch.Gui.Component
private void RenderPixbuf (Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
{
- Project project = (Project) model.GetValue (iter, 0);
- (cell as Gtk.CellRendererPixbuf).Pixbuf= project.File.Preview;
+ ProjectDescription project = (ProjectDescription) model.GetValue (iter, 0);
+ (cell as Gtk.CellRendererPixbuf).Pixbuf= project.Preview;
}
private void RenderName (Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
{
- Project _project = (Project) model.GetValue (iter, 0);
- string _filePath = _project.File.FilePath;
- string text;
+ ProjectDescription project = (ProjectDescription) model.GetValue (iter, 0);
+ string text;
-
- text = Catalog.GetString("<b>File:</b> ") + System.IO.Path.GetFileName(_filePath.ToString());
- text = text +"\n"+Catalog.GetString("<b>Local Team:</b> ") + _project.LocalName;
- text = text +"\n"+Catalog.GetString("<b>Visitor Team:</b> ") + _project.VisitorName;
- text = text +"\n"+Catalog.GetString("<b>Season:</b> ") + _project.Season;
- text = text +"\n"+Catalog.GetString("<b>Competition:</b> ") + _project.Competition;
- text = text +"\n"+Catalog.GetString("<b>Result:</b> ") + _project.LocalGoals+"-"+_project.VisitorGoals;
- text = text +"\n"+Catalog.GetString("<b>Date:</b> ") + _project.MatchDate.ToShortDateString();
+ text = Catalog.GetString("<b>Title:</b> ") + project.Title;
+ text = text +"\n"+Catalog.GetString("<b>Local Team:</b> ") + project.LocalName;
+ text = text +"\n"+Catalog.GetString("<b>Visitor Team:</b> ") + project.VisitorName;
+ text = text +"\n"+Catalog.GetString("<b>Season:</b> ") + project.Season;
+ text = text +"\n"+Catalog.GetString("<b>Competition:</b> ") + project.Competition;
+ text = text +"\n"+Catalog.GetString("<b>Result:</b> ") + project.LocalGoals+"-"+ project.VisitorGoals;
+ text = text +"\n"+Catalog.GetString("<b>Date:</b> ") + project.MatchDate.ToShortDateString();
(cell as Gtk.CellRendererText).Markup = text;
}
- public void Fill(ArrayList db){
+ public void Fill(List<ProjectDescription> projectsList){
projectsListStore.Clear();
- db.Sort();
-
- foreach (Project _project in db){
- projectsListStore.AppendValues(_project);
+ projectsList.Sort();
+ foreach (ProjectDescription project in projectsList){
+ projectsListStore.AppendValues(project);
}
}
- public Project GetSelection(){
+ public ProjectDescription GetSelection(){
TreePath path;
TreeViewColumn col;
treeview.GetCursor(out path,out col);
- return this.GetProject(path);
-
+ return this.GetProject(path);
}
public void ClearSearch(){
filterEntry.Text="";
}
- private Project GetProject(TreePath path){
+ private ProjectDescription GetProject(TreePath path){
if (path != null){
Gtk.TreeIter iter;
filter.GetIter (out iter, path);
- Project project = (Project) filter.GetValue (iter, 0);
+ ProjectDescription project = (ProjectDescription) filter.GetValue (iter, 0);
return project;
}
else return null;
}
-
protected virtual void OnTreeviewCursorChanged (object sender, System.EventArgs e)
{
TreeIter iter;
this.treeview.Selection.GetSelected(out iter);
- Project selectedProject = (Project) filter.GetValue (iter, 0);
+ ProjectDescription selectedProject = (ProjectDescription) filter.GetValue (iter, 0);
if (ProjectSelectedEvent!=null)
ProjectSelectedEvent(selectedProject);
}
protected virtual void OnFilterentryChanged (object sender, System.EventArgs e)
{
- filter.Refilter ();
-
+ filter.Refilter ();
}
private bool FilterTree (Gtk.TreeModel model, Gtk.TreeIter iter)
{
- Project project =(Project) model.GetValue (iter, 0);
+ ProjectDescription project =(ProjectDescription) model.GetValue (iter, 0);
if (project == null)
return true;
-
+
if (filterEntry.Text == "")
return true;
@@ -159,10 +153,6 @@ namespace LongoMatch.Gui.Component
return true;
else
return false;
- }
-
-
-
-
+ }
}
}
diff --git a/LongoMatch/Gui/Component/TimeLineWidget.cs b/LongoMatch/Gui/Component/TimeLineWidget.cs
index 8e3f9ac..a867362 100644
--- a/LongoMatch/Gui/Component/TimeLineWidget.cs
+++ b/LongoMatch/Gui/Component/TimeLineWidget.cs
@@ -122,16 +122,19 @@ namespace LongoMatch.Gui.Component {
public Project Project{
set{
+ ResetGui();
+
+ if (value == null){
+ sections = null;
+ tnArray = null;
+ tsArray=null;
+ return;
+ }
+
sections = value.Sections;
tnArray = value.GetDataArray();
- tsArray = new TimeScale[sections.Count];
-
- //Unrealize all children
- foreach (Widget w in vbox1.AllChildren){
- w.Unrealize();
- vbox1.Remove(w);
- }
-
+ tsArray = new TimeScale[sections.Count];
+
frames = value.File.GetFrames();
ushort fps = value.File.Fps;
@@ -149,8 +152,15 @@ namespace LongoMatch.Gui.Component {
ts.Show();
}
SetPixelRatio(3);
- }
-
+ }
+ }
+
+ private void ResetGui(){
+ //Unrealize all children
+ foreach (Widget w in vbox1.AllChildren){
+ vbox1.Remove(w);
+ w.Destroy();
+ }
}
protected virtual void OnNewMark(int section, int frame){
diff --git a/LongoMatch/Gui/Dialog/OpenProjectDialog.cs b/LongoMatch/Gui/Dialog/OpenProjectDialog.cs
index d7d0584..72afdb5 100644
--- a/LongoMatch/Gui/Dialog/OpenProjectDialog.cs
+++ b/LongoMatch/Gui/Dialog/OpenProjectDialog.cs
@@ -29,30 +29,19 @@ namespace LongoMatch.Gui.Dialog
[System.ComponentModel.ToolboxItem(false)]
public partial class OpenProjectDialog : Gtk.Dialog
{
-
-
public OpenProjectDialog()
{
this.Build();
- this.Fill();
-
- }
-
+ this.Fill();
+ }
- public Project GetSelection(){
+ public ProjectDescription GetSelection(){
return projectlistwidget.GetSelection();
}
public void Fill(){
- projectlistwidget.Fill(MainClass.DB.GetAllDB());
- }
-
- protected virtual void OnFiledatalistwidgetProjectSelectedEvent (Project project)
- {
- this.buttonOk.Activate();
+ projectlistwidget.Fill(MainClass.DB.GetAllProjects());
}
-
-
}
-}
+}
\ No newline at end of file
diff --git a/LongoMatch/Gui/Dialog/ProjectsManager.cs b/LongoMatch/Gui/Dialog/ProjectsManager.cs
index bab85f6..67df837 100644
--- a/LongoMatch/Gui/Dialog/ProjectsManager.cs
+++ b/LongoMatch/Gui/Dialog/ProjectsManager.cs
@@ -19,7 +19,7 @@
//
using System;
-using System.Collections;
+using System.Collections.Generic;
using Gtk;
using Mono.Unix;
using LongoMatch.DB;
@@ -33,9 +33,9 @@ namespace LongoMatch.Gui.Dialog
public partial class ProjectsManager : Gtk.Dialog
{
- public bool edited;
- public string originalFilePath;
-
+ private bool edited;
+ private string originalFilePath;
+
public ProjectsManager()
{
this.Build();
@@ -45,8 +45,8 @@ namespace LongoMatch.Gui.Dialog
}
public void Fill(){
- ArrayList allDB = MainClass.DB.GetAllDB();
- projectlistwidget1.Fill(allDB);
+ List<ProjectDescription> projectsList = MainClass.DB.GetAllProjects();
+ projectlistwidget1.Fill(projectsList);
projectlistwidget1.ClearSearch();
projectdetails.Clear();
projectdetails.Sensitive = false;
@@ -81,32 +81,34 @@ namespace LongoMatch.Gui.Dialog
protected virtual void OnDeleteButtonPressed (object sender, System.EventArgs e)
{
- Project selectedProject = projectlistwidget1.GetSelection();
+ ProjectDescription selectedProject = projectlistwidget1.GetSelection();
if (selectedProject != null){
- if (MainWindow.OpenedProject()!= null && selectedProject.Equals(MainWindow.OpenedProject())) {
-
+ if (MainWindow.OpenedProject() != null &&selectedProject.File == MainWindow.OpenedProject().File.FilePath) {
MessagePopup.PopupMessage(this, MessageType.Warning,
- Catalog.GetString("This Project is actually in use.")+"\n"+Catalog.GetString("Close it first to allow its removal from the database"));
+ Catalog.GetString("This Project is actually in use.")+"\n"+
+ Catalog.GetString("Close it first to allow its removal from the database"));
}
else {
- MessageDialog md = new MessageDialog(this,DialogFlags.Modal,MessageType.Question,ButtonsType.YesNo,
- Catalog.GetString("Do yo really want to delete:")+"\n"+selectedProject.File.FilePath);
+ MessageDialog md = new MessageDialog(this,DialogFlags.Modal,
+ MessageType.Question,
+ ButtonsType.YesNo,
+ Catalog.GetString("Do yo really want to delete:")+
+ "\n"+selectedProject.File);
if (md.Run()== (int)ResponseType.Yes){
projectdetails.Clear();
- MainClass.DB.RemoveProject(selectedProject);
+ MainClass.DB.RemoveProject(selectedProject.File);
Fill();
}
md.Destroy();
}
}
- }
-
+ }
protected virtual void OnSaveButtonPressed (object sender, System.EventArgs e)
{
SaveProject();
projectdetails.Edited=false;
- }
+ }
protected virtual void OnButtonOkClicked (object sender, System.EventArgs e)
@@ -114,7 +116,7 @@ namespace LongoMatch.Gui.Dialog
this.Destroy();
}
- protected virtual void OnProjectlistwidget1ProjectSelectedEvent (LongoMatch.DB.Project project)
+ protected virtual void OnProjectlistwidget1ProjectSelectedEvent (ProjectDescription project)
{
if (projectdetails.Edited){
MessageDialog md = new MessageDialog((Window)this.Toplevel,DialogFlags.Modal,
@@ -126,7 +128,7 @@ namespace LongoMatch.Gui.Dialog
}
md.Destroy();
}
- if (MainWindow.OpenedProject()!= null && project.Equals(MainWindow.OpenedProject())) {
+ if (MainWindow.OpenedProject() != null && project.File == MainWindow.OpenedProject().File.FilePath) {
MessagePopup.PopupMessage(this, MessageType.Warning,
Catalog.GetString("The Project you are trying to load is actually in use.")+"\n" +Catalog.GetString ("Close it first to edit it"));
@@ -137,8 +139,8 @@ namespace LongoMatch.Gui.Dialog
}
else{
projectdetails.Sensitive = true;
- projectdetails.SetProject(project);
- originalFilePath = project.File.FilePath;
+ projectdetails.SetProject(MainClass.DB.GetProject(project.File));
+ originalFilePath = project.File;
saveButton.Sensitive = false;
deleteButton.Sensitive = true;
}
diff --git a/LongoMatch/Gui/MainWindow.cs b/LongoMatch/Gui/MainWindow.cs
index 5bd73d7..e631da7 100644
--- a/LongoMatch/Gui/MainWindow.cs
+++ b/LongoMatch/Gui/MainWindow.cs
@@ -129,7 +129,7 @@ namespace LongoMatch.Gui
}
MakeActionsSensitive(true);
ShowWidgets();
- hkManager.SetSections(project.Sections);
+ hkManager.Sections=project.Sections;
KeyPressEvent += hotkeysListener;
}
catch (GLib.GException ex){
@@ -143,16 +143,20 @@ namespace LongoMatch.Gui
private void CloseActualProyect(){
Title = "LongoMatch";
+ ClearWidgets();
HideWidgets();
playerbin1.Close();
playerbin1.LogoMode = true;
- SaveDB();
- openedProject = null;
- eManager.OpenedProject = null;
+ SaveDB();
+ if (openedProject != null){
+ openedProject.Clear();
+ openedProject = null;
+ eManager.OpenedProject = null;
+ }
selectedTimeNode = null;
MakeActionsSensitive(false);
- KeyPressEvent -= hotkeysListener;
-
+ hkManager.Sections = null;
+ KeyPressEvent -= hotkeysListener;
}
private void MakeActionsSensitive(bool sensitive){
@@ -174,11 +178,18 @@ namespace LongoMatch.Gui
private void HideWidgets(){
leftbox.Hide();
+ rightvbox.Hide();
buttonswidget1.Hide();
timelinewidget1.Hide();
}
-
+ private void ClearWidgets(){
+ buttonswidget1.Sections = null;
+ treewidget1.Project = null;
+ timelinewidget1.Project = null;
+ localplayerslisttreewidget.Clear();
+ visitorplayerslisttreewidget.Clear();
+ }
private void SaveDB(){
if (openedProject != null){
@@ -220,21 +231,15 @@ namespace LongoMatch.Gui
protected virtual void OnOpenActivated (object sender, System.EventArgs e)
{
- Project project;
+ ProjectDescription project=null;
OpenProjectDialog opd = new OpenProjectDialog();
opd.TransientFor = this;
- int answer=opd.Run();
- while (answer == (int)ResponseType.Reject){
- project = opd.GetSelection();
- MainClass.DB.RemoveProject(project);
- opd.Fill();
- answer=opd.Run();
- }
- if (answer == (int)ResponseType.Ok){
+
+ if (opd.Run() == (int)ResponseType.Ok)
project = opd.GetSelection();
- SetProject(project);
- }
opd.Destroy();
+ if (project != null)
+ SetProject(MainClass.DB.GetProject(project.File));
}
protected virtual void OnNewActivated (object sender, System.EventArgs e)
@@ -271,8 +276,6 @@ namespace LongoMatch.Gui
protected virtual void OnCloseActivated (object sender, System.EventArgs e)
{
-
- SaveDB();
CloseActualProyect();
}
@@ -295,13 +298,10 @@ namespace LongoMatch.Gui
SaveDB();
// We never know...
System.Threading.Thread.Sleep(1000);
- playerbin1.Dispose();
-
- Application.Quit();
-
+ playerbin1.Dispose();
+ Application.Quit();
}
-
protected virtual void OnQuitActivated (object sender, System.EventArgs e)
{
playlistwidget2.StopEdition();
@@ -357,9 +357,6 @@ namespace LongoMatch.Gui
CloseActualProyect();
}
-
-
-
protected virtual void OnCaptureModeActionToggled (object sender, System.EventArgs e)
{
if (((Gtk.ToggleAction)sender).Active){
@@ -386,25 +383,10 @@ namespace LongoMatch.Gui
{
if (openedProject != null && evnt.State == ModifierType.None){
Gdk.Key key = evnt.Key;
- if (key == Gdk.Key.z){
- if (selectedTimeNode == null)
- playerbin1.SeekToPreviousFrame(false);
- else
- playerbin1.SeekToPreviousFrame(true);
- }
- if (key == Gdk.Key.x){
- if (selectedTimeNode == null)
- playerbin1.SeekToNextFrame(false);
- else
- playerbin1.SeekToNextFrame(true);
- }
- if (key == Gdk.Key.q){
- playerbin1.LogoMode=true;
- }
- if (key == Gdk.Key.r){
- playerbin1.LogoMode=false;
- }
-
+ if (key == Gdk.Key.z)
+ playerbin1.SeekToPreviousFrame(selectedTimeNode != null);
+ if (key == Gdk.Key.x)
+ playerbin1.SeekToNextFrame(selectedTimeNode != null);
}
return base.OnKeyPressEvent (evnt);
}
@@ -425,8 +407,7 @@ namespace LongoMatch.Gui
updater.Fill(version, URL);
updater.TransientFor = this;
updater.Run();
- updater.Destroy();
-
+ updater.Destroy();
}
protected virtual void OnDrawingToolActionToggled (object sender, System.EventArgs e)
@@ -492,7 +473,6 @@ GNU General Public License for more details.";
protected override bool OnConfigureEvent (Gdk.EventConfigure evnt)
{
- //playerbin1.RedrawLastFrame();
return base.OnConfigureEvent (evnt);
}
diff --git a/LongoMatch/Handlers/HotKeysManager.cs b/LongoMatch/Handlers/HotKeysManager.cs
index 4c2e70a..bbacb77 100644
--- a/LongoMatch/Handlers/HotKeysManager.cs
+++ b/LongoMatch/Handlers/HotKeysManager.cs
@@ -39,16 +39,18 @@ namespace LongoMatch.Handlers
dic = new Dictionary<HotKey,int>();
}
- public void SetSections(Sections sections){
- dic.Clear();
- for (int i=0;i<sections.Count;i++){
- if (sections.GetHotKey(i).Defined)
- if (!dic.ContainsKey(sections.GetHotKey(i)))
- dic.Add(sections.GetHotKey(i),i);
+ public Sections Sections{
+ set{
+ dic.Clear();
+ if (value == null)
+ return;
+ for (int i=0;i<value.Count;i++){
+ if (value.GetHotKey(i).Defined &&
+ !dic.ContainsKey(value.GetHotKey(i)))
+ dic.Add(value.GetHotKey(i),i);
+ }
}
-
- }
-
+ }
public void KeyListener(object sender, KeyPressEventArgs args){
if ((args.Event.State & (ModifierType.Mod1Mask | ModifierType.Mod5Mask | ModifierType.ShiftMask)) != 0){
diff --git a/LongoMatch/LongoMatch.mdp b/LongoMatch/LongoMatch.mdp
index 4433ad3..9cd4e3f 100644
--- a/LongoMatch/LongoMatch.mdp
+++ b/LongoMatch/LongoMatch.mdp
@@ -162,6 +162,7 @@
<File name="Time/Drawing.cs" subtype="Code" buildaction="Compile" />
<File name="Handlers/VideoDrawingsManager.cs" subtype="Code" buildaction="Compile" />
<File name="Time/DrawingsList.cs" subtype="Code" buildaction="Compile" />
+ <File name="DB/ProjectDescription.cs" subtype="Code" buildaction="Compile" />
</Contents>
<References>
<ProjectReference type="Gac" localcopy="True" refto="Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
diff --git a/LongoMatch/Main.cs b/LongoMatch/Main.cs
index 211f9ef..8bf9815 100644
--- a/LongoMatch/Main.cs
+++ b/LongoMatch/Main.cs
@@ -192,7 +192,7 @@ namespace LongoMatch
}
//No config file exists, use default
catch {
- //Vista permissions doesn't not allow to use the 'etc' dir
+ //Vista permissions doesn't allow to use the 'etc' dir
//in the installation path. Use the default homeDirectory
//and let the user change it by hand
configDirectory=homeDirectory;
@@ -204,7 +204,8 @@ namespace LongoMatch
}
private static void ProcessExecutionError(Exception ex){
- if (MainWindow.OpenedProject() != null)
+ //Try to save the database before exiting
+ if (MainWindow.OpenedProject() != null)
DB.UpdateProject(MainWindow.OpenedProject());
string logFile ="LongoMatch-" + DateTime.Now +".log";
string message;
@@ -215,12 +216,14 @@ namespace LongoMatch
logFile = System.IO.Path.Combine(HomeDir(),logFile);
if (ex.InnerException != null)
- message = String.Format("{0}\n{1}\n{2}\n{3}",ex.Message,ex.Source,ex.StackTrace,ex.InnerException.StackTrace);
+ message = String.Format("{0}\n{1}\n{2}\n{3}\n{4}",ex.Message,ex.InnerException.Message,ex.Source,ex.StackTrace,ex.InnerException.StackTrace);
else
message = String.Format("{0}\n{1}\n{2}",ex.Message,ex.Source,ex.StackTrace);
using (StreamWriter s = new StreamWriter(logFile)){
s.WriteLine(message);
+ s.WriteLine("\n\n\nStackTrace:");
+ s.WriteLine(System.Environment.StackTrace);
}
//TODO Add bug reports link
MessagePopup.PopupMessage(null, MessageType.Error,
diff --git a/LongoMatch/Makefile.am b/LongoMatch/Makefile.am
index ab04f57..05d87f6 100644
--- a/LongoMatch/Makefile.am
+++ b/LongoMatch/Makefile.am
@@ -93,6 +93,7 @@ FILES = \
Compat/0.0/Time/TimeNode.cs \
DB/DataBase.cs \
DB/Project.cs \
+ DB/ProjectDescription.cs\
DB/Sections.cs \
DB/Tag.cs \
DB/TagsTemplate.cs \
diff --git a/LongoMatch/gtk-gui/LongoMatch.Gui.Dialog.OpenProjectDialog.cs b/LongoMatch/gtk-gui/LongoMatch.Gui.Dialog.OpenProjectDialog.cs
index 7b3b920..c67f295 100644
--- a/LongoMatch/gtk-gui/LongoMatch.Gui.Dialog.OpenProjectDialog.cs
+++ b/LongoMatch/gtk-gui/LongoMatch.Gui.Dialog.OpenProjectDialog.cs
@@ -67,7 +67,7 @@ namespace LongoMatch.Gui.Dialog {
this.buttonOk.Name = "buttonOk";
this.buttonOk.UseStock = true;
this.buttonOk.UseUnderline = true;
- this.buttonOk.Label = "gtk-ok";
+ this.buttonOk.Label = "gtk-open";
this.AddActionWidget(this.buttonOk, -5);
Gtk.ButtonBox.ButtonBoxChild w5 = ((Gtk.ButtonBox.ButtonBoxChild)(w3[this.buttonOk]));
w5.Position = 1;
@@ -79,7 +79,6 @@ namespace LongoMatch.Gui.Dialog {
this.DefaultWidth = 615;
this.DefaultHeight = 359;
this.Show();
- this.projectlistwidget.ProjectSelectedEvent += new LongoMatch.Gui.Component.ProjectSelectedHandler(this.OnFiledatalistwidgetProjectSelectedEvent);
}
}
}
diff --git a/LongoMatch/gtk-gui/LongoMatch.Gui.MainWindow.cs b/LongoMatch/gtk-gui/LongoMatch.Gui.MainWindow.cs
index 20f09b4..a553030 100644
--- a/LongoMatch/gtk-gui/LongoMatch.Gui.MainWindow.cs
+++ b/LongoMatch/gtk-gui/LongoMatch.Gui.MainWindow.cs
@@ -214,7 +214,7 @@ namespace LongoMatch.Gui {
this.hpaned = new Gtk.HPaned();
this.hpaned.CanFocus = true;
this.hpaned.Name = "hpaned";
- this.hpaned.Position = 295;
+ this.hpaned.Position = 299;
// Container child hpaned.Gtk.Paned+PanedChild
this.leftbox = new Gtk.VBox();
this.leftbox.Name = "leftbox";
@@ -223,7 +223,7 @@ namespace LongoMatch.Gui {
this.notebook1 = new Gtk.Notebook();
this.notebook1.CanFocus = true;
this.notebook1.Name = "notebook1";
- this.notebook1.CurrentPage = 2;
+ this.notebook1.CurrentPage = 0;
this.notebook1.TabPos = ((Gtk.PositionType)(3));
// Container child notebook1.Gtk.Notebook+NotebookChild
this.treewidget1 = new LongoMatch.Gui.Component.PlaysListTreeWidget();
@@ -272,7 +272,7 @@ namespace LongoMatch.Gui {
this.hpaned1 = new Gtk.HPaned();
this.hpaned1.CanFocus = true;
this.hpaned1.Name = "hpaned1";
- this.hpaned1.Position = 795;
+ this.hpaned1.Position = 789;
// Container child hpaned1.Gtk.Paned+PanedChild
this.vbox5 = new Gtk.VBox();
this.vbox5.Name = "vbox5";
diff --git a/LongoMatch/gtk-gui/gui.stetic b/LongoMatch/gtk-gui/gui.stetic
index 8701b21..7a00643 100644
--- a/LongoMatch/gtk-gui/gui.stetic
+++ b/LongoMatch/gtk-gui/gui.stetic
@@ -1080,7 +1080,6 @@
<widget class="LongoMatch.Gui.Component.ProjectListWidget" id="projectlistwidget">
<property name="MemberName">projectlistwidget</property>
<property name="Events">ButtonPressMask</property>
- <signal name="ProjectSelectedEvent" handler="OnFiledatalistwidgetProjectSelectedEvent" />
</widget>
<packing>
<property name="Position">0</property>
@@ -1119,9 +1118,9 @@
<property name="CanFocus">True</property>
<property name="UseStock">True</property>
<property name="Type">StockItem</property>
- <property name="StockId">gtk-ok</property>
+ <property name="StockId">gtk-open</property>
<property name="ResponseId">-5</property>
- <property name="label">gtk-ok</property>
+ <property name="label">gtk-open</property>
</widget>
<packing>
<property name="Position">1</property>
@@ -1656,7 +1655,7 @@
<widget class="Gtk.HPaned" id="hpaned">
<property name="MemberName" />
<property name="CanFocus">True</property>
- <property name="Position">295</property>
+ <property name="Position">299</property>
<child>
<widget class="Gtk.VBox" id="leftbox">
<property name="MemberName" />
@@ -1666,7 +1665,7 @@
<widget class="Gtk.Notebook" id="notebook1">
<property name="MemberName" />
<property name="CanFocus">True</property>
- <property name="CurrentPage">2</property>
+ <property name="CurrentPage">0</property>
<property name="TabPos">Bottom</property>
<child>
<widget class="LongoMatch.Gui.Component.PlaysListTreeWidget" id="treewidget1">
@@ -1735,7 +1734,7 @@
<widget class="Gtk.HPaned" id="hpaned1">
<property name="MemberName" />
<property name="CanFocus">True</property>
- <property name="Position">795</property>
+ <property name="Position">789</property>
<child>
<widget class="Gtk.VBox" id="vbox5">
<property name="MemberName" />
diff --git a/LongoMatch/gtk-gui/objects.xml b/LongoMatch/gtk-gui/objects.xml
index 138059b..e013c10 100644
--- a/LongoMatch/gtk-gui/objects.xml
+++ b/LongoMatch/gtk-gui/objects.xml
@@ -103,14 +103,6 @@
</itemgroup>
</signals>
</object>
- <object type="LongoMatch.Gui.Component.ProjectListWidget" palette-category="LongoMatch" allow-children="false" base-type="Gtk.Bin">
- <itemgroups />
- <signals>
- <itemgroup label="ProjectListWidget Signals">
- <signal name="ProjectSelectedEvent" />
- </itemgroup>
- </signals>
- </object>
<object type="LongoMatch.Gui.Component.CategoriesTreeView" palette-category="LongoMatch" allow-children="false" base-type="Gtk.TreeView">
<itemgroups />
<signals>
@@ -243,4 +235,12 @@
<itemgroups />
<signals />
</object>
+ <object type="LongoMatch.Gui.Component.ProjectListWidget" palette-category="LongoMatch" allow-children="false" base-type="Gtk.Bin">
+ <itemgroups />
+ <signals>
+ <itemgroup label="ProjectListWidget Signals">
+ <signal name="ProjectSelectedEvent" />
+ </itemgroup>
+ </signals>
+ </object>
</objects>
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]