Merge lp://staging/keryx/unstable into lp://staging/~jacseen/keryx/unstable

Proposed by mac9416
Status: Merged
Merged at revision: not available
Proposed branch: lp://staging/keryx/unstable
Merge into: lp://staging/~jacseen/keryx/unstable
Diff against target: 1287 lines (+734/-414)
7 files modified
doc/README (+1/-1)
doc/StatusMerge.py (+268/-0)
lib/plugins.py (+1/-1)
lib/project.py (+1/-1)
lib/wxkeryx/main.py (+457/-407)
lib/wxkeryx/misc.py (+1/-1)
plugins/Debian.py (+5/-3)
To merge this branch: bzr merge lp://staging/keryx/unstable
Reviewer Review Type Date Requested Status
Keryx Admins Pending
Review via email: mp+15355@code.staging.launchpad.net
To post a comment you must log in.
Revision history for this message
mac9416 (mac9416) wrote :

Merging back into your branch to get everything synchronized. I made you a pretty good Install Project dialog, but haven't finished it off, so I just left the current ones in place and commented out the line for testing the new one.

Revision history for this message
Jack N (jacseen) wrote :

I'll merge it into my branch.
Just a note, a lot of lines are being flagged as 'changed' due to only a <space> having been added to the end. Is your editor doing this automatically?
One way to catch these before a commit, is to review the work with 'bzr diff'.

I'll clean the lines as I merge :)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'doc/README'
2--- doc/README 2009-08-09 19:36:06 +0000
3+++ doc/README 2009-12-16 01:34:10 +0000
4@@ -96,7 +96,7 @@
5
6 Buran Ayuthia
7 John Gleissner
8-Mac Crenshaw
9+mac9416
10 Kevin Buente
11 Douglass Clem
12 Cory Thompson
13
14=== added file 'doc/StatusMerge.py'
15--- doc/StatusMerge.py 1970-01-01 00:00:00 +0000
16+++ doc/StatusMerge.py 2009-12-16 01:34:10 +0000
17@@ -0,0 +1,268 @@
18+#!/usr/bin/env python
19+# -*- coding: utf-8 -*-
20+#
21+# Author: mac9416
22+#
23+# This program is free software; you can redistribute it and/or modify
24+# it under the terms of the GNU General Public License as published by
25+# the Free Software Foundation; either version 2 of the License, or
26+# (at your option) any later version.
27+#
28+# This program is distributed in the hope that it will be useful,
29+# but WITHOUT ANY WARRANTY; without even the implied warranty of
30+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31+# GNU Library General Public License for more details.
32+#
33+# You should have received a copy of the GNU General Public License
34+# along with this program; if not, write to the Free Software
35+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
36+
37+import os
38+import sys
39+
40+def compare(status1, status2, older=True):
41+ """Takes two status file strings and returns only packages in both (chosing
42+ the older version of the two by default)
43+ """
44+ # Make each string a dict of package names : package entries
45+ status = []
46+ status2 = dict([[get_property(x, 'Package'), x] for x in status2.split('\n\n')])
47+
48+ for entry in status1.split('\n\n'):
49+ if entry.strip() == '': continue # Empty strings. Who needs them.
50+ pkg_name = get_property(entry, 'Package')
51+ if pkg_name in status2.keys():
52+ ver1 = get_property(entry, 'Version')
53+ ver2 = get_property(status2[pkg_name], 'Version')
54+ if DpkgVersion(ver1) < DpkgVersion(ver2) or DpkgVersion(ver1) == DpkgVersion(ver2):
55+ status.append(entry)
56+ elif DpkgVersion(ver1) > DpkgVersion(ver2):
57+ status.append(status2[pkg_name])
58+
59+ return '\n\n'.join(status)
60+
61+def get_property(pkg_str, prop):
62+ """Takes a status file package entry and package property; returns value for
63+ that property
64+ """
65+ for line in pkg_str.split('\n'):
66+ if line.startswith(prop):
67+ return line.split(':')[-1].strip()
68+
69+
70+############ Minideblib's Version Compare Code ############
71+
72+
73+# -*- coding: UTF-8 -*-
74+# Small changes by Steve Kowalik, GPL (C) 2005
75+# Scott James Remnant told me the license is MIT
76+"""Parse and compare Debian version strings.
77+
78+This module contains a class designed to sit in your Python code pretty
79+naturally and represent a Debian version string. It implements various
80+special methods to make dealing with them sweet.
81+"""
82+
83+__author__ = "Scott James Remnant <scott@netsplit.com>"
84+
85+
86+import re
87+
88+
89+# Regular expressions make validating things easy
90+valid_epoch = re.compile(r'^[0-9]+$')
91+valid_upstream = re.compile(r'^[0-9][A-Za-z0-9+:.~-]*$')
92+valid_revision = re.compile(r'^[A-Za-z0-9+.~]+$')
93+
94+# Character comparison table for upstream and revision components
95+cmp_table = "~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-.:"
96+
97+
98+class VersionError(Exception): pass
99+class BadInputError(VersionError): pass
100+class BadEpochError(BadInputError): pass
101+class BadUpstreamError(BadInputError): pass
102+class BadRevisionError(BadInputError): pass
103+
104+class DpkgVersion(object):
105+ """
106+ Debian version number.
107+
108+ This class is designed to be reasonably transparent and allow you to write code like:
109+
110+ >>> s.version >= '1.100-1'
111+
112+ The comparison will be done according to Debian rules, so '1.2' will compare lower.
113+
114+ Properties:
115+ - epoch: Epoch
116+ - upstream: Upstream version
117+ - revision: Debian/local revision
118+ """
119+
120+ def __init__(self, ver):
121+ """Parse a string or number into the three components."""
122+ self.epoch = None
123+ self.upstream = None
124+ self.revision = None
125+
126+ ver = str(ver)
127+ if not len(ver):
128+ raise BadInputError, "Input cannot be empty"
129+
130+ # Epoch is component before first colon
131+ idx = ver.find(":")
132+ if idx != -1:
133+ self.epoch = ver[:idx]
134+ if not len(self.epoch):
135+ raise BadEpochError, "Epoch cannot be empty"
136+ if not valid_epoch.search(self.epoch):
137+ raise BadEpochError, "Bad epoch format"
138+ ver = ver[idx+1:]
139+
140+ # Revision is component after last hyphen
141+ idx = ver.rfind("-")
142+ if idx != -1:
143+ self.revision = ver[idx+1:]
144+ if not len(self.revision):
145+ raise BadRevisionError, "Revision cannot be empty"
146+ if not valid_revision.search(self.revision):
147+ raise BadRevisionError, "Bad revision format"
148+ ver = ver[:idx]
149+
150+ # Remaining component is upstream
151+ self.upstream = ver
152+ if not len(self.upstream):
153+ raise BadUpstreamError, "Upstream version cannot be empty"
154+ if not valid_upstream.search(self.upstream):
155+ raise BadUpstreamError, "Bad upstream version format"
156+
157+ if self.epoch is not None:
158+ self.epoch = int(self.epoch)
159+
160+ def getWithoutEpoch(self):
161+ """Return the version without the epoch."""
162+ str = self.upstream
163+ if self.revision is not None:
164+ str += "-%s" % (self.revision,)
165+ return str
166+
167+ without_epoch = property(getWithoutEpoch)
168+
169+ def __str__(self):
170+ """Return the class as a string for printing."""
171+ str = ""
172+ if self.epoch is not None:
173+ str += "%d:" % (self.epoch,)
174+ str += self.upstream
175+ if self.revision is not None:
176+ str += "-%s" % (self.revision,)
177+ return str
178+
179+ def __repr__(self):
180+ """Return a debugging representation of the object."""
181+ return "<%s epoch: %r, upstream: %r, revision: %r>" \
182+ % (self.__class__.__name__, self.epoch,
183+ self.upstream, self.revision)
184+
185+ def __cmp__(self, other):
186+ """Compare two Version classes."""
187+ other = DpkgVersion(other)
188+
189+ # Compare epochs only if they are not equal.
190+ if self.epoch != other.epoch:
191+ # Special cases for braindead packages
192+ sepoch = self.epoch
193+ oepoch = other.epoch
194+ if sepoch is None:
195+ sepoch = 0
196+ if oepoch is None:
197+ oepoch = 0
198+ result = cmp(sepoch, oepoch)
199+ if result != 0: return result
200+
201+ result = deb_cmp(self.upstream, other.upstream)
202+ if result != 0: return result
203+
204+ result = deb_cmp(self.revision or "", other.revision or "")
205+ if result != 0: return result
206+
207+ return 0
208+
209+ def is_native(self):
210+ native = False
211+ if not self.revision:
212+ native = True
213+ return native
214+
215+def strcut(str, idx, accept):
216+ """Cut characters from str that are entirely in accept."""
217+ ret = ""
218+ while idx < len(str) and str[idx] in accept:
219+ ret += str[idx]
220+ idx += 1
221+
222+ return (ret, idx)
223+
224+def deb_order(str, idx):
225+ """Return the comparison order of two characters."""
226+ if idx >= len(str):
227+ return 0
228+ elif str[idx] == "~":
229+ return -1
230+ else:
231+ return cmp_table.index(str[idx])
232+
233+def deb_cmp_str(x, y):
234+ """Compare two strings in a deb version."""
235+ idx = 0
236+ while (idx < len(x)) or (idx < len(y)):
237+ result = deb_order(x, idx) - deb_order(y, idx)
238+ if result < 0:
239+ return -1
240+ elif result > 0:
241+ return 1
242+
243+ idx += 1
244+
245+ return 0
246+
247+def deb_cmp(x, y):
248+ """Implement the string comparison outlined by Debian policy."""
249+ x_idx = y_idx = 0
250+ while x_idx < len(x) or y_idx < len(y):
251+ # Compare strings
252+ (x_str, x_idx) = strcut(x, x_idx, cmp_table)
253+ (y_str, y_idx) = strcut(y, y_idx, cmp_table)
254+ result = deb_cmp_str(x_str, y_str)
255+ if result != 0: return result
256+
257+ # Compare numbers
258+ (x_str, x_idx) = strcut(x, x_idx, "0123456789")
259+ (y_str, y_idx) = strcut(y, y_idx, "0123456789")
260+ result = cmp(int(x_str or "0"), int(y_str or "0"))
261+ if result != 0: return result
262+
263+ return 0
264+
265+############ End Minideblib's Version Compare Code ############
266+
267+
268+if __name__ == '__main__':
269+ # Open the status files and put the strings in a list.
270+ status_list = []
271+ for status in sys.argv[1:]:
272+ try:
273+ # Assume the full directory is given.
274+ status_list.append(open(status, 'rb').read())
275+ except IOError:
276+ # Then again, maybe it's in the current directory.
277+ status_list.append(open(os.path.join(os.getcwd(), status), 'rb').read())
278+
279+ status1 = status_list.pop(0)
280+
281+ for status2 in status_list:
282+ status1 = compare(status1, status2)
283+ print len(status1)
284+
285+ open(os.path.join(os.getcwd(), 'StatusMerge_out'), 'wb').write(status1)
286
287=== modified file 'lib/plugins.py'
288--- lib/plugins.py 2009-11-18 03:56:58 +0000
289+++ lib/plugins.py 2009-12-16 01:34:10 +0000
290@@ -23,7 +23,7 @@
291 app = None
292 fail = False
293
294-class pluginBase:
295+class pluginBase(object):
296 """ Used to make sure plugins have necessary functions """
297 def __init__(self): pass
298 def IsOS(self): pass
299
300=== modified file 'lib/project.py'
301--- lib/project.py 2009-02-13 02:35:55 +0000
302+++ lib/project.py 2009-12-16 01:34:10 +0000
303@@ -25,7 +25,7 @@
304 # List of currently opened projects
305 projects = []
306
307-class Project():
308+class Project(object):
309 """
310 Stores project information and common tasks
311 """
312
313=== modified file 'lib/wxkeryx/main.py'
314--- lib/wxkeryx/main.py 2009-12-13 08:17:50 +0000
315+++ lib/wxkeryx/main.py 2009-12-16 01:34:10 +0000
316@@ -1,355 +1,357 @@
317-# -*- coding: utf-8 -*-
318-#
319-# Author: Chris Oliver (excid3@gmail.com)
320-#
321-# This program is free software; you can redistribute it and/or modify
322-# it under the terms of the GNU General Public License as published by
323-# the Free Software Foundation; either version 2 of the License, or
324-# (at your option) any later version.
325-#
326-# This program is distributed in the hope that it will be useful,
327-# but WITHOUT ANY WARRANTY; without even the implied warranty of
328-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
329-# GNU Library General Public License for more details.
330-#
331-# You should have received a copy of the GNU General Public License
332-# along with this program; if not, write to the Free Software
333-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
334-
335-import os.path, lib, sys, wx
336-import wx.lib.buttons as buttons
337-from lib import consts, log, plugins, project
338-from startDialog import startDialog
339-from misc import detailsTab, ProportionalSplitter, VirtualList
340-from options import optionDialog
341-from delayedresult import thread
342-from download import download
343-from editor import FileEditor
344-
345-class MainApp(wx.Frame):
346- def __init__(self, *args, **kwds):
347- kwds["style"] = wx.DEFAULT_FRAME_STYLE
348- wx.Frame.__init__(self, *args, **kwds)
349- self.splitter = ProportionalSplitter(self)#, style=wx.SP_3D|wx.SP_BORDER)
350- self.panel = wx.Panel(self.splitter)
351- self.notebook = wx.Notebook(self.panel, -1, style=wx.NB_BOTTOM)
352- self.project_notebook_pane = wx.Panel(self.notebook, -1, style=wx.TAB_TRAVERSAL)
353- self.SetIcon(wx.Icon(consts.fileIco, wx.BITMAP_TYPE_ICO))
354- self.statusbar = self.CreateStatusBar(1, 0)
355-
356- # Side Buttons
357- self.buttonPanel = wx.Panel(self)
358- self.downloadButton = buttons.GenBitmapTextButton(self.buttonPanel, -1, wx.Bitmap(consts.icon_download), _("Download"))#, size=(95, 25))
359- self.updatesButton = buttons.GenBitmapTextButton(self.buttonPanel, -1, wx.Bitmap(consts.icon_updates), _("Get Updates"))#, size=(95, 25))
360- self.refreshButton = buttons.GenBitmapTextButton(self.buttonPanel, -1, wx.Bitmap(consts.icon_refresh), _("Refresh"))#, size=(95, 25))
361- #self.updateStatusButton = buttons.GenBitmapTextButton(self.buttonPanel, -1, wx.Bitmap(consts.icon_refresh), _("Update Status"))#, size=(95, 25))
362-
363- self.notebook_il = wx.ImageList(16, 16)
364- self.notebook_il.Add(wx.Bitmap(consts.icon_project_details))
365- self.notebook.SetImageList(self.notebook_il)
366-
367- self.projectDetails = wx.TextCtrl(self.project_notebook_pane, style = wx.TE_MULTILINE | wx.TE_RICH |wx.TE_READONLY)
368- self.details = detailsTab(self.notebook)
369-
370- # Create list view
371- self.list = VirtualList(self.splitter, self.details)
372-
373- # Create Popup menu for self.list
374- self.__popup_menu()
375- self.__create_menu()
376- self.__set_properties()
377- self.__do_layout()
378- self.__bind_events()
379-
380- plugins.load(consts.dirPlugins, self)
381- for name, instance, type, ver in plugins.InterfacePluginList: instance.start()
382-
383- if len(plugins.OSPluginList) < 1:
384- wx.MessageBox(_("No OS plugins were loaded. Make sure you have OS plugins in ") +
385- consts.dirPlugins + ". " + _("Check the log for more details."))
386- sys.exit(1)
387-
388- def __popup_menu(self):
389- self.popupmenu = wx.Menu()
390- #FIXME: popup menu items cannot display bitmap properly?
391- item = self.popupmenu.Append(-1, _("Download"))
392- self.Bind(wx.EVT_MENU, self.OnDownload, item)
393- item = self.popupmenu.Append(-1, _("View Details"))
394- self.Bind(wx.EVT_MENU, self.OnDetails, item)
395- self.list.Bind(wx.EVT_CONTEXT_MENU, self.OnShowPopup)
396-
397- def __create_menu(self):
398- # Menu Bar
399- self.menubar = wx.MenuBar()
400- self.fileFile = wx.Menu()
401- self.fileClose = wx.MenuItem(self.fileFile, wx.NewId(), _("&Close Project...\tCtrl+X"), _("Closes the current project"), wx.ITEM_NORMAL)
402- self.fileClose.SetBitmap(wx.Bitmap(consts.icon_close))
403- self.fileFile.AppendItem(self.fileClose)
404- self.fileFile.AppendSeparator()
405- self.fileQuit = wx.MenuItem(self.fileFile, wx.NewId(), _("&Quit\tCtrl+Q"), _("Quit this application"), wx.ITEM_NORMAL)
406- self.fileQuit.SetBitmap(wx.Bitmap(consts.icon_quit))
407- self.fileFile.AppendItem(self.fileQuit)
408- self.menubar.Append(self.fileFile, _("&File"))
409-
410- tmp_menu = wx.Menu()
411- self.editOptions = wx.MenuItem(tmp_menu, wx.NewId(), _("&Options...\tCtrl+O"), _("Open options dialog"), wx.ITEM_NORMAL)
412- self.editOptions.SetBitmap(wx.Bitmap(consts.icon_options))
413- tmp_menu.AppendItem(self.editOptions)
414- self.menubar.Append(tmp_menu, _("&Edit"))
415-
416- tmp_menu = wx.Menu()
417- self.projRefresh = wx.MenuItem(tmp_menu, wx.NewId(), _("&Refresh\tCtrl+R"), _("Refresh package list"), wx.ITEM_NORMAL)
418- self.projRefresh.SetBitmap(wx.Bitmap(consts.icon_refresh))
419- tmp_menu.AppendItem(self.projRefresh)
420- tmp_menu.AppendSeparator()
421- self.projUpdates = wx.MenuItem(tmp_menu, wx.NewId(), _("Get &Updates\tCtrl+U"), _("Grabs all packages that have updates"), wx.ITEM_NORMAL)
422- self.projUpdates.SetBitmap(wx.Bitmap(consts.icon_updates))
423- tmp_menu.AppendItem(self.projUpdates)
424- self.projDownload = wx.MenuItem(tmp_menu, wx.NewId(), _("&Download Package\tCtrl+D"), _("Downloads selected package"), wx.ITEM_NORMAL)
425- self.projDownload.SetBitmap(wx.Bitmap(consts.icon_download))
426- tmp_menu.AppendItem(self.projDownload)
427- self.projInstall = wx.MenuItem(tmp_menu, wx.NewId(), _("&Install Project..."), _("Helps you install packages onto Project Machine"), wx.ITEM_NORMAL)
428- self.projInstall.SetBitmap(wx.Bitmap(consts.icon_install))
429- tmp_menu.AppendItem(self.projInstall)
430- self.projUpdateStatus = wx.MenuItem(tmp_menu, wx.NewId(), _("&Update Status"), _("Regrabs the list of installed packages"), wx.ITEM_NORMAL)
431- self.projUpdateStatus.SetBitmap(wx.Bitmap(consts.icon_refresh))
432- tmp_menu.AppendItem(self.projUpdateStatus)
433- tmp_menu.AppendSeparator()
434- self.projDetails = wx.MenuItem(tmp_menu, wx.NewId(), _("&View Details\tCtrl+V"), _("Shows details of selected package"), wx.ITEM_NORMAL)
435- self.projDetails.SetBitmap(wx.Bitmap(consts.icon_package))
436- tmp_menu.AppendItem(self.projDetails)
437- tmp_menu.AppendSeparator()
438- self.projSources = wx.MenuItem(tmp_menu, wx.NewId(), _("&Edit Sources...\tCtrl+E"), _("Edit project sources"), wx.ITEM_NORMAL)
439- self.projSources.SetBitmap(wx.Bitmap(consts.icon_sources))
440- tmp_menu.AppendItem(self.projSources)
441-
442- self.menubar.Append(tmp_menu, _("&Project"))
443-
444- tmp_menu = wx.Menu()
445- self.helpHomepage = wx.MenuItem(tmp_menu, wx.NewId(), _("&Homepage"), _("Visit the website"), wx.ITEM_NORMAL)
446- self.helpHomepage.SetBitmap(wx.Bitmap(consts.icon_home))
447- tmp_menu.AppendItem(self.helpHomepage)
448- self.helpOnline = wx.MenuItem(tmp_menu, wx.NewId(), _("&Get Help Online"), _("Visit the forums"), wx.ITEM_NORMAL)
449- self.helpOnline.SetBitmap(wx.Bitmap(consts.icon_help))
450- tmp_menu.AppendItem(self.helpOnline)
451- self.helpTranslate = wx.MenuItem(tmp_menu, wx.NewId(), _("&Translate This Application"), _("Help translate to other languages"), wx.ITEM_NORMAL)
452- self.helpTranslate.SetBitmap(wx.Bitmap(consts.icon_translate))
453- tmp_menu.AppendItem(self.helpTranslate)
454- self.helpReport = wx.MenuItem(tmp_menu, wx.NewId(), _("R&eport A Problem"), _("Report a bug"), wx.ITEM_NORMAL)
455- self.helpReport.SetBitmap(wx.Bitmap(consts.icon_bug_report))
456- tmp_menu.AppendItem(self.helpReport)
457- tmp_menu.AppendSeparator()
458- self.helpDonate = wx.MenuItem(tmp_menu, wx.NewId(), _("&Donate"), _("Make a donation"), wx.ITEM_NORMAL)
459- self.helpDonate.SetBitmap(wx.Bitmap(consts.icon_donate))
460- tmp_menu.AppendItem(self.helpDonate)
461- tmp_menu.AppendSeparator()
462- self.helpAbout = wx.MenuItem(tmp_menu, wx.NewId(), _("&About..."), _("About " + consts.appName), wx.ITEM_NORMAL)
463- self.helpAbout.SetBitmap(wx.Bitmap(consts.icon_about))
464- tmp_menu.AppendItem(self.helpAbout)
465- self.menubar.Append(tmp_menu, _("&Help"))
466- self.SetMenuBar(self.menubar)
467- # Menu Bar end
468-
469- def __bind_events(self):
470- self.Bind(wx.EVT_MENU, self.OnClose, self.fileClose)
471- self.Bind(wx.EVT_MENU, self.OnQuit, self.fileQuit)
472- self.Bind(wx.EVT_MENU, self.OnOptions, self.editOptions)
473- self.Bind(wx.EVT_MENU, self.OnHomepage, self.helpHomepage)
474- self.Bind(wx.EVT_MENU, self.OnHelpOnline, self.helpOnline)
475- self.Bind(wx.EVT_MENU, self.OnTranslate, self.helpTranslate)
476- self.Bind(wx.EVT_MENU, self.OnReport, self.helpReport)
477- self.Bind(wx.EVT_MENU, self.OnDonate, self.helpDonate)
478- self.Bind(wx.EVT_MENU, self.OnAbout, self.helpAbout)
479-
480- self.Bind(wx.EVT_MENU, self.OnRefresh, self.projRefresh)
481- self.Bind(wx.EVT_MENU, self.OnUpdates, self.projUpdates)
482- self.Bind(wx.EVT_MENU, self.OnDownload, self.projDownload)
483- self.Bind(wx.EVT_MENU, self.OnInstall, self.projInstall)
484- self.Bind(wx.EVT_MENU, self.OnUpdateStatus, self.projUpdateStatus)
485- self.Bind(wx.EVT_MENU, self.OnDetails, self.projDetails)
486- self.Bind(wx.EVT_MENU, self.OnSources, self.projSources)
487-
488- self.Bind(wx.EVT_BUTTON, self.OnDownload, self.downloadButton)
489- self.Bind(wx.EVT_BUTTON, self.OnRefresh, self.refreshButton)
490- #self.Bind(wx.EVT_BUTTON, self.OnUpdateStatus, self.updateStatusButton)
491- self.Bind(wx.EVT_BUTTON, self.OnUpdates, self.updatesButton)
492- self.Bind(wx.EVT_CLOSE, self.Closing)
493-
494- def __set_properties(self):
495- self.SetSize((700, 500))
496- self.statusbar.SetStatusWidths([-1])
497- # statusbar fields
498- statusbar_fields = [_("Ready")]
499- for i in range(len(statusbar_fields)):
500- self.statusbar.SetStatusText(statusbar_fields[i], i)
501-
502- attr = wx.TextAttr()
503- attr.SetTabs([400])
504- self.projectDetails.SetDefaultStyle(attr)
505-
506- def __do_layout(self):
507- sizer = wx.BoxSizer(wx.VERTICAL)
508- sizer_bottom = wx.BoxSizer(wx.HORIZONTAL)
509- sizer_buttons = wx.BoxSizer(wx.HORIZONTAL)
510- sizer_buttons.Add(self.downloadButton, 0, wx.ALL, 3)
511- sizer_buttons.Add(self.updatesButton, 0, wx.ALL, 3)
512- sizer_buttons.Add(self.refreshButton, 0, wx.ALL, 3)
513- #sizer_buttons.Add(self.updateStatusButton, 0, wx.ALL, 3)
514- #sizer_bottom.Add(sizer_buttons, 0, wx.ALIGN_CENTER_VERTICAL, 0)
515- self.buttonPanel.SetSizer(sizer_buttons)
516-
517- sizer_project = wx.BoxSizer(wx.VERTICAL)
518- sizer_project.Add(self.projectDetails, 1, wx.EXPAND, 0)
519- self.project_notebook_pane.SetSizer(sizer_project)
520- self.notebook.InsertPage(0, self.project_notebook_pane, _("Project Details"), False, 0)
521- sizer_bottom.Add(self.notebook, 1, wx.EXPAND, 0)
522- self.panel.SetSizer(sizer_bottom)
523- self.notebook.SetSelection(0)
524-
525- self.splitter.SplitHorizontally(self.list, self.panel)
526- sizer.Add(self.buttonPanel, 0, wx.EXPAND, 0)
527- sizer.Add(self.splitter, 1, wx.EXPAND, 0)
528- self.SetSizer(sizer)
529- self.Layout()
530- self.Centre()
531-
532- def OnShowPopup(self, evt):
533- pos = evt.GetPosition()
534- pos = self.ScreenToClient(pos)
535- self.PopupMenu(self.popupmenu, pos)
536-
537- def Closing(self, event): # Cleanup cleanup, everybody do your share
538- #self.thread.StopThreads()
539- #self.thread.Destroy()
540- log.info(_('Cleaning up plugins'))
541- for name, instance, type, version in plugins.InterfacePluginList: instance.cleanup()
542- log.info(_('Shutting down'))
543- self.Destroy()
544-
545- def OnClose(self, event):
546- self.list.DeleteAllItems()
547- self.projectDetails.Clear()
548- self.list.tabpage.SetPackage()
549- start = startDialog(None, -1, '')
550- success = start.ShowModal()
551- start.Destroy()
552-
553- if success == wx.ID_CANCEL:
554- self.Close()
555- else:
556- self.Refresh(project.projects[len(project.projects) - 1].GetData())
557-
558- def OnQuit(self, event): self.Close()
559- def OnHomepage(self, event): lib.browserOpen(consts.urlHomepage)
560- def OnHelpOnline(self, event): lib.browserOpen(consts.urlHelp)
561- def OnTranslate(self, event): lib.browserOpen(consts.urlTranslate)
562- def OnReport(self, event): lib.browserOpen(consts.urlBug)
563- def OnDonate(self, event): lib.browserOpen(consts.urlDonate)
564- def OnAbout(self, event):
565- info = wx.AboutDialogInfo()
566-
567- info.SetIcon(wx.Icon(consts.fileLogo, wx.BITMAP_TYPE_PNG))
568- info.SetName(consts.appName)
569- info.SetVersion(consts.appVersion)
570- info.SetDescription(consts.description)
571- info.SetCopyright(consts.copyright)
572- info.SetWebSite(consts.urlHomepage)
573- info.SetLicence(consts.license)
574- info.AddDeveloper(consts.authors)
575- info.AddDocWriter(consts.docwriters)
576- info.AddArtist(consts.artists)
577- info.AddTranslator(consts.translators)
578-
579- wx.AboutBox(info)
580-
581- def OnSources(self, event):
582- proj = project.projects[len(project.projects) - 1]
583- name = proj.getSources() + _(' - Sources Editor')
584- edit = FileEditor(name, proj.getSources())
585- if edit.ShowModal() == wx.ID_OK:
586- edit.txt.SaveFile(proj.getSources())
587- if wx.MessageBox(_("Sources have changed. Would you like to reload the package list?"), _("Save Successful"), wx.YES_NO) == 2: #wx.ID_YES:
588- self.OnRefresh(None)
589- edit.Destroy()
590-
591- def OnOptions(self, event):
592- options = optionDialog(None, -1, '')
593- if options.ShowModal() == wx.ID_OK:
594- # Set settings
595- consts.proxy_enabled = options.proxyCheckBox.GetValue()
596- conf = open(consts.file_config, 'w')
597- conf.write('LogDir=' + options.logCtrl.GetValue() + '\n' +
598- #'LocaleDir=' + options.localeCtrl.GetValue() + '\n' +
599- #'PackagesDir=' + options.packagesCtrl.GetValue() + '\n' +
600- 'PluginsDir=' + options.pluginsCtrl.GetValue() + '\n' +
601- 'ProjectsDir=' + options.projectsCtrl.GetValue() + '\n' +
602- 'PixmapsDir=' + options.pixmapsCtrl.GetValue() + '\n' +
603- 'ThemesDir=' + options.themesCtrl.GetValue() + '\n' +
604- 'DefaultTheme=' + options.defaultThemeCtrl.GetValue() + '\n' +
605- 'CurrentTheme=' + options.defaultThemeCtrl.GetValue() + '\n')
606-
607+# -*- coding: utf-8 -*-
608+#
609+# Author: Chris Oliver (excid3@gmail.com)
610+#
611+# This program is free software; you can redistribute it and/or modify
612+# it under the terms of the GNU General Public License as published by
613+# the Free Software Foundation; either version 2 of the License, or
614+# (at your option) any later version.
615+#
616+# This program is distributed in the hope that it will be useful,
617+# but WITHOUT ANY WARRANTY; without even the implied warranty of
618+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
619+# GNU Library General Public License for more details.
620+#
621+# You should have received a copy of the GNU General Public License
622+# along with this program; if not, write to the Free Software
623+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
624+
625+import os.path, lib, sys, wx
626+import wx.lib.buttons as buttons
627+from lib import consts, log, plugins, project
628+from startDialog import startDialog
629+from misc import detailsTab, ProportionalSplitter, VirtualList
630+from options import optionDialog
631+from delayedresult import thread
632+from download import download
633+from editor import FileEditor
634+
635+class MainApp(wx.Frame):
636+ def __init__(self, *args, **kwds):
637+ kwds["style"] = wx.DEFAULT_FRAME_STYLE
638+ wx.Frame.__init__(self, *args, **kwds)
639+ self.splitter = ProportionalSplitter(self)#, style=wx.SP_3D|wx.SP_BORDER)
640+ self.panel = wx.Panel(self.splitter)
641+ self.notebook = wx.Notebook(self.panel, -1, style=wx.NB_BOTTOM)
642+ self.project_notebook_pane = wx.Panel(self.notebook, -1, style=wx.TAB_TRAVERSAL)
643+ self.SetIcon(wx.Icon(consts.fileIco, wx.BITMAP_TYPE_ICO))
644+ self.statusbar = self.CreateStatusBar(1, 0)
645+
646+ # Side Buttons
647+ self.buttonPanel = wx.Panel(self)
648+ self.downloadButton = buttons.GenBitmapTextButton(self.buttonPanel, -1, wx.Bitmap(consts.icon_download), _("Download"))#, size=(95, 25))
649+ self.updatesButton = buttons.GenBitmapTextButton(self.buttonPanel, -1, wx.Bitmap(consts.icon_updates), _("Get Updates"))#, size=(95, 25))
650+ self.refreshButton = buttons.GenBitmapTextButton(self.buttonPanel, -1, wx.Bitmap(consts.icon_refresh), _("Refresh"))#, size=(95, 25))
651+ #self.updateStatusButton = buttons.GenBitmapTextButton(self.buttonPanel, -1, wx.Bitmap(consts.icon_refresh), _("Update Status"))#, size=(95, 25))
652+
653+ self.notebook_il = wx.ImageList(16, 16)
654+ self.notebook_il.Add(wx.Bitmap(consts.icon_project_details))
655+ self.notebook.SetImageList(self.notebook_il)
656+
657+ self.projectDetails = wx.TextCtrl(self.project_notebook_pane, style = wx.TE_MULTILINE | wx.TE_RICH |wx.TE_READONLY)
658+ self.details = detailsTab(self.notebook)
659+
660+ # Create list view
661+ self.list = VirtualList(self.splitter, self.details)
662+
663+ # Create Popup menu for self.list
664+ self.__popup_menu()
665+ self.__create_menu()
666+ self.__set_properties()
667+ self.__do_layout()
668+ self.__bind_events()
669+
670+ plugins.load(consts.dirPlugins, self)
671+ for name, instance, type, ver in plugins.InterfacePluginList: instance.start()
672+
673+ if len(plugins.OSPluginList) < 1:
674+ wx.MessageBox(_("No OS plugins were loaded. Make sure you have OS plugins in ") +
675+ consts.dirPlugins + ". " + _("Check the log for more details."))
676+ sys.exit(1)
677+
678+ def __popup_menu(self):
679+ self.popupmenu = wx.Menu()
680+ #FIXME: popup menu items cannot display bitmap properly?
681+ item = self.popupmenu.Append(-1, _("Download"))
682+ self.Bind(wx.EVT_MENU, self.OnDownload, item)
683+ item = self.popupmenu.Append(-1, _("View Details"))
684+ self.Bind(wx.EVT_MENU, self.OnDetails, item)
685+ self.list.Bind(wx.EVT_CONTEXT_MENU, self.OnShowPopup)
686+
687+ def __create_menu(self):
688+ # Menu Bar
689+ self.menubar = wx.MenuBar()
690+ self.fileFile = wx.Menu()
691+ self.fileClose = wx.MenuItem(self.fileFile, wx.NewId(), _("&Close Project...\tCtrl+X"), _("Closes the current project"), wx.ITEM_NORMAL)
692+ self.fileClose.SetBitmap(wx.Bitmap(consts.icon_close))
693+ self.fileFile.AppendItem(self.fileClose)
694+ self.fileFile.AppendSeparator()
695+ self.fileQuit = wx.MenuItem(self.fileFile, wx.NewId(), _("&Quit\tCtrl+Q"), _("Quit this application"), wx.ITEM_NORMAL)
696+ self.fileQuit.SetBitmap(wx.Bitmap(consts.icon_quit))
697+ self.fileFile.AppendItem(self.fileQuit)
698+ self.menubar.Append(self.fileFile, _("&File"))
699+
700+ tmp_menu = wx.Menu()
701+ self.editOptions = wx.MenuItem(tmp_menu, wx.NewId(), _("&Options...\tCtrl+O"), _("Open options dialog"), wx.ITEM_NORMAL)
702+ self.editOptions.SetBitmap(wx.Bitmap(consts.icon_options))
703+ tmp_menu.AppendItem(self.editOptions)
704+ self.menubar.Append(tmp_menu, _("&Edit"))
705+
706+ tmp_menu = wx.Menu()
707+ self.projRefresh = wx.MenuItem(tmp_menu, wx.NewId(), _("&Refresh\tCtrl+R"), _("Refresh package list"), wx.ITEM_NORMAL)
708+ self.projRefresh.SetBitmap(wx.Bitmap(consts.icon_refresh))
709+ tmp_menu.AppendItem(self.projRefresh)
710+ tmp_menu.AppendSeparator()
711+ self.projUpdates = wx.MenuItem(tmp_menu, wx.NewId(), _("Get &Updates\tCtrl+U"), _("Grabs all packages that have updates"), wx.ITEM_NORMAL)
712+ self.projUpdates.SetBitmap(wx.Bitmap(consts.icon_updates))
713+ tmp_menu.AppendItem(self.projUpdates)
714+ self.projDownload = wx.MenuItem(tmp_menu, wx.NewId(), _("&Download Package\tCtrl+D"), _("Downloads selected package"), wx.ITEM_NORMAL)
715+ self.projDownload.SetBitmap(wx.Bitmap(consts.icon_download))
716+ tmp_menu.AppendItem(self.projDownload)
717+ self.projInstall = wx.MenuItem(tmp_menu, wx.NewId(), _("&Install Project..."), _("Helps you install packages onto Project Machine"), wx.ITEM_NORMAL)
718+ self.projInstall.SetBitmap(wx.Bitmap(consts.icon_install))
719+ tmp_menu.AppendItem(self.projInstall)
720+ self.projUpdateStatus = wx.MenuItem(tmp_menu, wx.NewId(), _("&Update Status"), _("Regrabs the list of installed packages"), wx.ITEM_NORMAL)
721+ self.projUpdateStatus.SetBitmap(wx.Bitmap(consts.icon_refresh))
722+ tmp_menu.AppendItem(self.projUpdateStatus)
723+ tmp_menu.AppendSeparator()
724+ self.projDetails = wx.MenuItem(tmp_menu, wx.NewId(), _("&View Details\tCtrl+V"), _("Shows details of selected package"), wx.ITEM_NORMAL)
725+ self.projDetails.SetBitmap(wx.Bitmap(consts.icon_package))
726+ tmp_menu.AppendItem(self.projDetails)
727+ tmp_menu.AppendSeparator()
728+ self.projSources = wx.MenuItem(tmp_menu, wx.NewId(), _("&Edit Sources...\tCtrl+E"), _("Edit project sources"), wx.ITEM_NORMAL)
729+ self.projSources.SetBitmap(wx.Bitmap(consts.icon_sources))
730+ tmp_menu.AppendItem(self.projSources)
731+
732+ self.menubar.Append(tmp_menu, _("&Project"))
733+
734+ tmp_menu = wx.Menu()
735+ self.helpHomepage = wx.MenuItem(tmp_menu, wx.NewId(), _("&Homepage"), _("Visit the website"), wx.ITEM_NORMAL)
736+ self.helpHomepage.SetBitmap(wx.Bitmap(consts.icon_home))
737+ tmp_menu.AppendItem(self.helpHomepage)
738+ self.helpOnline = wx.MenuItem(tmp_menu, wx.NewId(), _("&Get Help Online"), _("Visit the forums"), wx.ITEM_NORMAL)
739+ self.helpOnline.SetBitmap(wx.Bitmap(consts.icon_help))
740+ tmp_menu.AppendItem(self.helpOnline)
741+ self.helpTranslate = wx.MenuItem(tmp_menu, wx.NewId(), _("&Translate This Application"), _("Help translate to other languages"), wx.ITEM_NORMAL)
742+ self.helpTranslate.SetBitmap(wx.Bitmap(consts.icon_translate))
743+ tmp_menu.AppendItem(self.helpTranslate)
744+ self.helpReport = wx.MenuItem(tmp_menu, wx.NewId(), _("R&eport A Problem"), _("Report a bug"), wx.ITEM_NORMAL)
745+ self.helpReport.SetBitmap(wx.Bitmap(consts.icon_bug_report))
746+ tmp_menu.AppendItem(self.helpReport)
747+ tmp_menu.AppendSeparator()
748+ self.helpDonate = wx.MenuItem(tmp_menu, wx.NewId(), _("&Donate"), _("Make a donation"), wx.ITEM_NORMAL)
749+ self.helpDonate.SetBitmap(wx.Bitmap(consts.icon_donate))
750+ tmp_menu.AppendItem(self.helpDonate)
751+ tmp_menu.AppendSeparator()
752+ self.helpAbout = wx.MenuItem(tmp_menu, wx.NewId(), _("&About..."), _("About " + consts.appName), wx.ITEM_NORMAL)
753+ self.helpAbout.SetBitmap(wx.Bitmap(consts.icon_about))
754+ tmp_menu.AppendItem(self.helpAbout)
755+ self.menubar.Append(tmp_menu, _("&Help"))
756+ self.SetMenuBar(self.menubar)
757+ # Menu Bar end
758+
759+ def __bind_events(self):
760+ self.Bind(wx.EVT_MENU, self.OnClose, self.fileClose)
761+ self.Bind(wx.EVT_MENU, self.OnQuit, self.fileQuit)
762+ self.Bind(wx.EVT_MENU, self.OnOptions, self.editOptions)
763+ self.Bind(wx.EVT_MENU, self.OnHomepage, self.helpHomepage)
764+ self.Bind(wx.EVT_MENU, self.OnHelpOnline, self.helpOnline)
765+ self.Bind(wx.EVT_MENU, self.OnTranslate, self.helpTranslate)
766+ self.Bind(wx.EVT_MENU, self.OnReport, self.helpReport)
767+ self.Bind(wx.EVT_MENU, self.OnDonate, self.helpDonate)
768+ self.Bind(wx.EVT_MENU, self.OnAbout, self.helpAbout)
769+
770+ self.Bind(wx.EVT_MENU, self.OnRefresh, self.projRefresh)
771+ self.Bind(wx.EVT_MENU, self.OnUpdates, self.projUpdates)
772+ self.Bind(wx.EVT_MENU, self.OnDownload, self.projDownload)
773+ self.Bind(wx.EVT_MENU, self.OnInstall, self.projInstall)
774+ self.Bind(wx.EVT_MENU, self.OnUpdateStatus, self.projUpdateStatus)
775+ self.Bind(wx.EVT_MENU, self.OnDetails, self.projDetails)
776+ self.Bind(wx.EVT_MENU, self.OnSources, self.projSources)
777+
778+ self.Bind(wx.EVT_BUTTON, self.OnDownload, self.downloadButton)
779+ self.Bind(wx.EVT_BUTTON, self.OnRefresh, self.refreshButton)
780+ #self.Bind(wx.EVT_BUTTON, self.OnUpdateStatus, self.updateStatusButton)
781+ self.Bind(wx.EVT_BUTTON, self.OnUpdates, self.updatesButton)
782+ self.Bind(wx.EVT_CLOSE, self.Closing)
783+
784+ def __set_properties(self):
785+ self.SetSize((700, 500))
786+ self.statusbar.SetStatusWidths([-1])
787+ # statusbar fields
788+ statusbar_fields = [_("Ready")]
789+ for i in range(len(statusbar_fields)):
790+ self.statusbar.SetStatusText(statusbar_fields[i], i)
791+
792+ attr = wx.TextAttr()
793+ attr.SetTabs([400])
794+ self.projectDetails.SetDefaultStyle(attr)
795+
796+ def __do_layout(self):
797+ sizer = wx.BoxSizer(wx.VERTICAL)
798+ sizer_bottom = wx.BoxSizer(wx.HORIZONTAL)
799+ sizer_buttons = wx.BoxSizer(wx.HORIZONTAL)
800+ sizer_buttons.Add(self.downloadButton, 0, wx.ALL, 3)
801+ sizer_buttons.Add(self.updatesButton, 0, wx.ALL, 3)
802+ sizer_buttons.Add(self.refreshButton, 0, wx.ALL, 3)
803+ #sizer_buttons.Add(self.updateStatusButton, 0, wx.ALL, 3)
804+ #sizer_bottom.Add(sizer_buttons, 0, wx.ALIGN_CENTER_VERTICAL, 0)
805+ self.buttonPanel.SetSizer(sizer_buttons)
806+
807+ sizer_project = wx.BoxSizer(wx.VERTICAL)
808+ sizer_project.Add(self.projectDetails, 1, wx.EXPAND, 0)
809+ self.project_notebook_pane.SetSizer(sizer_project)
810+ self.notebook.InsertPage(0, self.project_notebook_pane, _("Project Details"), False, 0)
811+ sizer_bottom.Add(self.notebook, 1, wx.EXPAND, 0)
812+ self.panel.SetSizer(sizer_bottom)
813+ self.notebook.SetSelection(0)
814+
815+ self.splitter.SplitHorizontally(self.list, self.panel)
816+ sizer.Add(self.buttonPanel, 0, wx.EXPAND, 0)
817+ sizer.Add(self.splitter, 1, wx.EXPAND, 0)
818+ self.SetSizer(sizer)
819+ self.Layout()
820+ self.Centre()
821+
822+ def OnShowPopup(self, evt):
823+ pos = evt.GetPosition()
824+ pos = self.ScreenToClient(pos)
825+ self.PopupMenu(self.popupmenu, pos)
826+
827+ def Closing(self, event): # Cleanup cleanup, everybody do your share
828+ #self.thread.StopThreads()
829+ #self.thread.Destroy()
830+ log.info(_('Cleaning up plugins'))
831+ for name, instance, type, version in plugins.InterfacePluginList: instance.cleanup()
832+ log.info(_('Shutting down'))
833+ self.Destroy()
834+
835+ def OnClose(self, event):
836+ self.list.DeleteAllItems()
837+ self.projectDetails.Clear()
838+ self.list.tabpage.SetPackage()
839+ start = startDialog(None, -1, '')
840+ success = start.ShowModal()
841+ start.Destroy()
842+
843+ if success == wx.ID_CANCEL:
844+ self.Close()
845+ else:
846+ self.Refresh(project.projects[len(project.projects) - 1].GetData())
847+
848+ def OnQuit(self, event): self.Close()
849+ def OnHomepage(self, event): lib.browserOpen(consts.urlHomepage)
850+ def OnHelpOnline(self, event): lib.browserOpen(consts.urlHelp)
851+ def OnTranslate(self, event): lib.browserOpen(consts.urlTranslate)
852+ def OnReport(self, event): lib.browserOpen(consts.urlBug)
853+ def OnDonate(self, event): lib.browserOpen(consts.urlDonate)
854+ def OnAbout(self, event):
855+ info = wx.AboutDialogInfo()
856+
857+ info.SetIcon(wx.Icon(consts.fileLogo, wx.BITMAP_TYPE_PNG))
858+ info.SetName(consts.appName)
859+ info.SetVersion(consts.appVersion)
860+ info.SetDescription(consts.description)
861+ info.SetCopyright(consts.copyright)
862+ info.SetWebSite(consts.urlHomepage)
863+ info.SetLicence(consts.license)
864+ info.AddDeveloper(consts.authors)
865+ info.AddDocWriter(consts.docwriters)
866+ info.AddArtist(consts.artists)
867+ info.AddTranslator(consts.translators)
868+
869+ wx.AboutBox(info)
870+
871+ def OnSources(self, event):
872+ proj = project.projects[len(project.projects) - 1]
873+ name = proj.getSources() + _(' - Sources Editor')
874+ edit = FileEditor(name, proj.getSources())
875+ if edit.ShowModal() == wx.ID_OK:
876+ edit.txt.SaveFile(proj.getSources())
877+ if wx.MessageBox(_("Sources have changed. Would you like to reload the package list?"), _("Save Successful"), wx.YES_NO) == 2: #wx.ID_YES:
878+ self.OnRefresh(None)
879+ edit.Destroy()
880+
881+ def OnOptions(self, event):
882+ options = optionDialog(None, -1, '')
883+ if options.ShowModal() == wx.ID_OK:
884+ # Set settings
885+ consts.proxy_enabled = options.proxyCheckBox.GetValue()
886+ conf = open(consts.file_config, 'w')
887+ conf.write('LogDir=' + options.logCtrl.GetValue() + '\n' +
888+ #'LocaleDir=' + options.localeCtrl.GetValue() + '\n' +
889+ #'PackagesDir=' + options.packagesCtrl.GetValue() + '\n' +
890+ 'PluginsDir=' + options.pluginsCtrl.GetValue() + '\n' +
891+ 'ProjectsDir=' + options.projectsCtrl.GetValue() + '\n' +
892+ 'PixmapsDir=' + options.pixmapsCtrl.GetValue() + '\n' +
893+ 'ThemesDir=' + options.themesCtrl.GetValue() + '\n' +
894+ 'DefaultTheme=' + options.defaultThemeCtrl.GetValue() + '\n' +
895+ 'CurrentTheme=' + options.defaultThemeCtrl.GetValue() + '\n')
896+
897 if options.proxyCheckBox.GetValue():
898- proxy_url = 'http://%s:%s' % (options.proxy_url.GetValue(), options.proxy_port.GetValue())
899- consts.http_proxy = {'http': proxy_url}
900- conf.write('HTTPProxy=' + proxy_url + '\n' +
901- 'ProxyUsername=' + options.proxy_username.GetValue() + '\n' +
902- 'ProxyPassword=' + options.proxy_password.GetValue() + '\n')
903- conf.close()
904- wx.MessageBox(_("If you changed a folder location, changes take affect after restarting Keryx."), _("Saved Changes"))
905- options.Destroy()
906-
907- def OnDownload(self, event):
908- # Downloads selected package and dependencies
909- try:
910- selected = self.list.GetSelectedItem()
911- if selected: files = project.projects[len(project.projects) - 1].getDependencies(selected[1])
912+ proxy_url = 'http://%s:%s' % (options.proxy_url.GetValue(), options.proxy_port.GetValue())
913+ consts.http_proxy = {'http': proxy_url}
914+ conf.write('HTTPProxy=' + proxy_url + '\n' +
915+ 'ProxyUsername=' + options.proxy_username.GetValue() + '\n' +
916+ 'ProxyPassword=' + options.proxy_password.GetValue() + '\n')
917+ conf.close()
918+ wx.MessageBox(_("If you changed a folder location, changes take affect after restarting Keryx."), _("Saved Changes"))
919+ options.Destroy()
920+
921+ def OnDownload(self, event):
922+ # Downloads selected package and dependencies
923+ try:
924+ selected = self.list.GetSelectedItem()
925+ if selected: files = project.projects[len(project.projects) - 1].getDependencies(selected[1])
926 except:
927- return
928-
929- # Generate filename list.
930- list = ""
931+ return
932+
933+ # Generate filename list.
934+ list = ""
935 for i in range(len(files)):
936- list += files[i][0] + "\n"
937-
938- # Confirm downloads
939- dlg = ScrolledMessageDialog(None, _("Confirm Download"), _("Do you wish to download the following") + " " + str(len(files)) + " " + _("files?"), list)
940- #dlg = wx.MessageDialog(None, _("Do you wish to download the following") + " " + str(len(files)) + " " + _("files?") + list, _("Confirm Downloads"), wx.YES_NO | wx.ICON_QUESTION)
941- result = dlg.ShowModal() == wx.ID_OK
942- dlg.Destroy()
943-
944- # User doesn't want to download them
945- if not result:
946- self.Refresh(project.projects[len(project.projects) -1].GetData())
947- #self.downloadedLists()
948- return
949-
950- # Make sure packages directory exists
951- dir = os.path.join(project.projects[len(project.projects) -1].dir, 'packages')
952- if not os.path.exists(dir):
953- os.mkdir(dir)
954-
955- #########################################################
956- # FIXME: Return to the plugin for post download cleanup #
957- #########################################################
958- frame = download(self, None, files)
959- #self.downloads.files = files
960- #self.thread.start(self, self.downloads.start, None) #self.downloadedLsts) # Do nothing after the packages are downloaded
961- #a.start(self, lists.start, None) # New thread
962-
963- # If it fails, reset the package lists, in other words, reload the list again.
964-
965- #self.download.downloads = files
966- #self.download.start()
967-
968- #FIXME: If any package fails to download, set package installed version to blank
969-
970+ list += files[i][0] + "\n"
971+
972+ # Confirm downloads
973+ dlg = ScrolledMessageDialog(None, _("Confirm Download"), _("Do you wish to download the following") + " " + str(len(files)) + " " + _("files?"), list)
974+ #dlg = wx.MessageDialog(None, _("Do you wish to download the following") + " " + str(len(files)) + " " + _("files?") + list, _("Confirm Downloads"), wx.YES_NO | wx.ICON_QUESTION)
975+ result = dlg.ShowModal() == wx.ID_OK
976+ dlg.Destroy()
977+
978+ # User doesn't want to download them
979+ if not result:
980+ self.Refresh(project.projects[len(project.projects) -1].GetData())
981+ #self.downloadedLists()
982+ return
983+
984+ # Make sure packages directory exists
985+ dir = os.path.join(project.projects[len(project.projects) -1].dir, 'packages')
986+ if not os.path.exists(dir):
987+ os.mkdir(dir)
988+
989+ #########################################################
990+ # FIXME: Return to the plugin for post download cleanup #
991+ #########################################################
992+ frame = download(self, None, files)
993+ #self.downloads.files = files
994+ #self.thread.start(self, self.downloads.start, None) #self.downloadedLsts) # Do nothing after the packages are downloaded
995+ #a.start(self, lists.start, None) # New thread
996+
997+ # If it fails, reset the package lists, in other words, reload the list again.
998+
999+ #self.download.downloads = files
1000+ #self.download.start()
1001+
1002+ #FIXME: If any package fails to download, set package installed version to blank
1003+
1004 def OnInstall(self, event):
1005+
1006 dlg = wx.MessageDialog(None, _("This procedure will first make the downloaded packages available to the OS in a format suitable for installation, then will call the OS to install them. " + \
1007 "These steps both require 'root' access to the machine, so keryx will write the commands to a script and then run it as 'root'. " + \
1008- "Would you like to continue? (got root?)"),
1009- _("Intro of Install"), wx.YES_NO | wx.ICON_QUESTION)
1010+ "Would you like to continue? (got root?)"),
1011+ _("Intro of Install"), wx.YES_NO | wx.ICON_QUESTION)
1012+ #dlg = InstallProjectDialog(None, -1, _("Install Project"))
1013 result = dlg.ShowModal()
1014- dlg.Destroy()
1015+ dlg.Destroy()
1016 if result == wx.ID_YES:
1017 dlg = wx.MessageDialog(None, _("There are two methods for making the packages available. First, mimicing a Repository and informing the OS of it and letting it use the repo to retrieve its updates, " + \
1018 "or moving the packages directly into the OS'es cache so that the OS thinks its already downloaded them and only needs to install them. This way is easier. " + \
1019@@ -357,7 +359,7 @@
1020 _("Choose Install method"), wx.YES_NO | wx.ICON_QUESTION)
1021 result = dlg.ShowModal()
1022 dlg.Destroy()
1023- install = True
1024+ install = True
1025 if result == wx.ID_YES:
1026 dlg = wx.MessageDialog(None, _("You can either move your packages you have downloaded to the cache, or just copy them.\n" + \
1027 "Moving them will free up space in your project again. Move?\nPlease ensure no package manager is running before continuing! The script will be run next."), \
1028@@ -427,100 +429,148 @@
1029 # _('New Project'), platform.node())
1030 # if dlg.ShowModal() == wx.ID_OK:
1031 # response = dlg.GetValue()
1032-# #print response
1033+# #print response
1034 # dlg.Destroy()
1035
1036 def OnUpdateStatus(self, event):
1037 dlg = wx.MessageDialog(None, _("This will update the list of packages installed on your computer. Only run this on the computer you created this project on.\n\n" + \
1038- "Would you like to continue?"),
1039- _("Update Status"), wx.YES_NO | wx.ICON_QUESTION)
1040+ "Would you like to continue?"),
1041+ _("Update Status"), wx.YES_NO | wx.ICON_QUESTION)
1042 result = dlg.ShowModal()
1043 dlg.Destroy()
1044 if not result:
1045 return
1046 if not self.UpdateStatus():
1047- dlg = wx.MessageDialog(None, _("Status update failed. Try running Keryx as root (using 'sudo')."),
1048- _("Status Update Failed"), wx.ICON_ERROR)
1049+ dlg = wx.MessageDialog(None, _("Status update failed. Try running Keryx as root (using 'sudo')."),
1050+ _("Status Update Failed"), wx.ICON_ERROR)
1051 result = dlg.ShowModal()
1052 dlg.Destroy()
1053 def UpdateStatus(self):
1054 project_dir = project.projects[len(project.projects) -1].dir
1055 return project.projects[len(project.projects) - 1].plugin.updateStatus(project_dir)
1056-
1057-
1058+
1059+
1060 def OnRefresh(self, event):
1061- self.Refresh(project.projects[len(project.projects) -1].GetData())
1062- def Refresh(self, data):
1063- self.SetTitle(data[0] + " - " + consts.appName + " v" + consts.appVersion)
1064- self.projectDetails.Clear()
1065- self.projectDetails.AppendText(data[0] + '\n')
1066- if data[2] != '': self.projectDetails.AppendText(_("Operating System:") + '\t' + data[2] + '\n')
1067- if data[3] != '': self.projectDetails.AppendText(_("Version:") + '\t' + data[3] + '\n')
1068- if data[4] != '': self.projectDetails.AppendText(_("Kernel:") + '\t' + data[5] + '\n')
1069- if data[5] != '': self.projectDetails.AppendText(_("Architecture:") + '\t' + data[4] + '\n')
1070- self.projectDetails.AppendText(_("Drive Free Space:") + '\t' + lib.driveFreeSpace() + '\n')
1071- #self.projectDetails.AppendText("%s\n%s\t%s\n%s\t%s\n%s\t%s\n%s\t%s\n%s\t%s" %
1072- # (data[0], os, data[2], v, data[3], k, data[4], a, data[5], f, lib.driveFreeSpace()))
1073-
1074- points = self.projectDetails.GetFont().GetPointSize()
1075- style = wx.Font(points, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
1076- self.projectDetails.SetStyle(0, len(data[0]), wx.TextAttr("black", wx.NullColour, style))
1077-
1078- # Inquire whether latest package list should be downloaded
1079- dlg = wx.MessageDialog(None, _('Download the latest package list?'),
1080- _("Download latest?"), wx.YES_NO | wx.ICON_QUESTION)
1081- result = dlg.ShowModal()
1082- dlg.Destroy()
1083-
1084- # Load package list
1085- self.SetStatusText(_("Loading packages") + "...", 0)
1086-
1087- if result == wx.ID_YES: frame = download(self, self.loadLocal, project.projects[len(project.projects) -1].getUrls(), True)
1088+ self.Refresh(project.projects[len(project.projects) -1].GetData())
1089+ def Refresh(self, data):
1090+ self.SetTitle(data[0] + " - " + consts.appName + " v" + consts.appVersion)
1091+ self.projectDetails.Clear()
1092+ self.projectDetails.AppendText(data[0] + '\n')
1093+ if data[2] != '': self.projectDetails.AppendText(_("Operating System:") + '\t' + data[2] + '\n')
1094+ if data[3] != '': self.projectDetails.AppendText(_("Version:") + '\t' + data[3] + '\n')
1095+ if data[4] != '': self.projectDetails.AppendText(_("Kernel:") + '\t' + data[5] + '\n')
1096+ if data[5] != '': self.projectDetails.AppendText(_("Architecture:") + '\t' + data[4] + '\n')
1097+ self.projectDetails.AppendText(_("Drive Free Space:") + '\t' + lib.driveFreeSpace() + '\n')
1098+ #self.projectDetails.AppendText("%s\n%s\t%s\n%s\t%s\n%s\t%s\n%s\t%s\n%s\t%s" %
1099+ # (data[0], os, data[2], v, data[3], k, data[4], a, data[5], f, lib.driveFreeSpace()))
1100+
1101+ points = self.projectDetails.GetFont().GetPointSize()
1102+ style = wx.Font(points, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
1103+ self.projectDetails.SetStyle(0, len(data[0]), wx.TextAttr("black", wx.NullColour, style))
1104+
1105+ # Get index file URLs.
1106+ urls = project.projects[len(project.projects) -1].getUrls()
1107+
1108+ # Inquire whether latest package list should be downloaded
1109+ #dlg = wx.MessageDialog(None, _('Download the latest package list?'),
1110+ # _("Download latest?"), wx.YES_NO | wx.ICON_QUESTION)
1111+ urls_string = '\n'.join(['\n'.join(x) for x in urls])
1112+ dlg = ScrolledMessageDialog(None, _("Download Latest?"),
1113+ _("Download the latest package list?"), urls_string)
1114+
1115+ result = dlg.ShowModal()
1116+ dlg.Destroy()
1117+
1118+ # Load package list
1119+ self.SetStatusText(_("Loading packages") + "...", 0)
1120+
1121+ if result == wx.ID_OK: frame = download(self, self.loadLocal, urls, True)
1122 else: self.loadLocal()
1123-
1124-
1125- def loadLocal(self, result=None):
1126- #TODO: Verify downloads?
1127- thread(self, project.projects[len(project.projects) - 1].loadLocal, self.loadPackages)
1128-
1129- def loadPackages(self, result=None):
1130- proj = project.projects[len(project.projects) - 1]
1131- #self.thread.Start(project.LocalPackagesThread(proj), None)
1132- self.list.SetMap(proj.packages)
1133- self.list.SortListItems(1, 1) # Sort column 1, ascending A->Z order
1134-
1135- self.SetStatusText(str(len(proj.packages.keys())) + " " + _("Packages"),0)
1136-
1137+
1138+
1139+ def loadLocal(self, result=None):
1140+ #TODO: Verify downloads?
1141+ thread(self, project.projects[len(project.projects) - 1].loadLocal, self.loadPackages)
1142+
1143+ def loadPackages(self, result=None):
1144+ proj = project.projects[len(project.projects) - 1]
1145+ #self.thread.Start(project.LocalPackagesThread(proj), None)
1146+ self.list.SetMap(proj.packages)
1147+ self.list.SortListItems(1, 1) # Sort column 1, ascending A->Z order
1148+
1149+ self.SetStatusText(str(len(proj.packages.keys())) + " " + _("Packages"),0)
1150+
1151 # end of class MainApp
1152
1153-# Begin mac9416's wonderful custom dialog!
1154+# Begin mac9416's wonderful custom dialog!
1155
1156 class ScrolledMessageDialog(wx.Dialog):
1157 def __init__(self, parent, title, caption, msg,
1158- pos=wx.DefaultPosition, size=(500,300),
1159+ pos=wx.DefaultPosition, size=(400,250),
1160 style=wx.DEFAULT_DIALOG_STYLE):
1161 wx.Dialog.__init__(self, parent, -1, title, pos, size, style)
1162 x, y = pos
1163 if x == -1 and y == -1:
1164 self.CenterOnScreen(wx.BOTH)
1165
1166- text1 = wx.StaticText(self, -1, caption)
1167- text2 = wx.TextCtrl(self, -1, msg, size=(500,300),
1168+ text1 = wx.StaticText(self, -1, caption, (5, 5), (370, 15))
1169+ text2 = wx.TextCtrl(self, -1, msg, (5, 20), (370, 220),
1170 style=wx.TE_MULTILINE | wx.TE_READONLY)
1171
1172 sizer = wx.BoxSizer(wx.VERTICAL)
1173
1174- btnsizer = wx.BoxSizer()
1175-
1176- btn = wx.Button(self, wx.ID_OK, "Yes")
1177- btnsizer.Add(btn, 0, wx.ALL, 5)
1178- btnsizer.Add((5,-1), 0, wx.ALL, 5)
1179-
1180- btn = wx.Button(self, wx.ID_CANCEL, "No")
1181+ btnsizer = wx.BoxSizer(wx.HORIZONTAL)
1182+ btn = wx.Button(self, wx.ID_CANCEL, _('No'), size=(100, 35))
1183+ btnsizer.Add(btn, 1)
1184+ btn = wx.Button(self, wx.ID_OK, _('Yes'), size=(100, 35))
1185 btn.SetDefault()
1186- btnsizer.Add(btn, 0, wx.ALL, 5)
1187+ btnsizer.Add(btn, 1)
1188
1189 sizer.Add(text1, 0, wx.EXPAND|wx.ALL, 5)
1190 sizer.Add(text2, 0, wx.EXPAND|wx.ALL, 5)
1191- sizer.Add(btnsizer, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
1192+ sizer.Add(btnsizer, 0, wx.ALIGN_RIGHT | wx.TOP | wx.BOTTOM, 10)
1193 self.SetSizerAndFit(sizer)
1194+
1195+class InstallProjectDialog(wx.Dialog):
1196+ def __init__(self, parent, id, title):
1197+ wx.Dialog.__init__(self, parent, id, title, size=(480, 190))
1198+
1199+ panel = wx.Panel(self, -1)
1200+ vbox = wx.BoxSizer(wx.VERTICAL)
1201+
1202+ wx.StaticBox(panel, -1, _("Installation method"), (5, 5), (470, 115))
1203+
1204+ self.sys_cache_radio = wx.RadioButton(panel, -1, _("Move packages to system cache"), (15, 30), style=wx.RB_GROUP)
1205+ self.Bind(wx.EVT_RADIOBUTTON, self.OnSysCache, self.sys_cache_radio)
1206+ self.local_repo_radio = wx.RadioButton(panel, -1, _("Create local repository"), (15, 55))
1207+ self.Bind(wx.EVT_RADIOBUTTON, self.OnLocalRepo, self.local_repo_radio)
1208+
1209+ self.dir_textctrl = wx.TextCtrl(self, -1, "", (190, 85), (200, 25))
1210+ self.dir_textctrl.Disable()
1211+ self.browse_btn = buttons.GenBitmapTextButton(panel, -1, wx.Bitmap(consts.icon_open), _("Save to..."), (40, 80), (140, 30))
1212+ self.browse_btn.Disable()
1213+ self.Bind(wx.EVT_BUTTON, self.OnBrowse, self.browse_btn)
1214+
1215+ wx.CheckBox(panel, -1, _("Delete packages from project folder after installation"), (5, 125))
1216+
1217+ hbox = wx.BoxSizer(wx.HORIZONTAL)
1218+ btn = wx.Button(self, -1, 'Cancel', size=(100, 30))
1219+ hbox.Add(btn, 1)
1220+ btn = wx.Button(self, -1, 'Continue', size=(100, 30))
1221+ hbox.Add(btn, 1, wx.LEFT, 5)
1222+
1223+ vbox.Add(panel)
1224+ vbox.Add(hbox, 1, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 10)
1225+
1226+ self.SetSizer(vbox)
1227+
1228+ def OnBrowse(self, evt):
1229+ print "Browsing..."
1230+
1231+ def OnLocalRepo(self, evt):
1232+ self.dir_textctrl.Enable()
1233+ self.browse_btn.Enable()
1234+
1235+ def OnSysCache(self, evt):
1236+ self.dir_textctrl.Disable()
1237+ self.browse_btn.Disable()
1238
1239=== modified file 'lib/wxkeryx/misc.py'
1240--- lib/wxkeryx/misc.py 2009-08-09 20:08:52 +0000
1241+++ lib/wxkeryx/misc.py 2009-12-16 01:34:10 +0000
1242@@ -158,7 +158,7 @@
1243
1244 # end of class VirtualList
1245
1246-class detailsTab():
1247+class detailsTab(object):
1248 def __init__(self, notebook):
1249 self.notebook = notebook
1250 self.pane = wx.Panel(self.notebook, -1, style=wx.TAB_TRAVERSAL)
1251
1252=== modified file 'plugins/Debian.py'
1253--- plugins/Debian.py 2009-12-15 23:20:21 +0000
1254+++ plugins/Debian.py 2009-12-16 01:34:10 +0000
1255@@ -473,7 +473,7 @@
1256 exit = (64, 'Error spawning shell command')
1257 return exit
1258
1259-class version_compare:
1260+class version_compare(object):
1261 def __init__(self):
1262 pass
1263
1264@@ -594,7 +594,7 @@
1265
1266 return equal
1267
1268-class version_parse:
1269+class version_parse(object):
1270 def __init__(self, string):
1271 self.string = string
1272
1273@@ -650,7 +650,7 @@
1274
1275 return ret_type
1276
1277-class version:
1278+class version(object):
1279 def __init__(self, ver_string):
1280 self.version = ver_string
1281 self.epoch_value = self.__get_epoch(self.version)
1282@@ -693,3 +693,5 @@
1283 upstream = str1
1284
1285 return [upstream, debver]
1286+
1287+

Subscribers

People subscribed via source and target branches