from explorer import models
-
class BookForm(forms.Form):
- text = forms.CharField(widget=forms.Textarea)
- commit_message = forms.CharField()
- user = forms.CharField()
+ content = forms.CharField(widget=forms.Textarea)
+ message = forms.CharField(required=False)
class ImageFoldersForm(forms.Form):
folders = forms.ChoiceField(required=False)
from librarian import html
-import hg, urllib2
+import hg, urllib2, time
from django.utils import simplejson as json
from django.views.generic.simple import direct_to_template
'objects': repo.all_files(),
})
+
+#
+# Edit the file
+#
def file_xml(request, path):
if request.method == 'POST':
form = forms.BookForm(request.POST)
if form.is_valid():
- # save the changes to a local branch
-# repo.write_lock()
- print request.user
-# repo.switch_to_branch(request.user.name)
-# repo.add_file(path, form.cleaned_data['text'])
-
- # add references to comment
- issues = _get_issues_for_file(path)
- commit_message = _add_references(form.cleaned_data['commit_message'], issues)
- print 'Commiting with: ' + commit_message
-
-# repo.commit(message=commit_message, user=form.cleaned_data['user'])
- return HttpResponse( json.dumps({'message': commit_message}) )
+ print 'Saving whole text.', request.user.username
+ def save_action():
+ repo.add_file(path, form.cleaned_data['content'])
+ repo.commit(message='Local save at %s' % time.ctime(), user=request.user.username)
+
+ repo.in_branch('local_'+request.user.username, save_action);
+ result = "ok"
+ else:
+ result = "error"
+
+ errors = dict( (field[0], field[1].as_text()) for field in form.errors.iteritems() )
+ return HttpResponse( json.dumps({'result': result, 'errors': errors}) );
else:
form = forms.BookForm()
- form.fields['text'].initial = repo.get_file(path).data()
-
- return direct_to_template(request, 'explorer/file_xml.html', extra_context={
- 'hash': path,
+ form.fields['content'].initial = repo.get_file(path).data()
+
+ return direct_to_template(request, 'explorer/edit_text.html', extra_context={
'form': form,
- 'image_folders_form': forms.ImageFoldersForm(),
})
+def file_dc(request, path):
+ if request.method == 'POST':
+ form = forms.DublinCoreForm(request.POST)
+ if form.is_valid():
+ form.save(repo, path)
+ result = "ok"
+ else:
+ result = "error"
+
+ errors = dict( (field[0], field[1].as_text()) for field in form.errors.iteritems() )
+ return HttpResponse( json.dumps({'result': result, 'errors': errors}) );
+ else:
+ fulltext = repo.get_file(path).data()
+ form = forms.DublinCoreForm(text=fulltext)
+
+ return direct_to_template(request, 'explorer/edit_dc.html', extra_context={
+ 'form': form,
+ 'fpath': path,
+ })
+
+# Display the main editor view
+def display_editor(request, path):
+ return direct_to_template(request, 'explorer/editor.html', extra_context={
+ 'hash': path,
+ })
# ===============
# = Panel views =
# ===============
+
def xmleditor_panel(request, path):
form = forms.BookForm()
text = repo.get_file(path).data()
return direct_to_template(request, 'explorer/panels/xmleditor.html', extra_context={
+ 'fpath': path,
'text': text,
})
def gallery_panel(request, path):
return direct_to_template(request, 'explorer/panels/gallery.html', extra_context={
+ 'fpath': path,
'form': forms.ImageFoldersForm(),
})
def htmleditor_panel(request, path):
return direct_to_template(request, 'explorer/panels/htmleditor.html', extra_context={
+ 'fpath': path,
'html': html.transform(repo.get_file(path).data(), is_file=False),
})
def dceditor_panel(request, path):
- if request.method == 'POST':
- form = forms.DublinCoreForm(request.POST)
- if form.is_valid():
- form.save(repo, path)
- repo.commit(message='%s: DublinCore edited' % path)
- else:
- text = repo.get_file(path).data()
- form = forms.DublinCoreForm(text=text)
+ text = repo.get_file(path).data()
+ form = forms.DublinCoreForm(text=text)
return direct_to_template(request, 'explorer/panels/dceditor.html', extra_context={
+ 'fpath': path,
'form': form,
})
# reread keys
# self._keys = self.get_persisted_objects_keys()
# return node.hex(rev)
+
+ def in_branch(self, branch_name, action):
+ wlock = self.repo.wlock()
+ try:
+ current_branch = self.repo[None].branch()
+ self.repo.dirstate.setbranch(branch_name)
+ try:
+ # do some stuff
+ action()
+ finally:
+ self.repo.dirstate.setbranch(current_branch)
+ finally:
+ wlock.release()
+
+ def write_lock(self):
+ """Returns w write lock to the repository."""
+ return self.repo.wlock()
+
.panel-content {
position: absolute;
overflow: auto;
+ overflow-x: hidden;
top: 22px; left: 0px; bottom:0px; right: 0px;
}
background-color: #DDD;
}
+
/* ================= */
/* = Gallery panel = */
/* ================= */
if(self != data)
self.otherPanelChanged(event.target);
else
- self.changed();
+ self.markChanged();
return false;
});
{
// arguments.shift();
$.log('calling hook: ', hookName, 'with args: ', arguments);
- this.hooks[hookName].apply(this, arguments);
+ return this.hooks[hookName].apply(this, arguments);
}
}
$.log('preparing xhr load: ', this.wrap);
$(document).trigger('panel:unload', this);
var self = this;
+ self.current_url = url;
$.ajax({
url: url,
};
}
+Panel.prototype.refresh = function(event, data) {
+ $('.change-notification', this.wrap).fadeOut();
+ $.log('refreshing view for panel ', this.current_url);
+ this.load(this.current_url);
+// if( this.callHook('refresh') )
+}
+
Panel.prototype.otherPanelChanged = function(other) {
$.log('panel ', other, ' changed.');
$('.change-notification', this.wrap).fadeIn();
this.callHook('dirty');
}
+Panel.prototype.markChanged = function () {
+ if(!this.wrap.hasClass('changed') ) // TODO: is this needed ?
+ this.wrap.addClass('changed');
+}
+
Panel.prototype.changed = function () {
- this.wrap.addClass('changed');
+ return this.wrap.hasClass('changed');
+}
+
+Panel.prototype.unmarkChanged = function () {
+ this.wrap.removeClass('changed');
}
Panel.prototype.saveInfo = function() {
// set up the UI visually and attach callbacks
var self = this;
var panelRoot = $('#panels');
+ self.rootDiv = panelRoot;
panelRoot.makeHorizPanel({}); // TODO: this probably doesn't belong into jQuery
panelRoot.css('top', ($('#header').outerHeight() ) + 'px');
Editor.prototype.saveToBranch = function() {
var changed_panel = $('.panel-wrap.changed');
+ var self = this;
$.log('Saving to local branch - panel:', changed_panel);
if( changed_panel.length == 0) {
saveInfo = changed_panel.data('ctrl').saveInfo();
$.ajax({
- url: location.href + (saveInfo.part || ''),
- dataType: (saveInfo.dataType || 'text'),
+ url: saveInfo.url,
+ dataType: 'json',
success: function(data, textStatus) {
- $.log('Success:', data);
+ if (data.result != 'ok')
+ $.log('save errors: ', data.errors)
+ else
+ self.refreshPanels(changed_panel);
},
error: function(rq, tstat, err) {
$.log('save error', rq, tstat, err);
},
type: 'POST',
- data: (saveInfo.content || '')
+ data: saveInfo.postData
});
};
+Editor.prototype.refreshPanels = function(goodPanel) {
+ var self = this;
+ var panels = $('#' + self.rootDiv.attr('id') +' > *.panel-wrap', self.rootDiv.parent());
+
+ panels.each(function() {
+ var panel = $(this).data('ctrl');
+ $.log(this, panel);
+ if ( panel.changed() )
+ panel.unmarkChanged();
+ else
+ panel.refresh();
+ });
+};
+
$(function() {
editor = new Editor();
--- /dev/null
+<form action="" method="POST">
+{{ form.as_p }}
+<input type="submit" value="Submit" />
+</form>
--- /dev/null
+<form action="" method="POST">
+{{ form.as_p }}
+<input type="submit" value="Submit" />
+</form>
--- /dev/null
+{% extends "base.html" %}
+
+{% block extrahead %}
+ <script src="/static/js/jquery.lazyload.js" type="text/javascript" charset="utf-8"></script>
+ <script src="/static/js/codemirror/codemirror.js" type="text/javascript" charset="utf-8"></script>
+ <script src="/static/js/jquery.autoscroll.js" type="text/javascript" charset="utf-8"></script>
+ <script src="/static/js/jquery.wtooltip.js" type="text/javascript" charset="utf-8"></script>
+ <script src="/static/js/jquery.hpanel.js" type="text/javascript" charset="utf-8"></script>
+ <script src="/static/js/editor.js" type="text/javascript" charset="utf-8"></script>
+{% endblock extrahead %}
+
+{% block breadcrumbs %}<a href="{% url file_list %}">Platforma Redakcyjna</a> ❯ plik {{ hash }}{% endblock breadcrumbs %}
+
+{% block header-toolbar %}
+ <button type="button" class="toolbar-button" id="toolbar-button-save">Zapisz</button>
+{% endblock %}
+{% block maincontent %}
+ <div id="panels">
+ <div id="left-panel-wrap" class="panel-wrap">
+ <div id="left-panel-toolbar" class="panel-toolbar">
+ <label for="select-left-panel">Lewy panel:</label>
+ <select name="select-left-panel" id="select-left-panel">
+ <option value="{% url xmleditor_panel hash %}">Edytor XML</option>
+ <option value="{% url htmleditor_panel hash %}">Edytor HTML</option>
+ <option value="{% url gallery_panel hash %}">Galeria skanów</option>
+ <option value="{% url dceditor_panel hash %}">Edytor DublinCore</option>
+ </select>
+ <strong class="change-notification" style="display: none">Widok nieaktualny!</strong>
+ </div>
+ <div id="left-panel-content" class="panel-content"></div>
+ <button type="button" class="panel-slider" id="slider01"></button>
+ </div>
+ <div id="right-panel-wrap" class="panel-wrap last-panel">
+ <div id="right-panel-toolbar" class="panel-toolbar">
+ <label for="select-right-panel">Prawy panel:</label>
+ <select name="select-right-panel" id="select-right-panel">
+ <option value="{% url xmleditor_panel hash %}">Edytor XML</option>
+ <option value="{% url htmleditor_panel hash %}">Edytor HTML</option>
+ <option value="{% url gallery_panel hash %}">Galeria skanów</option>
+ <option value="{% url dceditor_panel hash %}">Edytor DublinCore</option>
+ </select>
+ <strong class="change-notification" style="display: none">Widok nieaktualny!</strong>
+ </div>
+ <div id="right-panel-content" class="panel-content"></div>
+ </div>
+ </div>
+{% endblock maincontent %}
{% block maincontent %}
<ul>
{% for blob in objects %}
- <li><a href="{% url file_xml blob %}">{{ blob }}</a></li>
+ <li><a href="{% url editor_view blob %}">{{ blob }}</a></li>
{% endfor %}
</ul>
{% endblock maincontent %}
+++ /dev/null
-{% extends "base.html" %}
-
-{% block extrahead %}
- <script src="/static/js/jquery.lazyload.js" type="text/javascript" charset="utf-8"></script>
- <script src="/static/js/codemirror/codemirror.js" type="text/javascript" charset="utf-8"></script>
- <script src="/static/js/jquery.autoscroll.js" type="text/javascript" charset="utf-8"></script>
- <script src="/static/js/jquery.wtooltip.js" type="text/javascript" charset="utf-8"></script>
- <script src="/static/js/jquery.hpanel.js" type="text/javascript" charset="utf-8"></script>
- <script src="/static/js/editor.js" type="text/javascript" charset="utf-8"></script>
-{% endblock extrahead %}
-
-{% block breadcrumbs %}<a href="{% url file_list %}">Platforma Redakcyjna</a> ❯ plik {{ hash }}{% endblock breadcrumbs %}
-
-{% block header-toolbar %}
- <button type="button" class="toolbar-button" id="toolbar-button-save">Zapisz</button>
-{% endblock %}
-{% block maincontent %}
- <div id="panels">
- <div id="left-panel-wrap" class="panel-wrap">
- <div id="left-panel-toolbar" class="panel-toolbar">
- <label for="select-left-panel">Lewy panel:</label>
- <select name="select-left-panel" id="select-left-panel">
- <option value="{% url xmleditor_panel hash %}">Edytor XML</option>
- <option value="{% url htmleditor_panel hash %}">Edytor HTML</option>
- <option value="{% url gallery_panel hash %}">Galeria skanów</option>
- <option value="{% url dceditor_panel hash %}">Edytor DublinCore</option>
- </select>
- <strong class="change-notification" style="display: none">Widok nieaktualny!</strong>
- </div>
- <div id="left-panel-content" class="panel-content"></div>
- <button type="button" class="panel-slider" id="slider01"></button>
- </div>
- <div id="right-panel-wrap" class="panel-wrap last-panel">
- <div id="right-panel-toolbar" class="panel-toolbar">
- <label for="select-right-panel">Prawy panel:</label>
- <select name="select-right-panel" id="select-right-panel">
- <option value="{% url xmleditor_panel hash %}">Edytor XML</option>
- <option value="{% url htmleditor_panel hash %}">Edytor HTML</option>
- <option value="{% url gallery_panel hash %}">Galeria skanów</option>
- <option value="{% url dceditor_panel hash %}">Edytor DublinCore</option>
- </select>
- <strong class="change-notification" style="display: none">Widok nieaktualny!</strong>
- </div>
- <div id="right-panel-content" class="panel-content"></div>
- </div>
- </div>
-{% endblock maincontent %}
<div class="panel-dceditor">
<form action="{{ request.get_full_path }}" method="post" accept-charset="utf-8">
- {{ form }}
- <p><input type="submit" value="Continue →"/></p>
+ {{ form.as_p }}
+<!-- <p><input type="submit" value="Continue →"/></p> -->
</form>
</div>
<script type="text/javascript" charset="utf-8">
-panel_hooks = { };
+panel_hooks = {
+
+ load: function() {
+ var self = this;
+ self.form = $('form', self.contentDiv);
+ $("input[type='text'], textarea", self.form).each(function() {
+ $(this).change(function(event) {
+ self.contentDiv.trigger('panel:contentChanged', self);
+ });
+ });
+ },
+ saveInfo: function(hn, saveInfo) {
+ var myInfo = {
+ url: "{% url file_dc fpath %}",
+ postData: $('form', this.contentDiv).serialize()
+ };
+ $.extend(saveInfo, myInfo);
+ }
+};
</script>
-<div class="panel">
- <div class="toolbar">
- <select name="folders" class="id_folders">
- <option value="" selected="selected">-- Wybierz folder z obrazkami --</option>
- <option value="andersen_basnie">andersen_basnie</option>
- </select>
- </div>
- <div class="images-wrap">
- <div class="images">
- </div>
- </div>
+<div class="toolbar" style="height: 24px">
+ <select name="folders" class="id_folders">
+ <option value="" selected="selected">-- Wybierz folder z obrazkami --</option>
+ <option value="andersen_basnie">andersen_basnie</option>
+ </select>
+</div>
+
+<div class="images-wrap" style="position: absolute; top: 24px; left:0px; right:0px; bottom: 0px;">
+ <div class="images"><!-- To jest div na obrazki, które są wstawiane później --></div>
</div>
<script type="text/javascript" charset="utf-8">
var pos = texteditor.cursorPosition();
texteditor.selectLines(pos.line, pos.character + tag.length + 2);
}
- $(document).trigger('panel:contentChanged', panel);
+ $(document).trigger('panel:contentChanged', self);
}
if ($(this).attr('p:key')) {
keys[$(this).attr('p:key')] = handler;
this.texteditor = null;
},
+
+ refresh: function(hn) {
+ // TODO
+ return true;
+ },
+
saveInfo: function(hn, saveInfo) {
- var myInfo = {content: this.texteditor.getCode(), dataType: 'xml'};
+ var myInfo = {
+ url: "{% url file_xml fpath %}",
+ postData: {
+ content: this.texteditor.getCode()
+ }
+ };
$.extend(saveInfo, myInfo);
}
};
from django.contrib import admin
from django.conf import settings
-
admin.autodiscover()
-
+PATH_END = r"(?P<path>[^/]+)$"
urlpatterns = patterns('',
# Explorer:
url(r'^$', 'explorer.views.file_list', name='file_list'),
- url(r'^file/(?P<path>[^/]+)/$', 'explorer.views.file_xml', name='file_xml'),
+
+ url(r'^file/text/'+PATH_END, 'explorer.views.file_xml', name='file_xml'),
+ url(r'^file/dc/'+PATH_END, 'explorer.views.file_dc', name='file_dc'),
+
url(r'^images/(?P<folder>[^/]+)/$', 'explorer.views.folder_images', name='folder_image'),
url(r'^images/$', 'explorer.views.folder_images', {'folder': '.'}, name='folder_image_ajax'),
# Editor panels
- url(r'^editor/(?P<path>[^/]+)/panels/xmleditor/$', 'explorer.views.xmleditor_panel', name='xmleditor_panel'),
- url(r'^editor/(?P<path>[^/]+)/panels/gallery/$', 'explorer.views.gallery_panel', name='gallery_panel'),
- url(r'^editor/(?P<path>[^/]+)/panels/htmleditor/$', 'explorer.views.htmleditor_panel', name='htmleditor_panel'),
- url(r'^editor/(?P<path>[^/]+)/panels/dceditor/$', 'explorer.views.dceditor_panel', name='dceditor_panel'),
-
+ url(r'^editor/panel/xmleditor/'+PATH_END, 'explorer.views.xmleditor_panel', name='xmleditor_panel'),
+ url(r'^editor/panel/gallery/'+PATH_END, 'explorer.views.gallery_panel', name='gallery_panel'),
+ url(r'^editor/panel/htmleditor/'+PATH_END, 'explorer.views.htmleditor_panel', name='htmleditor_panel'),
+ url(r'^editor/panel/dceditor/'+PATH_END, 'explorer.views.dceditor_panel', name='dceditor_panel'),
+ url(r'^editor/'+PATH_END, 'explorer.views.display_editor', name='editor_view'),
+
# Admin panel
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/(.*)', admin.site.root),