1 """
2 Abstract way of user interaction
3
4 This file is part of Pisi.
5
6 In order to make it possible, to use core functionality code with any kind of User Interface, the user interaction is
7 being abstracted to an interface, which has to be overwritten for a UI implementation.
8
9 The UI implementation is simply registered in the beginning, the core functionality modules access it by using the
10 Singleton implementation. This way, there is no need for passing around a reference to the UI all the time.
11
12 Pisi is free software: you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation, either version 3 of the License, or
15 (at your option) any later version.
16
17 Pisi is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with Pisi. If not, see <http://www.gnu.org/licenses/>.
24 """
25
26 global instance
27 instance = None
28
30 """
31 Singleton
32
33 This function may be called from anywhere within the program in order to carry out user interaction.
34 """
35 global instance
36 if instance == None:
37 raise ValueError("No callback yet implemented - progress cannot be reported!")
38 return instance
39
41 """
42 Register a callback instance
43
44 @param callback: Implementation of interface L{AbstractCallback}
45 """
46 global instance
47 instance = callback
48
49
51 """
52 Each callback implementation (CLI or GUI) should overwrite this interface
53 """
55 """
56 Constructor
57
58 Initializes a L{Progress} instance.
59 """
60 self.progress = Progress()
61
63 """
64 Output a message to the user
65 """
66 pass
67
69 """
70 Output a message (of lower interest) to the user
71 """
72 pass
73
75 """
76 Pass on an error message to the user
77 """
78 pass
79
81 """
82 Prompt the user for a single entry to type in
83 """
84 return None
85
87 """
88 Ask user for a single confirmation (OK / Cancel)
89 """
90 return False
91
93 """
94 Prompt the user for providing a file name
95 """
96 return self.promptGeneric(prompt, default)
97
99 """
100 Use interaction for choosing which contact entry to keep in case of a conflict
101
102 @return: A dictionary which contains the action for each conflict entry; the key is the id of the contact entry,
103 the value one out of a - keep entry from first source, b - keep value from second source and s - skip this entry (no change on either side)
104 """
105 return {}
106
108 """
109 This function should be called whenever new information has been made available and the UI should be updates somehow.
110 """
111 pass
112
114 """
115 Handling of progress in terms of percentage
116
117 You may have a linear progress 'bar' or create several layers of progresses.
118 There is a need to put some more documentation here soon.
119 """
121 """
122 Initialize progress with one single layer
123 """
124 self.reset()
125
127 """
128 Set progress in top layer
129 """
130 self._progress[len(self._progress)-1][0] = x
131
132 - def push(self, x1, x2):
133 """
134 Add another layer of progress
135 """
136 self.setProgress(x1)
137 self._progress.append([0, (x1, x2)])
138
140 """
141 Remove the top layer in progress
142 """
143 current = self._progress[len(self._progress)-1]
144 self._progress[len(self._progress)-1:] = []
145 x1, x2 = current[1]
146 self.setProgress(x2)
147
149 """
150 Drop all layers and reset to 0
151 """
152 self._progress = []
153 self._progress.append([0, (0, 100)])
154
156 """
157 Iterate through layers to calculate the current overall progress
158 """
159 total = 0.0
160 for i in reversed (range(0, len(self._progress))):
161 current = self._progress[i]
162 x1, x2 = current[1]
163 total = (total + current[0]) / 100 * (x2 - x1)
164 return total
165